trellis-herbivore 0.1.0
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/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 +174 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/channel/adapters/claude.d.ts +38 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +209 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +77 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +495 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +79 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +109 -0
- package/dist/commands/channel/adapters/index.js.map +1 -0
- package/dist/commands/channel/adapters/types.d.ts +33 -0
- package/dist/commands/channel/adapters/types.d.ts.map +1 -0
- package/dist/commands/channel/adapters/types.js +2 -0
- package/dist/commands/channel/adapters/types.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +32 -0
- package/dist/commands/channel/agent-loader.d.ts.map +1 -0
- package/dist/commands/channel/agent-loader.js +154 -0
- package/dist/commands/channel/agent-loader.js.map +1 -0
- package/dist/commands/channel/context-loader.d.ts +26 -0
- package/dist/commands/channel/context-loader.d.ts.map +1 -0
- package/dist/commands/channel/context-loader.js +290 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context.d.ts +16 -0
- package/dist/commands/channel/context.d.ts.map +1 -0
- package/dist/commands/channel/context.js +83 -0
- package/dist/commands/channel/context.js.map +1 -0
- package/dist/commands/channel/create.d.ts +27 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +39 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
- package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/channel/dev-parse-trace.js +70 -0
- package/dist/commands/channel/dev-parse-trace.js.map +1 -0
- package/dist/commands/channel/index.d.ts +3 -0
- package/dist/commands/channel/index.d.ts.map +1 -0
- package/dist/commands/channel/index.js +496 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/kill.d.ts +7 -0
- package/dist/commands/channel/kill.d.ts.map +1 -0
- package/dist/commands/channel/kill.js +121 -0
- package/dist/commands/channel/kill.js.map +1 -0
- package/dist/commands/channel/list.d.ts +17 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +233 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/messages.d.ts +16 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +237 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/rm.d.ts +27 -0
- package/dist/commands/channel/rm.d.ts.map +1 -0
- package/dist/commands/channel/rm.js +216 -0
- package/dist/commands/channel/rm.js.map +1 -0
- package/dist/commands/channel/run.d.ts +31 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +137 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +12 -0
- package/dist/commands/channel/send.d.ts.map +1 -0
- package/dist/commands/channel/send.js +24 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/channel/spawn.d.ts +25 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +192 -0
- package/dist/commands/channel/spawn.js.map +1 -0
- package/dist/commands/channel/store/events.d.ts +39 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +87 -0
- package/dist/commands/channel/store/events.js.map +1 -0
- package/dist/commands/channel/store/filter.d.ts +3 -0
- package/dist/commands/channel/store/filter.d.ts.map +1 -0
- package/dist/commands/channel/store/filter.js +2 -0
- package/dist/commands/channel/store/filter.js.map +1 -0
- package/dist/commands/channel/store/lock.d.ts +23 -0
- package/dist/commands/channel/store/lock.d.ts.map +1 -0
- package/dist/commands/channel/store/lock.js +99 -0
- package/dist/commands/channel/store/lock.js.map +1 -0
- package/dist/commands/channel/store/paths.d.ts +63 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +246 -0
- package/dist/commands/channel/store/paths.js.map +1 -0
- package/dist/commands/channel/store/schema.d.ts +27 -0
- package/dist/commands/channel/store/schema.d.ts.map +1 -0
- package/dist/commands/channel/store/schema.js +34 -0
- package/dist/commands/channel/store/schema.js.map +1 -0
- package/dist/commands/channel/store/thread-state.d.ts +5 -0
- package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
- package/dist/commands/channel/store/thread-state.js +16 -0
- package/dist/commands/channel/store/thread-state.js.map +1 -0
- package/dist/commands/channel/store/watch.d.ts +19 -0
- package/dist/commands/channel/store/watch.d.ts.map +1 -0
- package/dist/commands/channel/store/watch.js +130 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +25 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +99 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +66 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +143 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +49 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +107 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +47 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +283 -0
- package/dist/commands/channel/supervisor.js.map +1 -0
- package/dist/commands/channel/text-body.d.ts +13 -0
- package/dist/commands/channel/text-body.d.ts.map +1 -0
- package/dist/commands/channel/text-body.js +47 -0
- package/dist/commands/channel/text-body.js.map +1 -0
- package/dist/commands/channel/threads.d.ts +39 -0
- package/dist/commands/channel/threads.d.ts.map +1 -0
- package/dist/commands/channel/threads.js +106 -0
- package/dist/commands/channel/threads.js.map +1 -0
- package/dist/commands/channel/title.d.ts +12 -0
- package/dist/commands/channel/title.d.ts.map +1 -0
- package/dist/commands/channel/title.js +24 -0
- package/dist/commands/channel/title.js.map +1 -0
- package/dist/commands/channel/wait.d.ts +18 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +76 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +57 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1466 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mem.d.ts +234 -0
- package/dist/commands/mem.d.ts.map +1 -0
- package/dist/commands/mem.js +1869 -0
- package/dist/commands/mem.js.map +1 -0
- package/dist/commands/uninstall.d.ts +27 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +339 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +72 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +1926 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +84 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/configurators/antigravity.d.ts +7 -0
- package/dist/configurators/antigravity.d.ts.map +1 -0
- package/dist/configurators/antigravity.js +19 -0
- package/dist/configurators/antigravity.js.map +1 -0
- package/dist/configurators/claude.d.ts +9 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +72 -0
- package/dist/configurators/claude.js.map +1 -0
- package/dist/configurators/codebuddy.d.ts +10 -0
- package/dist/configurators/codebuddy.d.ts.map +1 -0
- package/dist/configurators/codebuddy.js +30 -0
- package/dist/configurators/codebuddy.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 +87 -0
- package/dist/configurators/codex.js.map +1 -0
- package/dist/configurators/copilot.d.ts +10 -0
- package/dist/configurators/copilot.d.ts.map +1 -0
- package/dist/configurators/copilot.js +51 -0
- package/dist/configurators/copilot.js.map +1 -0
- package/dist/configurators/cursor.d.ts +10 -0
- package/dist/configurators/cursor.d.ts.map +1 -0
- package/dist/configurators/cursor.js +29 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/droid.d.ts +10 -0
- package/dist/configurators/droid.d.ts.map +1 -0
- package/dist/configurators/droid.js +30 -0
- package/dist/configurators/droid.js.map +1 -0
- package/dist/configurators/gemini.d.ts +16 -0
- package/dist/configurators/gemini.d.ts.map +1 -0
- package/dist/configurators/gemini.js +38 -0
- package/dist/configurators/gemini.js.map +1 -0
- package/dist/configurators/index.d.ts +65 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +367 -0
- package/dist/configurators/index.js.map +1 -0
- package/dist/configurators/kilo.d.ts +7 -0
- package/dist/configurators/kilo.d.ts.map +1 -0
- package/dist/configurators/kilo.js +19 -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 +24 -0
- package/dist/configurators/kiro.js.map +1 -0
- package/dist/configurators/opencode.d.ts +14 -0
- package/dist/configurators/opencode.d.ts.map +1 -0
- package/dist/configurators/opencode.js +96 -0
- package/dist/configurators/opencode.js.map +1 -0
- package/dist/configurators/pi.d.ts +3 -0
- package/dist/configurators/pi.d.ts.map +1 -0
- package/dist/configurators/pi.js +45 -0
- package/dist/configurators/pi.js.map +1 -0
- package/dist/configurators/qoder.d.ts +11 -0
- package/dist/configurators/qoder.d.ts.map +1 -0
- package/dist/configurators/qoder.js +31 -0
- package/dist/configurators/qoder.js.map +1 -0
- package/dist/configurators/shared.d.ts +178 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +538 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/windsurf.d.ts +7 -0
- package/dist/configurators/windsurf.d.ts.map +1 -0
- package/dist/configurators/windsurf.js +19 -0
- package/dist/configurators/windsurf.js.map +1 -0
- package/dist/configurators/workflow.d.ts +29 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +163 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/constants/paths.d.ts +70 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +79 -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 +62 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +187 -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 +297 -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/migrations/manifests/0.3.1.json +9 -0
- package/dist/migrations/manifests/0.3.10.json +9 -0
- package/dist/migrations/manifests/0.3.2.json +9 -0
- package/dist/migrations/manifests/0.3.3.json +9 -0
- package/dist/migrations/manifests/0.3.4.json +21 -0
- package/dist/migrations/manifests/0.3.5.json +9 -0
- package/dist/migrations/manifests/0.3.6.json +9 -0
- package/dist/migrations/manifests/0.3.7.json +9 -0
- package/dist/migrations/manifests/0.3.8.json +9 -0
- package/dist/migrations/manifests/0.3.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.1.json +228 -0
- package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
- package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.4.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.4.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.0.json +1646 -0
- package/dist/migrations/manifests/0.5.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
- package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.5.json +222 -0
- package/dist/migrations/manifests/0.5.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
- package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.1.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.2.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.3.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.4.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.5.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.6.json +9 -0
- package/dist/migrations/manifests/0.5.0-rc.7.json +9 -0
- package/dist/migrations/manifests/0.5.0.json +9 -0
- package/dist/migrations/manifests/0.5.1.json +9 -0
- package/dist/migrations/manifests/0.5.10.json +9 -0
- package/dist/migrations/manifests/0.5.11.json +16 -0
- package/dist/migrations/manifests/0.5.12.json +9 -0
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.2.json +9 -0
- package/dist/migrations/manifests/0.5.3.json +9 -0
- package/dist/migrations/manifests/0.5.4.json +9 -0
- package/dist/migrations/manifests/0.5.5.json +9 -0
- package/dist/migrations/manifests/0.5.6.json +9 -0
- package/dist/migrations/manifests/0.5.7.json +16 -0
- package/dist/migrations/manifests/0.5.8.json +9 -0
- package/dist/migrations/manifests/0.5.9.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.0.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +114 -0
- package/dist/templates/claude/agents/trellis-implement.md +113 -0
- package/dist/templates/claude/agents/trellis-research.md +137 -0
- package/dist/templates/claude/index.d.ts +22 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +46 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +73 -0
- package/dist/templates/codebuddy/agents/trellis-check.md +109 -0
- package/dist/templates/codebuddy/agents/trellis-implement.md +110 -0
- package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
- package/dist/templates/codebuddy/index.d.ts +15 -0
- package/dist/templates/codebuddy/index.d.ts.map +1 -0
- package/dist/templates/codebuddy/index.js +15 -0
- package/dist/templates/codebuddy/index.js.map +1 -0
- package/dist/templates/codebuddy/settings.json +59 -0
- package/dist/templates/codex/agents/trellis-check.toml +84 -0
- package/dist/templates/codex/agents/trellis-implement.toml +65 -0
- package/dist/templates/codex/agents/trellis-research.toml +73 -0
- package/dist/templates/codex/config.toml +35 -0
- package/dist/templates/codex/hooks/session-start.py +545 -0
- package/dist/templates/codex/hooks.json +15 -0
- package/dist/templates/codex/index.d.ts +39 -0
- package/dist/templates/codex/index.d.ts.map +1 -0
- package/dist/templates/codex/index.js +85 -0
- package/dist/templates/codex/index.js.map +1 -0
- package/dist/templates/codex/skills/before-dev/SKILL.md +40 -0
- package/dist/templates/codex/skills/brainstorm/SKILL.md +112 -0
- package/dist/templates/codex/skills/break-loop/SKILL.md +130 -0
- package/dist/templates/codex/skills/check/SKILL.md +98 -0
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +158 -0
- package/dist/templates/codex/skills/create-command/SKILL.md +101 -0
- package/dist/templates/codex/skills/finish-work/SKILL.md +90 -0
- package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -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 +64 -0
- package/dist/templates/codex/skills/update-spec/SKILL.md +335 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +84 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +65 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +103 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +80 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
- package/dist/templates/common/commands/continue.md +56 -0
- package/dist/templates/common/commands/finish-work.md +66 -0
- package/dist/templates/common/commands/start.md +59 -0
- package/dist/templates/common/index.d.ts +48 -0
- package/dist/templates/common/index.d.ts.map +1 -0
- package/dist/templates/common/index.js +104 -0
- package/dist/templates/common/index.js.map +1 -0
- package/dist/templates/common/skills/before-dev.md +35 -0
- package/dist/templates/common/skills/brainstorm.md +112 -0
- package/dist/templates/common/skills/break-loop.md +125 -0
- package/dist/templates/common/skills/check.md +93 -0
- package/dist/templates/common/skills/update-spec.md +351 -0
- package/dist/templates/copilot/hooks/session-start.py +547 -0
- package/dist/templates/copilot/hooks.json +19 -0
- package/dist/templates/copilot/index.d.ts +23 -0
- package/dist/templates/copilot/index.d.ts.map +1 -0
- package/dist/templates/copilot/index.js +54 -0
- package/dist/templates/copilot/index.js.map +1 -0
- package/dist/templates/copilot/prompts/before-dev.prompt.md +39 -0
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +111 -0
- package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
- package/dist/templates/copilot/prompts/check.prompt.md +97 -0
- package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
- package/dist/templates/copilot/prompts/finish-work.prompt.md +99 -0
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
- package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
- package/dist/templates/copilot/prompts/parallel.prompt.md +204 -0
- package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
- package/dist/templates/copilot/prompts/start.prompt.md +63 -0
- package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
- package/dist/templates/cursor/agents/trellis-check.md +108 -0
- package/dist/templates/cursor/agents/trellis-implement.md +109 -0
- package/dist/templates/cursor/agents/trellis-research.md +136 -0
- package/dist/templates/cursor/hooks.json +30 -0
- package/dist/templates/cursor/index.d.ts +13 -0
- package/dist/templates/cursor/index.d.ts.map +1 -0
- package/dist/templates/cursor/index.js +13 -0
- package/dist/templates/cursor/index.js.map +1 -0
- package/dist/templates/droid/droids/trellis-check.md +101 -0
- package/dist/templates/droid/droids/trellis-implement.md +102 -0
- package/dist/templates/droid/droids/trellis-research.md +137 -0
- package/dist/templates/droid/index.d.ts +15 -0
- package/dist/templates/droid/index.d.ts.map +1 -0
- package/dist/templates/droid/index.js +15 -0
- package/dist/templates/droid/index.js.map +1 -0
- package/dist/templates/droid/settings.json +59 -0
- package/dist/templates/extract.d.ts +40 -0
- package/dist/templates/extract.d.ts.map +1 -0
- package/dist/templates/extract.js +106 -0
- package/dist/templates/extract.js.map +1 -0
- package/dist/templates/gemini/agents/trellis-check.md +101 -0
- package/dist/templates/gemini/agents/trellis-implement.md +102 -0
- package/dist/templates/gemini/agents/trellis-research.md +136 -0
- package/dist/templates/gemini/index.d.ts +13 -0
- package/dist/templates/gemini/index.d.ts.map +1 -0
- package/dist/templates/gemini/index.js +13 -0
- package/dist/templates/gemini/index.js.map +1 -0
- package/dist/templates/gemini/settings.json +28 -0
- package/dist/templates/kiro/agents/trellis-check.json +26 -0
- package/dist/templates/kiro/agents/trellis-implement.json +26 -0
- package/dist/templates/kiro/agents/trellis-research.json +30 -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 +18 -0
- package/dist/templates/kiro/index.js.map +1 -0
- package/dist/templates/markdown/agents.md +21 -0
- package/dist/templates/markdown/gitignore.txt +15 -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.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/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.txt +223 -0
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +259 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +595 -0
- package/dist/templates/markdown/spec/guides/index.md.txt +97 -0
- package/dist/templates/markdown/workspace-index.md +125 -0
- package/dist/templates/markdown/worktree.yaml.txt +58 -0
- package/dist/templates/opencode/agents/trellis-check.md +116 -0
- package/dist/templates/opencode/agents/trellis-implement.md +118 -0
- package/dist/templates/opencode/agents/trellis-research.md +145 -0
- package/dist/templates/opencode/lib/session-utils.js +521 -0
- package/dist/templates/opencode/lib/trellis-context.js +381 -0
- package/dist/templates/opencode/package.json +5 -0
- package/dist/templates/opencode/plugins/inject-subagent-context.js +513 -0
- package/dist/templates/opencode/plugins/inject-workflow-state.js +159 -0
- package/dist/templates/opencode/plugins/session-start.js +101 -0
- package/dist/templates/pi/agents/trellis-check.md +36 -0
- package/dist/templates/pi/agents/trellis-implement.md +41 -0
- package/dist/templates/pi/agents/trellis-research.md +25 -0
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1174 -0
- package/dist/templates/pi/index.d.ts +5 -0
- package/dist/templates/pi/index.d.ts.map +1 -0
- package/dist/templates/pi/index.js +12 -0
- package/dist/templates/pi/index.js.map +1 -0
- package/dist/templates/pi/settings.json +21 -0
- package/dist/templates/qoder/agents/trellis-check.md +102 -0
- package/dist/templates/qoder/agents/trellis-implement.md +103 -0
- package/dist/templates/qoder/agents/trellis-research.md +137 -0
- package/dist/templates/qoder/index.d.ts +15 -0
- package/dist/templates/qoder/index.d.ts.map +1 -0
- package/dist/templates/qoder/index.js +15 -0
- package/dist/templates/qoder/index.js.map +1 -0
- package/dist/templates/qoder/settings.json +47 -0
- package/dist/templates/shared-hooks/index.d.ts +50 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +89 -0
- package/dist/templates/shared-hooks/index.js.map +1 -0
- package/dist/templates/shared-hooks/inject-shell-session-context.py +183 -0
- package/dist/templates/shared-hooks/inject-subagent-context.py +771 -0
- package/dist/templates/shared-hooks/inject-workflow-state.py +363 -0
- package/dist/templates/shared-hooks/session-start.py +827 -0
- package/dist/templates/template-utils.d.ts +26 -0
- package/dist/templates/template-utils.d.ts.map +1 -0
- package/dist/templates/template-utils.js +60 -0
- package/dist/templates/template-utils.js.map +1 -0
- package/dist/templates/trellis/config.yaml +90 -0
- package/dist/templates/trellis/gitignore.txt +32 -0
- package/dist/templates/trellis/index.d.ts +52 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +97 -0
- package/dist/templates/trellis/index.js.map +1 -0
- package/dist/templates/trellis/scripts/__init__.py +5 -0
- package/dist/templates/trellis/scripts/add_session.py +547 -0
- package/dist/templates/trellis/scripts/common/__init__.py +92 -0
- package/dist/templates/trellis/scripts/common/active_task.py +626 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +811 -0
- package/dist/templates/trellis/scripts/common/config.py +445 -0
- package/dist/templates/trellis/scripts/common/developer.py +190 -0
- package/dist/templates/trellis/scripts/common/git.py +31 -0
- package/dist/templates/trellis/scripts/common/git_context.py +106 -0
- package/dist/templates/trellis/scripts/common/io.py +37 -0
- package/dist/templates/trellis/scripts/common/log.py +45 -0
- package/dist/templates/trellis/scripts/common/packages_context.py +238 -0
- package/dist/templates/trellis/scripts/common/paths.py +447 -0
- package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
- package/dist/templates/trellis/scripts/common/session_context.py +821 -0
- package/dist/templates/trellis/scripts/common/task_context.py +223 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
- package/dist/templates/trellis/scripts/common/task_store.py +698 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +274 -0
- package/dist/templates/trellis/scripts/common/tasks.py +112 -0
- package/dist/templates/trellis/scripts/common/trellis_config.py +131 -0
- package/dist/templates/trellis/scripts/common/types.py +110 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +212 -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/hooks/linear_sync.py +243 -0
- package/dist/templates/trellis/scripts/init_developer.py +51 -0
- package/dist/templates/trellis/scripts/task.py +500 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +690 -0
- package/dist/types/ai-tools.d.ts +95 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +280 -0
- package/dist/types/ai-tools.js.map +1 -0
- package/dist/types/migration.d.ts +125 -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 +86 -0
- package/dist/utils/compare-versions.js.map +1 -0
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +36 -0
- package/dist/utils/file-writer.d.ts.map +1 -0
- package/dist/utils/file-writer.js +203 -0
- package/dist/utils/file-writer.js.map +1 -0
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/posix.d.ts +13 -0
- package/dist/utils/posix.d.ts.map +1 -0
- package/dist/utils/posix.js +15 -0
- package/dist/utils/posix.js.map +1 -0
- package/dist/utils/project-detector.d.ts +46 -0
- package/dist/utils/project-detector.d.ts.map +1 -0
- package/dist/utils/project-detector.js +666 -0
- package/dist/utils/project-detector.js.map +1 -0
- package/dist/utils/proxy.d.ts +25 -0
- package/dist/utils/proxy.d.ts.map +1 -0
- package/dist/utils/proxy.js +60 -0
- package/dist/utils/proxy.js.map +1 -0
- package/dist/utils/task-json.d.ts +13 -0
- package/dist/utils/task-json.d.ts.map +1 -0
- package/dist/utils/task-json.js +12 -0
- package/dist/utils/task-json.js.map +1 -0
- package/dist/utils/template-fetcher.d.ts +150 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +907 -0
- package/dist/utils/template-fetcher.js.map +1 -0
- package/dist/utils/template-hash.d.ts +123 -0
- package/dist/utils/template-hash.d.ts.map +1 -0
- package/dist/utils/template-hash.js +334 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts +66 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
- package/dist/utils/uninstall-scrubbers.js +342 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -0
- package/package.json +90 -0
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Task CRUD operations.
|
|
4
|
+
|
|
5
|
+
Provides:
|
|
6
|
+
ensure_tasks_dir - Ensure tasks directory exists
|
|
7
|
+
cmd_create - Create a new task
|
|
8
|
+
cmd_archive - Archive completed task
|
|
9
|
+
cmd_set_branch - Set git branch for task
|
|
10
|
+
cmd_set_base_branch - Set PR target branch
|
|
11
|
+
cmd_set_scope - Set scope for PR title
|
|
12
|
+
cmd_add_subtask - Link child task to parent
|
|
13
|
+
cmd_remove_subtask - Unlink child task from parent
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import json
|
|
20
|
+
import re
|
|
21
|
+
import sys
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
|
|
25
|
+
from .config import (
|
|
26
|
+
get_packages,
|
|
27
|
+
get_session_auto_commit,
|
|
28
|
+
is_monorepo,
|
|
29
|
+
resolve_package,
|
|
30
|
+
validate_package,
|
|
31
|
+
)
|
|
32
|
+
from .git import run_git
|
|
33
|
+
from .io import read_json, write_json
|
|
34
|
+
from .log import Colors, colored
|
|
35
|
+
from .paths import (
|
|
36
|
+
DIR_ARCHIVE,
|
|
37
|
+
DIR_TASKS,
|
|
38
|
+
DIR_WORKFLOW,
|
|
39
|
+
FILE_TASK_JSON,
|
|
40
|
+
generate_task_date_prefix,
|
|
41
|
+
get_developer,
|
|
42
|
+
get_repo_root,
|
|
43
|
+
get_tasks_dir,
|
|
44
|
+
)
|
|
45
|
+
from .safe_commit import (
|
|
46
|
+
print_gitignore_warning,
|
|
47
|
+
safe_archive_paths_to_add,
|
|
48
|
+
safe_git_add,
|
|
49
|
+
)
|
|
50
|
+
from .task_utils import (
|
|
51
|
+
archive_task_complete,
|
|
52
|
+
find_task_by_name,
|
|
53
|
+
resolve_task_dir,
|
|
54
|
+
run_task_hooks,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# =============================================================================
|
|
59
|
+
# Helper Functions
|
|
60
|
+
# =============================================================================
|
|
61
|
+
|
|
62
|
+
def _slugify(title: str) -> str:
|
|
63
|
+
"""Convert title to slug (only works with ASCII)."""
|
|
64
|
+
result = title.lower()
|
|
65
|
+
result = re.sub(r"[^a-z0-9]", "-", result)
|
|
66
|
+
result = re.sub(r"-+", "-", result)
|
|
67
|
+
result = result.strip("-")
|
|
68
|
+
return result
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def ensure_tasks_dir(repo_root: Path) -> Path:
|
|
72
|
+
"""Ensure tasks directory exists."""
|
|
73
|
+
tasks_dir = get_tasks_dir(repo_root)
|
|
74
|
+
archive_dir = tasks_dir / "archive"
|
|
75
|
+
|
|
76
|
+
if not tasks_dir.exists():
|
|
77
|
+
tasks_dir.mkdir(parents=True)
|
|
78
|
+
print(colored(f"Created tasks directory: {tasks_dir}", Colors.GREEN), file=sys.stderr)
|
|
79
|
+
|
|
80
|
+
if not archive_dir.exists():
|
|
81
|
+
archive_dir.mkdir(parents=True)
|
|
82
|
+
|
|
83
|
+
return tasks_dir
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# =============================================================================
|
|
87
|
+
# Sub-agent platform detection + JSONL seeding
|
|
88
|
+
# =============================================================================
|
|
89
|
+
|
|
90
|
+
# Config directories of platforms that consume implement.jsonl / check.jsonl.
|
|
91
|
+
# Keep in sync with src/types/ai-tools.ts AI_TOOLS entries — these are the
|
|
92
|
+
# platforms listed in workflow.md's "agent-capable" Skill Routing block
|
|
93
|
+
# (Class-1 hook-inject + Class-2 pull-based preludes). Kilo / Antigravity /
|
|
94
|
+
# Windsurf are NOT in this list: they do not consume JSONL.
|
|
95
|
+
_SUBAGENT_CONFIG_DIRS: tuple[str, ...] = (
|
|
96
|
+
".claude",
|
|
97
|
+
".cursor",
|
|
98
|
+
".codex",
|
|
99
|
+
".kiro",
|
|
100
|
+
".gemini",
|
|
101
|
+
".opencode",
|
|
102
|
+
".qoder",
|
|
103
|
+
".codebuddy",
|
|
104
|
+
".factory", # Factory Droid
|
|
105
|
+
".github/copilot",
|
|
106
|
+
".pi", # Pi Agent
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
_SEED_EXAMPLE = (
|
|
110
|
+
"Fill with {\"file\": \"<path>\", \"reason\": \"<why>\"}. "
|
|
111
|
+
"Put spec/research files only — no code paths. "
|
|
112
|
+
"Run `python3 .trellis/scripts/get_context.py --mode packages` to list available specs. "
|
|
113
|
+
"Delete this line once real entries are added."
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _has_subagent_platform(repo_root: Path) -> bool:
|
|
118
|
+
"""Return True if any sub-agent-capable platform is configured.
|
|
119
|
+
|
|
120
|
+
Detected by probing well-known config directories at the repo root. Used
|
|
121
|
+
only to decide whether ``task.py create`` should seed empty
|
|
122
|
+
``implement.jsonl`` / ``check.jsonl`` files.
|
|
123
|
+
"""
|
|
124
|
+
for config_dir in _SUBAGENT_CONFIG_DIRS:
|
|
125
|
+
if (repo_root / config_dir).is_dir():
|
|
126
|
+
return True
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def _write_seed_jsonl(path: Path) -> None:
|
|
131
|
+
"""Write a one-line seed JSONL file with a self-describing ``_example``.
|
|
132
|
+
|
|
133
|
+
The seed row has no ``file`` field, so downstream consumers (hooks +
|
|
134
|
+
preludes) that iterate entries via ``item.get("file")`` naturally skip
|
|
135
|
+
it. The row exists purely as an in-file prompt for the AI curator.
|
|
136
|
+
"""
|
|
137
|
+
seed = {"_example": _SEED_EXAMPLE}
|
|
138
|
+
path.write_text(json.dumps(seed, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def _default_prd_content(title: str, description: str | None = None) -> str:
|
|
142
|
+
"""Return the default PRD skeleton created with every task."""
|
|
143
|
+
goal = (description or "").strip() or "TBD."
|
|
144
|
+
heading = title.strip() or "Untitled task"
|
|
145
|
+
return f"""# {heading}
|
|
146
|
+
|
|
147
|
+
## Goal
|
|
148
|
+
|
|
149
|
+
{goal}
|
|
150
|
+
|
|
151
|
+
## Requirements
|
|
152
|
+
|
|
153
|
+
- TBD
|
|
154
|
+
|
|
155
|
+
## Acceptance Criteria
|
|
156
|
+
|
|
157
|
+
- [ ] TBD
|
|
158
|
+
|
|
159
|
+
## Notes
|
|
160
|
+
|
|
161
|
+
- Keep `prd.md` focused on requirements, constraints, and acceptance criteria.
|
|
162
|
+
- Lightweight tasks can remain PRD-only.
|
|
163
|
+
- For complex tasks, add `design.md` for technical design and `implement.md` for execution planning before `task.py start`.
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# =============================================================================
|
|
168
|
+
# Command: create
|
|
169
|
+
# =============================================================================
|
|
170
|
+
|
|
171
|
+
def cmd_create(args: argparse.Namespace) -> int:
|
|
172
|
+
"""Create a new task."""
|
|
173
|
+
repo_root = get_repo_root()
|
|
174
|
+
|
|
175
|
+
if not args.title:
|
|
176
|
+
print(colored("Error: title is required", Colors.RED), file=sys.stderr)
|
|
177
|
+
return 1
|
|
178
|
+
|
|
179
|
+
# Validate --package (CLI source: fail-fast)
|
|
180
|
+
package: str | None = getattr(args, "package", None)
|
|
181
|
+
if not is_monorepo(repo_root):
|
|
182
|
+
# Single-repo: ignore --package, no package prefix
|
|
183
|
+
if package:
|
|
184
|
+
print(colored(f"Warning: --package ignored in single-repo project", Colors.YELLOW), file=sys.stderr)
|
|
185
|
+
package = None
|
|
186
|
+
elif package:
|
|
187
|
+
if not validate_package(package, repo_root):
|
|
188
|
+
packages = get_packages(repo_root)
|
|
189
|
+
available = ", ".join(sorted(packages.keys())) if packages else "(none)"
|
|
190
|
+
print(colored(f"Error: unknown package '{package}'. Available: {available}", Colors.RED), file=sys.stderr)
|
|
191
|
+
return 1
|
|
192
|
+
else:
|
|
193
|
+
# Inferred: default_package → None (no task.json yet for create)
|
|
194
|
+
package = resolve_package(repo_root=repo_root)
|
|
195
|
+
|
|
196
|
+
# Default assignee to current developer
|
|
197
|
+
assignee = args.assignee
|
|
198
|
+
if not assignee:
|
|
199
|
+
assignee = get_developer(repo_root)
|
|
200
|
+
if not assignee:
|
|
201
|
+
print(colored("Error: No developer set. Run init_developer.py first or use --assignee", Colors.RED), file=sys.stderr)
|
|
202
|
+
return 1
|
|
203
|
+
|
|
204
|
+
ensure_tasks_dir(repo_root)
|
|
205
|
+
|
|
206
|
+
# Get current developer as creator
|
|
207
|
+
creator = get_developer(repo_root) or assignee
|
|
208
|
+
|
|
209
|
+
# Generate slug if not provided
|
|
210
|
+
slug = args.slug or _slugify(args.title)
|
|
211
|
+
if not slug:
|
|
212
|
+
print(colored("Error: could not generate slug from title", Colors.RED), file=sys.stderr)
|
|
213
|
+
return 1
|
|
214
|
+
|
|
215
|
+
# Create task directory with MM-DD-slug format
|
|
216
|
+
tasks_dir = get_tasks_dir(repo_root)
|
|
217
|
+
date_prefix = generate_task_date_prefix()
|
|
218
|
+
dir_name = f"{date_prefix}-{slug}"
|
|
219
|
+
task_dir = tasks_dir / dir_name
|
|
220
|
+
task_json_path = task_dir / FILE_TASK_JSON
|
|
221
|
+
|
|
222
|
+
if task_dir.exists():
|
|
223
|
+
print(colored(f"Warning: Task directory already exists: {dir_name}", Colors.YELLOW), file=sys.stderr)
|
|
224
|
+
else:
|
|
225
|
+
task_dir.mkdir(parents=True)
|
|
226
|
+
|
|
227
|
+
today = datetime.now().strftime("%Y-%m-%d")
|
|
228
|
+
|
|
229
|
+
# Record current branch as base_branch (PR target)
|
|
230
|
+
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
231
|
+
current_branch = branch_out.strip() or "main"
|
|
232
|
+
|
|
233
|
+
task_data = {
|
|
234
|
+
"id": slug,
|
|
235
|
+
"name": slug,
|
|
236
|
+
"title": args.title,
|
|
237
|
+
"description": args.description or "",
|
|
238
|
+
"status": "planning",
|
|
239
|
+
"dev_type": None,
|
|
240
|
+
"scope": None,
|
|
241
|
+
"package": package,
|
|
242
|
+
"priority": args.priority,
|
|
243
|
+
"creator": creator,
|
|
244
|
+
"assignee": assignee,
|
|
245
|
+
"createdAt": today,
|
|
246
|
+
"completedAt": None,
|
|
247
|
+
"branch": None,
|
|
248
|
+
"base_branch": current_branch,
|
|
249
|
+
"worktree_path": None,
|
|
250
|
+
"commit": None,
|
|
251
|
+
"pr_url": None,
|
|
252
|
+
"subtasks": [],
|
|
253
|
+
"children": [],
|
|
254
|
+
"parent": None,
|
|
255
|
+
"relatedFiles": [],
|
|
256
|
+
"notes": "",
|
|
257
|
+
"meta": {},
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
write_json(task_json_path, task_data)
|
|
261
|
+
|
|
262
|
+
prd_path = task_dir / "prd.md"
|
|
263
|
+
if not prd_path.exists():
|
|
264
|
+
prd_path.write_text(
|
|
265
|
+
_default_prd_content(args.title, args.description),
|
|
266
|
+
encoding="utf-8",
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
# Seed implement.jsonl / check.jsonl for sub-agent-capable platforms.
|
|
270
|
+
# Agent curates real entries during planning when the task needs them.
|
|
271
|
+
# Agent-less platforms (Kilo / Antigravity / Windsurf) skip this — they
|
|
272
|
+
# load specs via the trellis-before-dev skill instead of JSONL.
|
|
273
|
+
seeded_jsonl = False
|
|
274
|
+
if _has_subagent_platform(repo_root):
|
|
275
|
+
for jsonl_name in ("implement.jsonl", "check.jsonl"):
|
|
276
|
+
jsonl_path = task_dir / jsonl_name
|
|
277
|
+
if not jsonl_path.exists():
|
|
278
|
+
_write_seed_jsonl(jsonl_path)
|
|
279
|
+
seeded_jsonl = True
|
|
280
|
+
|
|
281
|
+
# Handle --parent: establish bidirectional link
|
|
282
|
+
if args.parent:
|
|
283
|
+
parent_dir = resolve_task_dir(args.parent, repo_root)
|
|
284
|
+
parent_json_path = parent_dir / FILE_TASK_JSON
|
|
285
|
+
if not parent_json_path.is_file():
|
|
286
|
+
print(colored(f"Warning: Parent task.json not found: {args.parent}", Colors.YELLOW), file=sys.stderr)
|
|
287
|
+
else:
|
|
288
|
+
parent_data = read_json(parent_json_path)
|
|
289
|
+
if parent_data:
|
|
290
|
+
# Add child to parent's children list
|
|
291
|
+
parent_children = parent_data.get("children", [])
|
|
292
|
+
if dir_name not in parent_children:
|
|
293
|
+
parent_children.append(dir_name)
|
|
294
|
+
parent_data["children"] = parent_children
|
|
295
|
+
write_json(parent_json_path, parent_data)
|
|
296
|
+
|
|
297
|
+
# Set parent in child's task.json
|
|
298
|
+
task_data["parent"] = parent_dir.name
|
|
299
|
+
write_json(task_json_path, task_data)
|
|
300
|
+
|
|
301
|
+
print(colored(f"Linked as child of: {parent_dir.name}", Colors.GREEN), file=sys.stderr)
|
|
302
|
+
|
|
303
|
+
# Auto-activate the new task so the per-turn breadcrumb fires planning
|
|
304
|
+
# state. Best-effort: gracefully degrade if no session identity (CLI run
|
|
305
|
+
# outside an AI session) — the task is still created, the user can run
|
|
306
|
+
# task.py start later. Pointer is session-scoped so this never affects
|
|
307
|
+
# other AI sessions.
|
|
308
|
+
try:
|
|
309
|
+
from .active_task import resolve_context_key, set_active_task
|
|
310
|
+
if resolve_context_key():
|
|
311
|
+
try:
|
|
312
|
+
rel_dir = task_dir.relative_to(repo_root).as_posix()
|
|
313
|
+
except ValueError:
|
|
314
|
+
rel_dir = str(task_dir)
|
|
315
|
+
set_active_task(rel_dir, repo_root)
|
|
316
|
+
except Exception:
|
|
317
|
+
pass
|
|
318
|
+
|
|
319
|
+
print(colored(f"Created task: {dir_name}", Colors.GREEN), file=sys.stderr)
|
|
320
|
+
print("", file=sys.stderr)
|
|
321
|
+
print(colored("Next steps:", Colors.BLUE), file=sys.stderr)
|
|
322
|
+
print(" - Fill prd.md with requirements and acceptance criteria", file=sys.stderr)
|
|
323
|
+
print(" - Lightweight task: PRD-only is valid", file=sys.stderr)
|
|
324
|
+
print(" - Complex task: add design.md and implement.md before task.py start", file=sys.stderr)
|
|
325
|
+
if seeded_jsonl:
|
|
326
|
+
print(
|
|
327
|
+
" - Curate implement.jsonl / check.jsonl as spec/research manifests when sub-agents need context",
|
|
328
|
+
file=sys.stderr,
|
|
329
|
+
)
|
|
330
|
+
print(" - Use /trellis:continue or phase context to decide the next step", file=sys.stderr)
|
|
331
|
+
print("", file=sys.stderr)
|
|
332
|
+
|
|
333
|
+
# Output relative path for script chaining
|
|
334
|
+
print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{dir_name}")
|
|
335
|
+
|
|
336
|
+
run_task_hooks("after_create", task_json_path, repo_root)
|
|
337
|
+
return 0
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
# =============================================================================
|
|
341
|
+
# Command: archive
|
|
342
|
+
# =============================================================================
|
|
343
|
+
|
|
344
|
+
def cmd_archive(args: argparse.Namespace) -> int:
|
|
345
|
+
"""Archive completed task."""
|
|
346
|
+
repo_root = get_repo_root()
|
|
347
|
+
task_name = args.name
|
|
348
|
+
|
|
349
|
+
if not task_name:
|
|
350
|
+
print(colored("Error: Task name is required", Colors.RED), file=sys.stderr)
|
|
351
|
+
return 1
|
|
352
|
+
|
|
353
|
+
tasks_dir = get_tasks_dir(repo_root)
|
|
354
|
+
|
|
355
|
+
# Resolve task directory (supports task name, relative path, or absolute path)
|
|
356
|
+
task_dir = resolve_task_dir(task_name, repo_root)
|
|
357
|
+
|
|
358
|
+
if not task_dir or not task_dir.is_dir():
|
|
359
|
+
print(colored(f"Error: Task not found: {task_name}", Colors.RED), file=sys.stderr)
|
|
360
|
+
print("Active tasks:", file=sys.stderr)
|
|
361
|
+
# Import lazily to avoid circular dependency
|
|
362
|
+
from .tasks import iter_active_tasks
|
|
363
|
+
for t in iter_active_tasks(tasks_dir):
|
|
364
|
+
print(f" - {t.dir_name}/", file=sys.stderr)
|
|
365
|
+
return 1
|
|
366
|
+
|
|
367
|
+
dir_name = task_dir.name
|
|
368
|
+
task_json_path = task_dir / FILE_TASK_JSON
|
|
369
|
+
|
|
370
|
+
# Update status before archiving
|
|
371
|
+
today = datetime.now().strftime("%Y-%m-%d")
|
|
372
|
+
# Names of child task dirs whose task.json gets modified below; passed
|
|
373
|
+
# into safe_archive_paths_to_add so they're staged in this commit.
|
|
374
|
+
modified_children: list[str] = []
|
|
375
|
+
if task_json_path.is_file():
|
|
376
|
+
data = read_json(task_json_path)
|
|
377
|
+
if data:
|
|
378
|
+
data["status"] = "completed"
|
|
379
|
+
data["completedAt"] = today
|
|
380
|
+
write_json(task_json_path, data)
|
|
381
|
+
|
|
382
|
+
# Handle subtask relationships on archive.
|
|
383
|
+
# Keep this task in its parent's children list so progress
|
|
384
|
+
# counters (children_progress) stay consistent — children
|
|
385
|
+
# missing from the active set are treated as completed.
|
|
386
|
+
task_children = data.get("children", [])
|
|
387
|
+
|
|
388
|
+
# If this is a parent, clear parent field in all children
|
|
389
|
+
if task_children:
|
|
390
|
+
for child_name in task_children:
|
|
391
|
+
child_dir_path = find_task_by_name(child_name, tasks_dir)
|
|
392
|
+
if child_dir_path:
|
|
393
|
+
child_json = child_dir_path / FILE_TASK_JSON
|
|
394
|
+
if child_json.is_file():
|
|
395
|
+
child_data = read_json(child_json)
|
|
396
|
+
if child_data:
|
|
397
|
+
child_data["parent"] = None
|
|
398
|
+
write_json(child_json, child_data)
|
|
399
|
+
modified_children.append(child_dir_path.name)
|
|
400
|
+
|
|
401
|
+
# Clear any session that still points at this task before the path moves.
|
|
402
|
+
from .active_task import clear_task_from_sessions
|
|
403
|
+
clear_task_from_sessions(str(task_dir), repo_root)
|
|
404
|
+
|
|
405
|
+
# Archive
|
|
406
|
+
result = archive_task_complete(task_dir, repo_root)
|
|
407
|
+
if "archived_to" in result:
|
|
408
|
+
archive_dest = Path(result["archived_to"])
|
|
409
|
+
year_month = archive_dest.parent.name
|
|
410
|
+
print(colored(f"Archived: {dir_name} -> archive/{year_month}/", Colors.GREEN), file=sys.stderr)
|
|
411
|
+
|
|
412
|
+
# Auto-commit unless --no-commit
|
|
413
|
+
if not getattr(args, "no_commit", False):
|
|
414
|
+
_auto_commit_archive(dir_name, repo_root, modified_children)
|
|
415
|
+
|
|
416
|
+
# Return the archive path
|
|
417
|
+
print(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{year_month}/{dir_name}")
|
|
418
|
+
|
|
419
|
+
# Run hooks with the archived path
|
|
420
|
+
archived_json = archive_dest / FILE_TASK_JSON
|
|
421
|
+
run_task_hooks("after_archive", archived_json, repo_root)
|
|
422
|
+
return 0
|
|
423
|
+
|
|
424
|
+
return 1
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
def _auto_commit_archive(
|
|
428
|
+
task_name: str,
|
|
429
|
+
repo_root: Path,
|
|
430
|
+
modified_children: list[str] | None = None,
|
|
431
|
+
) -> None:
|
|
432
|
+
"""Stage Trellis-owned task paths and commit after archive.
|
|
433
|
+
|
|
434
|
+
Scoped narrowly to the archived task's source + destination paths
|
|
435
|
+
plus any child task dirs whose ``task.json`` was edited (parent →
|
|
436
|
+
children relationship update). Dirty changes in OTHER active task
|
|
437
|
+
dirs are NOT bundled into the archive commit.
|
|
438
|
+
|
|
439
|
+
If ``.gitignore`` blocks the paths, we warn + skip — we do NOT
|
|
440
|
+
retry with ``git add -f``. The warning explicitly forbids
|
|
441
|
+
``git add -f .trellis/`` (which would fan out to caches/backups)
|
|
442
|
+
and points users at ``session_auto_commit: false``.
|
|
443
|
+
|
|
444
|
+
Honors ``session_auto_commit`` in ``.trellis/config.yaml``: when
|
|
445
|
+
set to ``false``, this function returns immediately without
|
|
446
|
+
touching git (the archive directory move on disk is unaffected).
|
|
447
|
+
"""
|
|
448
|
+
if not get_session_auto_commit(repo_root):
|
|
449
|
+
print(
|
|
450
|
+
"[OK] session_auto_commit: false — skipping git stage/commit.",
|
|
451
|
+
file=sys.stderr,
|
|
452
|
+
)
|
|
453
|
+
return
|
|
454
|
+
|
|
455
|
+
paths = safe_archive_paths_to_add(
|
|
456
|
+
repo_root, task_name=task_name, modified_children=modified_children
|
|
457
|
+
)
|
|
458
|
+
if not paths:
|
|
459
|
+
print("[OK] No task changes to commit.", file=sys.stderr)
|
|
460
|
+
return
|
|
461
|
+
|
|
462
|
+
success, _, err = safe_git_add(paths, repo_root)
|
|
463
|
+
if not success:
|
|
464
|
+
if err and "ignored by" in err.lower():
|
|
465
|
+
print_gitignore_warning(paths)
|
|
466
|
+
else:
|
|
467
|
+
print(
|
|
468
|
+
f"[WARN] git add failed: {err.strip() if err else 'unknown error'}",
|
|
469
|
+
file=sys.stderr,
|
|
470
|
+
)
|
|
471
|
+
return
|
|
472
|
+
|
|
473
|
+
# Belt-and-suspenders for the phantom-delete bug: `safe_git_add` uses
|
|
474
|
+
# `git add` (no -A) which only stages additions/modifications. The
|
|
475
|
+
# source task directory was moved away by `shutil.move`, so its files
|
|
476
|
+
# need an explicit `git rm --cached` to stage the deletions in this
|
|
477
|
+
# same commit — otherwise they sit as uncommitted "phantom deletes"
|
|
478
|
+
# against HEAD until something later picks them up.
|
|
479
|
+
#
|
|
480
|
+
# `--ignore-unmatch` makes this a no-op when the task was never tracked
|
|
481
|
+
# (e.g. archiving a task that lived only in working tree).
|
|
482
|
+
source_rel = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}"
|
|
483
|
+
run_git(
|
|
484
|
+
["rm", "-r", "--cached", "--ignore-unmatch", "--", source_rel],
|
|
485
|
+
cwd=repo_root,
|
|
486
|
+
)
|
|
487
|
+
|
|
488
|
+
rc, _, _ = run_git(
|
|
489
|
+
["diff", "--cached", "--quiet", "--", *paths, source_rel],
|
|
490
|
+
cwd=repo_root,
|
|
491
|
+
)
|
|
492
|
+
if rc == 0:
|
|
493
|
+
print("[OK] No task changes to commit.", file=sys.stderr)
|
|
494
|
+
return
|
|
495
|
+
|
|
496
|
+
commit_msg = f"chore(task): archive {task_name}"
|
|
497
|
+
rc, _, err = run_git(["commit", "-m", commit_msg], cwd=repo_root)
|
|
498
|
+
if rc == 0:
|
|
499
|
+
print(f"[OK] Auto-committed: {commit_msg}", file=sys.stderr)
|
|
500
|
+
else:
|
|
501
|
+
print(f"[WARN] Auto-commit failed: {err.strip()}", file=sys.stderr)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
# =============================================================================
|
|
505
|
+
# Command: add-subtask
|
|
506
|
+
# =============================================================================
|
|
507
|
+
|
|
508
|
+
def cmd_add_subtask(args: argparse.Namespace) -> int:
|
|
509
|
+
"""Link a child task to a parent task."""
|
|
510
|
+
repo_root = get_repo_root()
|
|
511
|
+
|
|
512
|
+
parent_dir = resolve_task_dir(args.parent_dir, repo_root)
|
|
513
|
+
child_dir = resolve_task_dir(args.child_dir, repo_root)
|
|
514
|
+
|
|
515
|
+
parent_json_path = parent_dir / FILE_TASK_JSON
|
|
516
|
+
child_json_path = child_dir / FILE_TASK_JSON
|
|
517
|
+
|
|
518
|
+
if not parent_json_path.is_file():
|
|
519
|
+
print(colored(f"Error: Parent task.json not found: {args.parent_dir}", Colors.RED), file=sys.stderr)
|
|
520
|
+
return 1
|
|
521
|
+
|
|
522
|
+
if not child_json_path.is_file():
|
|
523
|
+
print(colored(f"Error: Child task.json not found: {args.child_dir}", Colors.RED), file=sys.stderr)
|
|
524
|
+
return 1
|
|
525
|
+
|
|
526
|
+
parent_data = read_json(parent_json_path)
|
|
527
|
+
child_data = read_json(child_json_path)
|
|
528
|
+
|
|
529
|
+
if not parent_data or not child_data:
|
|
530
|
+
print(colored("Error: Failed to read task.json", Colors.RED), file=sys.stderr)
|
|
531
|
+
return 1
|
|
532
|
+
|
|
533
|
+
# Check if child already has a parent
|
|
534
|
+
existing_parent = child_data.get("parent")
|
|
535
|
+
if existing_parent:
|
|
536
|
+
print(colored(f"Error: Child task already has a parent: {existing_parent}", Colors.RED), file=sys.stderr)
|
|
537
|
+
return 1
|
|
538
|
+
|
|
539
|
+
# Add child to parent's children list
|
|
540
|
+
parent_children = parent_data.get("children", [])
|
|
541
|
+
child_dir_name = child_dir.name
|
|
542
|
+
if child_dir_name not in parent_children:
|
|
543
|
+
parent_children.append(child_dir_name)
|
|
544
|
+
parent_data["children"] = parent_children
|
|
545
|
+
|
|
546
|
+
# Set parent in child's task.json
|
|
547
|
+
child_data["parent"] = parent_dir.name
|
|
548
|
+
|
|
549
|
+
# Write both
|
|
550
|
+
write_json(parent_json_path, parent_data)
|
|
551
|
+
write_json(child_json_path, child_data)
|
|
552
|
+
|
|
553
|
+
print(colored(f"Linked: {child_dir.name} -> {parent_dir.name}", Colors.GREEN), file=sys.stderr)
|
|
554
|
+
return 0
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
# =============================================================================
|
|
558
|
+
# Command: remove-subtask
|
|
559
|
+
# =============================================================================
|
|
560
|
+
|
|
561
|
+
def cmd_remove_subtask(args: argparse.Namespace) -> int:
|
|
562
|
+
"""Unlink a child task from a parent task."""
|
|
563
|
+
repo_root = get_repo_root()
|
|
564
|
+
|
|
565
|
+
parent_dir = resolve_task_dir(args.parent_dir, repo_root)
|
|
566
|
+
child_dir = resolve_task_dir(args.child_dir, repo_root)
|
|
567
|
+
|
|
568
|
+
parent_json_path = parent_dir / FILE_TASK_JSON
|
|
569
|
+
child_json_path = child_dir / FILE_TASK_JSON
|
|
570
|
+
|
|
571
|
+
if not parent_json_path.is_file():
|
|
572
|
+
print(colored(f"Error: Parent task.json not found: {args.parent_dir}", Colors.RED), file=sys.stderr)
|
|
573
|
+
return 1
|
|
574
|
+
|
|
575
|
+
if not child_json_path.is_file():
|
|
576
|
+
print(colored(f"Error: Child task.json not found: {args.child_dir}", Colors.RED), file=sys.stderr)
|
|
577
|
+
return 1
|
|
578
|
+
|
|
579
|
+
parent_data = read_json(parent_json_path)
|
|
580
|
+
child_data = read_json(child_json_path)
|
|
581
|
+
|
|
582
|
+
if not parent_data or not child_data:
|
|
583
|
+
print(colored("Error: Failed to read task.json", Colors.RED), file=sys.stderr)
|
|
584
|
+
return 1
|
|
585
|
+
|
|
586
|
+
# Remove child from parent's children list
|
|
587
|
+
parent_children = parent_data.get("children", [])
|
|
588
|
+
child_dir_name = child_dir.name
|
|
589
|
+
if child_dir_name in parent_children:
|
|
590
|
+
parent_children.remove(child_dir_name)
|
|
591
|
+
parent_data["children"] = parent_children
|
|
592
|
+
|
|
593
|
+
# Clear parent in child's task.json
|
|
594
|
+
child_data["parent"] = None
|
|
595
|
+
|
|
596
|
+
# Write both
|
|
597
|
+
write_json(parent_json_path, parent_data)
|
|
598
|
+
write_json(child_json_path, child_data)
|
|
599
|
+
|
|
600
|
+
print(colored(f"Unlinked: {child_dir.name} from {parent_dir.name}", Colors.GREEN), file=sys.stderr)
|
|
601
|
+
return 0
|
|
602
|
+
|
|
603
|
+
|
|
604
|
+
# =============================================================================
|
|
605
|
+
# Command: set-branch
|
|
606
|
+
# =============================================================================
|
|
607
|
+
|
|
608
|
+
def cmd_set_branch(args: argparse.Namespace) -> int:
|
|
609
|
+
"""Set git branch for task."""
|
|
610
|
+
repo_root = get_repo_root()
|
|
611
|
+
target_dir = resolve_task_dir(args.dir, repo_root)
|
|
612
|
+
branch = args.branch
|
|
613
|
+
|
|
614
|
+
if not branch:
|
|
615
|
+
print(colored("Error: Missing arguments", Colors.RED))
|
|
616
|
+
print("Usage: python3 task.py set-branch <task-dir> <branch-name>")
|
|
617
|
+
return 1
|
|
618
|
+
|
|
619
|
+
task_json = target_dir / FILE_TASK_JSON
|
|
620
|
+
if not task_json.is_file():
|
|
621
|
+
print(colored(f"Error: task.json not found at {target_dir}", Colors.RED))
|
|
622
|
+
return 1
|
|
623
|
+
|
|
624
|
+
data = read_json(task_json)
|
|
625
|
+
if not data:
|
|
626
|
+
return 1
|
|
627
|
+
|
|
628
|
+
data["branch"] = branch
|
|
629
|
+
write_json(task_json, data)
|
|
630
|
+
|
|
631
|
+
print(colored(f"✓ Branch set to: {branch}", Colors.GREEN))
|
|
632
|
+
return 0
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
# =============================================================================
|
|
636
|
+
# Command: set-base-branch
|
|
637
|
+
# =============================================================================
|
|
638
|
+
|
|
639
|
+
def cmd_set_base_branch(args: argparse.Namespace) -> int:
|
|
640
|
+
"""Set the base branch (PR target) for task."""
|
|
641
|
+
repo_root = get_repo_root()
|
|
642
|
+
target_dir = resolve_task_dir(args.dir, repo_root)
|
|
643
|
+
base_branch = args.base_branch
|
|
644
|
+
|
|
645
|
+
if not base_branch:
|
|
646
|
+
print(colored("Error: Missing arguments", Colors.RED))
|
|
647
|
+
print("Usage: python3 task.py set-base-branch <task-dir> <base-branch>")
|
|
648
|
+
print("Example: python3 task.py set-base-branch <dir> develop")
|
|
649
|
+
print()
|
|
650
|
+
print("This sets the target branch for PR (the branch your feature will merge into).")
|
|
651
|
+
return 1
|
|
652
|
+
|
|
653
|
+
task_json = target_dir / FILE_TASK_JSON
|
|
654
|
+
if not task_json.is_file():
|
|
655
|
+
print(colored(f"Error: task.json not found at {target_dir}", Colors.RED))
|
|
656
|
+
return 1
|
|
657
|
+
|
|
658
|
+
data = read_json(task_json)
|
|
659
|
+
if not data:
|
|
660
|
+
return 1
|
|
661
|
+
|
|
662
|
+
data["base_branch"] = base_branch
|
|
663
|
+
write_json(task_json, data)
|
|
664
|
+
|
|
665
|
+
print(colored(f"✓ Base branch set to: {base_branch}", Colors.GREEN))
|
|
666
|
+
print(f" PR will target: {base_branch}")
|
|
667
|
+
return 0
|
|
668
|
+
|
|
669
|
+
|
|
670
|
+
# =============================================================================
|
|
671
|
+
# Command: set-scope
|
|
672
|
+
# =============================================================================
|
|
673
|
+
|
|
674
|
+
def cmd_set_scope(args: argparse.Namespace) -> int:
|
|
675
|
+
"""Set scope for PR title."""
|
|
676
|
+
repo_root = get_repo_root()
|
|
677
|
+
target_dir = resolve_task_dir(args.dir, repo_root)
|
|
678
|
+
scope = args.scope
|
|
679
|
+
|
|
680
|
+
if not scope:
|
|
681
|
+
print(colored("Error: Missing arguments", Colors.RED))
|
|
682
|
+
print("Usage: python3 task.py set-scope <task-dir> <scope>")
|
|
683
|
+
return 1
|
|
684
|
+
|
|
685
|
+
task_json = target_dir / FILE_TASK_JSON
|
|
686
|
+
if not task_json.is_file():
|
|
687
|
+
print(colored(f"Error: task.json not found at {target_dir}", Colors.RED))
|
|
688
|
+
return 1
|
|
689
|
+
|
|
690
|
+
data = read_json(task_json)
|
|
691
|
+
if not data:
|
|
692
|
+
return 1
|
|
693
|
+
|
|
694
|
+
data["scope"] = scope
|
|
695
|
+
write_json(task_json, data)
|
|
696
|
+
|
|
697
|
+
print(colored(f"✓ Scope set to: {scope}", Colors.GREEN))
|
|
698
|
+
return 0
|