| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
fix(release): download clobber/skip, named-asset strictness, streaming upload, view/delete polish download: an existing file was silently overwritten (temp+rename with no existence check), and a mistyped asset name exited 0 with "No assets to download" — scripts could not tell a typo from an empty release. Existing files now refuse by default with --clobber to overwrite and --skip-existing to skip (mutually exclusive, gh-aligned). Named downloads are strict: any miss is an error listing the available asset names, and the named set bypasses the source-archive filter — naming an archive explicitly is intent and must download it even without --all. upload: the whole file was buffered in memory (io.ReadAll then a []byte PUT — double the asset size, OOM territory for large binaries); UploadToURL and UploadReleaseAssetByTag now take an io.Reader with an explicit ContentLength (presigned URLs reject chunked PUTs) and uploadFile streams from the file handle with a 512-byte sniff-and-rewind for content type. The platform's overwrite behavior for duplicate asset names is undefined, so a GetRelease precheck refuses the whole batch (zero PUTs) when any name collides, pointing at delete-asset or a rename. A mid-batch failure now names what already landed. The --label example that errors when copied is gone (the flag stays, with its explicit rejection). delete: the confirmation prompt showed the release Name but expected the tag — when they differ, typing what the screen says was rejected. confirmTitle shows "Name (tag: tag)" so the expected input is always visible; Expected stays the tag (the API key). view: gained its first run-level tests (web/TTY/non-TTY browser fallback via an injected opener matching the pr create seam, JSON, human render, not-found wrapping). list: the body-first-line truncate was byte-based and corrupted CJK text at the 60-byte boundary; a shared rune-aware output.Truncate now serves release list, issue templates (same latent bug), and the plugin list (which had its own correct copy). COMMANDS.md documents the new download/upload semantics and fixes the extension-name wording for source archives (detection is by URL, not extension). Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 | |
perf(api): stream --input file/stdin as request body (align with gh) - readInput now returns *os.File for file input and io.NopCloser(stdin) for stdin, instead of buffering the entire content into memory via os.ReadFile/bytes.NewReader. - run() defers Close on the returned reader when it implements io.Closer. - Mirrors GitHub CLI's openUserFile (pkg/cmd/api/api.go) which streams the file directly as the HTTP request body. - Add tests: TestReadInputEmptyReturnsNil, TestReadInputStreamsFile. | 3 个月前 | |
fix(review): pin success-state JSON and tighten always-present wording - add the success-path --json test (token_valid:true plus username, token_source, git_protocol), closing the three-state coverage of the always-serialized state booleans the test review flagged - docs/COMMANDS.md: the failure sentence now states both fields always serialize, per the docs review suggestion, so agent consumers know they can skip field-presence branching Refs #624 Co-Authored-By: Claude Code <noreply@anthropic.com> | 16 天前 | |
fix(browse): respect --no-interactive, add url.PathEscape, fix error wrapping Address Round 1 independent review findings (PR #489): P1 fixes (must fix): - Add opts.IO.NoInteractive() check so --no-interactive suppresses browser opening in TTY mode (agent-friendly CLI contract §6.1) - This aligns code with docs/COMMANDS.md which already documents --no-interactive as suppressing browser P2 fixes (should fix): - Add url.PathEscape for owner/repo/commit path segments, aligning with api/repo_path.go security convention - Normalize api.gitcode.com → gitcode.com in resolveHost to avoid opening API host in browser - Wrap resolveHost error with fmt.Errorf("failed to resolve host: %w") - Add 5 new tests: resolveHost error path, API host normalization, --no-interactive browser suppression, invalid repo format Test count: 20 → 25, all passing. Refs gitcode-cli/cli#521 | 2 个月前 | |
fix(cmdutil): SetFlagEnum returns error, no panic + spec rule (#415) #415: SetFlagEnum 在注解失败时 panic 让 CLI 崩溃,绕过 error 语义。spec 此前 无「禁止裸 panic」规则(issue 引用条文不存在),先补规则再修: - spec/foundations/coding-standards.md: 错误处理节加「禁止裸 panic」规则 (业务/运行期 error 返回;构造期非功能性元数据无法传播 error 时降级 stderr 告警+继续,不得崩溃;Must* 前缀显式 fail-fast;cobra 第三方不在范围) - pkg/cmdutil/flag_annotations.go: SetFlagEnum 改返 error(去 panic); 新增 SetFlagEnumOrWarn(构造期降级告警+继续,不崩溃) - pkg/cmdutil/format.go: AddFormatFlag/AddTimeFormatFlag 同包调用改 OrWarn - 18 处命令构造调用点 cmdutil.SetFlagEnum( → cmdutil.SetFlagEnumOrWarn( - pkg/cmdutil/flag_annotations_test.go: 新增 4 测试(注册 flag 注解成功; 未注册 flag 返 error 不 panic;OrWarn 不崩溃+stderr 告警;OrWarn 成功静默) 正确代码行为不变(注解照常设置);仅编程错误(注解未注册 flag)时从崩溃改为告警。 Closes #415 | 2 个月前 | |
fix(config): address Round 1 review — clear-cache help + editor/pager defaults + docs Address Round 1 independent review findings (PR #494): P1 fixes (must fix): - D2: Fix clear-cache Long help text — remove references to non-existent cache types (API responses/completion scripts/update timestamps); state honestly what it clears - D1: Add config list to --json supported commands list in COMMANDS.md P2 fixes (should fix): - C5: Show editor=vim and pager=less as default values in config list, matching Config.Editor()/Config.Pager() behavior - D3: Add default_repo to config get/set supported keys in docs - D4: Add GC_CONFIG_DIR mention to config clear-cache docs 16/16 tests pass. Refs gitcode-cli/cli#527 | 2 个月前 | |
!562 merge feature/issue-552-repo-comments into main feat(discussions): add repo discussion comment edit/reply Created-by: langjitianya008 Commit-by: langjitianya008 Merged-by: kerer-sk Description: ## 变更内容 新增仓库级讨论评论写命令 edit/reply。 ### 新增命令(2 个) | 命令 | API | |------|-----| | gc discussions project comments edit <number> <comment-id> [-R owner/repo] --body [--json] | PUT /api/v5/repos/{owner}/{repo}/discuss/{number}/comment/{id} | | gc discussions project comments reply <number> <comment-id> [-R owner/repo] --body [--json] | POST /api/v5/repos/{owner}/{repo}/discuss/{number}/comment/{id}/reply | ### 改动说明 - api/queries_discussions.go:UpdateRepoDiscussionComment 改用 PUT(对照官方 OpenAPI) - pkg/cmd/discussions/project/comments/edit|reply/:新命令包,遵循仓库命令模板(Options 结构体 + NewCmdXxx 工厂 + runF 注入),全部支持 --json、--body-file -(stdin)、提交前密钥扫描 - docs/COMMANDS.md:2 个新命令章节 ## Test Plan - [x] go build ./... / go vet ./... / gofmt -l 通过 - [x] go test ./... 全部通过(162 个包) - [x] 新命令包覆盖率:project comments edit 79.1%、reply 79.1%(≥70% 门禁) - [x] pre-commit 11/11 hooks 通过 - [x] gitleaks 工作区 + 历史扫描 0 findings - [x] 单元测试覆盖:flag 解析、run 校验、HTTP mock 断言(method/path/body)、--json 输出、错误路径 ## 自检说明 - api-doc/ submodule 三种方式均认证失败不可达,以 issue 正文 + 官方文档站核对 PUT 端点 - 真实命令验证受限:infra-test/* 仓库无讨论环境,已用 HTTP mock 全路径断言替代(method/path/body/响应解析) Refs #552 See merge request: atomgit-cli/cli!562 | 1 个月前 | |
fix(ci): remove unused truncate leftover; JSON-encode paths in doctor test manifests Two CI failures on the first run of this batch: - Lint: the C7 rewiring replaced the call site but the local truncate body in release/list survived (a scripted replacement missed silently); golangci-lint's unused check caught it. Removed. The full-repo lint run is now part of this batch's verification (it was previously only run per-directory). - Test (windows): the npm-prefix conflict fixture interpolated the temp-dir path into the manifest JSON raw — on Windows those paths carry backslashes, which are invalid JSON escape sequences, so json.Unmarshal failed, npmPrefix returned empty, and the conflict branch under test silently never ran (green on Linux, where paths have no backslashes). Both path-carrying manifests in the file now use json.Marshal, which cannot emit invalid JSON. Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 | |
fix(cmdutil): SetFlagEnum returns error, no panic + spec rule (#415) #415: SetFlagEnum 在注解失败时 panic 让 CLI 崩溃,绕过 error 语义。spec 此前 无「禁止裸 panic」规则(issue 引用条文不存在),先补规则再修: - spec/foundations/coding-standards.md: 错误处理节加「禁止裸 panic」规则 (业务/运行期 error 返回;构造期非功能性元数据无法传播 error 时降级 stderr 告警+继续,不得崩溃;Must* 前缀显式 fail-fast;cobra 第三方不在范围) - pkg/cmdutil/flag_annotations.go: SetFlagEnum 改返 error(去 panic); 新增 SetFlagEnumOrWarn(构造期降级告警+继续,不崩溃) - pkg/cmdutil/format.go: AddFormatFlag/AddTimeFormatFlag 同包调用改 OrWarn - 18 处命令构造调用点 cmdutil.SetFlagEnum( → cmdutil.SetFlagEnumOrWarn( - pkg/cmdutil/flag_annotations_test.go: 新增 4 测试(注册 flag 注解成功; 未注册 flag 返 error 不 panic;OrWarn 不崩溃+stderr 告警;OrWarn 成功静默) 正确代码行为不变(注解照常设置);仅编程错误(注解未注册 flag)时从崩溃改为告警。 Closes #415 | 2 个月前 | |
feat(cli): 统一 list 命令分页 flag(--limit + --per-page 全覆盖) issue #501:list 类命令分页 flag 命名分裂——issue/label/milestone/ repo list/repo log 仅 --limit;discussions(org+project) 仅 --per-page; pr list/actions 两者并存。agent 无法预知某命令用哪个 flag(§6.1)。 方案 A:所有 list 命令统一提供 --per-page(API page size)+ --limit (客户端结果上限,默认 30)。语义对齐 pr list 既有双 flag 模式 (resolvePerPage + trim + LimitSet/PerPageSet)。 改动: - issue/label/milestone/repo list/repo log(5 命令)补 --per-page + resolvePerPage/trim + PerPage<0 校验 - discussions list(org) + project list(2 命令)补 --limit + trim + Limit<=0 校验 - pr list / actions(已合规)不改 - docs/COMMANDS.md 更新 7 命令分页 flag 说明(修正 label list 旧误述) - 单测:issue list 补 resolvePerPage/trim/validation 表驱动测试; discussions org+project 修 fixture(Limit:30) + 补 limit 校验用例 §5.9.B:已查 gc-api-doc 确认 issues/labels/milestones 端点均支持 per_page(无功能缺口,仅 flag 命名分裂)。 Closes #501 | 2 个月前 | |
fix(label): set GC_TOKEN in edit tests + fix --json list category Refs #525 | 2 个月前 | |
test(lark): cross-platform stubs for CI (fix #499) lark 测试硬编码 /bin/true 作 FindLarkCLI 桩,该路径仅 Linux 存在,导致 macOS/Windows CI 报 lark-cli not installed(4 测试跨平台失败,main HEAD 既有)。改用 os.Executable() (运行中的测试二进制,全平台存在且 isExecutable 通过)。另 TestSaveDefaultChat 的 0600 权限断言 Windows-only 失败(Go 在 Windows 报 0666),改为 unix-only 断言。 - doctor_test.go/install_test.go: /bin/true → existingExecutable(t) (os.Executable) - config_test.go: 0600 断言 runtime.GOOS != windows 时才校验 | 2 个月前 | |
feat(cli): 统一 list 命令分页 flag(--limit + --per-page 全覆盖) issue #501:list 类命令分页 flag 命名分裂——issue/label/milestone/ repo list/repo log 仅 --limit;discussions(org+project) 仅 --per-page; pr list/actions 两者并存。agent 无法预知某命令用哪个 flag(§6.1)。 方案 A:所有 list 命令统一提供 --per-page(API page size)+ --limit (客户端结果上限,默认 30)。语义对齐 pr list 既有双 flag 模式 (resolvePerPage + trim + LimitSet/PerPageSet)。 改动: - issue/label/milestone/repo list/repo log(5 命令)补 --per-page + resolvePerPage/trim + PerPage<0 校验 - discussions list(org) + project list(2 命令)补 --limit + trim + Limit<=0 校验 - pr list / actions(已合规)不改 - docs/COMMANDS.md 更新 7 命令分页 flag 说明(修正 label list 旧误述) - 单测:issue list 补 resolvePerPage/trim/validation 表驱动测试; discussions org+project 修 fixture(Limit:30) + 补 limit 校验用例 §5.9.B:已查 gc-api-doc 确认 issues/labels/milestones 端点均支持 per_page(无功能缺口,仅 flag 命名分裂)。 Closes #501 | 2 个月前 | |
test(pr): add mergers JSON and clear-semantics tests, document --mergers - Add TestEditRunSetsPRMergersJSON covering the {"pull_request", "mergers"} JSON output shape introduced with --mergers - Add TestEditRunClearsPRMergers pinning --mergers "" as an explicit empty-set PUT that clears all mergers - Document --mergers in the pr edit flag list (PUT /pulls/{number}/mergers, full replacement), the "" clear usage, and the wrapped JSON output shape - Align MergerRequest comment with help text (login names) Refs #552 | 1 个月前 | |
fix(precommit): enforce pre-push hooks | 3 个月前 | |
fix(ci): remove unused truncate leftover; JSON-encode paths in doctor test manifests Two CI failures on the first run of this batch: - Lint: the C7 rewiring replaced the call site but the local truncate body in release/list survived (a scripted replacement missed silently); golangci-lint's unused check caught it. Removed. The full-repo lint run is now part of this batch's verification (it was previously only run per-directory). - Test (windows): the npm-prefix conflict fixture interpolated the temp-dir path into the manifest JSON raw — on Windows those paths carry backslashes, which are invalid JSON escape sequences, so json.Unmarshal failed, npmPrefix returned empty, and the conflict branch under test silently never ran (green on Linux, where paths have no backslashes). Both path-carrying manifests in the file now use json.Marshal, which cannot emit invalid JSON. Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 | |
test(repo): cover archive --json + docs json list Refs #523 | 2 个月前 | |
fix(update): align lifecycle semantics and close lock-identity gaps A failing gc command skipped the update lifecycle entirely on the bootstrap channel (cobra skips PersistentPostRun when RunE errors), while the npm wrapper runs its lifecycle on every exit code: pending summaries, first-run notice and due background checks all stalled while a user's commands kept failing (e.g. an expired token). Execute now runs the lifecycle explicitly on the error path, mirroring gc.js. A background spawn that raced a mode flip to off still installed on the npm channel (shouldOnlyNotify has no off branch); the under-lock mode recheck now returns disabled for background runs — writing no state, so the winner's nextCheck stays put. updateMode trims whitespace on both JS channels (CRLF-contaminated profile values like " off" resolved differently than the Go side, which trims). A transient bootstrap failure over an existing permanent pause now says the pause remains (mirroring the npm channel's sticky guidance). Lock identity: the JS releaseLock's inode check always passes on Windows (libuv leaves st_ino at 0), so a stalled holder resuming after a stale reclaim would still delete the reclaimer's fresh lock there — the locks now record the holder pid and release verifies it by content (the Go side already did), keeping the inode check as the POSIX fast path. The stale-reclaim restore path used rename, which silently overwrites: a third process claiming the freed path between the retire and the restore would have its fresh lock clobbered; the restore now uses link+unlink (EEXIST means the path is taken — give up the hold) on all three implementations. writeState failures no longer vanish silently: mutateStateLocked reports them, and the hourly spawn backoff degrades to a single fixed "state is not writable" notice instead of reprinting the spawn detail on every command. Fifth review P3 backlog, issue 607 items 11, 12, 13, 14, 15, 17, 18. Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 | |
fix(cmdutil): SetFlagEnum returns error, no panic + spec rule (#415) #415: SetFlagEnum 在注解失败时 panic 让 CLI 崩溃,绕过 error 语义。spec 此前 无「禁止裸 panic」规则(issue 引用条文不存在),先补规则再修: - spec/foundations/coding-standards.md: 错误处理节加「禁止裸 panic」规则 (业务/运行期 error 返回;构造期非功能性元数据无法传播 error 时降级 stderr 告警+继续,不得崩溃;Must* 前缀显式 fail-fast;cobra 第三方不在范围) - pkg/cmdutil/flag_annotations.go: SetFlagEnum 改返 error(去 panic); 新增 SetFlagEnumOrWarn(构造期降级告警+继续,不崩溃) - pkg/cmdutil/format.go: AddFormatFlag/AddTimeFormatFlag 同包调用改 OrWarn - 18 处命令构造调用点 cmdutil.SetFlagEnum( → cmdutil.SetFlagEnumOrWarn( - pkg/cmdutil/flag_annotations_test.go: 新增 4 测试(注册 flag 注解成功; 未注册 flag 返 error 不 panic;OrWarn 不崩溃+stderr 告警;OrWarn 成功静默) 正确代码行为不变(注解照常设置);仅编程错误(注解未注册 flag)时从崩溃改为告警。 Closes #415 | 2 个月前 | |
fix(search): address Round 1 review — refactor SearchIssues + limit validation + types Address Round 1 independent review findings (PR #498): Blocker fixes: - C3: Refactor SearchIssues to take Repo/State in SearchOptions struct instead of separate parameters, eliminating manual URL &-concatenation edge case (buildSearchQuery handles all params via queryBuilder.Set) - C1: SearchIssueResult.Number changed from interface{} to FlexibleNumber (aligns with existing Issue.Number type) - D1: Add --limit/--page to search issues docs (was missing) Should-fix: - C4: Add --limit/--page validation to all three subcommands (aligns with repo branch list pattern) - C5: SearchRepoResult.Status changed from interface{} to string (api-doc confirms it is always string) - D2: Add exit code 2 (parameter error) to all three search docs 14/14 tests pass. Refs gitcode-cli/cli#518 | 2 个月前 | |
Revert "fix: validate SSH public key wire format" This reverts commit 63c1e78ca4b0cdb348a9bc514d23b9613b17c0ca. | 2 个月前 | |
fix(channels): make uv detection reachable and its guidance correct The uv channel added in the third round was unreachable: uv tools enter through wrapper.py, which unconditionally declared DISTRIBUTION_ENV=pypi, and the environment always wins over path markers — so uv tool install users got pipx/pip guidance, whose advice (run pip inside the uv-managed venv) is exactly what uv tells users not to do. Detect the uv layout in the wrapper itself (sys.prefix under /uv/tools/) and report "uv" there. The guidance command was also wrong: uv names tools by their install requirement, so the message now says "uv tool upgrade gitcode-cli" (--from alias installs need their custom name). The symlink-collision hints lacked a uv entry entirely: a uv tool link in ~/.local/bin (the bootstrap fallback directory) fell through to the generic "remove the symlink" advice, which would break the uv channel entry instead of cleanly uninstalling it — add the matching marker with the proper uninstall guidance. Fourth review batch 1, issue 604 items 4 and 6. Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 | |
fix(user): address Round 1 review — re-read after update + json index + secret test Address Round 1 independent review findings (PR #497): Blocker fixes: - C1: UpdateUser now re-reads CurrentUser after PATCH to return complete User object (PATCH response uses nickname/description while User struct uses name/bio; re-reading via GET /user gets the full canonical object) - D1: Add user view to --json read-only commands index - D1: Add user edit to --json write-path commands index - T2/S2: Add TestEditRunSecretScanRejection test (verifies secret in --bio is rejected before HTTP request is made) Doc fixes: - D2/D3: Add ExitAuth(4) to user view and user edit exit codes 13/13 tests pass (12 original + 1 secret scan rejection). Refs gitcode-cli/cli#540 | 2 个月前 | |
fix: repair module import clobbered by URL unification; move recovery contract to the guard script The URL unification commit rewrote every gitcode.com/gitcode-cli/cli occurrence in version.go — including the module import path, which is an identifier, not a URL. The broken build escaped that commit's verification because the scoop json.tool check (which fails on the manifest's legal # comments) short-circuited the && chain before go test ran. Restore the import; the module path stays gitcode.com/gitcode-cli/cli everywhere. The release-workflow contract test asserted the backslide refusal string lived inline in release.yml; the guard moved to scripts/npm-dist-tag-guard.mjs (locked by its own unit tests), so the contract now requires the workflow to invoke the script on both the main publish path and recovery. Co-Authored-By: Claude Code <noreply@anthropic.com> | 1 个月前 |