@pennixrv/trellis 0.7.0-beta.8 → 0.7.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/README.md +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +14 -26
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/ablate.js +1 -1
- package/dist/commands/ablate.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +30 -56
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/task-progress.d.ts +2 -0
- package/dist/commands/task-progress.d.ts.map +1 -1
- package/dist/commands/task-progress.js +37 -30
- package/dist/commands/task-progress.js.map +1 -1
- package/dist/commands/{channel → teamwork}/adapters/claude.d.ts +3 -3
- package/dist/commands/teamwork/adapters/claude.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/claude.js +3 -3
- package/dist/commands/teamwork/adapters/claude.js.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/codex.d.ts +1 -15
- package/dist/commands/teamwork/adapters/codex.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/codex.js +5 -42
- package/dist/commands/teamwork/adapters/codex.js.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/index.d.ts +6 -6
- package/dist/commands/teamwork/adapters/index.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/index.js +16 -52
- package/dist/commands/teamwork/adapters/index.js.map +1 -0
- package/dist/commands/{channel → teamwork}/adapters/types.d.ts +2 -2
- package/dist/commands/teamwork/adapters/types.d.ts.map +1 -0
- package/dist/commands/teamwork/adapters/types.js.map +1 -0
- package/dist/commands/{channel → teamwork}/agent-loader.d.ts +2 -4
- package/dist/commands/teamwork/agent-loader.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/agent-loader.js +4 -35
- package/dist/commands/teamwork/agent-loader.js.map +1 -0
- package/dist/commands/teamwork/artifact.d.ts +177 -0
- package/dist/commands/teamwork/artifact.d.ts.map +1 -0
- package/dist/commands/teamwork/artifact.js +908 -0
- package/dist/commands/teamwork/artifact.js.map +1 -0
- package/dist/commands/{channel → teamwork}/context-loader.d.ts +1 -1
- package/dist/commands/teamwork/context-loader.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/context-loader.js +12 -12
- package/dist/commands/teamwork/context-loader.js.map +1 -0
- package/dist/commands/{channel → teamwork}/context-trust.d.ts +6 -6
- package/dist/commands/teamwork/context-trust.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/context-trust.js +16 -16
- package/dist/commands/teamwork/context-trust.js.map +1 -0
- package/dist/commands/teamwork/context.d.ts +16 -0
- package/dist/commands/teamwork/context.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/context.js +17 -17
- package/dist/commands/teamwork/context.js.map +1 -0
- package/dist/commands/teamwork/coordinator.d.ts +89 -0
- package/dist/commands/teamwork/coordinator.d.ts.map +1 -0
- package/dist/commands/teamwork/coordinator.js +1198 -0
- package/dist/commands/teamwork/coordinator.js.map +1 -0
- package/dist/commands/teamwork/create.d.ts +23 -0
- package/dist/commands/teamwork/create.d.ts.map +1 -0
- package/dist/commands/teamwork/create.js +39 -0
- package/dist/commands/teamwork/create.js.map +1 -0
- package/dist/commands/{channel → teamwork}/dev-parse-trace.d.ts +1 -1
- package/dist/commands/teamwork/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/dev-parse-trace.js +1 -1
- package/dist/commands/teamwork/dev-parse-trace.js.map +1 -0
- package/dist/commands/{channel → teamwork}/guard.d.ts +27 -46
- package/dist/commands/teamwork/guard.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/guard.js +54 -156
- package/dist/commands/teamwork/guard.js.map +1 -0
- package/dist/commands/teamwork/index.d.ts +3 -0
- package/dist/commands/teamwork/index.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/index.js +135 -165
- package/dist/commands/teamwork/index.js.map +1 -0
- package/dist/commands/{channel → teamwork}/interrupt.d.ts +1 -1
- package/dist/commands/teamwork/interrupt.d.ts.map +1 -0
- package/dist/commands/teamwork/interrupt.js +22 -0
- package/dist/commands/teamwork/interrupt.js.map +1 -0
- package/dist/commands/teamwork/kill.d.ts +7 -0
- package/dist/commands/teamwork/kill.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/kill.js +21 -21
- package/dist/commands/teamwork/kill.js.map +1 -0
- package/dist/commands/teamwork/list.d.ts +17 -0
- package/dist/commands/teamwork/list.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/list.js +18 -27
- package/dist/commands/teamwork/list.js.map +1 -0
- package/dist/commands/{channel → teamwork}/messages.d.ts +1 -1
- package/dist/commands/teamwork/messages.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/messages.js +18 -18
- package/dist/commands/teamwork/messages.js.map +1 -0
- package/dist/commands/teamwork/profiles.d.ts +25 -0
- package/dist/commands/teamwork/profiles.d.ts.map +1 -0
- package/dist/commands/teamwork/profiles.js +125 -0
- package/dist/commands/teamwork/profiles.js.map +1 -0
- package/dist/commands/teamwork/rm.d.ts +27 -0
- package/dist/commands/teamwork/rm.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/rm.js +21 -22
- package/dist/commands/teamwork/rm.js.map +1 -0
- package/dist/commands/teamwork/run.d.ts +29 -0
- package/dist/commands/{channel → teamwork}/run.d.ts.map +1 -1
- package/dist/commands/teamwork/run.js +129 -0
- package/dist/commands/teamwork/run.js.map +1 -0
- package/dist/commands/{channel → teamwork}/send.d.ts +1 -1
- package/dist/commands/teamwork/send.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/send.js +7 -7
- package/dist/commands/teamwork/send.js.map +1 -0
- package/dist/commands/{channel → teamwork}/spawn.d.ts +8 -12
- package/dist/commands/teamwork/spawn.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/spawn.js +51 -112
- package/dist/commands/teamwork/spawn.js.map +1 -0
- package/dist/commands/teamwork/store/events.d.ts +22 -0
- package/dist/commands/teamwork/store/events.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/store/events.js +8 -8
- package/dist/commands/teamwork/store/events.js.map +1 -0
- package/dist/commands/teamwork/store/filter.d.ts +3 -0
- package/dist/commands/teamwork/store/filter.d.ts.map +1 -0
- package/dist/commands/teamwork/store/filter.js +2 -0
- package/dist/commands/teamwork/store/filter.js.map +1 -0
- package/dist/commands/{channel → teamwork}/store/lock.d.ts +1 -1
- package/dist/commands/teamwork/store/lock.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/store/lock.js +2 -2
- package/dist/commands/teamwork/store/lock.js.map +1 -0
- package/dist/commands/{channel → teamwork}/store/paths.d.ts +18 -32
- package/dist/commands/teamwork/store/paths.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/store/paths.js +42 -109
- package/dist/commands/teamwork/store/paths.js.map +1 -0
- package/dist/commands/teamwork/store/schema.d.ts +18 -0
- package/dist/commands/teamwork/store/schema.d.ts.map +1 -0
- package/dist/commands/teamwork/store/schema.js +23 -0
- package/dist/commands/teamwork/store/schema.js.map +1 -0
- package/dist/commands/{channel → teamwork}/store/thread-state.d.ts +3 -3
- package/dist/commands/teamwork/store/thread-state.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/store/thread-state.js +1 -1
- package/dist/commands/teamwork/store/thread-state.js.map +1 -0
- package/dist/commands/teamwork/store/watch.d.ts +19 -0
- package/dist/commands/teamwork/store/watch.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/store/watch.js +8 -8
- package/dist/commands/teamwork/store/watch.js.map +1 -0
- package/dist/commands/teamwork/supervisor/idle.d.ts.map +1 -0
- package/dist/commands/teamwork/supervisor/idle.js.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/inbox.d.ts +2 -2
- package/dist/commands/teamwork/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/inbox.js +14 -14
- package/dist/commands/teamwork/supervisor/inbox.js.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/shutdown.d.ts +3 -6
- package/dist/commands/teamwork/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/shutdown.js +7 -17
- package/dist/commands/teamwork/supervisor/shutdown.js.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/stdout.d.ts +3 -5
- package/dist/commands/teamwork/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/stdout.js +12 -23
- package/dist/commands/teamwork/supervisor/stdout.js.map +1 -0
- package/dist/commands/teamwork/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/teamwork/supervisor/turns.js.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/warning.d.ts +5 -5
- package/dist/commands/teamwork/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor/warning.js +6 -6
- package/dist/commands/teamwork/supervisor/warning.js.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor.d.ts +21 -21
- package/dist/commands/teamwork/supervisor.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/supervisor.js +53 -63
- package/dist/commands/teamwork/supervisor.js.map +1 -0
- package/dist/commands/teamwork/teammate-adapters.d.ts +31 -0
- package/dist/commands/teamwork/teammate-adapters.d.ts.map +1 -0
- package/dist/commands/teamwork/teammate-adapters.js +96 -0
- package/dist/commands/teamwork/teammate-adapters.js.map +1 -0
- package/dist/commands/teamwork/teammate-config.d.ts +19 -0
- package/dist/commands/teamwork/teammate-config.d.ts.map +1 -0
- package/dist/commands/teamwork/teammate-config.js +97 -0
- package/dist/commands/teamwork/teammate-config.js.map +1 -0
- package/dist/commands/teamwork/teammate-launch.d.ts +58 -0
- package/dist/commands/teamwork/teammate-launch.d.ts.map +1 -0
- package/dist/commands/teamwork/teammate-launch.js +125 -0
- package/dist/commands/teamwork/teammate-launch.js.map +1 -0
- package/dist/commands/teamwork/text-body.d.ts +13 -0
- package/dist/commands/teamwork/text-body.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/text-body.js +3 -3
- package/dist/commands/teamwork/text-body.js.map +1 -0
- package/dist/commands/teamwork/threads.d.ts +35 -0
- package/dist/commands/teamwork/threads.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/threads.js +19 -19
- package/dist/commands/teamwork/threads.js.map +1 -0
- package/dist/commands/teamwork/title.d.ts +12 -0
- package/dist/commands/teamwork/title.d.ts.map +1 -0
- package/dist/commands/teamwork/title.js +24 -0
- package/dist/commands/teamwork/title.js.map +1 -0
- package/dist/commands/{channel → teamwork}/wait.d.ts +1 -5
- package/dist/commands/teamwork/wait.d.ts.map +1 -0
- package/dist/commands/{channel → teamwork}/wait.js +8 -21
- package/dist/commands/teamwork/wait.js.map +1 -0
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +48 -89
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/workflow.d.ts +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +9 -10
- package/dist/commands/workflow.js.map +1 -1
- package/dist/configurators/claude.d.ts +0 -17
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +2 -61
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/shared.d.ts.map +1 -1
- package/dist/configurators/shared.js +2 -2
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/snow.js +1 -1
- package/dist/configurators/snow.js.map +1 -1
- package/dist/configurators/workflow.d.ts +1 -1
- package/dist/configurators/workflow.js +5 -5
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/constants/paths.d.ts +1 -1
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +1 -1
- package/dist/constants/paths.js.map +1 -1
- package/dist/migrations/manifests/0.7.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.18.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.21.json +17 -0
- package/dist/migrations/manifests/0.7.0-beta.22.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.23.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.24.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.25.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.26.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.27.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.28.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.29.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.30.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.31.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.32.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.33.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.34.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.35.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.36.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.37.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.38.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.39.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.40.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.41.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.42.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.43.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.44.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.45.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.46.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.47.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.48.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.49.json +13 -0
- package/dist/migrations/manifests/0.7.0-beta.50.json +12 -0
- package/dist/migrations/manifests/0.7.0-beta.51.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.52.json +9 -0
- package/dist/migrations/manifests/0.7.0-beta.53.json +27 -0
- package/dist/migrations/manifests/0.7.0-beta.54.json +8 -0
- package/dist/migrations/manifests/0.7.0-beta.9.json +9 -0
- package/dist/migrations/manifests/0.7.1.json +9 -0
- package/dist/templates/claude/hooks/statusline.py +0 -7
- package/dist/templates/codex/hooks/session-start.py +31 -38
- package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/SKILL.md +10 -0
- package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/workflow.md +40 -0
- package/dist/templates/common/bundled-skills/trellis-delivery-review-and-closeout/SKILL.md +10 -0
- package/dist/templates/common/bundled-skills/trellis-delivery-review-and-closeout/workflow.md +55 -0
- package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/SKILL.md +10 -0
- package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/workflow.md +33 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +25 -25
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +13 -19
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +27 -75
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +17 -56
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/bundled-skills.md +14 -11
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +0 -33
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-teamwork.md +32 -0
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +25 -111
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +19 -60
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/SKILL.md +10 -0
- package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/workflow.md +36 -0
- package/dist/templates/common/bundled-skills/trellis-task-implementation/SKILL.md +10 -0
- package/dist/templates/common/bundled-skills/trellis-task-implementation/workflow.md +29 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/SKILL.md +73 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/coordination-modes.md +29 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-configuration-matrix.md +31 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-processes.md +37 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teamwork-plan-construction.md +78 -0
- package/dist/templates/common/commands/continue.md +9 -49
- package/dist/templates/common/commands/finish-work.md +10 -58
- package/dist/templates/common/commands/start.md +19 -49
- package/dist/templates/common/skills/brainstorm.md +11 -191
- package/dist/templates/copilot/hooks/session-start.py +30 -26
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +7 -150
- package/dist/templates/copilot/prompts/finish-work.prompt.md +11 -88
- package/dist/templates/copilot/prompts/record-session.prompt.md +4 -12
- package/dist/templates/copilot/prompts/start.prompt.md +12 -10
- package/dist/templates/dsh/DSH.md +2 -2
- package/dist/templates/kiro/agents/trellis.json +2 -2
- package/dist/templates/markdown/agents.md +14 -3
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +9 -8
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +1 -1
- package/dist/templates/markdown/workspace-index.md +0 -1
- package/dist/templates/omp/extensions/trellis/index.ts.txt +28 -17
- package/dist/templates/opencode/lib/session-utils.js +20 -25
- package/dist/templates/opencode/lib/trellis-context.js +4 -76
- package/dist/templates/opencode/plugins/inject-subagent-context.js +5 -4
- package/dist/templates/opencode/plugins/inject-workflow-state.js +14 -17
- package/dist/templates/shared-hooks/inject-shell-session-context.py +3 -3
- package/dist/templates/shared-hooks/inject-subagent-context.py +445 -67
- package/dist/templates/shared-hooks/inject-workflow-state.py +44 -36
- package/dist/templates/shared-hooks/session-start.py +21 -33
- package/dist/templates/trellis/agents/delegated-worktree-primary-agent.md +18 -0
- package/dist/templates/trellis/agents/teammate-profiles.json +8 -0
- package/dist/templates/trellis/agents/teammate.md +63 -0
- package/dist/templates/trellis/config.yaml +29 -38
- package/dist/templates/trellis/gitignore.txt +1 -0
- package/dist/templates/trellis/index.d.ts +8 -12
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +14 -25
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/add_session.py +1 -1
- package/dist/templates/trellis/scripts/common/__init__.py +0 -1
- package/dist/templates/trellis/scripts/common/active_task.py +136 -100
- package/dist/templates/trellis/scripts/common/config.py +7 -9
- package/dist/templates/trellis/scripts/common/git_context.py +1 -1
- package/dist/templates/trellis/scripts/common/io.py +19 -0
- package/dist/templates/trellis/scripts/common/paths.py +0 -1
- package/dist/templates/trellis/scripts/common/safe_commit.py +11 -90
- package/dist/templates/trellis/scripts/common/session_context.py +1 -8
- package/dist/templates/trellis/scripts/common/spec_match.py +1 -1
- package/dist/templates/trellis/scripts/common/task_context.py +152 -59
- package/dist/templates/trellis/scripts/common/task_continuity.py +563 -0
- package/dist/templates/trellis/scripts/common/task_store.py +70 -548
- package/dist/templates/trellis/scripts/common/task_utils.py +4 -98
- package/dist/templates/trellis/scripts/common/task_workflow.py +1096 -0
- package/dist/templates/trellis/scripts/common/tasks.py +5 -8
- package/dist/templates/trellis/scripts/common/workflow_phase.py +8 -7
- package/dist/templates/trellis/scripts/hooks/linear_sync.py +3 -3
- package/dist/templates/trellis/scripts/task.py +114 -377
- package/dist/templates/trellis/workflow.md +111 -699
- package/dist/utils/agent-refs.d.ts +5 -5
- package/dist/utils/agent-refs.js +6 -6
- package/dist/utils/file-writer.d.ts +3 -2
- package/dist/utils/file-writer.d.ts.map +1 -1
- package/dist/utils/file-writer.js +3 -2
- package/dist/utils/file-writer.js.map +1 -1
- package/dist/utils/managed-paths.d.ts +0 -7
- package/dist/utils/managed-paths.d.ts.map +1 -1
- package/dist/utils/managed-paths.js +0 -40
- package/dist/utils/managed-paths.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts.map +1 -1
- package/dist/utils/manifest-prune.js +2 -11
- package/dist/utils/manifest-prune.js.map +1 -1
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
- package/dist/utils/uninstall-scrubbers.js +3 -3
- package/dist/utils/uninstall-scrubbers.js.map +1 -1
- package/dist/utils/workflow-resolver.d.ts +10 -16
- package/dist/utils/workflow-resolver.d.ts.map +1 -1
- package/dist/utils/workflow-resolver.js +25 -36
- package/dist/utils/workflow-resolver.js.map +1 -1
- package/package.json +2 -2
- package/dist/commands/channel/adapters/claude.d.ts.map +0 -1
- package/dist/commands/channel/adapters/claude.js.map +0 -1
- package/dist/commands/channel/adapters/codex.d.ts.map +0 -1
- package/dist/commands/channel/adapters/codex.js.map +0 -1
- package/dist/commands/channel/adapters/index.d.ts.map +0 -1
- package/dist/commands/channel/adapters/index.js.map +0 -1
- package/dist/commands/channel/adapters/types.d.ts.map +0 -1
- package/dist/commands/channel/adapters/types.js.map +0 -1
- package/dist/commands/channel/agent-loader.d.ts.map +0 -1
- package/dist/commands/channel/agent-loader.js.map +0 -1
- package/dist/commands/channel/context-loader.d.ts.map +0 -1
- package/dist/commands/channel/context-loader.js.map +0 -1
- package/dist/commands/channel/context-trust.d.ts.map +0 -1
- package/dist/commands/channel/context-trust.js.map +0 -1
- package/dist/commands/channel/context.d.ts +0 -16
- package/dist/commands/channel/context.d.ts.map +0 -1
- package/dist/commands/channel/context.js.map +0 -1
- package/dist/commands/channel/create.d.ts +0 -29
- package/dist/commands/channel/create.d.ts.map +0 -1
- package/dist/commands/channel/create.js +0 -47
- package/dist/commands/channel/create.js.map +0 -1
- package/dist/commands/channel/dev-parse-trace.d.ts.map +0 -1
- package/dist/commands/channel/dev-parse-trace.js.map +0 -1
- package/dist/commands/channel/guard.d.ts.map +0 -1
- package/dist/commands/channel/guard.js.map +0 -1
- package/dist/commands/channel/index.d.ts +0 -3
- package/dist/commands/channel/index.d.ts.map +0 -1
- package/dist/commands/channel/index.js.map +0 -1
- package/dist/commands/channel/interrupt.d.ts.map +0 -1
- package/dist/commands/channel/interrupt.js +0 -22
- package/dist/commands/channel/interrupt.js.map +0 -1
- package/dist/commands/channel/kill.d.ts +0 -7
- package/dist/commands/channel/kill.d.ts.map +0 -1
- package/dist/commands/channel/kill.js.map +0 -1
- package/dist/commands/channel/list.d.ts +0 -18
- package/dist/commands/channel/list.d.ts.map +0 -1
- package/dist/commands/channel/list.js.map +0 -1
- package/dist/commands/channel/messages.d.ts.map +0 -1
- package/dist/commands/channel/messages.js.map +0 -1
- package/dist/commands/channel/rm.d.ts +0 -27
- package/dist/commands/channel/rm.d.ts.map +0 -1
- package/dist/commands/channel/rm.js.map +0 -1
- package/dist/commands/channel/run.d.ts +0 -32
- package/dist/commands/channel/run.js +0 -141
- package/dist/commands/channel/run.js.map +0 -1
- package/dist/commands/channel/send.d.ts.map +0 -1
- package/dist/commands/channel/send.js.map +0 -1
- package/dist/commands/channel/spawn.d.ts.map +0 -1
- package/dist/commands/channel/spawn.js.map +0 -1
- package/dist/commands/channel/store/events.d.ts +0 -22
- package/dist/commands/channel/store/events.d.ts.map +0 -1
- package/dist/commands/channel/store/events.js.map +0 -1
- package/dist/commands/channel/store/filter.d.ts +0 -3
- package/dist/commands/channel/store/filter.d.ts.map +0 -1
- package/dist/commands/channel/store/filter.js +0 -2
- package/dist/commands/channel/store/filter.js.map +0 -1
- package/dist/commands/channel/store/lock.d.ts.map +0 -1
- package/dist/commands/channel/store/lock.js.map +0 -1
- package/dist/commands/channel/store/paths.d.ts.map +0 -1
- package/dist/commands/channel/store/paths.js.map +0 -1
- package/dist/commands/channel/store/schema.d.ts +0 -27
- package/dist/commands/channel/store/schema.d.ts.map +0 -1
- package/dist/commands/channel/store/schema.js +0 -34
- package/dist/commands/channel/store/schema.js.map +0 -1
- package/dist/commands/channel/store/thread-state.d.ts.map +0 -1
- package/dist/commands/channel/store/thread-state.js.map +0 -1
- package/dist/commands/channel/store/watch.d.ts +0 -19
- package/dist/commands/channel/store/watch.d.ts.map +0 -1
- package/dist/commands/channel/store/watch.js.map +0 -1
- package/dist/commands/channel/supervisor/idle.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/idle.js.map +0 -1
- package/dist/commands/channel/supervisor/inbox.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/inbox.js.map +0 -1
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/shutdown.js.map +0 -1
- package/dist/commands/channel/supervisor/stdout.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/stdout.js.map +0 -1
- package/dist/commands/channel/supervisor/turns.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/turns.js.map +0 -1
- package/dist/commands/channel/supervisor/warning.d.ts.map +0 -1
- package/dist/commands/channel/supervisor/warning.js.map +0 -1
- package/dist/commands/channel/supervisor.d.ts.map +0 -1
- package/dist/commands/channel/supervisor.js.map +0 -1
- package/dist/commands/channel/text-body.d.ts +0 -13
- package/dist/commands/channel/text-body.d.ts.map +0 -1
- package/dist/commands/channel/text-body.js.map +0 -1
- package/dist/commands/channel/threads.d.ts +0 -39
- package/dist/commands/channel/threads.d.ts.map +0 -1
- package/dist/commands/channel/threads.js.map +0 -1
- package/dist/commands/channel/title.d.ts +0 -12
- package/dist/commands/channel/title.d.ts.map +0 -1
- package/dist/commands/channel/title.js +0 -24
- package/dist/commands/channel/title.js.map +0 -1
- package/dist/commands/channel/wait.d.ts.map +0 -1
- package/dist/commands/channel/wait.js.map +0 -1
- package/dist/commands/channel/workers.d.ts +0 -9
- package/dist/commands/channel/workers.d.ts.map +0 -1
- package/dist/commands/channel/workers.js +0 -31
- package/dist/commands/channel/workers.js.map +0 -1
- package/dist/templates/common/bundled-skills/trellis-channel/SKILL.md +0 -69
- package/dist/templates/common/bundled-skills/trellis-channel/references/command-reference.md +0 -549
- package/dist/templates/common/bundled-skills/trellis-channel/references/forum.md +0 -233
- package/dist/templates/common/bundled-skills/trellis-channel/references/progress-debugging.md +0 -237
- package/dist/templates/common/bundled-skills/trellis-channel/references/subnode-work.md +0 -193
- package/dist/templates/common/bundled-skills/trellis-channel/references/workers.md +0 -295
- package/dist/templates/common/bundled-skills/trellis-channel/references/workflows.md +0 -131
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-channel.md +0 -70
- package/dist/templates/common/bundled-skills/trellis-research-record/SKILL.md +0 -14
- package/dist/templates/copilot/prompts/parallel.prompt.md +0 -204
- package/dist/templates/trellis/agents/check.md +0 -70
- package/dist/templates/trellis/agents/implement.md +0 -71
- package/dist/templates/trellis/agents/subnode.env +0 -4
- package/dist/templates/trellis/agents/subnode.md +0 -69
- package/dist/templates/trellis/scripts/common/context_projection.py +0 -508
- package/dist/templates/trellis/scripts/common/continuation_record.py +0 -450
- package/dist/templates/trellis/scripts/common/ownership_record.py +0 -439
- package/dist/templates/trellis/scripts/subnode_artifact.py +0 -597
- package/dist/templates/trellis/scripts/workspace_note.py +0 -126
- /package/dist/commands/{channel → teamwork}/adapters/types.js +0 -0
- /package/dist/commands/{channel → teamwork}/supervisor/idle.d.ts +0 -0
- /package/dist/commands/{channel → teamwork}/supervisor/idle.js +0 -0
- /package/dist/commands/{channel → teamwork}/supervisor/turns.d.ts +0 -0
- /package/dist/commands/{channel → teamwork}/supervisor/turns.js +0 -0
|
@@ -87,14 +87,6 @@ def find_repo_root(start_path: str) -> str | None:
|
|
|
87
87
|
return None
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
def _real_path_contained(base_real: str, target_real: str) -> bool:
|
|
91
|
-
"""Return whether a real path is inside the real base path."""
|
|
92
|
-
try:
|
|
93
|
-
return os.path.commonpath([base_real, target_real]) == base_real
|
|
94
|
-
except ValueError:
|
|
95
|
-
return False
|
|
96
|
-
|
|
97
|
-
|
|
98
90
|
def _detect_platform(input_data: dict) -> str | None:
|
|
99
91
|
if _hook_event_name(input_data) == "SubagentStart":
|
|
100
92
|
return "codex"
|
|
@@ -149,7 +141,7 @@ def get_current_task(
|
|
|
149
141
|
input_data: dict,
|
|
150
142
|
*,
|
|
151
143
|
platform: str | None = None,
|
|
152
|
-
allow_single_session_fallback: bool =
|
|
144
|
+
allow_single_session_fallback: bool = True,
|
|
153
145
|
allow_environment_context: bool = True,
|
|
154
146
|
require_existing: bool = False,
|
|
155
147
|
) -> str | None:
|
|
@@ -175,11 +167,11 @@ def get_current_task(
|
|
|
175
167
|
|
|
176
168
|
|
|
177
169
|
# =============================================================================
|
|
178
|
-
# Context Injection
|
|
170
|
+
# Context Injection Limits (issue #441)
|
|
179
171
|
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
182
|
-
#
|
|
172
|
+
# Notice text and behavior mirrored byte-for-byte in the Pi TS extension
|
|
173
|
+
# (templates/pi/extensions/trellis/index.ts.txt). Changing wording here
|
|
174
|
+
# requires changing it there too.
|
|
183
175
|
# =============================================================================
|
|
184
176
|
|
|
185
177
|
DEFAULT_MAX_FILE_BYTES = 32768
|
|
@@ -206,64 +198,455 @@ def _get_limits(repo_root: str) -> dict[str, int]:
|
|
|
206
198
|
return dict(DEFAULT_LIMITS)
|
|
207
199
|
|
|
208
200
|
|
|
209
|
-
def
|
|
210
|
-
"""
|
|
201
|
+
def truncate_utf8(data: bytes, cap: int) -> bytes:
|
|
202
|
+
"""Truncate ``data`` to at most ``cap`` bytes without splitting a UTF-8
|
|
203
|
+
multi-byte sequence.
|
|
211
204
|
|
|
212
|
-
|
|
213
|
-
resolves from the active project's stamped `.trellis/scripts` tree.
|
|
205
|
+
``cap <= 0`` means "no limit" — returns ``data`` unchanged.
|
|
214
206
|
"""
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
207
|
+
if cap <= 0 or len(data) <= cap:
|
|
208
|
+
return data
|
|
209
|
+
|
|
210
|
+
truncated = data[:cap]
|
|
211
|
+
i = len(truncated)
|
|
212
|
+
# Back off over continuation bytes (10xxxxxx) to find the lead byte.
|
|
213
|
+
while i > 0 and (truncated[i - 1] & 0xC0) == 0x80:
|
|
214
|
+
i -= 1
|
|
215
|
+
if i == 0:
|
|
216
|
+
return b""
|
|
217
|
+
|
|
218
|
+
lead = truncated[i - 1]
|
|
219
|
+
if lead & 0x80:
|
|
220
|
+
if (lead & 0xE0) == 0xC0:
|
|
221
|
+
seq_len = 2
|
|
222
|
+
elif (lead & 0xF0) == 0xE0:
|
|
223
|
+
seq_len = 3
|
|
224
|
+
elif (lead & 0xF8) == 0xF0:
|
|
225
|
+
seq_len = 4
|
|
226
|
+
else:
|
|
227
|
+
seq_len = 1
|
|
228
|
+
# Cut before the lead byte when its full sequence didn't fit;
|
|
229
|
+
# otherwise the trailing sequence is complete — keep it whole.
|
|
230
|
+
if (i - 1) + seq_len > len(truncated):
|
|
231
|
+
return truncated[: i - 1]
|
|
232
|
+
|
|
233
|
+
return truncated
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class _Budget:
|
|
237
|
+
"""Tracks the running total of bytes emitted into the sub-agent context."""
|
|
238
|
+
|
|
239
|
+
def __init__(self, max_total_bytes: int) -> None:
|
|
240
|
+
self.max_total_bytes = max_total_bytes
|
|
241
|
+
self.used = 0
|
|
242
|
+
|
|
243
|
+
def has_room(self, size: int) -> bool:
|
|
244
|
+
if self.max_total_bytes <= 0:
|
|
245
|
+
return True
|
|
246
|
+
return self.used + size <= self.max_total_bytes
|
|
247
|
+
|
|
248
|
+
def add(self, size: int) -> None:
|
|
249
|
+
self.used += size
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _real_path_contained(base_real: str, target_real: str) -> bool:
|
|
253
|
+
"""Whether an already-realpath'd target sits under an already-realpath'd base.
|
|
254
|
+
|
|
255
|
+
ValueError on Windows when the two sit on different drives; that is
|
|
256
|
+
outside the base by definition, so it fails closed.
|
|
257
|
+
"""
|
|
258
|
+
try:
|
|
259
|
+
return os.path.commonpath([base_real, target_real]) == base_real
|
|
260
|
+
except ValueError:
|
|
261
|
+
return False
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def _read_file_bytes(base_path: str, file_path: str) -> bytes | None:
|
|
265
|
+
"""Read raw file bytes, return None if file doesn't exist."""
|
|
266
|
+
full_path = os.path.join(base_path, file_path)
|
|
267
|
+
try:
|
|
268
|
+
root_real = os.path.realpath(base_path)
|
|
269
|
+
# `.trellis` may itself be a symlink into a store outside the repo
|
|
270
|
+
# (#567); its real location is a second legitimate containment base.
|
|
271
|
+
workflow_real = os.path.realpath(os.path.join(base_path, ".trellis"))
|
|
272
|
+
full_real = os.path.realpath(full_path)
|
|
273
|
+
if not _real_path_contained(root_real, full_real) and not (
|
|
274
|
+
_real_path_contained(workflow_real, full_real)
|
|
275
|
+
):
|
|
276
|
+
return None
|
|
277
|
+
except OSError:
|
|
278
|
+
return None
|
|
279
|
+
if os.path.exists(full_path) and os.path.isfile(full_path):
|
|
280
|
+
try:
|
|
281
|
+
with open(full_path, "rb") as f:
|
|
282
|
+
return f.read()
|
|
283
|
+
except Exception:
|
|
284
|
+
return None
|
|
285
|
+
return None
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _truncate_notice(path: str, cap: int) -> str:
|
|
289
|
+
return f"\n[Trellis: truncated at {cap} bytes — read {path} for the full content]"
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
def _is_binary_content(data: bytes) -> bool:
|
|
293
|
+
"""Return True when raw bytes should not be decoded into model context."""
|
|
294
|
+
if b"\x00" in data:
|
|
295
|
+
return True
|
|
296
|
+
try:
|
|
297
|
+
data.decode("utf-8", errors="strict")
|
|
298
|
+
except UnicodeDecodeError:
|
|
299
|
+
return True
|
|
300
|
+
return False
|
|
301
|
+
|
|
219
302
|
|
|
220
|
-
|
|
221
|
-
|
|
303
|
+
def _binary_notice(path: str, size: int, reason: str) -> str:
|
|
304
|
+
return (
|
|
305
|
+
f"[Trellis: not inlined (binary file) — "
|
|
306
|
+
f"{path} ({size} bytes): {reason}]"
|
|
222
307
|
)
|
|
223
308
|
|
|
224
309
|
|
|
310
|
+
def _index_notice(path: str, size: int, reason: str) -> str:
|
|
311
|
+
return (
|
|
312
|
+
f"[Trellis: not inlined (total context limit reached) — "
|
|
313
|
+
f"{path} ({size} bytes): {reason}]"
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def _budgeted_block(
|
|
318
|
+
budget: _Budget,
|
|
319
|
+
header: str,
|
|
320
|
+
plain_path: str,
|
|
321
|
+
content: str,
|
|
322
|
+
reason: str,
|
|
323
|
+
size_for_index: int,
|
|
324
|
+
) -> str:
|
|
325
|
+
"""Return an inlined ``=== header ===`` block, or degrade to an index
|
|
326
|
+
notice once the total context budget is exhausted."""
|
|
327
|
+
block = f"=== {header} ===\n{content}"
|
|
328
|
+
block_bytes = len(block.encode("utf-8"))
|
|
329
|
+
if not budget.has_room(block_bytes):
|
|
330
|
+
notice = _index_notice(plain_path, size_for_index, reason)
|
|
331
|
+
budget.add(len(notice.encode("utf-8")))
|
|
332
|
+
return notice
|
|
333
|
+
budget.add(block_bytes)
|
|
334
|
+
return block
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def _materialize_file(
|
|
338
|
+
base_path: str,
|
|
339
|
+
file_path: str,
|
|
340
|
+
reason: str,
|
|
341
|
+
limits: dict[str, int],
|
|
342
|
+
budget: _Budget,
|
|
343
|
+
) -> str | None:
|
|
344
|
+
"""Read a JSONL-referenced file, apply the per-file cap, then budget it."""
|
|
345
|
+
data = _read_file_bytes(base_path, file_path)
|
|
346
|
+
if data is None:
|
|
347
|
+
return None
|
|
348
|
+
|
|
349
|
+
size = len(data)
|
|
350
|
+
if _is_binary_content(data):
|
|
351
|
+
notice = _binary_notice(file_path, size, reason)
|
|
352
|
+
budget.add(len(notice.encode("utf-8")))
|
|
353
|
+
return notice
|
|
354
|
+
|
|
355
|
+
cap = limits["max_file_bytes"]
|
|
356
|
+
truncated_bytes = truncate_utf8(data, cap)
|
|
357
|
+
content = truncated_bytes.decode("utf-8", errors="replace")
|
|
358
|
+
if len(truncated_bytes) < size:
|
|
359
|
+
content += _truncate_notice(file_path, cap)
|
|
360
|
+
|
|
361
|
+
return _budgeted_block(budget, file_path, file_path, content, reason, size)
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def _materialize_directory(
|
|
365
|
+
base_path: str,
|
|
366
|
+
dir_path: str,
|
|
367
|
+
reason: str,
|
|
368
|
+
limits: dict[str, int],
|
|
369
|
+
budget: _Budget,
|
|
370
|
+
max_files: int = 20,
|
|
371
|
+
) -> list[str]:
|
|
372
|
+
"""Read all .md files in a directory, applying the same per-file and
|
|
373
|
+
total caps as a single-file JSONL entry."""
|
|
374
|
+
full_path = os.path.join(base_path, dir_path)
|
|
375
|
+
if not os.path.exists(full_path) or not os.path.isdir(full_path):
|
|
376
|
+
return []
|
|
377
|
+
|
|
378
|
+
blocks: list[str] = []
|
|
379
|
+
try:
|
|
380
|
+
md_files = sorted(
|
|
381
|
+
f
|
|
382
|
+
for f in os.listdir(full_path)
|
|
383
|
+
if f.endswith(".md") and os.path.isfile(os.path.join(full_path, f))
|
|
384
|
+
)
|
|
385
|
+
for filename in md_files[:max_files]:
|
|
386
|
+
relative_path = os.path.join(dir_path, filename)
|
|
387
|
+
block = _materialize_file(base_path, relative_path, reason, limits, budget)
|
|
388
|
+
if block:
|
|
389
|
+
blocks.append(block)
|
|
390
|
+
except Exception:
|
|
391
|
+
pass
|
|
392
|
+
|
|
393
|
+
return blocks
|
|
394
|
+
|
|
395
|
+
|
|
225
396
|
def read_jsonl_entries(base_path: str, jsonl_path: str) -> list[dict]:
|
|
226
|
-
"""
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
397
|
+
"""
|
|
398
|
+
Parse all file/directory entries referenced in a jsonl context file.
|
|
399
|
+
|
|
400
|
+
Schema:
|
|
401
|
+
{"file": "path/to/file.md", "reason": "..."}
|
|
402
|
+
{"file": "path/to/dir/", "type": "directory", "reason": "..."}
|
|
403
|
+
{"_example": "..."} # legacy placeholder — skipped (no `file` field)
|
|
231
404
|
|
|
232
|
-
|
|
233
|
-
|
|
405
|
+
Rows without a ``file`` field (e.g. the placeholder line older Trellis
|
|
406
|
+
versions wrote at ``task.py create`` time) are skipped silently. If the
|
|
407
|
+
resulting entry list is empty, a stderr warning is emitted so the operator
|
|
408
|
+
can debug missing context.
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
[{"file": path, "type": "file" | "directory", "reason": reason}, ...]
|
|
412
|
+
"""
|
|
413
|
+
full_path = os.path.join(base_path, jsonl_path)
|
|
414
|
+
if not os.path.exists(full_path):
|
|
234
415
|
print(
|
|
235
416
|
f"[inject-subagent-context] WARN: {jsonl_path} not found — "
|
|
236
|
-
"sub-agent will receive only task artifacts",
|
|
417
|
+
f"sub-agent will receive only task artifacts",
|
|
237
418
|
file=sys.stderr,
|
|
238
419
|
)
|
|
239
|
-
|
|
420
|
+
return []
|
|
421
|
+
|
|
422
|
+
entries: list[dict] = []
|
|
423
|
+
saw_real_entry = False
|
|
424
|
+
try:
|
|
425
|
+
with open(full_path, "r", encoding="utf-8") as f:
|
|
426
|
+
for line in f:
|
|
427
|
+
line = line.strip()
|
|
428
|
+
if not line:
|
|
429
|
+
continue
|
|
430
|
+
try:
|
|
431
|
+
item = json.loads(line)
|
|
432
|
+
file_path = item.get("file") or item.get("path")
|
|
433
|
+
|
|
434
|
+
if not file_path:
|
|
435
|
+
# Seed / comment row — skip silently
|
|
436
|
+
continue
|
|
437
|
+
|
|
438
|
+
saw_real_entry = True
|
|
439
|
+
entries.append(
|
|
440
|
+
{
|
|
441
|
+
"file": file_path,
|
|
442
|
+
"type": item.get("type", "file"),
|
|
443
|
+
"reason": item.get("reason") or "-",
|
|
444
|
+
}
|
|
445
|
+
)
|
|
446
|
+
except json.JSONDecodeError:
|
|
447
|
+
continue
|
|
448
|
+
except Exception:
|
|
449
|
+
pass
|
|
450
|
+
|
|
451
|
+
if not saw_real_entry:
|
|
240
452
|
print(
|
|
241
453
|
f"[inject-subagent-context] WARN: {jsonl_path} has no curated "
|
|
242
|
-
"entries (only seed / empty) — sub-agent will receive only "
|
|
243
|
-
"task artifacts. See workflow.md planning artifact guidance.",
|
|
454
|
+
f"entries (only seed / empty) — sub-agent will receive only "
|
|
455
|
+
f"task artifacts. See workflow.md planning artifact guidance.",
|
|
244
456
|
file=sys.stderr,
|
|
245
457
|
)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
458
|
+
|
|
459
|
+
return entries
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def _materialize_jsonl_entries(
|
|
463
|
+
base_path: str, jsonl_path: str, limits: dict[str, int], budget: _Budget
|
|
464
|
+
) -> list[str]:
|
|
465
|
+
"""Materialize every entry in a jsonl context file into context blocks,
|
|
466
|
+
applying per-file and total budget caps."""
|
|
467
|
+
blocks: list[str] = []
|
|
468
|
+
for entry in read_jsonl_entries(base_path, jsonl_path):
|
|
469
|
+
if entry["type"] == "directory":
|
|
470
|
+
blocks.extend(
|
|
471
|
+
_materialize_directory(
|
|
472
|
+
base_path, entry["file"], entry["reason"], limits, budget
|
|
473
|
+
)
|
|
474
|
+
)
|
|
475
|
+
else:
|
|
476
|
+
block = _materialize_file(
|
|
477
|
+
base_path, entry["file"], entry["reason"], limits, budget
|
|
478
|
+
)
|
|
479
|
+
if block:
|
|
480
|
+
blocks.append(block)
|
|
481
|
+
return blocks
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def get_agent_context(
|
|
485
|
+
repo_root: str,
|
|
486
|
+
task_dir: str,
|
|
487
|
+
agent_type: str,
|
|
488
|
+
limits: dict[str, int],
|
|
489
|
+
budget: _Budget,
|
|
490
|
+
) -> str:
|
|
491
|
+
"""
|
|
492
|
+
Get context from {agent_type}.jsonl for the specified agent.
|
|
493
|
+
Only reads implement.jsonl or check.jsonl (the two JSONL files the task system creates).
|
|
494
|
+
"""
|
|
495
|
+
agent_jsonl = f"{task_dir}/{agent_type}.jsonl"
|
|
496
|
+
blocks = _materialize_jsonl_entries(repo_root, agent_jsonl, limits, budget)
|
|
497
|
+
if not blocks:
|
|
498
|
+
# Zero curated context reaches the model silently otherwise — the
|
|
499
|
+
# stderr WARN above never enters any session (#573). Put the fact in
|
|
500
|
+
# the prompt itself so the sub-agent compensates instead of assuming
|
|
501
|
+
# the spec context was complete.
|
|
502
|
+
return (
|
|
503
|
+
f"[Trellis] {agent_jsonl} has no curated entries, so no spec/research "
|
|
504
|
+
"context was injected. Before working, read the guidelines relevant "
|
|
505
|
+
"to the code you will touch under .trellis/spec/, and treat the task "
|
|
506
|
+
"artifacts below as the only prepared context."
|
|
507
|
+
)
|
|
508
|
+
return "\n\n".join(blocks)
|
|
509
|
+
|
|
510
|
+
|
|
511
|
+
def _materialize_artifact(
|
|
512
|
+
base_path: str,
|
|
513
|
+
file_path: str,
|
|
514
|
+
header_label: str,
|
|
515
|
+
reason: str,
|
|
516
|
+
limits: dict[str, int],
|
|
517
|
+
budget: _Budget,
|
|
518
|
+
) -> str | None:
|
|
519
|
+
"""Read a task artifact (prd/design/implement.md), apply the per-artifact
|
|
520
|
+
cap, then budget it."""
|
|
521
|
+
data = _read_file_bytes(base_path, file_path)
|
|
522
|
+
if data is None:
|
|
523
|
+
return None
|
|
524
|
+
|
|
525
|
+
size = len(data)
|
|
526
|
+
cap = limits["max_artifact_bytes"]
|
|
527
|
+
truncated_bytes = truncate_utf8(data, cap)
|
|
528
|
+
content = truncated_bytes.decode("utf-8", errors="replace")
|
|
529
|
+
if len(truncated_bytes) < size:
|
|
530
|
+
content += _truncate_notice(file_path, cap)
|
|
531
|
+
|
|
532
|
+
return _budgeted_block(budget, header_label, file_path, content, reason, size)
|
|
250
533
|
|
|
251
534
|
|
|
252
535
|
def get_implement_context(repo_root: str, task_dir: str) -> str:
|
|
253
|
-
"""
|
|
254
|
-
|
|
536
|
+
"""
|
|
537
|
+
Complete context for Implement Agent
|
|
538
|
+
|
|
539
|
+
Read order:
|
|
540
|
+
1. All files in implement.jsonl (spec/research manifests)
|
|
541
|
+
2. prd.md (requirements)
|
|
542
|
+
3. design.md if present (technical design)
|
|
543
|
+
4. implement.md if present (execution plan)
|
|
544
|
+
"""
|
|
545
|
+
limits = _get_limits(repo_root)
|
|
546
|
+
budget = _Budget(limits["max_total_bytes"])
|
|
547
|
+
context_parts = []
|
|
548
|
+
|
|
549
|
+
# 1. Read implement.jsonl
|
|
550
|
+
base_context = get_agent_context(repo_root, task_dir, "implement", limits, budget)
|
|
551
|
+
if base_context:
|
|
552
|
+
context_parts.append(base_context)
|
|
553
|
+
|
|
554
|
+
# 2. Requirements document
|
|
555
|
+
prd_block = _materialize_artifact(
|
|
556
|
+
repo_root,
|
|
557
|
+
f"{task_dir}/prd.md",
|
|
558
|
+
f"{task_dir}/prd.md (Requirements)",
|
|
559
|
+
"Requirements document",
|
|
560
|
+
limits,
|
|
561
|
+
budget,
|
|
562
|
+
)
|
|
563
|
+
if prd_block:
|
|
564
|
+
context_parts.append(prd_block)
|
|
565
|
+
|
|
566
|
+
# 3. Technical design for complex tasks
|
|
567
|
+
design_block = _materialize_artifact(
|
|
568
|
+
repo_root,
|
|
569
|
+
f"{task_dir}/design.md",
|
|
570
|
+
f"{task_dir}/design.md (Technical Design)",
|
|
571
|
+
"Technical design document",
|
|
572
|
+
limits,
|
|
573
|
+
budget,
|
|
574
|
+
)
|
|
575
|
+
if design_block:
|
|
576
|
+
context_parts.append(design_block)
|
|
577
|
+
|
|
578
|
+
# 4. Execution plan for complex tasks
|
|
579
|
+
implement_plan_block = _materialize_artifact(
|
|
580
|
+
repo_root,
|
|
581
|
+
f"{task_dir}/implement.md",
|
|
582
|
+
f"{task_dir}/implement.md (Execution Plan)",
|
|
583
|
+
"Execution plan document",
|
|
584
|
+
limits,
|
|
585
|
+
budget,
|
|
586
|
+
)
|
|
587
|
+
if implement_plan_block:
|
|
588
|
+
context_parts.append(implement_plan_block)
|
|
589
|
+
|
|
590
|
+
return "\n\n".join(context_parts)
|
|
255
591
|
|
|
256
592
|
|
|
257
593
|
def get_check_context(repo_root: str, task_dir: str) -> str:
|
|
258
|
-
"""
|
|
259
|
-
|
|
594
|
+
"""
|
|
595
|
+
Context for Check Agent: check.jsonl + task artifacts.
|
|
596
|
+
"""
|
|
597
|
+
limits = _get_limits(repo_root)
|
|
598
|
+
budget = _Budget(limits["max_total_bytes"])
|
|
599
|
+
context_parts = []
|
|
600
|
+
|
|
601
|
+
base_context = get_agent_context(repo_root, task_dir, "check", limits, budget)
|
|
602
|
+
if base_context:
|
|
603
|
+
context_parts.append(base_context)
|
|
604
|
+
|
|
605
|
+
prd_block = _materialize_artifact(
|
|
606
|
+
repo_root,
|
|
607
|
+
f"{task_dir}/prd.md",
|
|
608
|
+
f"{task_dir}/prd.md (Requirements)",
|
|
609
|
+
"Requirements document",
|
|
610
|
+
limits,
|
|
611
|
+
budget,
|
|
612
|
+
)
|
|
613
|
+
if prd_block:
|
|
614
|
+
context_parts.append(prd_block)
|
|
615
|
+
|
|
616
|
+
design_block = _materialize_artifact(
|
|
617
|
+
repo_root,
|
|
618
|
+
f"{task_dir}/design.md",
|
|
619
|
+
f"{task_dir}/design.md (Technical Design)",
|
|
620
|
+
"Technical design document",
|
|
621
|
+
limits,
|
|
622
|
+
budget,
|
|
623
|
+
)
|
|
624
|
+
if design_block:
|
|
625
|
+
context_parts.append(design_block)
|
|
626
|
+
|
|
627
|
+
implement_plan_block = _materialize_artifact(
|
|
628
|
+
repo_root,
|
|
629
|
+
f"{task_dir}/implement.md",
|
|
630
|
+
f"{task_dir}/implement.md (Execution Plan)",
|
|
631
|
+
"Execution plan document",
|
|
632
|
+
limits,
|
|
633
|
+
budget,
|
|
634
|
+
)
|
|
635
|
+
if implement_plan_block:
|
|
636
|
+
context_parts.append(implement_plan_block)
|
|
637
|
+
|
|
638
|
+
return "\n\n".join(context_parts)
|
|
260
639
|
|
|
261
640
|
|
|
262
641
|
def get_finish_context(repo_root: str, task_dir: str) -> str:
|
|
263
|
-
"""
|
|
642
|
+
"""
|
|
643
|
+
Context for Finish phase: reuses check.jsonl + prd.md
|
|
644
|
+
(Finish is a final check, same context source.)
|
|
645
|
+
"""
|
|
264
646
|
return get_check_context(repo_root, task_dir)
|
|
265
647
|
|
|
266
648
|
|
|
649
|
+
|
|
267
650
|
def build_implement_prompt(original_prompt: str, context: str) -> str:
|
|
268
651
|
"""Build complete prompt for Implement"""
|
|
269
652
|
return f"""<!-- trellis-hook-injected -->
|
|
@@ -774,31 +1157,26 @@ def main():
|
|
|
774
1157
|
# Check for [finish] marker in prompt (check agent with finish context)
|
|
775
1158
|
is_finish_phase = "[finish]" in original_prompt.lower()
|
|
776
1159
|
|
|
777
|
-
# Get context and build prompt based on subagent type
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
# Finish phase: use finish context (lighter, focused on final verification)
|
|
789
|
-
context = get_finish_context(repo_root, task_dir)
|
|
790
|
-
new_prompt = build_finish_prompt(original_prompt, context)
|
|
791
|
-
else:
|
|
792
|
-
# Regular check phase: use check context (full specs for self-fix loop)
|
|
793
|
-
context = get_check_context(repo_root, task_dir)
|
|
794
|
-
new_prompt = build_check_prompt(original_prompt, context)
|
|
795
|
-
elif subagent_type == AGENT_RESEARCH:
|
|
796
|
-
# Research can work without task directory
|
|
797
|
-
context = get_research_context(repo_root, task_dir)
|
|
798
|
-
new_prompt = build_research_prompt(original_prompt, context)
|
|
1160
|
+
# Get context and build prompt based on subagent type
|
|
1161
|
+
if subagent_type == AGENT_IMPLEMENT:
|
|
1162
|
+
assert task_dir is not None # validated above
|
|
1163
|
+
context = get_implement_context(repo_root, task_dir)
|
|
1164
|
+
new_prompt = build_implement_prompt(original_prompt, context)
|
|
1165
|
+
elif subagent_type == AGENT_CHECK:
|
|
1166
|
+
assert task_dir is not None # validated above
|
|
1167
|
+
if is_finish_phase:
|
|
1168
|
+
# Finish phase: use finish context (lighter, focused on final verification)
|
|
1169
|
+
context = get_finish_context(repo_root, task_dir)
|
|
1170
|
+
new_prompt = build_finish_prompt(original_prompt, context)
|
|
799
1171
|
else:
|
|
800
|
-
|
|
801
|
-
|
|
1172
|
+
# Regular check phase: use check context (full specs for self-fix loop)
|
|
1173
|
+
context = get_check_context(repo_root, task_dir)
|
|
1174
|
+
new_prompt = build_check_prompt(original_prompt, context)
|
|
1175
|
+
elif subagent_type == AGENT_RESEARCH:
|
|
1176
|
+
# Research can work without task directory
|
|
1177
|
+
context = get_research_context(repo_root, task_dir)
|
|
1178
|
+
new_prompt = build_research_prompt(original_prompt, context)
|
|
1179
|
+
else:
|
|
802
1180
|
sys.exit(0)
|
|
803
1181
|
|
|
804
1182
|
if not context:
|