@mindfoldhq/trellis 0.4.0 → 0.5.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +0 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +0 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -4
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts +5 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +83 -22
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/antigravity.d.ts +3 -4
- package/dist/configurators/antigravity.d.ts.map +1 -1
- package/dist/configurators/antigravity.js +17 -10
- package/dist/configurators/antigravity.js.map +1 -1
- package/dist/configurators/claude.d.ts +5 -28
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +30 -51
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/codebuddy.d.ts +6 -7
- package/dist/configurators/codebuddy.d.ts.map +1 -1
- package/dist/configurators/codebuddy.js +23 -51
- package/dist/configurators/codebuddy.js.map +1 -1
- package/dist/configurators/codex.d.ts +3 -6
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +29 -12
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/copilot.d.ts +6 -5
- package/dist/configurators/copilot.d.ts.map +1 -1
- package/dist/configurators/copilot.js +42 -13
- package/dist/configurators/copilot.js.map +1 -1
- package/dist/configurators/cursor.d.ts +6 -1
- package/dist/configurators/cursor.d.ts.map +1 -1
- package/dist/configurators/cursor.js +22 -45
- package/dist/configurators/cursor.js.map +1 -1
- package/dist/configurators/droid.d.ts +6 -1
- package/dist/configurators/droid.d.ts.map +1 -1
- package/dist/configurators/droid.js +23 -41
- package/dist/configurators/droid.js.map +1 -1
- package/dist/configurators/gemini.d.ts +8 -4
- package/dist/configurators/gemini.d.ts.map +1 -1
- package/dist/configurators/gemini.js +28 -47
- package/dist/configurators/gemini.js.map +1 -1
- package/dist/configurators/index.d.ts +1 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +142 -98
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/kilo.d.ts +3 -4
- package/dist/configurators/kilo.d.ts.map +1 -1
- package/dist/configurators/kilo.js +19 -46
- package/dist/configurators/kilo.js.map +1 -1
- package/dist/configurators/kiro.d.ts +4 -4
- package/dist/configurators/kiro.d.ts.map +1 -1
- package/dist/configurators/kiro.js +18 -14
- package/dist/configurators/kiro.js.map +1 -1
- package/dist/configurators/opencode.d.ts +3 -28
- package/dist/configurators/opencode.d.ts.map +1 -1
- package/dist/configurators/opencode.js +23 -48
- package/dist/configurators/opencode.js.map +1 -1
- package/dist/configurators/qoder.d.ts +6 -4
- package/dist/configurators/qoder.d.ts.map +1 -1
- package/dist/configurators/qoder.js +20 -47
- package/dist/configurators/qoder.js.map +1 -1
- package/dist/configurators/shared.d.ts +66 -3
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +251 -3
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/windsurf.d.ts +3 -4
- package/dist/configurators/windsurf.d.ts.map +1 -1
- package/dist/configurators/windsurf.js +17 -10
- package/dist/configurators/windsurf.js.map +1 -1
- package/dist/configurators/workflow.d.ts +0 -3
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +1 -7
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/migrations/manifests/0.4.0.json +1 -1
- package/dist/migrations/manifests/0.5.0-beta.0.json +1644 -0
- package/dist/templates/claude/agents/check.md +2 -29
- package/dist/templates/claude/agents/research.md +70 -52
- package/dist/templates/claude/index.d.ts +5 -37
- package/dist/templates/claude/index.d.ts.map +1 -1
- package/dist/templates/claude/index.js +3 -42
- package/dist/templates/claude/index.js.map +1 -1
- package/dist/templates/claude/settings.json +3 -4
- package/dist/templates/{iflow → codebuddy}/agents/check.md +3 -30
- package/dist/templates/{iflow → codebuddy}/agents/implement.md +1 -1
- package/dist/templates/codebuddy/agents/research.md +138 -0
- package/dist/templates/codebuddy/index.d.ts +6 -16
- package/dist/templates/codebuddy/index.d.ts.map +1 -1
- package/dist/templates/codebuddy/index.js +6 -36
- package/dist/templates/codebuddy/index.js.map +1 -1
- package/dist/templates/codebuddy/settings.json +59 -0
- package/dist/templates/codex/agents/research.toml +50 -16
- package/dist/templates/codex/config.toml +10 -0
- package/dist/templates/codex/hooks/session-start.py +65 -29
- package/dist/templates/codex/hooks.json +11 -0
- package/dist/templates/codex/index.d.ts +0 -1
- package/dist/templates/codex/index.d.ts.map +1 -1
- package/dist/templates/codex/index.js +1 -8
- package/dist/templates/codex/index.js.map +1 -1
- package/dist/templates/common/commands/continue.md +51 -0
- package/dist/templates/common/commands/finish-work.md +32 -0
- package/dist/templates/common/commands/start.md +56 -0
- package/dist/templates/common/index.d.ts +28 -0
- package/dist/templates/common/index.d.ts.map +1 -0
- package/dist/templates/common/index.js +55 -0
- package/dist/templates/common/index.js.map +1 -0
- package/dist/templates/{codebuddy/commands/trellis → common/skills}/brainstorm.md +4 -4
- package/dist/templates/{opencode/commands/trellis → common/skills}/break-loop.md +4 -4
- package/dist/templates/common/skills/check.md +87 -0
- package/dist/templates/{codebuddy/commands/trellis → common/skills}/update-spec.md +18 -21
- package/dist/templates/copilot/hooks/session-start.py +65 -29
- package/dist/templates/copilot/hooks.json +8 -0
- package/dist/templates/cursor/agents/check.md +95 -0
- package/dist/templates/cursor/agents/implement.md +95 -0
- package/dist/templates/cursor/agents/research.md +138 -0
- package/dist/templates/cursor/hooks.json +24 -0
- package/dist/templates/cursor/index.d.ts +6 -17
- package/dist/templates/cursor/index.d.ts.map +1 -1
- package/dist/templates/cursor/index.js +6 -37
- package/dist/templates/cursor/index.js.map +1 -1
- package/dist/templates/droid/droids/check.md +95 -0
- package/dist/templates/droid/droids/implement.md +95 -0
- package/dist/templates/droid/droids/research.md +138 -0
- package/dist/templates/droid/index.d.ts +7 -19
- package/dist/templates/droid/index.d.ts.map +1 -1
- package/dist/templates/droid/index.js +7 -39
- package/dist/templates/droid/index.js.map +1 -1
- package/dist/templates/droid/settings.json +59 -0
- package/dist/templates/extract.d.ts +7 -193
- package/dist/templates/extract.d.ts.map +1 -1
- package/dist/templates/extract.js +7 -310
- package/dist/templates/extract.js.map +1 -1
- package/dist/templates/gemini/agents/check.md +95 -0
- package/dist/templates/gemini/agents/implement.md +95 -0
- package/dist/templates/gemini/agents/research.md +138 -0
- package/dist/templates/gemini/index.d.ts +6 -14
- package/dist/templates/gemini/index.d.ts.map +1 -1
- package/dist/templates/gemini/index.js +6 -37
- package/dist/templates/gemini/index.js.map +1 -1
- package/dist/templates/gemini/settings.json +28 -0
- package/dist/templates/kiro/agents/check.json +13 -0
- package/dist/templates/kiro/agents/implement.json +13 -0
- package/dist/templates/kiro/agents/research.json +21 -0
- package/dist/templates/kiro/index.d.ts +11 -11
- package/dist/templates/kiro/index.d.ts.map +1 -1
- package/dist/templates/kiro/index.js +11 -33
- package/dist/templates/kiro/index.js.map +1 -1
- package/dist/templates/opencode/agents/check.md +3 -30
- package/dist/templates/opencode/agents/implement.md +1 -1
- package/dist/templates/opencode/agents/research.md +1 -2
- package/dist/templates/opencode/plugins/inject-subagent-context.js +9 -183
- package/dist/templates/opencode/plugins/inject-workflow-state.js +160 -0
- package/dist/templates/opencode/plugins/session-start.js +71 -32
- package/dist/templates/qoder/agents/check.md +95 -0
- package/dist/templates/qoder/agents/implement.md +95 -0
- package/dist/templates/qoder/agents/research.md +138 -0
- package/dist/templates/qoder/index.d.ts +7 -10
- package/dist/templates/qoder/index.d.ts.map +1 -1
- package/dist/templates/qoder/index.js +7 -32
- package/dist/templates/qoder/index.js.map +1 -1
- package/dist/templates/qoder/settings.json +47 -0
- package/dist/templates/shared-hooks/index.d.ts +19 -0
- package/dist/templates/shared-hooks/index.d.ts.map +1 -0
- package/dist/templates/shared-hooks/index.js +30 -0
- package/dist/templates/shared-hooks/index.js.map +1 -0
- package/dist/templates/{iflow/hooks → shared-hooks}/inject-subagent-context.py +74 -263
- package/dist/templates/shared-hooks/inject-workflow-state.py +231 -0
- package/dist/templates/{claude/hooks → shared-hooks}/session-start.py +162 -55
- package/dist/templates/template-utils.d.ts +26 -0
- package/dist/templates/template-utils.d.ts.map +1 -0
- package/dist/templates/template-utils.js +60 -0
- package/dist/templates/template-utils.js.map +1 -0
- package/dist/templates/trellis/index.d.ts +1 -14
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +2 -27
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/common/cli_adapter.py +2 -2
- package/dist/templates/trellis/scripts/common/config.py +126 -1
- package/dist/templates/trellis/scripts/common/git_context.py +25 -2
- package/dist/templates/trellis/scripts/common/task_context.py +3 -23
- package/dist/templates/trellis/scripts/common/task_store.py +0 -12
- package/dist/templates/trellis/scripts/common/workflow_phase.py +176 -0
- package/dist/templates/trellis/scripts/task.py +6 -35
- package/dist/templates/trellis/workflow.md +274 -297
- package/dist/types/ai-tools.d.ts +21 -3
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +106 -15
- package/dist/types/ai-tools.js.map +1 -1
- package/dist/types/migration.d.ts +8 -1
- package/dist/types/migration.d.ts.map +1 -1
- package/package.json +3 -2
- package/dist/configurators/iflow.d.ts +0 -33
- package/dist/configurators/iflow.d.ts.map +0 -1
- package/dist/configurators/iflow.js +0 -99
- package/dist/configurators/iflow.js.map +0 -1
- package/dist/templates/antigravity/index.d.ts +0 -12
- package/dist/templates/antigravity/index.d.ts.map +0 -1
- package/dist/templates/antigravity/index.js +0 -29
- package/dist/templates/antigravity/index.js.map +0 -1
- package/dist/templates/claude/agents/debug.md +0 -106
- package/dist/templates/claude/agents/dispatch.md +0 -213
- package/dist/templates/claude/agents/plan.md +0 -396
- package/dist/templates/claude/commands/trellis/brainstorm.md +0 -487
- package/dist/templates/claude/commands/trellis/break-loop.md +0 -125
- package/dist/templates/claude/commands/trellis/check-cross-layer.md +0 -153
- package/dist/templates/claude/commands/trellis/check.md +0 -25
- package/dist/templates/claude/commands/trellis/create-command.md +0 -154
- package/dist/templates/claude/commands/trellis/finish-work.md +0 -153
- package/dist/templates/claude/commands/trellis/integrate-skill.md +0 -219
- package/dist/templates/claude/commands/trellis/onboard.md +0 -358
- package/dist/templates/claude/commands/trellis/parallel.md +0 -192
- package/dist/templates/claude/commands/trellis/record-session.md +0 -62
- package/dist/templates/claude/commands/trellis/start.md +0 -393
- package/dist/templates/claude/commands/trellis/update-spec.md +0 -354
- package/dist/templates/claude/hooks/inject-subagent-context.py +0 -803
- package/dist/templates/claude/hooks/ralph-loop.py +0 -396
- package/dist/templates/codebuddy/commands/trellis/before-dev.md +0 -29
- package/dist/templates/codebuddy/commands/trellis/break-loop.md +0 -107
- package/dist/templates/codebuddy/commands/trellis/check-cross-layer.md +0 -153
- package/dist/templates/codebuddy/commands/trellis/check.md +0 -25
- package/dist/templates/codebuddy/commands/trellis/create-command.md +0 -154
- package/dist/templates/codebuddy/commands/trellis/finish-work.md +0 -143
- package/dist/templates/codebuddy/commands/trellis/integrate-skill.md +0 -219
- package/dist/templates/codebuddy/commands/trellis/onboard.md +0 -358
- package/dist/templates/codebuddy/commands/trellis/record-session.md +0 -61
- package/dist/templates/codebuddy/commands/trellis/start.md +0 -373
- package/dist/templates/codex/codex-skills/parallel/SKILL.md +0 -194
- package/dist/templates/cursor/commands/trellis-before-dev.md +0 -29
- package/dist/templates/cursor/commands/trellis-brainstorm.md +0 -487
- package/dist/templates/cursor/commands/trellis-break-loop.md +0 -107
- package/dist/templates/cursor/commands/trellis-check-cross-layer.md +0 -153
- package/dist/templates/cursor/commands/trellis-check.md +0 -25
- package/dist/templates/cursor/commands/trellis-create-command.md +0 -154
- package/dist/templates/cursor/commands/trellis-finish-work.md +0 -143
- package/dist/templates/cursor/commands/trellis-integrate-skill.md +0 -219
- package/dist/templates/cursor/commands/trellis-onboard.md +0 -358
- package/dist/templates/cursor/commands/trellis-record-session.md +0 -62
- package/dist/templates/cursor/commands/trellis-start.md +0 -373
- package/dist/templates/cursor/commands/trellis-update-spec.md +0 -354
- package/dist/templates/droid/commands/trellis/before-dev.md +0 -33
- package/dist/templates/droid/commands/trellis/brainstorm.md +0 -491
- package/dist/templates/droid/commands/trellis/break-loop.md +0 -111
- package/dist/templates/droid/commands/trellis/check-cross-layer.md +0 -157
- package/dist/templates/droid/commands/trellis/check.md +0 -29
- package/dist/templates/droid/commands/trellis/create-command.md +0 -158
- package/dist/templates/droid/commands/trellis/finish-work.md +0 -147
- package/dist/templates/droid/commands/trellis/integrate-skill.md +0 -223
- package/dist/templates/droid/commands/trellis/onboard.md +0 -362
- package/dist/templates/droid/commands/trellis/record-session.md +0 -66
- package/dist/templates/droid/commands/trellis/start.md +0 -377
- package/dist/templates/droid/commands/trellis/update-spec.md +0 -358
- package/dist/templates/gemini/commands/trellis/before-dev.toml +0 -33
- package/dist/templates/gemini/commands/trellis/brainstorm.toml +0 -435
- package/dist/templates/gemini/commands/trellis/break-loop.toml +0 -129
- package/dist/templates/gemini/commands/trellis/check-cross-layer.toml +0 -147
- package/dist/templates/gemini/commands/trellis/check.toml +0 -29
- package/dist/templates/gemini/commands/trellis/create-command.toml +0 -119
- package/dist/templates/gemini/commands/trellis/finish-work.toml +0 -133
- package/dist/templates/gemini/commands/trellis/integrate-skill.toml +0 -104
- package/dist/templates/gemini/commands/trellis/onboard.toml +0 -111
- package/dist/templates/gemini/commands/trellis/record-session.toml +0 -66
- package/dist/templates/gemini/commands/trellis/start.toml +0 -354
- package/dist/templates/gemini/commands/trellis/update-spec.toml +0 -132
- package/dist/templates/iflow/agents/debug.md +0 -106
- package/dist/templates/iflow/agents/dispatch.md +0 -213
- package/dist/templates/iflow/agents/plan.md +0 -396
- package/dist/templates/iflow/agents/research.md +0 -120
- package/dist/templates/iflow/commands/trellis/before-dev.md +0 -29
- package/dist/templates/iflow/commands/trellis/brainstorm.md +0 -487
- package/dist/templates/iflow/commands/trellis/break-loop.md +0 -125
- package/dist/templates/iflow/commands/trellis/check-cross-layer.md +0 -153
- package/dist/templates/iflow/commands/trellis/check.md +0 -25
- package/dist/templates/iflow/commands/trellis/create-command.md +0 -152
- package/dist/templates/iflow/commands/trellis/finish-work.md +0 -153
- package/dist/templates/iflow/commands/trellis/integrate-skill.md +0 -219
- package/dist/templates/iflow/commands/trellis/onboard.md +0 -358
- package/dist/templates/iflow/commands/trellis/parallel.md +0 -192
- package/dist/templates/iflow/commands/trellis/record-session.md +0 -62
- package/dist/templates/iflow/commands/trellis/start.md +0 -393
- package/dist/templates/iflow/commands/trellis/update-spec.md +0 -354
- package/dist/templates/iflow/hooks/ralph-loop.py +0 -395
- package/dist/templates/iflow/hooks/session-start.py +0 -403
- package/dist/templates/iflow/index.d.ts +0 -54
- package/dist/templates/iflow/index.d.ts.map +0 -1
- package/dist/templates/iflow/index.js +0 -85
- package/dist/templates/iflow/index.js.map +0 -1
- package/dist/templates/iflow/settings.json +0 -60
- package/dist/templates/kilo/index.d.ts +0 -16
- package/dist/templates/kilo/index.d.ts.map +0 -1
- package/dist/templates/kilo/index.js +0 -39
- package/dist/templates/kilo/index.js.map +0 -1
- package/dist/templates/kilo/workflows/before-dev.md +0 -29
- package/dist/templates/kilo/workflows/brainstorm.md +0 -487
- package/dist/templates/kilo/workflows/break-loop.md +0 -125
- package/dist/templates/kilo/workflows/check-cross-layer.md +0 -153
- package/dist/templates/kilo/workflows/check.md +0 -25
- package/dist/templates/kilo/workflows/create-command.md +0 -152
- package/dist/templates/kilo/workflows/finish-work.md +0 -129
- package/dist/templates/kilo/workflows/integrate-skill.md +0 -219
- package/dist/templates/kilo/workflows/onboard.md +0 -358
- package/dist/templates/kilo/workflows/parallel.md +0 -193
- package/dist/templates/kilo/workflows/record-session.md +0 -62
- package/dist/templates/kilo/workflows/start.md +0 -387
- package/dist/templates/kilo/workflows/update-spec.md +0 -285
- package/dist/templates/kiro/skills/before-dev/SKILL.md +0 -34
- package/dist/templates/kiro/skills/brainstorm/SKILL.md +0 -492
- package/dist/templates/kiro/skills/break-loop/SKILL.md +0 -130
- package/dist/templates/kiro/skills/check/SKILL.md +0 -30
- package/dist/templates/kiro/skills/check-cross-layer/SKILL.md +0 -158
- package/dist/templates/kiro/skills/create-command/SKILL.md +0 -101
- package/dist/templates/kiro/skills/finish-work/SKILL.md +0 -148
- package/dist/templates/kiro/skills/integrate-skill/SKILL.md +0 -221
- package/dist/templates/kiro/skills/onboard/SKILL.md +0 -363
- package/dist/templates/kiro/skills/record-session/SKILL.md +0 -67
- package/dist/templates/kiro/skills/start/SKILL.md +0 -351
- package/dist/templates/kiro/skills/update-spec/SKILL.md +0 -335
- package/dist/templates/opencode/agents/debug.md +0 -129
- package/dist/templates/opencode/agents/dispatch.md +0 -223
- package/dist/templates/opencode/agents/trellis-plan.md +0 -427
- package/dist/templates/opencode/commands/trellis/before-dev.md +0 -29
- package/dist/templates/opencode/commands/trellis/brainstorm.md +0 -487
- package/dist/templates/opencode/commands/trellis/check-cross-layer.md +0 -153
- package/dist/templates/opencode/commands/trellis/check.md +0 -25
- package/dist/templates/opencode/commands/trellis/create-command.md +0 -154
- package/dist/templates/opencode/commands/trellis/finish-work.md +0 -144
- package/dist/templates/opencode/commands/trellis/integrate-skill.md +0 -219
- package/dist/templates/opencode/commands/trellis/migrate-specs.md +0 -0
- package/dist/templates/opencode/commands/trellis/onboard.md +0 -358
- package/dist/templates/opencode/commands/trellis/parallel.md +0 -193
- package/dist/templates/opencode/commands/trellis/record-session.md +0 -62
- package/dist/templates/opencode/commands/trellis/start.md +0 -351
- package/dist/templates/opencode/commands/trellis/update-spec.md +0 -354
- package/dist/templates/qoder/skills/before-dev/SKILL.md +0 -34
- package/dist/templates/qoder/skills/brainstorm/SKILL.md +0 -492
- package/dist/templates/qoder/skills/break-loop/SKILL.md +0 -130
- package/dist/templates/qoder/skills/check/SKILL.md +0 -30
- package/dist/templates/qoder/skills/check-cross-layer/SKILL.md +0 -158
- package/dist/templates/qoder/skills/create-command/SKILL.md +0 -101
- package/dist/templates/qoder/skills/finish-work/SKILL.md +0 -134
- package/dist/templates/qoder/skills/integrate-skill/SKILL.md +0 -221
- package/dist/templates/qoder/skills/onboard/SKILL.md +0 -363
- package/dist/templates/qoder/skills/record-session/SKILL.md +0 -67
- package/dist/templates/qoder/skills/start/SKILL.md +0 -388
- package/dist/templates/qoder/skills/update-spec/SKILL.md +0 -290
- package/dist/templates/trellis/scripts/common/phase.py +0 -254
- package/dist/templates/trellis/scripts/common/registry.py +0 -335
- package/dist/templates/trellis/scripts/common/worktree.py +0 -305
- package/dist/templates/trellis/scripts/multi_agent/__init__.py +0 -5
- package/dist/templates/trellis/scripts/multi_agent/_bootstrap.py +0 -17
- package/dist/templates/trellis/scripts/multi_agent/cleanup.py +0 -398
- package/dist/templates/trellis/scripts/multi_agent/create_pr.py +0 -620
- package/dist/templates/trellis/scripts/multi_agent/plan.py +0 -213
- package/dist/templates/trellis/scripts/multi_agent/start.py +0 -539
- package/dist/templates/trellis/scripts/multi_agent/status.py +0 -76
- package/dist/templates/trellis/scripts/multi_agent/status_display.py +0 -542
- package/dist/templates/trellis/scripts/multi_agent/status_monitor.py +0 -225
- package/dist/templates/trellis/scripts-shell-archive/add-session.sh +0 -384
- package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +0 -129
- package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +0 -263
- package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +0 -208
- package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +0 -150
- package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +0 -247
- package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +0 -142
- package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +0 -151
- package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +0 -128
- package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +0 -299
- package/dist/templates/trellis/scripts-shell-archive/get-context.sh +0 -7
- package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +0 -15
- package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +0 -34
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +0 -396
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +0 -241
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +0 -207
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +0 -317
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +0 -828
- package/dist/templates/trellis/scripts-shell-archive/task.sh +0 -1204
- package/dist/templates/trellis/worktree.yaml +0 -47
- package/dist/templates/windsurf/index.d.ts +0 -21
- package/dist/templates/windsurf/index.d.ts.map +0 -1
- package/dist/templates/windsurf/index.js +0 -44
- package/dist/templates/windsurf/index.js.map +0 -1
- package/dist/templates/windsurf/workflows/trellis-before-dev.md +0 -31
- package/dist/templates/windsurf/workflows/trellis-brainstorm.md +0 -491
- package/dist/templates/windsurf/workflows/trellis-break-loop.md +0 -111
- package/dist/templates/windsurf/workflows/trellis-check-cross-layer.md +0 -157
- package/dist/templates/windsurf/workflows/trellis-check.md +0 -27
- package/dist/templates/windsurf/workflows/trellis-create-command.md +0 -154
- package/dist/templates/windsurf/workflows/trellis-finish-work.md +0 -147
- package/dist/templates/windsurf/workflows/trellis-integrate-skill.md +0 -220
- package/dist/templates/windsurf/workflows/trellis-onboard.md +0 -362
- package/dist/templates/windsurf/workflows/trellis-record-session.md +0 -66
- package/dist/templates/windsurf/workflows/trellis-start.md +0 -373
- package/dist/templates/windsurf/workflows/trellis-update-spec.md +0 -358
- /package/dist/templates/{claude/commands/trellis → common/skills}/before-dev.md +0 -0
- /package/dist/templates/{claude/hooks → shared-hooks}/statusline.py +0 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Trellis UserPromptSubmit hook: inject per-turn workflow breadcrumb.
|
|
3
|
+
|
|
4
|
+
Runs on every user prompt. Reads the active task (.trellis/.current-task)
|
|
5
|
+
and emits a short <workflow-state> block reminding the main AI what task
|
|
6
|
+
is active and its expected flow. Breadcrumb text is pulled from
|
|
7
|
+
workflow.md [workflow-state:STATUS] tag blocks (single source of truth
|
|
8
|
+
for users who fork the Trellis workflow), with hardcoded fallbacks so
|
|
9
|
+
the hook never breaks when workflow.md is missing or malformed.
|
|
10
|
+
|
|
11
|
+
Shared across all hook-capable platforms (Claude, Cursor, Codex, Qoder,
|
|
12
|
+
CodeBuddy, Droid, Gemini, Copilot). Kiro is not wired (no per-turn
|
|
13
|
+
hook entry point). Written to each platform's hooks directory via
|
|
14
|
+
writeSharedHooks() at init time.
|
|
15
|
+
|
|
16
|
+
Silent exit 0 cases (no output):
|
|
17
|
+
- No .trellis/ directory found (not a Trellis project)
|
|
18
|
+
- No .current-task file, or it's empty
|
|
19
|
+
- task.json malformed or missing status
|
|
20
|
+
|
|
21
|
+
Unknown status (no tag + no hardcoded fallback) emits a generic
|
|
22
|
+
breadcrumb rather than silent-exiting, so custom statuses surface in
|
|
23
|
+
the UI instead of appearing as "randomly broken".
|
|
24
|
+
"""
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import json
|
|
28
|
+
import os
|
|
29
|
+
import re
|
|
30
|
+
import sys
|
|
31
|
+
from pathlib import Path
|
|
32
|
+
from typing import Optional, Tuple
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ---------------------------------------------------------------------------
|
|
36
|
+
# CWD-robust Trellis root discovery (fixes hook-path-robustness for this hook)
|
|
37
|
+
# ---------------------------------------------------------------------------
|
|
38
|
+
|
|
39
|
+
def find_trellis_root(start: Path) -> Optional[Path]:
|
|
40
|
+
"""Walk up from start to find directory containing .trellis/.
|
|
41
|
+
|
|
42
|
+
Handles CWD drift: subdirectory launches, monorepo packages, etc.
|
|
43
|
+
Returns None if no .trellis/ found (silent no-op).
|
|
44
|
+
"""
|
|
45
|
+
cur = start.resolve()
|
|
46
|
+
while cur != cur.parent:
|
|
47
|
+
if (cur / ".trellis").is_dir():
|
|
48
|
+
return cur
|
|
49
|
+
cur = cur.parent
|
|
50
|
+
return None
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# ---------------------------------------------------------------------------
|
|
54
|
+
# Active task discovery
|
|
55
|
+
# ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
def _normalize_task_ref(task_ref: str) -> str:
|
|
58
|
+
"""Normalize .current-task path ref.
|
|
59
|
+
|
|
60
|
+
Accepts:
|
|
61
|
+
- Absolute paths (left as-is)
|
|
62
|
+
- Windows-style backslashes (converted to forward slash)
|
|
63
|
+
- Legacy relative refs like "tasks/foo" (prefixed with .trellis/)
|
|
64
|
+
"""
|
|
65
|
+
normalized = task_ref.strip()
|
|
66
|
+
if not normalized:
|
|
67
|
+
return ""
|
|
68
|
+
path_obj = Path(normalized)
|
|
69
|
+
if path_obj.is_absolute():
|
|
70
|
+
return str(path_obj)
|
|
71
|
+
normalized = normalized.replace("\\", "/")
|
|
72
|
+
while normalized.startswith("./"):
|
|
73
|
+
normalized = normalized[2:]
|
|
74
|
+
if normalized.startswith("tasks/"):
|
|
75
|
+
normalized = f".trellis/{normalized}"
|
|
76
|
+
return normalized
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def get_active_task(root: Path) -> Optional[Tuple[str, str]]:
|
|
80
|
+
"""Return (task_id, status) from the current active task, else None.
|
|
81
|
+
|
|
82
|
+
Reads .trellis/.current-task (a path relative to root, e.g.
|
|
83
|
+
".trellis/tasks/04-17-foo") then that task's task.json.
|
|
84
|
+
Normalizes backslashes so Windows paths work on Unix and vice versa.
|
|
85
|
+
"""
|
|
86
|
+
ref_file = root / ".trellis" / ".current-task"
|
|
87
|
+
if not ref_file.is_file():
|
|
88
|
+
return None
|
|
89
|
+
try:
|
|
90
|
+
raw = ref_file.read_text(encoding="utf-8").strip()
|
|
91
|
+
except OSError:
|
|
92
|
+
return None
|
|
93
|
+
task_ref = _normalize_task_ref(raw)
|
|
94
|
+
if not task_ref:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
path_obj = Path(task_ref)
|
|
98
|
+
task_dir = path_obj if path_obj.is_absolute() else root / path_obj
|
|
99
|
+
task_json = task_dir / "task.json"
|
|
100
|
+
if not task_json.is_file():
|
|
101
|
+
return None
|
|
102
|
+
try:
|
|
103
|
+
data = json.loads(task_json.read_text(encoding="utf-8"))
|
|
104
|
+
except (json.JSONDecodeError, OSError):
|
|
105
|
+
return None
|
|
106
|
+
|
|
107
|
+
task_id = data.get("id") or task_dir.name
|
|
108
|
+
status = data.get("status", "")
|
|
109
|
+
if not isinstance(status, str) or not status:
|
|
110
|
+
return None
|
|
111
|
+
return task_id, status
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
# ---------------------------------------------------------------------------
|
|
115
|
+
# Breadcrumb loading: parse workflow.md, fall back to hardcoded defaults
|
|
116
|
+
# ---------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
# Supports STATUS values with letters, digits, underscores, hyphens
|
|
119
|
+
# (so "in-review" / "blocked-by-team" work alongside "in_progress").
|
|
120
|
+
_TAG_RE = re.compile(
|
|
121
|
+
r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n(.*?)\n\s*\[/workflow-state:\1\]",
|
|
122
|
+
re.DOTALL,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# Hardcoded defaults for built-in Trellis statuses. Used when workflow.md is
|
|
126
|
+
# missing, malformed, or lacks the tag for this status.
|
|
127
|
+
#
|
|
128
|
+
# `no_task` is a pseudo-status emitted when .current-task is missing — it keeps
|
|
129
|
+
# the Next-Action reminder flowing per-turn even without an active task.
|
|
130
|
+
_FALLBACK_BREADCRUMBS = {
|
|
131
|
+
"no_task": (
|
|
132
|
+
"No active task. If the user describes multi-step work, load "
|
|
133
|
+
"trellis-brainstorm skill to clarify requirements and create a task "
|
|
134
|
+
"via `python3 ./.trellis/scripts/task.py create`. Simple one-off "
|
|
135
|
+
"questions or trivial edits don't need a task — just answer directly."
|
|
136
|
+
),
|
|
137
|
+
"planning": (
|
|
138
|
+
"Complete prd.md via trellis-brainstorm skill; "
|
|
139
|
+
"then run task.py start."
|
|
140
|
+
),
|
|
141
|
+
"in_progress": (
|
|
142
|
+
"Flow: implement → check → update-spec → finish\n"
|
|
143
|
+
"Check conversation history + git status to determine current step; "
|
|
144
|
+
"do NOT skip check."
|
|
145
|
+
),
|
|
146
|
+
"completed": (
|
|
147
|
+
"User commits changes; then run task.py archive."
|
|
148
|
+
),
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def load_breadcrumbs(root: Path) -> dict[str, str]:
|
|
153
|
+
"""Parse workflow.md for [workflow-state:STATUS] blocks.
|
|
154
|
+
|
|
155
|
+
Returns {status: body_text}. Missing tags fall back to hardcoded
|
|
156
|
+
defaults so the hook always has something to say for built-in
|
|
157
|
+
statuses. Custom statuses without tags fall to generic breadcrumb
|
|
158
|
+
downstream (see build_breadcrumb).
|
|
159
|
+
"""
|
|
160
|
+
result = dict(_FALLBACK_BREADCRUMBS)
|
|
161
|
+
|
|
162
|
+
workflow = root / ".trellis" / "workflow.md"
|
|
163
|
+
if not workflow.is_file():
|
|
164
|
+
return result
|
|
165
|
+
try:
|
|
166
|
+
content = workflow.read_text(encoding="utf-8")
|
|
167
|
+
except OSError:
|
|
168
|
+
return result
|
|
169
|
+
|
|
170
|
+
for match in _TAG_RE.finditer(content):
|
|
171
|
+
status = match.group(1)
|
|
172
|
+
body = match.group(2).strip()
|
|
173
|
+
if body:
|
|
174
|
+
result[status] = body
|
|
175
|
+
return result
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def build_breadcrumb(
|
|
179
|
+
task_id: Optional[str], status: str, templates: dict[str, str]
|
|
180
|
+
) -> str:
|
|
181
|
+
"""Build the <workflow-state>...</workflow-state> block.
|
|
182
|
+
|
|
183
|
+
- Known status (in templates or fallback) → detailed template body
|
|
184
|
+
- Unknown status (no tag + no fallback) → generic "refer to workflow.md"
|
|
185
|
+
- `no_task` pseudo-status (task_id is None) → header omits task info
|
|
186
|
+
"""
|
|
187
|
+
body = templates.get(status)
|
|
188
|
+
if body is None:
|
|
189
|
+
body = "Refer to workflow.md for current step."
|
|
190
|
+
header = f"Status: {status}" if task_id is None else f"Task: {task_id} ({status})"
|
|
191
|
+
return f"<workflow-state>\n{header}\n{body}\n</workflow-state>"
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
# ---------------------------------------------------------------------------
|
|
195
|
+
# Entry
|
|
196
|
+
# ---------------------------------------------------------------------------
|
|
197
|
+
|
|
198
|
+
def main() -> int:
|
|
199
|
+
try:
|
|
200
|
+
data = json.load(sys.stdin)
|
|
201
|
+
except (json.JSONDecodeError, ValueError):
|
|
202
|
+
data = {}
|
|
203
|
+
|
|
204
|
+
cwd_str = data.get("cwd") or os.getcwd()
|
|
205
|
+
cwd = Path(cwd_str)
|
|
206
|
+
|
|
207
|
+
root = find_trellis_root(cwd)
|
|
208
|
+
if root is None:
|
|
209
|
+
return 0 # not a Trellis project
|
|
210
|
+
|
|
211
|
+
templates = load_breadcrumbs(root)
|
|
212
|
+
task = get_active_task(root)
|
|
213
|
+
if task is None:
|
|
214
|
+
# No active task — still emit a breadcrumb nudging AI toward
|
|
215
|
+
# trellis-brainstorm + task.py create when user describes real work.
|
|
216
|
+
breadcrumb = build_breadcrumb(None, "no_task", templates)
|
|
217
|
+
else:
|
|
218
|
+
breadcrumb = build_breadcrumb(*task, templates=templates)
|
|
219
|
+
|
|
220
|
+
output = {
|
|
221
|
+
"hookSpecificOutput": {
|
|
222
|
+
"hookEventName": "UserPromptSubmit",
|
|
223
|
+
"additionalContext": breadcrumb,
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
print(json.dumps(output))
|
|
227
|
+
return 0
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
if __name__ == "__main__":
|
|
231
|
+
sys.exit(main())
|
|
@@ -25,11 +25,20 @@ if sys.platform == "win32":
|
|
|
25
25
|
sys.stdout = _io.TextIOWrapper(sys.stdout.detach(), encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
|
|
28
29
|
def should_skip_injection() -> bool:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
"""Check if any platform's non-interactive flag is set."""
|
|
31
|
+
non_interactive_vars = [
|
|
32
|
+
"CLAUDE_NON_INTERACTIVE",
|
|
33
|
+
"QODER_NON_INTERACTIVE",
|
|
34
|
+
"CODEBUDDY_NON_INTERACTIVE",
|
|
35
|
+
"FACTORY_NON_INTERACTIVE",
|
|
36
|
+
"CURSOR_NON_INTERACTIVE",
|
|
37
|
+
"GEMINI_NON_INTERACTIVE",
|
|
38
|
+
"KIRO_NON_INTERACTIVE",
|
|
39
|
+
"COPILOT_NON_INTERACTIVE",
|
|
40
|
+
]
|
|
41
|
+
return any(os.environ.get(var) == "1" for var in non_interactive_vars)
|
|
33
42
|
|
|
34
43
|
|
|
35
44
|
def read_file(path: Path, fallback: str = "") -> str:
|
|
@@ -95,19 +104,33 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
|
|
|
95
104
|
|
|
96
105
|
|
|
97
106
|
def _get_task_status(trellis_dir: Path) -> str:
|
|
98
|
-
"""Check current task status and return structured status string.
|
|
107
|
+
"""Check current task status and return structured status string with explicit next action.
|
|
108
|
+
|
|
109
|
+
Returns a block with three fields:
|
|
110
|
+
- Status: current state
|
|
111
|
+
- Task: task identifier (when applicable)
|
|
112
|
+
- Next-Action: explicit skill/command/tool call the AI should invoke
|
|
113
|
+
"""
|
|
99
114
|
current_task_file = trellis_dir / ".current-task"
|
|
100
|
-
|
|
101
|
-
|
|
115
|
+
|
|
116
|
+
# Case 1: No active task — waiting for user to describe intent
|
|
117
|
+
if not current_task_file.is_file() or not current_task_file.read_text(encoding="utf-8").strip():
|
|
118
|
+
return (
|
|
119
|
+
"Status: NO ACTIVE TASK\n"
|
|
120
|
+
"Next-Action: After the user describes their intent, load skill `trellis-brainstorm` "
|
|
121
|
+
"to clarify requirements and create a task via `python3 ./.trellis/scripts/task.py create`."
|
|
122
|
+
)
|
|
102
123
|
|
|
103
124
|
task_ref = _normalize_task_ref(current_task_file.read_text(encoding="utf-8").strip())
|
|
104
|
-
if not task_ref:
|
|
105
|
-
return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
|
|
106
125
|
|
|
107
|
-
#
|
|
126
|
+
# Case 2: Stale pointer — task dir was deleted
|
|
108
127
|
task_dir = _resolve_task_dir(trellis_dir, task_ref)
|
|
109
128
|
if not task_dir.is_dir():
|
|
110
|
-
return
|
|
129
|
+
return (
|
|
130
|
+
f"Status: STALE POINTER\nTask: {task_ref}\n"
|
|
131
|
+
f"Next-Action: Run `python3 ./.trellis/scripts/task.py finish` to clear the stale pointer, "
|
|
132
|
+
"then ask the user what to work on next."
|
|
133
|
+
)
|
|
111
134
|
|
|
112
135
|
# Read task.json
|
|
113
136
|
task_json_path = task_dir / "task.json"
|
|
@@ -121,26 +144,31 @@ def _get_task_status(trellis_dir: Path) -> str:
|
|
|
121
144
|
task_title = task_data.get("title", task_ref)
|
|
122
145
|
task_status = task_data.get("status", "unknown")
|
|
123
146
|
|
|
147
|
+
# Case 3: Task completed — time to archive
|
|
124
148
|
if task_status == "completed":
|
|
125
|
-
return
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
jsonl_path = task_dir / jsonl_name
|
|
131
|
-
if jsonl_path.is_file() and jsonl_path.stat().st_size > 0:
|
|
132
|
-
has_context = True
|
|
133
|
-
break
|
|
149
|
+
return (
|
|
150
|
+
f"Status: COMPLETED\nTask: {task_title}\n"
|
|
151
|
+
f"Next-Action: Load skill `trellis-update-spec` to capture learnings, "
|
|
152
|
+
f"then archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}`."
|
|
153
|
+
)
|
|
134
154
|
|
|
135
155
|
has_prd = (task_dir / "prd.md").is_file()
|
|
136
156
|
|
|
157
|
+
# Case 4: No PRD — still in Plan phase
|
|
137
158
|
if not has_prd:
|
|
138
|
-
return
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
return (
|
|
160
|
+
f"Status: PLANNING\nTask: {task_title}\n"
|
|
161
|
+
"Next-Action: Load skill `trellis-brainstorm` to clarify requirements with the user "
|
|
162
|
+
"and produce prd.md in the task directory."
|
|
163
|
+
)
|
|
142
164
|
|
|
143
|
-
|
|
165
|
+
# Case 5: PRD ready — enter Execute phase
|
|
166
|
+
return (
|
|
167
|
+
f"Status: READY\nTask: {task_title}\n"
|
|
168
|
+
"Next-Action: Load skill `trellis-before-dev` to read relevant specs, "
|
|
169
|
+
"then spawn `implement` sub-agent via the Task tool. "
|
|
170
|
+
"After implementation, spawn `check` sub-agent for quality verification."
|
|
171
|
+
)
|
|
144
172
|
|
|
145
173
|
|
|
146
174
|
def _load_trellis_config(trellis_dir: Path) -> tuple:
|
|
@@ -288,37 +316,97 @@ def _resolve_spec_scope(
|
|
|
288
316
|
return None # Unknown scope type: full scan
|
|
289
317
|
|
|
290
318
|
|
|
291
|
-
def
|
|
292
|
-
"""
|
|
319
|
+
def _extract_range(content: str, start_header: str, end_header: str) -> str:
|
|
320
|
+
"""Extract lines starting at `## start_header` up to (but excluding) `## end_header`.
|
|
293
321
|
|
|
294
|
-
|
|
295
|
-
|
|
322
|
+
Both parameters are full header lines WITHOUT the `## ` prefix (e.g. "Phase Index").
|
|
323
|
+
Returns empty string if start header is not found.
|
|
324
|
+
End header missing → extracts to end of file.
|
|
325
|
+
"""
|
|
326
|
+
lines = content.splitlines()
|
|
327
|
+
start: int | None = None
|
|
328
|
+
end: int = len(lines)
|
|
329
|
+
start_match = f"## {start_header}"
|
|
330
|
+
end_match = f"## {end_header}"
|
|
331
|
+
for i, line in enumerate(lines):
|
|
332
|
+
stripped = line.strip()
|
|
333
|
+
if start is None and stripped == start_match:
|
|
334
|
+
start = i
|
|
335
|
+
continue
|
|
336
|
+
if start is not None and stripped == end_match:
|
|
337
|
+
end = i
|
|
338
|
+
break
|
|
339
|
+
if start is None:
|
|
340
|
+
return ""
|
|
341
|
+
return "\n".join(lines[start:end]).rstrip()
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _build_workflow_overview(workflow_path: Path) -> str:
|
|
345
|
+
"""Inject the workflow guide for the session.
|
|
346
|
+
|
|
347
|
+
Contents:
|
|
348
|
+
1. Section index (all `## ` headings — navigation)
|
|
349
|
+
2. Phase Index section (rules, skill routing table, anti-rationalization table)
|
|
350
|
+
3. Phase 1/2/3 step-level details (the actual how-to for each step)
|
|
351
|
+
|
|
352
|
+
The meta sections (Core Principles / Trellis System / Workflow State
|
|
353
|
+
Breadcrumbs) are NOT injected — Core Principles is short prose the AI can
|
|
354
|
+
Read on demand; Trellis System lists reference commands duplicated in
|
|
355
|
+
step bodies; Breadcrumbs are consumed by the UserPromptSubmit hook.
|
|
356
|
+
|
|
357
|
+
Total budget: Phase Index ~2 KB + Phase 1/2/3 ~7 KB = ~9 KB.
|
|
296
358
|
"""
|
|
297
359
|
content = read_file(workflow_path)
|
|
298
360
|
if not content:
|
|
299
361
|
return "No workflow.md found"
|
|
300
362
|
|
|
301
|
-
|
|
363
|
+
out_lines = [
|
|
302
364
|
"# Development Workflow — Section Index",
|
|
303
365
|
"Full guide: .trellis/workflow.md (read on demand)",
|
|
304
366
|
"",
|
|
367
|
+
"## Table of Contents",
|
|
305
368
|
]
|
|
306
369
|
for line in content.splitlines():
|
|
307
370
|
if line.startswith("## "):
|
|
308
|
-
|
|
371
|
+
out_lines.append(line)
|
|
372
|
+
out_lines += ["", "---", ""]
|
|
373
|
+
|
|
374
|
+
# Extract Phase Index through the end of Phase 3 (before Breadcrumbs).
|
|
375
|
+
# Since sections appear in order Phase Index → Phase 1 → Phase 2 → Phase 3
|
|
376
|
+
# → Workflow State Breadcrumbs, a single range grab captures all four.
|
|
377
|
+
phases = _extract_range(
|
|
378
|
+
content, "Phase Index", "Workflow State Breadcrumbs"
|
|
379
|
+
)
|
|
380
|
+
if phases:
|
|
381
|
+
out_lines.append(phases)
|
|
309
382
|
|
|
310
|
-
|
|
311
|
-
"",
|
|
312
|
-
"To read a section: use the Read tool on .trellis/workflow.md",
|
|
313
|
-
]
|
|
314
|
-
return "\n".join(toc_lines)
|
|
383
|
+
return "\n".join(out_lines).rstrip()
|
|
315
384
|
|
|
316
385
|
|
|
317
386
|
def main():
|
|
318
387
|
if should_skip_injection():
|
|
319
388
|
sys.exit(0)
|
|
320
389
|
|
|
321
|
-
|
|
390
|
+
# Try platform-specific env vars, fallback to cwd
|
|
391
|
+
project_dir_env_vars = [
|
|
392
|
+
"CLAUDE_PROJECT_DIR",
|
|
393
|
+
"QODER_PROJECT_DIR",
|
|
394
|
+
"CODEBUDDY_PROJECT_DIR",
|
|
395
|
+
"FACTORY_PROJECT_DIR",
|
|
396
|
+
"CURSOR_PROJECT_DIR",
|
|
397
|
+
"GEMINI_PROJECT_DIR",
|
|
398
|
+
"KIRO_PROJECT_DIR",
|
|
399
|
+
"COPILOT_PROJECT_DIR",
|
|
400
|
+
]
|
|
401
|
+
project_dir = None
|
|
402
|
+
for var in project_dir_env_vars:
|
|
403
|
+
val = os.environ.get(var)
|
|
404
|
+
if val:
|
|
405
|
+
project_dir = Path(val).resolve()
|
|
406
|
+
break
|
|
407
|
+
if project_dir is None:
|
|
408
|
+
project_dir = Path(".").resolve()
|
|
409
|
+
|
|
322
410
|
trellis_dir = project_dir / ".trellis"
|
|
323
411
|
|
|
324
412
|
# Load config for scope filtering and legacy detection
|
|
@@ -345,34 +433,43 @@ Read and follow all instructions below carefully.
|
|
|
345
433
|
output.write("\n</current-state>\n\n")
|
|
346
434
|
|
|
347
435
|
output.write("<workflow>\n")
|
|
348
|
-
output.write(
|
|
436
|
+
output.write(_build_workflow_overview(trellis_dir / "workflow.md"))
|
|
349
437
|
output.write("\n</workflow>\n\n")
|
|
350
438
|
|
|
351
439
|
output.write("<guidelines>\n")
|
|
352
|
-
output.write(
|
|
353
|
-
|
|
440
|
+
output.write(
|
|
441
|
+
"Project spec indexes are listed by path below. Each index contains a "
|
|
442
|
+
"**Pre-Development Checklist** listing the specific guideline files to "
|
|
443
|
+
"read before coding.\n\n"
|
|
444
|
+
"- If you're spawning an implement/check sub-agent, context is injected "
|
|
445
|
+
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
|
|
446
|
+
"need to read these indexes yourself.\n"
|
|
447
|
+
"- If you're editing code directly in the main session, Read the relevant "
|
|
448
|
+
"index(es) on-demand and follow their Pre-Dev Checklist.\n\n"
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
# guides/ is cross-package thinking — always include inline (small, broadly useful)
|
|
452
|
+
guides_index = trellis_dir / "spec" / "guides" / "index.md"
|
|
453
|
+
if guides_index.is_file():
|
|
454
|
+
output.write("## guides (inlined — cross-package thinking guides)\n")
|
|
455
|
+
output.write(read_file(guides_index))
|
|
456
|
+
output.write("\n\n")
|
|
354
457
|
|
|
458
|
+
# Other spec indexes — paths only (main agent reads on demand;
|
|
459
|
+
# sub-agents get their specific specs via jsonl injection)
|
|
460
|
+
paths: list[str] = []
|
|
355
461
|
spec_dir = trellis_dir / "spec"
|
|
356
462
|
if spec_dir.is_dir():
|
|
357
463
|
for sub in sorted(spec_dir.iterdir()):
|
|
358
464
|
if not sub.is_dir() or sub.name.startswith("."):
|
|
359
465
|
continue
|
|
360
|
-
|
|
361
|
-
# Always include guides/ regardless of scope
|
|
362
466
|
if sub.name == "guides":
|
|
363
|
-
|
|
364
|
-
if index_file.is_file():
|
|
365
|
-
output.write(f"## {sub.name}\n")
|
|
366
|
-
output.write(read_file(index_file))
|
|
367
|
-
output.write("\n\n")
|
|
368
|
-
continue
|
|
467
|
+
continue # already inlined above
|
|
369
468
|
|
|
370
469
|
index_file = sub / "index.md"
|
|
371
470
|
if index_file.is_file():
|
|
372
471
|
# Flat spec dir (single-repo layer like spec/backend/)
|
|
373
|
-
|
|
374
|
-
output.write(read_file(index_file))
|
|
375
|
-
output.write("\n\n")
|
|
472
|
+
paths.append(f".trellis/spec/{sub.name}/index.md")
|
|
376
473
|
else:
|
|
377
474
|
# Nested package dirs (monorepo: spec/<pkg>/<layer>/index.md)
|
|
378
475
|
# Apply scope filter
|
|
@@ -383,10 +480,20 @@ Read and follow all instructions below carefully.
|
|
|
383
480
|
continue
|
|
384
481
|
nested_index = nested / "index.md"
|
|
385
482
|
if nested_index.is_file():
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
483
|
+
paths.append(
|
|
484
|
+
f".trellis/spec/{sub.name}/{nested.name}/index.md"
|
|
485
|
+
)
|
|
486
|
+
|
|
487
|
+
if paths:
|
|
488
|
+
output.write("## Available spec indexes (read on demand)\n")
|
|
489
|
+
for p in paths:
|
|
490
|
+
output.write(f"- {p}\n")
|
|
491
|
+
output.write("\n")
|
|
492
|
+
|
|
493
|
+
output.write(
|
|
494
|
+
"Discover more via: "
|
|
495
|
+
"`python3 ./.trellis/scripts/get_context.py --mode packages`\n"
|
|
496
|
+
)
|
|
390
497
|
output.write("</guidelines>\n\n")
|
|
391
498
|
|
|
392
499
|
# Check task status and inject structured tag
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for platform template modules.
|
|
3
|
+
* Eliminates boilerplate across qoder/, codebuddy/, droid/, cursor/, gemini/, kiro/ index.ts files.
|
|
4
|
+
*/
|
|
5
|
+
export interface AgentTemplate {
|
|
6
|
+
name: string;
|
|
7
|
+
content: string;
|
|
8
|
+
}
|
|
9
|
+
export interface HookTemplate {
|
|
10
|
+
targetPath: string;
|
|
11
|
+
content: string;
|
|
12
|
+
}
|
|
13
|
+
export interface TemplateReader {
|
|
14
|
+
readTemplate: (relativePath: string) => string;
|
|
15
|
+
listFiles: (dir: string) => string[];
|
|
16
|
+
listMdAgents: (dir?: string) => AgentTemplate[];
|
|
17
|
+
listJsonAgents: (dir?: string) => AgentTemplate[];
|
|
18
|
+
getSettings: (filename?: string) => HookTemplate;
|
|
19
|
+
getConfig: (filename: string) => string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a template reader bound to the caller's directory.
|
|
23
|
+
* Usage: `const { readTemplate, listMdAgents, getSettings } = createTemplateReader(import.meta.url);`
|
|
24
|
+
*/
|
|
25
|
+
export declare function createTemplateReader(importMetaUrl: string): TemplateReader;
|
|
26
|
+
//# sourceMappingURL=template-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAClD,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;IACjD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAqD1E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utilities for platform template modules.
|
|
3
|
+
* Eliminates boilerplate across qoder/, codebuddy/, droid/, cursor/, gemini/, kiro/ index.ts files.
|
|
4
|
+
*/
|
|
5
|
+
import { readdirSync, readFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
/**
|
|
9
|
+
* Create a template reader bound to the caller's directory.
|
|
10
|
+
* Usage: `const { readTemplate, listMdAgents, getSettings } = createTemplateReader(import.meta.url);`
|
|
11
|
+
*/
|
|
12
|
+
export function createTemplateReader(importMetaUrl) {
|
|
13
|
+
const __dirname = dirname(fileURLToPath(importMetaUrl));
|
|
14
|
+
function readTemplate(relativePath) {
|
|
15
|
+
return readFileSync(join(__dirname, relativePath), "utf-8");
|
|
16
|
+
}
|
|
17
|
+
function listFiles(dir) {
|
|
18
|
+
try {
|
|
19
|
+
return readdirSync(join(__dirname, dir)).sort();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Read all .md agent files from a subdirectory */
|
|
26
|
+
function listMdAgents(dir = "agents") {
|
|
27
|
+
return listFiles(dir)
|
|
28
|
+
.filter((f) => f.endsWith(".md"))
|
|
29
|
+
.map((f) => ({
|
|
30
|
+
name: f.replace(".md", ""),
|
|
31
|
+
content: readTemplate(`${dir}/${f}`),
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
/** Read all .json agent files from a subdirectory (Kiro) */
|
|
35
|
+
function listJsonAgents(dir = "agents") {
|
|
36
|
+
return listFiles(dir)
|
|
37
|
+
.filter((f) => f.endsWith(".json"))
|
|
38
|
+
.map((f) => ({
|
|
39
|
+
name: f.replace(".json", ""),
|
|
40
|
+
content: readTemplate(`${dir}/${f}`),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
/** Read settings.json and return as HookTemplate */
|
|
44
|
+
function getSettings(filename = "settings.json") {
|
|
45
|
+
return { targetPath: filename, content: readTemplate(filename) };
|
|
46
|
+
}
|
|
47
|
+
/** Read a config file and return raw string */
|
|
48
|
+
function getConfig(filename) {
|
|
49
|
+
return readTemplate(filename);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
readTemplate,
|
|
53
|
+
listFiles,
|
|
54
|
+
listMdAgents,
|
|
55
|
+
listJsonAgents,
|
|
56
|
+
getSettings,
|
|
57
|
+
getConfig,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=template-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-utils.js","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqBzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAExD,SAAS,YAAY,CAAC,YAAoB;QACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,SAAS,CAAC,GAAW;QAC5B,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,SAAS,YAAY,CAAC,GAAG,GAAG,QAAQ;QAClC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,4DAA4D;IAC5D,SAAS,cAAc,CAAC,GAAG,GAAG,QAAQ;QACpC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,oDAAoD;IACpD,SAAS,WAAW,CAAC,QAAQ,GAAG,eAAe;QAC7C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,+CAA+C;IAC/C,SAAS,SAAS,CAAC,QAAgB;QACjC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,cAAc;QACd,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC"}
|