devrites 7.2.8 → 7.3.0
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/CHANGELOG.md +32 -0
- package/README.md +1 -1
- package/docs/candidate-integrity.md +10 -0
- package/docs/cli.md +7 -1
- package/docs/command-map.md +5 -2
- package/docs/engine/commands.md +28 -4
- package/docs/orchestration.md +26 -13
- package/docs/skills.md +5 -0
- package/engine/internal/acceptance/cli.go +27 -26
- package/engine/internal/acceptance/preconditions.go +1 -1
- package/engine/internal/acceptance/run.go +42 -16
- package/engine/internal/acceptance/transcript.go +236 -45
- package/engine/internal/devritespaths/paths.go +16 -3
- package/engine/internal/gate/gate.go +6 -0
- package/engine/internal/lib/candidate.go +20 -7
- package/engine/internal/lib/candidate_coverage.go +2 -19
- package/engine/internal/lib/closeout.go +16 -4
- package/engine/internal/lib/context.go +64 -45
- package/engine/internal/lib/context_io.go +171 -0
- package/engine/internal/lib/detect.go +8 -8
- package/engine/internal/lib/dispatch.go +2 -0
- package/engine/internal/lib/packet.go +37 -7
- package/engine/internal/lib/packet_freeze.go +60 -12
- package/engine/internal/lib/packet_integrity.go +179 -0
- package/engine/internal/lib/perturb.go +3 -3
- package/engine/internal/lib/slicecheck.go +7 -1
- package/engine/internal/lib/taskgraph.go +20 -36
- package/engine/internal/lib/triggers.go +28 -29
- package/engine/internal/lib/workspace_pool.go +330 -0
- package/engine/internal/parallel/cli.go +190 -49
- package/engine/internal/parallel/git.go +47 -14
- package/engine/internal/parallel/landing.go +232 -0
- package/engine/internal/parallel/lease.go +97 -18
- package/engine/internal/parallel/ops.go +312 -155
- package/engine/internal/parallel/pathdisjoint.go +48 -4
- package/engine/internal/parallel/prune.go +133 -0
- package/engine/internal/parallel/repository.go +239 -0
- package/engine/internal/parallel/select.go +64 -42
- package/engine/main.go +2 -1
- package/pack/.claude/agents/devrites-proof-runner.md +16 -9
- package/pack/.claude/skills/devrites-lib/SKILL.md +2 -0
- package/pack/.claude/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/.claude/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/.claude/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/.claude/skills/rite-build/SKILL.md +13 -10
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/.claude/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/.claude/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/.claude/skills/rite-clarify/SKILL.md +2 -2
- package/pack/.claude/skills/rite-converge/SKILL.md +4 -4
- package/pack/.claude/skills/rite-define/SKILL.md +7 -3
- package/pack/.claude/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/.claude/skills/rite-plan/SKILL.md +11 -8
- package/pack/.claude/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/.claude/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/.claude/skills/rite-polish/SKILL.md +3 -3
- package/pack/.claude/skills/rite-prove/SKILL.md +9 -5
- package/pack/.claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/.claude/skills/rite-review/SKILL.md +4 -3
- package/pack/.claude/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/.claude/skills/rite-seal/SKILL.md +1 -1
- package/pack/.claude/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/.claude/skills/rite-ship/SKILL.md +2 -2
- package/pack/.claude/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/.claude/skills/rite-spec/SKILL.md +8 -5
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/.claude/skills/rite-temper/SKILL.md +3 -3
- package/pack/.claude/skills/rite-vet/SKILL.md +9 -5
- package/pack/.claude/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/claude/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/claude/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/claude/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/claude/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/claude/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/claude/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/claude/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/claude/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/claude/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/claude/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/claude/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/claude/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/claude/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/claude/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/claude/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/claude/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/claude/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/codex/agents/devrites-proof-runner.toml +16 -9
- package/pack/generated/codex/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/codex/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/codex/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/codex/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/codex/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/codex/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/codex/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/codex/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/codex/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/codex/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/codex/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/codex/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/codex/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/codex/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/codex/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/codex/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/codex/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/devin/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/devin/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/devin/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/devin/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/devin/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/devin/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/devin/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/devin/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/devin/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/devin/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/devin/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/devin/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/devin/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/devin/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/devin/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/devin/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/devin/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/devin/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/devin/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/devin/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/devin/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/devin/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/devin/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/dsh/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/dsh/runtime/cordis.patch.yml +1 -1
- package/pack/generated/dsh/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/dsh/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/dsh/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/dsh/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/dsh/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/dsh/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/dsh/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/dsh/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/dsh/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/dsh/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/dsh/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/dsh/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/dsh/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/dsh/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/dsh/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/dsh/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/dsh/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/dsh/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/dsh/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/dsh/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/dsh/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/dsh/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/dsh/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/dsh/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/dsh/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/dsh/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/dsh/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/dsh/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/dsh/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/dsh/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/dsh/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/omp/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/omp/commands/rite-build.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/omp/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/omp/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/omp/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/omp/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/omp/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/omp/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/omp/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/omp/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/omp/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/omp/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/omp/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/omp/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/omp/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/omp/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/omp/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/omp/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/omp/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/omp/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/pi/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/pi/prompts/rite-build.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/pi/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/pi/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +57 -36
- package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/pi/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/pi/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/pi/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/pi/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/pi/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/pi/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/pi/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/pi/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/pi/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/pi/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/pi/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/pi/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/pi/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/pi/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +12 -5
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ import (
|
|
|
5
5
|
"fmt"
|
|
6
6
|
"io"
|
|
7
7
|
"os"
|
|
8
|
+
"path/filepath"
|
|
8
9
|
"strconv"
|
|
9
10
|
"strings"
|
|
10
11
|
)
|
|
@@ -79,18 +80,27 @@ func cmdSelect(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
79
80
|
capN := 0
|
|
80
81
|
sawCap := false
|
|
81
82
|
fromPlan := false
|
|
83
|
+
workspaces := ""
|
|
84
|
+
sawWorkspaces, sawInput := false, false
|
|
82
85
|
for i := 0; i < len(args); i++ {
|
|
83
86
|
switch args[i] {
|
|
84
|
-
case "--root", "--slug":
|
|
87
|
+
case "--root", "--slug", "--workspaces":
|
|
85
88
|
if i+1 >= len(args) {
|
|
86
89
|
fmt.Fprintln(stderr, usageSelect)
|
|
87
90
|
return ExitUsage
|
|
88
91
|
}
|
|
89
92
|
i++
|
|
90
|
-
|
|
93
|
+
switch args[i-1] {
|
|
94
|
+
case "--root":
|
|
91
95
|
root = args[i]
|
|
92
|
-
|
|
96
|
+
case "--slug":
|
|
93
97
|
slug = args[i]
|
|
98
|
+
case "--workspaces":
|
|
99
|
+
if sawWorkspaces {
|
|
100
|
+
fmt.Fprintln(stderr, "parallel select: duplicate --workspaces")
|
|
101
|
+
return ExitUsage
|
|
102
|
+
}
|
|
103
|
+
workspaces, sawWorkspaces = args[i], true
|
|
94
104
|
}
|
|
95
105
|
case "--cap":
|
|
96
106
|
if i+1 >= len(args) {
|
|
@@ -116,28 +126,90 @@ func cmdSelect(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
116
126
|
return ExitUsage
|
|
117
127
|
}
|
|
118
128
|
jsonPath = args[i]
|
|
129
|
+
if sawInput {
|
|
130
|
+
fmt.Fprintln(stderr, "parallel select: multiple JSON inputs")
|
|
131
|
+
return ExitUsage
|
|
132
|
+
}
|
|
133
|
+
sawInput = true
|
|
119
134
|
}
|
|
120
135
|
}
|
|
121
|
-
if !sawCap {
|
|
136
|
+
if !sawCap || capN < 1 || capN > MaxParallelSlices {
|
|
122
137
|
fmt.Fprintln(stderr, usageSelect)
|
|
123
138
|
return ExitUsage
|
|
124
139
|
}
|
|
140
|
+
if sawWorkspaces && (!fromPlan || root == "" || slug == "" || sawInput) {
|
|
141
|
+
fmt.Fprintln(stderr, "parallel select: --workspaces requires --from-plan, --root and --slug and takes no JSON input")
|
|
142
|
+
return ExitUsage
|
|
143
|
+
}
|
|
125
144
|
var slices []SlicePaths
|
|
126
145
|
if fromPlan {
|
|
127
|
-
if slug == "" ||
|
|
146
|
+
if slug == "" || sawInput {
|
|
128
147
|
fmt.Fprintln(stderr, "parallel select: --from-plan needs --slug and takes no JSON input")
|
|
129
148
|
return ExitUsage
|
|
130
149
|
}
|
|
131
|
-
if
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
150
|
+
if sawWorkspaces {
|
|
151
|
+
order := []string{slug}
|
|
152
|
+
seen := make(map[string]bool)
|
|
153
|
+
if err := validateSlug(slug); err != nil {
|
|
154
|
+
fmt.Fprintf(stderr, "parallel select: %v\n", err)
|
|
155
|
+
return ExitUsage
|
|
156
|
+
}
|
|
157
|
+
for _, target := range strings.Split(workspaces, ",") {
|
|
158
|
+
if err := validateSlug(target); err != nil || seen[target] {
|
|
159
|
+
fmt.Fprintf(stderr, "parallel select: invalid or duplicate workspace %q\n", target)
|
|
160
|
+
return ExitUsage
|
|
161
|
+
}
|
|
162
|
+
seen[target] = true
|
|
163
|
+
if target != slug {
|
|
164
|
+
order = append(order, target)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if _, err := controllerLease(root, slug); err != nil {
|
|
168
|
+
fmt.Fprintf(stderr, "parallel select: %v\n", err)
|
|
169
|
+
return ExitBlocked
|
|
170
|
+
}
|
|
171
|
+
if WorkspaceReady == nil {
|
|
172
|
+
fmt.Fprintln(stderr, "parallel select: --workspaces is unavailable in this build")
|
|
173
|
+
return ExitBlocked
|
|
174
|
+
}
|
|
175
|
+
for _, target := range order {
|
|
176
|
+
ready, notices, err := WorkspaceReady(root, slug, target)
|
|
177
|
+
for _, notice := range notices {
|
|
178
|
+
fmt.Fprintf(stderr, "parallel select: workspace %s: %s\n", target, notice)
|
|
179
|
+
}
|
|
180
|
+
if err == nil {
|
|
181
|
+
ready, err = normalizeSlices(slug, ready, root)
|
|
182
|
+
}
|
|
183
|
+
if err == nil {
|
|
184
|
+
for _, sp := range ready {
|
|
185
|
+
source := sp.Workspace
|
|
186
|
+
if source == "" {
|
|
187
|
+
source = slug
|
|
188
|
+
}
|
|
189
|
+
if source != target {
|
|
190
|
+
err = fmt.Errorf("candidate source %s does not match requested workspace", source)
|
|
191
|
+
break
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if err != nil {
|
|
196
|
+
fmt.Fprintf(stderr, "parallel select: workspace %s: %v\n", target, err)
|
|
197
|
+
continue
|
|
198
|
+
}
|
|
199
|
+
slices = append(slices, ready...)
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
if PlanReady == nil {
|
|
203
|
+
fmt.Fprintln(stderr, "parallel select: --from-plan is unavailable in this build")
|
|
204
|
+
return ExitBlocked
|
|
205
|
+
}
|
|
206
|
+
ready, err := PlanReady(root, slug)
|
|
207
|
+
if err != nil {
|
|
208
|
+
fmt.Fprintf(stderr, "parallel select: %v\n", err)
|
|
209
|
+
return ExitBlocked
|
|
210
|
+
}
|
|
211
|
+
slices = ready
|
|
139
212
|
}
|
|
140
|
-
slices = ready
|
|
141
213
|
} else {
|
|
142
214
|
data, err := readJSONInput(jsonPath, stdin)
|
|
143
215
|
if err != nil {
|
|
@@ -161,26 +233,6 @@ func cmdSelect(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
161
233
|
return ExitOK
|
|
162
234
|
}
|
|
163
235
|
|
|
164
|
-
// runningLease returns slug's lease when it is still in flight
|
|
165
|
-
// (running|integrate-failed), or nil when there is none to seed from.
|
|
166
|
-
func runningLease(root, slug string) (*Lease, error) {
|
|
167
|
-
path, err := LeasePath(root, slug)
|
|
168
|
-
if err != nil {
|
|
169
|
-
return nil, err
|
|
170
|
-
}
|
|
171
|
-
lease, err := ReadLease(path)
|
|
172
|
-
if os.IsNotExist(err) {
|
|
173
|
-
return nil, nil
|
|
174
|
-
}
|
|
175
|
-
if err != nil {
|
|
176
|
-
return nil, err
|
|
177
|
-
}
|
|
178
|
-
if lease.Status != StatusRunning && lease.Status != StatusIntegrateFailed {
|
|
179
|
-
return nil, nil
|
|
180
|
-
}
|
|
181
|
-
return lease, nil
|
|
182
|
-
}
|
|
183
|
-
|
|
184
236
|
func runParallel(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
185
237
|
if len(args) == 0 {
|
|
186
238
|
fmt.Fprintln(stderr, parallelUsage())
|
|
@@ -200,6 +252,8 @@ func runParallel(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
200
252
|
return cmdIntegrate(rest, stdout, stderr)
|
|
201
253
|
case "cleanup":
|
|
202
254
|
return cmdCleanup(rest, stdout, stderr)
|
|
255
|
+
case "prune":
|
|
256
|
+
return cmdPrune(rest, stdout, stderr)
|
|
203
257
|
case "status":
|
|
204
258
|
return cmdStatus(rest, stdout, stderr)
|
|
205
259
|
case "lease-write":
|
|
@@ -220,35 +274,37 @@ func runParallel(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
220
274
|
}
|
|
221
275
|
|
|
222
276
|
const (
|
|
223
|
-
usageCreate = "usage: parallel create --root --slug --batch --base --json"
|
|
224
|
-
usageAdd = "usage: parallel add --root --slug --json <json-file>|-"
|
|
277
|
+
usageCreate = "usage: parallel create --root --slug --batch --base --json [--cap <1-10>]"
|
|
278
|
+
usageAdd = "usage: parallel add --root --slug --json <json-file>|- [--cap <1-10>]"
|
|
225
279
|
usageRecordGreen = "usage: parallel record-green --root --slug --slice --commit"
|
|
226
280
|
usageAbort = "usage: parallel abort --root --slug"
|
|
227
281
|
usageIntegrate = "usage: parallel integrate --root --slug [--apply-to-control [--slice <id>]]"
|
|
228
282
|
usageCleanup = "usage: parallel cleanup --root --slug [--force]"
|
|
283
|
+
usagePrune = "usage: parallel prune --root --slug"
|
|
229
284
|
usageStatus = "usage: parallel status --root --slug"
|
|
230
285
|
usageLeaseWrite = "usage: parallel lease-write --root --slug --json"
|
|
231
286
|
usageLeaseRead = "usage: parallel lease-read --root --slug [--field name]"
|
|
232
287
|
usageLeaseClear = "usage: parallel lease-clear --root --slug"
|
|
233
288
|
usagePathDisjoint = "usage: check path-disjoint [--root <dir>] [<json-file>|-]"
|
|
234
|
-
usageSelect = "usage: parallel select --cap <1-10> [--root <dir>] [--slug <slug>] [--from-plan | <json-file>|-]"
|
|
289
|
+
usageSelect = "usage: parallel select --cap <1-10> [--root <dir>] [--slug <slug>] [--from-plan [--workspaces <slugs>] | <json-file>|-]"
|
|
235
290
|
)
|
|
236
291
|
|
|
237
292
|
func parallelUsage() string {
|
|
238
293
|
return strings.TrimSpace(`usage: parallel <subcommand> [options]
|
|
239
294
|
|
|
240
295
|
Subcommands:
|
|
241
|
-
create --root --slug --batch --base --json
|
|
242
|
-
add --root --slug --json
|
|
296
|
+
create --root --slug --batch --base --json [--cap <1-10>]
|
|
297
|
+
add --root --slug --json [--cap <1-10>]
|
|
243
298
|
record-green --root --slug --slice --commit
|
|
244
299
|
abort --root --slug
|
|
245
300
|
integrate --root --slug [--apply-to-control [--slice <id>]]
|
|
246
301
|
cleanup --root --slug [--force]
|
|
302
|
+
prune --root --slug
|
|
247
303
|
status --root --slug
|
|
248
304
|
lease-write --root --slug --json
|
|
249
305
|
lease-read --root --slug [--field name]
|
|
250
306
|
lease-clear --root --slug
|
|
251
|
-
select --cap <1-10> [--root] [--slug] [--from-plan | <json-file>|-]
|
|
307
|
+
select --cap <1-10> [--root] [--slug] [--from-plan [--workspaces <slugs>] | <json-file>|-]
|
|
252
308
|
|
|
253
309
|
Exit codes: 0 ok, 2 usage, 3 blocked`)
|
|
254
310
|
}
|
|
@@ -269,6 +325,8 @@ func CommandUsage(name string) string {
|
|
|
269
325
|
return usageIntegrate
|
|
270
326
|
case "cleanup":
|
|
271
327
|
return usageCleanup
|
|
328
|
+
case "prune":
|
|
329
|
+
return usagePrune
|
|
272
330
|
case "status":
|
|
273
331
|
return usageStatus
|
|
274
332
|
case "lease-write":
|
|
@@ -288,7 +346,8 @@ func CommandUsage(name string) string {
|
|
|
288
346
|
|
|
289
347
|
type flagSet struct {
|
|
290
348
|
Root, Slug, Batch, Base, Slice, Commit, JSON, Field, Session string
|
|
291
|
-
ApplyToControl, Force, Help
|
|
349
|
+
ApplyToControl, Force, Help, HasCapacity bool
|
|
350
|
+
Capacity int
|
|
292
351
|
}
|
|
293
352
|
|
|
294
353
|
func parseFlags(args []string, stderr io.Writer) (flagSet, []string, int) {
|
|
@@ -359,6 +418,17 @@ func parseFlags(args []string, stderr io.Writer) (flagSet, []string, int) {
|
|
|
359
418
|
return f, nil, ExitUsage
|
|
360
419
|
}
|
|
361
420
|
f.Session = v
|
|
421
|
+
case "--cap":
|
|
422
|
+
v, ok := need(a)
|
|
423
|
+
if !ok {
|
|
424
|
+
return f, nil, ExitUsage
|
|
425
|
+
}
|
|
426
|
+
n, err := strconv.Atoi(v)
|
|
427
|
+
if err != nil || n < 1 || n > MaxParallelSlices || f.HasCapacity {
|
|
428
|
+
fmt.Fprintf(stderr, "parallel: --cap must be one integer from 1-%d\n", MaxParallelSlices)
|
|
429
|
+
return f, nil, ExitUsage
|
|
430
|
+
}
|
|
431
|
+
f.Capacity, f.HasCapacity = n, true
|
|
362
432
|
case "--apply-to-control":
|
|
363
433
|
f.ApplyToControl = true
|
|
364
434
|
case "--force":
|
|
@@ -386,6 +456,10 @@ func parseFlagsOrHelp(args []string, stdout, stderr io.Writer, usage string) (fl
|
|
|
386
456
|
fmt.Fprintln(stdout, usage)
|
|
387
457
|
return f, ExitOK, true
|
|
388
458
|
}
|
|
459
|
+
if f.HasCapacity && usage != usageCreate && usage != usageAdd {
|
|
460
|
+
fmt.Fprintln(stderr, "parallel: --cap is only supported by create and add")
|
|
461
|
+
return f, ExitUsage, true
|
|
462
|
+
}
|
|
389
463
|
return f, ExitOK, false
|
|
390
464
|
}
|
|
391
465
|
|
|
@@ -450,12 +524,13 @@ func cmdCreate(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
450
524
|
return ExitBlocked
|
|
451
525
|
}
|
|
452
526
|
lease, err := Create(CreateOpts{
|
|
453
|
-
Root:
|
|
454
|
-
Slug:
|
|
455
|
-
BatchID:
|
|
456
|
-
BaseSHA:
|
|
457
|
-
Session:
|
|
458
|
-
Slices:
|
|
527
|
+
Root: f.Root,
|
|
528
|
+
Slug: f.Slug,
|
|
529
|
+
BatchID: f.Batch,
|
|
530
|
+
BaseSHA: f.Base,
|
|
531
|
+
Session: f.Session,
|
|
532
|
+
Slices: slices,
|
|
533
|
+
Capacity: f.Capacity,
|
|
459
534
|
})
|
|
460
535
|
if err != nil {
|
|
461
536
|
fmt.Fprintf(stderr, "parallel create: %v\n", err)
|
|
@@ -490,11 +565,15 @@ func cmdAdd(args []string, stdin io.Reader, stdout, stderr io.Writer) int {
|
|
|
490
565
|
fmt.Fprintf(stderr, "parallel add: %v\n", err)
|
|
491
566
|
return ExitBlocked
|
|
492
567
|
}
|
|
493
|
-
lease, err := Add(AddOpts{Root: f.Root, Slug: f.Slug, Slices: slices})
|
|
568
|
+
lease, err := Add(AddOpts{Root: f.Root, Slug: f.Slug, Slices: slices, Capacity: f.Capacity})
|
|
494
569
|
if err != nil {
|
|
495
570
|
fmt.Fprintf(stderr, "parallel add: %v\n", err)
|
|
496
571
|
return ExitBlocked
|
|
497
572
|
}
|
|
573
|
+
if len(slices) == 0 {
|
|
574
|
+
fmt.Fprintf(stdout, "capacity: %d; batch=%s active=%d\n", leaseCapacity(lease), lease.BatchID, len(activeSlices(lease)))
|
|
575
|
+
return ExitOK
|
|
576
|
+
}
|
|
498
577
|
fmt.Fprintf(stdout, "added: %d worktrees; batch=%s active=%d base=%s\n",
|
|
499
578
|
len(slices), lease.BatchID, len(activeSlices(lease)), lease.Slices[len(lease.Slices)-1].BaseSHA)
|
|
500
579
|
return ExitOK
|
|
@@ -620,6 +699,29 @@ func cmdCleanup(args []string, stdout, stderr io.Writer) int {
|
|
|
620
699
|
return ExitOK
|
|
621
700
|
}
|
|
622
701
|
|
|
702
|
+
func cmdPrune(args []string, stdout, stderr io.Writer) int {
|
|
703
|
+
f, code, done := parseFlagsOrHelp(args, stdout, stderr, usagePrune)
|
|
704
|
+
if done {
|
|
705
|
+
return code
|
|
706
|
+
}
|
|
707
|
+
if code := requireRootSlug(f, stderr); code != ExitOK {
|
|
708
|
+
return code
|
|
709
|
+
}
|
|
710
|
+
if code := rejectUnsupportedFlags(f, stderr, false, false); code != ExitOK {
|
|
711
|
+
return code
|
|
712
|
+
}
|
|
713
|
+
removed, err := Prune(f.Root, f.Slug)
|
|
714
|
+
for _, path := range removed {
|
|
715
|
+
fmt.Fprintf(stdout, "pruned: %s\n", path)
|
|
716
|
+
}
|
|
717
|
+
if err != nil {
|
|
718
|
+
fmt.Fprintf(stderr, "parallel prune: %v\n", err)
|
|
719
|
+
return ExitBlocked
|
|
720
|
+
}
|
|
721
|
+
fmt.Fprintln(stdout, "prune: done; branches and lease retained")
|
|
722
|
+
return ExitOK
|
|
723
|
+
}
|
|
724
|
+
|
|
623
725
|
func cmdStatus(args []string, stdout, stderr io.Writer) int {
|
|
624
726
|
f, code, done := parseFlagsOrHelp(args, stdout, stderr, usageStatus)
|
|
625
727
|
if done {
|
|
@@ -673,7 +775,40 @@ func cmdLeaseWrite(args []string, stdin io.Reader, stdout, stderr io.Writer) int
|
|
|
673
775
|
fmt.Fprintf(stderr, "parallel lease-write: %v\n", err)
|
|
674
776
|
return ExitUsage
|
|
675
777
|
}
|
|
676
|
-
err = withLeaseLock(f.Root, f.Slug, func() error {
|
|
778
|
+
err = withLeaseLock(f.Root, f.Slug, func() error {
|
|
779
|
+
found, err := controllerLease(f.Root, f.Slug)
|
|
780
|
+
if err != nil {
|
|
781
|
+
return err
|
|
782
|
+
}
|
|
783
|
+
var current *Lease
|
|
784
|
+
if found != nil {
|
|
785
|
+
current = found.lease
|
|
786
|
+
if lease.BatchID != current.BatchID || lease.BaseSHA != current.BaseSHA || expectedControl(&lease) != expectedControl(current) {
|
|
787
|
+
return fmt.Errorf("lease-write cannot replace retained batch or control tip; cleanup the current controller explicitly")
|
|
788
|
+
}
|
|
789
|
+
if lease.Capacity == 0 {
|
|
790
|
+
lease.Capacity = current.Capacity
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if err := normalizeLease(&lease, f.Slug); err != nil {
|
|
794
|
+
return err
|
|
795
|
+
}
|
|
796
|
+
if err := protectRawLease(current, &lease); err != nil {
|
|
797
|
+
return err
|
|
798
|
+
}
|
|
799
|
+
if current != nil {
|
|
800
|
+
if err := ensureControllerIdentity(f.Root, current); err != nil {
|
|
801
|
+
return err
|
|
802
|
+
}
|
|
803
|
+
if current.PendingLanding != nil {
|
|
804
|
+
return nil
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if err := validateLeaseSources(filepath.Join(f.Root, ".devrites"), &lease); err != nil {
|
|
808
|
+
return err
|
|
809
|
+
}
|
|
810
|
+
return WriteLease(path, &lease)
|
|
811
|
+
})
|
|
677
812
|
if err != nil {
|
|
678
813
|
fmt.Fprintf(stderr, "parallel lease-write: %v\n", err)
|
|
679
814
|
return ExitBlocked
|
|
@@ -703,6 +838,10 @@ func cmdLeaseRead(args []string, stdout, stderr io.Writer) int {
|
|
|
703
838
|
fmt.Fprintf(stderr, "parallel lease-read: %v\n", err)
|
|
704
839
|
return ExitBlocked
|
|
705
840
|
}
|
|
841
|
+
if err := normalizeLease(lease, f.Slug); err != nil {
|
|
842
|
+
fmt.Fprintf(stderr, "parallel lease-read: %v\n", err)
|
|
843
|
+
return ExitBlocked
|
|
844
|
+
}
|
|
706
845
|
switch f.Field {
|
|
707
846
|
case "", "yaml", "md":
|
|
708
847
|
text, err := EmitLeaseMarkdown(lease)
|
|
@@ -726,6 +865,8 @@ func cmdLeaseRead(args []string, stdout, stderr io.Writer) int {
|
|
|
726
865
|
fmt.Fprintln(stdout, lease.BatchID)
|
|
727
866
|
case "n":
|
|
728
867
|
fmt.Fprintln(stdout, lease.N)
|
|
868
|
+
case "capacity":
|
|
869
|
+
fmt.Fprintln(stdout, leaseCapacity(lease))
|
|
729
870
|
default:
|
|
730
871
|
fmt.Fprintf(stderr, "parallel lease-read: unknown field %q\n", f.Field)
|
|
731
872
|
return ExitUsage
|
|
@@ -192,12 +192,30 @@ func deleteBranch(repo, branch string) error {
|
|
|
192
192
|
if err != nil || !exists {
|
|
193
193
|
return err
|
|
194
194
|
}
|
|
195
|
-
|
|
195
|
+
tip, err := revParse(repo, "refs/heads/"+branch)
|
|
196
|
+
if err != nil {
|
|
197
|
+
return err
|
|
198
|
+
}
|
|
199
|
+
return deleteBranchAt(repo, branch, tip)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Bind deletion to the observed tip without bypassing checked-out branch safety.
|
|
203
|
+
func deleteBranchAt(repo, branch, tip string) error {
|
|
204
|
+
worktrees, err := git(repo, "worktree", "list", "--porcelain", "-z")
|
|
205
|
+
if err != nil {
|
|
206
|
+
return err
|
|
207
|
+
}
|
|
208
|
+
for _, field := range strings.Split(worktrees, "\x00") {
|
|
209
|
+
if field == "branch refs/heads/"+branch {
|
|
210
|
+
return fmt.Errorf("branch %s remains checked out in a registered worktree", branch)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
_, err = git(repo, "update-ref", "-d", "refs/heads/"+branch, tip)
|
|
196
214
|
return err
|
|
197
215
|
}
|
|
198
216
|
|
|
199
217
|
func worktreeAdd(repo, path, branch, startPoint string) error {
|
|
200
|
-
_, err := git(repo, "worktree", "add", "-b", branch, path, startPoint)
|
|
218
|
+
_, err := git(repo, "worktree", "add", "-b", branch, resolvedPath(path), startPoint)
|
|
201
219
|
return err
|
|
202
220
|
}
|
|
203
221
|
|
|
@@ -208,27 +226,27 @@ func AddDetachedWorktree(repo, path, rev string) error {
|
|
|
208
226
|
return err
|
|
209
227
|
}
|
|
210
228
|
|
|
211
|
-
// RemoveWorktree force-removes a
|
|
212
|
-
|
|
229
|
+
// RemoveWorktree force-removes a caller-owned throwaway worktree. A Git
|
|
230
|
+
// refusal never grants permission to recursively delete its remaining data.
|
|
231
|
+
func RemoveWorktree(repo, path string) error {
|
|
232
|
+
_, err := git(repo, "worktree", "remove", "--force", resolvedPath(path))
|
|
233
|
+
return err
|
|
234
|
+
}
|
|
213
235
|
|
|
214
236
|
func worktreeRemove(repo, path string) error {
|
|
215
|
-
_, err := git(repo, "worktree", "remove",
|
|
216
|
-
if err != nil {
|
|
217
|
-
_ = os.RemoveAll(path)
|
|
218
|
-
_, _ = git(repo, "worktree", "prune")
|
|
219
|
-
}
|
|
237
|
+
_, err := git(repo, "worktree", "remove", resolvedPath(path))
|
|
220
238
|
return err
|
|
221
239
|
}
|
|
222
240
|
|
|
223
241
|
// registeredWorktrees returns the symlink-resolved paths git lists as
|
|
224
242
|
// worktrees of repo: the only authoritative record of what worktree add made.
|
|
225
243
|
func registeredWorktrees(repo string) (map[string]bool, error) {
|
|
226
|
-
out, err := git(repo, "worktree", "list", "--porcelain")
|
|
244
|
+
out, err := git(repo, "worktree", "list", "--porcelain", "-z")
|
|
227
245
|
if err != nil {
|
|
228
246
|
return nil, err
|
|
229
247
|
}
|
|
230
248
|
set := map[string]bool{}
|
|
231
|
-
for _, line := range strings.Split(out, "\
|
|
249
|
+
for _, line := range strings.Split(out, "\x00") {
|
|
232
250
|
if p, ok := strings.CutPrefix(line, "worktree "); ok {
|
|
233
251
|
set[resolvedPath(p)] = true
|
|
234
252
|
}
|
|
@@ -240,10 +258,25 @@ func registeredWorktrees(repo string) (map[string]bool, error) {
|
|
|
240
258
|
func RegisteredWorktrees(repo string) (map[string]bool, error) { return registeredWorktrees(repo) }
|
|
241
259
|
|
|
242
260
|
func resolvedPath(p string) string {
|
|
243
|
-
if
|
|
244
|
-
|
|
261
|
+
if abs, err := filepath.Abs(p); err == nil {
|
|
262
|
+
p = abs
|
|
263
|
+
}
|
|
264
|
+
original := filepath.Clean(p)
|
|
265
|
+
prefix, suffix := original, ""
|
|
266
|
+
for {
|
|
267
|
+
if resolved, err := filepath.EvalSymlinks(prefix); err == nil {
|
|
268
|
+
return filepath.Join(resolved, suffix)
|
|
269
|
+
} else if !os.IsNotExist(err) {
|
|
270
|
+
return original
|
|
271
|
+
}
|
|
272
|
+
parent := filepath.Dir(prefix)
|
|
273
|
+
if parent == prefix {
|
|
274
|
+
return original
|
|
275
|
+
}
|
|
276
|
+
// Missing leaves must retain their existing ancestors' canonical identity.
|
|
277
|
+
suffix = filepath.Join(filepath.Base(prefix), suffix)
|
|
278
|
+
prefix = parent
|
|
245
279
|
}
|
|
246
|
-
return filepath.Clean(p)
|
|
247
280
|
}
|
|
248
281
|
|
|
249
282
|
// createdWorktree reports whether p is a registered worktree. A path that is
|