@paths.design/caws-cli 11.1.7 → 11.1.8

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.
Files changed (158) hide show
  1. package/dist/index.js +55 -58
  2. package/dist/init/hook-packs/manifest-claude-code.d.ts +1 -1
  3. package/dist/init/hook-packs/manifest-claude-code.d.ts.map +1 -1
  4. package/dist/init/hook-packs/manifest-claude-code.js +260 -2
  5. package/dist/init/hook-packs/manifest-claude-code.js.map +1 -1
  6. package/dist/shell/binding/resolve-binding.d.ts.map +1 -1
  7. package/dist/shell/binding/resolve-binding.js +105 -1
  8. package/dist/shell/binding/resolve-binding.js.map +1 -1
  9. package/dist/shell/binding/types.d.ts +47 -3
  10. package/dist/shell/binding/types.d.ts.map +1 -1
  11. package/dist/shell/command-metadata.d.ts +93 -0
  12. package/dist/shell/command-metadata.d.ts.map +1 -0
  13. package/dist/shell/command-metadata.js +687 -0
  14. package/dist/shell/command-metadata.js.map +1 -0
  15. package/dist/shell/commands/agents.d.ts +1 -2
  16. package/dist/shell/commands/agents.d.ts.map +1 -1
  17. package/dist/shell/commands/claim.d.ts +16 -0
  18. package/dist/shell/commands/claim.d.ts.map +1 -1
  19. package/dist/shell/commands/claim.js +85 -26
  20. package/dist/shell/commands/claim.js.map +1 -1
  21. package/dist/shell/commands/events.d.ts +106 -0
  22. package/dist/shell/commands/events.d.ts.map +1 -0
  23. package/dist/shell/commands/events.js +510 -0
  24. package/dist/shell/commands/events.js.map +1 -0
  25. package/dist/shell/commands/gates.d.ts +2 -2
  26. package/dist/shell/commands/gates.d.ts.map +1 -1
  27. package/dist/shell/commands/gates.js +106 -25
  28. package/dist/shell/commands/gates.js.map +1 -1
  29. package/dist/shell/commands/init.d.ts.map +1 -1
  30. package/dist/shell/commands/init.js +26 -0
  31. package/dist/shell/commands/init.js.map +1 -1
  32. package/dist/shell/commands/prepush.d.ts +26 -0
  33. package/dist/shell/commands/prepush.d.ts.map +1 -0
  34. package/dist/shell/commands/prepush.js +373 -0
  35. package/dist/shell/commands/prepush.js.map +1 -0
  36. package/dist/shell/commands/scope.d.ts.map +1 -1
  37. package/dist/shell/commands/scope.js +31 -1
  38. package/dist/shell/commands/scope.js.map +1 -1
  39. package/dist/shell/commands/specs.d.ts +44 -3
  40. package/dist/shell/commands/specs.d.ts.map +1 -1
  41. package/dist/shell/commands/specs.js +411 -15
  42. package/dist/shell/commands/specs.js.map +1 -1
  43. package/dist/shell/commands/worktree.d.ts.map +1 -1
  44. package/dist/shell/commands/worktree.js +51 -1
  45. package/dist/shell/commands/worktree.js.map +1 -1
  46. package/dist/shell/gates/disposition.d.ts.map +1 -1
  47. package/dist/shell/gates/disposition.js +43 -2
  48. package/dist/shell/gates/disposition.js.map +1 -1
  49. package/dist/shell/index.d.ts +10 -4
  50. package/dist/shell/index.d.ts.map +1 -1
  51. package/dist/shell/index.js +22 -2
  52. package/dist/shell/index.js.map +1 -1
  53. package/dist/shell/legacy-command-map.js +832 -0
  54. package/dist/shell/push-range/classify-range.d.ts +99 -0
  55. package/dist/shell/push-range/classify-range.d.ts.map +1 -0
  56. package/dist/shell/push-range/classify-range.js +155 -0
  57. package/dist/shell/push-range/classify-range.js.map +1 -0
  58. package/dist/shell/push-range/scope-match.d.ts +13 -0
  59. package/dist/shell/push-range/scope-match.d.ts.map +1 -0
  60. package/dist/shell/push-range/scope-match.js +53 -0
  61. package/dist/shell/push-range/scope-match.js.map +1 -0
  62. package/dist/shell/register.d.ts.map +1 -1
  63. package/dist/shell/register.js +263 -228
  64. package/dist/shell/register.js.map +1 -1
  65. package/dist/shell/registered-command-groups.js +48 -0
  66. package/dist/shell/rules.d.ts +19 -0
  67. package/dist/shell/rules.d.ts.map +1 -1
  68. package/dist/shell/rules.js +27 -0
  69. package/dist/shell/rules.js.map +1 -1
  70. package/dist/shell/session/resolve-session.d.ts +29 -1
  71. package/dist/shell/session/resolve-session.d.ts.map +1 -1
  72. package/dist/shell/session/resolve-session.js +817 -11
  73. package/dist/shell/session/resolve-session.js.map +1 -1
  74. package/dist/shell/session/types.d.ts +127 -1
  75. package/dist/shell/session/types.d.ts.map +1 -1
  76. package/dist/shell/session/types.js +10 -4
  77. package/dist/shell/session/types.js.map +1 -1
  78. package/dist/store/doctor-snapshot.d.ts.map +1 -1
  79. package/dist/store/doctor-snapshot.js +26 -0
  80. package/dist/store/doctor-snapshot.js.map +1 -1
  81. package/dist/store/events-migration.d.ts +207 -0
  82. package/dist/store/events-migration.d.ts.map +1 -0
  83. package/dist/store/events-migration.js +358 -0
  84. package/dist/store/events-migration.js.map +1 -0
  85. package/dist/store/events-store.d.ts +47 -1
  86. package/dist/store/events-store.d.ts.map +1 -1
  87. package/dist/store/events-store.js +278 -0
  88. package/dist/store/events-store.js.map +1 -1
  89. package/dist/store/git-autocommit.d.ts +46 -0
  90. package/dist/store/git-autocommit.d.ts.map +1 -0
  91. package/dist/store/git-autocommit.js +198 -0
  92. package/dist/store/git-autocommit.js.map +1 -0
  93. package/dist/store/index.d.ts +4 -1
  94. package/dist/store/index.d.ts.map +1 -1
  95. package/dist/store/index.js +7 -1
  96. package/dist/store/index.js.map +1 -1
  97. package/dist/store/leases-store.d.ts.map +1 -1
  98. package/dist/store/leases-store.js +58 -0
  99. package/dist/store/leases-store.js.map +1 -1
  100. package/dist/store/rules.d.ts +53 -0
  101. package/dist/store/rules.d.ts.map +1 -1
  102. package/dist/store/rules.js +54 -0
  103. package/dist/store/rules.js.map +1 -1
  104. package/dist/store/specs-migration.d.ts +128 -0
  105. package/dist/store/specs-migration.d.ts.map +1 -0
  106. package/dist/store/specs-migration.js +481 -0
  107. package/dist/store/specs-migration.js.map +1 -0
  108. package/dist/store/specs-store.d.ts.map +1 -1
  109. package/dist/store/specs-store.js +14 -2
  110. package/dist/store/specs-store.js.map +1 -1
  111. package/dist/store/specs-writer.d.ts +130 -3
  112. package/dist/store/specs-writer.d.ts.map +1 -1
  113. package/dist/store/specs-writer.js +941 -102
  114. package/dist/store/specs-writer.js.map +1 -1
  115. package/dist/store/types.d.ts +6 -0
  116. package/dist/store/types.d.ts.map +1 -1
  117. package/dist/store/waivers-store.d.ts.map +1 -1
  118. package/dist/store/waivers-store.js +8 -1
  119. package/dist/store/waivers-store.js.map +1 -1
  120. package/dist/store/worktrees-writer.d.ts +28 -0
  121. package/dist/store/worktrees-writer.d.ts.map +1 -1
  122. package/dist/store/worktrees-writer.js +110 -12
  123. package/dist/store/worktrees-writer.js.map +1 -1
  124. package/package.json +5 -2
  125. package/templates/hook-packs/claude-code/CLAUDE.md +7 -1
  126. package/templates/hook-packs/claude-code/agent-heartbeat.sh +1 -1
  127. package/templates/hook-packs/claude-code/agent-register.sh +1 -1
  128. package/templates/hook-packs/claude-code/agent-stop.sh +1 -1
  129. package/templates/hook-packs/claude-code/audit.sh +1 -1
  130. package/templates/hook-packs/claude-code/block-dangerous.sh +1 -1
  131. package/templates/hook-packs/claude-code/classify_command.py +1 -1
  132. package/templates/hook-packs/claude-code/cwd-guard.sh +30 -0
  133. package/templates/hook-packs/claude-code/dispatch/post_tool_use.sh +15 -4
  134. package/templates/hook-packs/claude-code/dispatch/pre_tool_use.sh +10 -2
  135. package/templates/hook-packs/claude-code/dispatch/session_start.sh +1 -1
  136. package/templates/hook-packs/claude-code/dispatch/stop.sh +2 -2
  137. package/templates/hook-packs/claude-code/duplicate-export-check.sh +156 -0
  138. package/templates/hook-packs/claude-code/god-object-check.sh +102 -0
  139. package/templates/hook-packs/claude-code/guard-strikes.sh +1 -1
  140. package/templates/hook-packs/claude-code/lib/parse-input.sh +115 -1
  141. package/templates/hook-packs/claude-code/lib/run-handlers.sh +1 -1
  142. package/templates/hook-packs/claude-code/loc-delta-check.sh +91 -0
  143. package/templates/hook-packs/claude-code/naming-check.sh +128 -0
  144. package/templates/hook-packs/claude-code/plan-transcript-finalize.sh +59 -0
  145. package/templates/hook-packs/claude-code/plan-transcript-snapshot.sh +86 -0
  146. package/templates/hook-packs/claude-code/protected-paths.sh +59 -0
  147. package/templates/hook-packs/claude-code/quiet-merge.sh +68 -0
  148. package/templates/hook-packs/claude-code/reset-danger-latch.sh +1 -1
  149. package/templates/hook-packs/claude-code/reset-strikes.sh +1 -1
  150. package/templates/hook-packs/claude-code/runtime-paths.sh +1 -1
  151. package/templates/hook-packs/claude-code/scan-secrets.sh +98 -0
  152. package/templates/hook-packs/claude-code/scope-guard.sh +47 -65
  153. package/templates/hook-packs/claude-code/session-caws-status.sh +1 -1
  154. package/templates/hook-packs/claude-code/session-log.sh +1 -1
  155. package/templates/hook-packs/claude-code/session_log_renderer.py +956 -0
  156. package/templates/hook-packs/claude-code/shortcut-language-check.sh +147 -0
  157. package/templates/hook-packs/claude-code/worktree-guard.sh +1 -1
  158. package/templates/hook-packs/claude-code/worktree-write-guard.sh +1 -1
@@ -0,0 +1,687 @@
1
+ "use strict";
2
+ // Single-source command metadata for the v11 CLI surface
3
+ // (CAWS-CLI-HELP-METADATA-AUTHORITY-001).
4
+ //
5
+ // PROBLEM this solves: every `.description()` / `.argument()` / `.option()`
6
+ // in register.ts is a hand-authored string literal with no binding to the
7
+ // command's actual behavior. They drift (e.g. `specs archive --help` said
8
+ // "moves the YAML to .archive/" long after archive became a tombstone). This
9
+ // module makes the help metadata a typed, single-authority object that
10
+ // register.ts consumes, so:
11
+ // - description prose lives co-located with the handler it describes
12
+ // (each commands/<group>.ts exports its own *_COMMAND_META),
13
+ // - enum-backed option values (--mode, --resolution, ...) are DERIVED from
14
+ // the kernel enum arrays (SPEC_MODES, etc.) rather than re-typed, and a
15
+ // lock test asserts they equal the kernel/schema enums,
16
+ // - a lock test asserts the metadata group set equals
17
+ // REGISTERED_COMMAND_GROUPS and that register.ts carries no inline
18
+ // description/option string literals.
19
+ //
20
+ // STAGING (this is slice 1): this module defines the interfaces and exports
21
+ // an EMPTY frozen COMMAND_SURFACE_METADATA. register.ts is NOT yet refactored
22
+ // to consume it (that is slices 2-3, group by group). The interface shapes
23
+ // are stable; later slices only ADD entries.
24
+ //
25
+ // What is machine-derivable vs. hand-authored:
26
+ // - DERIVABLE (lock-tested against the kernel/schema): option `allowedValues`
27
+ // for enum flags, the group-name set, option required-ness.
28
+ // - HAND-AUTHORED (no schema source; co-located with the handler): the
29
+ // behavioral description prose ("tombstone, not move"; "does NOT run git
30
+ // push"). The lock test cannot verify prose accuracy — co-location +
31
+ // same-slice scope.in is the discipline that keeps it honest.
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.COMMAND_SURFACE_METADATA = exports.AGENTS_COMMAND_META = exports.WAIVER_COMMAND_META = exports.EVENTS_COMMAND_META = exports.EVIDENCE_COMMAND_META = exports.GATES_COMMAND_META = exports.SCOPE_COMMAND_META = exports.PREPUSH_COMMAND_META = exports.CLAIM_COMMAND_META = exports.STATUS_COMMAND_META = exports.DOCTOR_COMMAND_META = exports.INIT_COMMAND_META = exports.WORKTREE_COMMAND_META = exports.SPECS_COMMAND_META = void 0;
34
+ const caws_kernel_1 = require("@paths.design/caws-kernel");
35
+ /**
36
+ * The `--data` option appears on every leaf command in the surface. Declaring
37
+ * it once keeps the per-command metadata focused on what is distinctive.
38
+ */
39
+ const DATA_OPTION = {
40
+ flag: '--data',
41
+ description: 'Show structured data block on diagnostics',
42
+ };
43
+ // ─── specs group (CLI-SPECS-001) ──────────────────────────────────────────
44
+ // Co-located authority for `caws specs` help. The descriptions here are the
45
+ // single source consumed by register.ts; the option `allowedValues` derive
46
+ // from the kernel enum arrays (SPEC_MODES / SPEC_RESOLUTIONS / RISK_TIERS) so
47
+ // --mode/--resolution/--risk-tier help cannot drift from the validation enums.
48
+ exports.SPECS_COMMAND_META = {
49
+ kind: 'group',
50
+ name: 'specs',
51
+ description: 'Manage CAWS spec lifecycle (create/list/show/recover/retire-draft/activate/close/archive/prune-archive/migrate)',
52
+ subcommands: [
53
+ {
54
+ kind: 'leaf',
55
+ name: 'create',
56
+ argument: { name: 'id', required: true, description: 'Spec id to create' },
57
+ description: 'Create a new spec in lifecycle_state: active.',
58
+ // W3: --title/--mode/--risk-tier are functionally required, but the
59
+ // handler (runSpecsCreateCommand) owns the missing-args check so it can
60
+ // emit rich guidance (usage block + --type hint) that Commander's
61
+ // .requiredOption() pre-validation would degrade. So we mark them
62
+ // "(required)" in prose and keep them .option() — help states the
63
+ // requirement; the handler enforces it.
64
+ options: [
65
+ { flag: '--title <title>', description: 'Short spec title (required)' },
66
+ {
67
+ flag: '--mode <mode>',
68
+ description: 'Spec mode (required)',
69
+ allowedValues: caws_kernel_1.SPEC_MODES,
70
+ },
71
+ {
72
+ flag: '--risk-tier <n>',
73
+ description: 'Risk tier (required)',
74
+ allowedValues: caws_kernel_1.RISK_TIERS,
75
+ },
76
+ {
77
+ flag: '--type <type>',
78
+ description: 'Removed v10 alias; use --mode <feature|refactor|fix|doc|chore> instead',
79
+ },
80
+ DATA_OPTION,
81
+ ],
82
+ },
83
+ {
84
+ kind: 'leaf',
85
+ name: 'list',
86
+ description: 'List specs. By default excludes archived specs.',
87
+ options: [
88
+ { flag: '--archived', description: 'Include archived specs in the listing' },
89
+ DATA_OPTION,
90
+ ],
91
+ },
92
+ {
93
+ kind: 'leaf',
94
+ name: 'show',
95
+ argument: { name: 'id', required: true, description: 'Spec id to show' },
96
+ description: 'Show a spec by id. Defaults to active specs only; pass --archived to recover an archived spec body from the event log + git history.',
97
+ options: [
98
+ DATA_OPTION,
99
+ {
100
+ flag: '--archived',
101
+ description: 'Recover an archived spec body via the event log + git show <blob_sha>. The body is NOT loaded from .caws/specs/.archive/ (which the post-CAWS-ARCHIVE-AS-TOMBSTONE-001 archive flow does not write).',
102
+ },
103
+ ],
104
+ },
105
+ {
106
+ kind: 'leaf',
107
+ name: 'recover',
108
+ argument: { name: 'id', required: true, description: 'Archived spec id to recover' },
109
+ description: 'Recover an archived spec body via the event log + git show <blob_sha>. Topology-independent (works with merge commits, rebases, cherry-picks). Reads .caws/events.jsonl for the spec_archived event, validates the blob_sha, runs git show, prints to stdout (or --out <path>). Does NOT mutate .caws/specs/.',
110
+ options: [
111
+ DATA_OPTION,
112
+ {
113
+ flag: '--out <path>',
114
+ description: 'Write the recovered body to this path instead of stdout',
115
+ },
116
+ ],
117
+ },
118
+ {
119
+ kind: 'leaf',
120
+ name: 'retire-draft',
121
+ argument: { name: 'id', required: true, description: 'Draft spec id to retire' },
122
+ description: 'Retire a never-activated DRAFT spec via tombstone. Refuses active (use close), closed (use archive), and archived specs. Deletes the draft YAML and appends a recoverable spec_retired event (recover via caws specs show <id> --archived). The governed alternative to raw git rm.',
123
+ options: [
124
+ { flag: '--reason <text>', description: 'Optional human-readable retirement note' },
125
+ DATA_OPTION,
126
+ ],
127
+ },
128
+ {
129
+ kind: 'leaf',
130
+ name: 'activate',
131
+ argument: { name: 'id', required: true, description: 'Draft spec id to activate' },
132
+ description: 'Activate a pre-authored draft spec. Draft-only: patches lifecycle_state to active and appends spec_activated.',
133
+ options: [DATA_OPTION],
134
+ },
135
+ {
136
+ kind: 'leaf',
137
+ name: 'close',
138
+ argument: { name: 'id', required: true, description: 'Active spec id to close' },
139
+ description: 'Close an active spec. Non-destructive raw-byte YAML patch; appends spec_closed event.',
140
+ options: [
141
+ {
142
+ flag: '--resolution <r>',
143
+ description: 'Resolution',
144
+ allowedValues: caws_kernel_1.SPEC_RESOLUTIONS,
145
+ defaultValue: 'completed',
146
+ },
147
+ {
148
+ flag: '--reason <text>',
149
+ description: 'Closure notes recorded on the spec YAML and the spec_closed event',
150
+ },
151
+ {
152
+ flag: '--merge-commit <sha>',
153
+ description: 'Optional merge commit SHA (e.g., when closure follows a worktree merge)',
154
+ },
155
+ {
156
+ flag: '--superseded-by <id>',
157
+ description: 'Spec id that supersedes this one (use with --resolution superseded)',
158
+ },
159
+ DATA_OPTION,
160
+ ],
161
+ },
162
+ {
163
+ kind: 'leaf',
164
+ name: 'archive',
165
+ argument: { name: 'id', required: true, description: 'Closed spec id to archive' },
166
+ description: 'Archive a closed spec (tombstone, not a move): deletes the spec YAML and appends a recoverable spec_archived event carrying its blob_sha. Recover the body with caws specs show <id> --archived or caws specs recover <id>.',
167
+ options: [
168
+ {
169
+ flag: '--reason <text>',
170
+ description: 'Archive reason (advisory; the spec_archived schema does not carry it)',
171
+ },
172
+ DATA_OPTION,
173
+ ],
174
+ },
175
+ {
176
+ kind: 'leaf',
177
+ name: 'prune-archive',
178
+ description: 'Migrate legacy .caws/specs/.archive/<id>.yaml bodies (CAWS-ARCHIVE-AS-TOMBSTONE-001). Dry-run by default — pass --apply to execute. Recoverable bodies (reachable via git log --follow) are removed from the working tree; unrecoverable bodies are QUARANTINED to .caws/specs/.archive/.unrecoverable/ (never silently deleted, no override flag). Emits one spec_archive_pruned event per id on --apply.',
179
+ options: [
180
+ { flag: '--apply', description: 'Execute the migration. Default is dry-run.' },
181
+ DATA_OPTION,
182
+ ],
183
+ },
184
+ {
185
+ kind: 'leaf',
186
+ name: 'migrate',
187
+ description: 'v10→v11 spec YAML migrator (CAWS-MIGRATE-V10-SPECS-001). Default is dry-run; --apply opts into mutation. --apply without --partial refuses if any spec hits a "refused" verdict. --apply --partial writes migratable specs, skips refused, emits a durable JSON report under .caws/migrations/v10-specs/.',
188
+ options: [
189
+ {
190
+ flag: '--from <version>',
191
+ required: true,
192
+ description: 'Source schema version (only v10 is supported in v11.2)',
193
+ },
194
+ { flag: '--apply', description: 'Write migrated YAMLs to disk (default: dry-run)' },
195
+ {
196
+ flag: '--partial',
197
+ description: 'Allow apply to proceed even when some specs are refused (only meaningful with --apply)',
198
+ },
199
+ {
200
+ flag: '--lifecycle-mapping <path>',
201
+ description: 'Path to a JSON file mapping spec ids to v11 lifecycle values, for v10 lifecycles outside the v11 enum (superseded/proven/frozen). Operator-owned; the transformer never auto-defaults.',
202
+ },
203
+ { flag: '--json', description: 'Emit machine-readable JSON output instead of human text' },
204
+ DATA_OPTION,
205
+ ],
206
+ },
207
+ ],
208
+ };
209
+ // ─── worktree group (CLI-WORKTREE-001) ────────────────────────────────────
210
+ // Co-located authority for `caws worktree` help. The group description here
211
+ // enumerates EVERY subcommand (create/list/bind/destroy/merge/migrate-registry/
212
+ // repair-sparse), unlike the prior inline string that omitted the last two.
213
+ exports.WORKTREE_COMMAND_META = {
214
+ kind: 'group',
215
+ name: 'worktree',
216
+ description: 'Manage CAWS worktrees (create/list/bind/destroy/merge/migrate-registry/repair-sparse). Worktrees are git worktrees bound to active specs.',
217
+ subcommands: [
218
+ {
219
+ kind: 'leaf',
220
+ name: 'create',
221
+ argument: { name: 'name', required: true, description: 'Worktree name' },
222
+ description: 'Create a new git worktree under .caws/worktrees/<name> bound to an active spec.',
223
+ options: [
224
+ { flag: '--spec <id>', required: true, description: 'Active spec id to bind the worktree to' },
225
+ {
226
+ flag: '--base-branch <branch>',
227
+ description: 'Base branch to start from (default: current branch)',
228
+ },
229
+ { flag: '--branch <branch>', description: 'New branch name (default: worktree name)' },
230
+ DATA_OPTION,
231
+ ],
232
+ },
233
+ {
234
+ kind: 'leaf',
235
+ name: 'list',
236
+ description: 'List registered worktrees with branch, spec binding, and owner.',
237
+ options: [DATA_OPTION],
238
+ },
239
+ {
240
+ kind: 'leaf',
241
+ name: 'bind',
242
+ argument: { name: 'name', required: true, description: 'Worktree name' },
243
+ description: 'Repair bidirectional binding between a worktree and a spec (one-sided → bound).',
244
+ options: [
245
+ { flag: '--spec <id>', required: true, description: 'Spec id to bind the worktree to' },
246
+ DATA_OPTION,
247
+ ],
248
+ },
249
+ {
250
+ kind: 'leaf',
251
+ name: 'destroy',
252
+ argument: { name: 'name', required: true, description: 'Worktree name' },
253
+ description: 'Destroy a worktree. Non-forceful: refuses foreign ownership, dirty checkout, unmerged branch (use --abandon-unmerged to override branch check only).',
254
+ options: [
255
+ {
256
+ flag: '--abandon-unmerged',
257
+ description: 'Destroy even when the branch is not merged into base. Still respects ownership and clean working tree.',
258
+ },
259
+ DATA_OPTION,
260
+ ],
261
+ },
262
+ {
263
+ kind: 'leaf',
264
+ name: 'merge',
265
+ argument: { name: 'name', required: true, description: 'Worktree name' },
266
+ description: 'Merge a worktree branch into its base. Auto-closes the bound spec via caws specs close.',
267
+ options: [
268
+ { flag: '--dry-run', description: 'Validate prerequisites only; no git, no file writes, no events' },
269
+ {
270
+ flag: '--message <text>',
271
+ description: 'Custom merge commit message (default: merge(worktree): <name>)',
272
+ },
273
+ DATA_OPTION,
274
+ ],
275
+ },
276
+ {
277
+ kind: 'leaf',
278
+ name: 'migrate-registry',
279
+ description: 'Convert v10.2 legacy-envelope .caws/worktrees.json into the v11 flat-map shape. Destroyed records are omitted iff no spec claims them and their path is absent; refuses otherwise. Idempotent on already-flat files.',
280
+ options: [
281
+ { flag: '--dry-run', description: 'Classify and report what would happen; do not write.' },
282
+ DATA_OPTION,
283
+ ],
284
+ },
285
+ {
286
+ kind: 'leaf',
287
+ name: 'repair-sparse',
288
+ argument: { name: 'name', required: true, description: 'Worktree name' },
289
+ description: 'Restore the .caws/specs sparse-checkout invariant on a linked worktree. Idempotent and non-destructive: refuses if .caws/specs/ has dirty or untracked content rather than stashing, cleaning, resetting, or deleting it. Use this after a `git sparse-checkout disable` has materialized canonical spec files into the worktree.',
290
+ options: [DATA_OPTION],
291
+ },
292
+ ],
293
+ };
294
+ // ─── flat top-level commands (init/doctor/status/claim/prepush) ───────────
295
+ // These are registered directly on `program` (no subcommand layer); they are
296
+ // LeafCommandMeta entries at the top of COMMAND_SURFACE_METADATA. register.ts
297
+ // consumes them via the defineFlat helper.
298
+ exports.INIT_COMMAND_META = {
299
+ kind: 'leaf',
300
+ name: 'init',
301
+ description: 'Bootstrap the canonical vNext .caws/ project state (idempotent; refuses to overwrite legacy single-spec layout). With --agent-surface, also installs the corresponding hook pack.',
302
+ options: [
303
+ DATA_OPTION,
304
+ {
305
+ flag: '--agent-surface <name>',
306
+ description: 'Install a hook pack for an agent harness (claude-code | cursor | windsurf | none). When omitted, init attempts filesystem detection and skips hook install when ambiguous.',
307
+ },
308
+ {
309
+ flag: '--overwrite',
310
+ description: 'For hook-pack install: replace drifted or unmanaged files at managed pack paths. CAUTION: local edits to those files will be lost.',
311
+ },
312
+ {
313
+ flag: '--adopt',
314
+ description: 'For hook-pack install: leave drifted or unmanaged files in place without enforcing pack contents. CAUTION: pack drift is no longer tracked for those paths.',
315
+ },
316
+ ],
317
+ };
318
+ exports.DOCTOR_COMMAND_META = {
319
+ kind: 'leaf',
320
+ name: 'doctor',
321
+ description: 'Run drift detection against the current .caws/ state',
322
+ options: [{ flag: '--data', description: 'Show structured data block on findings/diagnostics' }],
323
+ };
324
+ exports.STATUS_COMMAND_META = {
325
+ kind: 'leaf',
326
+ name: 'status',
327
+ description: 'Read-only dashboard: project, current context, claim, and doctor findings',
328
+ options: [{ flag: '--data', description: 'Show structured data block on rendered diagnostics' }],
329
+ };
330
+ exports.CLAIM_COMMAND_META = {
331
+ kind: 'leaf',
332
+ name: 'claim',
333
+ description: "Surface ownership of the current worktree; with --takeover, acquire ownership from a foreign session (writes prior_owners audit). With --paths, declare working-tree ownership metadata on the current session's lease (SESSION-OWNERSHIP-METADATA-001).",
334
+ options: [
335
+ {
336
+ flag: '--takeover',
337
+ description: 'Forcibly take ownership of a foreign-owned worktree. Required when the current owner is a different session.',
338
+ },
339
+ {
340
+ flag: '--paths <path>',
341
+ description: 'Declare a path as claimed by the current session. Repeatable; order preserved; strings stored verbatim. Refused with no write if no lease exists for the current session.',
342
+ collect: true,
343
+ },
344
+ DATA_OPTION,
345
+ ],
346
+ };
347
+ exports.PREPUSH_COMMAND_META = {
348
+ kind: 'leaf',
349
+ name: 'prepush',
350
+ description: 'Classify the outgoing commit range before publish and refuse commits not attributable to the current slice. Diagnose/decide only — does NOT run git push.',
351
+ options: [
352
+ { flag: '--remote <remote>', description: 'Push remote', defaultValue: 'origin' },
353
+ { flag: '--branch <branch>', description: 'Push branch', defaultValue: 'main' },
354
+ { flag: '--base <ref>', description: 'Base ref override (default <remote>/<branch>)' },
355
+ { flag: '--spec <id>', description: 'Current session active spec id (for slice-match)' },
356
+ {
357
+ flag: '--ack <sha>',
358
+ description: 'Acknowledge an unexpected commit by SHA (repeatable)',
359
+ collect: true,
360
+ // Seed []: the prepush handler reads opts.ack as an array unconditionally.
361
+ defaultValue: [],
362
+ },
363
+ DATA_OPTION,
364
+ ],
365
+ };
366
+ // ─── scope group ──────────────────────────────────────────────────────────
367
+ exports.SCOPE_COMMAND_META = {
368
+ kind: 'group',
369
+ name: 'scope',
370
+ description: 'Evaluate file paths against the bound spec scope',
371
+ subcommands: [
372
+ {
373
+ kind: 'leaf',
374
+ name: 'show',
375
+ argument: { name: 'path', required: true, description: 'File path to evaluate' },
376
+ description: 'Explain the scope decision for <path>; always exits 0',
377
+ options: [{ flag: '--data', description: 'Show structured data block' }],
378
+ },
379
+ {
380
+ kind: 'leaf',
381
+ name: 'check',
382
+ argument: { name: 'path', required: true, description: 'File path to enforce' },
383
+ description: 'Enforce the scope decision for <path>; exits 0 on admit, 1 otherwise',
384
+ options: [{ flag: '--data', description: 'Show structured data block' }],
385
+ },
386
+ ],
387
+ };
388
+ // ─── gates group (W4: exit-code contract documented) ──────────────────────
389
+ exports.GATES_COMMAND_META = {
390
+ kind: 'group',
391
+ name: 'gates',
392
+ description: 'Run quality gates against the current changes (policy-driven)',
393
+ subcommands: [
394
+ {
395
+ kind: 'leaf',
396
+ name: 'run',
397
+ description: 'Run CAWS-local policy evaluators and apply policy.gates[gate].mode to decide block/warn/skip. Appends one gate_evaluated event per policy-declared gate. Exit codes: 0/1 on gate disposition; 2 on hard composition error (no policy / subprocess-contract failure); 3 on evidence-integrity failure (a gate_evaluated event failed to append or validate).',
398
+ options: [
399
+ { flag: '--spec <id>', required: true, description: 'Spec id this gate run is about' },
400
+ {
401
+ flag: '--context <ctx>',
402
+ description: 'Compatibility no-op retained from the former quality-gates subprocess path',
403
+ defaultValue: 'cli',
404
+ },
405
+ DATA_OPTION,
406
+ ],
407
+ },
408
+ ],
409
+ };
410
+ // ─── evidence group ───────────────────────────────────────────────────────
411
+ exports.EVIDENCE_COMMAND_META = {
412
+ kind: 'group',
413
+ name: 'evidence',
414
+ description: 'Record typed evidence events into .caws/events.jsonl',
415
+ subcommands: [
416
+ {
417
+ kind: 'leaf',
418
+ name: 'record',
419
+ description: 'Append a typed evidence event (test|gate|ac)',
420
+ options: [
421
+ { flag: '--type <kind>', required: true, description: 'Evidence kind: test | gate | ac' },
422
+ { flag: '--spec <id>', required: true, description: 'Spec id this evidence is about' },
423
+ { flag: '--data <json>', required: true, description: 'Event payload as a JSON object string' },
424
+ {
425
+ flag: '--actor-kind <kind>',
426
+ description: 'Actor kind: agent | human | system | automation',
427
+ defaultValue: 'agent',
428
+ },
429
+ { flag: '--actor-id <id>', description: 'Override actor id (defaults to session id)' },
430
+ ],
431
+ },
432
+ ],
433
+ };
434
+ // ─── events group ─────────────────────────────────────────────────────────
435
+ exports.EVENTS_COMMAND_META = {
436
+ kind: 'group',
437
+ name: 'events',
438
+ description: 'Maintenance commands for .caws/events.jsonl (rotate, migrate, verify-archive)',
439
+ subcommands: [
440
+ {
441
+ kind: 'leaf',
442
+ name: 'migrate',
443
+ description: 'Migrate a v10-shape events.jsonl to a v11 chain via chain_rotated rotation. Dry-run by default; --apply executes.',
444
+ options: [
445
+ {
446
+ flag: '--from <version>',
447
+ required: true,
448
+ description: 'Source schema version (only v10 supported in v11.2)',
449
+ },
450
+ { flag: '--apply', description: 'Execute the rotation (default is dry-run)' },
451
+ {
452
+ flag: '--reason <text>',
453
+ description: 'Operator reason recorded into the chain_rotated payload (required with --apply)',
454
+ },
455
+ {
456
+ flag: '--actor-kind <kind>',
457
+ description: 'Actor kind: agent | human | system | automation',
458
+ defaultValue: 'agent',
459
+ },
460
+ { flag: '--actor-id <id>', description: 'Override actor id (defaults to session id)' },
461
+ {
462
+ flag: '--allow-partial-upgrade',
463
+ description: 'Allow rotation when v10 specs are still present (off by default; see CAWS-MIGRATE-V10-SPECS-001)',
464
+ },
465
+ ],
466
+ },
467
+ {
468
+ kind: 'leaf',
469
+ name: 'rotate',
470
+ description: 'Rotate events.jsonl: archive existing chain, start fresh chain with chain_rotated genesis event. Distinct from migrate — admits fully-unparseable logs.',
471
+ options: [
472
+ {
473
+ flag: '--reason <text>',
474
+ required: true,
475
+ description: 'Operator reason recorded into the chain_rotated payload',
476
+ },
477
+ {
478
+ flag: '--actor-kind <kind>',
479
+ description: 'Actor kind: agent | human | system | automation',
480
+ defaultValue: 'agent',
481
+ },
482
+ { flag: '--actor-id <id>', description: 'Override actor id (defaults to session id)' },
483
+ { flag: '--allow-clean', description: 'Allow rotation of a clean v11 chain (friction flag)' },
484
+ ],
485
+ },
486
+ {
487
+ kind: 'leaf',
488
+ name: 'verify-archive',
489
+ description: 'Verify that the archive file named in the most recent chain_rotated event byte-matches its committed digest + line count.',
490
+ options: [],
491
+ },
492
+ ],
493
+ };
494
+ // ─── waiver group ─────────────────────────────────────────────────────────
495
+ exports.WAIVER_COMMAND_META = {
496
+ kind: 'group',
497
+ name: 'waiver',
498
+ description: 'Manage CAWS waivers (bounded exception records that suppress matching gate violations)',
499
+ subcommands: [
500
+ {
501
+ kind: 'leaf',
502
+ name: 'create',
503
+ argument: { name: 'id', required: true, description: 'Waiver id to create' },
504
+ description: 'Create a new active waiver. Validates against the kernel before writing.',
505
+ options: [
506
+ { flag: '--title <title>', required: true, description: 'Short waiver title (≥5 chars)' },
507
+ {
508
+ flag: '--gate <gate>',
509
+ required: true,
510
+ description: 'Gate id this waiver covers; repeat for multiple gates',
511
+ collect: true,
512
+ },
513
+ { flag: '--reason <reason>', required: true, description: 'Justification for the waiver' },
514
+ { flag: '--approved-by <id>', required: true, description: 'Approver identity' },
515
+ {
516
+ flag: '--expires-at <iso>',
517
+ required: true,
518
+ description: 'Expiry as an ISO-8601 datetime with timezone',
519
+ },
520
+ {
521
+ flag: '--spec <id>',
522
+ description: 'Optional spec id this waiver is scoped to (omit for project-wide)',
523
+ },
524
+ DATA_OPTION,
525
+ ],
526
+ },
527
+ {
528
+ kind: 'leaf',
529
+ name: 'list',
530
+ description: 'List waivers. By default excludes revoked and expired records.',
531
+ options: [
532
+ { flag: '--include-revoked', description: 'Include revoked waivers' },
533
+ { flag: '--include-expired', description: 'Include expired waivers' },
534
+ DATA_OPTION,
535
+ ],
536
+ },
537
+ {
538
+ kind: 'leaf',
539
+ name: 'show',
540
+ argument: { name: 'id', required: true, description: 'Waiver id to show' },
541
+ description: 'Show a waiver, including its derived effectiveness at now.',
542
+ options: [DATA_OPTION],
543
+ },
544
+ {
545
+ kind: 'leaf',
546
+ name: 'revoke',
547
+ argument: { name: 'id', required: true, description: 'Waiver id to revoke' },
548
+ description: 'Revoke a waiver. Writes a revocation record; refuses double-revoke.',
549
+ options: [
550
+ { flag: '--revoked-by <id>', description: 'Identity recorded in revocation.revoked_by' },
551
+ {
552
+ flag: '--reason <reason>',
553
+ description: 'Reason recorded in revocation.reason (recommended for audit)',
554
+ },
555
+ DATA_OPTION,
556
+ ],
557
+ },
558
+ ],
559
+ };
560
+ // ─── agents group ─────────────────────────────────────────────────────────
561
+ exports.AGENTS_COMMAND_META = {
562
+ kind: 'group',
563
+ name: 'agents',
564
+ description: 'Agent liveness substrate: register/heartbeat/stop/list/show/prune. Operational cache only — NEVER authority. CAWS-native JSON; never Claude Code hook envelope.',
565
+ subcommands: [
566
+ {
567
+ kind: 'leaf',
568
+ name: 'register',
569
+ description: 'Register this session in .caws/leases/. Hook-invoked at SessionStart.',
570
+ options: [
571
+ {
572
+ flag: '--session-id <id>',
573
+ description: 'Explicit session id (required for hook-invoked usage; overrides resolveSession)',
574
+ },
575
+ { flag: '--platform <p>', description: 'Platform tag (e.g., claude-code, cursor, manual)' },
576
+ { flag: '--reason <r>', description: 'session_start | pre_tool_use | manual_register | claim | status' },
577
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout (never hookSpecificOutput)' },
578
+ {
579
+ flag: '--include-active-summary',
580
+ description: 'Include active_agent_count + active_agents in JSON output',
581
+ },
582
+ DATA_OPTION,
583
+ ],
584
+ },
585
+ {
586
+ kind: 'leaf',
587
+ name: 'heartbeat',
588
+ description: "Refresh this session's lease. Hook-invoked at PreToolUse. Throttle-aware.",
589
+ options: [
590
+ { flag: '--session-id <id>', description: 'Explicit session id (required for hook-invoked usage)' },
591
+ { flag: '--platform <p>', description: 'Platform tag' },
592
+ { flag: '--reason <r>', description: 'pre_tool_use | claim | status | manual_register' },
593
+ {
594
+ flag: '--throttle <ms>',
595
+ description: 'Skip write if last_active within this many ms (default: 0 — no throttle)',
596
+ },
597
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout' },
598
+ {
599
+ flag: '--include-active-summary',
600
+ description: 'Include active_agent_count + active_agents in JSON output',
601
+ },
602
+ DATA_OPTION,
603
+ ],
604
+ },
605
+ {
606
+ kind: 'leaf',
607
+ name: 'stop',
608
+ description: "Mark this session's lease stopped. Hook-invoked at Stop. Warn no-op if no prior lease.",
609
+ options: [
610
+ { flag: '--session-id <id>', description: 'Explicit session id' },
611
+ { flag: '--platform <p>', description: 'Platform tag' },
612
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout' },
613
+ DATA_OPTION,
614
+ ],
615
+ },
616
+ {
617
+ kind: 'leaf',
618
+ name: 'list',
619
+ description: 'List active / stale / stopped agents. Read-only.',
620
+ options: [
621
+ { flag: '--include-stale', description: 'Include stale (active-but-TTL-expired) records' },
622
+ { flag: '--include-stopped', description: 'Include stopped records' },
623
+ {
624
+ flag: '--active',
625
+ description: 'Active-only (overrides --include-* flags); TTL-classified active, not raw status field',
626
+ },
627
+ { flag: '--stale-ttl-ms <ms>', description: 'TTL for stale classification (default: 1800000 = 30m)' },
628
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout' },
629
+ DATA_OPTION,
630
+ ],
631
+ },
632
+ {
633
+ kind: 'leaf',
634
+ name: 'show',
635
+ argument: { name: 'id', required: true, description: 'Session id of the lease to show' },
636
+ description: 'Show one lease by session id. Read-only.',
637
+ options: [
638
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout' },
639
+ DATA_OPTION,
640
+ ],
641
+ },
642
+ {
643
+ kind: 'leaf',
644
+ name: 'prune',
645
+ description: 'Operator-invoked cleanup. Defaults to dry-run; pass --apply to actually delete. Never invoked by hooks.',
646
+ options: [
647
+ { flag: '--status <s>', required: true, description: 'stopped | stale' },
648
+ { flag: '--older-than-ms <ms>', required: true, description: 'Retention threshold in milliseconds' },
649
+ {
650
+ flag: '--stale-ttl-ms <ms>',
651
+ description: 'TTL for stale classification (used with --status stale; default 30m)',
652
+ },
653
+ { flag: '--apply', description: 'Actually delete (default: dry-run)' },
654
+ { flag: '--json', description: 'Emit CAWS-native JSON to stdout' },
655
+ DATA_OPTION,
656
+ ],
657
+ },
658
+ ],
659
+ };
660
+ /**
661
+ * The complete v11 command-surface metadata — the single authority for every
662
+ * `.description()` / `.argument()` / `.option()` in register.ts.
663
+ *
664
+ * SLICE 3: all thirteen surface entries are populated and consumed by
665
+ * register.ts — the five flat top-level commands (init/doctor/status/claim/
666
+ * prepush) as LeafCommandMeta, and eight groups (scope/gates/evidence/events/
667
+ * waiver/agents/specs/worktree). The lock test enforces full set-equality with
668
+ * REGISTERED_COMMAND_GROUPS (L1), enum/value-list parity (L3), non-empty
669
+ * descriptions (L4), and the global no-inline-strings invariant on register.ts
670
+ * (L5).
671
+ */
672
+ exports.COMMAND_SURFACE_METADATA = Object.freeze([
673
+ exports.INIT_COMMAND_META,
674
+ exports.DOCTOR_COMMAND_META,
675
+ exports.STATUS_COMMAND_META,
676
+ exports.SCOPE_COMMAND_META,
677
+ exports.CLAIM_COMMAND_META,
678
+ exports.GATES_COMMAND_META,
679
+ exports.EVIDENCE_COMMAND_META,
680
+ exports.EVENTS_COMMAND_META,
681
+ exports.WAIVER_COMMAND_META,
682
+ exports.SPECS_COMMAND_META,
683
+ exports.WORKTREE_COMMAND_META,
684
+ exports.AGENTS_COMMAND_META,
685
+ exports.PREPUSH_COMMAND_META,
686
+ ]);
687
+ //# sourceMappingURL=command-metadata.js.map