@jahanxu/trellis 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +235 -0
- package/README.md +212 -0
- package/bin/trellis.js +3 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +97 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/init.d.ts +21 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +527 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/update.d.ts +27 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +1289 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/configurators/antigravity.d.ts +8 -0
- package/dist/configurators/antigravity.d.ts.map +1 -0
- package/dist/configurators/antigravity.js +18 -0
- package/dist/configurators/antigravity.js.map +1 -0
- package/dist/configurators/claude.d.ts +32 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +98 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/codex.d.ts +8 -0
- package/dist/configurators/codex.d.ts.map +1 -0
- package/dist/configurators/codex.js +20 -0
- package/dist/configurators/codex.js.map +1 -0
- package/dist/configurators/cursor.d.ts +5 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +52 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/gemini.d.ts +8 -0
- package/dist/configurators/gemini.d.ts.map +1 -0
- package/dist/configurators/gemini.js +52 -0
- package/dist/configurators/gemini.js.map +1 -0
- package/dist/configurators/iflow.d.ts +33 -0
- package/dist/configurators/iflow.d.ts.map +1 -0
- package/dist/configurators/iflow.js +99 -0
- package/dist/configurators/iflow.js.map +1 -0
- package/dist/configurators/index.d.ts +55 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +220 -0
- package/dist/configurators/index.js.map +1 -0
- package/dist/configurators/kilo.d.ts +8 -0
- package/dist/configurators/kilo.d.ts.map +1 -0
- package/dist/configurators/kilo.js +51 -0
- package/dist/configurators/kilo.js.map +1 -0
- package/dist/configurators/kiro.d.ts +8 -0
- package/dist/configurators/kiro.d.ts.map +1 -0
- package/dist/configurators/kiro.js +20 -0
- package/dist/configurators/kiro.js.map +1 -0
- package/dist/configurators/opencode.d.ts +32 -0
- package/dist/configurators/opencode.d.ts.map +1 -0
- package/dist/configurators/opencode.js +92 -0
- package/dist/configurators/opencode.js.map +1 -0
- package/dist/configurators/shared.d.ts +12 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +21 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/workflow.d.ts +28 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +134 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +68 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +77 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/constants/version.d.ts +9 -0
- package/dist/constants/version.d.ts.map +1 -0
- package/dist/constants/version.js +15 -0
- package/dist/constants/version.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/migrations/index.d.ts +54 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +160 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/manifests/0.1.9.json +30 -0
- package/dist/migrations/manifests/0.2.0.json +49 -0
- package/dist/migrations/manifests/0.2.12.json +9 -0
- package/dist/migrations/manifests/0.2.13.json +9 -0
- package/dist/migrations/manifests/0.2.14.json +175 -0
- package/dist/migrations/manifests/0.2.15.json +33 -0
- package/dist/migrations/manifests/0.3.0-beta.0.json +278 -0
- package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
- package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.3.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.3.0.json +11 -0
- package/dist/templates/antigravity/index.d.ts +12 -0
- package/dist/templates/antigravity/index.d.ts.map +1 -0
- package/dist/templates/antigravity/index.js +29 -0
- package/dist/templates/antigravity/index.js.map +1 -0
- package/dist/templates/claude/agents/check.md +122 -0
- package/dist/templates/claude/agents/debug.md +106 -0
- package/dist/templates/claude/agents/dispatch.md +214 -0
- package/dist/templates/claude/agents/implement.md +96 -0
- package/dist/templates/claude/agents/plan.md +396 -0
- package/dist/templates/claude/agents/research.md +120 -0
- package/dist/templates/claude/commands/trellis/before-backend-dev.md +13 -0
- package/dist/templates/claude/commands/trellis/before-frontend-dev.md +13 -0
- package/dist/templates/claude/commands/trellis/before-role-work.md +364 -0
- package/dist/templates/claude/commands/trellis/brainstorm.md +474 -0
- package/dist/templates/claude/commands/trellis/break-loop.md +125 -0
- package/dist/templates/claude/commands/trellis/check-backend.md +13 -0
- package/dist/templates/claude/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/claude/commands/trellis/check-frontend.md +13 -0
- package/dist/templates/claude/commands/trellis/create-command.md +154 -0
- package/dist/templates/claude/commands/trellis/finish-work.md +153 -0
- package/dist/templates/claude/commands/trellis/handoff.md +445 -0
- package/dist/templates/claude/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/claude/commands/trellis/onboard.md +358 -0
- package/dist/templates/claude/commands/trellis/parallel.md +193 -0
- package/dist/templates/claude/commands/trellis/pick-task.md +515 -0
- package/dist/templates/claude/commands/trellis/record-session.md +62 -0
- package/dist/templates/claude/commands/trellis/start.md +373 -0
- package/dist/templates/claude/commands/trellis/update-spec.md +354 -0
- package/dist/templates/claude/hooks/inject-subagent-context.py +873 -0
- package/dist/templates/claude/hooks/ralph-loop.py +388 -0
- package/dist/templates/claude/hooks/session-start.py +200 -0
- package/dist/templates/claude/index.d.ts +54 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +85 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +41 -0
- package/dist/templates/codex/index.d.ts +18 -0
- package/dist/templates/codex/index.d.ts.map +1 -0
- package/dist/templates/codex/index.js +40 -0
- package/dist/templates/codex/index.js.map +1 -0
- package/dist/templates/codex/skills/before-backend-dev/SKILL.md +18 -0
- package/dist/templates/codex/skills/before-frontend-dev/SKILL.md +18 -0
- package/dist/templates/codex/skills/brainstorm/SKILL.md +479 -0
- package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
- package/dist/templates/codex/skills/check-backend/SKILL.md +18 -0
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
- package/dist/templates/codex/skills/check-frontend/SKILL.md +18 -0
- package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
- package/dist/templates/codex/skills/finish-work/SKILL.md +148 -0
- package/dist/templates/codex/skills/integrate-skill/SKILL.md +221 -0
- package/dist/templates/codex/skills/onboard/SKILL.md +363 -0
- package/dist/templates/codex/skills/record-session/SKILL.md +67 -0
- package/dist/templates/codex/skills/start/SKILL.md +330 -0
- package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
- package/dist/templates/cursor/commands/trellis-before-backend-dev.md +13 -0
- package/dist/templates/cursor/commands/trellis-before-frontend-dev.md +13 -0
- package/dist/templates/cursor/commands/trellis-brainstorm.md +474 -0
- package/dist/templates/cursor/commands/trellis-break-loop.md +107 -0
- package/dist/templates/cursor/commands/trellis-check-backend.md +13 -0
- package/dist/templates/cursor/commands/trellis-check-cross-layer.md +153 -0
- package/dist/templates/cursor/commands/trellis-check-frontend.md +13 -0
- package/dist/templates/cursor/commands/trellis-create-command.md +154 -0
- package/dist/templates/cursor/commands/trellis-finish-work.md +143 -0
- package/dist/templates/cursor/commands/trellis-integrate-skill.md +219 -0
- package/dist/templates/cursor/commands/trellis-onboard.md +358 -0
- package/dist/templates/cursor/commands/trellis-record-session.md +62 -0
- package/dist/templates/cursor/commands/trellis-start.md +366 -0
- package/dist/templates/cursor/commands/trellis-update-spec.md +354 -0
- package/dist/templates/cursor/index.d.ts +24 -0
- package/dist/templates/cursor/index.d.ts.map +1 -0
- package/dist/templates/cursor/index.js +44 -0
- package/dist/templates/cursor/index.js.map +1 -0
- package/dist/templates/extract.d.ts +166 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +296 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/gemini/commands/trellis/before-backend-dev.toml +17 -0
- package/dist/templates/gemini/commands/trellis/before-frontend-dev.toml +17 -0
- package/dist/templates/gemini/commands/trellis/brainstorm.toml +420 -0
- package/dist/templates/gemini/commands/trellis/break-loop.toml +129 -0
- package/dist/templates/gemini/commands/trellis/check-backend.toml +17 -0
- package/dist/templates/gemini/commands/trellis/check-cross-layer.toml +147 -0
- package/dist/templates/gemini/commands/trellis/check-frontend.toml +17 -0
- package/dist/templates/gemini/commands/trellis/create-command.toml +119 -0
- package/dist/templates/gemini/commands/trellis/finish-work.toml +133 -0
- package/dist/templates/gemini/commands/trellis/integrate-skill.toml +104 -0
- package/dist/templates/gemini/commands/trellis/onboard.toml +111 -0
- package/dist/templates/gemini/commands/trellis/record-session.toml +66 -0
- package/dist/templates/gemini/commands/trellis/start.toml +292 -0
- package/dist/templates/gemini/commands/trellis/update-spec.toml +132 -0
- package/dist/templates/gemini/index.d.ts +21 -0
- package/dist/templates/gemini/index.d.ts.map +1 -0
- package/dist/templates/gemini/index.js +44 -0
- package/dist/templates/gemini/index.js.map +1 -0
- package/dist/templates/iflow/agents/check.md +122 -0
- package/dist/templates/iflow/agents/debug.md +106 -0
- package/dist/templates/iflow/agents/dispatch.md +214 -0
- package/dist/templates/iflow/agents/implement.md +96 -0
- package/dist/templates/iflow/agents/plan.md +396 -0
- package/dist/templates/iflow/agents/research.md +120 -0
- package/dist/templates/iflow/commands/trellis/before-backend-dev.md +13 -0
- package/dist/templates/iflow/commands/trellis/before-frontend-dev.md +13 -0
- package/dist/templates/iflow/commands/trellis/brainstorm.md +474 -0
- package/dist/templates/iflow/commands/trellis/break-loop.md +125 -0
- package/dist/templates/iflow/commands/trellis/check-backend.md +13 -0
- package/dist/templates/iflow/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/iflow/commands/trellis/check-frontend.md +13 -0
- package/dist/templates/iflow/commands/trellis/create-command.md +152 -0
- package/dist/templates/iflow/commands/trellis/finish-work.md +153 -0
- package/dist/templates/iflow/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/iflow/commands/trellis/onboard.md +358 -0
- package/dist/templates/iflow/commands/trellis/parallel.md +193 -0
- package/dist/templates/iflow/commands/trellis/record-session.md +62 -0
- package/dist/templates/iflow/commands/trellis/start.md +373 -0
- package/dist/templates/iflow/commands/trellis/update-spec.md +354 -0
- package/dist/templates/iflow/hooks/inject-subagent-context.py +788 -0
- package/dist/templates/iflow/hooks/ralph-loop.py +388 -0
- package/dist/templates/iflow/hooks/session-start.py +143 -0
- package/dist/templates/iflow/index.d.ts +54 -0
- package/dist/templates/iflow/index.d.ts.map +1 -0
- package/dist/templates/iflow/index.js +85 -0
- package/dist/templates/iflow/index.js.map +1 -0
- package/dist/templates/iflow/settings.json +40 -0
- package/dist/templates/kilo/commands/trellis/before-backend-dev.md +13 -0
- package/dist/templates/kilo/commands/trellis/before-frontend-dev.md +13 -0
- package/dist/templates/kilo/commands/trellis/brainstorm.md +474 -0
- package/dist/templates/kilo/commands/trellis/break-loop.md +125 -0
- package/dist/templates/kilo/commands/trellis/check-backend.md +13 -0
- package/dist/templates/kilo/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/kilo/commands/trellis/check-frontend.md +13 -0
- package/dist/templates/kilo/commands/trellis/create-command.md +152 -0
- package/dist/templates/kilo/commands/trellis/finish-work.md +129 -0
- package/dist/templates/kilo/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/kilo/commands/trellis/onboard.md +358 -0
- package/dist/templates/kilo/commands/trellis/parallel.md +194 -0
- package/dist/templates/kilo/commands/trellis/record-session.md +62 -0
- package/dist/templates/kilo/commands/trellis/start.md +321 -0
- package/dist/templates/kilo/commands/trellis/update-spec.md +285 -0
- package/dist/templates/kilo/index.d.ts +16 -0
- package/dist/templates/kilo/index.d.ts.map +1 -0
- package/dist/templates/kilo/index.js +39 -0
- package/dist/templates/kilo/index.js.map +1 -0
- package/dist/templates/kiro/index.d.ts +18 -0
- package/dist/templates/kiro/index.d.ts.map +1 -0
- package/dist/templates/kiro/index.js +40 -0
- package/dist/templates/kiro/index.js.map +1 -0
- package/dist/templates/kiro/skills/before-backend-dev/SKILL.md +18 -0
- package/dist/templates/kiro/skills/before-frontend-dev/SKILL.md +18 -0
- package/dist/templates/kiro/skills/brainstorm/SKILL.md +479 -0
- package/dist/templates/kiro/skills/break-loop/SKILL.md +130 -0
- package/dist/templates/kiro/skills/check-backend/SKILL.md +18 -0
- package/dist/templates/kiro/skills/check-cross-layer/SKILL.md +158 -0
- package/dist/templates/kiro/skills/check-frontend/SKILL.md +18 -0
- package/dist/templates/kiro/skills/create-command/SKILL.md +101 -0
- package/dist/templates/kiro/skills/finish-work/SKILL.md +148 -0
- package/dist/templates/kiro/skills/integrate-skill/SKILL.md +221 -0
- package/dist/templates/kiro/skills/onboard/SKILL.md +363 -0
- package/dist/templates/kiro/skills/record-session/SKILL.md +67 -0
- package/dist/templates/kiro/skills/start/SKILL.md +330 -0
- package/dist/templates/kiro/skills/update-spec/SKILL.md +335 -0
- package/dist/templates/markdown/agents.md +18 -0
- package/dist/templates/markdown/gitignore.txt +12 -0
- package/dist/templates/markdown/index.d.ts +27 -0
- package/dist/templates/markdown/index.d.ts.map +1 -0
- package/dist/templates/markdown/index.js +52 -0
- package/dist/templates/markdown/index.js.map +1 -0
- package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/index.md +40 -0
- package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
- package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/backend/script-conventions.md +467 -0
- package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
- package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
- package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
- package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
- package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +118 -0
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +92 -0
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +94 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +394 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +319 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +79 -0
- package/dist/templates/markdown/workspace-index.md +123 -0
- package/dist/templates/markdown/worktree.yaml.txt +58 -0
- package/dist/templates/opencode/agents/check.md +146 -0
- package/dist/templates/opencode/agents/debug.md +129 -0
- package/dist/templates/opencode/agents/dispatch.md +223 -0
- package/dist/templates/opencode/agents/implement.md +120 -0
- package/dist/templates/opencode/agents/research.md +147 -0
- package/dist/templates/opencode/agents/trellis-plan.md +427 -0
- package/dist/templates/opencode/commands/trellis/before-backend-dev.md +13 -0
- package/dist/templates/opencode/commands/trellis/before-frontend-dev.md +13 -0
- package/dist/templates/opencode/commands/trellis/brainstorm.md +474 -0
- package/dist/templates/opencode/commands/trellis/break-loop.md +125 -0
- package/dist/templates/opencode/commands/trellis/check-backend.md +13 -0
- package/dist/templates/opencode/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/opencode/commands/trellis/check-frontend.md +13 -0
- package/dist/templates/opencode/commands/trellis/create-command.md +154 -0
- package/dist/templates/opencode/commands/trellis/finish-work.md +144 -0
- package/dist/templates/opencode/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/opencode/commands/trellis/migrate-specs.md +0 -0
- package/dist/templates/opencode/commands/trellis/onboard.md +358 -0
- package/dist/templates/opencode/commands/trellis/parallel.md +194 -0
- package/dist/templates/opencode/commands/trellis/record-session.md +62 -0
- package/dist/templates/opencode/commands/trellis/start.md +338 -0
- package/dist/templates/opencode/commands/trellis/update-spec.md +354 -0
- package/dist/templates/opencode/lib/trellis-context.js +436 -0
- package/dist/templates/opencode/package.json +5 -0
- package/dist/templates/opencode/plugin/inject-subagent-context.js +538 -0
- package/dist/templates/opencode/plugin/session-start.js +192 -0
- package/dist/templates/trellis/VERSION +1 -0
- package/dist/templates/trellis/deliverables/README.md +51 -0
- package/dist/templates/trellis/gitignore.txt +29 -0
- package/dist/templates/trellis/index.d.ts +49 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +92 -0
- package/dist/templates/trellis/index.js.map +1 -0
- package/dist/templates/trellis/paths.README.md +277 -0
- package/dist/templates/trellis/paths.yaml +41 -0
- package/dist/templates/trellis/pool/implementations.json +5 -0
- package/dist/templates/trellis/pool/prototypes.json +5 -0
- package/dist/templates/trellis/pool/requirements.json +5 -0
- package/dist/templates/trellis/scripts/__init__.py +5 -0
- package/dist/templates/trellis/scripts/add_session.py +391 -0
- package/dist/templates/trellis/scripts/common/__init__.py +80 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +522 -0
- package/dist/templates/trellis/scripts/common/developer.py +189 -0
- package/dist/templates/trellis/scripts/common/git_context.py +383 -0
- package/dist/templates/trellis/scripts/common/paths.py +346 -0
- package/dist/templates/trellis/scripts/common/phase.py +253 -0
- package/dist/templates/trellis/scripts/common/project_paths.py +189 -0
- package/dist/templates/trellis/scripts/common/registry.py +365 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +255 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +177 -0
- package/dist/templates/trellis/scripts/common/worktree.py +218 -0
- package/dist/templates/trellis/scripts/create_bootstrap.py +290 -0
- package/dist/templates/trellis/scripts/get_context.py +16 -0
- package/dist/templates/trellis/scripts/get_developer.py +26 -0
- package/dist/templates/trellis/scripts/handoff_generator.py +380 -0
- package/dist/templates/trellis/scripts/init_developer.py +51 -0
- package/dist/templates/trellis/scripts/multi_agent/__init__.py +5 -0
- package/dist/templates/trellis/scripts/multi_agent/cleanup.py +403 -0
- package/dist/templates/trellis/scripts/multi_agent/create_pr.py +329 -0
- package/dist/templates/trellis/scripts/multi_agent/plan.py +233 -0
- package/dist/templates/trellis/scripts/multi_agent/start.py +461 -0
- package/dist/templates/trellis/scripts/multi_agent/status.py +817 -0
- package/dist/templates/trellis/scripts/pool.py +373 -0
- package/dist/templates/trellis/scripts/task.py +1162 -0
- package/dist/templates/trellis/scripts-shell-archive/add-session.sh +384 -0
- package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +129 -0
- package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +263 -0
- package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +208 -0
- package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +150 -0
- package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +247 -0
- package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +142 -0
- package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +151 -0
- package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +128 -0
- package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +299 -0
- package/dist/templates/trellis/scripts-shell-archive/get-context.sh +7 -0
- package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +15 -0
- package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +34 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +396 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +241 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +207 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +317 -0
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +828 -0
- package/dist/templates/trellis/scripts-shell-archive/task.sh +1204 -0
- package/dist/templates/trellis/spec/roles/designer/index.md +243 -0
- package/dist/templates/trellis/spec/roles/designer/mock-data-standards.md +481 -0
- package/dist/templates/trellis/spec/roles/designer/prototype-guidelines.md +429 -0
- package/dist/templates/trellis/spec/roles/frontend-impl/api-integration.md +565 -0
- package/dist/templates/trellis/spec/roles/frontend-impl/index.md +321 -0
- package/dist/templates/trellis/spec/roles/frontend-impl/state-management.md +599 -0
- package/dist/templates/trellis/spec/roles/pm/index.md +112 -0
- package/dist/templates/trellis/spec/roles/pm/prd-template.md +124 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +416 -0
- package/dist/templates/trellis/worktree.yaml +47 -0
- package/dist/types/ai-tools.d.ts +56 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +103 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/types/migration.d.ts +86 -0
- package/dist/types/migration.d.ts.map +1 -0
- package/dist/types/migration.js +8 -0
- package/dist/types/migration.js.map +1 -0
- package/dist/utils/compare-versions.d.ts +12 -0
- package/dist/utils/compare-versions.d.ts.map +1 -0
- package/dist/utils/compare-versions.js +76 -0
- package/dist/utils/compare-versions.js.map +1 -0
- package/dist/utils/file-writer.d.ts +23 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +140 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/project-detector.d.ts +16 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +186 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +51 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +174 -0
- package/dist/utils/template-fetcher.js.map +1 -0
- package/dist/utils/template-hash.d.ts +78 -0
- package/dist/utils/template-hash.d.ts.map +1 -0
- package/dist/utils/template-hash.js +233 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Project-specific path configuration loader.
|
|
4
|
+
|
|
5
|
+
Reads .trellis/paths.yaml to get project-specific directory structure.
|
|
6
|
+
Falls back to defaults if config file doesn't exist.
|
|
7
|
+
|
|
8
|
+
This separates framework layer from business layer, allowing different
|
|
9
|
+
projects to use different directory structures.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from typing import Optional, Dict
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
import yaml
|
|
18
|
+
HAS_YAML = True
|
|
19
|
+
except ImportError:
|
|
20
|
+
HAS_YAML = False
|
|
21
|
+
|
|
22
|
+
# =============================================================================
|
|
23
|
+
# Default Configuration (Framework Layer)
|
|
24
|
+
# =============================================================================
|
|
25
|
+
|
|
26
|
+
DEFAULT_CONFIG = {
|
|
27
|
+
"deliverables_base": "deliverables",
|
|
28
|
+
"role_outputs": {
|
|
29
|
+
"pm": {"dir": "requirements"},
|
|
30
|
+
"designer": {"dir": "prototypes"},
|
|
31
|
+
"frontend": {"dir": "production/features"},
|
|
32
|
+
},
|
|
33
|
+
"pools": {
|
|
34
|
+
"pm": "requirements",
|
|
35
|
+
"designer": "prototypes",
|
|
36
|
+
"frontend": "implementations",
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# =============================================================================
|
|
41
|
+
# Configuration Loader
|
|
42
|
+
# =============================================================================
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def load_paths_config(repo_root: Path) -> Dict:
|
|
46
|
+
"""Load paths configuration from .trellis/paths.yaml.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
repo_root: Repository root path
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Configuration dict with paths
|
|
53
|
+
"""
|
|
54
|
+
config_file = repo_root / ".trellis" / "paths.yaml"
|
|
55
|
+
|
|
56
|
+
# If config file doesn't exist, use defaults
|
|
57
|
+
if not config_file.exists():
|
|
58
|
+
return DEFAULT_CONFIG.copy()
|
|
59
|
+
|
|
60
|
+
# If yaml not available, use defaults
|
|
61
|
+
if not HAS_YAML:
|
|
62
|
+
print(
|
|
63
|
+
"Warning: PyYAML not installed, using default paths. "
|
|
64
|
+
"Install with: pip install pyyaml",
|
|
65
|
+
file=sys.stderr,
|
|
66
|
+
)
|
|
67
|
+
return DEFAULT_CONFIG.copy()
|
|
68
|
+
|
|
69
|
+
# Load config from yaml
|
|
70
|
+
try:
|
|
71
|
+
with open(config_file, "r", encoding="utf-8") as f:
|
|
72
|
+
config = yaml.safe_load(f) or {}
|
|
73
|
+
|
|
74
|
+
# Merge with defaults (in case some keys are missing)
|
|
75
|
+
merged = DEFAULT_CONFIG.copy()
|
|
76
|
+
merged.update(config)
|
|
77
|
+
|
|
78
|
+
# Ensure role_outputs has all roles
|
|
79
|
+
for role in ["pm", "designer", "frontend"]:
|
|
80
|
+
if role not in merged["role_outputs"]:
|
|
81
|
+
merged["role_outputs"][role] = DEFAULT_CONFIG["role_outputs"][role]
|
|
82
|
+
|
|
83
|
+
return merged
|
|
84
|
+
except Exception as e:
|
|
85
|
+
print(
|
|
86
|
+
f"Warning: Failed to load {config_file}: {e}. Using defaults.",
|
|
87
|
+
file=sys.stderr,
|
|
88
|
+
)
|
|
89
|
+
return DEFAULT_CONFIG.copy()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_deliverables_base(repo_root: Path) -> str:
|
|
93
|
+
"""Get deliverables base directory.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
repo_root: Repository root path
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Deliverables base directory name
|
|
100
|
+
"""
|
|
101
|
+
config = load_paths_config(repo_root)
|
|
102
|
+
return config.get("deliverables_base", "deliverables")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def get_role_output_dir(repo_root: Path, role: str) -> str:
|
|
106
|
+
"""Get output directory for a specific role.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
repo_root: Repository root path
|
|
110
|
+
role: Role name (pm, designer, frontend)
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Full output directory path (relative to repo_root)
|
|
114
|
+
"""
|
|
115
|
+
config = load_paths_config(repo_root)
|
|
116
|
+
base = config.get("deliverables_base", "deliverables")
|
|
117
|
+
role_config = config.get("role_outputs", {}).get(role, {})
|
|
118
|
+
role_dir = role_config.get("dir", "")
|
|
119
|
+
|
|
120
|
+
if not role_dir:
|
|
121
|
+
# Fallback to default
|
|
122
|
+
role_dir = DEFAULT_CONFIG["role_outputs"].get(role, {}).get("dir", "")
|
|
123
|
+
|
|
124
|
+
return f"{base}/{role_dir}"
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def get_pool_name(role: str) -> str:
|
|
128
|
+
"""Get pool name for a specific role.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
role: Role name (pm, designer, frontend)
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Pool name (e.g., 'requirements', 'prototypes', 'implementations')
|
|
135
|
+
"""
|
|
136
|
+
# Pool names are usually fixed in framework layer
|
|
137
|
+
# But can be overridden in config if needed
|
|
138
|
+
return DEFAULT_CONFIG["pools"].get(role, role)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_output_dir_for_task(repo_root: Path, role: str, task_id: str) -> str:
|
|
142
|
+
"""Get complete output directory for a specific task.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
repo_root: Repository root path
|
|
146
|
+
role: Role name (pm, designer, frontend)
|
|
147
|
+
task_id: Task ID
|
|
148
|
+
|
|
149
|
+
Returns:
|
|
150
|
+
Full output directory path (e.g., "deliverables/requirements/user-login")
|
|
151
|
+
"""
|
|
152
|
+
role_dir = get_role_output_dir(repo_root, role)
|
|
153
|
+
return f"{role_dir}/{task_id}"
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
# =============================================================================
|
|
157
|
+
# CLI for testing
|
|
158
|
+
# =============================================================================
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def main():
|
|
162
|
+
"""Test configuration loading."""
|
|
163
|
+
# Add parent directory to path for imports
|
|
164
|
+
sys.path.insert(0, str(Path(__file__).parent))
|
|
165
|
+
from paths import get_repo_root
|
|
166
|
+
|
|
167
|
+
repo_root = get_repo_root()
|
|
168
|
+
config = load_paths_config(repo_root)
|
|
169
|
+
|
|
170
|
+
print("=== Loaded Configuration ===")
|
|
171
|
+
print(f"Deliverables base: {config['deliverables_base']}")
|
|
172
|
+
print("\nRole output directories:")
|
|
173
|
+
for role in ["pm", "designer", "frontend"]:
|
|
174
|
+
full_path = get_role_output_dir(repo_root, role)
|
|
175
|
+
print(f" {role}: {full_path}")
|
|
176
|
+
|
|
177
|
+
print("\nPool names:")
|
|
178
|
+
for role in ["pm", "designer", "frontend"]:
|
|
179
|
+
pool = get_pool_name(role)
|
|
180
|
+
print(f" {role}: {pool}")
|
|
181
|
+
|
|
182
|
+
print("\nExample output paths:")
|
|
183
|
+
for role in ["pm", "designer", "frontend"]:
|
|
184
|
+
path = get_output_dir_for_task(repo_root, role, "user-login")
|
|
185
|
+
print(f" {role}/user-login: {path}")
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
if __name__ == "__main__":
|
|
189
|
+
main()
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Registry utility functions for multi-agent pipeline.
|
|
4
|
+
|
|
5
|
+
Provides:
|
|
6
|
+
registry_get_file - Get registry file path
|
|
7
|
+
registry_get_agent_by_id - Find agent by ID
|
|
8
|
+
registry_get_agent_by_worktree - Find agent by worktree path
|
|
9
|
+
registry_get_task_dir - Get task dir for a worktree
|
|
10
|
+
registry_remove_by_id - Remove agent by ID
|
|
11
|
+
registry_remove_by_worktree - Remove agent by worktree path
|
|
12
|
+
registry_add_agent - Add agent to registry
|
|
13
|
+
registry_search_agent - Search agent by ID or task_dir
|
|
14
|
+
registry_list_agents - List all agents
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
import json
|
|
19
|
+
from datetime import datetime
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from .paths import get_repo_root
|
|
23
|
+
from .worktree import get_agents_dir
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _read_json_file(path: Path) -> Optional[dict]:
|
|
27
|
+
"""Read and parse a JSON file."""
|
|
28
|
+
try:
|
|
29
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
30
|
+
except (FileNotFoundError, json.JSONDecodeError, OSError):
|
|
31
|
+
return None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _write_json_file(path: Path, data: dict) -> bool:
|
|
35
|
+
"""Write dict to JSON file."""
|
|
36
|
+
try:
|
|
37
|
+
path.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
38
|
+
return True
|
|
39
|
+
except (OSError, IOError):
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# =============================================================================
|
|
44
|
+
# Registry File Access
|
|
45
|
+
# =============================================================================
|
|
46
|
+
|
|
47
|
+
def registry_get_file(repo_root: Optional[Path] = None) -> Optional[Path]:
|
|
48
|
+
"""Get registry file path.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
52
|
+
|
|
53
|
+
Returns:
|
|
54
|
+
Path to registry.json, or None if agents dir not found.
|
|
55
|
+
"""
|
|
56
|
+
if repo_root is None:
|
|
57
|
+
repo_root = get_repo_root()
|
|
58
|
+
|
|
59
|
+
agents_dir = get_agents_dir(repo_root)
|
|
60
|
+
if agents_dir:
|
|
61
|
+
return agents_dir / "registry.json"
|
|
62
|
+
return None
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _ensure_registry(repo_root: Optional[Path] = None) -> Optional[Path]:
|
|
66
|
+
"""Ensure registry file exists with valid structure.
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Path to registry file, or None if cannot create.
|
|
73
|
+
"""
|
|
74
|
+
if repo_root is None:
|
|
75
|
+
repo_root = get_repo_root()
|
|
76
|
+
|
|
77
|
+
registry_file = registry_get_file(repo_root)
|
|
78
|
+
if not registry_file:
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
agents_dir = registry_file.parent
|
|
82
|
+
|
|
83
|
+
try:
|
|
84
|
+
agents_dir.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
|
|
86
|
+
if not registry_file.exists():
|
|
87
|
+
_write_json_file(registry_file, {"agents": []})
|
|
88
|
+
|
|
89
|
+
return registry_file
|
|
90
|
+
except (OSError, IOError):
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# =============================================================================
|
|
95
|
+
# Agent Lookup
|
|
96
|
+
# =============================================================================
|
|
97
|
+
|
|
98
|
+
def registry_get_agent_by_id(
|
|
99
|
+
agent_id: str,
|
|
100
|
+
repo_root: Optional[Path] = None
|
|
101
|
+
) -> Optional[dict]:
|
|
102
|
+
"""Get agent by ID.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
agent_id: Agent ID.
|
|
106
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
Agent dict, or None if not found.
|
|
110
|
+
"""
|
|
111
|
+
if repo_root is None:
|
|
112
|
+
repo_root = get_repo_root()
|
|
113
|
+
|
|
114
|
+
registry_file = registry_get_file(repo_root)
|
|
115
|
+
if not registry_file or not registry_file.is_file():
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
data = _read_json_file(registry_file)
|
|
119
|
+
if not data:
|
|
120
|
+
return None
|
|
121
|
+
|
|
122
|
+
for agent in data.get("agents", []):
|
|
123
|
+
if agent.get("id") == agent_id:
|
|
124
|
+
return agent
|
|
125
|
+
|
|
126
|
+
return None
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def registry_get_agent_by_worktree(
|
|
130
|
+
worktree_path: str,
|
|
131
|
+
repo_root: Optional[Path] = None
|
|
132
|
+
) -> Optional[dict]:
|
|
133
|
+
"""Get agent by worktree path.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
worktree_path: Worktree path.
|
|
137
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
Agent dict, or None if not found.
|
|
141
|
+
"""
|
|
142
|
+
if repo_root is None:
|
|
143
|
+
repo_root = get_repo_root()
|
|
144
|
+
|
|
145
|
+
registry_file = registry_get_file(repo_root)
|
|
146
|
+
if not registry_file or not registry_file.is_file():
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
data = _read_json_file(registry_file)
|
|
150
|
+
if not data:
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
for agent in data.get("agents", []):
|
|
154
|
+
if agent.get("worktree_path") == worktree_path:
|
|
155
|
+
return agent
|
|
156
|
+
|
|
157
|
+
return None
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def registry_search_agent(
|
|
161
|
+
search: str,
|
|
162
|
+
repo_root: Optional[Path] = None
|
|
163
|
+
) -> Optional[dict]:
|
|
164
|
+
"""Search agent by ID or task_dir containing search term.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
search: Search term.
|
|
168
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
First matching agent dict, or None if not found.
|
|
172
|
+
"""
|
|
173
|
+
if repo_root is None:
|
|
174
|
+
repo_root = get_repo_root()
|
|
175
|
+
|
|
176
|
+
registry_file = registry_get_file(repo_root)
|
|
177
|
+
if not registry_file or not registry_file.is_file():
|
|
178
|
+
return None
|
|
179
|
+
|
|
180
|
+
data = _read_json_file(registry_file)
|
|
181
|
+
if not data:
|
|
182
|
+
return None
|
|
183
|
+
|
|
184
|
+
for agent in data.get("agents", []):
|
|
185
|
+
# Exact ID match
|
|
186
|
+
if agent.get("id") == search:
|
|
187
|
+
return agent
|
|
188
|
+
# Partial match on task_dir
|
|
189
|
+
task_dir = agent.get("task_dir", "")
|
|
190
|
+
if search in task_dir:
|
|
191
|
+
return agent
|
|
192
|
+
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def registry_get_task_dir(
|
|
197
|
+
worktree_path: str,
|
|
198
|
+
repo_root: Optional[Path] = None
|
|
199
|
+
) -> Optional[str]:
|
|
200
|
+
"""Get task directory for a worktree.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
worktree_path: Worktree path.
|
|
204
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
Task directory path, or None if not found.
|
|
208
|
+
"""
|
|
209
|
+
agent = registry_get_agent_by_worktree(worktree_path, repo_root)
|
|
210
|
+
if agent:
|
|
211
|
+
return agent.get("task_dir")
|
|
212
|
+
return None
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# =============================================================================
|
|
216
|
+
# Agent Modification
|
|
217
|
+
# =============================================================================
|
|
218
|
+
|
|
219
|
+
def registry_remove_by_id(agent_id: str, repo_root: Optional[Path] = None) -> bool:
|
|
220
|
+
"""Remove agent by ID.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
agent_id: Agent ID.
|
|
224
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
True on success.
|
|
228
|
+
"""
|
|
229
|
+
if repo_root is None:
|
|
230
|
+
repo_root = get_repo_root()
|
|
231
|
+
|
|
232
|
+
registry_file = registry_get_file(repo_root)
|
|
233
|
+
if not registry_file or not registry_file.is_file():
|
|
234
|
+
return True # Nothing to remove
|
|
235
|
+
|
|
236
|
+
data = _read_json_file(registry_file)
|
|
237
|
+
if not data:
|
|
238
|
+
return True
|
|
239
|
+
|
|
240
|
+
agents = data.get("agents", [])
|
|
241
|
+
data["agents"] = [a for a in agents if a.get("id") != agent_id]
|
|
242
|
+
|
|
243
|
+
return _write_json_file(registry_file, data)
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def registry_remove_by_worktree(
|
|
247
|
+
worktree_path: str,
|
|
248
|
+
repo_root: Optional[Path] = None
|
|
249
|
+
) -> bool:
|
|
250
|
+
"""Remove agent by worktree path.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
worktree_path: Worktree path.
|
|
254
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
255
|
+
|
|
256
|
+
Returns:
|
|
257
|
+
True on success.
|
|
258
|
+
"""
|
|
259
|
+
if repo_root is None:
|
|
260
|
+
repo_root = get_repo_root()
|
|
261
|
+
|
|
262
|
+
registry_file = registry_get_file(repo_root)
|
|
263
|
+
if not registry_file or not registry_file.is_file():
|
|
264
|
+
return True # Nothing to remove
|
|
265
|
+
|
|
266
|
+
data = _read_json_file(registry_file)
|
|
267
|
+
if not data:
|
|
268
|
+
return True
|
|
269
|
+
|
|
270
|
+
agents = data.get("agents", [])
|
|
271
|
+
data["agents"] = [a for a in agents if a.get("worktree_path") != worktree_path]
|
|
272
|
+
|
|
273
|
+
return _write_json_file(registry_file, data)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def registry_add_agent(
|
|
277
|
+
agent_id: str,
|
|
278
|
+
worktree_path: str,
|
|
279
|
+
pid: int,
|
|
280
|
+
task_dir: str,
|
|
281
|
+
repo_root: Optional[Path] = None,
|
|
282
|
+
platform: str = "claude",
|
|
283
|
+
) -> bool:
|
|
284
|
+
"""Add agent to registry (replaces if same ID exists).
|
|
285
|
+
|
|
286
|
+
Args:
|
|
287
|
+
agent_id: Agent ID.
|
|
288
|
+
worktree_path: Worktree path.
|
|
289
|
+
pid: Process ID.
|
|
290
|
+
task_dir: Task directory path.
|
|
291
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
292
|
+
platform: Platform used (e.g., 'claude', 'opencode', 'codex', 'kiro', 'antigravity'). Defaults to 'claude'.
|
|
293
|
+
|
|
294
|
+
Returns:
|
|
295
|
+
True on success.
|
|
296
|
+
"""
|
|
297
|
+
if repo_root is None:
|
|
298
|
+
repo_root = get_repo_root()
|
|
299
|
+
|
|
300
|
+
registry_file = _ensure_registry(repo_root)
|
|
301
|
+
if not registry_file:
|
|
302
|
+
return False
|
|
303
|
+
|
|
304
|
+
data = _read_json_file(registry_file)
|
|
305
|
+
if not data:
|
|
306
|
+
data = {"agents": []}
|
|
307
|
+
|
|
308
|
+
# Remove existing agent with same ID
|
|
309
|
+
agents = data.get("agents", [])
|
|
310
|
+
agents = [a for a in agents if a.get("id") != agent_id]
|
|
311
|
+
|
|
312
|
+
# Create new agent record
|
|
313
|
+
started_at = datetime.now().isoformat()
|
|
314
|
+
new_agent = {
|
|
315
|
+
"id": agent_id,
|
|
316
|
+
"worktree_path": worktree_path,
|
|
317
|
+
"pid": pid,
|
|
318
|
+
"started_at": started_at,
|
|
319
|
+
"task_dir": task_dir,
|
|
320
|
+
"platform": platform,
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
agents.append(new_agent)
|
|
324
|
+
data["agents"] = agents
|
|
325
|
+
|
|
326
|
+
return _write_json_file(registry_file, data)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
def registry_list_agents(repo_root: Optional[Path] = None) -> list[dict]:
|
|
330
|
+
"""List all agents.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
List of agent dicts.
|
|
337
|
+
"""
|
|
338
|
+
if repo_root is None:
|
|
339
|
+
repo_root = get_repo_root()
|
|
340
|
+
|
|
341
|
+
registry_file = registry_get_file(repo_root)
|
|
342
|
+
if not registry_file or not registry_file.is_file():
|
|
343
|
+
return []
|
|
344
|
+
|
|
345
|
+
data = _read_json_file(registry_file)
|
|
346
|
+
if not data:
|
|
347
|
+
return []
|
|
348
|
+
|
|
349
|
+
return data.get("agents", [])
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
# =============================================================================
|
|
353
|
+
# Main Entry (for testing)
|
|
354
|
+
# =============================================================================
|
|
355
|
+
|
|
356
|
+
if __name__ == "__main__":
|
|
357
|
+
import json as json_mod
|
|
358
|
+
|
|
359
|
+
repo = get_repo_root()
|
|
360
|
+
print(f"Repository root: {repo}")
|
|
361
|
+
print(f"Registry file: {registry_get_file(repo)}")
|
|
362
|
+
print()
|
|
363
|
+
print("Agents:")
|
|
364
|
+
agents = registry_list_agents(repo)
|
|
365
|
+
print(json_mod.dumps(agents, indent=2))
|