@pennixrv/trellis 0.7.1 → 0.7.2-beta.2
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 +10 -7
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +6 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/ablate.d.ts.map +1 -1
- package/dist/commands/ablate.js +2 -0
- package/dist/commands/ablate.js.map +1 -1
- package/dist/commands/backup.d.ts +4 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +75 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +705 -681
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mem.d.ts.map +1 -1
- package/dist/commands/mem.js +49 -7
- package/dist/commands/mem.js.map +1 -1
- package/dist/commands/task-progress.d.ts +1 -0
- package/dist/commands/task-progress.d.ts.map +1 -1
- package/dist/commands/task-progress.js +67 -25
- package/dist/commands/task-progress.js.map +1 -1
- package/dist/commands/teamwork/adapters/acp.d.ts +20 -0
- package/dist/commands/teamwork/adapters/acp.d.ts.map +1 -0
- package/dist/commands/teamwork/adapters/acp.js +268 -0
- package/dist/commands/teamwork/adapters/acp.js.map +1 -0
- package/dist/commands/teamwork/adapters/claude.d.ts +1 -0
- package/dist/commands/teamwork/adapters/claude.d.ts.map +1 -1
- package/dist/commands/teamwork/adapters/claude.js +5 -0
- package/dist/commands/teamwork/adapters/claude.js.map +1 -1
- package/dist/commands/teamwork/adapters/codex.d.ts +3 -2
- package/dist/commands/teamwork/adapters/codex.d.ts.map +1 -1
- package/dist/commands/teamwork/adapters/codex.js +14 -15
- package/dist/commands/teamwork/adapters/codex.js.map +1 -1
- package/dist/commands/teamwork/adapters/index.d.ts +23 -1
- package/dist/commands/teamwork/adapters/index.d.ts.map +1 -1
- package/dist/commands/teamwork/adapters/index.js +163 -24
- package/dist/commands/teamwork/adapters/index.js.map +1 -1
- package/dist/commands/teamwork/agent-loader.d.ts +2 -1
- package/dist/commands/teamwork/agent-loader.d.ts.map +1 -1
- package/dist/commands/teamwork/agent-loader.js +2 -1
- package/dist/commands/teamwork/agent-loader.js.map +1 -1
- package/dist/commands/teamwork/artifact.d.ts +42 -14
- package/dist/commands/teamwork/artifact.d.ts.map +1 -1
- package/dist/commands/teamwork/artifact.js +188 -85
- package/dist/commands/teamwork/artifact.js.map +1 -1
- package/dist/commands/teamwork/batch-reservation.d.ts +16 -0
- package/dist/commands/teamwork/batch-reservation.d.ts.map +1 -0
- package/dist/commands/teamwork/batch-reservation.js +43 -0
- package/dist/commands/teamwork/batch-reservation.js.map +1 -0
- package/dist/commands/teamwork/batch.d.ts +23 -0
- package/dist/commands/teamwork/batch.d.ts.map +1 -0
- package/dist/commands/teamwork/batch.js +415 -0
- package/dist/commands/teamwork/batch.js.map +1 -0
- package/dist/commands/teamwork/context-loader.d.ts +1 -1
- package/dist/commands/teamwork/context-loader.d.ts.map +1 -1
- package/dist/commands/teamwork/context-loader.js +19 -6
- package/dist/commands/teamwork/context-loader.js.map +1 -1
- package/dist/commands/teamwork/coordination.d.ts +88 -0
- package/dist/commands/teamwork/coordination.d.ts.map +1 -0
- package/dist/commands/teamwork/coordination.js +153 -0
- package/dist/commands/teamwork/coordination.js.map +1 -0
- package/dist/commands/teamwork/coordinator.d.ts +33 -6
- package/dist/commands/teamwork/coordinator.d.ts.map +1 -1
- package/dist/commands/teamwork/coordinator.js +948 -342
- package/dist/commands/teamwork/coordinator.js.map +1 -1
- package/dist/commands/teamwork/create.d.ts +1 -0
- package/dist/commands/teamwork/create.d.ts.map +1 -1
- package/dist/commands/teamwork/create.js +2 -1
- package/dist/commands/teamwork/create.js.map +1 -1
- package/dist/commands/teamwork/dev-parse-trace.d.ts +2 -1
- package/dist/commands/teamwork/dev-parse-trace.d.ts.map +1 -1
- package/dist/commands/teamwork/dev-parse-trace.js +2 -0
- package/dist/commands/teamwork/dev-parse-trace.js.map +1 -1
- package/dist/commands/teamwork/foreground-wait.d.ts +6 -0
- package/dist/commands/teamwork/foreground-wait.d.ts.map +1 -0
- package/dist/commands/teamwork/foreground-wait.js +65 -0
- package/dist/commands/teamwork/foreground-wait.js.map +1 -0
- package/dist/commands/teamwork/guard.d.ts +2 -2
- package/dist/commands/teamwork/guard.d.ts.map +1 -1
- package/dist/commands/teamwork/guard.js +25 -7
- package/dist/commands/teamwork/guard.js.map +1 -1
- package/dist/commands/teamwork/index.d.ts.map +1 -1
- package/dist/commands/teamwork/index.js +163 -10
- package/dist/commands/teamwork/index.js.map +1 -1
- package/dist/commands/teamwork/kill.d.ts +2 -0
- package/dist/commands/teamwork/kill.d.ts.map +1 -1
- package/dist/commands/teamwork/kill.js +79 -38
- package/dist/commands/teamwork/kill.js.map +1 -1
- package/dist/commands/teamwork/messages.d.ts.map +1 -1
- package/dist/commands/teamwork/messages.js +3 -0
- package/dist/commands/teamwork/messages.js.map +1 -1
- package/dist/commands/teamwork/plan.d.ts +22 -0
- package/dist/commands/teamwork/plan.d.ts.map +1 -0
- package/dist/commands/teamwork/plan.js +288 -0
- package/dist/commands/teamwork/plan.js.map +1 -0
- package/dist/commands/teamwork/process-identity.d.ts +3 -0
- package/dist/commands/teamwork/process-identity.d.ts.map +1 -0
- package/dist/commands/teamwork/process-identity.js +24 -0
- package/dist/commands/teamwork/process-identity.js.map +1 -0
- package/dist/commands/teamwork/profiles.d.ts +43 -6
- package/dist/commands/teamwork/profiles.d.ts.map +1 -1
- package/dist/commands/teamwork/profiles.js +138 -110
- package/dist/commands/teamwork/profiles.js.map +1 -1
- package/dist/commands/teamwork/prompt.d.ts +4 -0
- package/dist/commands/teamwork/prompt.d.ts.map +1 -0
- package/dist/commands/teamwork/prompt.js +33 -0
- package/dist/commands/teamwork/prompt.js.map +1 -0
- package/dist/commands/teamwork/result.d.ts +55 -0
- package/dist/commands/teamwork/result.d.ts.map +1 -0
- package/dist/commands/teamwork/result.js +94 -0
- package/dist/commands/teamwork/result.js.map +1 -0
- package/dist/commands/teamwork/rm.d.ts.map +1 -1
- package/dist/commands/teamwork/rm.js +64 -64
- package/dist/commands/teamwork/rm.js.map +1 -1
- package/dist/commands/teamwork/run.d.ts +5 -0
- package/dist/commands/teamwork/run.d.ts.map +1 -1
- package/dist/commands/teamwork/run.js +120 -24
- package/dist/commands/teamwork/run.js.map +1 -1
- package/dist/commands/teamwork/runtime.d.ts +9 -0
- package/dist/commands/teamwork/runtime.d.ts.map +1 -0
- package/dist/commands/teamwork/runtime.js +401 -0
- package/dist/commands/teamwork/runtime.js.map +1 -0
- package/dist/commands/teamwork/send.d.ts +1 -0
- package/dist/commands/teamwork/send.d.ts.map +1 -1
- package/dist/commands/teamwork/send.js +2 -1
- package/dist/commands/teamwork/send.js.map +1 -1
- package/dist/commands/teamwork/spawn.d.ts +10 -3
- package/dist/commands/teamwork/spawn.d.ts.map +1 -1
- package/dist/commands/teamwork/spawn.js +42 -27
- package/dist/commands/teamwork/spawn.js.map +1 -1
- package/dist/commands/teamwork/store/lock.js +28 -4
- package/dist/commands/teamwork/store/lock.js.map +1 -1
- package/dist/commands/teamwork/supervisor/inbox.d.ts +1 -0
- package/dist/commands/teamwork/supervisor/inbox.d.ts.map +1 -1
- package/dist/commands/teamwork/supervisor/inbox.js +28 -9
- package/dist/commands/teamwork/supervisor/inbox.js.map +1 -1
- package/dist/commands/teamwork/supervisor/stdout.d.ts.map +1 -1
- package/dist/commands/teamwork/supervisor/stdout.js +2 -3
- package/dist/commands/teamwork/supervisor/stdout.js.map +1 -1
- package/dist/commands/teamwork/supervisor/warning.d.ts.map +1 -1
- package/dist/commands/teamwork/supervisor/warning.js +2 -3
- package/dist/commands/teamwork/supervisor/warning.js.map +1 -1
- package/dist/commands/teamwork/supervisor.d.ts +5 -0
- package/dist/commands/teamwork/supervisor.d.ts.map +1 -1
- package/dist/commands/teamwork/supervisor.js +21 -12
- package/dist/commands/teamwork/supervisor.js.map +1 -1
- package/dist/commands/teamwork/teammate-adapters.d.ts +0 -5
- package/dist/commands/teamwork/teammate-adapters.d.ts.map +1 -1
- package/dist/commands/teamwork/teammate-adapters.js +9 -56
- package/dist/commands/teamwork/teammate-adapters.js.map +1 -1
- package/dist/commands/teamwork/teammate-config.d.ts +5 -1
- package/dist/commands/teamwork/teammate-config.d.ts.map +1 -1
- package/dist/commands/teamwork/teammate-config.js +62 -19
- package/dist/commands/teamwork/teammate-config.js.map +1 -1
- package/dist/commands/teamwork/teammate-launch.d.ts +15 -6
- package/dist/commands/teamwork/teammate-launch.d.ts.map +1 -1
- package/dist/commands/teamwork/teammate-launch.js +129 -22
- package/dist/commands/teamwork/teammate-launch.js.map +1 -1
- package/dist/commands/teamwork/wait.d.ts +2 -0
- package/dist/commands/teamwork/wait.d.ts.map +1 -1
- package/dist/commands/teamwork/wait.js +44 -3
- package/dist/commands/teamwork/wait.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +92 -84
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +635 -592
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +94 -89
- package/dist/commands/workflow.js.map +1 -1
- package/dist/configurators/shared.js +2 -2
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +14 -32
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/constants/paths.d.ts +3 -10
- package/dist/constants/paths.d.ts.map +1 -1
- package/dist/constants/paths.js +4 -13
- package/dist/constants/paths.js.map +1 -1
- 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-beta.10.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.11.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.12.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.13.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.14.json +11 -0
- package/dist/migrations/manifests/0.7.1-beta.15.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.16.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.17.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.18.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.19.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.2.json +522 -0
- package/dist/migrations/manifests/0.7.1-beta.3.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.4.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.5.json +9 -0
- package/dist/migrations/manifests/0.7.1-beta.6.json +10 -0
- package/dist/migrations/manifests/0.7.1-beta.7.json +8 -0
- package/dist/migrations/manifests/0.7.1-beta.8.json +481 -0
- package/dist/migrations/manifests/0.7.1-beta.9.json +191 -0
- package/dist/migrations/manifests/0.7.2-beta.0.json +11 -0
- package/dist/migrations/manifests/0.7.2-beta.1.json +11 -0
- package/dist/migrations/manifests/0.7.2-beta.2.json +11 -0
- package/dist/templates/claude/hooks/statusline.py +9 -4
- package/dist/templates/codex/hooks/session-start.py +14 -11
- package/dist/templates/codex/hooks.json +10 -0
- package/dist/templates/common/bundled-skills/trellis-decision-space-construction-and-merging/workflow.md +2 -0
- package/dist/templates/common/bundled-skills/trellis-goal-exploration-and-requirements/workflow.md +2 -0
- package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +5 -5
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +3 -2
- 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/context-injection.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/multi-agent-teamwork.md +14 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +8 -2
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/cli-quick-reference.md +2 -1
- package/dist/templates/common/bundled-skills/trellis-session-insight/references/triggering-patterns.md +2 -2
- package/dist/templates/common/bundled-skills/trellis-solution-design-and-convergence/workflow.md +8 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/mcp-setup.md +4 -2
- package/dist/templates/common/bundled-skills/trellis-spec-bootstrap/references/spec-task-planning.md +2 -2
- package/dist/templates/common/bundled-skills/trellis-task-implementation/workflow.md +6 -0
- package/dist/templates/common/bundled-skills/trellis-teamwork/SKILL.md +18 -3
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/coordination-modes.md +34 -3
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-configuration-matrix.md +37 -26
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teammate-processes.md +128 -14
- package/dist/templates/common/bundled-skills/trellis-teamwork/references/teamwork-plan-construction.md +152 -20
- package/dist/templates/common/commands/start.md +2 -2
- package/dist/templates/common/skills/before-dev.md +1 -4
- package/dist/templates/common/skills/break-loop.md +7 -18
- package/dist/templates/common/skills/check.md +7 -11
- package/dist/templates/common/skills/{brainstorm.md → request-intake.md} +5 -3
- package/dist/templates/common/skills/update-spec.md +5 -7
- package/dist/templates/copilot/hooks/session-start.py +14 -11
- package/dist/templates/copilot/index.d.ts +1 -6
- package/dist/templates/copilot/index.d.ts.map +1 -1
- package/dist/templates/copilot/index.js +1 -14
- package/dist/templates/copilot/index.js.map +1 -1
- package/dist/templates/extract.js +4 -0
- package/dist/templates/extract.js.map +1 -1
- package/dist/templates/markdown/spec/backend/index.md.txt +4 -35
- package/dist/templates/markdown/spec/frontend/index.md.txt +4 -36
- package/dist/templates/omp/extensions/trellis/index.ts.txt +2 -2
- package/dist/templates/opencode/lib/session-utils.js +301 -209
- package/dist/templates/pi/extensions/trellis/index.ts.txt +17 -1
- package/dist/templates/shared-hooks/guard-teamwork-wait.py +58 -0
- package/dist/templates/shared-hooks/index.d.ts +1 -1
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +1 -0
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-workflow-state.py +8 -3
- package/dist/templates/shared-hooks/session-start.py +16 -12
- package/dist/templates/snow/SNOW.md +1 -1
- package/dist/templates/trellis/agents/delegated-worktree-primary-agent.md +9 -0
- package/dist/templates/trellis/agents/profiles/architecture.md +9 -0
- package/dist/templates/trellis/agents/profiles/diagnosis.md +9 -0
- package/dist/templates/trellis/agents/profiles/exploration.md +9 -0
- package/dist/templates/trellis/agents/profiles/research.md +9 -0
- package/dist/templates/trellis/agents/profiles/review.md +9 -0
- package/dist/templates/trellis/agents/profiles/verification.md +9 -0
- package/dist/templates/trellis/agents/teammate-profiles.json +56 -4
- package/dist/templates/trellis/agents/teammate.md +4 -52
- package/dist/templates/trellis/config.yaml +2 -5
- package/dist/templates/trellis/index.d.ts +4 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +22 -4
- 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/active_task.py +3 -47
- package/dist/templates/trellis/scripts/common/config.py +5 -0
- package/dist/templates/trellis/scripts/common/paths.py +9 -25
- package/dist/templates/trellis/scripts/common/safe_commit.py +8 -8
- package/dist/templates/trellis/scripts/common/task_context.py +11 -51
- package/dist/templates/trellis/scripts/common/task_continuity.py +191 -60
- package/dist/templates/trellis/scripts/common/task_layout.py +80 -0
- package/dist/templates/trellis/scripts/common/task_move.py +345 -0
- package/dist/templates/trellis/scripts/common/task_store.py +51 -57
- package/dist/templates/trellis/scripts/common/task_utils.py +23 -19
- package/dist/templates/trellis/scripts/common/task_workflow.py +395 -49
- package/dist/templates/trellis/scripts/common/tasks.py +6 -5
- package/dist/templates/trellis/scripts/hooks/linear_sync.py +13 -3
- package/dist/templates/trellis/scripts/task.py +76 -24
- package/dist/templates/trellis/teamwork.json +10 -0
- package/dist/templates/trellis/workflow.md +11 -2
- package/dist/utils/ablation-store.d.ts +1 -1
- package/dist/utils/ablation-store.d.ts.map +1 -1
- package/dist/utils/ablation-store.js +58 -24
- package/dist/utils/ablation-store.js.map +1 -1
- package/dist/utils/asset-backup.d.ts +138 -0
- package/dist/utils/asset-backup.d.ts.map +1 -0
- package/dist/utils/asset-backup.js +525 -0
- package/dist/utils/asset-backup.js.map +1 -0
- package/dist/utils/atomic-write.d.ts +1 -1
- package/dist/utils/atomic-write.d.ts.map +1 -1
- package/dist/utils/atomic-write.js +6 -3
- package/dist/utils/atomic-write.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts +4 -1
- package/dist/utils/manifest-prune.d.ts.map +1 -1
- package/dist/utils/manifest-prune.js +17 -6
- package/dist/utils/manifest-prune.js.map +1 -1
- package/dist/utils/template-fetcher.d.ts +4 -19
- package/dist/utils/template-fetcher.d.ts.map +1 -1
- package/dist/utils/template-fetcher.js +9 -45
- package/dist/utils/template-fetcher.js.map +1 -1
- package/dist/utils/template-hash.d.ts +5 -4
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +24 -17
- package/dist/utils/template-hash.js.map +1 -1
- package/package.json +3 -2
- package/dist/templates/copilot/prompts/before-dev.prompt.md +0 -39
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +0 -13
- package/dist/templates/copilot/prompts/break-loop.prompt.md +0 -129
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +0 -170
- package/dist/templates/copilot/prompts/check.prompt.md +0 -110
- package/dist/templates/copilot/prompts/create-command.prompt.md +0 -116
- package/dist/templates/copilot/prompts/finish-work.prompt.md +0 -22
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +0 -223
- package/dist/templates/copilot/prompts/onboard.prompt.md +0 -362
- package/dist/templates/copilot/prompts/record-session.prompt.md +0 -58
- package/dist/templates/copilot/prompts/start.prompt.md +0 -65
- package/dist/templates/copilot/prompts/update-spec.prompt.md +0 -358
|
@@ -19,6 +19,7 @@ from pathlib import Path
|
|
|
19
19
|
from .io import describe_json_read_failure, read_json_checked
|
|
20
20
|
from .paths import FILE_TASK_JSON
|
|
21
21
|
from .types import TaskInfo
|
|
22
|
+
from .task_layout import iter_task_dirs, task_status_dir
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
def load_task(task_dir: Path) -> TaskInfo | None:
|
|
@@ -72,14 +73,14 @@ def iter_active_tasks(tasks_dir: Path) -> Iterator[TaskInfo]:
|
|
|
72
73
|
Yields:
|
|
73
74
|
TaskInfo for each valid task.
|
|
74
75
|
"""
|
|
75
|
-
|
|
76
|
-
return
|
|
76
|
+
from .task_move import require_settled_layout
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
continue
|
|
78
|
+
require_settled_layout(tasks_dir.parent.parent)
|
|
79
|
+
for d in iter_task_dirs(tasks_dir):
|
|
81
80
|
info = load_task(d)
|
|
82
81
|
if info is not None:
|
|
82
|
+
if info.status != task_status_dir(d, tasks_dir):
|
|
83
|
+
print(f"[WARN] Task status/directory mismatch: {d}", file=sys.stderr)
|
|
83
84
|
yield info
|
|
84
85
|
|
|
85
86
|
|
|
@@ -9,7 +9,7 @@ Usage (called automatically by task.py hooks):
|
|
|
9
9
|
python3 .trellis/scripts/hooks/linear_sync.py complete
|
|
10
10
|
|
|
11
11
|
Manual usage:
|
|
12
|
-
TASK_JSON_PATH=.trellis/tasks/<
|
|
12
|
+
TASK_JSON_PATH=.trellis/tasks/<task-dir>/task.json python3 .trellis/scripts/hooks/linear_sync.py sync
|
|
13
13
|
|
|
14
14
|
Environment:
|
|
15
15
|
TASK_JSON_PATH - Absolute path to task.json (set by task.py)
|
|
@@ -211,8 +211,18 @@ def _resolve_parent_linear_issue(task: dict) -> str | None:
|
|
|
211
211
|
return None
|
|
212
212
|
|
|
213
213
|
current_task_dir = Path(task_json_path).parent
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
scripts_dir = Path(__file__).resolve().parents[1]
|
|
215
|
+
if str(scripts_dir) not in sys.path:
|
|
216
|
+
sys.path.insert(0, str(scripts_dir))
|
|
217
|
+
from common.paths import get_tasks_dir
|
|
218
|
+
from common.task_utils import find_task_by_name
|
|
219
|
+
workflow_dir = next((parent for parent in current_task_dir.parents if parent.name == ".trellis"), None)
|
|
220
|
+
if workflow_dir is None:
|
|
221
|
+
return None
|
|
222
|
+
parent_dir = find_task_by_name(parent_name, get_tasks_dir(workflow_dir.parent))
|
|
223
|
+
if parent_dir is None:
|
|
224
|
+
return None
|
|
225
|
+
parent_json = parent_dir / "task.json"
|
|
216
226
|
|
|
217
227
|
if parent_json.exists():
|
|
218
228
|
try:
|
|
@@ -14,6 +14,7 @@ Usage:
|
|
|
14
14
|
python3 task.py workflow <id>|--clear # Set/clear per-task workflow selection
|
|
15
15
|
python3 task.py phase <action> <task-dir> # Read/update task phase workflow state
|
|
16
16
|
python3 task.py cancel <task-dir> --reason <text> --evidence-ref <ref> # Cancel task lifecycle
|
|
17
|
+
python3 task.py reopen <task-dir> --reason <text> --evidence-ref <ref> # Restore terminal task to planning
|
|
17
18
|
python3 task.py set-branch <dir> <branch> # Set git branch
|
|
18
19
|
python3 task.py set-base-branch <dir> <branch> # Set PR target branch
|
|
19
20
|
python3 task.py set-scope <dir> <scope> # Set scope for PR title
|
|
@@ -79,8 +80,11 @@ from common.task_context import (
|
|
|
79
80
|
from common.task_workflow import (
|
|
80
81
|
TaskWorkflowError,
|
|
81
82
|
cmd_cancel_task,
|
|
83
|
+
cmd_reopen_task,
|
|
82
84
|
cmd_complete_task,
|
|
83
85
|
cmd_delegate_start,
|
|
86
|
+
cmd_delegate_bind,
|
|
87
|
+
cmd_delegate_reconcile,
|
|
84
88
|
cmd_phase,
|
|
85
89
|
implementation_start_ready,
|
|
86
90
|
)
|
|
@@ -101,7 +105,7 @@ def _record_start_state(
|
|
|
101
105
|
task_json_path: Path,
|
|
102
106
|
repo_root: Path,
|
|
103
107
|
label: str = "",
|
|
104
|
-
) ->
|
|
108
|
+
) -> Path:
|
|
105
109
|
"""Enter implementation and record its branch after current authorization.
|
|
106
110
|
|
|
107
111
|
Planning and analysis tasks keep their lifecycle status while the active
|
|
@@ -121,7 +125,7 @@ def _record_start_state(
|
|
|
121
125
|
file=sys.stderr,
|
|
122
126
|
)
|
|
123
127
|
print(hint, file=sys.stderr)
|
|
124
|
-
return
|
|
128
|
+
return task_json_path
|
|
125
129
|
|
|
126
130
|
applied: list[str] = []
|
|
127
131
|
|
|
@@ -132,7 +136,7 @@ def _record_start_state(
|
|
|
132
136
|
colored(f"Warning: Implementation start withheld; task.json not updated: {error.code}: {error}", Colors.YELLOW),
|
|
133
137
|
file=sys.stderr,
|
|
134
138
|
)
|
|
135
|
-
return
|
|
139
|
+
return task_json_path
|
|
136
140
|
if data.get("status") == "planning" and implementation_ready:
|
|
137
141
|
data["status"] = "in_progress"
|
|
138
142
|
applied.append(f"✓ Status: planning → in_progress{label}")
|
|
@@ -158,15 +162,18 @@ def _record_start_state(
|
|
|
158
162
|
)
|
|
159
163
|
|
|
160
164
|
if not applied:
|
|
161
|
-
return
|
|
165
|
+
return task_json_path
|
|
162
166
|
|
|
163
167
|
try:
|
|
164
168
|
assert_task_mutation_allowed(repo_root, task_json_path.parent, data)
|
|
165
169
|
except TaskWorkflowError as error:
|
|
166
170
|
print(colored(f"{error.code}: task metadata update withheld: {error}", Colors.YELLOW), file=sys.stderr)
|
|
167
|
-
return
|
|
171
|
+
return task_json_path
|
|
168
172
|
|
|
169
|
-
|
|
173
|
+
from common.task_move import relocate_task
|
|
174
|
+
relocated = relocate_task(repo_root, task_json_path.parent, data)
|
|
175
|
+
task_json_path = relocated / FILE_TASK_JSON
|
|
176
|
+
if not task_json_path.is_file():
|
|
170
177
|
print(
|
|
171
178
|
colored(
|
|
172
179
|
f"Warning: Failed to write {task_json_path}; "
|
|
@@ -175,7 +182,7 @@ def _record_start_state(
|
|
|
175
182
|
),
|
|
176
183
|
file=sys.stderr,
|
|
177
184
|
)
|
|
178
|
-
return
|
|
185
|
+
return task_json_path
|
|
179
186
|
|
|
180
187
|
for line in applied:
|
|
181
188
|
print(colored(line, Colors.GREEN))
|
|
@@ -190,12 +197,15 @@ def _record_start_state(
|
|
|
190
197
|
),
|
|
191
198
|
file=sys.stderr,
|
|
192
199
|
)
|
|
200
|
+
|
|
193
201
|
print(
|
|
194
202
|
f"Once you branch off, run: python3 {DIR_WORKFLOW}/scripts/task.py "
|
|
195
203
|
"set-branch <task> <feature-branch>",
|
|
196
204
|
file=sys.stderr,
|
|
197
205
|
)
|
|
198
206
|
|
|
207
|
+
return task_json_path
|
|
208
|
+
|
|
199
209
|
|
|
200
210
|
def cmd_start(args: argparse.Namespace) -> int:
|
|
201
211
|
"""Set active task."""
|
|
@@ -237,6 +247,11 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
237
247
|
return 1
|
|
238
248
|
|
|
239
249
|
task_json_path = full_path / FILE_TASK_JSON
|
|
250
|
+
if task_json_path.is_file():
|
|
251
|
+
task_data, _ = read_json_checked(task_json_path)
|
|
252
|
+
if task_data is not None and task_data.get("status") in {"completed", "cancelled"}:
|
|
253
|
+
print(colored(f"TASK_PHASE_TASK_TERMINAL: task is already {task_data['status']}", Colors.RED), file=sys.stderr)
|
|
254
|
+
return 1
|
|
240
255
|
|
|
241
256
|
if not resolve_context_key():
|
|
242
257
|
# Degraded mode: no session identity available.
|
|
@@ -256,18 +271,17 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
256
271
|
|
|
257
272
|
# Enter implementation only when the accepted phase contract authorizes it.
|
|
258
273
|
if task_json_path.is_file():
|
|
259
|
-
_record_start_state(task_json_path, repo_root, " (degraded)")
|
|
274
|
+
task_json_path = _record_start_state(task_json_path, repo_root, " (degraded)")
|
|
260
275
|
run_task_hooks("after_start", task_json_path, repo_root)
|
|
261
276
|
return 0
|
|
262
277
|
|
|
278
|
+
if task_json_path.is_file():
|
|
279
|
+
task_json_path = _record_start_state(task_json_path, repo_root)
|
|
280
|
+
task_dir = task_json_path.parent.relative_to(repo_root).as_posix()
|
|
263
281
|
active = set_active_task(task_dir, repo_root)
|
|
264
282
|
if active:
|
|
265
|
-
print(colored(f"✓ Current task set to: {
|
|
283
|
+
print(colored(f"✓ Current task set to: {task_json_path.parent.relative_to(repo_root).as_posix()}", Colors.GREEN))
|
|
266
284
|
print(f"Source: {active.source}")
|
|
267
|
-
|
|
268
|
-
if task_json_path.is_file():
|
|
269
|
-
_record_start_state(task_json_path, repo_root)
|
|
270
|
-
|
|
271
285
|
print()
|
|
272
286
|
print(colored("The hook will now inject context from this task's jsonl files.", Colors.BLUE))
|
|
273
287
|
|
|
@@ -348,6 +362,11 @@ def cmd_current(args: argparse.Namespace) -> int:
|
|
|
348
362
|
payload = {
|
|
349
363
|
"current_task": task_obj,
|
|
350
364
|
"source": active.source,
|
|
365
|
+
"session_source": (
|
|
366
|
+
f"session:{active.context_key}"
|
|
367
|
+
if active.context_key
|
|
368
|
+
else None
|
|
369
|
+
),
|
|
351
370
|
"stale": active.stale,
|
|
352
371
|
}
|
|
353
372
|
# Only present when the read failed, so the healthy shape is unchanged.
|
|
@@ -494,7 +513,7 @@ def cmd_list(args: argparse.Namespace) -> int:
|
|
|
494
513
|
if filter_status and t.status != filter_status:
|
|
495
514
|
continue
|
|
496
515
|
items.append({
|
|
497
|
-
"dir":
|
|
516
|
+
"dir": t.directory.relative_to(repo_root).as_posix(),
|
|
498
517
|
"id": t.raw.get("id") or dir_name,
|
|
499
518
|
"title": t.title,
|
|
500
519
|
"status": t.status,
|
|
@@ -533,7 +552,7 @@ def cmd_list(args: argparse.Namespace) -> int:
|
|
|
533
552
|
if filter_status and t.status != filter_status:
|
|
534
553
|
return
|
|
535
554
|
|
|
536
|
-
relative_path =
|
|
555
|
+
relative_path = t.directory.relative_to(repo_root).as_posix()
|
|
537
556
|
marker = ""
|
|
538
557
|
if relative_path == current_task:
|
|
539
558
|
marker = f" {colored('<- current', Colors.GREEN)}"
|
|
@@ -617,7 +636,7 @@ Rename options:
|
|
|
617
636
|
|
|
618
637
|
List options:
|
|
619
638
|
--mine, -m Show only tasks assigned to current developer
|
|
620
|
-
--status, -s <s> Filter by status (planning, in_progress,
|
|
639
|
+
--status, -s <s> Filter by status (planning, in_progress, completed, cancelled)
|
|
621
640
|
--json Output machine-readable JSON (also available on `current`)
|
|
622
641
|
|
|
623
642
|
Examples:
|
|
@@ -769,6 +788,7 @@ def main() -> int:
|
|
|
769
788
|
p_phase.add_argument("--route-reason", help="Reason when initialization omits one or more phases")
|
|
770
789
|
p_phase.add_argument("--route-evidence-ref", action="append", help="Evidence supporting an abbreviated initial route")
|
|
771
790
|
p_phase.add_argument("--target-phase", help="Earlier phase to revisit, or first affected phase for route change")
|
|
791
|
+
p_phase.add_argument("--return-kind", choices=("contract_change", "execution_rework", "withdrawal"), default="contract_change", help="Classify a return or explicitly record user withdrawal")
|
|
772
792
|
p_phase.add_argument("--artifact-ref", action="append", help="Task-relative file in the current phase output")
|
|
773
793
|
p_phase.add_argument("--artifact-revision", help="Current artifact_revision required for acceptance")
|
|
774
794
|
p_phase.add_argument("--result-ref", help="Task result artifact reference")
|
|
@@ -784,6 +804,14 @@ def main() -> int:
|
|
|
784
804
|
|
|
785
805
|
p_delegate = subparsers.add_parser("delegate-start", help="Start an authorized child task in a Paseo worktree")
|
|
786
806
|
p_delegate.add_argument("child_task", help="Linked child task directory or name")
|
|
807
|
+
p_delegate_bind = subparsers.add_parser("delegate-bind", help="Freeze a linked child contract within current parent authorization")
|
|
808
|
+
p_delegate_bind.add_argument("child_task")
|
|
809
|
+
p_delegate_bind.add_argument("--result-path", help="Assigned artifact under .trellis/delegated-results/")
|
|
810
|
+
p_delegate_reconcile = subparsers.add_parser("delegate-reconcile", help="Inspect or explicitly retire a verified delegated execution")
|
|
811
|
+
p_delegate_reconcile.add_argument("child_task")
|
|
812
|
+
p_delegate_reconcile.add_argument("--execute", action="store_true")
|
|
813
|
+
p_delegate_reconcile.add_argument("--reason")
|
|
814
|
+
p_delegate_reconcile.add_argument("--approval-ref")
|
|
787
815
|
|
|
788
816
|
add_continuity_commands(subparsers)
|
|
789
817
|
|
|
@@ -793,6 +821,11 @@ def main() -> int:
|
|
|
793
821
|
p_cancel.add_argument("--reason", required=True, help="Why the task is cancelled")
|
|
794
822
|
p_cancel.add_argument("--evidence-ref", action="append", required=True, help="Task-relative cancellation evidence")
|
|
795
823
|
|
|
824
|
+
p_reopen = subparsers.add_parser("reopen", help="Recover a terminal task to planning without implementation authorization")
|
|
825
|
+
p_reopen.add_argument("task_dir", help="Task directory or task name")
|
|
826
|
+
p_reopen.add_argument("--reason", required=True, help="Why the same task must continue")
|
|
827
|
+
p_reopen.add_argument("--evidence-ref", action="append", required=True, help="Recovery decision evidence")
|
|
828
|
+
|
|
796
829
|
# set-branch
|
|
797
830
|
p_branch = subparsers.add_parser("set-branch", help="Set git branch")
|
|
798
831
|
p_branch.add_argument("dir", help="Task directory")
|
|
@@ -844,16 +877,18 @@ def main() -> int:
|
|
|
844
877
|
p_complete = subparsers.add_parser("complete", help="Complete after Delivery Review and On-Site Closeout Phase acceptance")
|
|
845
878
|
p_complete.add_argument("task_dir", help="Task directory or task name")
|
|
846
879
|
|
|
880
|
+
p_migrate = subparsers.add_parser("migrate-layout", help="Preview or explicitly apply task status directory migration")
|
|
881
|
+
migration_mode = p_migrate.add_mutually_exclusive_group()
|
|
882
|
+
migration_mode.add_argument("--apply", action="store_true", help="Recheck and apply the migration")
|
|
883
|
+
migration_mode.add_argument("--recover", action="store_true", help="Roll back an interrupted relocation")
|
|
884
|
+
|
|
847
885
|
args = parser.parse_args()
|
|
848
886
|
|
|
849
887
|
if not args.command:
|
|
850
888
|
show_usage()
|
|
851
889
|
return 1
|
|
852
890
|
|
|
853
|
-
|
|
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)
|
|
891
|
+
from common.task_move import cmd_migrate_layout, layout_lock, require_settled_layout
|
|
857
892
|
|
|
858
893
|
commands = {
|
|
859
894
|
"create": cmd_create,
|
|
@@ -866,8 +901,11 @@ def main() -> int:
|
|
|
866
901
|
"workflow": cmd_workflow,
|
|
867
902
|
"phase": cmd_phase,
|
|
868
903
|
"delegate-start": cmd_delegate_start,
|
|
904
|
+
"delegate-bind": cmd_delegate_bind,
|
|
905
|
+
"delegate-reconcile": cmd_delegate_reconcile,
|
|
869
906
|
"complete": cmd_complete_task,
|
|
870
907
|
"cancel": cmd_cancel_task,
|
|
908
|
+
"reopen": cmd_reopen_task,
|
|
871
909
|
"set-branch": cmd_set_branch,
|
|
872
910
|
"set-base-branch": cmd_set_base_branch,
|
|
873
911
|
"set-scope": cmd_set_scope,
|
|
@@ -876,12 +914,26 @@ def main() -> int:
|
|
|
876
914
|
"add-subtask": cmd_add_subtask,
|
|
877
915
|
"remove-subtask": cmd_remove_subtask,
|
|
878
916
|
"list": cmd_list,
|
|
917
|
+
"migrate-layout": cmd_migrate_layout,
|
|
879
918
|
}
|
|
880
919
|
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
920
|
+
try:
|
|
921
|
+
with layout_lock(get_repo_root()):
|
|
922
|
+
if args.command != "migrate-layout":
|
|
923
|
+
require_settled_layout(get_repo_root())
|
|
924
|
+
if args.command == "continuity":
|
|
925
|
+
return continuity_show(args) if args.continuity_action == "show" else continuity_capture(args)
|
|
926
|
+
if args.command == "transfer":
|
|
927
|
+
return transfer_task_ownership(args)
|
|
928
|
+
if args.command in commands:
|
|
929
|
+
return commands[args.command](args)
|
|
930
|
+
show_usage()
|
|
931
|
+
return 1
|
|
932
|
+
except TaskWorkflowError as error:
|
|
933
|
+
print(f"{error.code}: {error}", file=sys.stderr)
|
|
934
|
+
return 1
|
|
935
|
+
except (ValueError, OSError) as error:
|
|
936
|
+
print(f"TASK_LAYOUT_WITHHELD: {error}", file=sys.stderr)
|
|
885
937
|
return 1
|
|
886
938
|
|
|
887
939
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 2,
|
|
3
|
+
"default_mode": "general",
|
|
4
|
+
"modes": {
|
|
5
|
+
"general": { "default_members": 1, "max_concurrency": 8 },
|
|
6
|
+
"advisor": { "default_members": 3, "max_concurrency": 3 },
|
|
7
|
+
"committee": { "default_members": 3, "max_concurrency": 3 }
|
|
8
|
+
},
|
|
9
|
+
"resources": { "max_live_teammates": 8, "non_batch_reserved": 0 }
|
|
10
|
+
}
|
|
@@ -20,7 +20,7 @@ python3 ./.trellis/scripts/get_context.py --mode spec --file <path>
|
|
|
20
20
|
|
|
21
21
|
### 任务记录
|
|
22
22
|
|
|
23
|
-
Trellis task
|
|
23
|
+
Trellis task 按 `task.json.status` 存放在 `.trellis/tasks/planning/<task>`、`in_progress/<task>`、`completed/YYYY-MM/<task>` 或 `cancelled/<task>`。创建进入 `planning`,获准实施后启动进入 `in_progress`;目录仅是状态的投影。每个任务包含 `task.json`、需求以及任务所需的设计、实施、研究或上下文资产。使用 Trellis CLI 创建和启动任务、初始化和推进阶段路线,以及完成或取消任务。不得手工修改任务状态或阶段状态。
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
python3 ./.trellis/scripts/task.py create "<title>" [--slug <name>] [--parent <task>]
|
|
@@ -30,11 +30,20 @@ python3 ./.trellis/scripts/task.py validate <task>
|
|
|
30
30
|
python3 ./.trellis/scripts/task.py start <task>
|
|
31
31
|
python3 ./.trellis/scripts/task.py complete <task>
|
|
32
32
|
python3 ./.trellis/scripts/task.py cancel <task> --reason "<reason>" --evidence-ref <reference>
|
|
33
|
+
python3 ./.trellis/scripts/task.py reopen <task> --reason "<reason>" --evidence-ref <reference>
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
使用 `phase artifact`、`accept`、`skip`、`wait`、`block`、`resume`、`return`、`route` 和 `authorize` 执行对应的阶段操作。准确参数以 `task.py --help` 为准。跳过阶段必须提供理由和证据;目标探索与需求核对阶段不可省略。
|
|
36
37
|
|
|
37
|
-
只有阶段路线已到达获准的实施入口时,`task.py start` 才会将任务从 `planning` 改为 `in_progress`。分析任务可在交付审查与现场收尾阶段后仍处于 `planning` 时完成。`complete`
|
|
38
|
+
只有阶段路线已到达获准的实施入口时,`task.py start` 才会将任务从 `planning` 改为 `in_progress`。分析任务可在交付审查与现场收尾阶段后仍处于 `planning` 时完成。`complete` 将任务移入 `completed/YYYY-MM/<task>`,`cancel` 将任务移入 `cancelled/<task>`,并在同一事务中清除任务的运行时会话指针。
|
|
39
|
+
|
|
40
|
+
工作流阶段回流与原生任务生命周期恢复分别操作。`completed` 或 `cancelled` 任务需要在原线程继续时,先用 `reopen` 恢复到 `planning`,保留终态事实、取消原因和恢复证据,清除旧运行态、实施授权和依赖准入;工作流阶段保持原记录。随后用 `phase return` 回到最早受影响阶段。实现任务重新接受合同、取得新的实施授权并核验准入后,才由 `start` 进入 `in_progress`。`phase return` 不能直接修改终态任务。
|
|
41
|
+
|
|
42
|
+
`phase return` 默认采用 `contract_change`,使受影响阶段接受和实施授权失效。合同不变的局部实施或证据返工可显式使用 `--return-kind execution_rework`,目标限于实施或交付阶段,可重入当前阶段;CLI 核验需求、已接受合同、授权摘要、路线 revision 和已声明依赖准入仍有效后,保留授权,清理目标阶段及下游的接受事实。不能以此修改目标、合同或绕过待决依赖。普通局部修复可直接在当前活动阶段完成,无需为了记录进展而回流。
|
|
43
|
+
|
|
44
|
+
新接受的 `implementation_contract`(以及省略设计阶段时新授权的合同)必须包含 `## 验收覆盖` 表,表头固定为 `接受条件 | 工作包 | Owner | 验证入口 | 交付证据 | 停止条件`,至少一行且各单元格非空。CLI 负责结构检查,阶段 Skill 负责逐条核对已接受条件的语义覆盖。既有接受和授权不会因本次升级自动失效;再次接受或授权时执行新检查。
|
|
45
|
+
|
|
46
|
+
旧布局须先预览 `task.py migrate-layout`,核对后执行 `task.py migrate-layout --apply`;旧 `archive/YYYY-MM` 中已完成的任务保留原月份,其他任务按真实状态放置。迁移会同步 JSON/JSONL 机器引用、会话指针和运行态索引,保留任务身份与父子关系,不重授历史授权。未完成事务会阻止普通任务命令,须用 `task.py migrate-layout --recover` 恢复;输入被外部改动时停止并保留现场。路径或产物内容改变导致接受证据失效时,须经原生阶段接受或 continuity 核对重新收敛。
|
|
38
47
|
|
|
39
48
|
在支持原生实施或检查 agent 的平台上,任务上下文清单(`implement.jsonl`、`check.jsonl`)用于提供相关规范和研究资料。只有这些 agent 会读取清单时才需要维护;清单不能替代任务资产或阶段证据。
|
|
40
49
|
|
|
@@ -103,7 +103,7 @@ export declare function parseAblationState(value: unknown): AblationStateV1;
|
|
|
103
103
|
export declare function stageAblationTransaction(input: StagedAblationInput, options?: StageAblationOptions): LoadedAblationTransaction;
|
|
104
104
|
export declare function loadAblationTransaction(projectRoot: string, stateRoot?: string): LoadedAblationTransaction | null;
|
|
105
105
|
export declare function transitionAblationState(transaction: LoadedAblationTransaction, status: AblationStatus): AblationStateV1;
|
|
106
|
-
/**
|
|
106
|
+
/** Shared project maintenance boundary; asynchronous operations retain ownership. */
|
|
107
107
|
export declare function withAblationProjectLock<T>(paths: TransactionPaths, operation: () => T): T;
|
|
108
108
|
/** Preflight every affected path before restore writes anything. */
|
|
109
109
|
export declare function collectRestoreConflicts(transaction: LoadedAblationTransaction): AblationConflict[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ablation-store.d.ts","sourceRoot":"","sources":["../../src/utils/ablation-store.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ablation-store.d.ts","sourceRoot":"","sources":["../../src/utils/ablation-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -412,8 +412,8 @@ function pidAlive(pid) {
|
|
|
412
412
|
process.kill(pid, 0);
|
|
413
413
|
return true;
|
|
414
414
|
}
|
|
415
|
-
catch {
|
|
416
|
-
return
|
|
415
|
+
catch (error) {
|
|
416
|
+
return error.code !== "ESRCH";
|
|
417
417
|
}
|
|
418
418
|
}
|
|
419
419
|
function acquireProjectLock(paths) {
|
|
@@ -421,41 +421,68 @@ function acquireProjectLock(paths) {
|
|
|
421
421
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
422
422
|
try {
|
|
423
423
|
const fd = fs.openSync(paths.lockFile, "wx", 0o600);
|
|
424
|
+
const content = JSON.stringify({ pid: process.pid, nonce: randomUUID() });
|
|
424
425
|
try {
|
|
425
|
-
fs.writeSync(fd,
|
|
426
|
+
fs.writeSync(fd, content);
|
|
427
|
+
const stat = fs.fstatSync(fd);
|
|
428
|
+
return { content, ino: stat.ino, dev: stat.dev };
|
|
426
429
|
}
|
|
427
430
|
finally {
|
|
428
431
|
fs.closeSync(fd);
|
|
429
432
|
}
|
|
430
|
-
return;
|
|
431
433
|
}
|
|
432
434
|
catch (error) {
|
|
433
435
|
if (error.code !== "EEXIST")
|
|
434
436
|
throw error;
|
|
435
437
|
}
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
438
|
+
const stat = fs.lstatSync(paths.lockFile);
|
|
439
|
+
if (!stat.isFile() || stat.isSymbolicLink()) {
|
|
440
|
+
throw new Error("Unknown Trellis maintenance lock; inspect it before retrying.");
|
|
439
441
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
+
const content = fs.readFileSync(paths.lockFile, "utf-8").trim();
|
|
443
|
+
let holderPid;
|
|
444
|
+
if (/^[1-9]\d*$/.test(content))
|
|
445
|
+
holderPid = Number(content);
|
|
446
|
+
else {
|
|
447
|
+
try {
|
|
448
|
+
const record = JSON.parse(content);
|
|
449
|
+
if (record &&
|
|
450
|
+
typeof record === "object" &&
|
|
451
|
+
"pid" in record &&
|
|
452
|
+
"nonce" in record &&
|
|
453
|
+
typeof record.nonce === "string")
|
|
454
|
+
holderPid = record.pid;
|
|
455
|
+
}
|
|
456
|
+
catch {
|
|
457
|
+
// An incomplete or unknown lock is not evidence that its owner exited.
|
|
458
|
+
}
|
|
442
459
|
}
|
|
443
|
-
if (holderPid
|
|
444
|
-
|
|
460
|
+
if (typeof holderPid !== "number" ||
|
|
461
|
+
!Number.isSafeInteger(holderPid) ||
|
|
462
|
+
holderPid <= 0) {
|
|
463
|
+
throw new Error("Unknown Trellis maintenance lock; inspect it before retrying.");
|
|
445
464
|
}
|
|
446
|
-
|
|
447
|
-
|
|
465
|
+
if (pidAlive(holderPid)) {
|
|
466
|
+
throw new Error(`Another Trellis maintenance operation is already in progress for this project (pid ${holderPid}).`);
|
|
448
467
|
}
|
|
449
|
-
|
|
450
|
-
|
|
468
|
+
const current = fs.lstatSync(paths.lockFile);
|
|
469
|
+
if (current.ino !== stat.ino ||
|
|
470
|
+
current.dev !== stat.dev ||
|
|
471
|
+
fs.readFileSync(paths.lockFile, "utf-8").trim() !== content) {
|
|
472
|
+
throw new Error("Trellis maintenance lock changed during inspection.");
|
|
451
473
|
}
|
|
474
|
+
fs.unlinkSync(paths.lockFile);
|
|
452
475
|
}
|
|
453
476
|
throw new Error("Unable to acquire the Trellis ablation-operation lock; retry the command.");
|
|
454
477
|
}
|
|
455
|
-
function releaseProjectLock(paths) {
|
|
478
|
+
function releaseProjectLock(paths, lock) {
|
|
456
479
|
try {
|
|
457
|
-
const
|
|
458
|
-
if (
|
|
480
|
+
const stat = fs.lstatSync(paths.lockFile);
|
|
481
|
+
if (stat.isFile() &&
|
|
482
|
+
!stat.isSymbolicLink() &&
|
|
483
|
+
stat.ino === lock.ino &&
|
|
484
|
+
stat.dev === lock.dev &&
|
|
485
|
+
fs.readFileSync(paths.lockFile, "utf-8") === lock.content) {
|
|
459
486
|
fs.unlinkSync(paths.lockFile);
|
|
460
487
|
}
|
|
461
488
|
}
|
|
@@ -463,14 +490,21 @@ function releaseProjectLock(paths) {
|
|
|
463
490
|
// Already released or replaced by another process.
|
|
464
491
|
}
|
|
465
492
|
}
|
|
466
|
-
/**
|
|
493
|
+
/** Shared project maintenance boundary; asynchronous operations retain ownership. */
|
|
467
494
|
export function withAblationProjectLock(paths, operation) {
|
|
468
|
-
acquireProjectLock(paths);
|
|
495
|
+
const lock = acquireProjectLock(paths);
|
|
496
|
+
let pending = false;
|
|
469
497
|
try {
|
|
470
|
-
|
|
498
|
+
const result = operation();
|
|
499
|
+
if (result instanceof Promise) {
|
|
500
|
+
pending = true;
|
|
501
|
+
return result.finally(() => releaseProjectLock(paths, lock));
|
|
502
|
+
}
|
|
503
|
+
return result;
|
|
471
504
|
}
|
|
472
505
|
finally {
|
|
473
|
-
|
|
506
|
+
if (!pending)
|
|
507
|
+
releaseProjectLock(paths, lock);
|
|
474
508
|
}
|
|
475
509
|
}
|
|
476
510
|
/** Preflight every affected path before restore writes anything. */
|
|
@@ -693,7 +727,7 @@ export function verifyAblatedState(transaction) {
|
|
|
693
727
|
export function restoreAblationTransaction(transaction, options = {}) {
|
|
694
728
|
const projectRoot = canonicalProjectRoot(transaction.state.projectRoot);
|
|
695
729
|
const paths = getTransactionPaths(projectRoot, transaction.paths.stateRoot);
|
|
696
|
-
acquireProjectLock(paths);
|
|
730
|
+
const lock = acquireProjectLock(paths);
|
|
697
731
|
try {
|
|
698
732
|
const reloaded = loadAblationTransaction(projectRoot, paths.stateRoot);
|
|
699
733
|
if (!reloaded) {
|
|
@@ -717,7 +751,7 @@ export function restoreAblationTransaction(transaction, options = {}) {
|
|
|
717
751
|
deleteAblationTransaction(transaction);
|
|
718
752
|
}
|
|
719
753
|
finally {
|
|
720
|
-
releaseProjectLock(paths);
|
|
754
|
+
releaseProjectLock(paths, lock);
|
|
721
755
|
}
|
|
722
756
|
}
|
|
723
757
|
/** Roll back this process's partial ablation while holding the project lock. */
|