@pennixrv/trellis 0.7.0-beta.9 → 0.7.1-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/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 +93 -90
- 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.1-beta.0.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.1.json +186 -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 -199
- package/dist/templates/copilot/hooks/session-start.py +30 -26
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +7 -160
- 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/extract.js +4 -0
- package/dist/templates/extract.js.map +1 -1
- 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 +598 -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 +119 -377
- package/dist/templates/trellis/workflow.md +111 -706
- 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 +2 -1
- package/dist/utils/manifest-prune.d.ts.map +1 -1
- package/dist/utils/manifest-prune.js +14 -16
- 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 -222
- 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 -76
- 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 -735
- 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
|
@@ -4,7 +4,7 @@ Safe git-add helpers for Trellis-owned paths.
|
|
|
4
4
|
Why this module exists
|
|
5
5
|
----------------------
|
|
6
6
|
A real user incident: a project's `.gitignore` listed `.trellis/` (company-wide
|
|
7
|
-
template / personal habit). When `add_session.py`
|
|
7
|
+
template / personal habit). When `add_session.py` ran
|
|
8
8
|
their auto-commit and `git add` failed with `ignored by .gitignore`, the AI
|
|
9
9
|
agent driving the workflow "fixed" it by retrying with
|
|
10
10
|
`git add -f .trellis/` — which fan-out-included every ignored subtree
|
|
@@ -13,8 +13,8 @@ agent driving the workflow "fixed" it by retrying with
|
|
|
13
13
|
|
|
14
14
|
Design
|
|
15
15
|
------
|
|
16
|
-
- Scripts only stage SPECIFIC product paths (journal files, index.md, the
|
|
17
|
-
current task dir
|
|
16
|
+
- Scripts only stage SPECIFIC product paths (journal files, index.md, and the
|
|
17
|
+
current task dir). Never the whole `.trellis/` tree.
|
|
18
18
|
- If plain `git add <specific>` fails with "ignored by", DO NOT retry with
|
|
19
19
|
``-f``. The presence of `.trellis/` in `.gitignore` is treated as user
|
|
20
20
|
intent ("keep .trellis/ local-only"). The script warns and skips the
|
|
@@ -37,7 +37,6 @@ from pathlib import Path
|
|
|
37
37
|
|
|
38
38
|
from .git import run_git, run_git_retry_index_lock
|
|
39
39
|
from .paths import (
|
|
40
|
-
DIR_ARCHIVE,
|
|
41
40
|
DIR_TASKS,
|
|
42
41
|
DIR_WORKFLOW,
|
|
43
42
|
DIR_WORKSPACE,
|
|
@@ -72,8 +71,7 @@ def safe_trellis_paths_to_add(
|
|
|
72
71
|
- .trellis/workspace/<developer>/journal-*.md
|
|
73
72
|
- .trellis/workspace/<developer>/index.md
|
|
74
73
|
- .trellis/tasks/<task_name>/ (ONLY the current task dir when
|
|
75
|
-
``task_name`` is passed
|
|
76
|
-
already lives under archive/)
|
|
74
|
+
``task_name`` is passed)
|
|
77
75
|
|
|
78
76
|
Excluded (intentionally — these must not be staged):
|
|
79
77
|
- .trellis/.backup-*, .trellis/worktrees/,
|
|
@@ -82,12 +80,11 @@ def safe_trellis_paths_to_add(
|
|
|
82
80
|
Scope contract (see #303 / break-loop analysis): when ``task_name`` is
|
|
83
81
|
passed, the task segment stages ONLY that task directory — it never walks
|
|
84
82
|
``tasks_dir.iterdir()`` over all active tasks. This mirrors
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
and prevents dirty changes in OTHER parallel-window task dirs from being
|
|
84
|
+
bundled into the session auto-commit.
|
|
87
85
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
should always pass ``task_name``.
|
|
86
|
+
With no ``task_name``, the function walks every direct task directory.
|
|
87
|
+
New callers should always pass ``task_name``.
|
|
91
88
|
"""
|
|
92
89
|
paths: list[str] = []
|
|
93
90
|
|
|
@@ -112,90 +109,20 @@ def safe_trellis_paths_to_add(
|
|
|
112
109
|
return paths
|
|
113
110
|
|
|
114
111
|
if task_name is not None:
|
|
115
|
-
# Narrow scope — ONLY the current task directory
|
|
112
|
+
# Narrow scope — ONLY the current task directory.
|
|
116
113
|
# Never iterdir() all tasks: parallel-window dirty task dirs must not
|
|
117
114
|
# leak into the session auto-commit.
|
|
118
115
|
active_task = tasks_dir / task_name
|
|
119
116
|
if active_task.is_dir():
|
|
120
117
|
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_name}")
|
|
121
|
-
archived_task = tasks_dir / DIR_ARCHIVE / task_name
|
|
122
|
-
if archived_task.is_dir():
|
|
123
|
-
paths.append(
|
|
124
|
-
f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}/{task_name}"
|
|
125
|
-
)
|
|
126
118
|
return paths
|
|
127
119
|
|
|
128
|
-
#
|
|
129
|
-
# directory and not the archive root, plus the whole archive subtree.
|
|
120
|
+
# Wide scope (no task_name): each direct task directory.
|
|
130
121
|
for child in sorted(tasks_dir.iterdir()):
|
|
131
122
|
if not child.is_dir():
|
|
132
123
|
continue
|
|
133
|
-
if child.name == DIR_ARCHIVE:
|
|
134
|
-
continue
|
|
135
124
|
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
|
|
136
125
|
|
|
137
|
-
archive_dir = tasks_dir / DIR_ARCHIVE
|
|
138
|
-
if archive_dir.is_dir():
|
|
139
|
-
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
|
|
140
|
-
|
|
141
|
-
return paths
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def safe_archive_paths_to_add(
|
|
145
|
-
repo_root: Path,
|
|
146
|
-
task_name: str | None = None,
|
|
147
|
-
modified_children: list[str] | None = None,
|
|
148
|
-
) -> list[str]:
|
|
149
|
-
"""Return paths to stage after `task.py archive`.
|
|
150
|
-
|
|
151
|
-
Scoped to ONLY the paths the archive operation actually touched:
|
|
152
|
-
|
|
153
|
-
- the archive subtree (where the freshly-moved task lives)
|
|
154
|
-
- the source task directory (for source-side deletes; caller pairs
|
|
155
|
-
this with `git rm --cached` since `git add` won't stage deletes
|
|
156
|
-
for a path that no longer exists in the working tree)
|
|
157
|
-
- any child task directories whose `task.json` was edited to drop
|
|
158
|
-
the archived parent (parent-children relationship update)
|
|
159
|
-
|
|
160
|
-
This narrow scope avoids "scope creep" — dirty changes in OTHER
|
|
161
|
-
active task dirs (parallel-window edits) are NOT bundled into the
|
|
162
|
-
archive commit. Callers handle each kind of change in its own
|
|
163
|
-
commit boundary.
|
|
164
|
-
|
|
165
|
-
Backwards-compat: with no arguments, the function walks the whole
|
|
166
|
-
`.trellis/tasks/` subtree the old way (active tasks + archive). New
|
|
167
|
-
callers should always pass `task_name`.
|
|
168
|
-
"""
|
|
169
|
-
paths: list[str] = []
|
|
170
|
-
tasks_dir = repo_root / DIR_WORKFLOW / DIR_TASKS
|
|
171
|
-
if not tasks_dir.is_dir():
|
|
172
|
-
return paths
|
|
173
|
-
|
|
174
|
-
archive_dir = tasks_dir / DIR_ARCHIVE
|
|
175
|
-
|
|
176
|
-
if task_name is not None:
|
|
177
|
-
# Narrow scope — only paths that still exist on disk (so
|
|
178
|
-
# `git add` doesn't choke on the moved-away source). The caller
|
|
179
|
-
# handles the source-side deletes via `git rm --cached`
|
|
180
|
-
# explicitly.
|
|
181
|
-
if archive_dir.is_dir():
|
|
182
|
-
paths.append(
|
|
183
|
-
f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}"
|
|
184
|
-
)
|
|
185
|
-
for child_name in modified_children or []:
|
|
186
|
-
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child_name}")
|
|
187
|
-
return paths
|
|
188
|
-
|
|
189
|
-
# Legacy wide scope (no task_name): preserve old behavior so callers
|
|
190
|
-
# that have not been updated keep working.
|
|
191
|
-
if archive_dir.is_dir():
|
|
192
|
-
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{DIR_ARCHIVE}")
|
|
193
|
-
for child in sorted(tasks_dir.iterdir()):
|
|
194
|
-
if not child.is_dir():
|
|
195
|
-
continue
|
|
196
|
-
if child.name == DIR_ARCHIVE:
|
|
197
|
-
continue
|
|
198
|
-
paths.append(f"{DIR_WORKFLOW}/{DIR_TASKS}/{child.name}")
|
|
199
126
|
return paths
|
|
200
127
|
|
|
201
128
|
|
|
@@ -225,9 +152,7 @@ def safe_git_add(
|
|
|
225
152
|
|
|
226
153
|
``retry_on_index_lock`` opts into the bounded backoff-retry for a held
|
|
227
154
|
``.git/index.lock`` (see :func:`~.git.run_git_retry_index_lock`). It is
|
|
228
|
-
off by default
|
|
229
|
-
directory on disk by the time it stages, needs to wait out a transient
|
|
230
|
-
lock rather than fail.
|
|
155
|
+
off by default; callers that already changed files on disk can opt in.
|
|
231
156
|
"""
|
|
232
157
|
if not paths:
|
|
233
158
|
return True, False, ""
|
|
@@ -275,10 +200,6 @@ def print_gitignore_warning(paths: list[str]) -> None:
|
|
|
275
200
|
"[WARN] .trellis/tasks/<task-dir>/",
|
|
276
201
|
file=sys.stderr,
|
|
277
202
|
)
|
|
278
|
-
print(
|
|
279
|
-
"[WARN] .trellis/tasks/archive/",
|
|
280
|
-
file=sys.stderr,
|
|
281
|
-
)
|
|
282
203
|
print("[WARN]", file=sys.stderr)
|
|
283
204
|
print(
|
|
284
205
|
"[WARN] Recommended: change your .gitignore from `.trellis/` to specific",
|
|
@@ -22,7 +22,6 @@ import sys
|
|
|
22
22
|
from pathlib import Path
|
|
23
23
|
|
|
24
24
|
from .active_task import resolve_context_key
|
|
25
|
-
from .continuation_record import status as continuity_status
|
|
26
25
|
from .config import get_git_packages
|
|
27
26
|
from .git import run_git
|
|
28
27
|
from .packages_context import get_packages_section
|
|
@@ -559,8 +558,6 @@ def get_context_json(repo_root: Path | None = None) -> dict:
|
|
|
559
558
|
if pkg_git_info:
|
|
560
559
|
result["packageGit"] = pkg_git_info
|
|
561
560
|
|
|
562
|
-
result["continuity"] = continuity_status(repo_root)
|
|
563
|
-
|
|
564
561
|
return result
|
|
565
562
|
|
|
566
563
|
|
|
@@ -647,8 +644,6 @@ def get_context_text(repo_root: Path | None = None) -> str:
|
|
|
647
644
|
lines.append("[!] This task has prd.md - read it for task details")
|
|
648
645
|
else:
|
|
649
646
|
lines.append("(none)")
|
|
650
|
-
continuity = continuity_status(repo_root)
|
|
651
|
-
lines.append(f"Continuation Record: {continuity['status']}")
|
|
652
647
|
lines.append("")
|
|
653
648
|
|
|
654
649
|
# Active tasks
|
|
@@ -802,8 +797,6 @@ def get_context_record_json(repo_root: Path | None = None) -> dict:
|
|
|
802
797
|
if pkg_git_info:
|
|
803
798
|
result["packageGit"] = pkg_git_info
|
|
804
799
|
|
|
805
|
-
result["continuity"] = continuity_status(repo_root)
|
|
806
|
-
|
|
807
800
|
return result
|
|
808
801
|
|
|
809
802
|
|
|
@@ -831,7 +824,7 @@ def get_context_text_record(repo_root: Path | None = None) -> str:
|
|
|
831
824
|
|
|
832
825
|
# MY ACTIVE TASKS — first and prominent
|
|
833
826
|
lines.append(f"## [!!!] MY ACTIVE TASKS (Assigned to {developer})")
|
|
834
|
-
lines.append("
|
|
827
|
+
lines.append("Review task progress and remaining work before recording this session.")
|
|
835
828
|
lines.append("")
|
|
836
829
|
|
|
837
830
|
tasks_dir = get_tasks_dir(repo_root)
|
|
@@ -55,7 +55,7 @@ Translation examples (glob → matches / non-matches):
|
|
|
55
55
|
matches only that exact file
|
|
56
56
|
packages/cli/src/commands/*.ts
|
|
57
57
|
matches packages/cli/src/commands/update.ts
|
|
58
|
-
not packages/cli/src/commands/
|
|
58
|
+
not packages/cli/src/commands/teamwork/spawn.ts
|
|
59
59
|
packages/cli/src/templates/**
|
|
60
60
|
matches packages/cli/src/templates/trellis/index.ts (any depth)
|
|
61
61
|
not packages/cli/src/templates (the directory itself)
|
|
@@ -26,11 +26,10 @@ import json
|
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
|
|
28
28
|
from .config import get_context_injection_limits
|
|
29
|
-
from .context_projection import parse_context_manifest, project_agent_context
|
|
30
29
|
from .git import branch_exists_locally
|
|
31
30
|
from .io import read_json
|
|
32
31
|
from .log import Colors, colored
|
|
33
|
-
from .paths import FILE_TASK_JSON, get_repo_root
|
|
32
|
+
from .paths import DIR_TASKS, DIR_WORKFLOW, FILE_TASK_JSON, get_repo_root
|
|
34
33
|
from .task_utils import resolve_task_dir
|
|
35
34
|
|
|
36
35
|
# Extensions that look like code rather than spec/research docs. Entries with
|
|
@@ -92,6 +91,12 @@ def cmd_add_context(args: argparse.Namespace) -> int:
|
|
|
92
91
|
jsonl_file = target_dir / jsonl_name
|
|
93
92
|
full_path = repo_root / path
|
|
94
93
|
|
|
94
|
+
from .task_continuity import task_mutation_guard
|
|
95
|
+
|
|
96
|
+
task_data = read_json(target_dir / FILE_TASK_JSON)
|
|
97
|
+
if not isinstance(task_data, dict):
|
|
98
|
+
print(colored(f"Error: task.json is unavailable at {target_dir}", Colors.RED))
|
|
99
|
+
return 1
|
|
95
100
|
entry_type = "file"
|
|
96
101
|
if full_path.is_dir():
|
|
97
102
|
entry_type = "directory"
|
|
@@ -115,8 +120,12 @@ def cmd_add_context(args: argparse.Namespace) -> int:
|
|
|
115
120
|
else:
|
|
116
121
|
entry = {"file": path, "reason": reason}
|
|
117
122
|
|
|
118
|
-
with
|
|
119
|
-
|
|
123
|
+
with task_mutation_guard(repo_root, target_dir, task_data) as allowed:
|
|
124
|
+
if not allowed:
|
|
125
|
+
print(colored("TASK_TRANSFER_ACTIVE: task changes are fenced until ownership is consumed or released", Colors.RED))
|
|
126
|
+
return 1
|
|
127
|
+
with jsonl_file.open("a", encoding="utf-8") as f:
|
|
128
|
+
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
|
|
120
129
|
|
|
121
130
|
print(colored(f"Added {entry_type}: {path}", Colors.GREEN))
|
|
122
131
|
return 0
|
|
@@ -126,19 +135,6 @@ def cmd_add_context(args: argparse.Namespace) -> int:
|
|
|
126
135
|
# Command: validate
|
|
127
136
|
# =============================================================================
|
|
128
137
|
|
|
129
|
-
def curated_entry_count(jsonl_file: Path) -> int | None:
|
|
130
|
-
"""Count curated entries in a jsonl context manifest.
|
|
131
|
-
|
|
132
|
-
Returns None when the file does not exist — `task.py create` seeds the
|
|
133
|
-
manifests only on sub-agent-capable platforms, so an absent file means no
|
|
134
|
-
sub-agent will ever read it and callers should not gate on it. A curated
|
|
135
|
-
entry is a JSON object row carrying a truthy ``file`` (or legacy ``path``)
|
|
136
|
-
value: the same rows the sub-agent injection hook materializes.
|
|
137
|
-
"""
|
|
138
|
-
entries, _, manifest_exists = parse_context_manifest(jsonl_file)
|
|
139
|
-
return len(entries) if manifest_exists else None
|
|
140
|
-
|
|
141
|
-
|
|
142
138
|
def cmd_validate(args: argparse.Namespace) -> int:
|
|
143
139
|
"""Validate JSONL context files."""
|
|
144
140
|
repo_root = get_repo_root()
|
|
@@ -199,6 +195,55 @@ def _is_exempt_from_code_file_warning(file_path: str, task_rel: str) -> bool:
|
|
|
199
195
|
return False
|
|
200
196
|
|
|
201
197
|
|
|
198
|
+
def _resolve_context_entry_path(
|
|
199
|
+
file_path: str, repo_root: Path, task_dir: Path | None
|
|
200
|
+
) -> Path | None:
|
|
201
|
+
"""Bind historical self-references to their archive copy without fallback."""
|
|
202
|
+
repo_path = repo_root / file_path
|
|
203
|
+
if task_dir is None:
|
|
204
|
+
return repo_path
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
task_parts = task_dir.resolve().relative_to(repo_root.resolve()).parts
|
|
208
|
+
except ValueError:
|
|
209
|
+
return repo_path
|
|
210
|
+
|
|
211
|
+
archive_prefix = (DIR_WORKFLOW, DIR_TASKS, "archive")
|
|
212
|
+
if len(task_parts) != 5 or task_parts[:3] != archive_prefix:
|
|
213
|
+
return repo_path
|
|
214
|
+
|
|
215
|
+
year_month = task_parts[3]
|
|
216
|
+
if (
|
|
217
|
+
len(year_month) != 7
|
|
218
|
+
or year_month[4] != "-"
|
|
219
|
+
or not year_month[:4].isdigit()
|
|
220
|
+
or not year_month[5:].isdigit()
|
|
221
|
+
):
|
|
222
|
+
return repo_path
|
|
223
|
+
|
|
224
|
+
historical_root = f"{DIR_WORKFLOW}/{DIR_TASKS}/{task_dir.name}"
|
|
225
|
+
posix_path = file_path.replace("\\", "/")
|
|
226
|
+
if posix_path == historical_root:
|
|
227
|
+
relative_parts: tuple[str, ...] = ()
|
|
228
|
+
elif posix_path.startswith(f"{historical_root}/"):
|
|
229
|
+
relative_path = posix_path[len(historical_root) + 1 :]
|
|
230
|
+
if relative_path.endswith("/"):
|
|
231
|
+
relative_path = relative_path[:-1]
|
|
232
|
+
relative_parts = tuple(relative_path.split("/")) if relative_path else ()
|
|
233
|
+
if any(part in ("", ".", "..") for part in relative_parts):
|
|
234
|
+
return None
|
|
235
|
+
else:
|
|
236
|
+
return repo_path
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
archive_root = task_dir.resolve()
|
|
240
|
+
resolved_path = task_dir.joinpath(*relative_parts).resolve()
|
|
241
|
+
resolved_path.relative_to(archive_root)
|
|
242
|
+
except (OSError, RuntimeError, ValueError):
|
|
243
|
+
return None
|
|
244
|
+
return resolved_path
|
|
245
|
+
|
|
246
|
+
|
|
202
247
|
def _validate_jsonl(jsonl_file: Path, repo_root: Path, task_dir: Path | None = None) -> int:
|
|
203
248
|
"""Validate a single JSONL file.
|
|
204
249
|
|
|
@@ -207,10 +252,11 @@ def _validate_jsonl(jsonl_file: Path, repo_root: Path, task_dir: Path | None = N
|
|
|
207
252
|
accepting them here would pass locally and fail later. Other rows without
|
|
208
253
|
a ``file`` field are skipped silently, matching what consumers do.
|
|
209
254
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
255
|
+
Beyond hard errors (missing file/dir, invalid JSON), this also prints
|
|
256
|
+
non-blocking hygiene warnings (never counted in ``errors``, never change
|
|
257
|
+
the exit code): entries that look like code files rather than
|
|
258
|
+
spec/research docs, and entries whose file size exceeds the configured
|
|
259
|
+
sub-agent context injection cap (``context_injection.max_file_bytes``).
|
|
214
260
|
"""
|
|
215
261
|
file_name = jsonl_file.name
|
|
216
262
|
errors = 0
|
|
@@ -226,57 +272,104 @@ def _validate_jsonl(jsonl_file: Path, repo_root: Path, task_dir: Path | None = N
|
|
|
226
272
|
except ValueError:
|
|
227
273
|
task_rel = ""
|
|
228
274
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
275
|
+
max_file_bytes = get_context_injection_limits(repo_root).get("max_file_bytes", 0)
|
|
276
|
+
|
|
277
|
+
line_num = 0
|
|
278
|
+
real_entries = 0
|
|
279
|
+
for line in jsonl_file.read_text(encoding="utf-8").splitlines():
|
|
280
|
+
line_num += 1
|
|
281
|
+
if not line.strip():
|
|
282
|
+
continue
|
|
283
|
+
|
|
284
|
+
try:
|
|
285
|
+
data = json.loads(line)
|
|
286
|
+
except json.JSONDecodeError:
|
|
287
|
+
print(f" {colored(f'{file_name}:{line_num}: Invalid JSON', Colors.RED)}")
|
|
288
|
+
errors += 1
|
|
289
|
+
continue
|
|
290
|
+
|
|
291
|
+
if not isinstance(data, dict):
|
|
292
|
+
print(
|
|
293
|
+
f" {colored(f'{file_name}:{line_num}: Expected a JSON object', Colors.RED)}"
|
|
294
|
+
)
|
|
295
|
+
errors += 1
|
|
296
|
+
continue
|
|
297
|
+
|
|
298
|
+
if "_example" in data:
|
|
299
|
+
error_message = (
|
|
300
|
+
f"{file_name}:{line_num}: Placeholder `_example` row left by an older "
|
|
301
|
+
"task.py create — delete this line, or replace it with "
|
|
302
|
+
'{"file": "<path>", "reason": "<why>"}'
|
|
303
|
+
)
|
|
304
|
+
print(f" {colored(error_message, Colors.RED)}")
|
|
305
|
+
errors += 1
|
|
306
|
+
continue
|
|
307
|
+
|
|
308
|
+
file_path = data.get("file")
|
|
309
|
+
entry_type = data.get("type", "file")
|
|
233
310
|
|
|
234
|
-
|
|
235
|
-
|
|
311
|
+
if not file_path:
|
|
312
|
+
# Comment / unknown row without a path — skip silently
|
|
236
313
|
continue
|
|
237
|
-
|
|
314
|
+
|
|
315
|
+
if not isinstance(file_path, str):
|
|
316
|
+
# A truthy non-string (e.g. {"file": 1}) reached path joining and
|
|
317
|
+
# raised TypeError, so validation crashed on the row it exists to
|
|
318
|
+
# report.
|
|
319
|
+
print(
|
|
320
|
+
f" {colored(f'{file_name}:{line_num}: `file` must be a string path', Colors.RED)}"
|
|
321
|
+
)
|
|
322
|
+
errors += 1
|
|
323
|
+
continue
|
|
324
|
+
|
|
325
|
+
real_entries += 1
|
|
326
|
+
full_path = _resolve_context_entry_path(file_path, repo_root, task_dir)
|
|
327
|
+
if entry_type == "directory":
|
|
328
|
+
if full_path is None or not full_path.is_dir():
|
|
329
|
+
print(f" {colored(f'{file_name}:{line_num}: Directory not found: {file_path}', Colors.RED)}")
|
|
330
|
+
errors += 1
|
|
331
|
+
continue
|
|
332
|
+
|
|
333
|
+
if full_path is None or not full_path.is_file():
|
|
334
|
+
print(f" {colored(f'{file_name}:{line_num}: File not found: {file_path}', Colors.RED)}")
|
|
335
|
+
errors += 1
|
|
336
|
+
continue
|
|
337
|
+
|
|
338
|
+
extension = Path(file_path).suffix.lower()
|
|
238
339
|
if extension in _CODE_FILE_EXTENSIONS and not _is_exempt_from_code_file_warning(
|
|
239
|
-
|
|
340
|
+
file_path, task_rel
|
|
240
341
|
):
|
|
241
342
|
warning_message = (
|
|
242
|
-
f"{file_name}:{
|
|
343
|
+
f"{file_name}:{line_num}: Warning: {file_path} looks like a code file — "
|
|
243
344
|
"implement/check.jsonl should reference spec/research docs; "
|
|
244
345
|
"agents read code themselves"
|
|
245
346
|
)
|
|
246
347
|
print(f" {colored(warning_message, Colors.YELLOW)}")
|
|
247
348
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
349
|
+
if max_file_bytes:
|
|
350
|
+
# Advisory hygiene warning, so it must never be what fails
|
|
351
|
+
# `validate`. `stat()` can still raise after the `is_file()` check
|
|
352
|
+
# above — a permission change, or the file removed in between.
|
|
353
|
+
try:
|
|
354
|
+
size: int | None = full_path.stat().st_size
|
|
355
|
+
except OSError:
|
|
356
|
+
size = None
|
|
357
|
+
if size is not None and size > max_file_bytes:
|
|
358
|
+
warning_message = (
|
|
359
|
+
f"{file_name}:{line_num}: Warning: {file_path} is {size} bytes, "
|
|
360
|
+
f"exceeds context_injection.max_file_bytes ({max_file_bytes}); "
|
|
361
|
+
"injection will truncate it"
|
|
362
|
+
)
|
|
363
|
+
print(f" {colored(warning_message, Colors.YELLOW)}")
|
|
263
364
|
|
|
264
|
-
if errors == 0 and
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
repo_root, task_dir, role, get_context_injection_limits(repo_root)
|
|
365
|
+
if errors == 0 and real_entries == 0:
|
|
366
|
+
print(
|
|
367
|
+
f" {colored(f'{file_name}: ✓ (no context entries; manifests are optional)', Colors.YELLOW)}"
|
|
268
368
|
)
|
|
269
|
-
|
|
270
|
-
line_label = str(issue.line) if issue.line is not None else "artifact"
|
|
271
|
-
message = (
|
|
272
|
-
f"{file_name}:{line_label}: role={issue.role} source={issue.category} "
|
|
273
|
-
f"path={issue.path}: cannot be injected in full — {issue.reason}"
|
|
274
|
-
)
|
|
275
|
-
print(f" {colored(message, Colors.RED)}")
|
|
276
|
-
errors += 1
|
|
369
|
+
return 0
|
|
277
370
|
|
|
278
371
|
if errors == 0:
|
|
279
|
-
print(f" {colored(f'{file_name}: ✓ ({
|
|
372
|
+
print(f" {colored(f'{file_name}: ✓ ({real_entries} entries)', Colors.GREEN)}")
|
|
280
373
|
else:
|
|
281
374
|
print(f" {colored(f'{file_name}: ✗ ({errors} errors)', Colors.RED)}")
|
|
282
375
|
|
|
@@ -320,7 +413,7 @@ def cmd_list_context(args: argparse.Namespace) -> int:
|
|
|
320
413
|
if not isinstance(data, dict):
|
|
321
414
|
continue
|
|
322
415
|
|
|
323
|
-
file_path = data.get("file")
|
|
416
|
+
file_path = data.get("file")
|
|
324
417
|
if not file_path:
|
|
325
418
|
# Placeholder / comment row — don't count as a real entry
|
|
326
419
|
continue
|