Skip to content

feat: implement extends resolution, --force update, and parent merge in export#55

Open
tianhaocui wants to merge 2 commits intoopen-gitagent:mainfrom
tianhaocui:feat/extends-and-dependency-merge
Open

feat: implement extends resolution, --force update, and parent merge in export#55
tianhaocui wants to merge 2 commits intoopen-gitagent:mainfrom
tianhaocui:feat/extends-and-dependency-merge

Conversation

@tianhaocui
Copy link
Copy Markdown

@tianhaocui tianhaocui commented Mar 30, 2026

What

Implement extends resolution in install, add --force flag for updates, and merge parent agent content in export --format claude-code.

Why

The spec (Section 15: Inheritance) defines extends with clear merge rules, but the implementation was completely missing:

  • extends field is parsed but never acted on — install only handles dependencies
  • install skips if target exists — no way to update without manual rm -rf
  • export only reads current directory — ignores installed parent agent
  • Git source detection hardcoded to github.com — Bitbucket/GitLab repos fail

This means the core cross-project sharing workflow described in the README doesn't work.

Closes #53

How Tested

  • npm run build passes
  • gitagent validate passes on example agents
  • Manual testing (describe below)

Tested with:

  • Bitbucket private repo via SSH (git@bitbucket.org:org/shared-agent.git)
  • extends in child agent.yamlgitagent install clones to .gitagent/parent/
  • gitagent install --force removes and re-clones
  • gitagent export --format claude-code -o CLAUDE.md merges parent SOUL.md, RULES.md, and skills/
  • Child SOUL.md replaces parent, child RULES.md appends to parent, child skills shadow parent

Checklist

  • My code follows the existing style of this project
  • I have added/updated tests (if applicable)
  • I have updated documentation (if applicable)
  • I have read the CONTRIBUTING.md

tianhaocui and others added 2 commits March 30, 2026 17:19
The `export` and `import` commands each registered the same required
option twice (once for gemini, once for codex), causing commander to
throw on startup and making the entire CLI unusable.

Additionally, `case 'codex'` was placed inside the `default` branch
in both switch statements, so it could never be matched correctly.

Changes:
- Merge duplicate `.requiredOption()` calls into a single call listing
  all supported formats
- Move `case 'codex'` out of `default` as an independent case with
  its own `break`

Fixes open-gitagent#53

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The spec (Section 15) defines inheritance via `extends` with clear
merge rules, but the implementation was missing. This commit adds:

1. `install` now resolves `extends` — clones the parent agent repo
   into `.gitagent/parent/` alongside existing dependency handling.

2. `install --force` — removes existing installations before
   re-cloning, enabling updates without manual `rm -rf`.

3. `export --format claude-code` now merges parent content per spec:
   - SOUL.md: child replaces parent entirely
   - RULES.md: parent + child appended (union)
   - skills/: union with child shadowing parent on name collision

4. Git source detection now supports Bitbucket and GitLab URLs
   in addition to GitHub.

Closes open-gitagent#53

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
shreyas-lyzr added a commit that referenced this pull request Apr 3, 2026
… export (#55)

- `gitagent install` now resolves `extends` field — clones parent agent
  to .gitagent/parent/
- `--force` flag removes and re-installs existing deps/parent
- `gitagent export -f claude-code` merges parent content:
  - SOUL.md: child replaces parent
  - RULES.md: parent + child appended (union)
  - skills/: parent skills copied where child doesn't shadow
- Git source detection supports GitHub, Bitbucket, and GitLab
- Security: uses execFileSync (not execSync) and cpSync (not cp -r shell)
@shreyas-lyzr
Copy link
Copy Markdown
Contributor

Reviewed and merged with fixes.

What was good:

  • extends resolution is a meaningful feature — the spec defined it but it was never implemented
  • Merge rules are correct per spec Section 15 (child SOUL replaces parent, child RULES appends, skills union with child shadowing)
  • --force flag is useful for updates
  • isGitSource() supporting GitHub, Bitbucket, and GitLab is a good broadening

Fixes applied before merge:

  1. Command injectioncloneGitRepo used execSync with string interpolation (\git clone ... "${source}"`). Replaced with execFileSync('git', [...args])` per the security fix in PR fix: replace execSync string interpolation with execFileSync to prevent command injection #48.
  2. Shell cp -r calls — Two execSync(\cp -r ...`)calls replaced withcpSync()` (same fix pattern as PR fix: replace execSync string interpolation with execFileSync to prevent command injection #48).
  3. export.ts / import.ts skipped — These changes overlapped with the already-merged PR fix(issue,53): fixed duplicated required options in export and import #60 fix. Only install.ts and claude-code.ts were taken from this PR.

Note for future work:

  • Parent merge only applies to claude-code export. Other adapters (system-prompt, cursor, opencode, etc.) don't resolve extends. This should be generalized — probably at the loader level rather than per-adapter.
  • No tests included. Would be good to add tests for extends resolution.

Thanks @tianhaocui!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] CLI crashes on startup: duplicate option registration in export.js and import.js

2 participants