@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
|
@@ -8,20 +8,19 @@ Usage:
|
|
|
8
8
|
python3 task.py add-context <dir> <file> <path> [reason] # Add jsonl entry
|
|
9
9
|
python3 task.py validate <dir> # Validate jsonl files
|
|
10
10
|
python3 task.py list-context <dir> # List jsonl entries
|
|
11
|
-
python3 task.py start <dir> # Set active task
|
|
12
|
-
python3 task.py replan <dir> "<reason>" # Return an in-progress task to planning
|
|
11
|
+
python3 task.py start <dir> # Set active task; enter implementation only after phase authorization
|
|
13
12
|
python3 task.py current [--source] [--json] # Show active task
|
|
14
|
-
python3 task.py ownership <operation> ... # Manage formal handoff task ownership
|
|
15
13
|
python3 task.py finish # Clear active task
|
|
16
14
|
python3 task.py workflow <id>|--clear # Set/clear per-task workflow selection
|
|
15
|
+
python3 task.py phase <action> <task-dir> # Read/update task phase workflow state
|
|
16
|
+
python3 task.py cancel <task-dir> --reason <text> --evidence-ref <ref> # Cancel task lifecycle
|
|
17
17
|
python3 task.py set-branch <dir> <branch> # Set git branch
|
|
18
18
|
python3 task.py set-base-branch <dir> <branch> # Set PR target branch
|
|
19
19
|
python3 task.py set-scope <dir> <scope> # Set scope for PR title
|
|
20
20
|
python3 task.py set-meta <dir> <key> <value> # Set a task metadata key
|
|
21
21
|
python3 task.py rename <dir> <new-slug> [--dry-run] # Rename task + references
|
|
22
|
-
python3 task.py
|
|
22
|
+
python3 task.py complete <task-dir> # Complete after Delivery Review and On-Site Closeout Phase acceptance
|
|
23
23
|
python3 task.py list # List active tasks
|
|
24
|
-
python3 task.py list-archive [month] # List archived tasks
|
|
25
24
|
python3 task.py add-subtask <parent-dir> <child-dir> # Link child to parent
|
|
26
25
|
python3 task.py remove-subtask <parent-dir> <child-dir> # Unlink child from parent
|
|
27
26
|
"""
|
|
@@ -30,9 +29,7 @@ from __future__ import annotations
|
|
|
30
29
|
|
|
31
30
|
import argparse
|
|
32
31
|
import json
|
|
33
|
-
import os
|
|
34
32
|
import sys
|
|
35
|
-
from datetime import datetime, timezone
|
|
36
33
|
from pathlib import Path
|
|
37
34
|
|
|
38
35
|
from common.log import Colors, colored
|
|
@@ -67,7 +64,6 @@ from common.workflow_selection import WORKFLOW_ID_RE, workflow_md_for_task
|
|
|
67
64
|
from common.task_store import (
|
|
68
65
|
cmd_create,
|
|
69
66
|
cmd_rename,
|
|
70
|
-
cmd_archive,
|
|
71
67
|
cmd_set_branch,
|
|
72
68
|
cmd_set_base_branch,
|
|
73
69
|
cmd_set_scope,
|
|
@@ -79,26 +75,21 @@ from common.task_context import (
|
|
|
79
75
|
cmd_add_context,
|
|
80
76
|
cmd_validate,
|
|
81
77
|
cmd_list_context,
|
|
82
|
-
curated_entry_count,
|
|
83
78
|
)
|
|
84
|
-
from common.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
from common.task_workflow import (
|
|
80
|
+
TaskWorkflowError,
|
|
81
|
+
cmd_cancel_task,
|
|
82
|
+
cmd_complete_task,
|
|
83
|
+
cmd_delegate_start,
|
|
84
|
+
cmd_phase,
|
|
85
|
+
implementation_start_ready,
|
|
90
86
|
)
|
|
91
|
-
from common.
|
|
92
|
-
|
|
93
|
-
archive as archive_ownership,
|
|
87
|
+
from common.task_continuity import (
|
|
88
|
+
add_continuity_commands,
|
|
94
89
|
assert_task_mutation_allowed,
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
retire as retire_ownership,
|
|
99
|
-
retire_handoff as retire_handoff_ownership,
|
|
100
|
-
seal as seal_ownership,
|
|
101
|
-
status as ownership_status,
|
|
90
|
+
continuity_capture,
|
|
91
|
+
continuity_show,
|
|
92
|
+
transfer_task_ownership,
|
|
102
93
|
)
|
|
103
94
|
|
|
104
95
|
|
|
@@ -111,12 +102,11 @@ def _record_start_state(
|
|
|
111
102
|
repo_root: Path,
|
|
112
103
|
label: str = "",
|
|
113
104
|
) -> None:
|
|
114
|
-
"""
|
|
105
|
+
"""Enter implementation and record its branch after current authorization.
|
|
115
106
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
ever set by hand tends to reach archive with `branch: null`.
|
|
107
|
+
Planning and analysis tasks keep their lifecycle status while the active
|
|
108
|
+
session pointer supports workflow context. Only the start of an authorized
|
|
109
|
+
Task Implementation and Test Verification Phase changes `planning` to `in_progress`.
|
|
120
110
|
|
|
121
111
|
Tolerant on purpose — a broken task.json does not fail `start`, because the
|
|
122
112
|
session pointer is the point of the command. But the read overwrites the
|
|
@@ -135,14 +125,22 @@ def _record_start_state(
|
|
|
135
125
|
|
|
136
126
|
applied: list[str] = []
|
|
137
127
|
|
|
138
|
-
|
|
128
|
+
try:
|
|
129
|
+
implementation_ready = implementation_start_ready(data, task_json_path.parent)
|
|
130
|
+
except TaskWorkflowError as error:
|
|
131
|
+
print(
|
|
132
|
+
colored(f"Warning: Implementation start withheld; task.json not updated: {error.code}: {error}", Colors.YELLOW),
|
|
133
|
+
file=sys.stderr,
|
|
134
|
+
)
|
|
135
|
+
return
|
|
136
|
+
if data.get("status") == "planning" and implementation_ready:
|
|
139
137
|
data["status"] = "in_progress"
|
|
140
138
|
applied.append(f"✓ Status: planning → in_progress{label}")
|
|
141
139
|
|
|
142
140
|
# Only fill an empty field: an explicit `set-branch` must survive a later
|
|
143
141
|
# `start` (re-starting a task after a checkout is a normal thing to do).
|
|
144
142
|
base_branch_conflict: str | None = None
|
|
145
|
-
if not data.get("branch"):
|
|
143
|
+
if implementation_ready and data.get("status") == "in_progress" and not data.get("branch"):
|
|
146
144
|
branch = current_branch_name(repo_root)
|
|
147
145
|
if branch:
|
|
148
146
|
data["branch"] = branch
|
|
@@ -162,6 +160,12 @@ def _record_start_state(
|
|
|
162
160
|
if not applied:
|
|
163
161
|
return
|
|
164
162
|
|
|
163
|
+
try:
|
|
164
|
+
assert_task_mutation_allowed(repo_root, task_json_path.parent, data)
|
|
165
|
+
except TaskWorkflowError as error:
|
|
166
|
+
print(colored(f"{error.code}: task metadata update withheld: {error}", Colors.YELLOW), file=sys.stderr)
|
|
167
|
+
return
|
|
168
|
+
|
|
165
169
|
if not write_json(task_json_path, data):
|
|
166
170
|
print(
|
|
167
171
|
colored(
|
|
@@ -178,11 +182,10 @@ def _record_start_state(
|
|
|
178
182
|
|
|
179
183
|
if base_branch_conflict:
|
|
180
184
|
# Recorded anyway — the value is true, it just cannot describe a PR.
|
|
181
|
-
# Archive refuses this shape, so say so now rather than at the gate.
|
|
182
185
|
print(
|
|
183
186
|
colored(
|
|
184
187
|
f"Warning: '{base_branch_conflict}' is also this task's base_branch; "
|
|
185
|
-
"a PR cannot target its own branch
|
|
188
|
+
"a PR cannot target its own branch.",
|
|
186
189
|
Colors.YELLOW,
|
|
187
190
|
),
|
|
188
191
|
file=sys.stderr,
|
|
@@ -217,35 +220,6 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
217
220
|
print("Hint: Use task name (e.g., 'my-task') or full path (e.g., '.trellis/tasks/01-31-my-task')")
|
|
218
221
|
return 1
|
|
219
222
|
|
|
220
|
-
try:
|
|
221
|
-
assert_task_mutation_allowed(repo_root, full_path)
|
|
222
|
-
except (OwnershipError, OSError) as exc:
|
|
223
|
-
print(colored(f"Error: {exc}", Colors.RED), file=sys.stderr)
|
|
224
|
-
return 2
|
|
225
|
-
|
|
226
|
-
# Context-manifest gate (#573): a seeded-but-uncurated implement/check
|
|
227
|
-
# manifest means every sub-agent dispatched for this task runs with zero
|
|
228
|
-
# spec context, and nothing downstream surfaces that to the main session.
|
|
229
|
-
# An absent manifest is not gated — create seeds the files only on
|
|
230
|
-
# sub-agent-capable platforms, so absence means no sub-agent reads them.
|
|
231
|
-
if not getattr(args, "allow_empty_context", False):
|
|
232
|
-
empty_manifests = [
|
|
233
|
-
name
|
|
234
|
-
for name in ("implement.jsonl", "check.jsonl")
|
|
235
|
-
if curated_entry_count(full_path / name) == 0
|
|
236
|
-
]
|
|
237
|
-
if empty_manifests:
|
|
238
|
-
print(colored(
|
|
239
|
-
f"Error: {' and '.join(empty_manifests)} "
|
|
240
|
-
f"{'has' if len(empty_manifests) == 1 else 'have'} no curated entries",
|
|
241
|
-
Colors.RED,
|
|
242
|
-
))
|
|
243
|
-
print("Sub-agents (implement/check) would run with zero spec context.")
|
|
244
|
-
print(f" Curate: python3 .trellis/scripts/task.py add-context {task_input} implement <path> \"<why>\"")
|
|
245
|
-
print(f" Verify: python3 .trellis/scripts/task.py validate {task_input}")
|
|
246
|
-
print(" Intentionally empty? Re-run start with --allow-empty-context")
|
|
247
|
-
return 1
|
|
248
|
-
|
|
249
223
|
# Convert to relative path for storage. repo_root is resolved because
|
|
250
224
|
# full_path already is (resolve_task_dir only returns paths inside the
|
|
251
225
|
# resolved root), so an unresolved repo_root would mismatch under a
|
|
@@ -280,7 +254,7 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
280
254
|
Colors.YELLOW,
|
|
281
255
|
))
|
|
282
256
|
|
|
283
|
-
#
|
|
257
|
+
# Enter implementation only when the accepted phase contract authorizes it.
|
|
284
258
|
if task_json_path.is_file():
|
|
285
259
|
_record_start_state(task_json_path, repo_root, " (degraded)")
|
|
286
260
|
run_task_hooks("after_start", task_json_path, repo_root)
|
|
@@ -304,103 +278,23 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
304
278
|
return 1
|
|
305
279
|
|
|
306
280
|
|
|
307
|
-
def cmd_replan(args: argparse.Namespace) -> int:
|
|
308
|
-
"""Return an in-progress task to planning without losing its binding."""
|
|
309
|
-
repo_root = get_repo_root()
|
|
310
|
-
full_path = resolve_task_dir(args.dir, repo_root)
|
|
311
|
-
if full_path is None or not full_path.is_dir():
|
|
312
|
-
print(colored(f"Error: Task not found: {args.dir}", Colors.RED), file=sys.stderr)
|
|
313
|
-
return 1
|
|
314
|
-
|
|
315
|
-
try:
|
|
316
|
-
assert_task_mutation_allowed(repo_root, full_path)
|
|
317
|
-
except (OwnershipError, OSError) as exc:
|
|
318
|
-
print(colored(f"Error: {exc}", Colors.RED), file=sys.stderr)
|
|
319
|
-
return 2
|
|
320
|
-
|
|
321
|
-
reason = " ".join(args.reason).strip()
|
|
322
|
-
if not reason:
|
|
323
|
-
print(colored("Error: replan reason must not be empty", Colors.RED), file=sys.stderr)
|
|
324
|
-
return 1
|
|
325
|
-
|
|
326
|
-
task_json_path = full_path / FILE_TASK_JSON
|
|
327
|
-
data, read_reason = read_json_checked(task_json_path)
|
|
328
|
-
if data is None:
|
|
329
|
-
problem, hint = describe_json_read_failure(task_json_path, read_reason)
|
|
330
|
-
print(colored(f"Error: {problem}", Colors.RED), file=sys.stderr)
|
|
331
|
-
print(hint, file=sys.stderr)
|
|
332
|
-
return 1
|
|
333
|
-
if data.get("status") != "in_progress":
|
|
334
|
-
print(
|
|
335
|
-
colored(
|
|
336
|
-
f"Error: replan requires status=in_progress (found {data.get('status')!r})",
|
|
337
|
-
Colors.RED,
|
|
338
|
-
),
|
|
339
|
-
file=sys.stderr,
|
|
340
|
-
)
|
|
341
|
-
return 1
|
|
342
|
-
|
|
343
|
-
event = {
|
|
344
|
-
"timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
345
|
-
"task": full_path.relative_to(repo_root).as_posix(),
|
|
346
|
-
"from_status": "in_progress",
|
|
347
|
-
"reason": reason,
|
|
348
|
-
"branch": data.get("branch"),
|
|
349
|
-
}
|
|
350
|
-
context_key = resolve_context_key()
|
|
351
|
-
if context_key:
|
|
352
|
-
event["session"] = context_key
|
|
353
|
-
|
|
354
|
-
replans_path = full_path / "replans.jsonl"
|
|
355
|
-
try:
|
|
356
|
-
with replans_path.open("a", encoding="utf-8") as handle:
|
|
357
|
-
handle.write(json.dumps(event, ensure_ascii=False) + "\n")
|
|
358
|
-
handle.flush()
|
|
359
|
-
os.fsync(handle.fileno())
|
|
360
|
-
except OSError as exc:
|
|
361
|
-
print(colored(f"Error: could not record replan: {exc}", Colors.RED), file=sys.stderr)
|
|
362
|
-
return 1
|
|
363
|
-
|
|
364
|
-
data["status"] = "planning"
|
|
365
|
-
if not write_json(task_json_path, data):
|
|
366
|
-
print(colored("Error: replan event recorded but task status was not changed", Colors.RED), file=sys.stderr)
|
|
367
|
-
return 1
|
|
368
|
-
|
|
369
|
-
print(colored(f"✓ Task returned to planning: {full_path.relative_to(repo_root)}", Colors.GREEN))
|
|
370
|
-
print("Reason:", reason)
|
|
371
|
-
run_task_hooks("after_replan", task_json_path, repo_root)
|
|
372
|
-
return 0
|
|
373
|
-
|
|
374
|
-
|
|
375
281
|
def cmd_finish(args: argparse.Namespace) -> int:
|
|
376
282
|
"""Clear active task."""
|
|
377
283
|
repo_root = get_repo_root()
|
|
378
|
-
active =
|
|
284
|
+
active = clear_active_task(repo_root)
|
|
379
285
|
current = active.task_path
|
|
380
286
|
|
|
381
287
|
if not current:
|
|
382
288
|
print(colored("No current task set", Colors.YELLOW))
|
|
383
289
|
return 0
|
|
384
290
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
print(
|
|
388
|
-
return
|
|
389
|
-
if active.source_type == "unbound_ambiguous":
|
|
390
|
-
print(colored("Multiple tasks exist but no direct session is bound; choose one before finishing", Colors.YELLOW))
|
|
391
|
-
for candidate in active.candidate_paths:
|
|
392
|
-
print(f"Candidate: {candidate}")
|
|
393
|
-
return 0
|
|
394
|
-
|
|
395
|
-
try:
|
|
396
|
-
assert_task_mutation_allowed(repo_root, repo_root / current)
|
|
397
|
-
except (OwnershipError, OSError) as exc:
|
|
398
|
-
print(colored(f"Error: {exc}", Colors.RED), file=sys.stderr)
|
|
399
|
-
return 2
|
|
291
|
+
remaining = resolve_active_task(repo_root)
|
|
292
|
+
if remaining.context_key == active.context_key and remaining.task_path == current:
|
|
293
|
+
print(colored("Error: task ownership is fenced; this session cannot clear the active task", Colors.RED))
|
|
294
|
+
return 1
|
|
400
295
|
|
|
401
296
|
# Resolve task.json path before clearing
|
|
402
297
|
task_json_path = repo_root / current / FILE_TASK_JSON
|
|
403
|
-
clear_active_task(repo_root)
|
|
404
298
|
|
|
405
299
|
print(colored(f"✓ Cleared current task (was: {current})", Colors.GREEN))
|
|
406
300
|
print(f"Source: {active.source}")
|
|
@@ -441,13 +335,21 @@ def cmd_current(args: argparse.Namespace) -> int:
|
|
|
441
335
|
"branch": data.get("branch"),
|
|
442
336
|
"base_branch": data.get("base_branch"),
|
|
443
337
|
}
|
|
338
|
+
meta = data.get("meta")
|
|
339
|
+
phase_workflow = meta.get("task_workflow") if isinstance(meta, dict) else None
|
|
340
|
+
if isinstance(phase_workflow, dict):
|
|
341
|
+
current_phase_id = phase_workflow.get("current_phase_id")
|
|
342
|
+
phase_map = phase_workflow.get("phases")
|
|
343
|
+
phase_record = phase_map.get(current_phase_id) if isinstance(phase_map, dict) and isinstance(current_phase_id, str) else None
|
|
344
|
+
task_obj["current_phase_id"] = current_phase_id
|
|
345
|
+
task_obj["task_route_revision"] = phase_workflow.get("task_route_revision")
|
|
346
|
+
task_obj["input_revision"] = phase_workflow.get("input_revision")
|
|
347
|
+
task_obj["phase_status"] = phase_record.get("status") if isinstance(phase_record, dict) else None
|
|
444
348
|
payload = {
|
|
445
349
|
"current_task": task_obj,
|
|
446
350
|
"source": active.source,
|
|
447
351
|
"stale": active.stale,
|
|
448
352
|
}
|
|
449
|
-
if active.candidate_paths:
|
|
450
|
-
payload["candidates"] = list(active.candidate_paths)
|
|
451
353
|
# Only present when the read failed, so the healthy shape is unchanged.
|
|
452
354
|
if read_error:
|
|
453
355
|
payload["error"] = read_error
|
|
@@ -455,12 +357,6 @@ def cmd_current(args: argparse.Namespace) -> int:
|
|
|
455
357
|
return 0 if active.task_path else 1
|
|
456
358
|
|
|
457
359
|
if args.source:
|
|
458
|
-
if active.source_type == "unbound_ambiguous":
|
|
459
|
-
print("Current task: (ambiguous)")
|
|
460
|
-
print("Source: unbound_ambiguous")
|
|
461
|
-
for candidate in active.candidate_paths:
|
|
462
|
-
print(f"Candidate: {candidate}")
|
|
463
|
-
return 1
|
|
464
360
|
print(f"Current task: {active.task_path or '(none)'}")
|
|
465
361
|
print(f"Source: {active.source}")
|
|
466
362
|
if active.stale:
|
|
@@ -471,92 +367,9 @@ def cmd_current(args: argparse.Namespace) -> int:
|
|
|
471
367
|
print(active.task_path)
|
|
472
368
|
return 0
|
|
473
369
|
|
|
474
|
-
if active.source_type == "unbound_ambiguous":
|
|
475
|
-
print("Multiple active tasks require explicit binding:")
|
|
476
|
-
for candidate in active.candidate_paths:
|
|
477
|
-
print(candidate)
|
|
478
|
-
|
|
479
370
|
return 1
|
|
480
371
|
|
|
481
372
|
|
|
482
|
-
def cmd_continuity(args: argparse.Namespace) -> int:
|
|
483
|
-
"""Read or explicitly mutate the current task's Continuation Record."""
|
|
484
|
-
repo_root = get_repo_root()
|
|
485
|
-
try:
|
|
486
|
-
if args.continuity_command == "status":
|
|
487
|
-
result = continuity_status(repo_root)
|
|
488
|
-
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
|
489
|
-
return 0
|
|
490
|
-
if not getattr(args, "explicit_user_request", False):
|
|
491
|
-
print(colored("Error: continuity writes require --explicit-user-request", Colors.RED), file=sys.stderr)
|
|
492
|
-
return 2
|
|
493
|
-
if args.continuity_command == "seal":
|
|
494
|
-
request = Path(args.request)
|
|
495
|
-
if request.is_absolute() or ".." in request.parts:
|
|
496
|
-
print(colored("Error: continuity request must be project-relative", Colors.RED), file=sys.stderr)
|
|
497
|
-
return 2
|
|
498
|
-
result = seal_continuity(repo_root, repo_root / request, args.expected)
|
|
499
|
-
else:
|
|
500
|
-
result = clear_continuity(repo_root, args.expected)
|
|
501
|
-
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
|
502
|
-
return 0
|
|
503
|
-
except (ContinuationError, OSError) as exc:
|
|
504
|
-
print(json.dumps({"status": STATUS_WITHHELD, "reason": str(exc)}, ensure_ascii=False, sort_keys=True))
|
|
505
|
-
return 2
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
def cmd_ownership(args: argparse.Namespace) -> int:
|
|
509
|
-
"""Manage the task-bound formal handoff ownership record."""
|
|
510
|
-
repo_root = get_repo_root()
|
|
511
|
-
if args.ownership_command == "status":
|
|
512
|
-
try:
|
|
513
|
-
result = ownership_status(repo_root, args.task_id, args.handoff_id, args.core_digest)
|
|
514
|
-
except (OwnershipError, OSError) as exc:
|
|
515
|
-
print(json.dumps({"status": "withheld", "reason": str(exc)}, ensure_ascii=False, sort_keys=True))
|
|
516
|
-
return 2
|
|
517
|
-
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
|
518
|
-
return 0
|
|
519
|
-
if not getattr(args, "explicit_user_request", False):
|
|
520
|
-
print(colored("Error: ownership writes require --explicit-user-request", Colors.RED), file=sys.stderr)
|
|
521
|
-
return 2
|
|
522
|
-
try:
|
|
523
|
-
command = args.ownership_command
|
|
524
|
-
if command == "quiesce":
|
|
525
|
-
result = quiesce_ownership(
|
|
526
|
-
repo_root, args.task, args.handoff_id, args.core_digest, args.source_session_id
|
|
527
|
-
)
|
|
528
|
-
elif command == "seal":
|
|
529
|
-
result = seal_ownership(
|
|
530
|
-
repo_root, args.task_id, args.handoff_id, args.core_digest, args.expected_generation
|
|
531
|
-
)
|
|
532
|
-
elif command == "retire":
|
|
533
|
-
result = retire_ownership(
|
|
534
|
-
repo_root, args.task_id, args.handoff_id, args.core_digest,
|
|
535
|
-
args.expected_generation, args.archive_observation,
|
|
536
|
-
)
|
|
537
|
-
elif command == "retire-handoff":
|
|
538
|
-
result = retire_handoff_ownership(
|
|
539
|
-
repo_root, args.task_id, args.handoff_id, args.core_digest,
|
|
540
|
-
)
|
|
541
|
-
elif command == "claim":
|
|
542
|
-
result = claim_ownership(
|
|
543
|
-
repo_root, args.task_id, args.task, args.handoff_id, args.core_digest, args.expected_generation
|
|
544
|
-
)
|
|
545
|
-
elif command == "consume":
|
|
546
|
-
result = consume_ownership(
|
|
547
|
-
repo_root, args.task_id, args.handoff_id, args.core_digest, args.expected_generation
|
|
548
|
-
)
|
|
549
|
-
else:
|
|
550
|
-
result = archive_ownership(
|
|
551
|
-
repo_root, args.task_id, args.handoff_id, args.core_digest, args.expected_generation
|
|
552
|
-
)
|
|
553
|
-
print(json.dumps(result, ensure_ascii=False, sort_keys=True))
|
|
554
|
-
return 0
|
|
555
|
-
except (OwnershipError, OSError) as exc:
|
|
556
|
-
print(json.dumps({"status": "withheld", "reason": str(exc)}, ensure_ascii=False, sort_keys=True))
|
|
557
|
-
return 2
|
|
558
|
-
|
|
559
|
-
|
|
560
373
|
# =============================================================================
|
|
561
374
|
# Command: workflow
|
|
562
375
|
# =============================================================================
|
|
@@ -590,6 +403,12 @@ def cmd_workflow(args: argparse.Namespace) -> int:
|
|
|
590
403
|
print(colored(f"Error: failed to read {task_json_path}", Colors.RED))
|
|
591
404
|
return 1
|
|
592
405
|
|
|
406
|
+
try:
|
|
407
|
+
assert_task_mutation_allowed(repo_root, task_dir, data)
|
|
408
|
+
except TaskWorkflowError as error:
|
|
409
|
+
print(f"{error.code}: {error}", file=sys.stderr)
|
|
410
|
+
return 1
|
|
411
|
+
|
|
593
412
|
if args.clear:
|
|
594
413
|
if data.pop("workflow", None) is None:
|
|
595
414
|
print(colored("No workflow selection set on this task", Colors.YELLOW))
|
|
@@ -758,40 +577,6 @@ def cmd_list(args: argparse.Namespace) -> int:
|
|
|
758
577
|
return 0
|
|
759
578
|
|
|
760
579
|
|
|
761
|
-
# =============================================================================
|
|
762
|
-
# Command: list-archive
|
|
763
|
-
# =============================================================================
|
|
764
|
-
|
|
765
|
-
def cmd_list_archive(args: argparse.Namespace) -> int:
|
|
766
|
-
"""List archived tasks."""
|
|
767
|
-
repo_root = get_repo_root()
|
|
768
|
-
tasks_dir = get_tasks_dir(repo_root)
|
|
769
|
-
archive_dir = tasks_dir / "archive"
|
|
770
|
-
month = args.month
|
|
771
|
-
|
|
772
|
-
print(colored("Archived tasks:", Colors.BLUE))
|
|
773
|
-
print()
|
|
774
|
-
|
|
775
|
-
if month:
|
|
776
|
-
month_dir = archive_dir / month
|
|
777
|
-
if month_dir.is_dir():
|
|
778
|
-
print(f"[{month}]")
|
|
779
|
-
for d in sorted(month_dir.iterdir()):
|
|
780
|
-
if d.is_dir():
|
|
781
|
-
print(f" - {d.name}/")
|
|
782
|
-
else:
|
|
783
|
-
print(f" No archives for {month}")
|
|
784
|
-
else:
|
|
785
|
-
if archive_dir.is_dir():
|
|
786
|
-
for month_dir in sorted(archive_dir.iterdir()):
|
|
787
|
-
if month_dir.is_dir():
|
|
788
|
-
month_name = month_dir.name
|
|
789
|
-
count = sum(1 for d in month_dir.iterdir() if d.is_dir())
|
|
790
|
-
print(f"[{month_name}] - {count} task(s)")
|
|
791
|
-
|
|
792
|
-
return 0
|
|
793
|
-
|
|
794
|
-
|
|
795
580
|
# =============================================================================
|
|
796
581
|
# Help
|
|
797
582
|
# =============================================================================
|
|
@@ -809,7 +594,7 @@ Usage:
|
|
|
809
594
|
python3 task.py add-context <dir> <jsonl> <path> [reason] Add entry to jsonl
|
|
810
595
|
python3 task.py validate <dir> Validate jsonl files
|
|
811
596
|
python3 task.py list-context <dir> List jsonl entries
|
|
812
|
-
python3 task.py start <dir> Set active task;
|
|
597
|
+
python3 task.py start <dir> Set active task; enter implementation only after phase authorization
|
|
813
598
|
python3 task.py current [--source] Show active task
|
|
814
599
|
python3 task.py finish Clear active task
|
|
815
600
|
python3 task.py workflow <id> Select workflow variant for active task
|
|
@@ -819,11 +604,10 @@ Usage:
|
|
|
819
604
|
python3 task.py set-scope <dir> <scope> Set scope for PR title
|
|
820
605
|
python3 task.py set-meta <dir> <key> <value> Set/overwrite a task metadata key
|
|
821
606
|
python3 task.py rename <dir> <new-slug> Rename task, identity fields and references
|
|
822
|
-
python3 task.py
|
|
607
|
+
python3 task.py complete <task-dir> Complete after Delivery Review and On-Site Closeout Phase acceptance
|
|
823
608
|
python3 task.py add-subtask <parent> <child> Link child task to parent
|
|
824
609
|
python3 task.py remove-subtask <parent> <child> Unlink child from parent
|
|
825
610
|
python3 task.py list [--mine] [--status <status>] [--json] List tasks
|
|
826
|
-
python3 task.py list-archive [YYYY-MM] List archived tasks
|
|
827
611
|
|
|
828
612
|
Monorepo options:
|
|
829
613
|
--package <pkg> Package name (validated against config.yaml packages)
|
|
@@ -831,16 +615,6 @@ Monorepo options:
|
|
|
831
615
|
Rename options:
|
|
832
616
|
--dry-run Print the change set without writing anything
|
|
833
617
|
|
|
834
|
-
Archive options:
|
|
835
|
-
--no-commit Skip the auto git commit after archiving
|
|
836
|
-
--skip-branch-validation Archive despite missing or self-referential branch metadata.
|
|
837
|
-
Archive normally refuses a task with no `branch` when it has a
|
|
838
|
-
`base_branch` and the repo has a remote, or with
|
|
839
|
-
`branch == base_branch`; repair those with `set-branch` /
|
|
840
|
-
`set-base-branch` instead. Use this flag only for tasks that
|
|
841
|
-
were never PR-backed. A recorded branch that was merged and
|
|
842
|
-
deleted is only a warning and needs no flag.
|
|
843
|
-
|
|
844
618
|
List options:
|
|
845
619
|
--mine, -m Show only tasks assigned to current developer
|
|
846
620
|
--status, -s <s> Filter by status (planning, in_progress, review, completed)
|
|
@@ -858,8 +632,7 @@ Examples:
|
|
|
858
632
|
python3 task.py finish
|
|
859
633
|
python3 task.py rename add-login add-sso --dry-run # Preview the change set
|
|
860
634
|
python3 task.py rename add-login add-sso
|
|
861
|
-
python3 task.py
|
|
862
|
-
python3 task.py archive add-login --skip-branch-validation # Task never had a branch of its own
|
|
635
|
+
python3 task.py complete add-login
|
|
863
636
|
python3 task.py add-subtask parent-task child-task # Link existing tasks
|
|
864
637
|
python3 task.py remove-subtask parent-task child-task
|
|
865
638
|
python3 task.py list # List all active tasks
|
|
@@ -919,7 +692,7 @@ def main() -> int:
|
|
|
919
692
|
p_create.add_argument(
|
|
920
693
|
"--description",
|
|
921
694
|
"-d",
|
|
922
|
-
help="Task description (required, non-empty — an empty one
|
|
695
|
+
help="Task description (required, non-empty — an empty one cannot be completed)",
|
|
923
696
|
)
|
|
924
697
|
p_create.add_argument("--parent", help="Parent task directory (establishes subtask link)")
|
|
925
698
|
p_create.add_argument("--package", help="Package name for monorepo projects")
|
|
@@ -965,17 +738,6 @@ def main() -> int:
|
|
|
965
738
|
# start
|
|
966
739
|
p_start = subparsers.add_parser("start", help="Set active task")
|
|
967
740
|
p_start.add_argument("dir", help="Task directory")
|
|
968
|
-
p_start.add_argument(
|
|
969
|
-
"--allow-empty-context",
|
|
970
|
-
action="store_true",
|
|
971
|
-
help="Start even when implement.jsonl / check.jsonl have no curated entries",
|
|
972
|
-
)
|
|
973
|
-
|
|
974
|
-
# replan
|
|
975
|
-
p_replan = subparsers.add_parser("replan", help="Return an in-progress task to planning")
|
|
976
|
-
p_replan.add_argument("dir", help="Task directory")
|
|
977
|
-
p_replan.add_argument("reason", nargs="+", help="Material reason for returning to planning")
|
|
978
|
-
|
|
979
741
|
# current
|
|
980
742
|
p_current = subparsers.add_parser("current", help="Show active task")
|
|
981
743
|
p_current.add_argument("--source", action="store_true",
|
|
@@ -983,61 +745,6 @@ def main() -> int:
|
|
|
983
745
|
p_current.add_argument("--json", action="store_true",
|
|
984
746
|
help="Output machine-readable JSON")
|
|
985
747
|
|
|
986
|
-
# continuity
|
|
987
|
-
p_continuity = subparsers.add_parser("continuity", help="Read or explicitly update the current task Continuation Record")
|
|
988
|
-
continuity_sub = p_continuity.add_subparsers(dest="continuity_command", required=True)
|
|
989
|
-
continuity_status_parser = continuity_sub.add_parser("status", help="Show read-only Continuation Record status")
|
|
990
|
-
continuity_status_parser.add_argument("--json", action="store_true", help="Output machine-readable JSON")
|
|
991
|
-
continuity_seal = continuity_sub.add_parser("seal", help="Write a Continuation Record from an explicit request")
|
|
992
|
-
continuity_seal.add_argument("--request", required=True, type=Path, help="Project-relative bounded request JSON")
|
|
993
|
-
continuity_seal.add_argument("--expected", required=True, help="absent or the current record digest")
|
|
994
|
-
continuity_seal.add_argument("--explicit-user-request", action="store_true", help="Required write confirmation")
|
|
995
|
-
continuity_clear = continuity_sub.add_parser("clear", help="Clear the current Continuation Record")
|
|
996
|
-
continuity_clear.add_argument("--expected", required=True, help="The current record digest or absent")
|
|
997
|
-
continuity_clear.add_argument("--explicit-user-request", action="store_true", help="Required write confirmation")
|
|
998
|
-
|
|
999
|
-
# ownership
|
|
1000
|
-
p_ownership = subparsers.add_parser("ownership", help="Manage formal handoff task ownership")
|
|
1001
|
-
ownership_sub = p_ownership.add_subparsers(dest="ownership_command", required=True)
|
|
1002
|
-
|
|
1003
|
-
def add_ownership_common(parser, *, expected=False):
|
|
1004
|
-
parser.add_argument("--task-id", required=True, help="Task id bound to the handoff")
|
|
1005
|
-
parser.add_argument("--handoff-id", required=True, help="Immutable handoff id")
|
|
1006
|
-
parser.add_argument("--core-digest", required=True, help="Immutable handoff core digest")
|
|
1007
|
-
if expected:
|
|
1008
|
-
parser.add_argument("--expected-generation", required=True, type=int)
|
|
1009
|
-
parser.add_argument("--explicit-user-request", action="store_true", help="Required write confirmation")
|
|
1010
|
-
|
|
1011
|
-
ownership_quiesce = ownership_sub.add_parser("quiesce", help="Begin source handoff quiescence")
|
|
1012
|
-
ownership_quiesce.add_argument("--task", required=True, help="Current task path")
|
|
1013
|
-
ownership_quiesce.add_argument("--source-session-id", required=True)
|
|
1014
|
-
add_ownership_common(ownership_quiesce)
|
|
1015
|
-
|
|
1016
|
-
ownership_seal = ownership_sub.add_parser("seal", help="Seal the source ownership boundary")
|
|
1017
|
-
add_ownership_common(ownership_seal, expected=True)
|
|
1018
|
-
|
|
1019
|
-
ownership_retire = ownership_sub.add_parser("retire", help="Retire source and expose handoff")
|
|
1020
|
-
ownership_retire.add_argument("--archive-observation", required=True, choices=("not_required", "observed"))
|
|
1021
|
-
add_ownership_common(ownership_retire, expected=True)
|
|
1022
|
-
|
|
1023
|
-
ownership_retire_handoff = ownership_sub.add_parser("retire-handoff", help="Release one sealed handoff by exact id")
|
|
1024
|
-
add_ownership_common(ownership_retire_handoff)
|
|
1025
|
-
|
|
1026
|
-
ownership_claim = ownership_sub.add_parser("claim", help="Claim a ready handoff as this session")
|
|
1027
|
-
ownership_claim.add_argument("--task", required=True, help="Task path to bind to this session")
|
|
1028
|
-
add_ownership_common(ownership_claim, expected=True)
|
|
1029
|
-
|
|
1030
|
-
ownership_consume = ownership_sub.add_parser("consume", help="Record target consumption")
|
|
1031
|
-
add_ownership_common(ownership_consume, expected=True)
|
|
1032
|
-
|
|
1033
|
-
ownership_archive = ownership_sub.add_parser("archive", help="Record post-consume retention archive")
|
|
1034
|
-
add_ownership_common(ownership_archive, expected=True)
|
|
1035
|
-
|
|
1036
|
-
ownership_status_parser = ownership_sub.add_parser("status", help="Show ownership status")
|
|
1037
|
-
add_ownership_common(ownership_status_parser)
|
|
1038
|
-
ownership_status_parser.add_argument("--json", action="store_true", help="Output machine-readable JSON")
|
|
1039
|
-
ownership_status_parser.set_defaults(explicit_user_request=True)
|
|
1040
|
-
|
|
1041
748
|
# finish
|
|
1042
749
|
subparsers.add_parser("finish", help="Clear active task")
|
|
1043
750
|
|
|
@@ -1047,6 +754,45 @@ def main() -> int:
|
|
|
1047
754
|
p_workflow.add_argument("--clear", action="store_true",
|
|
1048
755
|
help="Remove the workflow selection (use default resolution)")
|
|
1049
756
|
|
|
757
|
+
# Business-phase task workflow state.
|
|
758
|
+
p_phase = subparsers.add_parser("phase", help="Read or update task phase state")
|
|
759
|
+
p_phase.add_argument(
|
|
760
|
+
"phase_action",
|
|
761
|
+
choices=("init", "show", "artifact", "accept", "skip", "wait", "block", "resume", "return", "route", "authorize", "admission"),
|
|
762
|
+
)
|
|
763
|
+
p_phase.add_argument("task_dir", help="Task directory or task name")
|
|
764
|
+
p_phase.add_argument("--expected-route-revision", help="Current task_route_revision required for mutation")
|
|
765
|
+
p_phase.add_argument("--task-kind", help="analysis | implementation | combined (init / route)")
|
|
766
|
+
p_phase.add_argument("--complexity", help="simple | standard | complex (init / route)")
|
|
767
|
+
p_phase.add_argument("--project-context", help="new | existing (init / route)")
|
|
768
|
+
p_phase.add_argument("--phase-ids", help="Comma-separated phase route (init / route)")
|
|
769
|
+
p_phase.add_argument("--route-reason", help="Reason when initialization omits one or more phases")
|
|
770
|
+
p_phase.add_argument("--route-evidence-ref", action="append", help="Evidence supporting an abbreviated initial route")
|
|
771
|
+
p_phase.add_argument("--target-phase", help="Earlier phase to revisit, or first affected phase for route change")
|
|
772
|
+
p_phase.add_argument("--artifact-ref", action="append", help="Task-relative file in the current phase output")
|
|
773
|
+
p_phase.add_argument("--artifact-revision", help="Current artifact_revision required for acceptance")
|
|
774
|
+
p_phase.add_argument("--result-ref", help="Task result artifact reference")
|
|
775
|
+
p_phase.add_argument("--outcome-kind", help="Phase result kind; pending phase outcomes may accompany wait/block")
|
|
776
|
+
p_phase.add_argument("--evidence-ref", action="append", help="Evidence reference (repeatable)")
|
|
777
|
+
p_phase.add_argument("--reason", help="Reason for skip, block, return, route change, or cancellation")
|
|
778
|
+
p_phase.add_argument("--contract-ref", help="Accepted implementation contract reference")
|
|
779
|
+
p_phase.add_argument("--approval-ref", help="Explicit implementation approval reference")
|
|
780
|
+
p_phase.add_argument("--closeout-disposition", help="delivery_ready | no_go | cancelled (Delivery Review and On-Site Closeout Phase)")
|
|
781
|
+
p_phase.add_argument("--child-disposition", action="append", help="Child task disposition as <task-id>=integrated|continue|independent|cancelled (repeatable at closeout)")
|
|
782
|
+
p_phase.add_argument("--dependency", action="append", help="Route dependency identifier (admission)")
|
|
783
|
+
p_phase.add_argument("--admission-state", choices=("ready", "missing", "stale", "incompatible", "blocked"), help="Dependency admission result")
|
|
784
|
+
|
|
785
|
+
p_delegate = subparsers.add_parser("delegate-start", help="Start an authorized child task in a Paseo worktree")
|
|
786
|
+
p_delegate.add_argument("child_task", help="Linked child task directory or name")
|
|
787
|
+
|
|
788
|
+
add_continuity_commands(subparsers)
|
|
789
|
+
|
|
790
|
+
# cancel task lifecycle independently of phase transitions
|
|
791
|
+
p_cancel = subparsers.add_parser("cancel", help="Cancel task lifecycle")
|
|
792
|
+
p_cancel.add_argument("task_dir", help="Task directory or task name")
|
|
793
|
+
p_cancel.add_argument("--reason", required=True, help="Why the task is cancelled")
|
|
794
|
+
p_cancel.add_argument("--evidence-ref", action="append", required=True, help="Task-relative cancellation evidence")
|
|
795
|
+
|
|
1050
796
|
# set-branch
|
|
1051
797
|
p_branch = subparsers.add_parser("set-branch", help="Set git branch")
|
|
1052
798
|
p_branch.add_argument("dir", help="Task directory")
|
|
@@ -1078,19 +824,6 @@ def main() -> int:
|
|
|
1078
824
|
help="Print the change set without writing anything",
|
|
1079
825
|
)
|
|
1080
826
|
|
|
1081
|
-
# archive
|
|
1082
|
-
p_archive = subparsers.add_parser("archive", help="Archive task")
|
|
1083
|
-
p_archive.add_argument("name", help="Task directory or name")
|
|
1084
|
-
p_archive.add_argument("--no-commit", action="store_true", help="Skip auto git commit after archive")
|
|
1085
|
-
p_archive.add_argument(
|
|
1086
|
-
"--skip-branch-validation",
|
|
1087
|
-
action="store_true",
|
|
1088
|
-
help=(
|
|
1089
|
-
"Archive even when branch metadata is missing or self-referential "
|
|
1090
|
-
"(for tasks that were never PR-backed)"
|
|
1091
|
-
),
|
|
1092
|
-
)
|
|
1093
|
-
|
|
1094
827
|
# list
|
|
1095
828
|
p_list = subparsers.add_parser("list", help="List tasks")
|
|
1096
829
|
p_list.add_argument("--mine", "-m", action="store_true", help="My tasks only")
|
|
@@ -1107,9 +840,9 @@ def main() -> int:
|
|
|
1107
840
|
p_rmsub.add_argument("parent_dir", help="Parent task directory")
|
|
1108
841
|
p_rmsub.add_argument("child_dir", help="Child task directory")
|
|
1109
842
|
|
|
1110
|
-
#
|
|
1111
|
-
|
|
1112
|
-
|
|
843
|
+
# complete task lifecycle
|
|
844
|
+
p_complete = subparsers.add_parser("complete", help="Complete after Delivery Review and On-Site Closeout Phase acceptance")
|
|
845
|
+
p_complete.add_argument("task_dir", help="Task directory or task name")
|
|
1113
846
|
|
|
1114
847
|
args = parser.parse_args()
|
|
1115
848
|
|
|
@@ -1117,28 +850,32 @@ def main() -> int:
|
|
|
1117
850
|
show_usage()
|
|
1118
851
|
return 1
|
|
1119
852
|
|
|
853
|
+
if args.command == "continuity":
|
|
854
|
+
return continuity_show(args) if args.continuity_action == "show" else continuity_capture(args)
|
|
855
|
+
if args.command == "transfer":
|
|
856
|
+
return transfer_task_ownership(args)
|
|
857
|
+
|
|
1120
858
|
commands = {
|
|
1121
859
|
"create": cmd_create,
|
|
1122
860
|
"add-context": cmd_add_context,
|
|
1123
861
|
"validate": cmd_validate,
|
|
1124
862
|
"list-context": cmd_list_context,
|
|
1125
863
|
"start": cmd_start,
|
|
1126
|
-
"replan": cmd_replan,
|
|
1127
864
|
"current": cmd_current,
|
|
1128
|
-
"continuity": cmd_continuity,
|
|
1129
|
-
"ownership": cmd_ownership,
|
|
1130
865
|
"finish": cmd_finish,
|
|
1131
866
|
"workflow": cmd_workflow,
|
|
867
|
+
"phase": cmd_phase,
|
|
868
|
+
"delegate-start": cmd_delegate_start,
|
|
869
|
+
"complete": cmd_complete_task,
|
|
870
|
+
"cancel": cmd_cancel_task,
|
|
1132
871
|
"set-branch": cmd_set_branch,
|
|
1133
872
|
"set-base-branch": cmd_set_base_branch,
|
|
1134
873
|
"set-scope": cmd_set_scope,
|
|
1135
874
|
"set-meta": cmd_set_meta,
|
|
1136
875
|
"rename": cmd_rename,
|
|
1137
|
-
"archive": cmd_archive,
|
|
1138
876
|
"add-subtask": cmd_add_subtask,
|
|
1139
877
|
"remove-subtask": cmd_remove_subtask,
|
|
1140
878
|
"list": cmd_list,
|
|
1141
|
-
"list-archive": cmd_list_archive,
|
|
1142
879
|
}
|
|
1143
880
|
|
|
1144
881
|
if args.command in commands:
|