@pennixrv/trellis 0.6.17
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 +168 -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 +299 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/commands/ablate.d.ts +14 -0
- package/dist/commands/ablate.d.ts.map +1 -0
- package/dist/commands/ablate.js +307 -0
- package/dist/commands/ablate.js.map +1 -0
- package/dist/commands/channel/adapters/claude.d.ts +53 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +225 -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 +94 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +116 -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 +130 -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 +134 -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 +22 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +43 -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 +153 -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 +71 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +229 -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 +91 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +463 -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 +81 -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 +423 -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 +205 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +104 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +2163 -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 +35 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +232 -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 +29 -0
- package/dist/configurators/dsh.d.ts.map +1 -0
- package/dist/configurators/dsh.js +64 -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 +80 -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 +589 -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 +25 -0
- package/dist/configurators/zcode.d.ts.map +1 -0
- package/dist/configurators/zcode.js +67 -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.15.json +9 -0
- package/dist/migrations/manifests/0.6.16.json +9 -0
- package/dist/migrations/manifests/0.6.17.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 +110 -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 +73 -0
- package/dist/templates/codebuddy/agents/trellis-check.md +115 -0
- package/dist/templates/codebuddy/agents/trellis-implement.md +110 -0
- package/dist/templates/codebuddy/agents/trellis-research.md +137 -0
- package/dist/templates/codebuddy/index.d.ts +15 -0
- package/dist/templates/codebuddy/index.d.ts.map +1 -0
- package/dist/templates/codebuddy/index.js +15 -0
- package/dist/templates/codebuddy/index.js.map +1 -0
- package/dist/templates/codebuddy/settings.json +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 +552 -0
- package/dist/templates/codex/hooks.json +27 -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 +83 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +72 -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 +112 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +86 -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 +195 -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/update-spec.md +351 -0
- package/dist/templates/copilot/copilot-instructions.md +11 -0
- package/dist/templates/copilot/hooks/session-start.py +548 -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 +156 -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 +109 -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 +102 -0
- package/dist/templates/droid/droids/trellis-research.md +137 -0
- package/dist/templates/droid/index.d.ts +15 -0
- package/dist/templates/droid/index.d.ts.map +1 -0
- package/dist/templates/droid/index.js +15 -0
- package/dist/templates/droid/index.js.map +1 -0
- package/dist/templates/droid/settings.json +69 -0
- package/dist/templates/dsh/DSH.md +56 -0
- package/dist/templates/dsh/index.d.ts +21 -0
- package/dist/templates/dsh/index.d.ts.map +1 -0
- package/dist/templates/dsh/index.js +25 -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 +102 -0
- package/dist/templates/gemini/agents/trellis-research.md +136 -0
- package/dist/templates/gemini/index.d.ts +13 -0
- package/dist/templates/gemini/index.d.ts.map +1 -0
- package/dist/templates/gemini/index.js +13 -0
- package/dist/templates/gemini/index.js.map +1 -0
- package/dist/templates/gemini/settings.json +40 -0
- package/dist/templates/grok/agents/trellis-check.md +105 -0
- package/dist/templates/grok/agents/trellis-implement.md +116 -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 +103 -0
- package/dist/templates/kimi/agents/trellis-implement.md +115 -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 +45 -0
- package/dist/templates/omp/agents/trellis-research.md +30 -0
- package/dist/templates/omp/extensions/trellis/index.ts.txt +1105 -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 +118 -0
- package/dist/templates/opencode/agents/trellis-research.md +145 -0
- package/dist/templates/opencode/lib/context-visibility.js +148 -0
- package/dist/templates/opencode/lib/session-utils.js +527 -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-subagent-context.js +569 -0
- package/dist/templates/opencode/plugins/inject-workflow-state.js +240 -0
- package/dist/templates/opencode/plugins/session-start.js +65 -0
- package/dist/templates/pi/agents/trellis-check.md +37 -0
- package/dist/templates/pi/agents/trellis-implement.md +42 -0
- package/dist/templates/pi/agents/trellis-research.md +25 -0
- package/dist/templates/pi/extensions/trellis/index.ts.txt +2027 -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 +103 -0
- package/dist/templates/qoder/agents/trellis-research.md +137 -0
- package/dist/templates/qoder/index.d.ts +15 -0
- package/dist/templates/qoder/index.d.ts.map +1 -0
- package/dist/templates/qoder/index.js +15 -0
- package/dist/templates/qoder/index.js.map +1 -0
- package/dist/templates/qoder/settings.json +59 -0
- package/dist/templates/reasonix/agents/trellis-check.md +36 -0
- package/dist/templates/reasonix/agents/trellis-implement.md +41 -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 +77 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +140 -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-subagent-context.py +1212 -0
- package/dist/templates/shared-hooks/inject-workflow-state.py +488 -0
- package/dist/templates/shared-hooks/session-start.py +949 -0
- package/dist/templates/snow/SNOW.md +86 -0
- package/dist/templates/snow/agents/trellis-check.md +135 -0
- package/dist/templates/snow/agents/trellis-implement.md +153 -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 +103 -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 +71 -0
- package/dist/templates/trellis/config.yaml +158 -0
- package/dist/templates/trellis/gitattributes.txt +9 -0
- package/dist/templates/trellis/gitignore.txt +32 -0
- package/dist/templates/trellis/index.d.ts +67 -0
- package/dist/templates/trellis/index.d.ts.map +1 -0
- package/dist/templates/trellis/index.js +121 -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 +1545 -0
- package/dist/templates/trellis/scripts/common/__init__.py +94 -0
- package/dist/templates/trellis/scripts/common/active_task.py +857 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +950 -0
- package/dist/templates/trellis/scripts/common/config.py +482 -0
- package/dist/templates/trellis/scripts/common/developer.py +192 -0
- package/dist/templates/trellis/scripts/common/git.py +203 -0
- package/dist/templates/trellis/scripts/common/git_context.py +106 -0
- package/dist/templates/trellis/scripts/common/io.py +160 -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 +543 -0
- package/dist/templates/trellis/scripts/common/safe_commit.py +322 -0
- package/dist/templates/trellis/scripts/common/session_context.py +892 -0
- package/dist/templates/trellis/scripts/common/task_context.py +470 -0
- package/dist/templates/trellis/scripts/common/task_queue.py +188 -0
- package/dist/templates/trellis/scripts/common/task_store.py +1874 -0
- package/dist/templates/trellis/scripts/common/task_utils.py +498 -0
- package/dist/templates/trellis/scripts/common/tasks.py +122 -0
- package/dist/templates/trellis/scripts/common/trellis_config.py +239 -0
- package/dist/templates/trellis/scripts/common/types.py +110 -0
- package/dist/templates/trellis/scripts/common/workflow_phase.py +242 -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 +801 -0
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +721 -0
- package/dist/templates/zcode/agents/trellis-check.md +109 -0
- package/dist/templates/zcode/agents/trellis-implement.md +111 -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 +105 -0
- package/dist/types/ai-tools.d.ts.map +1 -0
- package/dist/types/ai-tools.js +502 -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/ablation-store.d.ts +123 -0
- package/dist/utils/ablation-store.d.ts.map +1 -0
- package/dist/utils/ablation-store.js +749 -0
- package/dist/utils/ablation-store.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/managed-paths.d.ts +5 -0
- package/dist/utils/managed-paths.d.ts.map +1 -0
- package/dist/utils/managed-paths.js +51 -0
- package/dist/utils/managed-paths.js.map +1 -0
- package/dist/utils/managed-removal.d.ts +74 -0
- package/dist/utils/managed-removal.d.ts.map +1 -0
- package/dist/utils/managed-removal.js +270 -0
- package/dist/utils/managed-removal.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 +135 -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 +127 -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 +66 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -0
- package/dist/utils/uninstall-scrubbers.js +417 -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,498 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Task utility functions.
|
|
4
|
+
|
|
5
|
+
Provides:
|
|
6
|
+
is_within_tasks_dir - Check a resolved path is a task directly under tasks/
|
|
7
|
+
find_task_by_name - Find task directory by name
|
|
8
|
+
resolve_task_dir - Resolve task directory from name, relative, or absolute path
|
|
9
|
+
archive_destination_for - Path a task would be archived to
|
|
10
|
+
archive_task_dir - Archive task to monthly directory
|
|
11
|
+
run_task_hooks - Run lifecycle hooks for task events
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import shutil
|
|
17
|
+
import sys
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import TYPE_CHECKING
|
|
21
|
+
|
|
22
|
+
from .paths import get_repo_root, get_tasks_dir
|
|
23
|
+
|
|
24
|
+
if TYPE_CHECKING:
|
|
25
|
+
import subprocess
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# =============================================================================
|
|
29
|
+
# Path Safety
|
|
30
|
+
# =============================================================================
|
|
31
|
+
|
|
32
|
+
def is_within_tasks_dir(task_dir_abs: Path, repo_root: Path | None = None) -> bool:
|
|
33
|
+
"""Check that a resolved task directory really is a task under the tasks dir.
|
|
34
|
+
|
|
35
|
+
A real task lives directly at ``.trellis/tasks/<name>``. This returns True
|
|
36
|
+
only when ``task_dir_abs`` is an immediate child of the tasks directory.
|
|
37
|
+
|
|
38
|
+
Narrows ``resolve_task_dir``'s containment for archive: that chokepoint
|
|
39
|
+
accepts anything under the tasks dir, including a task already in
|
|
40
|
+
``archive/<YYYY-MM>/``. This rejects those, plus the tasks dir itself, so
|
|
41
|
+
``shutil.move`` never re-archives an archived task into a nested copy.
|
|
42
|
+
"""
|
|
43
|
+
if repo_root is None:
|
|
44
|
+
repo_root = get_repo_root()
|
|
45
|
+
try:
|
|
46
|
+
resolved = task_dir_abs.resolve()
|
|
47
|
+
tasks_resolved = get_tasks_dir(repo_root).resolve()
|
|
48
|
+
except (OSError, RuntimeError):
|
|
49
|
+
return False
|
|
50
|
+
if resolved.parent != tasks_resolved:
|
|
51
|
+
return False
|
|
52
|
+
return resolved.name != "archive"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# =============================================================================
|
|
56
|
+
# Task Lookup
|
|
57
|
+
# =============================================================================
|
|
58
|
+
|
|
59
|
+
def find_task_by_name(task_name: str, tasks_dir: Path) -> Path | None:
|
|
60
|
+
"""Find task directory by name (exact or suffix match).
|
|
61
|
+
|
|
62
|
+
A task name is a single directory name under ``tasks_dir``, never a path:
|
|
63
|
+
names carrying a separator or a dot segment are rejected before the join,
|
|
64
|
+
so ``".."`` cannot hand back the tasks dir's own parent.
|
|
65
|
+
|
|
66
|
+
An ambiguous suffix (two tasks created on different days with the same
|
|
67
|
+
slug) is a failure, not a coin flip — ``iterdir()`` order is filesystem
|
|
68
|
+
order, so silently picking the first match picks a different task on a
|
|
69
|
+
different machine.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
task_name: Task name to find.
|
|
73
|
+
tasks_dir: Tasks directory path.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Absolute path to task directory, or None if not found or ambiguous.
|
|
77
|
+
"""
|
|
78
|
+
if not task_name or not tasks_dir or not tasks_dir.is_dir():
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
if "/" in task_name or "\\" in task_name or task_name in (".", ".."):
|
|
82
|
+
print(f"Error: invalid task name: {task_name}", file=sys.stderr)
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
# Try exact match first
|
|
86
|
+
exact_match = tasks_dir / task_name
|
|
87
|
+
if exact_match.is_dir():
|
|
88
|
+
return exact_match
|
|
89
|
+
|
|
90
|
+
# Try suffix match (e.g., "my-task" matches "01-21-my-task")
|
|
91
|
+
matches = sorted(
|
|
92
|
+
d for d in tasks_dir.iterdir()
|
|
93
|
+
if d.is_dir() and d.name.endswith(f"-{task_name}")
|
|
94
|
+
)
|
|
95
|
+
if len(matches) == 1:
|
|
96
|
+
return matches[0]
|
|
97
|
+
if matches:
|
|
98
|
+
print(f"Error: ambiguous task name '{task_name}' matches:", file=sys.stderr)
|
|
99
|
+
for match in matches:
|
|
100
|
+
print(f" - {match.name}", file=sys.stderr)
|
|
101
|
+
print("Pass the full task directory name.", file=sys.stderr)
|
|
102
|
+
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# =============================================================================
|
|
107
|
+
# Archive Operations
|
|
108
|
+
# =============================================================================
|
|
109
|
+
|
|
110
|
+
def archive_destination_for(task_dir_abs: Path) -> Path:
|
|
111
|
+
"""Path a task would be archived to: <tasks>/archive/<YYYY-MM>/<name>."""
|
|
112
|
+
tasks_dir = task_dir_abs.parent
|
|
113
|
+
year_month = datetime.now().strftime("%Y-%m")
|
|
114
|
+
return tasks_dir / "archive" / year_month / task_dir_abs.name
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def archive_task_dir(task_dir_abs: Path, repo_root: Path | None = None) -> Path | None:
|
|
118
|
+
"""Archive a task directory to archive/{YYYY-MM}/.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
task_dir_abs: Absolute path to task directory.
|
|
122
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
Path to archived directory, or None on error.
|
|
126
|
+
"""
|
|
127
|
+
if not task_dir_abs.is_dir():
|
|
128
|
+
print(f"Error: task directory not found: {task_dir_abs}", file=sys.stderr)
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
dest = archive_destination_for(task_dir_abs)
|
|
132
|
+
month_dir = dest.parent
|
|
133
|
+
|
|
134
|
+
# Create archive directory
|
|
135
|
+
try:
|
|
136
|
+
month_dir.mkdir(parents=True, exist_ok=True)
|
|
137
|
+
except (OSError, IOError) as e:
|
|
138
|
+
print(f"Error: Failed to create archive directory: {e}", file=sys.stderr)
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
# shutil.move into an existing directory moves the source *inside* it,
|
|
142
|
+
# producing archive/<month>/<task>/<task>/ and returning a path that is not
|
|
143
|
+
# where the task actually landed. That wrong path then flows into the
|
|
144
|
+
# printed result, the after_archive hook's TASK_JSON_PATH, and auto-commit
|
|
145
|
+
# staging, so refuse before the move instead.
|
|
146
|
+
if dest.exists():
|
|
147
|
+
print(
|
|
148
|
+
f"Error: refusing to archive {task_dir_abs}: "
|
|
149
|
+
f"archive destination already exists: {dest}",
|
|
150
|
+
file=sys.stderr,
|
|
151
|
+
)
|
|
152
|
+
print(
|
|
153
|
+
"Move or rename the existing archived task, then retry.",
|
|
154
|
+
file=sys.stderr,
|
|
155
|
+
)
|
|
156
|
+
return None
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
shutil.move(str(task_dir_abs), str(dest))
|
|
160
|
+
except (OSError, IOError, shutil.Error) as e:
|
|
161
|
+
print(f"Error: Failed to move task to archive: {e}", file=sys.stderr)
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
return dest
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def archive_task_complete(
|
|
168
|
+
task_dir_abs: Path,
|
|
169
|
+
repo_root: Path | None = None
|
|
170
|
+
) -> dict[str, str]:
|
|
171
|
+
"""Complete archive workflow: archive directory.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
task_dir_abs: Absolute path to task directory.
|
|
175
|
+
repo_root: Repository root path. Defaults to auto-detected.
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Dict with archive result info.
|
|
179
|
+
"""
|
|
180
|
+
if not task_dir_abs.is_dir():
|
|
181
|
+
print(f"Error: task directory not found: {task_dir_abs}", file=sys.stderr)
|
|
182
|
+
return {}
|
|
183
|
+
|
|
184
|
+
archive_dest = archive_task_dir(task_dir_abs, repo_root)
|
|
185
|
+
if archive_dest:
|
|
186
|
+
return {"archived_to": str(archive_dest)}
|
|
187
|
+
|
|
188
|
+
return {}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# =============================================================================
|
|
192
|
+
# Task Directory Resolution
|
|
193
|
+
# =============================================================================
|
|
194
|
+
|
|
195
|
+
def resolve_task_dir(target_dir: str, repo_root: Path) -> Path | None:
|
|
196
|
+
"""Resolve task directory to an absolute path inside the tasks directory.
|
|
197
|
+
|
|
198
|
+
Supports:
|
|
199
|
+
- Absolute path: /path/to/task
|
|
200
|
+
- Relative path: .trellis/tasks/01-31-my-task
|
|
201
|
+
- Task name: my-task (uses find_task_by_name for lookup)
|
|
202
|
+
|
|
203
|
+
This is the containment chokepoint for every command that accepts a task
|
|
204
|
+
directory argument. The candidate is resolved (following symlinks) and must
|
|
205
|
+
land strictly under ``.trellis/tasks/``; archived tasks under
|
|
206
|
+
``archive/<YYYY-MM>/`` qualify. Traversal (``../victim``), absolute paths
|
|
207
|
+
outside the repo, a task dir symlinked out of the tasks tree, and the
|
|
208
|
+
tasks directory itself are all rejected here so no caller has to re-check.
|
|
209
|
+
The containment base is the tasks dir's own real location, so a
|
|
210
|
+
``.trellis`` that is itself a symlink into a shared store (#567) works.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
target_dir: Task directory specification.
|
|
214
|
+
repo_root: Repository root path.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
Absolute path spelled through the repo's own tasks dir (in-repo
|
|
218
|
+
lexical form), or None when it is not a location inside the tasks
|
|
219
|
+
directory (an error naming the path is printed to stderr).
|
|
220
|
+
"""
|
|
221
|
+
if not target_dir:
|
|
222
|
+
print("Error: task directory is required", file=sys.stderr)
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
normalized = target_dir.replace("\\", "/")
|
|
226
|
+
while normalized.startswith("./"):
|
|
227
|
+
normalized = normalized[2:]
|
|
228
|
+
|
|
229
|
+
tasks_dir = get_tasks_dir(repo_root)
|
|
230
|
+
|
|
231
|
+
if Path(target_dir).is_absolute():
|
|
232
|
+
candidate = Path(target_dir)
|
|
233
|
+
elif "/" in normalized or normalized.startswith(".trellis"):
|
|
234
|
+
# Relative path (contains path separator or starts with .trellis)
|
|
235
|
+
candidate = repo_root / Path(normalized)
|
|
236
|
+
else:
|
|
237
|
+
# Task name - must resolve inside the tasks directory. The historical
|
|
238
|
+
# fallback to repo_root/<name> only ever produced a path the check
|
|
239
|
+
# below rejects, so a miss ends here instead.
|
|
240
|
+
candidate = find_task_by_name(target_dir, tasks_dir)
|
|
241
|
+
if candidate is None:
|
|
242
|
+
# find_task_by_name reports invalid names and ambiguity itself.
|
|
243
|
+
print(
|
|
244
|
+
f"Error: could not resolve task '{target_dir}' under {tasks_dir}",
|
|
245
|
+
file=sys.stderr,
|
|
246
|
+
)
|
|
247
|
+
return None
|
|
248
|
+
|
|
249
|
+
try:
|
|
250
|
+
resolved = candidate.resolve()
|
|
251
|
+
tasks_lexical = get_tasks_dir(repo_root.resolve())
|
|
252
|
+
tasks_resolved = tasks_lexical.resolve()
|
|
253
|
+
except (OSError, RuntimeError) as e:
|
|
254
|
+
print(f"Error: could not resolve task directory '{target_dir}': {e}", file=sys.stderr)
|
|
255
|
+
return None
|
|
256
|
+
|
|
257
|
+
if resolved == tasks_resolved:
|
|
258
|
+
print(
|
|
259
|
+
f"Error: refusing to use '{target_dir}': {tasks_resolved} is the tasks "
|
|
260
|
+
"directory itself, not a task",
|
|
261
|
+
file=sys.stderr,
|
|
262
|
+
)
|
|
263
|
+
return None
|
|
264
|
+
|
|
265
|
+
if tasks_resolved not in resolved.parents:
|
|
266
|
+
print(
|
|
267
|
+
f"Error: refusing to use '{target_dir}': {resolved} is outside {tasks_resolved}",
|
|
268
|
+
file=sys.stderr,
|
|
269
|
+
)
|
|
270
|
+
return None
|
|
271
|
+
|
|
272
|
+
# Hand back the path spelled through the repo's own tasks dir rather than
|
|
273
|
+
# `resolved`: `.trellis` may be a symlink into a store outside the repo
|
|
274
|
+
# (#567), in which case `resolved` sits outside the repo even though the
|
|
275
|
+
# task is legitimate, and callers converting to a repo-relative ref for
|
|
276
|
+
# storage would refuse it.
|
|
277
|
+
return tasks_lexical / resolved.relative_to(tasks_resolved)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
# =============================================================================
|
|
281
|
+
# Lifecycle Hooks
|
|
282
|
+
# =============================================================================
|
|
283
|
+
|
|
284
|
+
HOOK_TIMEOUT_SECONDS = 60
|
|
285
|
+
HOOK_KILL_GRACE_SECONDS = 5
|
|
286
|
+
HOOK_OUTPUT_LIMIT = 2000
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _kill_hook_tree(proc: subprocess.Popen[str]) -> None:
|
|
290
|
+
"""Kill a timed-out hook's whole process tree, not just the shell.
|
|
291
|
+
|
|
292
|
+
With ``shell=True`` the direct child is the shell; the actual work runs in
|
|
293
|
+
its children. Killing only the shell leaves grandchildren alive holding the
|
|
294
|
+
inherited stdout/stderr pipes, and collecting output afterwards then blocks
|
|
295
|
+
until those orphans exit — the exact "command that never returns" the
|
|
296
|
+
timeout exists to prevent.
|
|
297
|
+
|
|
298
|
+
POSIX: the hook is started with ``start_new_session=True``, so the shell and
|
|
299
|
+
every descendant share one fresh process group; SIGKILL the group.
|
|
300
|
+
Windows: ``taskkill /F /T`` walks the tree (best effort).
|
|
301
|
+
Either way ``proc.kill()`` is the fallback.
|
|
302
|
+
|
|
303
|
+
Limitation: a hook that calls ``setsid`` itself leaves the group and
|
|
304
|
+
survives this. Accepted and out of scope — a hook is arbitrary code, and the
|
|
305
|
+
timeout is a liveness guarantee, not a containment boundary.
|
|
306
|
+
"""
|
|
307
|
+
import os
|
|
308
|
+
import signal
|
|
309
|
+
import subprocess
|
|
310
|
+
|
|
311
|
+
if os.name == "posix":
|
|
312
|
+
try:
|
|
313
|
+
os.killpg(os.getpgid(proc.pid), signal.SIGKILL)
|
|
314
|
+
return
|
|
315
|
+
except (ProcessLookupError, PermissionError, OSError):
|
|
316
|
+
pass
|
|
317
|
+
else:
|
|
318
|
+
try:
|
|
319
|
+
subprocess.run(
|
|
320
|
+
["taskkill", "/F", "/T", "/PID", str(proc.pid)],
|
|
321
|
+
capture_output=True,
|
|
322
|
+
)
|
|
323
|
+
except (OSError, ValueError):
|
|
324
|
+
pass
|
|
325
|
+
|
|
326
|
+
try:
|
|
327
|
+
proc.kill()
|
|
328
|
+
except OSError:
|
|
329
|
+
pass
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def _release_hook_process(proc: subprocess.Popen[str]) -> None:
|
|
333
|
+
"""Close our pipe ends and reap a finished hook under a bound.
|
|
334
|
+
|
|
335
|
+
``Popen`` used as a context manager calls ``wait()`` with no timeout when
|
|
336
|
+
the block exits. That is the one place the liveness guarantee could still
|
|
337
|
+
be lost: if ``_kill_hook_tree`` failed outright — both the process-group
|
|
338
|
+
kill and the direct kill raising — the lifecycle command would block there
|
|
339
|
+
forever, which is the exact hang the timeout exists to prevent.
|
|
340
|
+
"""
|
|
341
|
+
import subprocess
|
|
342
|
+
|
|
343
|
+
for stream in (proc.stdout, proc.stderr, proc.stdin):
|
|
344
|
+
if stream is not None:
|
|
345
|
+
try:
|
|
346
|
+
stream.close()
|
|
347
|
+
except OSError:
|
|
348
|
+
pass
|
|
349
|
+
try:
|
|
350
|
+
proc.wait(timeout=HOOK_KILL_GRACE_SECONDS)
|
|
351
|
+
except (subprocess.TimeoutExpired, OSError, ValueError):
|
|
352
|
+
# Leaves a zombie until this process exits. Fail-open and bounded beats
|
|
353
|
+
# a task command that never returns.
|
|
354
|
+
pass
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
def _decode_hook_output(raw: object) -> str:
|
|
358
|
+
"""TimeoutExpired carries bytes or str depending on the platform."""
|
|
359
|
+
if raw is None:
|
|
360
|
+
return ""
|
|
361
|
+
if isinstance(raw, bytes):
|
|
362
|
+
return raw.decode("utf-8", errors="replace")
|
|
363
|
+
return str(raw)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
def _print_hook_stream(name: str, text: str) -> None:
|
|
367
|
+
"""Print a captured hook stream to stderr, truncated."""
|
|
368
|
+
text = text.strip()
|
|
369
|
+
if not text:
|
|
370
|
+
return
|
|
371
|
+
if len(text) > HOOK_OUTPUT_LIMIT:
|
|
372
|
+
text = (
|
|
373
|
+
text[:HOOK_OUTPUT_LIMIT]
|
|
374
|
+
+ f"\n… ({len(text) - HOOK_OUTPUT_LIMIT} more characters truncated)"
|
|
375
|
+
)
|
|
376
|
+
print(f" {name}:", file=sys.stderr)
|
|
377
|
+
for line in text.splitlines():
|
|
378
|
+
print(f" {line}", file=sys.stderr)
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def run_task_hooks(event: str, task_json_path: Path, repo_root: Path) -> None:
|
|
382
|
+
"""Run lifecycle hooks for a task event.
|
|
383
|
+
|
|
384
|
+
Hooks are shell commands read from ``.trellis/config.yaml`` and executed
|
|
385
|
+
with ``shell=True`` from the repo root — see the trust boundary note in
|
|
386
|
+
``.trellis/spec/cli/backend/script-conventions.md``.
|
|
387
|
+
|
|
388
|
+
Fail-open by design: a broken hook warns and the lifecycle command
|
|
389
|
+
continues. The warning names the event, command, exit status, and both
|
|
390
|
+
captured streams, because a hook whose only symptom is "nothing happened"
|
|
391
|
+
is undebuggable. A hook that hangs is bounded by
|
|
392
|
+
``HOOK_TIMEOUT_SECONDS``; output is captured, so without the timeout the
|
|
393
|
+
user sees a task command that never returns and prints nothing. On timeout
|
|
394
|
+
the hook's entire process tree is killed (see ``_kill_hook_tree``) and
|
|
395
|
+
output is collected under a bounded grace, so a surviving grandchild
|
|
396
|
+
holding the pipes cannot re-create that same hang. Cleanup is bounded for
|
|
397
|
+
the same reason — see ``_release_hook_process``.
|
|
398
|
+
|
|
399
|
+
Args:
|
|
400
|
+
event: Event name (e.g. "after_create").
|
|
401
|
+
task_json_path: Absolute path to the task's task.json.
|
|
402
|
+
repo_root: Repository root for cwd and config lookup.
|
|
403
|
+
"""
|
|
404
|
+
import os
|
|
405
|
+
import subprocess
|
|
406
|
+
|
|
407
|
+
from .config import get_hooks
|
|
408
|
+
from .log import Colors, colored
|
|
409
|
+
|
|
410
|
+
commands = get_hooks(event, repo_root)
|
|
411
|
+
if not commands:
|
|
412
|
+
return
|
|
413
|
+
|
|
414
|
+
env = {**os.environ, "TASK_JSON_PATH": str(task_json_path)}
|
|
415
|
+
|
|
416
|
+
# POSIX only: a fresh session puts the shell and every descendant in one
|
|
417
|
+
# process group, which is what makes the timeout kill the whole tree.
|
|
418
|
+
popen_kwargs: dict = {}
|
|
419
|
+
if os.name == "posix":
|
|
420
|
+
popen_kwargs["start_new_session"] = True
|
|
421
|
+
|
|
422
|
+
for cmd in commands:
|
|
423
|
+
proc = None
|
|
424
|
+
try:
|
|
425
|
+
proc = subprocess.Popen(
|
|
426
|
+
cmd,
|
|
427
|
+
shell=True,
|
|
428
|
+
cwd=repo_root,
|
|
429
|
+
env=env,
|
|
430
|
+
stdout=subprocess.PIPE,
|
|
431
|
+
stderr=subprocess.PIPE,
|
|
432
|
+
text=True,
|
|
433
|
+
encoding="utf-8",
|
|
434
|
+
errors="replace",
|
|
435
|
+
**popen_kwargs,
|
|
436
|
+
)
|
|
437
|
+
try:
|
|
438
|
+
stdout, stderr = proc.communicate(timeout=HOOK_TIMEOUT_SECONDS)
|
|
439
|
+
except subprocess.TimeoutExpired as e:
|
|
440
|
+
_kill_hook_tree(proc)
|
|
441
|
+
stdout = _decode_hook_output(e.stdout)
|
|
442
|
+
stderr = _decode_hook_output(e.stderr)
|
|
443
|
+
try:
|
|
444
|
+
# Bounded: an orphan that escaped the kill still holds
|
|
445
|
+
# the pipes, and waiting on it forever here would be
|
|
446
|
+
# the very hang the timeout prevents.
|
|
447
|
+
rest_out, rest_err = proc.communicate(
|
|
448
|
+
timeout=HOOK_KILL_GRACE_SECONDS
|
|
449
|
+
)
|
|
450
|
+
stdout = rest_out or stdout
|
|
451
|
+
stderr = rest_err or stderr
|
|
452
|
+
except (subprocess.TimeoutExpired, OSError, ValueError):
|
|
453
|
+
pass
|
|
454
|
+
print(
|
|
455
|
+
colored(
|
|
456
|
+
f"[WARN] Hook timed out ({event}) after "
|
|
457
|
+
f"{HOOK_TIMEOUT_SECONDS}s: {cmd}",
|
|
458
|
+
Colors.YELLOW,
|
|
459
|
+
),
|
|
460
|
+
file=sys.stderr,
|
|
461
|
+
)
|
|
462
|
+
print(f" cwd: {repo_root}", file=sys.stderr)
|
|
463
|
+
_print_hook_stream("stdout", stdout)
|
|
464
|
+
_print_hook_stream("stderr", stderr)
|
|
465
|
+
continue
|
|
466
|
+
|
|
467
|
+
if proc.returncode != 0:
|
|
468
|
+
print(
|
|
469
|
+
colored(
|
|
470
|
+
f"[WARN] Hook failed ({event}): exit {proc.returncode}: {cmd}",
|
|
471
|
+
Colors.YELLOW,
|
|
472
|
+
),
|
|
473
|
+
file=sys.stderr,
|
|
474
|
+
)
|
|
475
|
+
print(f" cwd: {repo_root}", file=sys.stderr)
|
|
476
|
+
_print_hook_stream("stdout", stdout or "")
|
|
477
|
+
_print_hook_stream("stderr", stderr or "")
|
|
478
|
+
except Exception as e:
|
|
479
|
+
print(
|
|
480
|
+
colored(
|
|
481
|
+
f"[WARN] Hook error ({event}): {cmd} — {type(e).__name__}: {e}",
|
|
482
|
+
Colors.YELLOW,
|
|
483
|
+
),
|
|
484
|
+
file=sys.stderr,
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
# =============================================================================
|
|
489
|
+
# Main Entry (for testing)
|
|
490
|
+
# =============================================================================
|
|
491
|
+
|
|
492
|
+
if __name__ == "__main__":
|
|
493
|
+
repo = get_repo_root()
|
|
494
|
+
tasks = get_tasks_dir(repo)
|
|
495
|
+
|
|
496
|
+
print(f"Tasks dir: {tasks}")
|
|
497
|
+
print(f"resolve_task_dir('.trellis/tasks/test'): {resolve_task_dir('.trellis/tasks/test', repo)}")
|
|
498
|
+
print(f"resolve_task_dir('../test'): {resolve_task_dir('../test', repo)}")
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Task data access layer.
|
|
3
|
+
|
|
4
|
+
Single source of truth for loading and iterating task directories.
|
|
5
|
+
Replaces scattered task.json parsing across 9+ files.
|
|
6
|
+
|
|
7
|
+
Provides:
|
|
8
|
+
load_task — Load a single task by directory path
|
|
9
|
+
iter_active_tasks — Iterate all non-archived tasks (sorted)
|
|
10
|
+
get_all_statuses — Get {dir_name: status} map for children progress
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import sys
|
|
16
|
+
from collections.abc import Iterator
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from .io import describe_json_read_failure, read_json_checked
|
|
20
|
+
from .paths import FILE_TASK_JSON
|
|
21
|
+
from .types import TaskInfo
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def load_task(task_dir: Path) -> TaskInfo | None:
|
|
25
|
+
"""Load task from a directory containing task.json.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
task_dir: Absolute path to the task directory.
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
TaskInfo if task.json exists and is valid, None otherwise.
|
|
32
|
+
|
|
33
|
+
A directory without task.json is not a task, so it is skipped silently.
|
|
34
|
+
A task.json that exists but cannot be loaded is different: the task
|
|
35
|
+
disappears from `task.py list` and from every context the iterator feeds.
|
|
36
|
+
Callers stay tolerant, but the skip is announced on stderr so a task
|
|
37
|
+
cannot vanish from the workflow with no diagnostic anywhere.
|
|
38
|
+
"""
|
|
39
|
+
task_json = task_dir / FILE_TASK_JSON
|
|
40
|
+
if not task_json.is_file():
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
data, reason = read_json_checked(task_json)
|
|
44
|
+
if data is None:
|
|
45
|
+
problem, hint = describe_json_read_failure(task_json, reason)
|
|
46
|
+
print(f"[WARN] Skipping task '{task_dir.name}': {problem}", file=sys.stderr)
|
|
47
|
+
print(f" {hint}", file=sys.stderr)
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
return TaskInfo(
|
|
51
|
+
dir_name=task_dir.name,
|
|
52
|
+
directory=task_dir,
|
|
53
|
+
title=data.get("title") or data.get("name") or "unknown",
|
|
54
|
+
status=data.get("status", "unknown"),
|
|
55
|
+
assignee=data.get("assignee", ""),
|
|
56
|
+
priority=data.get("priority", "P2"),
|
|
57
|
+
children=tuple(data.get("children", [])),
|
|
58
|
+
parent=data.get("parent"),
|
|
59
|
+
package=data.get("package"),
|
|
60
|
+
raw=data,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def iter_active_tasks(tasks_dir: Path) -> Iterator[TaskInfo]:
|
|
65
|
+
"""Iterate all active (non-archived) tasks, sorted by directory name.
|
|
66
|
+
|
|
67
|
+
Skips the "archive" directory and directories without valid task.json.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
tasks_dir: Path to the tasks directory.
|
|
71
|
+
|
|
72
|
+
Yields:
|
|
73
|
+
TaskInfo for each valid task.
|
|
74
|
+
"""
|
|
75
|
+
if not tasks_dir.is_dir():
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
for d in sorted(tasks_dir.iterdir()):
|
|
79
|
+
if not d.is_dir() or d.name == "archive":
|
|
80
|
+
continue
|
|
81
|
+
info = load_task(d)
|
|
82
|
+
if info is not None:
|
|
83
|
+
yield info
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_all_statuses(tasks_dir: Path) -> dict[str, str]:
|
|
87
|
+
"""Get a {dir_name: status} mapping for all active tasks.
|
|
88
|
+
|
|
89
|
+
Useful for computing children progress without loading full TaskInfo.
|
|
90
|
+
|
|
91
|
+
Args:
|
|
92
|
+
tasks_dir: Path to the tasks directory.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Dict mapping directory names to status strings.
|
|
96
|
+
"""
|
|
97
|
+
return {t.dir_name: t.status for t in iter_active_tasks(tasks_dir)}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def children_progress(
|
|
101
|
+
children: tuple[str, ...] | list[str],
|
|
102
|
+
all_statuses: dict[str, str],
|
|
103
|
+
) -> str:
|
|
104
|
+
"""Format children progress string like " [2/3 done]".
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
children: List of child directory names.
|
|
108
|
+
all_statuses: Status map from get_all_statuses().
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Formatted string, or "" if no children.
|
|
112
|
+
"""
|
|
113
|
+
if not children:
|
|
114
|
+
return ""
|
|
115
|
+
# A child missing from active statuses has been archived (cmd_archive
|
|
116
|
+
# sets status=completed before moving the dir). Count it as done so
|
|
117
|
+
# parent progress doesn't regress when children are archived.
|
|
118
|
+
done = sum(
|
|
119
|
+
1 for c in children
|
|
120
|
+
if c not in all_statuses or all_statuses.get(c) in ("completed", "done")
|
|
121
|
+
)
|
|
122
|
+
return f" [{done}/{len(children)} done]"
|