@blulotus/trellis 0.7.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/LICENSE +235 -0
- package/README.md +149 -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 +276 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/channel/adapters/claude.d.ts +29 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +203 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +93 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +573 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +86 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +115 -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 +158 -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 +311 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context-trust.d.ts +31 -0
- package/dist/commands/channel/context-trust.d.ts.map +1 -0
- package/dist/commands/channel/context-trust.js +139 -0
- package/dist/commands/channel/context-trust.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/guard.d.ts +150 -0
- package/dist/commands/channel/guard.d.ts.map +1 -0
- package/dist/commands/channel/guard.js +479 -0
- package/dist/commands/channel/guard.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 +535 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/interrupt.d.ts +10 -0
- package/dist/commands/channel/interrupt.d.ts.map +1 -0
- package/dist/commands/channel/interrupt.js +22 -0
- package/dist/commands/channel/interrupt.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 +15 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +245 -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 +30 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +130 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +11 -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 +43 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +247 -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 +77 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +272 -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 +146 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/idle.d.ts +45 -0
- package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/idle.js +70 -0
- package/dist/commands/channel/supervisor/idle.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +160 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +146 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +53 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +168 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor/turns.d.ts +31 -0
- package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/turns.js +45 -0
- package/dist/commands/channel/supervisor/turns.js.map +1 -0
- package/dist/commands/channel/supervisor/warning.d.ts +48 -0
- package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/warning.js +77 -0
- package/dist/commands/channel/supervisor/warning.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +75 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +397 -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 +17 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +75 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +71 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +1603 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mem.d.ts +30 -0
- package/dist/commands/mem.d.ts.map +1 -0
- package/dist/commands/mem.js +447 -0
- package/dist/commands/mem.js.map +1 -0
- package/dist/commands/uninstall.d.ts +36 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +410 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +111 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +2152 -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/commands/workflow.d.ts +52 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +454 -0
- package/dist/commands/workflow.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 +11 -0
- package/dist/configurators/antigravity.js.map +1 -0
- package/dist/configurators/claude.d.ts +23 -0
- package/dist/configurators/claude.d.ts.map +1 -0
- package/dist/configurators/claude.js +123 -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 +24 -0
- package/dist/configurators/codebuddy.js.map +1 -0
- package/dist/configurators/codex.d.ts +57 -0
- package/dist/configurators/codex.d.ts.map +1 -0
- package/dist/configurators/codex.js +170 -0
- package/dist/configurators/codex.js.map +1 -0
- package/dist/configurators/copilot.d.ts +14 -0
- package/dist/configurators/copilot.d.ts.map +1 -0
- package/dist/configurators/copilot.js +46 -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 +23 -0
- package/dist/configurators/cursor.js.map +1 -0
- package/dist/configurators/devin.d.ts +8 -0
- package/dist/configurators/devin.d.ts.map +1 -0
- package/dist/configurators/devin.js +12 -0
- package/dist/configurators/devin.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 +24 -0
- package/dist/configurators/droid.js.map +1 -0
- package/dist/configurators/dsh.d.ts +26 -0
- package/dist/configurators/dsh.d.ts.map +1 -0
- package/dist/configurators/dsh.js +76 -0
- package/dist/configurators/dsh.js.map +1 -0
- package/dist/configurators/gemini.d.ts +18 -0
- package/dist/configurators/gemini.d.ts.map +1 -0
- package/dist/configurators/gemini.js +39 -0
- package/dist/configurators/gemini.js.map +1 -0
- package/dist/configurators/grok.d.ts +17 -0
- package/dist/configurators/grok.d.ts.map +1 -0
- package/dist/configurators/grok.js +38 -0
- package/dist/configurators/grok.js.map +1 -0
- package/dist/configurators/index.d.ts +68 -0
- package/dist/configurators/index.d.ts.map +1 -0
- package/dist/configurators/index.js +191 -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 +11 -0
- package/dist/configurators/kilo.js.map +1 -0
- package/dist/configurators/kimi.d.ts +26 -0
- package/dist/configurators/kimi.d.ts.map +1 -0
- package/dist/configurators/kimi.js +74 -0
- package/dist/configurators/kimi.js.map +1 -0
- package/dist/configurators/kiro.d.ts +11 -0
- package/dist/configurators/kiro.d.ts.map +1 -0
- package/dist/configurators/kiro.js +30 -0
- package/dist/configurators/kiro.js.map +1 -0
- package/dist/configurators/omp.d.ts +6 -0
- package/dist/configurators/omp.d.ts.map +1 -0
- package/dist/configurators/omp.js +28 -0
- package/dist/configurators/omp.js.map +1 -0
- package/dist/configurators/opencode.d.ts +5 -0
- package/dist/configurators/opencode.d.ts.map +1 -0
- package/dist/configurators/opencode.js +84 -0
- package/dist/configurators/opencode.js.map +1 -0
- package/dist/configurators/pi.d.ts +5 -0
- package/dist/configurators/pi.d.ts.map +1 -0
- package/dist/configurators/pi.js +39 -0
- package/dist/configurators/pi.js.map +1 -0
- package/dist/configurators/qoder.d.ts +12 -0
- package/dist/configurators/qoder.d.ts.map +1 -0
- package/dist/configurators/qoder.js +30 -0
- package/dist/configurators/qoder.js.map +1 -0
- package/dist/configurators/reasonix.d.ts +17 -0
- package/dist/configurators/reasonix.d.ts.map +1 -0
- package/dist/configurators/reasonix.js +37 -0
- package/dist/configurators/reasonix.js.map +1 -0
- package/dist/configurators/shared.d.ts +187 -0
- package/dist/configurators/shared.d.ts.map +1 -0
- package/dist/configurators/shared.js +590 -0
- package/dist/configurators/shared.js.map +1 -0
- package/dist/configurators/snow.d.ts +25 -0
- package/dist/configurators/snow.d.ts.map +1 -0
- package/dist/configurators/snow.js +69 -0
- package/dist/configurators/snow.js.map +1 -0
- package/dist/configurators/trae.d.ts +16 -0
- package/dist/configurators/trae.d.ts.map +1 -0
- package/dist/configurators/trae.js +34 -0
- package/dist/configurators/trae.js.map +1 -0
- package/dist/configurators/workflow.d.ts +51 -0
- package/dist/configurators/workflow.d.ts.map +1 -0
- package/dist/configurators/workflow.js +210 -0
- package/dist/configurators/workflow.js.map +1 -0
- package/dist/configurators/zcode.d.ts +23 -0
- package/dist/configurators/zcode.d.ts.map +1 -0
- package/dist/configurators/zcode.js +63 -0
- package/dist/configurators/zcode.js.map +1 -0
- package/dist/constants/paths.d.ts +74 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +83 -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.16.json +9 -0
- package/dist/migrations/manifests/0.5.17.json +9 -0
- package/dist/migrations/manifests/0.5.18.json +9 -0
- package/dist/migrations/manifests/0.5.19.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.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.21.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.22.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.23.json +88 -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/migrations/manifests/0.6.0-rc.0.json +9 -0
- package/dist/migrations/manifests/0.6.0.json +1 -0
- package/dist/migrations/manifests/0.6.1.json +9 -0
- package/dist/migrations/manifests/0.6.10.json +9 -0
- package/dist/migrations/manifests/0.6.11.json +9 -0
- package/dist/migrations/manifests/0.6.12.json +9 -0
- package/dist/migrations/manifests/0.6.13.json +9 -0
- package/dist/migrations/manifests/0.6.14.json +9 -0
- package/dist/migrations/manifests/0.6.2.json +9 -0
- package/dist/migrations/manifests/0.6.3.json +24 -0
- package/dist/migrations/manifests/0.6.4.json +9 -0
- package/dist/migrations/manifests/0.6.5.json +9 -0
- package/dist/migrations/manifests/0.6.6.json +17 -0
- package/dist/migrations/manifests/0.6.7.json +9 -0
- package/dist/migrations/manifests/0.6.8.json +17 -0
- package/dist/migrations/manifests/0.6.9.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.0.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.1.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.3.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +115 -0
- package/dist/templates/claude/agents/trellis-implement.md +115 -0
- package/dist/templates/claude/agents/trellis-research.md +137 -0
- package/dist/templates/claude/hooks/statusline.py +332 -0
- package/dist/templates/claude/index.d.ts +31 -0
- package/dist/templates/claude/index.d.ts.map +1 -0
- package/dist/templates/claude/index.js +57 -0
- package/dist/templates/claude/index.js.map +1 -0
- package/dist/templates/claude/settings.json +95 -0
- package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
- package/dist/templates/codebuddy/agents/trellis-implement.md +115 -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 +69 -0
- package/dist/templates/codex/agents/trellis-check.toml +56 -0
- package/dist/templates/codex/agents/trellis-implement.toml +37 -0
- package/dist/templates/codex/agents/trellis-research.toml +78 -0
- package/dist/templates/codex/config.toml +39 -0
- package/dist/templates/codex/hooks/session-start.py +568 -0
- package/dist/templates/codex/hooks.json +52 -0
- package/dist/templates/codex/index.d.ts +35 -0
- package/dist/templates/codex/index.d.ts.map +1 -0
- package/dist/templates/codex/index.js +67 -0
- package/dist/templates/codex/index.js.map +1 -0
- package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +67 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +480 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +233 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +226 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +276 -0
- package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +128 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +85 -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 +56 -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 +123 -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/bundled-skills.md +159 -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/multi-agent-channel.md +69 -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 +130 -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 +84 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +73 -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 +113 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +87 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +81 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +65 -0
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +93 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/SKILL.md +41 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/repository-analysis.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +61 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-writing.md +70 -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 +46 -0
- package/dist/templates/common/skills/brainstorm.md +212 -0
- package/dist/templates/common/skills/break-loop.md +184 -0
- package/dist/templates/common/skills/check.md +106 -0
- package/dist/templates/common/skills/tdd.md +142 -0
- package/dist/templates/common/skills/update-spec.md +351 -0
- package/dist/templates/copilot/copilot-instructions.md +11 -0
- package/dist/templates/copilot/hooks/session-start.py +564 -0
- package/dist/templates/copilot/hooks.json +19 -0
- package/dist/templates/copilot/index.d.ts +28 -0
- package/dist/templates/copilot/index.d.ts.map +1 -0
- package/dist/templates/copilot/index.js +61 -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 +173 -0
- package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +170 -0
- package/dist/templates/copilot/prompts/check.prompt.md +110 -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 +114 -0
- package/dist/templates/cursor/agents/trellis-implement.md +114 -0
- package/dist/templates/cursor/agents/trellis-research.md +136 -0
- package/dist/templates/cursor/hooks.json +24 -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 +107 -0
- package/dist/templates/droid/droids/trellis-implement.md +107 -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 +69 -0
- package/dist/templates/dsh/DSH.md +80 -0
- package/dist/templates/dsh/agents/trellis-check.md +99 -0
- package/dist/templates/dsh/agents/trellis-implement.md +106 -0
- package/dist/templates/dsh/agents/trellis-research.md +134 -0
- package/dist/templates/dsh/index.d.ts +22 -0
- package/dist/templates/dsh/index.d.ts.map +1 -0
- package/dist/templates/dsh/index.js +27 -0
- package/dist/templates/dsh/index.js.map +1 -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 +107 -0
- package/dist/templates/gemini/agents/trellis-implement.md +107 -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 +40 -0
- package/dist/templates/grok/agents/trellis-check.md +106 -0
- package/dist/templates/grok/agents/trellis-implement.md +121 -0
- package/dist/templates/grok/agents/trellis-research.md +146 -0
- package/dist/templates/grok/index.d.ts +16 -0
- package/dist/templates/grok/index.d.ts.map +1 -0
- package/dist/templates/grok/index.js +19 -0
- package/dist/templates/grok/index.js.map +1 -0
- package/dist/templates/kimi/agents/trellis-check.md +104 -0
- package/dist/templates/kimi/agents/trellis-implement.md +120 -0
- package/dist/templates/kimi/agents/trellis-research.md +144 -0
- package/dist/templates/kimi/index.d.ts +20 -0
- package/dist/templates/kimi/index.d.ts.map +1 -0
- package/dist/templates/kimi/index.js +23 -0
- package/dist/templates/kimi/index.js.map +1 -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/agents/trellis.json +34 -0
- package/dist/templates/kiro/hooks/trellis-workflow-state.kiro.hook +14 -0
- package/dist/templates/kiro/index.d.ts +32 -0
- package/dist/templates/kiro/index.d.ts.map +1 -0
- package/dist/templates/kiro/index.js +28 -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 +327 -0
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +633 -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/omp/agents/trellis-check.md +41 -0
- package/dist/templates/omp/agents/trellis-implement.md +55 -0
- package/dist/templates/omp/agents/trellis-research.md +30 -0
- package/dist/templates/omp/extensions/trellis/index.ts.txt +592 -0
- package/dist/templates/omp/index.d.ts +4 -0
- package/dist/templates/omp/index.d.ts.map +1 -0
- package/dist/templates/omp/index.js +9 -0
- package/dist/templates/omp/index.js.map +1 -0
- package/dist/templates/opencode/agents/trellis-check.md +122 -0
- package/dist/templates/opencode/agents/trellis-implement.md +123 -0
- package/dist/templates/opencode/agents/trellis-research.md +145 -0
- package/dist/templates/opencode/lib/context-visibility.js +86 -0
- package/dist/templates/opencode/lib/session-utils.js +526 -0
- package/dist/templates/opencode/lib/trellis-context.js +627 -0
- package/dist/templates/opencode/package.json +5 -0
- package/dist/templates/opencode/plugins/inject-spec-context.js +121 -0
- package/dist/templates/opencode/plugins/inject-subagent-context.js +569 -0
- package/dist/templates/opencode/plugins/inject-workflow-state.js +340 -0
- package/dist/templates/opencode/plugins/session-start.js +74 -0
- package/dist/templates/pi/agents/trellis-check.md +37 -0
- package/dist/templates/pi/agents/trellis-implement.md +52 -0
- package/dist/templates/pi/agents/trellis-research.md +25 -0
- package/dist/templates/pi/extensions/trellis/index.ts.txt +2033 -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 +9 -0
- package/dist/templates/qoder/agents/trellis-check.md +108 -0
- package/dist/templates/qoder/agents/trellis-implement.md +108 -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 +59 -0
- package/dist/templates/reasonix/agents/trellis-check.md +36 -0
- package/dist/templates/reasonix/agents/trellis-implement.md +51 -0
- package/dist/templates/reasonix/index.d.ts +13 -0
- package/dist/templates/reasonix/index.d.ts.map +1 -0
- package/dist/templates/reasonix/index.js +16 -0
- package/dist/templates/reasonix/index.js.map +1 -0
- package/dist/templates/shared-hooks/index.d.ts +83 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +152 -0
- package/dist/templates/shared-hooks/index.js.map +1 -0
- package/dist/templates/shared-hooks/inject-shell-session-context.py +292 -0
- package/dist/templates/shared-hooks/inject-spec-context.py +844 -0
- package/dist/templates/shared-hooks/inject-subagent-context.py +1175 -0
- package/dist/templates/shared-hooks/inject-workflow-state.py +501 -0
- package/dist/templates/shared-hooks/session-start.py +969 -0
- package/dist/templates/snow/SNOW.md +86 -0
- package/dist/templates/snow/agents/trellis-check.md +136 -0
- package/dist/templates/snow/agents/trellis-implement.md +158 -0
- package/dist/templates/snow/agents/trellis-research.md +114 -0
- package/dist/templates/snow/hooks/beforeSubAgentStart.json +15 -0
- package/dist/templates/snow/hooks/onSessionStart.json +15 -0
- package/dist/templates/snow/hooks/onUserMessage.json +15 -0
- package/dist/templates/snow/hooks/write-trellis-context.py +644 -0
- package/dist/templates/snow/index.d.ts +26 -0
- package/dist/templates/snow/index.d.ts.map +1 -0
- package/dist/templates/snow/index.js +36 -0
- package/dist/templates/snow/index.js.map +1 -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 +64 -0
- package/dist/templates/template-utils.js.map +1 -0
- package/dist/templates/trae/agents/trellis-check.md +108 -0
- package/dist/templates/trae/agents/trellis-implement.md +108 -0
- package/dist/templates/trae/agents/trellis-research.md +137 -0
- package/dist/templates/trae/hooks.json +39 -0
- package/dist/templates/trae/index.d.ts +15 -0
- package/dist/templates/trae/index.d.ts.map +1 -0
- package/dist/templates/trae/index.js +15 -0
- package/dist/templates/trae/index.js.map +1 -0
- package/dist/templates/trellis/agents/check.md +70 -0
- package/dist/templates/trellis/agents/implement.md +81 -0
- package/dist/templates/trellis/config.yaml +205 -0
- package/dist/templates/trellis/gitattributes.txt +9 -0
- package/dist/templates/trellis/gitignore.txt +32 -0
- package/dist/templates/trellis/index.d.ts +70 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +127 -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 +681 -0
- package/dist/templates/trellis/scripts/common/__init__.py +92 -0
- package/dist/templates/trellis/scripts/common/active_task.py +787 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +982 -0
- package/dist/templates/trellis/scripts/common/config.py +587 -0
- package/dist/templates/trellis/scripts/common/developer.py +190 -0
- package/dist/templates/trellis/scripts/common/git.py +74 -0
- package/dist/templates/trellis/scripts/common/git_context.py +138 -0
- package/dist/templates/trellis/scripts/common/io.py +61 -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 +508 -0
- package/dist/templates/trellis/scripts/common/safe_commit.py +315 -0
- package/dist/templates/trellis/scripts/common/session_context.py +892 -0
- package/dist/templates/trellis/scripts/common/spec_inject.py +439 -0
- package/dist/templates/trellis/scripts/common/spec_match.py +395 -0
- package/dist/templates/trellis/scripts/common/task_context.py +372 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
- package/dist/templates/trellis/scripts/common/task_store.py +1016 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +309 -0
- package/dist/templates/trellis/scripts/common/tasks.py +112 -0
- package/dist/templates/trellis/scripts/common/trellis_config.py +132 -0
- package/dist/templates/trellis/scripts/common/types.py +110 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +243 -0
- package/dist/templates/trellis/scripts/common/workflow_selection.py +177 -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 +694 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +777 -0
- package/dist/templates/zcode/agents/trellis-check.md +110 -0
- package/dist/templates/zcode/agents/trellis-implement.md +116 -0
- package/dist/templates/zcode/agents/trellis-research.md +133 -0
- package/dist/templates/zcode/config.json +52 -0
- package/dist/templates/zcode/index.d.ts +25 -0
- package/dist/templates/zcode/index.d.ts.map +1 -0
- package/dist/templates/zcode/index.js +29 -0
- package/dist/templates/zcode/index.js.map +1 -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 +509 -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/agent-refs.d.ts +31 -0
- package/dist/utils/agent-refs.d.ts.map +1 -0
- package/dist/utils/agent-refs.js +63 -0
- package/dist/utils/agent-refs.js.map +1 -0
- package/dist/utils/atomic-write.d.ts +12 -0
- package/dist/utils/atomic-write.d.ts.map +1 -0
- package/dist/utils/atomic-write.js +30 -0
- package/dist/utils/atomic-write.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 +204 -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/registry-config.d.ts +7 -0
- package/dist/utils/registry-config.d.ts.map +1 -0
- package/dist/utils/registry-config.js +172 -0
- package/dist/utils/registry-config.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 +161 -0
- package/dist/utils/template-fetcher.d.ts.map +1 -0
- package/dist/utils/template-fetcher.js +994 -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 +335 -0
- package/dist/utils/template-hash.js.map +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts +67 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
- package/dist/utils/uninstall-scrubbers.js +361 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -0
- package/dist/utils/workflow-resolver.d.ts +86 -0
- package/dist/utils/workflow-resolver.d.ts.map +1 -0
- package/dist/utils/workflow-resolver.js +265 -0
- package/dist/utils/workflow-resolver.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,1175 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
Multi-Platform Sub-Agent Context Injection Hook
|
|
5
|
+
|
|
6
|
+
Injects task-specific context when sub-agents (implement, check, research) are spawned.
|
|
7
|
+
|
|
8
|
+
Core Design Philosophy:
|
|
9
|
+
- Hook is responsible for injecting all context, subagent works autonomously with complete info
|
|
10
|
+
- Each agent has a dedicated jsonl file defining its context
|
|
11
|
+
- No resume needed, no segmentation, behavior controlled by code not prompt
|
|
12
|
+
|
|
13
|
+
Trigger: PreToolUse (before Task tool call)
|
|
14
|
+
|
|
15
|
+
Context Source: Trellis active task resolver points to task directory
|
|
16
|
+
- implement.jsonl - Implement agent dedicated context
|
|
17
|
+
- check.jsonl - Check agent dedicated context
|
|
18
|
+
- prd.md - Requirements document
|
|
19
|
+
- design.md - Technical design for complex tasks
|
|
20
|
+
- implement.md - Execution plan for complex tasks
|
|
21
|
+
- codex-review-output.txt - Code Review results
|
|
22
|
+
"""
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
# IMPORTANT: Suppress all warnings FIRST
|
|
26
|
+
import warnings
|
|
27
|
+
warnings.filterwarnings("ignore")
|
|
28
|
+
|
|
29
|
+
import json
|
|
30
|
+
import os
|
|
31
|
+
import sys
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
from typing import Any
|
|
34
|
+
|
|
35
|
+
# Hook hosts send UTF-8 JSON regardless of the process locale.
|
|
36
|
+
_stdin_reconfigure = getattr(sys.stdin, "reconfigure", None)
|
|
37
|
+
if callable(_stdin_reconfigure):
|
|
38
|
+
try:
|
|
39
|
+
_stdin_reconfigure(encoding="utf-8", errors="replace")
|
|
40
|
+
except (OSError, ValueError):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
# IMPORTANT: Force stdout to use UTF-8 on Windows
|
|
44
|
+
# This fixes UnicodeEncodeError when outputting non-ASCII characters
|
|
45
|
+
if sys.platform.startswith("win"):
|
|
46
|
+
import io as _io
|
|
47
|
+
if hasattr(sys.stdout, "reconfigure"):
|
|
48
|
+
sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
49
|
+
elif hasattr(sys.stdout, "detach"):
|
|
50
|
+
sys.stdout = _io.TextIOWrapper(sys.stdout.detach(), encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# =============================================================================
|
|
54
|
+
# Path Constants (change here to rename directories)
|
|
55
|
+
# =============================================================================
|
|
56
|
+
|
|
57
|
+
DIR_WORKFLOW = ".trellis"
|
|
58
|
+
DIR_SPEC = "spec"
|
|
59
|
+
FILE_TASK_JSON = "task.json"
|
|
60
|
+
|
|
61
|
+
# =============================================================================
|
|
62
|
+
# Subagent Constants (change here to rename subagent types)
|
|
63
|
+
# =============================================================================
|
|
64
|
+
|
|
65
|
+
AGENT_IMPLEMENT = "trellis-implement"
|
|
66
|
+
AGENT_CHECK = "trellis-check"
|
|
67
|
+
AGENT_RESEARCH = "trellis-research"
|
|
68
|
+
|
|
69
|
+
# Agents that require a task directory
|
|
70
|
+
AGENTS_REQUIRE_TASK = (AGENT_IMPLEMENT, AGENT_CHECK)
|
|
71
|
+
# All supported agents
|
|
72
|
+
AGENTS_ALL = (AGENT_IMPLEMENT, AGENT_CHECK, AGENT_RESEARCH)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def find_repo_root(start_path: str) -> str | None:
|
|
76
|
+
"""
|
|
77
|
+
Find git repo root from start_path upwards
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
Repo root path, or None if not found
|
|
81
|
+
"""
|
|
82
|
+
current = Path(start_path).resolve()
|
|
83
|
+
while current != current.parent:
|
|
84
|
+
if (current / ".git").exists():
|
|
85
|
+
return str(current)
|
|
86
|
+
current = current.parent
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _detect_platform(input_data: dict) -> str | None:
|
|
91
|
+
if _hook_event_name(input_data) == "SubagentStart":
|
|
92
|
+
return "codex"
|
|
93
|
+
if isinstance(input_data.get("cursor_version"), str):
|
|
94
|
+
return "cursor"
|
|
95
|
+
# CLAUDE_PROJECT_DIR is a compatibility alias that several hosts set
|
|
96
|
+
# alongside their own variable — CodeBuddy, ZCode and Trae all do. It must
|
|
97
|
+
# therefore be checked LAST, or every one of them is detected as claude and
|
|
98
|
+
# the context key becomes `claude_<their-session-id>`. That key does not
|
|
99
|
+
# match the session file `task.py start` wrote under the host's real name,
|
|
100
|
+
# so the sub-agent starts with no task context while the pointer exists on
|
|
101
|
+
# disk. Same fix as inject-workflow-state.py and session-start.py; this
|
|
102
|
+
# third copy was missed when those two were corrected.
|
|
103
|
+
env_map = {
|
|
104
|
+
"ZCODE_PROJECT_DIR": "zcode",
|
|
105
|
+
"CURSOR_PROJECT_DIR": "cursor",
|
|
106
|
+
"CODEBUDDY_PROJECT_DIR": "codebuddy",
|
|
107
|
+
"FACTORY_PROJECT_DIR": "droid",
|
|
108
|
+
"GEMINI_PROJECT_DIR": "gemini",
|
|
109
|
+
"QODER_PROJECT_DIR": "qoder",
|
|
110
|
+
"KIRO_PROJECT_DIR": "kiro",
|
|
111
|
+
"COPILOT_PROJECT_DIR": "copilot",
|
|
112
|
+
"TRAE_PROJECT_DIR": "trae",
|
|
113
|
+
# Last: the shared alias, only meaningful once no vendor key matched.
|
|
114
|
+
"CLAUDE_PROJECT_DIR": "claude",
|
|
115
|
+
}
|
|
116
|
+
for env_name, platform in env_map.items():
|
|
117
|
+
if os.environ.get(env_name):
|
|
118
|
+
return platform
|
|
119
|
+
script_parts = set(Path(sys.argv[0]).parts)
|
|
120
|
+
if ".claude" in script_parts:
|
|
121
|
+
return "claude"
|
|
122
|
+
if ".cursor" in script_parts:
|
|
123
|
+
return "cursor"
|
|
124
|
+
if ".gemini" in script_parts:
|
|
125
|
+
return "gemini"
|
|
126
|
+
if ".qoder" in script_parts:
|
|
127
|
+
return "qoder"
|
|
128
|
+
if ".codebuddy" in script_parts:
|
|
129
|
+
return "codebuddy"
|
|
130
|
+
if ".factory" in script_parts:
|
|
131
|
+
return "droid"
|
|
132
|
+
if ".kiro" in script_parts:
|
|
133
|
+
return "kiro"
|
|
134
|
+
if ".zcode" in script_parts:
|
|
135
|
+
return "zcode"
|
|
136
|
+
return None
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def get_current_task(
|
|
140
|
+
repo_root: str,
|
|
141
|
+
input_data: dict,
|
|
142
|
+
*,
|
|
143
|
+
platform: str | None = None,
|
|
144
|
+
allow_single_session_fallback: bool = True,
|
|
145
|
+
allow_environment_context: bool = True,
|
|
146
|
+
require_existing: bool = False,
|
|
147
|
+
) -> str | None:
|
|
148
|
+
"""Resolve current task directory through the unified active task resolver."""
|
|
149
|
+
scripts_dir = Path(repo_root) / DIR_WORKFLOW / "scripts"
|
|
150
|
+
if str(scripts_dir) not in sys.path:
|
|
151
|
+
sys.path.insert(0, str(scripts_dir))
|
|
152
|
+
try:
|
|
153
|
+
from common.active_task import resolve_active_task # type: ignore[import-not-found]
|
|
154
|
+
except Exception:
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
active = resolve_active_task(
|
|
158
|
+
Path(repo_root),
|
|
159
|
+
input_data,
|
|
160
|
+
platform=platform or _detect_platform(input_data),
|
|
161
|
+
allow_single_session_fallback=allow_single_session_fallback,
|
|
162
|
+
allow_environment_context=allow_environment_context,
|
|
163
|
+
)
|
|
164
|
+
if require_existing and active.stale:
|
|
165
|
+
return None
|
|
166
|
+
return active.task_path
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# =============================================================================
|
|
170
|
+
# Context Injection Limits (issue #441)
|
|
171
|
+
#
|
|
172
|
+
# Notice text and behavior mirrored byte-for-byte in the Pi TS extension
|
|
173
|
+
# (templates/pi/extensions/trellis/index.ts.txt). Changing wording here
|
|
174
|
+
# requires changing it there too.
|
|
175
|
+
# =============================================================================
|
|
176
|
+
|
|
177
|
+
DEFAULT_MAX_FILE_BYTES = 32768
|
|
178
|
+
DEFAULT_MAX_ARTIFACT_BYTES = 65536
|
|
179
|
+
DEFAULT_MAX_TOTAL_BYTES = 131072
|
|
180
|
+
|
|
181
|
+
DEFAULT_LIMITS: dict[str, int] = {
|
|
182
|
+
"max_file_bytes": DEFAULT_MAX_FILE_BYTES,
|
|
183
|
+
"max_artifact_bytes": DEFAULT_MAX_ARTIFACT_BYTES,
|
|
184
|
+
"max_total_bytes": DEFAULT_MAX_TOTAL_BYTES,
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _get_limits(repo_root: str) -> dict[str, int]:
|
|
189
|
+
"""Load context-injection byte limits from config.yaml, with safe fallback."""
|
|
190
|
+
scripts_dir = Path(repo_root) / DIR_WORKFLOW / "scripts"
|
|
191
|
+
if str(scripts_dir) not in sys.path:
|
|
192
|
+
sys.path.insert(0, str(scripts_dir))
|
|
193
|
+
try:
|
|
194
|
+
from common.config import get_context_injection_limits # type: ignore[import-not-found]
|
|
195
|
+
|
|
196
|
+
return get_context_injection_limits(Path(repo_root))
|
|
197
|
+
except Exception:
|
|
198
|
+
return dict(DEFAULT_LIMITS)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
def truncate_utf8(data: bytes, cap: int) -> bytes:
|
|
202
|
+
"""Truncate ``data`` to at most ``cap`` bytes without splitting a UTF-8
|
|
203
|
+
multi-byte sequence.
|
|
204
|
+
|
|
205
|
+
``cap <= 0`` means "no limit" — returns ``data`` unchanged.
|
|
206
|
+
"""
|
|
207
|
+
if cap <= 0 or len(data) <= cap:
|
|
208
|
+
return data
|
|
209
|
+
|
|
210
|
+
truncated = data[:cap]
|
|
211
|
+
i = len(truncated)
|
|
212
|
+
# Back off over continuation bytes (10xxxxxx) to find the lead byte.
|
|
213
|
+
while i > 0 and (truncated[i - 1] & 0xC0) == 0x80:
|
|
214
|
+
i -= 1
|
|
215
|
+
if i == 0:
|
|
216
|
+
return b""
|
|
217
|
+
|
|
218
|
+
lead = truncated[i - 1]
|
|
219
|
+
if lead & 0x80:
|
|
220
|
+
if (lead & 0xE0) == 0xC0:
|
|
221
|
+
seq_len = 2
|
|
222
|
+
elif (lead & 0xF0) == 0xE0:
|
|
223
|
+
seq_len = 3
|
|
224
|
+
elif (lead & 0xF8) == 0xF0:
|
|
225
|
+
seq_len = 4
|
|
226
|
+
else:
|
|
227
|
+
seq_len = 1
|
|
228
|
+
# Cut before the lead byte when its full sequence didn't fit;
|
|
229
|
+
# otherwise the trailing sequence is complete — keep it whole.
|
|
230
|
+
if (i - 1) + seq_len > len(truncated):
|
|
231
|
+
return truncated[: i - 1]
|
|
232
|
+
|
|
233
|
+
return truncated
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class _Budget:
|
|
237
|
+
"""Tracks the running total of bytes emitted into the sub-agent context."""
|
|
238
|
+
|
|
239
|
+
def __init__(self, max_total_bytes: int) -> None:
|
|
240
|
+
self.max_total_bytes = max_total_bytes
|
|
241
|
+
self.used = 0
|
|
242
|
+
|
|
243
|
+
def has_room(self, size: int) -> bool:
|
|
244
|
+
if self.max_total_bytes <= 0:
|
|
245
|
+
return True
|
|
246
|
+
return self.used + size <= self.max_total_bytes
|
|
247
|
+
|
|
248
|
+
def add(self, size: int) -> None:
|
|
249
|
+
self.used += size
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _read_file_bytes(base_path: str, file_path: str) -> bytes | None:
|
|
253
|
+
"""Read raw file bytes, return None if file doesn't exist."""
|
|
254
|
+
full_path = os.path.join(base_path, file_path)
|
|
255
|
+
if os.path.exists(full_path) and os.path.isfile(full_path):
|
|
256
|
+
try:
|
|
257
|
+
with open(full_path, "rb") as f:
|
|
258
|
+
return f.read()
|
|
259
|
+
except Exception:
|
|
260
|
+
return None
|
|
261
|
+
return None
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _truncate_notice(path: str, cap: int) -> str:
|
|
265
|
+
return f"\n[Trellis: truncated at {cap} bytes — read {path} for the full content]"
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _is_binary_content(data: bytes) -> bool:
|
|
269
|
+
"""Return True when raw bytes should not be decoded into model context."""
|
|
270
|
+
if b"\x00" in data:
|
|
271
|
+
return True
|
|
272
|
+
try:
|
|
273
|
+
data.decode("utf-8", errors="strict")
|
|
274
|
+
except UnicodeDecodeError:
|
|
275
|
+
return True
|
|
276
|
+
return False
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def _binary_notice(path: str, size: int, reason: str) -> str:
|
|
280
|
+
return (
|
|
281
|
+
f"[Trellis: not inlined (binary file) — "
|
|
282
|
+
f"{path} ({size} bytes): {reason}]"
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def _index_notice(path: str, size: int, reason: str) -> str:
|
|
287
|
+
return (
|
|
288
|
+
f"[Trellis: not inlined (total context limit reached) — "
|
|
289
|
+
f"{path} ({size} bytes): {reason}]"
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _budgeted_block(
|
|
294
|
+
budget: _Budget,
|
|
295
|
+
header: str,
|
|
296
|
+
plain_path: str,
|
|
297
|
+
content: str,
|
|
298
|
+
reason: str,
|
|
299
|
+
size_for_index: int,
|
|
300
|
+
) -> str:
|
|
301
|
+
"""Return an inlined ``=== header ===`` block, or degrade to an index
|
|
302
|
+
notice once the total context budget is exhausted."""
|
|
303
|
+
block = f"=== {header} ===\n{content}"
|
|
304
|
+
block_bytes = len(block.encode("utf-8"))
|
|
305
|
+
if not budget.has_room(block_bytes):
|
|
306
|
+
notice = _index_notice(plain_path, size_for_index, reason)
|
|
307
|
+
budget.add(len(notice.encode("utf-8")))
|
|
308
|
+
return notice
|
|
309
|
+
budget.add(block_bytes)
|
|
310
|
+
return block
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def _materialize_file(
|
|
314
|
+
base_path: str,
|
|
315
|
+
file_path: str,
|
|
316
|
+
reason: str,
|
|
317
|
+
limits: dict[str, int],
|
|
318
|
+
budget: _Budget,
|
|
319
|
+
) -> str | None:
|
|
320
|
+
"""Read a JSONL-referenced file, apply the per-file cap, then budget it."""
|
|
321
|
+
data = _read_file_bytes(base_path, file_path)
|
|
322
|
+
if data is None:
|
|
323
|
+
return None
|
|
324
|
+
|
|
325
|
+
size = len(data)
|
|
326
|
+
if _is_binary_content(data):
|
|
327
|
+
notice = _binary_notice(file_path, size, reason)
|
|
328
|
+
budget.add(len(notice.encode("utf-8")))
|
|
329
|
+
return notice
|
|
330
|
+
|
|
331
|
+
cap = limits["max_file_bytes"]
|
|
332
|
+
truncated_bytes = truncate_utf8(data, cap)
|
|
333
|
+
content = truncated_bytes.decode("utf-8", errors="replace")
|
|
334
|
+
if len(truncated_bytes) < size:
|
|
335
|
+
content += _truncate_notice(file_path, cap)
|
|
336
|
+
|
|
337
|
+
return _budgeted_block(budget, file_path, file_path, content, reason, size)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def _materialize_directory(
|
|
341
|
+
base_path: str,
|
|
342
|
+
dir_path: str,
|
|
343
|
+
reason: str,
|
|
344
|
+
limits: dict[str, int],
|
|
345
|
+
budget: _Budget,
|
|
346
|
+
max_files: int = 20,
|
|
347
|
+
) -> list[str]:
|
|
348
|
+
"""Read all .md files in a directory, applying the same per-file and
|
|
349
|
+
total caps as a single-file JSONL entry."""
|
|
350
|
+
full_path = os.path.join(base_path, dir_path)
|
|
351
|
+
if not os.path.exists(full_path) or not os.path.isdir(full_path):
|
|
352
|
+
return []
|
|
353
|
+
|
|
354
|
+
blocks: list[str] = []
|
|
355
|
+
try:
|
|
356
|
+
md_files = sorted(
|
|
357
|
+
f
|
|
358
|
+
for f in os.listdir(full_path)
|
|
359
|
+
if f.endswith(".md") and os.path.isfile(os.path.join(full_path, f))
|
|
360
|
+
)
|
|
361
|
+
for filename in md_files[:max_files]:
|
|
362
|
+
relative_path = os.path.join(dir_path, filename)
|
|
363
|
+
block = _materialize_file(base_path, relative_path, reason, limits, budget)
|
|
364
|
+
if block:
|
|
365
|
+
blocks.append(block)
|
|
366
|
+
except Exception:
|
|
367
|
+
pass
|
|
368
|
+
|
|
369
|
+
return blocks
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def read_jsonl_entries(base_path: str, jsonl_path: str) -> list[dict]:
|
|
373
|
+
"""
|
|
374
|
+
Parse all file/directory entries referenced in a jsonl context file.
|
|
375
|
+
|
|
376
|
+
Schema:
|
|
377
|
+
{"file": "path/to/file.md", "reason": "..."}
|
|
378
|
+
{"file": "path/to/dir/", "type": "directory", "reason": "..."}
|
|
379
|
+
{"_example": "..."} # seed row — skipped (no `file` field)
|
|
380
|
+
|
|
381
|
+
Rows without a ``file`` field (e.g. the self-describing seed line written
|
|
382
|
+
by ``task.py create`` before the agent has curated entries) are skipped
|
|
383
|
+
silently. If the resulting entry list is empty, a stderr warning is
|
|
384
|
+
emitted so the operator can debug missing context.
|
|
385
|
+
|
|
386
|
+
Returns:
|
|
387
|
+
[{"file": path, "type": "file" | "directory", "reason": reason}, ...]
|
|
388
|
+
"""
|
|
389
|
+
full_path = os.path.join(base_path, jsonl_path)
|
|
390
|
+
if not os.path.exists(full_path):
|
|
391
|
+
print(
|
|
392
|
+
f"[inject-subagent-context] WARN: {jsonl_path} not found — "
|
|
393
|
+
f"sub-agent will receive only task artifacts",
|
|
394
|
+
file=sys.stderr,
|
|
395
|
+
)
|
|
396
|
+
return []
|
|
397
|
+
|
|
398
|
+
entries: list[dict] = []
|
|
399
|
+
saw_real_entry = False
|
|
400
|
+
try:
|
|
401
|
+
with open(full_path, "r", encoding="utf-8") as f:
|
|
402
|
+
for line in f:
|
|
403
|
+
line = line.strip()
|
|
404
|
+
if not line:
|
|
405
|
+
continue
|
|
406
|
+
try:
|
|
407
|
+
item = json.loads(line)
|
|
408
|
+
file_path = item.get("file") or item.get("path")
|
|
409
|
+
|
|
410
|
+
if not file_path:
|
|
411
|
+
# Seed / comment row — skip silently
|
|
412
|
+
continue
|
|
413
|
+
|
|
414
|
+
saw_real_entry = True
|
|
415
|
+
entries.append(
|
|
416
|
+
{
|
|
417
|
+
"file": file_path,
|
|
418
|
+
"type": item.get("type", "file"),
|
|
419
|
+
"reason": item.get("reason") or "-",
|
|
420
|
+
}
|
|
421
|
+
)
|
|
422
|
+
except json.JSONDecodeError:
|
|
423
|
+
continue
|
|
424
|
+
except Exception:
|
|
425
|
+
pass
|
|
426
|
+
|
|
427
|
+
if not saw_real_entry:
|
|
428
|
+
print(
|
|
429
|
+
f"[inject-subagent-context] WARN: {jsonl_path} has no curated "
|
|
430
|
+
f"entries (only seed / empty) — sub-agent will receive only "
|
|
431
|
+
f"task artifacts. See workflow.md planning artifact guidance.",
|
|
432
|
+
file=sys.stderr,
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
return entries
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
def _materialize_jsonl_entries(
|
|
439
|
+
base_path: str, jsonl_path: str, limits: dict[str, int], budget: _Budget
|
|
440
|
+
) -> list[str]:
|
|
441
|
+
"""Materialize every entry in a jsonl context file into context blocks,
|
|
442
|
+
applying per-file and total budget caps."""
|
|
443
|
+
blocks: list[str] = []
|
|
444
|
+
for entry in read_jsonl_entries(base_path, jsonl_path):
|
|
445
|
+
if entry["type"] == "directory":
|
|
446
|
+
blocks.extend(
|
|
447
|
+
_materialize_directory(
|
|
448
|
+
base_path, entry["file"], entry["reason"], limits, budget
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
else:
|
|
452
|
+
block = _materialize_file(
|
|
453
|
+
base_path, entry["file"], entry["reason"], limits, budget
|
|
454
|
+
)
|
|
455
|
+
if block:
|
|
456
|
+
blocks.append(block)
|
|
457
|
+
return blocks
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
def get_agent_context(
|
|
461
|
+
repo_root: str,
|
|
462
|
+
task_dir: str,
|
|
463
|
+
agent_type: str,
|
|
464
|
+
limits: dict[str, int],
|
|
465
|
+
budget: _Budget,
|
|
466
|
+
) -> str:
|
|
467
|
+
"""
|
|
468
|
+
Get context from {agent_type}.jsonl for the specified agent.
|
|
469
|
+
Only reads implement.jsonl or check.jsonl (the two JSONL files the task system creates).
|
|
470
|
+
"""
|
|
471
|
+
agent_jsonl = f"{task_dir}/{agent_type}.jsonl"
|
|
472
|
+
blocks = _materialize_jsonl_entries(repo_root, agent_jsonl, limits, budget)
|
|
473
|
+
return "\n\n".join(blocks)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def _materialize_artifact(
|
|
477
|
+
base_path: str,
|
|
478
|
+
file_path: str,
|
|
479
|
+
header_label: str,
|
|
480
|
+
reason: str,
|
|
481
|
+
limits: dict[str, int],
|
|
482
|
+
budget: _Budget,
|
|
483
|
+
) -> str | None:
|
|
484
|
+
"""Read a task artifact (prd/design/implement.md), apply the per-artifact
|
|
485
|
+
cap, then budget it."""
|
|
486
|
+
data = _read_file_bytes(base_path, file_path)
|
|
487
|
+
if data is None:
|
|
488
|
+
return None
|
|
489
|
+
|
|
490
|
+
size = len(data)
|
|
491
|
+
cap = limits["max_artifact_bytes"]
|
|
492
|
+
truncated_bytes = truncate_utf8(data, cap)
|
|
493
|
+
content = truncated_bytes.decode("utf-8", errors="replace")
|
|
494
|
+
if len(truncated_bytes) < size:
|
|
495
|
+
content += _truncate_notice(file_path, cap)
|
|
496
|
+
|
|
497
|
+
return _budgeted_block(budget, header_label, file_path, content, reason, size)
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
def get_implement_context(repo_root: str, task_dir: str) -> str:
|
|
501
|
+
"""
|
|
502
|
+
Complete context for Implement Agent
|
|
503
|
+
|
|
504
|
+
Read order:
|
|
505
|
+
1. All files in implement.jsonl (spec/research manifests)
|
|
506
|
+
2. prd.md (requirements)
|
|
507
|
+
3. design.md if present (technical design)
|
|
508
|
+
4. implement.md if present (execution plan)
|
|
509
|
+
"""
|
|
510
|
+
limits = _get_limits(repo_root)
|
|
511
|
+
budget = _Budget(limits["max_total_bytes"])
|
|
512
|
+
context_parts = []
|
|
513
|
+
|
|
514
|
+
# 1. Read implement.jsonl
|
|
515
|
+
base_context = get_agent_context(repo_root, task_dir, "implement", limits, budget)
|
|
516
|
+
if base_context:
|
|
517
|
+
context_parts.append(base_context)
|
|
518
|
+
|
|
519
|
+
# 2. Requirements document
|
|
520
|
+
prd_block = _materialize_artifact(
|
|
521
|
+
repo_root,
|
|
522
|
+
f"{task_dir}/prd.md",
|
|
523
|
+
f"{task_dir}/prd.md (Requirements)",
|
|
524
|
+
"Requirements document",
|
|
525
|
+
limits,
|
|
526
|
+
budget,
|
|
527
|
+
)
|
|
528
|
+
if prd_block:
|
|
529
|
+
context_parts.append(prd_block)
|
|
530
|
+
|
|
531
|
+
# 3. Technical design for complex tasks
|
|
532
|
+
design_block = _materialize_artifact(
|
|
533
|
+
repo_root,
|
|
534
|
+
f"{task_dir}/design.md",
|
|
535
|
+
f"{task_dir}/design.md (Technical Design)",
|
|
536
|
+
"Technical design document",
|
|
537
|
+
limits,
|
|
538
|
+
budget,
|
|
539
|
+
)
|
|
540
|
+
if design_block:
|
|
541
|
+
context_parts.append(design_block)
|
|
542
|
+
|
|
543
|
+
# 4. Execution plan for complex tasks
|
|
544
|
+
implement_plan_block = _materialize_artifact(
|
|
545
|
+
repo_root,
|
|
546
|
+
f"{task_dir}/implement.md",
|
|
547
|
+
f"{task_dir}/implement.md (Execution Plan)",
|
|
548
|
+
"Execution plan document",
|
|
549
|
+
limits,
|
|
550
|
+
budget,
|
|
551
|
+
)
|
|
552
|
+
if implement_plan_block:
|
|
553
|
+
context_parts.append(implement_plan_block)
|
|
554
|
+
|
|
555
|
+
return "\n\n".join(context_parts)
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def get_check_context(repo_root: str, task_dir: str) -> str:
|
|
559
|
+
"""
|
|
560
|
+
Context for Check Agent: check.jsonl + task artifacts.
|
|
561
|
+
"""
|
|
562
|
+
limits = _get_limits(repo_root)
|
|
563
|
+
budget = _Budget(limits["max_total_bytes"])
|
|
564
|
+
context_parts = []
|
|
565
|
+
|
|
566
|
+
base_context = get_agent_context(repo_root, task_dir, "check", limits, budget)
|
|
567
|
+
if base_context:
|
|
568
|
+
context_parts.append(base_context)
|
|
569
|
+
|
|
570
|
+
prd_block = _materialize_artifact(
|
|
571
|
+
repo_root,
|
|
572
|
+
f"{task_dir}/prd.md",
|
|
573
|
+
f"{task_dir}/prd.md (Requirements)",
|
|
574
|
+
"Requirements document",
|
|
575
|
+
limits,
|
|
576
|
+
budget,
|
|
577
|
+
)
|
|
578
|
+
if prd_block:
|
|
579
|
+
context_parts.append(prd_block)
|
|
580
|
+
|
|
581
|
+
design_block = _materialize_artifact(
|
|
582
|
+
repo_root,
|
|
583
|
+
f"{task_dir}/design.md",
|
|
584
|
+
f"{task_dir}/design.md (Technical Design)",
|
|
585
|
+
"Technical design document",
|
|
586
|
+
limits,
|
|
587
|
+
budget,
|
|
588
|
+
)
|
|
589
|
+
if design_block:
|
|
590
|
+
context_parts.append(design_block)
|
|
591
|
+
|
|
592
|
+
implement_plan_block = _materialize_artifact(
|
|
593
|
+
repo_root,
|
|
594
|
+
f"{task_dir}/implement.md",
|
|
595
|
+
f"{task_dir}/implement.md (Execution Plan)",
|
|
596
|
+
"Execution plan document",
|
|
597
|
+
limits,
|
|
598
|
+
budget,
|
|
599
|
+
)
|
|
600
|
+
if implement_plan_block:
|
|
601
|
+
context_parts.append(implement_plan_block)
|
|
602
|
+
|
|
603
|
+
return "\n\n".join(context_parts)
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
def get_finish_context(repo_root: str, task_dir: str) -> str:
|
|
607
|
+
"""
|
|
608
|
+
Context for Finish phase: reuses check.jsonl + prd.md
|
|
609
|
+
(Finish is a final check, same context source.)
|
|
610
|
+
"""
|
|
611
|
+
return get_check_context(repo_root, task_dir)
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
def build_implement_prompt(original_prompt: str, context: str) -> str:
|
|
616
|
+
"""Build complete prompt for Implement"""
|
|
617
|
+
return f"""<!-- trellis-hook-injected -->
|
|
618
|
+
# Implement Agent Task
|
|
619
|
+
|
|
620
|
+
You are the Implement Agent in the Multi-Agent Pipeline.
|
|
621
|
+
|
|
622
|
+
## Your Context
|
|
623
|
+
|
|
624
|
+
All the information you need has been prepared for you:
|
|
625
|
+
|
|
626
|
+
{context}
|
|
627
|
+
|
|
628
|
+
---
|
|
629
|
+
|
|
630
|
+
## Your Task
|
|
631
|
+
|
|
632
|
+
{original_prompt}
|
|
633
|
+
|
|
634
|
+
---
|
|
635
|
+
|
|
636
|
+
## Workflow
|
|
637
|
+
|
|
638
|
+
1. **Understand specs** - All dev specs are injected above, understand them
|
|
639
|
+
2. **Understand task artifacts** - Read requirements, technical design if present, and execution plan if present
|
|
640
|
+
3. **Implement feature** - Implement following specs and task artifacts
|
|
641
|
+
4. **Self-check** - Ensure code quality against check specs
|
|
642
|
+
|
|
643
|
+
## Important Constraints
|
|
644
|
+
|
|
645
|
+
- Do NOT execute git commit, only code modifications
|
|
646
|
+
- Follow all dev specs injected above
|
|
647
|
+
- Report list of modified/created files when done"""
|
|
648
|
+
|
|
649
|
+
|
|
650
|
+
def build_check_prompt(original_prompt: str, context: str) -> str:
|
|
651
|
+
"""Build complete prompt for Check"""
|
|
652
|
+
return f"""<!-- trellis-hook-injected -->
|
|
653
|
+
# Check Agent Task
|
|
654
|
+
|
|
655
|
+
You are the Check Agent in the Multi-Agent Pipeline (code and cross-layer checker).
|
|
656
|
+
|
|
657
|
+
## Your Context
|
|
658
|
+
|
|
659
|
+
All check specs and dev specs you need:
|
|
660
|
+
|
|
661
|
+
{context}
|
|
662
|
+
|
|
663
|
+
---
|
|
664
|
+
|
|
665
|
+
## Your Task
|
|
666
|
+
|
|
667
|
+
{original_prompt}
|
|
668
|
+
|
|
669
|
+
---
|
|
670
|
+
|
|
671
|
+
## Workflow
|
|
672
|
+
|
|
673
|
+
1. **Get changes** - Run `git diff --name-only` and `git diff` to get code changes
|
|
674
|
+
2. **Check against specs** - Check item by item against specs above
|
|
675
|
+
3. **Self-fix** - Fix issues directly, don't just report
|
|
676
|
+
4. **Run verification** - Run project's lint and typecheck commands
|
|
677
|
+
|
|
678
|
+
## Important Constraints
|
|
679
|
+
|
|
680
|
+
- Fix issues yourself, don't just report
|
|
681
|
+
- Must execute complete checklist in check specs
|
|
682
|
+
- Pay special attention to impact radius analysis (L1-L5)"""
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
def build_finish_prompt(original_prompt: str, context: str) -> str:
|
|
686
|
+
"""Build complete prompt for Finish (final check before PR)"""
|
|
687
|
+
return f"""<!-- trellis-hook-injected -->
|
|
688
|
+
# Finish Agent Task
|
|
689
|
+
|
|
690
|
+
You are performing the final check before creating a PR.
|
|
691
|
+
|
|
692
|
+
## Your Context
|
|
693
|
+
|
|
694
|
+
Finish checklist and requirements:
|
|
695
|
+
|
|
696
|
+
{context}
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
## Your Task
|
|
701
|
+
|
|
702
|
+
{original_prompt}
|
|
703
|
+
|
|
704
|
+
---
|
|
705
|
+
|
|
706
|
+
## Workflow
|
|
707
|
+
|
|
708
|
+
1. **Review changes** - Run `git diff --name-only` to see all changed files
|
|
709
|
+
2. **Verify task artifacts** - Check requirements in prd.md and, when present, design.md / implement.md
|
|
710
|
+
3. **Spec sync** - Analyze whether changes introduce new patterns, contracts, or conventions
|
|
711
|
+
- If new pattern/convention found: read target spec file → update it → update index.md if needed
|
|
712
|
+
- If infra/cross-layer change: follow the 7-section mandatory template from update-spec.md
|
|
713
|
+
- If pure code fix with no new patterns: skip this step
|
|
714
|
+
4. **Run final checks** - Execute lint and typecheck
|
|
715
|
+
5. **Confirm ready** - Ensure code is ready for PR
|
|
716
|
+
|
|
717
|
+
## Important Constraints
|
|
718
|
+
|
|
719
|
+
- You MAY update spec files when gaps are detected (use update-spec.md as guide)
|
|
720
|
+
- MUST read the target spec file BEFORE editing (avoid duplicating existing content)
|
|
721
|
+
- Do NOT update specs for trivial changes (typos, formatting, obvious fixes)
|
|
722
|
+
- If critical CODE issues found, report them clearly (fix specs, not code)
|
|
723
|
+
- Verify all acceptance criteria in prd.md are met
|
|
724
|
+
- Verify design.md and implement.md constraints when those files are present"""
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
def get_research_context(repo_root: str, task_dir: str | None) -> str:
|
|
729
|
+
"""
|
|
730
|
+
Context for Research Agent — project structure overview for spec directories.
|
|
731
|
+
|
|
732
|
+
`task_dir` kept for signature parity with get_implement_context / get_check_context
|
|
733
|
+
so the dispatcher can call them uniformly.
|
|
734
|
+
"""
|
|
735
|
+
_ = task_dir
|
|
736
|
+
context_parts = []
|
|
737
|
+
|
|
738
|
+
# 1. Project structure overview (dynamically discover spec directories)
|
|
739
|
+
spec_path = f"{DIR_WORKFLOW}/{DIR_SPEC}"
|
|
740
|
+
spec_root = Path(repo_root) / DIR_WORKFLOW / DIR_SPEC
|
|
741
|
+
|
|
742
|
+
# Build spec tree dynamically
|
|
743
|
+
tree_lines = [f"{spec_path}/"]
|
|
744
|
+
if spec_root.is_dir():
|
|
745
|
+
pkg_dirs = sorted(d for d in spec_root.iterdir() if d.is_dir())
|
|
746
|
+
for i, pkg_dir in enumerate(pkg_dirs):
|
|
747
|
+
is_last = i == len(pkg_dirs) - 1
|
|
748
|
+
prefix = "└── " if is_last else "├── "
|
|
749
|
+
layers = sorted(d.name for d in pkg_dir.iterdir() if d.is_dir())
|
|
750
|
+
layer_info = f" ({', '.join(layers)})" if layers else ""
|
|
751
|
+
tree_lines.append(f"{prefix}{pkg_dir.name}/{layer_info}")
|
|
752
|
+
|
|
753
|
+
spec_tree = "\n".join(tree_lines)
|
|
754
|
+
|
|
755
|
+
project_structure = f"""## Project Spec Directory Structure
|
|
756
|
+
|
|
757
|
+
```
|
|
758
|
+
{spec_tree}
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
To get structured package info, run: `python3 ./{DIR_WORKFLOW}/scripts/get_context.py --mode packages`
|
|
762
|
+
|
|
763
|
+
## Search Tips
|
|
764
|
+
|
|
765
|
+
- Spec files: `{spec_path}/**/*.md`
|
|
766
|
+
- Code search: Use Glob and Grep tools
|
|
767
|
+
- Tech solutions: Use mcp__exa__web_search_exa or mcp__exa__get_code_context_exa"""
|
|
768
|
+
|
|
769
|
+
context_parts.append(project_structure)
|
|
770
|
+
|
|
771
|
+
return "\n\n".join(context_parts)
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
def build_research_prompt(original_prompt: str, context: str) -> str:
|
|
775
|
+
"""Build complete prompt for Research"""
|
|
776
|
+
return f"""# Research Agent Task
|
|
777
|
+
|
|
778
|
+
You are the Research Agent in the Multi-Agent Pipeline (search researcher).
|
|
779
|
+
|
|
780
|
+
## Core Principle
|
|
781
|
+
|
|
782
|
+
**You do one thing: find and explain information.**
|
|
783
|
+
|
|
784
|
+
You are a documenter, not a reviewer.
|
|
785
|
+
|
|
786
|
+
## Project Info
|
|
787
|
+
|
|
788
|
+
{context}
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## Your Task
|
|
793
|
+
|
|
794
|
+
{original_prompt}
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
## Workflow
|
|
799
|
+
|
|
800
|
+
1. **Understand query** - Determine search type (internal/external) and scope
|
|
801
|
+
2. **Plan search** - List search steps for complex queries
|
|
802
|
+
3. **Execute search** - Execute multiple independent searches in parallel
|
|
803
|
+
4. **Organize results** - Output structured report
|
|
804
|
+
|
|
805
|
+
## Search Tools
|
|
806
|
+
|
|
807
|
+
| Tool | Purpose |
|
|
808
|
+
|------|---------|
|
|
809
|
+
| Glob | Search by filename pattern |
|
|
810
|
+
| Grep | Search by content |
|
|
811
|
+
| Read | Read file content |
|
|
812
|
+
| mcp__exa__web_search_exa | External web search |
|
|
813
|
+
| mcp__exa__get_code_context_exa | External code/doc search |
|
|
814
|
+
|
|
815
|
+
## Strict Boundaries
|
|
816
|
+
|
|
817
|
+
**Only allowed**: Describe what exists, where it is, how it works
|
|
818
|
+
|
|
819
|
+
**Forbidden** (unless explicitly asked):
|
|
820
|
+
- Suggest improvements
|
|
821
|
+
- Criticize implementation
|
|
822
|
+
- Recommend refactoring
|
|
823
|
+
- Modify any files
|
|
824
|
+
|
|
825
|
+
## Report Format
|
|
826
|
+
|
|
827
|
+
Provide structured search results including:
|
|
828
|
+
- List of files found (with paths)
|
|
829
|
+
- Code pattern analysis (if applicable)
|
|
830
|
+
- Related spec documents
|
|
831
|
+
- External references (if any)"""
|
|
832
|
+
|
|
833
|
+
|
|
834
|
+
def _string_value(value: Any) -> str:
|
|
835
|
+
if isinstance(value, str):
|
|
836
|
+
stripped = value.strip()
|
|
837
|
+
return stripped
|
|
838
|
+
return ""
|
|
839
|
+
|
|
840
|
+
|
|
841
|
+
def _hook_event_name(input_data: dict) -> str:
|
|
842
|
+
"""Return a hook event name from the documented snake/camel-case fields."""
|
|
843
|
+
return _string_value(
|
|
844
|
+
input_data.get("hook_event_name") or input_data.get("hookEventName")
|
|
845
|
+
)
|
|
846
|
+
|
|
847
|
+
|
|
848
|
+
def _codex_subagent_type(input_data: dict) -> str:
|
|
849
|
+
"""Return a Trellis Codex agent type only for a native start event."""
|
|
850
|
+
if _hook_event_name(input_data) != "SubagentStart":
|
|
851
|
+
return ""
|
|
852
|
+
agent_type = _string_value(
|
|
853
|
+
input_data.get("agent_type") or input_data.get("agentType")
|
|
854
|
+
)
|
|
855
|
+
return agent_type if agent_type in AGENTS_ALL else ""
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
def build_codex_subagent_context(
|
|
859
|
+
subagent_type: str,
|
|
860
|
+
task_dir: str,
|
|
861
|
+
context: str,
|
|
862
|
+
) -> str:
|
|
863
|
+
"""Build developer context for a native, already-dispatched Codex role."""
|
|
864
|
+
role = subagent_type.removeprefix("trellis-")
|
|
865
|
+
return f"""<!-- trellis-hook-injected -->
|
|
866
|
+
# Trellis Native {role.title()} Subagent
|
|
867
|
+
|
|
868
|
+
You are the dispatched `{subagent_type}` role for this task. Perform that role
|
|
869
|
+
directly; do not follow main-session dispatch or wait instructions, and do not
|
|
870
|
+
spawn another Trellis subagent.
|
|
871
|
+
|
|
872
|
+
Active task: {task_dir}
|
|
873
|
+
|
|
874
|
+
## Curated Context
|
|
875
|
+
|
|
876
|
+
{context}"""
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
def _handle_codex_subagent_start(input_data: dict) -> None:
|
|
880
|
+
"""Emit Codex developer context for a recognised native Trellis subagent.
|
|
881
|
+
|
|
882
|
+
The event supplies the parent session id. Disabling the generic
|
|
883
|
+
single-session fallback is essential here: native starts must never borrow
|
|
884
|
+
a task from another Codex window when that parent id is absent or stale.
|
|
885
|
+
"""
|
|
886
|
+
subagent_type = _codex_subagent_type(input_data)
|
|
887
|
+
parent_session_id = _string_value(input_data.get("session_id"))
|
|
888
|
+
if not subagent_type or not parent_session_id:
|
|
889
|
+
return
|
|
890
|
+
|
|
891
|
+
# Payload cwd first, then our own — some hosts (CodeBuddy IDE 4.10.4)
|
|
892
|
+
# report "/" for every hook event. See inject-workflow-state.py.
|
|
893
|
+
repo_root = None
|
|
894
|
+
for candidate in (_string_value(input_data.get("cwd")), os.getcwd()):
|
|
895
|
+
if not candidate:
|
|
896
|
+
continue
|
|
897
|
+
repo_root = find_repo_root(candidate)
|
|
898
|
+
if repo_root:
|
|
899
|
+
break
|
|
900
|
+
if not repo_root:
|
|
901
|
+
return
|
|
902
|
+
|
|
903
|
+
task_dir = get_current_task(
|
|
904
|
+
repo_root,
|
|
905
|
+
{"session_id": parent_session_id},
|
|
906
|
+
platform="codex",
|
|
907
|
+
allow_single_session_fallback=False,
|
|
908
|
+
allow_environment_context=False,
|
|
909
|
+
require_existing=True,
|
|
910
|
+
)
|
|
911
|
+
if not task_dir:
|
|
912
|
+
return
|
|
913
|
+
|
|
914
|
+
if subagent_type in AGENTS_REQUIRE_TASK:
|
|
915
|
+
task_dir_full = Path(repo_root) / task_dir
|
|
916
|
+
if not task_dir_full.is_dir():
|
|
917
|
+
return
|
|
918
|
+
|
|
919
|
+
if subagent_type == AGENT_IMPLEMENT:
|
|
920
|
+
context = get_implement_context(repo_root, task_dir)
|
|
921
|
+
elif subagent_type == AGENT_CHECK:
|
|
922
|
+
context = get_check_context(repo_root, task_dir)
|
|
923
|
+
else:
|
|
924
|
+
context = get_research_context(repo_root, task_dir)
|
|
925
|
+
|
|
926
|
+
if not context:
|
|
927
|
+
return
|
|
928
|
+
|
|
929
|
+
output = {
|
|
930
|
+
"hookSpecificOutput": {
|
|
931
|
+
"hookEventName": "SubagentStart",
|
|
932
|
+
"additionalContext": build_codex_subagent_context(
|
|
933
|
+
subagent_type, task_dir, context
|
|
934
|
+
),
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
print(json.dumps(output, ensure_ascii=False))
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
def _extract_subagent_name(value: Any) -> str:
|
|
941
|
+
"""Extract a sub-agent name from common platform encodings.
|
|
942
|
+
|
|
943
|
+
Cursor's native Task args encode custom sub-agents as a protobuf oneof,
|
|
944
|
+
which can appear in hook JSON as either ``{"custom": {"name": "..."}}``
|
|
945
|
+
or ``{"type": {"case": "custom", "value": {"name": "..."}}}``.
|
|
946
|
+
"""
|
|
947
|
+
direct = _string_value(value)
|
|
948
|
+
if direct:
|
|
949
|
+
return direct
|
|
950
|
+
|
|
951
|
+
if not isinstance(value, dict):
|
|
952
|
+
return ""
|
|
953
|
+
|
|
954
|
+
for key in ("name", "subagent_type_name", "subagentTypeName"):
|
|
955
|
+
direct = _string_value(value.get(key))
|
|
956
|
+
if direct:
|
|
957
|
+
return direct
|
|
958
|
+
|
|
959
|
+
custom = value.get("custom")
|
|
960
|
+
if isinstance(custom, dict):
|
|
961
|
+
custom_name = _string_value(custom.get("name"))
|
|
962
|
+
if custom_name:
|
|
963
|
+
return custom_name
|
|
964
|
+
|
|
965
|
+
oneof = value.get("type")
|
|
966
|
+
if isinstance(oneof, dict):
|
|
967
|
+
case_name = _string_value(oneof.get("case"))
|
|
968
|
+
if case_name == "custom":
|
|
969
|
+
nested_value = oneof.get("value")
|
|
970
|
+
if isinstance(nested_value, dict):
|
|
971
|
+
custom_name = _string_value(nested_value.get("name"))
|
|
972
|
+
if custom_name:
|
|
973
|
+
return custom_name
|
|
974
|
+
if case_name:
|
|
975
|
+
return case_name
|
|
976
|
+
|
|
977
|
+
case_name = _string_value(value.get("case"))
|
|
978
|
+
if case_name == "custom":
|
|
979
|
+
nested_value = value.get("value")
|
|
980
|
+
if isinstance(nested_value, dict):
|
|
981
|
+
custom_name = _string_value(nested_value.get("name"))
|
|
982
|
+
if custom_name:
|
|
983
|
+
return custom_name
|
|
984
|
+
if case_name:
|
|
985
|
+
return case_name
|
|
986
|
+
|
|
987
|
+
for agent_name in AGENTS_ALL:
|
|
988
|
+
if agent_name in value:
|
|
989
|
+
return agent_name
|
|
990
|
+
|
|
991
|
+
return ""
|
|
992
|
+
|
|
993
|
+
|
|
994
|
+
def _extract_subagent_type(tool_input: dict) -> str:
|
|
995
|
+
for key in (
|
|
996
|
+
"subagent_type",
|
|
997
|
+
"subagentType",
|
|
998
|
+
"subagent_type_name",
|
|
999
|
+
"subagentTypeName",
|
|
1000
|
+
"subagent_name",
|
|
1001
|
+
"subagentName",
|
|
1002
|
+
"agent_type",
|
|
1003
|
+
"agentType",
|
|
1004
|
+
"name",
|
|
1005
|
+
):
|
|
1006
|
+
agent_name = _extract_subagent_name(tool_input.get(key))
|
|
1007
|
+
if agent_name:
|
|
1008
|
+
return agent_name
|
|
1009
|
+
return ""
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
def _parse_hook_input(input_data: dict) -> tuple[str, str, dict]:
|
|
1013
|
+
"""Parse hook input across different platform formats.
|
|
1014
|
+
|
|
1015
|
+
Returns (subagent_type, original_prompt, tool_input).
|
|
1016
|
+
Handles:
|
|
1017
|
+
- Claude Code / Qoder / Droid: tool_name=Task|Agent, tool_input.subagent_type
|
|
1018
|
+
- CodeBuddy: tool_name=task (IDE) or Task (CLI), tool_input.subagent_name
|
|
1019
|
+
- Cursor: tool_name=Task|Subagent, tool_input.subagent_type
|
|
1020
|
+
- Copilot CLI: toolName=task (camelCase key, lowercase value)
|
|
1021
|
+
- ZCode: toolName=Agent, toolInput/tool_input.subagent_type
|
|
1022
|
+
- Gemini CLI: tool_name IS the agent name (BeforeTool matcher already filtered)
|
|
1023
|
+
- Kiro: agentSpawn hook, agent_name field at top level
|
|
1024
|
+
"""
|
|
1025
|
+
tool_input = input_data.get("tool_input", {})
|
|
1026
|
+
if not isinstance(tool_input, dict):
|
|
1027
|
+
tool_input = input_data.get("toolInput", {})
|
|
1028
|
+
if not isinstance(tool_input, dict):
|
|
1029
|
+
tool_input = {}
|
|
1030
|
+
|
|
1031
|
+
# Standard format: Task/Agent tool with subagent_type
|
|
1032
|
+
tool_name = input_data.get("tool_name", "") or input_data.get("toolName", "")
|
|
1033
|
+
if tool_name.lower() in ("task", "agent", "subagent"):
|
|
1034
|
+
return (
|
|
1035
|
+
_extract_subagent_type(tool_input),
|
|
1036
|
+
tool_input.get("prompt", ""),
|
|
1037
|
+
tool_input,
|
|
1038
|
+
)
|
|
1039
|
+
|
|
1040
|
+
# Kiro: agentSpawn hook passes agent_name at top level
|
|
1041
|
+
agent_name = input_data.get("agent_name", "")
|
|
1042
|
+
if agent_name:
|
|
1043
|
+
return agent_name, tool_input.get("prompt", input_data.get("prompt", "")), tool_input
|
|
1044
|
+
|
|
1045
|
+
# Gemini CLI: BeforeTool where tool_name IS the agent name
|
|
1046
|
+
# (matcher already ensured it's one of our agents)
|
|
1047
|
+
if tool_name in AGENTS_ALL:
|
|
1048
|
+
return tool_name, tool_input.get("prompt", ""), tool_input
|
|
1049
|
+
|
|
1050
|
+
# Copilot CLI: toolName field (camelCase), value might be the agent name
|
|
1051
|
+
tool_name_camel = input_data.get("toolName", "")
|
|
1052
|
+
if tool_name_camel in AGENTS_ALL:
|
|
1053
|
+
return tool_name_camel, input_data.get("toolArgs", ""), tool_input
|
|
1054
|
+
|
|
1055
|
+
return "", "", tool_input
|
|
1056
|
+
|
|
1057
|
+
|
|
1058
|
+
def main():
|
|
1059
|
+
if os.environ.get("TRELLIS_HOOKS") == "0" or os.environ.get("TRELLIS_DISABLE_HOOKS") == "1":
|
|
1060
|
+
sys.exit(0)
|
|
1061
|
+
|
|
1062
|
+
try:
|
|
1063
|
+
input_data = json.load(sys.stdin)
|
|
1064
|
+
except json.JSONDecodeError:
|
|
1065
|
+
sys.exit(0)
|
|
1066
|
+
if not isinstance(input_data, dict):
|
|
1067
|
+
sys.exit(0)
|
|
1068
|
+
|
|
1069
|
+
if _hook_event_name(input_data) == "SubagentStart":
|
|
1070
|
+
try:
|
|
1071
|
+
_handle_codex_subagent_start(input_data)
|
|
1072
|
+
except Exception:
|
|
1073
|
+
# A native context hook must never prevent Codex from spawning the
|
|
1074
|
+
# requested child when its runtime state is unavailable or stale.
|
|
1075
|
+
pass
|
|
1076
|
+
sys.exit(0)
|
|
1077
|
+
|
|
1078
|
+
subagent_type, original_prompt, tool_input = _parse_hook_input(input_data)
|
|
1079
|
+
cwd = input_data.get("cwd", os.getcwd())
|
|
1080
|
+
|
|
1081
|
+
# Only handle subagent types we care about
|
|
1082
|
+
if subagent_type not in AGENTS_ALL:
|
|
1083
|
+
sys.exit(0)
|
|
1084
|
+
|
|
1085
|
+
# Find repo root
|
|
1086
|
+
repo_root = find_repo_root(cwd)
|
|
1087
|
+
if not repo_root:
|
|
1088
|
+
sys.exit(0)
|
|
1089
|
+
|
|
1090
|
+
# Get current task directory (research doesn't require it)
|
|
1091
|
+
task_dir = get_current_task(repo_root, input_data)
|
|
1092
|
+
|
|
1093
|
+
# implement/check need task directory
|
|
1094
|
+
if subagent_type in AGENTS_REQUIRE_TASK:
|
|
1095
|
+
if not task_dir:
|
|
1096
|
+
sys.exit(0)
|
|
1097
|
+
# Contain the pointer before reading anything through it. `task.py` now
|
|
1098
|
+
# refuses to store a ref that leaves the repo, but a session file
|
|
1099
|
+
# written before that fix can still hold one, and `trellis update`
|
|
1100
|
+
# does not rewrite session files — so a poisoned pointer outlives the
|
|
1101
|
+
# upgrade that closed the writer. This is the last hop before the
|
|
1102
|
+
# task's prd.md/design.md reach the model prompt, so it checks again.
|
|
1103
|
+
try:
|
|
1104
|
+
root_real = os.path.realpath(repo_root)
|
|
1105
|
+
task_dir_full = os.path.realpath(os.path.join(repo_root, task_dir))
|
|
1106
|
+
# ValueError on Windows when the two sit on different drives; that
|
|
1107
|
+
# is outside the repo by definition, so it fails closed below.
|
|
1108
|
+
if os.path.commonpath([root_real, task_dir_full]) != root_real:
|
|
1109
|
+
sys.exit(0)
|
|
1110
|
+
except (OSError, ValueError):
|
|
1111
|
+
sys.exit(0)
|
|
1112
|
+
if not os.path.exists(task_dir_full):
|
|
1113
|
+
sys.exit(0)
|
|
1114
|
+
|
|
1115
|
+
# Check for [finish] marker in prompt (check agent with finish context)
|
|
1116
|
+
is_finish_phase = "[finish]" in original_prompt.lower()
|
|
1117
|
+
|
|
1118
|
+
# Get context and build prompt based on subagent type
|
|
1119
|
+
if subagent_type == AGENT_IMPLEMENT:
|
|
1120
|
+
assert task_dir is not None # validated above
|
|
1121
|
+
context = get_implement_context(repo_root, task_dir)
|
|
1122
|
+
new_prompt = build_implement_prompt(original_prompt, context)
|
|
1123
|
+
elif subagent_type == AGENT_CHECK:
|
|
1124
|
+
assert task_dir is not None # validated above
|
|
1125
|
+
if is_finish_phase:
|
|
1126
|
+
# Finish phase: use finish context (lighter, focused on final verification)
|
|
1127
|
+
context = get_finish_context(repo_root, task_dir)
|
|
1128
|
+
new_prompt = build_finish_prompt(original_prompt, context)
|
|
1129
|
+
else:
|
|
1130
|
+
# Regular check phase: use check context (full specs for self-fix loop)
|
|
1131
|
+
context = get_check_context(repo_root, task_dir)
|
|
1132
|
+
new_prompt = build_check_prompt(original_prompt, context)
|
|
1133
|
+
elif subagent_type == AGENT_RESEARCH:
|
|
1134
|
+
# Research can work without task directory
|
|
1135
|
+
context = get_research_context(repo_root, task_dir)
|
|
1136
|
+
new_prompt = build_research_prompt(original_prompt, context)
|
|
1137
|
+
else:
|
|
1138
|
+
sys.exit(0)
|
|
1139
|
+
|
|
1140
|
+
if not context:
|
|
1141
|
+
sys.exit(0)
|
|
1142
|
+
|
|
1143
|
+
# Return updated input. Most platforms ignore unrecognized fields, so we
|
|
1144
|
+
# include multiple formats. ZCode is stricter; live probing confirmed the
|
|
1145
|
+
# nested Claude-compatible shape below reaches the sub-agent prompt.
|
|
1146
|
+
updated = {**tool_input, "prompt": new_prompt}
|
|
1147
|
+
if _detect_platform(input_data) == "zcode":
|
|
1148
|
+
output = {
|
|
1149
|
+
"hookSpecificOutput": {
|
|
1150
|
+
"hookEventName": "PreToolUse",
|
|
1151
|
+
"permissionDecision": "allow",
|
|
1152
|
+
"updatedInput": updated,
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
else:
|
|
1156
|
+
output = {
|
|
1157
|
+
# Claude Code / Qoder / CodeBuddy / Droid format
|
|
1158
|
+
"hookSpecificOutput": {
|
|
1159
|
+
"hookEventName": "PreToolUse",
|
|
1160
|
+
"permissionDecision": "allow",
|
|
1161
|
+
"updatedInput": updated,
|
|
1162
|
+
},
|
|
1163
|
+
# Cursor format
|
|
1164
|
+
"permission": "allow",
|
|
1165
|
+
"updated_input": updated,
|
|
1166
|
+
# Gemini format
|
|
1167
|
+
"updatedInput": updated,
|
|
1168
|
+
}
|
|
1169
|
+
|
|
1170
|
+
print(json.dumps(output, ensure_ascii=False))
|
|
1171
|
+
sys.exit(0)
|
|
1172
|
+
|
|
1173
|
+
|
|
1174
|
+
if __name__ == "__main__":
|
|
1175
|
+
main()
|