Commit graph

2 commits

Author SHA1 Message Date
Gergő Magyar
6252aa745f
feat(setup): add CodeBuddy and Qoder coding-agent integrations (#2368)
* feat(setup): add CodeBuddy and Qoder coding-agent integrations

Adds Tencent CodeBuddy and Alibaba Qoder to gitnexus setup/uninstall,
fitted to the editor-targets registry and --coding-agent selection.

- CodeBuddy: MCP entry written into the first existing file of its
  documented priority chain (~/.codebuddy/.mcp.json recommended,
  ~/.codebuddy/mcp.json deprecated, ~/.codebuddy.json legacy) so a
  populated deprecated config is never shadowed; skills to
  ~/.codebuddy/skills/ (https://www.codebuddy.ai/docs/cli/mcp)
- Qoder: MCP entry in ~/.qoder.json, skills to ~/.qoder/skills/
  (https://docs.qoder.com/cli/using-cli, /extensions/skills)
- editor-targets gains optional legacyFiles; uninstall sweeps them
- roster strings updated (CLI help, i18n en/zh-CN, READMEs); en/zh-CN
  setup descriptions were stale (missing Antigravity) and are refreshed

Supersedes and credits PR #1030 by @zykai0302, re-fitted to the
post-#2168 selective-agent architecture with documented config paths.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(cli): assert stable zh-CN setup-description fragment

* fix(setup): surface non-ENOENT config read/stat failures instead of clobbering

* fix(setup): report corrupt legacy MCP files informationally during uninstall

* test(setup): cover multi-candidate uninstall sweep combinations

* fix(setup): detect CodeBuddy/Qoder installs via existing MCP config files

* fix(setup): skip empty and non-file candidates in the MCP config chain

* docs: add CodeBuddy and Qoder manual MCP configuration sections

* test(ci): run the setup-uninstall round-trip in the cross-platform matrix

* fix(setup): never claim "not configured" when uninstall recorded errors

* refactor(cli): share the isEnoent predicate via editor-targets

* refactor(setup): share chain-file install detection between CodeBuddy and Qoder

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 10:54:50 +01:00
Nilotpal Kashyap
1716bf7c1e
feat(cli): add gitnexus uninstall to reverse setup (#2060) (#2062)
* feat(cli): add `gitnexus uninstall` to reverse setup (#2060)

`gitnexus uninstall` was documented in #168 but never implemented, so the
CLI rejected it with "error: unknown command 'uninstall'" (#2060).

Add an `uninstall` command that reverses `gitnexus setup` target-by-target:
removes the GitNexus MCP server entries (Cursor, Claude Code, Antigravity,
OpenCode, Codex), the installed skill directories, and the Claude Code /
Antigravity hook entries plus their bundled hook scripts. Edits are surgical
and idempotent — only gitnexus-owned keys/entries/dirs are touched, and JSONC
comments/indentation are preserved. Defaults to a dry-run preview; `--force`
applies. Per-repo indexes and the global npm package are left alone with
printed hints, since both are destructive in ways setup never caused.

Adds i18n entries (en + zh-CN), help wiring, README/CHANGELOG docs, and unit
tests covering MCP/hook/skill/Codex-TOML removal, dry-run, corrupt-file
safety, and the no-op case.

* changelog changes

* changelog changes

* fix(cli): harden uninstall against data-loss edge cases (review #2062)

Address review findings on the uninstall command:

- Empty derived skill name no longer wipes the whole skills dir: a bare
  '.md' source file would make basename() return '', resolving to the
  skills dir itself. Skip empty names in derivation and reject
  empty/'.'/'..'/separator names in removeSkillsFrom.
- Corrupt settings.json no longer orphans the hook: gate the hook-script
  dir removal on status !== 'corrupt' so we don't delete a script while a
  still-registered entry points at it (Claude + Antigravity blocks).
- Hook removal is now element-granular: delete only the gitnexus command
  inside an entry's hooks[], removing the whole entry only when it becomes
  empty. Preserves a user command co-located in the same entry.
- Fallback TOML stripper: also remove descendant sub-tables
  ([mcp_servers.gitnexus.env]), track multiline strings so a bracketed
  line inside a value isn't treated as a header, and stop reflowing
  unrelated blank lines.
- Set process.exitCode=1 on partial failure; add a 10s timeout to
  'codex mcp remove'.

Tests expanded 7 -> 17: empty-skill guard, corrupt-settings hook
preservation, shared-entry hook removal, OpenCode MCP keyPath,
Antigravity MCP + AfterTool hooks, codex-remove success path, TOML
sub-table + multiline-string cases, dry-run for hooks/skills, and the
directory-layout skill branch.

* refactor(cli): share setup/uninstall target map + harden TOML fallback (review #2062)

Maintainer review follow-ups:

- Extract editor target identities into editor-targets.ts (MCP paths/keyPaths,
  Codex TOML section, skill dirs, hook settings/events/needles/script dirs,
  shared detectIndentation). Both setup.ts and uninstall.ts consume it, so a
  target change updates both sides — killing the silent drift hazard.
- Add a setup -> uninstall round-trip integration test that iterates
  getEditorTargets(): setup writes every target, uninstall removes all of them,
  and a co-located user MCP server + user hook survive. Drift tripwire in both
  directions.
- Preview now prints the exact paths it would remove; command output + README
  state skills are matched by bundled gitnexus skill name. (Provenance marker
  deferred to a tracked follow-up.)

Hardening of the hand-rolled Codex TOML fallback (found in code review):
- Strip a section header that has a trailing inline comment (was matched as a
  header but failed the exact classify check -> section left behind while
  reported removed).
- Preserve CRLF line endings instead of rewriting the whole file to LF.
- Fix multiline-string scan: a line with an odd count of BOTH """ and '''
  no longer mis-picks the delimiter and desyncs the scanner (left->right scan).
- removeSkillsFrom guard also rejects absolute names.

Regression tests added for each. Full setup/uninstall suite green.

---------

Co-authored-by: Gergő Magyar <gergomagyar@icloud.com>
2026-06-09 10:50:18 +01:00