dorfl 0.1.0 → 0.1.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/dist/advance-ci-template.d.ts +3 -3
- package/dist/advance-ci-template.js +1 -1
- package/dist/advance-ci-template.js.map +1 -1
- package/dist/advance-classify.d.ts +5 -5
- package/dist/advance-classify.d.ts.map +1 -1
- package/dist/advance-classify.js +4 -4
- package/dist/advance-drivers.d.ts +7 -7
- package/dist/advance-drivers.d.ts.map +1 -1
- package/dist/advance-drivers.js +5 -5
- package/dist/advance-drivers.js.map +1 -1
- package/dist/advance-isolated.d.ts +3 -3
- package/dist/advance-isolated.d.ts.map +1 -1
- package/dist/advance-isolated.js +1 -1
- package/dist/advance-lifecycle-template.d.ts +2 -2
- package/dist/advance-lifecycle-template.js +9 -9
- package/dist/advance-lifecycle-template.js.map +1 -1
- package/dist/advance-loop-driver.d.ts +3 -3
- package/dist/advance-loop-driver.d.ts.map +1 -1
- package/dist/advance-loop-driver.js +1 -1
- package/dist/advance-treeless-publish.d.ts +1 -1
- package/dist/advance.d.ts +11 -11
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +21 -21
- package/dist/advance.js.map +1 -1
- package/dist/advancing-lock.d.ts +1 -1
- package/dist/advancing-lock.js +5 -5
- package/dist/apply-decide.d.ts +2 -2
- package/dist/apply-decide.js +2 -2
- package/dist/apply-merge-action.d.ts +4 -4
- package/dist/apply-merge-action.js +2 -2
- package/dist/apply-persist.d.ts +5 -5
- package/dist/apply-persist.d.ts.map +1 -1
- package/dist/apply-persist.js +7 -7
- package/dist/apply-persist.js.map +1 -1
- package/dist/buildable-body.d.ts +14 -14
- package/dist/buildable-body.js +9 -9
- package/dist/claim-cas.d.ts +3 -3
- package/dist/claim-cas.js +1 -1
- package/dist/claim-cas.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +83 -77
- package/dist/cli.js.map +1 -1
- package/dist/close-job-template.d.ts +3 -3
- package/dist/close-job-template.js +8 -8
- package/dist/close-job.d.ts +8 -8
- package/dist/close-job.js +25 -25
- package/dist/close-job.js.map +1 -1
- package/dist/complete.d.ts +3 -3
- package/dist/complete.js +8 -8
- package/dist/complete.js.map +1 -1
- package/dist/concurrency.d.ts +1 -1
- package/dist/concurrency.js +1 -1
- package/dist/config.d.ts +32 -32
- package/dist/config.js +5 -5
- package/dist/config.js.map +1 -1
- package/dist/continue-branch.d.ts +1 -1
- package/dist/continue-branch.js +1 -1
- package/dist/cwd-section.js +1 -1
- package/dist/cwd-section.js.map +1 -1
- package/dist/decision-engine.d.ts +2 -2
- package/dist/do-autopick.d.ts +6 -6
- package/dist/do-autopick.d.ts.map +1 -1
- package/dist/do-autopick.js +5 -5
- package/dist/do-autopick.js.map +1 -1
- package/dist/do-config.d.ts +3 -3
- package/dist/do-config.js +3 -3
- package/dist/do-config.js.map +1 -1
- package/dist/do-remote-auto.d.ts +2 -2
- package/dist/do-remote-auto.js +1 -1
- package/dist/do.d.ts +25 -25
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +22 -22
- package/dist/do.js.map +1 -1
- package/dist/drop-source.d.ts +2 -2
- package/dist/env-config.js +8 -8
- package/dist/env-config.js.map +1 -1
- package/dist/format.js +3 -3
- package/dist/format.js.map +1 -1
- package/dist/frontmatter.d.ts +33 -39
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +18 -31
- package/dist/frontmatter.js.map +1 -1
- package/dist/install-ci-branch-protection.d.ts +1 -1
- package/dist/install-ci-branch-protection.js +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.d.ts +1 -1
- package/dist/install-ci-capabilities/advance-lifecycle.js +1 -1
- package/dist/install-ci-capabilities/close-job.d.ts +1 -1
- package/dist/install-ci-capabilities/close-job.js +1 -1
- package/dist/install-ci-capabilities/example-noop.d.ts +1 -1
- package/dist/install-ci-capabilities/example-noop.js +1 -1
- package/dist/install-ci-capabilities/intake.d.ts +2 -2
- package/dist/install-ci-capabilities/intake.js +2 -2
- package/dist/install-ci-capabilities/verify.d.ts +1 -1
- package/dist/install-ci-capabilities/verify.js +1 -1
- package/dist/install-ci-core.d.ts +3 -3
- package/dist/install-ci-core.js +2 -2
- package/dist/install-ci-core.js.map +1 -1
- package/dist/install-ci-github.d.ts +1 -1
- package/dist/install-ci-github.js +1 -1
- package/dist/install-ci.d.ts +1 -1
- package/dist/install-ci.js +4 -4
- package/dist/install-ci.js.map +1 -1
- package/dist/intake-event.d.ts +6 -6
- package/dist/intake-event.js +6 -6
- package/dist/intake-marker.d.ts +3 -3
- package/dist/intake-marker.d.ts.map +1 -1
- package/dist/intake-triage.d.ts +1 -1
- package/dist/intake-triage.js +2 -2
- package/dist/intake-trigger-template.d.ts +8 -8
- package/dist/intake-trigger-template.d.ts.map +1 -1
- package/dist/intake-trigger-template.js +16 -16
- package/dist/intake-trigger-template.js.map +1 -1
- package/dist/intake.d.ts +50 -50
- package/dist/intake.d.ts.map +1 -1
- package/dist/intake.js +70 -70
- package/dist/intake.js.map +1 -1
- package/dist/integration-core.d.ts +17 -17
- package/dist/integration-core.js +17 -17
- package/dist/integration-core.js.map +1 -1
- package/dist/isolation.d.ts +3 -3
- package/dist/issue-provider.d.ts +4 -4
- package/dist/issue-provider.js +1 -1
- package/dist/item-lock.d.ts +21 -21
- package/dist/item-lock.d.ts.map +1 -1
- package/dist/item-lock.js +16 -16
- package/dist/item-path.d.ts +2 -2
- package/dist/item-path.js +2 -2
- package/dist/ledger-lint.d.ts +9 -9
- package/dist/ledger-lint.js +9 -9
- package/dist/ledger-read.d.ts +57 -57
- package/dist/ledger-read.d.ts.map +1 -1
- package/dist/ledger-read.js +24 -24
- package/dist/ledger-read.js.map +1 -1
- package/dist/ledger-write.d.ts +2 -2
- package/dist/ledger-write.js +1 -1
- package/dist/lifecycle-gather.d.ts +1 -1
- package/dist/lifecycle-gather.js +16 -16
- package/dist/lifecycle-gather.js.map +1 -1
- package/dist/lifecycle-pools.d.ts +4 -4
- package/dist/lifecycle-pools.js +1 -1
- package/dist/merge-question-surfacer.d.ts +3 -3
- package/dist/merge-question-surfacer.js +2 -2
- package/dist/merge-question-surfacer.js.map +1 -1
- package/dist/mint-adr.js +4 -4
- package/dist/mirror-pool-scan.d.ts +2 -2
- package/dist/mirror-pool-scan.js +3 -3
- package/dist/mirror-pool-scan.js.map +1 -1
- package/dist/needs-attention.d.ts +13 -13
- package/dist/needs-attention.d.ts.map +1 -1
- package/dist/needs-attention.js +11 -11
- package/dist/needs-attention.js.map +1 -1
- package/dist/orphan-sidecar.d.ts +2 -2
- package/dist/placement.d.ts +6 -6
- package/dist/placement.js +2 -2
- package/dist/prd-to-spec.d.ts +15 -1
- package/dist/prd-to-spec.d.ts.map +1 -1
- package/dist/prd-to-spec.js +36 -14
- package/dist/prd-to-spec.js.map +1 -1
- package/dist/prompt.d.ts +24 -24
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +29 -31
- package/dist/prompt.js.map +1 -1
- package/dist/protocol/CLAIM-PROTOCOL.md +4 -4
- package/dist/protocol/REVIEW-PROTOCOL.md +1 -1
- package/dist/protocol/TASKING-PROTOCOL.md +12 -12
- package/dist/protocol/WORK-CONTRACT.md +39 -39
- package/dist/protocol/spec-template.md +1 -1
- package/dist/protocol/task-template.md +3 -3
- package/dist/readiness.d.ts +1 -1
- package/dist/recover-isolated.js +1 -1
- package/dist/repo-config.js +12 -12
- package/dist/repo-config.js.map +1 -1
- package/dist/review-gate.d.ts +3 -3
- package/dist/review-gate.d.ts.map +1 -1
- package/dist/review-gate.js +11 -10
- package/dist/review-gate.js.map +1 -1
- package/dist/review-verdict.d.ts +2 -2
- package/dist/review-verdict.d.ts.map +1 -1
- package/dist/review-verdict.js +1 -1
- package/dist/run.d.ts +1 -1
- package/dist/run.js +5 -5
- package/dist/run.js.map +1 -1
- package/dist/scan.d.ts +10 -10
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +8 -8
- package/dist/scan.js.map +1 -1
- package/dist/select-order.d.ts +1 -1
- package/dist/select-priority.d.ts +12 -12
- package/dist/select-priority.d.ts.map +1 -1
- package/dist/select-priority.js +5 -5
- package/dist/select-priority.js.map +1 -1
- package/dist/sidecar.d.ts +2 -2
- package/dist/sidecar.js +2 -2
- package/dist/sidecar.js.map +1 -1
- package/dist/slug-namespace.d.ts +1 -1
- package/dist/slug-namespace.js +3 -3
- package/dist/slug-namespace.js.map +1 -1
- package/dist/spec-complete.js +2 -2
- package/dist/spec-complete.js.map +1 -1
- package/dist/start.d.ts +1 -1
- package/dist/start.js +3 -3
- package/dist/start.js.map +1 -1
- package/dist/status.d.ts +3 -3
- package/dist/status.js +4 -4
- package/dist/status.js.map +1 -1
- package/dist/surface-gate.d.ts +2 -2
- package/dist/surface-gate.d.ts.map +1 -1
- package/dist/surface-persist.d.ts +2 -2
- package/dist/surface-persist.d.ts.map +1 -1
- package/dist/tasker-review-loop.d.ts +8 -8
- package/dist/tasker-review-loop.d.ts.map +1 -1
- package/dist/tasker-review-loop.js +8 -8
- package/dist/tasker-review-loop.js.map +1 -1
- package/dist/tasking-eligibility.d.ts +21 -21
- package/dist/tasking-eligibility.d.ts.map +1 -1
- package/dist/tasking-eligibility.js +10 -10
- package/dist/tasking-lock.d.ts +8 -8
- package/dist/tasking-lock.d.ts.map +1 -1
- package/dist/tasking-lock.js +20 -21
- package/dist/tasking-lock.js.map +1 -1
- package/dist/tasking.d.ts +33 -33
- package/dist/tasking.d.ts.map +1 -1
- package/dist/tasking.js +89 -88
- package/dist/tasking.js.map +1 -1
- package/dist/triage-gate.d.ts +1 -1
- package/dist/triage-persist.d.ts +5 -5
- package/dist/triage-persist.js +15 -15
- package/dist/triage-persist.js.map +1 -1
- package/dist/verify-workflow-template.d.ts +1 -1
- package/dist/verify-workflow-template.js +2 -2
- package/dist/work-layout.d.ts +9 -7
- package/dist/work-layout.d.ts.map +1 -1
- package/dist/work-layout.js +9 -7
- package/dist/work-layout.js.map +1 -1
- package/dist/workspace.d.ts +1 -1
- package/package.json +1 -1
- package/src/advance-ci-template.ts +4 -4
- package/src/advance-classify.ts +5 -5
- package/src/advance-drivers.ts +10 -10
- package/src/advance-isolated.ts +3 -3
- package/src/advance-lifecycle-template.ts +9 -9
- package/src/advance-loop-driver.ts +3 -3
- package/src/advance-treeless-publish.ts +1 -1
- package/src/advance.ts +30 -30
- package/src/advancing-lock.ts +6 -6
- package/src/apply-decide.ts +2 -2
- package/src/apply-merge-action.ts +5 -5
- package/src/apply-persist.ts +8 -8
- package/src/buildable-body.ts +14 -14
- package/src/claim-cas.ts +4 -4
- package/src/cli.ts +94 -84
- package/src/close-job-template.ts +8 -8
- package/src/close-job.ts +26 -26
- package/src/complete.ts +11 -11
- package/src/concurrency.ts +1 -1
- package/src/config.ts +37 -37
- package/src/continue-branch.ts +1 -1
- package/src/cwd-section.ts +1 -1
- package/src/decision-engine.ts +3 -3
- package/src/do-autopick.ts +9 -9
- package/src/do-config.ts +6 -6
- package/src/do-remote-auto.ts +2 -2
- package/src/do.ts +49 -49
- package/src/drop-source.ts +2 -2
- package/src/env-config.ts +8 -8
- package/src/format.ts +3 -3
- package/src/frontmatter.ts +42 -60
- package/src/install-ci-branch-protection.ts +1 -1
- package/src/install-ci-capabilities/advance-lifecycle.ts +1 -1
- package/src/install-ci-capabilities/close-job.ts +1 -1
- package/src/install-ci-capabilities/example-noop.ts +1 -1
- package/src/install-ci-capabilities/intake.ts +2 -2
- package/src/install-ci-capabilities/verify.ts +1 -1
- package/src/install-ci-core.ts +4 -4
- package/src/install-ci-github.ts +1 -1
- package/src/install-ci.ts +4 -4
- package/src/intake-event.ts +6 -6
- package/src/intake-marker.ts +3 -3
- package/src/intake-triage.ts +2 -2
- package/src/intake-trigger-template.ts +17 -17
- package/src/intake.ts +97 -97
- package/src/integration-core.ts +35 -35
- package/src/isolation.ts +3 -3
- package/src/issue-provider.ts +4 -4
- package/src/item-lock.ts +21 -21
- package/src/item-path.ts +2 -2
- package/src/ledger-lint.ts +9 -9
- package/src/ledger-read.ts +81 -81
- package/src/ledger-write.ts +3 -3
- package/src/lifecycle-gather.ts +16 -16
- package/src/lifecycle-pools.ts +4 -4
- package/src/merge-question-surfacer.ts +4 -4
- package/src/mint-adr.ts +4 -4
- package/src/mirror-pool-scan.ts +5 -5
- package/src/needs-attention.ts +22 -22
- package/src/orphan-sidecar.ts +2 -2
- package/src/placement.ts +6 -6
- package/src/prd-to-spec.ts +51 -15
- package/src/prompt.ts +33 -35
- package/src/readiness.ts +1 -1
- package/src/recover-isolated.ts +1 -1
- package/src/repo-config.ts +12 -12
- package/src/review-gate.ts +12 -11
- package/src/review-verdict.ts +2 -2
- package/src/run.ts +6 -6
- package/src/scan.ts +15 -15
- package/src/select-order.ts +1 -1
- package/src/select-priority.ts +13 -13
- package/src/sidecar.ts +3 -3
- package/src/slug-namespace.ts +3 -3
- package/src/spec-complete.ts +2 -2
- package/src/start.ts +4 -4
- package/src/status.ts +7 -7
- package/src/surface-gate.ts +2 -2
- package/src/surface-persist.ts +2 -2
- package/src/tasker-review-loop.ts +15 -15
- package/src/tasking-eligibility.ts +21 -21
- package/src/tasking-lock.ts +27 -28
- package/src/tasking.ts +124 -123
- package/src/triage-gate.ts +1 -1
- package/src/triage-persist.ts +16 -16
- package/src/verify-workflow-template.ts +2 -2
- package/src/work-layout.ts +9 -7
- package/src/workspace.ts +1 -1
package/src/cli.ts
CHANGED
|
@@ -353,10 +353,10 @@ function buildRegistrySetAdvanceTick(options: {
|
|
|
353
353
|
lifecycleGates: {
|
|
354
354
|
triage: config.observationTriage !== 'off',
|
|
355
355
|
surface: config.surfaceBlockers,
|
|
356
|
-
// `surfaceStaging` widens the SURFACE candidate set into STAGING (
|
|
356
|
+
// `surfaceStaging` widens the SURFACE candidate set into STAGING (spec
|
|
357
357
|
// `staging-surface-and-apply-promote-safety` F2). Default `true` — a
|
|
358
|
-
// tasked `needsAnswers` task in `tasks/backlog/` (or
|
|
359
|
-
// `
|
|
358
|
+
// tasked `needsAnswers` task in `tasks/backlog/` (or spec in
|
|
359
|
+
// `specs/proposed/`) surfaces its questions BEFORE promotion. BUILD/claim
|
|
360
360
|
// stays pool-only either way.
|
|
361
361
|
surfaceStaging: config.surfaceStaging,
|
|
362
362
|
},
|
|
@@ -388,10 +388,10 @@ function buildRegistrySetAdvanceTick(options: {
|
|
|
388
388
|
identity: config.identity,
|
|
389
389
|
autoTask: config.autoTask,
|
|
390
390
|
integration: config.integration,
|
|
391
|
-
// The per-TRANSITION TASKING override: the `do
|
|
391
|
+
// The per-TRANSITION TASKING override: the `do spec:` tasking path threads
|
|
392
392
|
// `taskingIntegration ?? integration`; the build path stays on `integration`.
|
|
393
393
|
taskingIntegration: config.taskingIntegration,
|
|
394
|
-
// The TASK-PLACEMENT configured default (`do
|
|
394
|
+
// The TASK-PLACEMENT configured default (`do spec:` tasking output:
|
|
395
395
|
// `pre-backlog` staged vs `ready` pool). No operator flag on this
|
|
396
396
|
// registry-driven advance context, so only the configured default rung is
|
|
397
397
|
// threaded (the resolver still layers untrusted-origin force + built-in floor).
|
|
@@ -400,7 +400,7 @@ function buildRegistrySetAdvanceTick(options: {
|
|
|
400
400
|
verify: config.verify,
|
|
401
401
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
402
402
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
403
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
403
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
404
404
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — resolved per-repo
|
|
405
405
|
// and threaded so the registry-driven advance path's `do` inherits it.
|
|
406
406
|
mergeRetries: config.mergeRetries,
|
|
@@ -439,7 +439,7 @@ function buildRegistrySetAdvanceTick(options: {
|
|
|
439
439
|
triageGate: harnessTriageGate({harness, agentCmd: config.agentCmd}),
|
|
440
440
|
triageModel: config.model,
|
|
441
441
|
// The ANSWERED-MERGE LAND DISPATCH context (task
|
|
442
|
-
// `apply-rung-merge-disposition`,
|
|
442
|
+
// `apply-rung-merge-disposition`, spec `land-time-reverify-and-parallel-
|
|
443
443
|
// merge-ceiling`): the dispatcher cuts a per-job worktree via
|
|
444
444
|
// `workspace.ts` `createJob` off the hub mirror (so we thread the resolved
|
|
445
445
|
// `workspacesDir` + the real arbiter URL — the per-mirror tree-less
|
|
@@ -544,7 +544,7 @@ interface RunFlags extends ScanFlags {
|
|
|
544
544
|
reviewMaxRounds?: string;
|
|
545
545
|
/** `--fresh-worktree-gate` / `--no-fresh-worktree-gate` — gate the REBASED tip in a clean throwaway worktree (ON by default). */
|
|
546
546
|
freshWorktreeGate?: boolean;
|
|
547
|
-
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (
|
|
547
|
+
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). */
|
|
548
548
|
mergeRetries?: string;
|
|
549
549
|
}
|
|
550
550
|
|
|
@@ -583,7 +583,7 @@ function runFlagOverrides(flags: RunFlags, command?: Commander): PartialConfig {
|
|
|
583
583
|
// fleet conditional lives in `runOnce`, not in this flag mapping).
|
|
584
584
|
Object.assign(overrides, freshWorktreeGateFlagOverrides(flags));
|
|
585
585
|
// `--merge-retries <n>` rides the SAME chain: the cross-job merge-serialiser
|
|
586
|
-
// CAS-retry cap (
|
|
586
|
+
// CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5 /
|
|
587
587
|
// Applied Answer q1 (a)). The `run` fleet inherits the resolved cap through
|
|
588
588
|
// the converged `performIntegration` core (config.mergeRetries threads into
|
|
589
589
|
// the merge loop, replacing the bare `DEFAULT_MERGE_RETRIES` fallback).
|
|
@@ -661,7 +661,7 @@ interface CompleteFlags {
|
|
|
661
661
|
reviewMaxRounds?: string;
|
|
662
662
|
/** `--fresh-worktree-gate` / `--no-fresh-worktree-gate` — gate the REBASED tip in a clean throwaway worktree (ON by default). */
|
|
663
663
|
freshWorktreeGate?: boolean;
|
|
664
|
-
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (
|
|
664
|
+
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). */
|
|
665
665
|
mergeRetries?: string;
|
|
666
666
|
/** `--isolated`: finish the slug's retained job worktree (the stranded-branch recover). */
|
|
667
667
|
isolated?: boolean;
|
|
@@ -670,7 +670,7 @@ interface CompleteFlags {
|
|
|
670
670
|
|
|
671
671
|
/**
|
|
672
672
|
* Resolve the EXPLICIT operator placement override from `--tasks-land-in <where>`
|
|
673
|
-
* (the top of the `do
|
|
673
|
+
* (the top of the `do spec:` tasking-placement precedence — task
|
|
674
674
|
* `runner-deterministic-slice-placement-policy-and-precedence`). Mirrors the
|
|
675
675
|
* `flagMode === 'merge'` ⇒ `explicitMerge: true` shape: it contributes
|
|
676
676
|
* `explicitTasksLandIn` ONLY when the operator actually typed the flag, so an
|
|
@@ -742,7 +742,7 @@ interface DoFlags {
|
|
|
742
742
|
strictMergeApproval?: boolean;
|
|
743
743
|
merge?: boolean;
|
|
744
744
|
propose?: boolean;
|
|
745
|
-
/** `--tasks-land-in <pre-backlog|ready>`: the explicit operator placement override for `do
|
|
745
|
+
/** `--tasks-land-in <pre-backlog|ready>`: the explicit operator placement override for `do spec:` tasking output (top of the placement precedence). Resolves into the `tasksLandIn` config key. */
|
|
746
746
|
tasksLandIn?: string;
|
|
747
747
|
/** `--no-pr` ⇒ commander stores `pr === false` (the suppress-PR intent). */
|
|
748
748
|
pr?: boolean;
|
|
@@ -758,15 +758,15 @@ interface DoFlags {
|
|
|
758
758
|
review?: boolean;
|
|
759
759
|
reviewModel?: string;
|
|
760
760
|
reviewMaxRounds?: string;
|
|
761
|
-
/** `--tasker-loop` / `--no-tasker-loop` — the tasker improver loop on/off toggle (`do
|
|
761
|
+
/** `--tasker-loop` / `--no-tasker-loop` — the tasker improver loop on/off toggle (`do spec:` path). Resolves into the `taskerLoop` config key. */
|
|
762
762
|
taskerLoop?: boolean;
|
|
763
|
-
/** `--tasker-loop-max <n>` — the tasker improver loop's in-context convergence cap (`do
|
|
763
|
+
/** `--tasker-loop-max <n>` — the tasker improver loop's in-context convergence cap (`do spec:` path). Resolves into the `taskerLoopMax` config key. */
|
|
764
764
|
taskerLoopMax?: string;
|
|
765
|
-
/** `--tasker-loop-model <id>` — the tasker improver loop reviewer's de-correlated model (`do
|
|
765
|
+
/** `--tasker-loop-model <id>` — the tasker improver loop reviewer's de-correlated model (`do spec:` path). Resolves into the `taskerLoopModel` config key. */
|
|
766
766
|
taskerLoopModel?: string;
|
|
767
767
|
/** `--fresh-worktree-gate` / `--no-fresh-worktree-gate` — gate the REBASED tip in a clean throwaway worktree (ON by default). */
|
|
768
768
|
freshWorktreeGate?: boolean;
|
|
769
|
-
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (
|
|
769
|
+
/** `--merge-retries <n>` — the cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)). */
|
|
770
770
|
mergeRetries?: string;
|
|
771
771
|
}
|
|
772
772
|
|
|
@@ -844,11 +844,21 @@ function printPrdToSpecReport(result: PrdToSpecResult): void {
|
|
|
844
844
|
);
|
|
845
845
|
|
|
846
846
|
if (result.resync) {
|
|
847
|
-
const changed = result.resync.docs.filter(
|
|
847
|
+
const changed = result.resync.docs.filter(
|
|
848
|
+
(d) => !d.unchanged && !d.skipped,
|
|
849
|
+
).length;
|
|
848
850
|
console.log(
|
|
849
851
|
`Contract re-sync: ${verb} sync ${result.resync.docs.length} protocol ` +
|
|
850
852
|
`doc(s) (${changed} changed) + bump ${result.resync.versionPath}.`,
|
|
851
853
|
);
|
|
854
|
+
// Surface any doc whose SOURCE could not be resolved LOUDLY: it was NOT
|
|
855
|
+
// copied, so the contract in the target repo is incomplete for that doc.
|
|
856
|
+
for (const skipped of result.resync.docs.filter((d) => d.skipped)) {
|
|
857
|
+
console.warn(
|
|
858
|
+
` !! ${skipped.name}: SOURCE could not be resolved — NOT copied ` +
|
|
859
|
+
`(the contract doc is missing/unchanged in the target repo).`,
|
|
860
|
+
);
|
|
861
|
+
}
|
|
852
862
|
}
|
|
853
863
|
console.log(`Folders: ${verb} move ${result.folderMoves.length} folder(s).`);
|
|
854
864
|
for (const m of result.folderMoves) {
|
|
@@ -876,7 +886,7 @@ function printPrdToSpecReport(result: PrdToSpecResult): void {
|
|
|
876
886
|
return;
|
|
877
887
|
}
|
|
878
888
|
if (result.leaks.length === 0) {
|
|
879
|
-
console.log('Leak scan: GREEN (no surviving
|
|
889
|
+
console.log('Leak scan: GREEN (no surviving spec data ref).');
|
|
880
890
|
} else {
|
|
881
891
|
console.error(`Leak scan: FAILED (${result.leaks.length} leak(s)):`);
|
|
882
892
|
for (const leak of result.leaks) {
|
|
@@ -969,11 +979,12 @@ interface CloseMergedIssuesFlags {
|
|
|
969
979
|
/**
|
|
970
980
|
* Resolve a task-only command's slug argument through the §3a namespace guard
|
|
971
981
|
* (`resolveTaskOnlyArg`): accept bare (= task) + `task:` (explicit alias),
|
|
972
|
-
* REJECT `spec:` with a clear "operates on tasks, not specs" error
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
*
|
|
976
|
-
*
|
|
982
|
+
* REJECT `spec:` with a clear "operates on tasks, not specs" error. On rejection
|
|
983
|
+
* it prints the error to stderr and exits 1 (the task-only commands never act on
|
|
984
|
+
* a spec). An OMITTED slug (`start`/`complete`/`prompt` infer it from the branch)
|
|
985
|
+
* passes through untouched. (The legacy `prd:` prefix is a DEAD namespace token
|
|
986
|
+
* after the hard cutover — it is neither special-cased nor rejected here; a
|
|
987
|
+
* `prd:<slug>` arg resolves as a bare literal task slug.)
|
|
977
988
|
*
|
|
978
989
|
* `do` is the ONE command that spans both namespaces; it consumes the full
|
|
979
990
|
* `resolveSlug` (with the cross-namespace collision check) in the `do-in-place`
|
|
@@ -1057,14 +1068,14 @@ function buildInteractiveLauncher(
|
|
|
1057
1068
|
* switching to its `work/<slug>` branch WITHOUT claiming). The runtime
|
|
1058
1069
|
* difference is exactly the `resume` flag — `resume` forces it on (its only mode
|
|
1059
1070
|
* is to re-engage), while `start` honours the (now hidden) `--resume` alias.
|
|
1060
|
-
* Both are task-only (§3a: accept bare + `task:`, reject `
|
|
1071
|
+
* Both are task-only (§3a: accept bare + `task:`, reject `spec:`).
|
|
1061
1072
|
*/
|
|
1062
1073
|
async function runStartAction(
|
|
1063
1074
|
rawSlug: string | undefined,
|
|
1064
1075
|
flags: StartFlags,
|
|
1065
1076
|
resume: boolean,
|
|
1066
1077
|
): Promise<void> {
|
|
1067
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1078
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1068
1079
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1069
1080
|
const cwd = process.cwd();
|
|
1070
1081
|
|
|
@@ -1520,7 +1531,7 @@ export function buildProgram(): Command {
|
|
|
1520
1531
|
'override the readiness guard: claim despite an unmet blockedBy, and silence the needsAnswers warning (loud, never default)',
|
|
1521
1532
|
)
|
|
1522
1533
|
.action(async (rawSlug: string, flags: ClaimFlags) => {
|
|
1523
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1534
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1524
1535
|
const slug = resolveTaskOnlySlug(rawSlug) as string;
|
|
1525
1536
|
// Wrap ONLY this CLI surface's `performClaim` call with the spinner
|
|
1526
1537
|
// helper (task `claim-cas-spinner`): the push can take seconds, so the
|
|
@@ -1726,7 +1737,7 @@ export function buildProgram(): Command {
|
|
|
1726
1737
|
flags.remote !== undefined && flags.remote.trim() !== ''
|
|
1727
1738
|
? flags.remote
|
|
1728
1739
|
: undefined;
|
|
1729
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1740
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1730
1741
|
const theSlug = resolveTaskOnlySlug(rawSlug) as string;
|
|
1731
1742
|
|
|
1732
1743
|
const configPath = flags.config ?? defaultConfigPath();
|
|
@@ -1778,14 +1789,14 @@ export function buildProgram(): Command {
|
|
|
1778
1789
|
.command('prompt')
|
|
1779
1790
|
.helpGroup(ADVANCED_GROUP)
|
|
1780
1791
|
.description(
|
|
1781
|
-
"Print to stdout the work-agent prompt for a task: the canonical CLAIM-PROTOCOL wrapper + the task's own ## Prompt (with <slug> and source
|
|
1792
|
+
"Print to stdout the work-agent prompt for a task: the canonical CLAIM-PROTOCOL wrapper + the task's own ## Prompt (with <slug> and source spec substituted). Resolves work/in-progress/<slug>.md then work/backlog/<slug>.md; infers <slug> from a work/<slug> branch when omitted. Read-only, stdout only — the same assembly the autonomous runner feeds agentCmd.",
|
|
1782
1793
|
)
|
|
1783
1794
|
.argument(
|
|
1784
1795
|
'[slug]',
|
|
1785
1796
|
'the slug to render (inferred from a work/<slug> branch if omitted)',
|
|
1786
1797
|
)
|
|
1787
1798
|
.action((rawSlug: string | undefined) => {
|
|
1788
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1799
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1789
1800
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1790
1801
|
// Resolve the `promptGuidance` NUDGE namespace through the SAME chain the
|
|
1791
1802
|
// gate family uses (env > per-repo > global > default), so e.g. a
|
|
@@ -1892,7 +1903,7 @@ export function buildProgram(): Command {
|
|
|
1892
1903
|
'cross-job merge-serialiser CAS-retry cap (see `run --help`); resolved flag > env > per-repo > global > default 1000.',
|
|
1893
1904
|
)
|
|
1894
1905
|
.action(async (rawSlug: string | undefined, flags: CompleteFlags) => {
|
|
1895
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
1906
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
1896
1907
|
const slug = resolveTaskOnlySlug(rawSlug);
|
|
1897
1908
|
const cwd = process.cwd();
|
|
1898
1909
|
const {global, override} = loadGlobalAndOverride(flags.config);
|
|
@@ -1956,7 +1967,7 @@ export function buildProgram(): Command {
|
|
|
1956
1967
|
// `--fresh-worktree-gate`/`--no-fresh-worktree-gate` rides the SAME chain.
|
|
1957
1968
|
...freshWorktreeGateFlagOverrides(flags),
|
|
1958
1969
|
// `--merge-retries <n>` rides the SAME chain: the cross-job merge-serialiser
|
|
1959
|
-
// CAS-retry cap (
|
|
1970
|
+
// CAS-retry cap (spec `land-time-reverify-and-parallel-merge-ceiling` Story 5
|
|
1960
1971
|
// / Applied Answer q1 (a)).
|
|
1961
1972
|
...mergeRetriesFlagOverrides(flags),
|
|
1962
1973
|
// `--no-pr` (the PR-INTENT axis) rides the SAME chain.
|
|
@@ -1996,7 +2007,7 @@ export function buildProgram(): Command {
|
|
|
1996
2007
|
// a single-job path, so the resolved flag is passed UNCONDITIONALLY (no
|
|
1997
2008
|
// fleet downgrade).
|
|
1998
2009
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
1999
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
2010
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
2000
2011
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — the resolved
|
|
2001
2012
|
// per-repo value reaches the merge loop via `performComplete`→
|
|
2002
2013
|
// `performIntegration`.
|
|
@@ -2029,7 +2040,7 @@ export function buildProgram(): Command {
|
|
|
2029
2040
|
.command('do')
|
|
2030
2041
|
.helpGroup(HEADLINE_GROUP)
|
|
2031
2042
|
.description(
|
|
2032
|
-
'The per-repo WORKER (the CI command): claim + onboard onto work/<slug>, run the agent, gate, integrate, and exit. In the CURRENT checkout by default (refuses on a dirty tree, integrates in-place). With --remote <r>: against a REGISTERED repo with NO checkout — materialise a hub mirror + job worktree in the agents\u2019 area, run the same pipeline there, then reap. do <slug> | do task:<slug> | do spec:<slug> (the tasking path
|
|
2043
|
+
'The per-repo WORKER (the CI command): claim + onboard onto work/<slug>, run the agent, gate, integrate, and exit. In the CURRENT checkout by default (refuses on a dirty tree, integrates in-place). With --remote <r>: against a REGISTERED repo with NO checkout — materialise a hub mirror + job worktree in the agents\u2019 area, run the same pipeline there, then reap. do <slug> | do task:<slug> | do spec:<slug> (the tasking path) | do (auto-pick one) | do <a> <b> (those, in sequence) | do -n <x> (x eligible, in sequence). Auto-pick draws TASKS-FIRST then SPECS-to-task by default (per-repo selectionOrder reorders the pools). --propose (default) / --merge resolved at integrate-time. Supersedes ar-run.sh.',
|
|
2033
2044
|
)
|
|
2034
2045
|
// EXTENSIBLE argument grammar (the three do-* tasks grow this one block):
|
|
2035
2046
|
// `do-autopick` widens the single optional positional into a VARIADIC one so
|
|
@@ -2038,7 +2049,7 @@ export function buildProgram(): Command {
|
|
|
2038
2049
|
// for the auto-pick form. `do` stays SEQUENTIAL (parallelism is `run`).
|
|
2039
2050
|
.argument(
|
|
2040
2051
|
'[slugs...]',
|
|
2041
|
-
'the item(s) to do: bare (= the task), task:<slug>, or spec:<slug> (task the spec
|
|
2052
|
+
'the item(s) to do: bare (= the task), task:<slug>, or spec:<slug> (task the spec). Zero args = auto-pick; multiple = do them in sequence.',
|
|
2042
2053
|
)
|
|
2043
2054
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2044
2055
|
.option(
|
|
@@ -2071,7 +2082,7 @@ export function buildProgram(): Command {
|
|
|
2071
2082
|
)
|
|
2072
2083
|
.option(
|
|
2073
2084
|
'--tasks-land-in <where>',
|
|
2074
|
-
'where `do
|
|
2085
|
+
'where `do spec:<slug>` tasking output lands: `pre-backlog` (staged, not agent-eligible) or `ready` (the agent POOL). The EXPLICIT operator override at the top of the placement precedence (explicit flag > untrusted-origin forces staging > tasksLandIn default > built-in). Resolved flag > env (DORFL_TASKS_LAND_IN) > per-repo > global > built-in.',
|
|
2075
2086
|
)
|
|
2076
2087
|
.option(
|
|
2077
2088
|
'--no-pr',
|
|
@@ -2124,15 +2135,15 @@ export function buildProgram(): Command {
|
|
|
2124
2135
|
)
|
|
2125
2136
|
.option(
|
|
2126
2137
|
'--tasker-loop',
|
|
2127
|
-
'run the tasker IMPROVER loop on `do
|
|
2138
|
+
'run the tasker IMPROVER loop on `do spec:<slug>` (review→edit→converge over the produced task set). ON by default; --no-tasker-loop skips it. DISTINCT from the acceptance gate (--review).',
|
|
2128
2139
|
)
|
|
2129
2140
|
.option(
|
|
2130
2141
|
'--no-tasker-loop',
|
|
2131
|
-
'skip the tasker improver loop on `do
|
|
2142
|
+
'skip the tasker improver loop on `do spec:<slug>`',
|
|
2132
2143
|
)
|
|
2133
2144
|
.option(
|
|
2134
2145
|
'--tasker-loop-max <n>',
|
|
2135
|
-
'cap the tasker improver loop on `do
|
|
2146
|
+
'cap the tasker improver loop on `do spec:<slug>` (in-context review passes); on exhaustion with blockers, reject via needsAnswers / route the spec to needs-attention (default 3)',
|
|
2136
2147
|
)
|
|
2137
2148
|
.option(
|
|
2138
2149
|
'--tasker-loop-model <id>',
|
|
@@ -2300,7 +2311,7 @@ export function buildProgram(): Command {
|
|
|
2300
2311
|
// Host-only runner IDENTITY — scopes git/provider ops only (not the
|
|
2301
2312
|
// agent launch); absent ⇒ ambient.
|
|
2302
2313
|
identity: remoteConfig.identity,
|
|
2303
|
-
// `do --remote
|
|
2314
|
+
// `do --remote spec:<slug>` tasking-gate policy (task-build path ignores it).
|
|
2304
2315
|
autoTask: remoteConfig.autoTask,
|
|
2305
2316
|
// The resolved `promptGuidance` nudge — threaded into the remote worker
|
|
2306
2317
|
// prompt (runRemotePipeline → buildAgentPrompt), mirroring in-place `do`.
|
|
@@ -2308,7 +2319,7 @@ export function buildProgram(): Command {
|
|
|
2308
2319
|
integration: remoteConfig.integration,
|
|
2309
2320
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
2310
2321
|
explicitMerge: flagMode === 'merge',
|
|
2311
|
-
// Per-TRANSITION TASKING override (the `do --remote
|
|
2322
|
+
// Per-TRANSITION TASKING override (the `do --remote spec:` tasking path).
|
|
2312
2323
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
2313
2324
|
// TASK-PLACEMENT: the configured default + the EXPLICIT operator override
|
|
2314
2325
|
// (`--tasks-land-in`), the top of the placement precedence — mirrors
|
|
@@ -2320,7 +2331,7 @@ export function buildProgram(): Command {
|
|
|
2320
2331
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
2321
2332
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
2322
2333
|
// Cross-job merge-serialiser CAS-retry cap (resolved through the per-repo
|
|
2323
|
-
// chain on the arbiter-side `.dorfl.json` too) —
|
|
2334
|
+
// chain on the arbiter-side `.dorfl.json` too) — spec
|
|
2324
2335
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
2325
2336
|
mergeRetries: remoteConfig.mergeRetries,
|
|
2326
2337
|
noPR: remoteConfig.noPR,
|
|
@@ -2337,7 +2348,7 @@ export function buildProgram(): Command {
|
|
|
2337
2348
|
agentCmd: remoteConfig.agentCmd,
|
|
2338
2349
|
})
|
|
2339
2350
|
: undefined,
|
|
2340
|
-
// The tasker IMPROVER loop on the `do --remote
|
|
2351
|
+
// The tasker IMPROVER loop on the `do --remote spec:` path is ON by default
|
|
2341
2352
|
// (auto-tasking has no `verify` floor, so the loop is the task path's
|
|
2342
2353
|
// quality engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
2343
2354
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -2350,7 +2361,7 @@ export function buildProgram(): Command {
|
|
|
2350
2361
|
: undefined,
|
|
2351
2362
|
taskerLoopMax: remoteConfig.taskerLoopMax,
|
|
2352
2363
|
taskerLoopModel: remoteConfig.taskerLoopModel,
|
|
2353
|
-
// The task-SET ACCEPTANCE GATE on the `do --remote
|
|
2364
|
+
// The task-SET ACCEPTANCE GATE on the `do --remote spec:` path too.
|
|
2354
2365
|
taskReviewGate: remoteConfig.review
|
|
2355
2366
|
? harnessTaskAcceptanceGate({
|
|
2356
2367
|
harness: remoteHarness,
|
|
@@ -2462,7 +2473,7 @@ export function buildProgram(): Command {
|
|
|
2462
2473
|
// ops (claim, push, integrate, `gh`) — NEVER the agent launch. Absent ⇒
|
|
2463
2474
|
// ambient (today's behaviour). Mapped Config → DoOptions like model/agentCmd.
|
|
2464
2475
|
identity: config.identity,
|
|
2465
|
-
// `do
|
|
2476
|
+
// `do spec:<slug>` tasking-gate policy (the task-build path ignores it).
|
|
2466
2477
|
autoTask: config.autoTask,
|
|
2467
2478
|
// The resolved `promptGuidance` NUDGE namespace (e.g. `testFirst`),
|
|
2468
2479
|
// threaded into the worker prompt by performDo → buildAgentPrompt so a
|
|
@@ -2475,11 +2486,11 @@ export function buildProgram(): Command {
|
|
|
2475
2486
|
// typed `--merge` (`flagMode`), never when `merge` came from config — so an
|
|
2476
2487
|
// untrusted-origin task still forces propose under a config `merge`.
|
|
2477
2488
|
explicitMerge: flagMode === 'merge',
|
|
2478
|
-
// Per-TRANSITION TASKING override: the `do
|
|
2489
|
+
// Per-TRANSITION TASKING override: the `do spec:` tasking path threads
|
|
2479
2490
|
// `taskingIntegration ?? integration`; the task-build path stays on
|
|
2480
2491
|
// `integration`. Unset ⇒ tasking falls back to `integration` (today's behaviour).
|
|
2481
2492
|
taskingIntegration: config.taskingIntegration,
|
|
2482
|
-
// TASK-PLACEMENT (`do
|
|
2493
|
+
// TASK-PLACEMENT (`do spec:` tasking output): the configured default rung +
|
|
2483
2494
|
// the EXPLICIT operator override `--tasks-land-in` (top of the precedence).
|
|
2484
2495
|
// `explicitTasksLandIn` is set ONLY when the flag was typed (mirrors
|
|
2485
2496
|
// `explicitMerge`), so an untrusted-origin staging force still wins under a
|
|
@@ -2492,7 +2503,7 @@ export function buildProgram(): Command {
|
|
|
2492
2503
|
verify: config.verify,
|
|
2493
2504
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
2494
2505
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
2495
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
2506
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
2496
2507
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)) — resolved per-repo
|
|
2497
2508
|
// and threaded to `performComplete`→`performIntegration`.
|
|
2498
2509
|
mergeRetries: config.mergeRetries,
|
|
@@ -2516,7 +2527,7 @@ export function buildProgram(): Command {
|
|
|
2516
2527
|
reviewGate: config.review
|
|
2517
2528
|
? harnessReviewGate({harness, agentCmd: config.agentCmd})
|
|
2518
2529
|
: undefined,
|
|
2519
|
-
// The tasker IMPROVER loop on the `do
|
|
2530
|
+
// The tasker IMPROVER loop on the `do spec:` tasking path is ON by default
|
|
2520
2531
|
// (auto-tasking has no `verify` floor — the loop is the task path's quality
|
|
2521
2532
|
// engine). `--tasker-loop`/`--no-tasker-loop` gates wiring the seam;
|
|
2522
2533
|
// `taskerLoopMax`/`taskerLoopModel` resolve per-repo (flag > env > per-repo
|
|
@@ -2544,7 +2555,7 @@ export function buildProgram(): Command {
|
|
|
2544
2555
|
noteBlock: (message) => console.error(message),
|
|
2545
2556
|
};
|
|
2546
2557
|
|
|
2547
|
-
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (
|
|
2558
|
+
// `--allow-backlog` is EXPLICIT-SINGLE-TASK-ONLY (spec
|
|
2548
2559
|
// `do-allow-backlog-drive-staged-tasks-without-promotion`, decision 4): it
|
|
2549
2560
|
// drives ONE named staged task in place. It must NOT combine with the
|
|
2550
2561
|
// AUTO-PICK (zero-args / -n) or MULTI-ITEM forms — those select FROM the
|
|
@@ -2605,11 +2616,11 @@ export function buildProgram(): Command {
|
|
|
2605
2616
|
});
|
|
2606
2617
|
|
|
2607
2618
|
// `advance` — the SIBLING top-level verb (NOT a `do` subcommand; `do`
|
|
2608
|
-
// subcommands + a standalone `task` verb are REJECTED in
|
|
2619
|
+
// subcommands + a standalone `task` verb are REJECTED in spec `advance-loop`).
|
|
2609
2620
|
// It reuses the SAME shared `prefix:arg` resolver `do` uses, EXTENDED with the
|
|
2610
2621
|
// `obs:` namespace, and wires the classify → lock → execute SKELETON: classify
|
|
2611
2622
|
// the rung (read-only, no model, no lock), take the `advancing` CAS borrow, then
|
|
2612
|
-
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do
|
|
2623
|
+
// dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do spec:` (never a
|
|
2613
2624
|
// duplicate), surface/apply/triage dispatch to a named executor seam later
|
|
2614
2625
|
// tasks fill. The DRIVERS (one-shot/loop) + `-n` + per-action gates and the
|
|
2615
2626
|
// rung BODIES are LATER tasks; the bare eligible-SET form errors clearly here.
|
|
@@ -2617,11 +2628,11 @@ export function buildProgram(): Command {
|
|
|
2617
2628
|
.command('advance')
|
|
2618
2629
|
.helpGroup(HEADLINE_GROUP)
|
|
2619
2630
|
.description(
|
|
2620
|
-
'Advance work/ item(s) one lifecycle rung toward ready/built (
|
|
2631
|
+
'Advance work/ item(s) one lifecycle rung toward ready/built (SPEC advance-loop), the SEQUENTIAL one-shot driver over the advance tick. advance <slug> (bare = the task) | advance spec:<slug> (the spec tasking rung) | advance obs:<slug> (triage an observation) | advance (auto-pick one eligible) | advance <a> <b> (those, in sequence) | advance -n <x> (x eligible, in sequence). Each item: classify (read-only, no model, no lock) → take the `advancing` CAS lock → dispatch winner-only — build/task rungs ORCHESTRATE `do`/`do spec:`, surface/apply always run, triage respects observationTriage (off|ask|auto). The bare/`-n` selection respects the per-action gates (build→autoBuild, task→autoTask, triage→observationTriage); `-n` is ALWAYS sequential (parallelism is `run` / the CI matrix).',
|
|
2621
2632
|
)
|
|
2622
2633
|
.argument(
|
|
2623
2634
|
'[slugs...]',
|
|
2624
|
-
'the item(s) to advance: bare (= the task), task:<slug>, spec:<slug
|
|
2635
|
+
'the item(s) to advance: bare (= the task), task:<slug>, spec:<slug>, or obs:<slug> (an observation). Zero args = auto-pick one eligible; multiple = advance them in sequence.',
|
|
2625
2636
|
)
|
|
2626
2637
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
2627
2638
|
.option(
|
|
@@ -2646,15 +2657,15 @@ export function buildProgram(): Command {
|
|
|
2646
2657
|
)
|
|
2647
2658
|
.option(
|
|
2648
2659
|
'--surface-blockers',
|
|
2649
|
-
'the declared-blocked-work gate (the orthogonal peer of --observation-triage): render a task/
|
|
2660
|
+
'the declared-blocked-work gate (the orthogonal peer of --observation-triage): render a task/spec carrying needsAnswers:true into an answerable question sidecar (the needsAnswers-blocked pool is enumerated into auto-pick). Resolved flag > env > per-repo > global > default off. An explicit `advance <slug>`/`advance spec:<slug>` bypasses this selection gate and surfaces regardless. Does NOT gate apply (an answered sidecar still applies) or needs-attention (always on).',
|
|
2650
2661
|
)
|
|
2651
2662
|
.option(
|
|
2652
2663
|
'--no-surface-blockers',
|
|
2653
|
-
'leave a needsAnswers:true task/
|
|
2664
|
+
'leave a needsAnswers:true task/spec silently blocked (default; the blocked pool is dropped from auto-pick)',
|
|
2654
2665
|
)
|
|
2655
2666
|
.option(
|
|
2656
2667
|
'--strict-merge-approval',
|
|
2657
|
-
'opt in to the host-agnostic "dismiss stale approvals on base change" discipline (
|
|
2668
|
+
'opt in to the host-agnostic "dismiss stale approvals on base change" discipline (spec `land-time-reverify-and-parallel-merge-ceiling` sidecar OQ6): when the merge-base CHANGED between the human’s merge-answer and the apply step, RE-SURFACE the merge-question (clear the answer back to no-answer; re-author the question on main/runner under the advancing lock) instead of auto-landing on a green re-verify. Default OFF (a green re-verify is trusted as sufficient; honour the prior answer). Story #16’s RED-re-verify refusal is UNCHANGED and independent of this flag. Resolved flag > env > per-repo > global > default off.',
|
|
2658
2669
|
)
|
|
2659
2670
|
.option(
|
|
2660
2671
|
'--no-strict-merge-approval',
|
|
@@ -2674,7 +2685,7 @@ export function buildProgram(): Command {
|
|
|
2674
2685
|
)
|
|
2675
2686
|
.option(
|
|
2676
2687
|
'--tasks-land-in <where>',
|
|
2677
|
-
'where `advance
|
|
2688
|
+
'where `advance spec:<slug>` tasking output lands: `pre-backlog` (staged) or `ready` (the agent POOL). The EXPLICIT operator override at the top of the placement precedence. Resolved flag > env (DORFL_TASKS_LAND_IN) > per-repo > global > built-in.',
|
|
2678
2689
|
)
|
|
2679
2690
|
.option(
|
|
2680
2691
|
'--watch',
|
|
@@ -2810,7 +2821,7 @@ export function buildProgram(): Command {
|
|
|
2810
2821
|
integration: remoteConfig.integration,
|
|
2811
2822
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule.
|
|
2812
2823
|
explicitMerge: flagMode === 'merge',
|
|
2813
|
-
// Per-TRANSITION TASKING override (the isolated `do --remote
|
|
2824
|
+
// Per-TRANSITION TASKING override (the isolated `do --remote spec:` path).
|
|
2814
2825
|
taskingIntegration: remoteConfig.taskingIntegration,
|
|
2815
2826
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
2816
2827
|
// (set only when typed, mirroring `explicitMerge`).
|
|
@@ -2820,7 +2831,7 @@ export function buildProgram(): Command {
|
|
|
2820
2831
|
verify: remoteConfig.verify,
|
|
2821
2832
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
2822
2833
|
freshWorktreeGate: remoteConfig.freshWorktreeGate,
|
|
2823
|
-
// Cross-job merge-serialiser CAS-retry cap —
|
|
2834
|
+
// Cross-job merge-serialiser CAS-retry cap — spec
|
|
2824
2835
|
// `land-time-reverify-and-parallel-merge-ceiling` Story 5.
|
|
2825
2836
|
mergeRetries: remoteConfig.mergeRetries,
|
|
2826
2837
|
noPR: remoteConfig.noPR,
|
|
@@ -2952,7 +2963,7 @@ export function buildProgram(): Command {
|
|
|
2952
2963
|
// EXPLICIT `--merge` override for the untrusted-origin build-propose rule (a
|
|
2953
2964
|
// bare `advance` auto-pick passes no flag ⇒ unset ⇒ untrusted forces propose).
|
|
2954
2965
|
explicitMerge: flagMode === 'merge',
|
|
2955
|
-
// Per-TRANSITION TASKING override (the `do
|
|
2966
|
+
// Per-TRANSITION TASKING override (the `do spec:` tasking path threads
|
|
2956
2967
|
// `taskingIntegration ?? integration`; the build path stays on `integration`).
|
|
2957
2968
|
taskingIntegration: config.taskingIntegration,
|
|
2958
2969
|
// TASK-PLACEMENT: configured default + EXPLICIT `--tasks-land-in` override
|
|
@@ -2963,7 +2974,7 @@ export function buildProgram(): Command {
|
|
|
2963
2974
|
verify: config.verify,
|
|
2964
2975
|
// Single-job build path: gate the REBASED tip (the default) unconditionally.
|
|
2965
2976
|
freshWorktreeGate: config.freshWorktreeGate,
|
|
2966
|
-
// Cross-job merge-serialiser CAS-retry cap (
|
|
2977
|
+
// Cross-job merge-serialiser CAS-retry cap (spec `land-time-reverify-and-
|
|
2967
2978
|
// parallel-merge-ceiling` Story 5 / Applied Answer q1 (a)).
|
|
2968
2979
|
mergeRetries: config.mergeRetries,
|
|
2969
2980
|
noPR: config.noPR,
|
|
@@ -3127,7 +3138,7 @@ export function buildProgram(): Command {
|
|
|
3127
3138
|
const config = resolveGlobalConfig(loadConfig(flags.config), {});
|
|
3128
3139
|
const workspacesDir = flags.workspace ?? config.workspacesDir;
|
|
3129
3140
|
|
|
3130
|
-
// The `gc`-STYLE ledger SWEEP (
|
|
3141
|
+
// The `gc`-STYLE ledger SWEEP (spec `ledger-integrity` story 3): a SEPARATE
|
|
3131
3142
|
// surface from the worktree reaper below — it REPORTS one-slug-one-folder
|
|
3132
3143
|
// violations in a repo's `work/` lifecycle ledger and NEVER deletes (a human
|
|
3133
3144
|
// resolves each). Distinct `work/`: the ledger, not the execution substrate.
|
|
@@ -3136,7 +3147,7 @@ export function buildProgram(): Command {
|
|
|
3136
3147
|
typeof flags.ledger === 'string' ? flags.ledger : process.cwd();
|
|
3137
3148
|
const result = sweepLedgerDuplicates(repoPath);
|
|
3138
3149
|
// The UNIFIED-LOCK stuck/orphaned-lock REPORT (task
|
|
3139
|
-
// `release-lock-verb-and-gc-stuck-report`,
|
|
3150
|
+
// `release-lock-verb-and-gc-stuck-report`, spec
|
|
3140
3151
|
// `ledger-status-per-item-lock-refs` US #12/#13/#14): generalises the
|
|
3141
3152
|
// advancing-marker report from advancing-only to the unified per-item
|
|
3142
3153
|
// lock. The locks live on the ARBITER ref (`refs/dorfl/lock/*`),
|
|
@@ -3221,7 +3232,7 @@ export function buildProgram(): Command {
|
|
|
3221
3232
|
// ALL are REPORTED here (never auto-deleted — no automatic sweep exists; a
|
|
3222
3233
|
// human clears a NAMED unified lock via `release-lock`).
|
|
3223
3234
|
//
|
|
3224
|
-
// SCOPED to the ATTENTION verdicts only (
|
|
3235
|
+
// SCOPED to the ATTENTION verdicts only (spec US#14/#21, ADR
|
|
3225
3236
|
// `ledger-status-on-per-item-lock-refs`: this surface is the STUCK /
|
|
3226
3237
|
// crash-orphaned lock, NOT every held one): a `kept-stuck` (terminal +
|
|
3227
3238
|
// stuck) or a `cleared-stale`-eligible (terminal + stale active = orphaned)
|
|
@@ -3251,7 +3262,7 @@ export function buildProgram(): Command {
|
|
|
3251
3262
|
dryRun: flags.dryRun === true,
|
|
3252
3263
|
note: (message) => console.error(`>> ${message}`),
|
|
3253
3264
|
});
|
|
3254
|
-
// The ORPHAN-SIDECAR sweep (
|
|
3265
|
+
// The ORPHAN-SIDECAR sweep (spec
|
|
3255
3266
|
// `agentic-question-resolution-retire-disposition-vocabulary`, US #10) rides
|
|
3256
3267
|
// the SAME `--remote-branches` invocation the SCHEDULED CI lifecycle workflow
|
|
3257
3268
|
// runs (`dorfl gc --remote-branches --arbiter origin`) — so the reap of a
|
|
@@ -3507,7 +3518,7 @@ export function buildProgram(): Command {
|
|
|
3507
3518
|
'append a dated handoff note to the item body for the next agent (append-only; applies to both default and --reset)',
|
|
3508
3519
|
)
|
|
3509
3520
|
.action(async (rawSlug: string, flags: RequeueFlags) => {
|
|
3510
|
-
// Task-only command (§3a): accept bare + `task:`, reject `
|
|
3521
|
+
// Task-only command (§3a): accept bare + `task:`, reject `spec:`.
|
|
3511
3522
|
const slug = resolveTaskOnlySlug(rawSlug) as string;
|
|
3512
3523
|
const cwd = flags.cwd ?? process.cwd();
|
|
3513
3524
|
// Route the requeue (default keep+continue / --reset discard / -m handoff)
|
|
@@ -3544,12 +3555,12 @@ export function buildProgram(): Command {
|
|
|
3544
3555
|
console.log(`Requeued '${slug}' to backlog for re-claiming.${how}`);
|
|
3545
3556
|
});
|
|
3546
3557
|
|
|
3547
|
-
// `promote [item]` (
|
|
3558
|
+
// `promote [item]` (spec `staging-pool-position-gate-and-trust-model`, tasks
|
|
3548
3559
|
// `pre-backlog-staging-folder-and-promote-step-a` /
|
|
3549
3560
|
// `pre-prd-staging-pool-split-and-untrusted-prd-placement`): the HUMAN/runner-
|
|
3550
3561
|
// owned verb that moves a STAGED item into its agent-eligible POOL — a task
|
|
3551
|
-
// `work/pre-backlog/<slug>.md → work/backlog/<slug>.md`, a
|
|
3552
|
-
// `work/
|
|
3562
|
+
// `work/pre-backlog/<slug>.md → work/backlog/<slug>.md`, a spec
|
|
3563
|
+
// `work/specs/proposed/<slug>.md → work/specs/ready/<slug>.md` — as a tree-less CAS on the
|
|
3553
3564
|
// arbiter, the SAME trust model + mechanism as `requeue`. The agent emits STAGED;
|
|
3554
3565
|
// only this verb (a human, or the runner) admits it to the pool. With NO argument
|
|
3555
3566
|
// it LISTS what is promotable (the "what is staged waiting for me?" discovery), so
|
|
@@ -3558,7 +3569,7 @@ export function buildProgram(): Command {
|
|
|
3558
3569
|
.command('promote [item]')
|
|
3559
3570
|
.helpGroup(HEADLINE_GROUP)
|
|
3560
3571
|
.description(
|
|
3561
|
-
|
|
3572
|
+
`Admit a STAGED item into its agent-eligible POOL (the runner/human side of the staging gate): a task \`work/pre-backlog/<slug>.md → work/backlog/<slug>.md\`, a spec \`${workFolderPrefix('specs-proposed')}<slug>.md → ${workFolderPrefix('specs-ready')}<slug>.md\`, published as a TREE-LESS compare-and-swap to the arbiter ref (EXACTLY like requeue/claim — it never stages/commits in the cwd tree). The agent only ever CREATES staged; this verb is the gate a human (or the runner) opens. Accepts \`task:<slug>\` / \`spec:<slug>\` / a bare \`<slug>\` (= task). With NO argument, LISTS every promotable item (the tasks in pre-backlog/ + the specs in specs/proposed/ on the arbiter) so you can see what is staged waiting for promotion. Idempotent: promoting an already-pooled slug is a clean no-op success.`,
|
|
3562
3573
|
)
|
|
3563
3574
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
3564
3575
|
.option(
|
|
@@ -3586,7 +3597,7 @@ export function buildProgram(): Command {
|
|
|
3586
3597
|
}
|
|
3587
3598
|
if (listed.items.length === 0) {
|
|
3588
3599
|
console.log(
|
|
3589
|
-
`Nothing staged to promote on ${arbiter}/main (work/pre-backlog/ and
|
|
3600
|
+
`Nothing staged to promote on ${arbiter}/main (work/pre-backlog/ and ${workFolderPrefix('specs-proposed')} are empty).`,
|
|
3590
3601
|
);
|
|
3591
3602
|
return;
|
|
3592
3603
|
}
|
|
@@ -3597,11 +3608,10 @@ export function buildProgram(): Command {
|
|
|
3597
3608
|
return;
|
|
3598
3609
|
}
|
|
3599
3610
|
|
|
3600
|
-
// AN ITEM → promote it. `task:`/`spec:` are explicit
|
|
3601
|
-
//
|
|
3602
|
-
//
|
|
3603
|
-
//
|
|
3604
|
-
// no pool).
|
|
3611
|
+
// AN ITEM → promote it. `task:`/`spec:` are explicit; a bare slug defaults to
|
|
3612
|
+
// a task (mirrors `requeue`). An `obs:`/`observation:` prefix is rejected
|
|
3613
|
+
// (observations have no pool). A legacy `prd:` prefix is a DEAD namespace token
|
|
3614
|
+
// after the hard cutover — it resolves as a bare literal task slug, not a spec.
|
|
3605
3615
|
const parsed = parseSlugArg(rawItem);
|
|
3606
3616
|
if (parsed.explicit === 'observation') {
|
|
3607
3617
|
console.error(
|
|
@@ -3638,7 +3648,7 @@ export function buildProgram(): Command {
|
|
|
3638
3648
|
// `action: advance` on the UNIFIED per-item lock, so `release-lock <item>` (below)
|
|
3639
3649
|
// is the SOLE named human release for ALL holds (implement/task/advance).
|
|
3640
3650
|
|
|
3641
|
-
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`,
|
|
3651
|
+
// `release-lock <item>` (task `release-lock-verb-and-gc-stuck-report`, spec
|
|
3642
3652
|
// `ledger-status-per-item-lock-refs` US #14): the HUMAN-invoked named release of
|
|
3643
3653
|
// a stuck/orphaned UNIFIED per-item lock (`refs/dorfl/lock/<entry>`) —
|
|
3644
3654
|
// the GENERALISATION of `release-advancing` from the advancing-only marker to
|
|
@@ -3655,7 +3665,7 @@ export function buildProgram(): Command {
|
|
|
3655
3665
|
.command('release-lock <item>')
|
|
3656
3666
|
.helpGroup(HEADLINE_GROUP)
|
|
3657
3667
|
.description(
|
|
3658
|
-
'Clear a NAMED stuck/orphaned UNIFIED per-item lock (refs/dorfl/lock/<entry>) by DELETING the ref on the arbiter — the recovery verb for a lock the system orphaned (a crashed build/task/advance that left the hold behind). The generalisation of `release-advancing` from the advancing marker to the ONE lock per item. Same trust model as `requeue`: a HUMAN asserts the lock is dead by NAMING it; the tool never guesses liveness (the lock has NO heartbeat, so there is NO automatic sweep / age-based reaper anywhere). Accepts the same item forms as the lock API: `task:<slug>` / `
|
|
3668
|
+
'Clear a NAMED stuck/orphaned UNIFIED per-item lock (refs/dorfl/lock/<entry>) by DELETING the ref on the arbiter — the recovery verb for a lock the system orphaned (a crashed build/task/advance that left the hold behind). The generalisation of `release-advancing` from the advancing marker to the ONE lock per item. Same trust model as `requeue`: a HUMAN asserts the lock is dead by NAMING it; the tool never guesses liveness (the lock has NO heartbeat, so there is NO automatic sweep / age-based reaper anywhere). Accepts the same item forms as the lock API: `task:<slug>` / `spec:<slug>` / `obs:<slug>` / a bare `<slug>` (= task). Idempotent — re-running on an already-cleared lock is a clean exit-0 no-op (deleting the lock ref is “all locks released”, recoverable). NEVER `--force`. Discoverable via `gc --ledger` (it REPORTS every lingering lock, never deletes).',
|
|
3659
3669
|
)
|
|
3660
3670
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
3661
3671
|
.option(
|
|
@@ -3696,7 +3706,7 @@ export function buildProgram(): Command {
|
|
|
3696
3706
|
process.exit(1);
|
|
3697
3707
|
});
|
|
3698
3708
|
|
|
3699
|
-
// `drop <slug>` (
|
|
3709
|
+
// `drop <slug>` (spec `agentic-question-resolution-retire-disposition-vocabulary`,
|
|
3700
3710
|
// US #5/#11; task `direct-delete-question-cli-helper`): the DIRECT "throw it
|
|
3701
3711
|
// away" verb — `git rm` a source item AND its question sidecar (when present) in
|
|
3702
3712
|
// ONE revertible commit, the reason in the commit MESSAGE (git history is the
|
|
@@ -3711,7 +3721,7 @@ export function buildProgram(): Command {
|
|
|
3711
3721
|
.command('drop <slug>')
|
|
3712
3722
|
.helpGroup(HEADLINE_GROUP)
|
|
3713
3723
|
.description(
|
|
3714
|
-
'DIRECTLY delete a source item + its question sidecar (when present) in ONE revertible commit — the "I just want to throw this away" path that does NOT round-trip through the decision engine or any agent. Resolves the source by its namespaced identity (`task:<slug>` / `
|
|
3724
|
+
'DIRECTLY delete a source item + its question sidecar (when present) in ONE revertible commit — the "I just want to throw this away" path that does NOT round-trip through the decision engine or any agent. Resolves the source by its namespaced identity (`task:<slug>` / `spec:<slug>` / `obs:<slug>` / a bare `<slug>` = task), `git rm`s the source AND its sidecar together, and records your --reason in the commit MESSAGE (git history is the archive). A single revertible commit, so a wrong delete is recoverable via `git revert`. DISTINCT from `remote rm` (the hub-mirror deleter). A LOCAL working-tree commit (like the apply rung); it does not touch the arbiter — push/integrate it as you normally would. If the named source is already gone it is a clean no-op (nothing to throw away).',
|
|
3715
3725
|
)
|
|
3716
3726
|
.option('-c, --config <path>', 'config file path', defaultConfigPath())
|
|
3717
3727
|
.option(
|
|
@@ -3849,7 +3859,7 @@ export function buildProgram(): Command {
|
|
|
3849
3859
|
console.error(`>> ${resolved.message}`);
|
|
3850
3860
|
}
|
|
3851
3861
|
const config = resolved.config;
|
|
3852
|
-
// Resolve the PER-OUTCOME integration modes (
|
|
3862
|
+
// Resolve the PER-OUTCOME integration modes (spec US #9): `intake` decides
|
|
3853
3863
|
// the artifact TYPE at runtime, so a single --merge/--propose can't express
|
|
3854
3864
|
// a type-conditional policy. The granular flags override the aggregate; an
|
|
3855
3865
|
// UNSET type falls back to the per-repo/global `integration` (the SAME chain
|
|
@@ -3931,10 +3941,10 @@ export function buildProgram(): Command {
|
|
|
3931
3941
|
process.exit(result.exitCode);
|
|
3932
3942
|
});
|
|
3933
3943
|
|
|
3934
|
-
// The CI CLOSE-JOB driver (
|
|
3944
|
+
// The CI CLOSE-JOB driver (spec `runner-in-ci`, capability E; task
|
|
3935
3945
|
// `install-ci-close-job-workflow`). The thin JOB the emitted close-job workflow
|
|
3936
3946
|
// invokes on a merge to main: resolve which source issue(s) the landed work
|
|
3937
|
-
// closes (resolveClosingIssue), run the "
|
|
3947
|
+
// closes (resolveClosingIssue), run the "spec complete?" query for the spec case
|
|
3938
3948
|
// (prd-complete-query, done), and close via the IssueProvider seam — all
|
|
3939
3949
|
// UNCHANGED engine pieces, CONSUMED not re-built (the Out-of-Scope fence). CI
|
|
3940
3950
|
// owns ONLY the job + trigger. Local-runnable too (a manual catch-up close).
|
|
@@ -3942,7 +3952,7 @@ export function buildProgram(): Command {
|
|
|
3942
3952
|
.command('close-merged-issues')
|
|
3943
3953
|
.helpGroup(ADVANCED_GROUP)
|
|
3944
3954
|
.description(
|
|
3945
|
-
'Close source issues whose work has landed on main (CI capability E,
|
|
3955
|
+
'Close source issues whose work has landed on main (CI capability E, spec runner-in-ci). Resolves each closing issue from the work/ tree (resolveClosingIssue: a lone task closes its own `issue:`; a fanned task reaches the number via `task.spec: → spec issue:`), runs the existing "spec complete?" query for the spec case (closes ONLY when ALL its spec:<slug> tasks are in work/done/), and closes via the IssueProvider seam (atomic comment+close; NO direct gh). Re-implements NONE of the resolution/query/close — it WIRES them. Invoked by the emitted close-job workflow on a merge to main; DEGRADES (never crashes) on a missing/unauthenticated gh.',
|
|
3946
3956
|
)
|
|
3947
3957
|
.option(
|
|
3948
3958
|
'--cwd <dir>',
|