@principles/pd-cli 1.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/README.md +90 -0
  2. package/dist/commands/artifact.d.ts +14 -0
  3. package/dist/commands/artifact.d.ts.map +1 -0
  4. package/dist/commands/artifact.js +67 -0
  5. package/dist/commands/artifact.js.map +1 -0
  6. package/dist/commands/candidate.d.ts +83 -0
  7. package/dist/commands/candidate.d.ts.map +1 -0
  8. package/dist/commands/candidate.js +891 -0
  9. package/dist/commands/candidate.js.map +1 -0
  10. package/dist/commands/central-sync.d.ts +10 -0
  11. package/dist/commands/central-sync.d.ts.map +1 -0
  12. package/dist/commands/central-sync.js +32 -0
  13. package/dist/commands/central-sync.js.map +1 -0
  14. package/dist/commands/console.d.ts +9 -0
  15. package/dist/commands/console.d.ts.map +1 -0
  16. package/dist/commands/console.js +114 -0
  17. package/dist/commands/console.js.map +1 -0
  18. package/dist/commands/context.d.ts +7 -0
  19. package/dist/commands/context.d.ts.map +1 -0
  20. package/dist/commands/context.js +55 -0
  21. package/dist/commands/context.js.map +1 -0
  22. package/dist/commands/demo-story-a.d.ts +12 -0
  23. package/dist/commands/demo-story-a.d.ts.map +1 -0
  24. package/dist/commands/demo-story-a.js +175 -0
  25. package/dist/commands/demo-story-a.js.map +1 -0
  26. package/dist/commands/diagnose.d.ts +35 -0
  27. package/dist/commands/diagnose.d.ts.map +1 -0
  28. package/dist/commands/diagnose.js +390 -0
  29. package/dist/commands/diagnose.js.map +1 -0
  30. package/dist/commands/evolution-tasks-list.d.ts +15 -0
  31. package/dist/commands/evolution-tasks-list.d.ts.map +1 -0
  32. package/dist/commands/evolution-tasks-list.js +34 -0
  33. package/dist/commands/evolution-tasks-list.js.map +1 -0
  34. package/dist/commands/evolution-tasks-show.d.ts +14 -0
  35. package/dist/commands/evolution-tasks-show.d.ts.map +1 -0
  36. package/dist/commands/evolution-tasks-show.js +52 -0
  37. package/dist/commands/evolution-tasks-show.js.map +1 -0
  38. package/dist/commands/flow.d.ts +7 -0
  39. package/dist/commands/flow.d.ts.map +1 -0
  40. package/dist/commands/flow.js +57 -0
  41. package/dist/commands/flow.js.map +1 -0
  42. package/dist/commands/health.d.ts +16 -0
  43. package/dist/commands/health.d.ts.map +1 -0
  44. package/dist/commands/health.js +150 -0
  45. package/dist/commands/health.js.map +1 -0
  46. package/dist/commands/history.d.ts +11 -0
  47. package/dist/commands/history.d.ts.map +1 -0
  48. package/dist/commands/history.js +50 -0
  49. package/dist/commands/history.js.map +1 -0
  50. package/dist/commands/legacy-cleanup.d.ts +27 -0
  51. package/dist/commands/legacy-cleanup.d.ts.map +1 -0
  52. package/dist/commands/legacy-cleanup.js +171 -0
  53. package/dist/commands/legacy-cleanup.js.map +1 -0
  54. package/dist/commands/legacy-import.d.ts +7 -0
  55. package/dist/commands/legacy-import.d.ts.map +1 -0
  56. package/dist/commands/legacy-import.js +86 -0
  57. package/dist/commands/legacy-import.js.map +1 -0
  58. package/dist/commands/pain-record.d.ts +10 -0
  59. package/dist/commands/pain-record.d.ts.map +1 -0
  60. package/dist/commands/pain-record.js +162 -0
  61. package/dist/commands/pain-record.js.map +1 -0
  62. package/dist/commands/proven-channel-baseline.d.ts +12 -0
  63. package/dist/commands/proven-channel-baseline.d.ts.map +1 -0
  64. package/dist/commands/proven-channel-baseline.js +97 -0
  65. package/dist/commands/proven-channel-baseline.js.map +1 -0
  66. package/dist/commands/remediation-output.d.ts +40 -0
  67. package/dist/commands/remediation-output.d.ts.map +1 -0
  68. package/dist/commands/remediation-output.js +23 -0
  69. package/dist/commands/remediation-output.js.map +1 -0
  70. package/dist/commands/run.d.ts +10 -0
  71. package/dist/commands/run.d.ts.map +1 -0
  72. package/dist/commands/run.js +68 -0
  73. package/dist/commands/run.js.map +1 -0
  74. package/dist/commands/runtime-activation.d.ts +11 -0
  75. package/dist/commands/runtime-activation.d.ts.map +1 -0
  76. package/dist/commands/runtime-activation.js +150 -0
  77. package/dist/commands/runtime-activation.js.map +1 -0
  78. package/dist/commands/runtime-canary.d.ts +30 -0
  79. package/dist/commands/runtime-canary.d.ts.map +1 -0
  80. package/dist/commands/runtime-canary.js +343 -0
  81. package/dist/commands/runtime-canary.js.map +1 -0
  82. package/dist/commands/runtime-diagnostics-export.d.ts +20 -0
  83. package/dist/commands/runtime-diagnostics-export.d.ts.map +1 -0
  84. package/dist/commands/runtime-diagnostics-export.js +177 -0
  85. package/dist/commands/runtime-diagnostics-export.js.map +1 -0
  86. package/dist/commands/runtime-features.d.ts +26 -0
  87. package/dist/commands/runtime-features.d.ts.map +1 -0
  88. package/dist/commands/runtime-features.js +70 -0
  89. package/dist/commands/runtime-features.js.map +1 -0
  90. package/dist/commands/runtime-gfi-snapshot.d.ts +7 -0
  91. package/dist/commands/runtime-gfi-snapshot.d.ts.map +1 -0
  92. package/dist/commands/runtime-gfi-snapshot.js +101 -0
  93. package/dist/commands/runtime-gfi-snapshot.js.map +1 -0
  94. package/dist/commands/runtime-health-snapshot.d.ts +7 -0
  95. package/dist/commands/runtime-health-snapshot.d.ts.map +1 -0
  96. package/dist/commands/runtime-health-snapshot.js +93 -0
  97. package/dist/commands/runtime-health-snapshot.js.map +1 -0
  98. package/dist/commands/runtime-idle-trigger.d.ts +12 -0
  99. package/dist/commands/runtime-idle-trigger.d.ts.map +1 -0
  100. package/dist/commands/runtime-idle-trigger.js +102 -0
  101. package/dist/commands/runtime-idle-trigger.js.map +1 -0
  102. package/dist/commands/runtime-internalization-enqueue-successors.d.ts +9 -0
  103. package/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -0
  104. package/dist/commands/runtime-internalization-enqueue-successors.js +393 -0
  105. package/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -0
  106. package/dist/commands/runtime-internalization-integrity-repair.d.ts +9 -0
  107. package/dist/commands/runtime-internalization-integrity-repair.d.ts.map +1 -0
  108. package/dist/commands/runtime-internalization-integrity-repair.js +54 -0
  109. package/dist/commands/runtime-internalization-integrity-repair.js.map +1 -0
  110. package/dist/commands/runtime-internalization-integrity.d.ts +7 -0
  111. package/dist/commands/runtime-internalization-integrity.d.ts.map +1 -0
  112. package/dist/commands/runtime-internalization-integrity.js +53 -0
  113. package/dist/commands/runtime-internalization-integrity.js.map +1 -0
  114. package/dist/commands/runtime-internalization-queue.d.ts +7 -0
  115. package/dist/commands/runtime-internalization-queue.d.ts.map +1 -0
  116. package/dist/commands/runtime-internalization-queue.js +85 -0
  117. package/dist/commands/runtime-internalization-queue.js.map +1 -0
  118. package/dist/commands/runtime-internalization-run-once.d.ts +12 -0
  119. package/dist/commands/runtime-internalization-run-once.d.ts.map +1 -0
  120. package/dist/commands/runtime-internalization-run-once.js +546 -0
  121. package/dist/commands/runtime-internalization-run-once.js.map +1 -0
  122. package/dist/commands/runtime-internalization-wake-once.d.ts +8 -0
  123. package/dist/commands/runtime-internalization-wake-once.d.ts.map +1 -0
  124. package/dist/commands/runtime-internalization-wake-once.js +72 -0
  125. package/dist/commands/runtime-internalization-wake-once.js.map +1 -0
  126. package/dist/commands/runtime-pain-flood-simulation.d.ts +10 -0
  127. package/dist/commands/runtime-pain-flood-simulation.d.ts.map +1 -0
  128. package/dist/commands/runtime-pain-flood-simulation.js +104 -0
  129. package/dist/commands/runtime-pain-flood-simulation.js.map +1 -0
  130. package/dist/commands/runtime-pruning.d.ts +45 -0
  131. package/dist/commands/runtime-pruning.d.ts.map +1 -0
  132. package/dist/commands/runtime-pruning.js +355 -0
  133. package/dist/commands/runtime-pruning.js.map +1 -0
  134. package/dist/commands/runtime-recovery.d.ts +9 -0
  135. package/dist/commands/runtime-recovery.d.ts.map +1 -0
  136. package/dist/commands/runtime-recovery.js +94 -0
  137. package/dist/commands/runtime-recovery.js.map +1 -0
  138. package/dist/commands/runtime-synthetic-baseline.d.ts +7 -0
  139. package/dist/commands/runtime-synthetic-baseline.d.ts.map +1 -0
  140. package/dist/commands/runtime-synthetic-baseline.js +59 -0
  141. package/dist/commands/runtime-synthetic-baseline.js.map +1 -0
  142. package/dist/commands/runtime-uat.d.ts +52 -0
  143. package/dist/commands/runtime-uat.d.ts.map +1 -0
  144. package/dist/commands/runtime-uat.js +274 -0
  145. package/dist/commands/runtime-uat.js.map +1 -0
  146. package/dist/commands/runtime.d.ts +20 -0
  147. package/dist/commands/runtime.d.ts.map +1 -0
  148. package/dist/commands/runtime.js +256 -0
  149. package/dist/commands/runtime.js.map +1 -0
  150. package/dist/commands/samples-list.d.ts +11 -0
  151. package/dist/commands/samples-list.d.ts.map +1 -0
  152. package/dist/commands/samples-list.js +37 -0
  153. package/dist/commands/samples-list.js.map +1 -0
  154. package/dist/commands/samples-review.d.ts +14 -0
  155. package/dist/commands/samples-review.d.ts.map +1 -0
  156. package/dist/commands/samples-review.js +22 -0
  157. package/dist/commands/samples-review.js.map +1 -0
  158. package/dist/commands/task.d.ts +14 -0
  159. package/dist/commands/task.d.ts.map +1 -0
  160. package/dist/commands/task.js +92 -0
  161. package/dist/commands/task.js.map +1 -0
  162. package/dist/commands/trace.d.ts +19 -0
  163. package/dist/commands/trace.d.ts.map +1 -0
  164. package/dist/commands/trace.js +154 -0
  165. package/dist/commands/trace.js.map +1 -0
  166. package/dist/commands/trajectory.d.ts +11 -0
  167. package/dist/commands/trajectory.d.ts.map +1 -0
  168. package/dist/commands/trajectory.js +47 -0
  169. package/dist/commands/trajectory.js.map +1 -0
  170. package/dist/index.d.ts +9 -0
  171. package/dist/index.d.ts.map +1 -0
  172. package/dist/index.js +736 -0
  173. package/dist/index.js.map +1 -0
  174. package/dist/legacy/legacy-import.d.ts +15 -0
  175. package/dist/legacy/legacy-import.d.ts.map +1 -0
  176. package/dist/legacy/legacy-import.js +141 -0
  177. package/dist/legacy/legacy-import.js.map +1 -0
  178. package/dist/legacy/session-history-import.d.ts +26 -0
  179. package/dist/legacy/session-history-import.d.ts.map +1 -0
  180. package/dist/legacy/session-history-import.js +151 -0
  181. package/dist/legacy/session-history-import.js.map +1 -0
  182. package/dist/principle-tree-ledger-adapter.d.ts +12 -0
  183. package/dist/principle-tree-ledger-adapter.d.ts.map +1 -0
  184. package/dist/principle-tree-ledger-adapter.js +12 -0
  185. package/dist/principle-tree-ledger-adapter.js.map +1 -0
  186. package/dist/resolve-workspace.d.ts +12 -0
  187. package/dist/resolve-workspace.d.ts.map +1 -0
  188. package/dist/resolve-workspace.js +20 -0
  189. package/dist/resolve-workspace.js.map +1 -0
  190. package/dist/services/demo-story-a-runner.d.ts +8 -0
  191. package/dist/services/demo-story-a-runner.d.ts.map +1 -0
  192. package/dist/services/demo-story-a-runner.js +369 -0
  193. package/dist/services/demo-story-a-runner.js.map +1 -0
  194. package/dist/services/feature-flag-loader.d.ts +6 -0
  195. package/dist/services/feature-flag-loader.d.ts.map +1 -0
  196. package/dist/services/feature-flag-loader.js +54 -0
  197. package/dist/services/feature-flag-loader.js.map +1 -0
  198. package/dist/services/pain-flood-simulation-runner.d.ts +10 -0
  199. package/dist/services/pain-flood-simulation-runner.d.ts.map +1 -0
  200. package/dist/services/pain-flood-simulation-runner.js +289 -0
  201. package/dist/services/pain-flood-simulation-runner.js.map +1 -0
  202. package/dist/services/proven-channel-baseline-runner.d.ts +12 -0
  203. package/dist/services/proven-channel-baseline-runner.d.ts.map +1 -0
  204. package/dist/services/proven-channel-baseline-runner.js +114 -0
  205. package/dist/services/proven-channel-baseline-runner.js.map +1 -0
  206. package/dist/services/synthetic-baseline-runner.d.ts +8 -0
  207. package/dist/services/synthetic-baseline-runner.d.ts.map +1 -0
  208. package/dist/services/synthetic-baseline-runner.js +251 -0
  209. package/dist/services/synthetic-baseline-runner.js.map +1 -0
  210. package/package.json +35 -0
  211. package/src/commands/artifact.ts +82 -0
  212. package/src/commands/candidate.ts +1117 -0
  213. package/src/commands/central-sync.ts +44 -0
  214. package/src/commands/console.ts +121 -0
  215. package/src/commands/context.ts +72 -0
  216. package/src/commands/demo-story-a.ts +195 -0
  217. package/src/commands/diagnose.ts +452 -0
  218. package/src/commands/evolution-tasks-list.ts +44 -0
  219. package/src/commands/evolution-tasks-show.ts +60 -0
  220. package/src/commands/flow.ts +60 -0
  221. package/src/commands/health.ts +189 -0
  222. package/src/commands/history.ts +63 -0
  223. package/src/commands/legacy-cleanup.ts +206 -0
  224. package/src/commands/legacy-import.ts +104 -0
  225. package/src/commands/pain-record.ts +167 -0
  226. package/src/commands/proven-channel-baseline.ts +113 -0
  227. package/src/commands/remediation-output.ts +66 -0
  228. package/src/commands/run.ts +89 -0
  229. package/src/commands/runtime-activation.ts +176 -0
  230. package/src/commands/runtime-canary.ts +371 -0
  231. package/src/commands/runtime-diagnostics-export.ts +229 -0
  232. package/src/commands/runtime-features.ts +103 -0
  233. package/src/commands/runtime-gfi-snapshot.ts +135 -0
  234. package/src/commands/runtime-health-snapshot.ts +106 -0
  235. package/src/commands/runtime-internalization-enqueue-successors.ts +479 -0
  236. package/src/commands/runtime-internalization-integrity-repair.ts +69 -0
  237. package/src/commands/runtime-internalization-integrity.ts +63 -0
  238. package/src/commands/runtime-internalization-queue.ts +106 -0
  239. package/src/commands/runtime-internalization-run-once.ts +658 -0
  240. package/src/commands/runtime-internalization-wake-once.ts +87 -0
  241. package/src/commands/runtime-pain-flood-simulation.ts +121 -0
  242. package/src/commands/runtime-pruning.ts +438 -0
  243. package/src/commands/runtime-recovery.ts +107 -0
  244. package/src/commands/runtime-synthetic-baseline.ts +70 -0
  245. package/src/commands/runtime-uat.ts +339 -0
  246. package/src/commands/runtime.ts +281 -0
  247. package/src/commands/samples-list.ts +43 -0
  248. package/src/commands/samples-review.ts +32 -0
  249. package/src/commands/task.ts +130 -0
  250. package/src/commands/trace.ts +174 -0
  251. package/src/commands/trajectory.ts +64 -0
  252. package/src/index.ts +829 -0
  253. package/src/legacy/legacy-import.ts +179 -0
  254. package/src/legacy/session-history-import.ts +231 -0
  255. package/src/principle-tree-ledger-adapter.ts +13 -0
  256. package/src/resolve-workspace.ts +20 -0
  257. package/src/services/demo-story-a-runner.ts +472 -0
  258. package/src/services/feature-flag-loader.ts +73 -0
  259. package/src/services/pain-flood-simulation-runner.ts +354 -0
  260. package/src/services/proven-channel-baseline-runner.ts +150 -0
  261. package/src/services/synthetic-baseline-runner.ts +291 -0
  262. package/tests/commands/candidate-audit-repair.test.ts +338 -0
  263. package/tests/commands/candidate-intake.test.ts +589 -0
  264. package/tests/commands/candidate-internalization-backfill.test.ts +480 -0
  265. package/tests/commands/candidate-internalize.test.ts +272 -0
  266. package/tests/commands/candidate-route.test.ts +328 -0
  267. package/tests/commands/candidate-show.test.ts +95 -0
  268. package/tests/commands/cli-command-tree.test.ts +64 -0
  269. package/tests/commands/context.test.ts +114 -0
  270. package/tests/commands/demo-story-a.test.ts +255 -0
  271. package/tests/commands/diagnose.test.ts +792 -0
  272. package/tests/commands/health.test.ts +330 -0
  273. package/tests/commands/pain-record.test.ts +316 -0
  274. package/tests/commands/plugin-config-resolution-cutover.test.ts +220 -0
  275. package/tests/commands/proven-channel-baseline.test.ts +441 -0
  276. package/tests/commands/runtime-activation.test.ts +168 -0
  277. package/tests/commands/runtime-canary.test.ts +369 -0
  278. package/tests/commands/runtime-diagnostics-export.test.ts +170 -0
  279. package/tests/commands/runtime-features.test.ts +114 -0
  280. package/tests/commands/runtime-health-snapshot.test.ts +357 -0
  281. package/tests/commands/runtime-internalization-enqueue-successors.test.ts +803 -0
  282. package/tests/commands/runtime-internalization-integrity-repair.test.ts +169 -0
  283. package/tests/commands/runtime-internalization-integrity.test.ts +102 -0
  284. package/tests/commands/runtime-internalization-queue.test.ts +252 -0
  285. package/tests/commands/runtime-internalization-run-once.test.ts +1318 -0
  286. package/tests/commands/runtime-internalization-wake-once.test.ts +170 -0
  287. package/tests/commands/runtime-internalization.test.ts +52 -0
  288. package/tests/commands/runtime-pain-flood-simulation.test.ts +418 -0
  289. package/tests/commands/runtime-pruning.test.ts +693 -0
  290. package/tests/commands/runtime-recovery.test.ts +96 -0
  291. package/tests/commands/runtime-synthetic-baseline.test.ts +249 -0
  292. package/tests/commands/runtime-uat.test.ts +397 -0
  293. package/tests/commands/runtime.test.ts +262 -0
  294. package/tests/commands/trace.test.ts +314 -0
  295. package/tests/e2e/candidate-intake-e2e.test.ts +316 -0
  296. package/tests/services/feature-flag-loader.test.ts +207 -0
  297. package/tests/services/proven-channel-baseline-runner.test.ts +30 -0
  298. package/tsconfig.json +26 -0
package/src/index.ts ADDED
@@ -0,0 +1,829 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pd CLI — Principles Disciple command-line interface.
4
+ *
5
+ * Usage:
6
+ * pd pain record --reason <text> [--score N] [--source manual]
7
+ */
8
+
9
+ import { Command } from 'commander';
10
+ import { handlePainRecord } from './commands/pain-record.js';
11
+ import { handleSamplesList } from './commands/samples-list.js';
12
+ import { handleSamplesReview } from './commands/samples-review.js';
13
+ import { handleEvolutionTasksList } from './commands/evolution-tasks-list.js';
14
+ import { handleEvolutionTasksShow } from './commands/evolution-tasks-show.js';
15
+ import { handleHealth } from './commands/health.js';
16
+ import { handleCentralSync } from './commands/central-sync.js';
17
+ import { handleTaskList, handleTaskShow } from './commands/task.js';
18
+ import { handleRunList, handleRunShow } from './commands/run.js';
19
+ import { handleTrajectoryLocate } from './commands/trajectory.js';
20
+ import { handleHistoryQuery } from './commands/history.js';
21
+ import { handleContextBuild } from './commands/context.js';
22
+ import { handleLegacyImportOpenClaw } from './commands/legacy-import.js';
23
+ import { handleLegacyCleanup } from './commands/legacy-cleanup.js';
24
+ import { handleDiagnoseStatus, handleDiagnoseRun } from './commands/diagnose.js';
25
+ import { handleRuntimeProbe } from './commands/runtime.js';
26
+ import { handleFlowShow } from './commands/flow.js';
27
+ import { handleTraceShow } from './commands/trace.js';
28
+ import { handlePruningReport, handlePruningExplain, handlePruningReview, handlePruningRollback, handlePruningOrphans } from './commands/runtime-pruning.js';
29
+ import { handleRuntimeHealthSnapshot } from './commands/runtime-health-snapshot.js';
30
+ import { handleRuntimeGfiSnapshot } from './commands/runtime-gfi-snapshot.js';
31
+ import { handleRuntimeUat } from './commands/runtime-uat.js';
32
+ import { handleRuntimeInternalizationQueue } from './commands/runtime-internalization-queue.js';
33
+ import { handleRuntimeInternalizationWakeOnce } from './commands/runtime-internalization-wake-once.js';
34
+ import { handleRuntimeInternalizationRunOnce } from './commands/runtime-internalization-run-once.js';
35
+ import { handleCandidateList, handleCandidateShow, handleCandidateIntake, handleCandidateAudit, handleCandidateRepair, handleCandidateRoute, handleCandidateInternalize, handleCandidateInternalizationBackfill } from './commands/candidate.js';
36
+ import { handleArtifactShow } from './commands/artifact.js';
37
+ import { handleRuntimeCanary } from './commands/runtime-canary.js';
38
+ import { handleRuntimeSyntheticBaseline } from './commands/runtime-synthetic-baseline.js';
39
+ import { handleRuntimePainFlood } from './commands/runtime-pain-flood-simulation.js';
40
+ import { handleRuntimeInternalizationIntegrity } from './commands/runtime-internalization-integrity.js';
41
+ import { handleRuntimeInternalizationIntegrityRepair } from './commands/runtime-internalization-integrity-repair.js';
42
+ import { handleRuntimeInternalizationEnqueueSuccessors } from './commands/runtime-internalization-enqueue-successors.js';
43
+ import { handleRuntimeDiagnosticsExport } from './commands/runtime-diagnostics-export.js';
44
+ import { handleRuntimeRecoverySweep } from './commands/runtime-recovery.js';
45
+ import { handleRuntimeActivationDispatch } from './commands/runtime-activation.js';
46
+ import { handleProvenChannelBaseline } from './commands/proven-channel-baseline.js';
47
+ import { handleDemoStoryA } from './commands/demo-story-a.js';
48
+ import { handleRuntimeFeaturesStatus } from './commands/runtime-features.js';
49
+
50
+ const program = new Command();
51
+
52
+ program
53
+ .name('pd')
54
+ .description('PD CLI — Pain recording, sample management, and evolution tasks')
55
+ .version('0.1.0');
56
+
57
+ const painCmd = program
58
+ .command('pain')
59
+ .description('Pain signal management');
60
+
61
+ painCmd
62
+ .command('record')
63
+ .description('Record a pain signal via Runtime v2 bridge')
64
+ .option('-r, --reason <text>', 'Reason for the pain signal (required)')
65
+ .option('-s, --score <number>', 'Pain score 0-100', parseInt)
66
+ .option('-S, --source <text>', 'Source of the pain signal', 'manual')
67
+ .option('-w, --workspace <path>', 'Workspace directory')
68
+ .option('--json', 'Output raw JSON')
69
+ .action(async (opts) => {
70
+ await handlePainRecord(opts);
71
+ });
72
+
73
+ const samplesCmd = program
74
+ .command('samples')
75
+ .description('Correction sample management');
76
+
77
+ samplesCmd
78
+ .command('list')
79
+ .description('List correction samples')
80
+ .option('-s, --status <pending|approved|rejected>', 'Filter by review status', 'pending')
81
+ .action(async (opts) => {
82
+ await handleSamplesList(opts);
83
+ });
84
+
85
+ samplesCmd
86
+ .command('review')
87
+ .description('Review a correction sample')
88
+ .argument('<sample-id>', 'The sample ID to review')
89
+ .argument('<approve|reject>', 'Review decision')
90
+ .argument('[note]', 'Optional review note')
91
+ .action(async (sampleId, decision, note) => {
92
+ if (decision !== 'approve' && decision !== 'reject') {
93
+ console.error('Error: decision must be "approve" or "reject"');
94
+ process.exit(1);
95
+ }
96
+ await handleSamplesReview({ sampleId, decision: decision === 'approve' ? 'approved' : 'rejected', note });
97
+ });
98
+
99
+ const evolutionCmd = program
100
+ .command('evolution')
101
+ .description('Evolution task management');
102
+
103
+ const tasksCmd = evolutionCmd
104
+ .command('tasks')
105
+ .description('List and show evolution tasks');
106
+
107
+ tasksCmd
108
+ .command('list')
109
+ .description('List evolution tasks')
110
+ .option('-s, --status <status>', 'Filter by status (pending|in_progress|completed|all)', 'all')
111
+ .option('-l, --limit <number>', 'Maximum tasks to return', parseInt, 50)
112
+ .option('-f, --date-from <date>', 'Filter tasks created on or after this date')
113
+ .option('-t, --date-to <date>', 'Filter tasks created on or before this date')
114
+ .action(async (opts) => {
115
+ await handleEvolutionTasksList(opts);
116
+ });
117
+
118
+ tasksCmd
119
+ .command('show')
120
+ .description('Show full details for an evolution task')
121
+ .argument('<id>', 'Task ID (numeric or string taskId)')
122
+ .action(async (id, _opts) => {
123
+ await handleEvolutionTasksShow({ id });
124
+ });
125
+
126
+ program
127
+ .command('health')
128
+ .description('Show health diagnostics for all workspaces')
129
+ .option('-w, --workspace <path>', 'Workspace directory')
130
+ .option('--json', 'Output raw JSON')
131
+ .action(async (opts) => {
132
+ await handleHealth(opts);
133
+ });
134
+
135
+ const centralCmd = program
136
+ .command('central')
137
+ .description('Central server management');
138
+
139
+ centralCmd
140
+ .command('sync')
141
+ .description('Trigger a sync cycle and report results')
142
+ .action(async () => {
143
+ await handleCentralSync();
144
+ });
145
+
146
+ // ── Runtime v2 task/run commands ──────────────────────────────────────────────
147
+
148
+ const rtTaskCmd = program
149
+ .command('task')
150
+ .description('Runtime v2 task inspection');
151
+
152
+ rtTaskCmd
153
+ .command('list')
154
+ .description('List runtime tasks')
155
+ .option('-s, --status <status>', 'Filter by status (pending, leased, retry_wait, succeeded, failed)')
156
+ .option('-k, --kind <kind>', 'Filter by task kind')
157
+ .option('-l, --limit <number>', 'Limit number of results', parseInt, 50)
158
+ .action(async (opts) => {
159
+ await handleTaskList(opts);
160
+ });
161
+
162
+ rtTaskCmd
163
+ .command('show <taskId>')
164
+ .description('Show detailed task information')
165
+ .option('-w, --workspace <path>', 'Workspace directory')
166
+ .option('--json', 'Output raw JSON')
167
+ .action(async (taskId, opts) => {
168
+ await handleTaskShow({ id: taskId, json: opts.json, workspace: opts.workspace });
169
+ });
170
+
171
+ const rtRunCmd = program
172
+ .command('run')
173
+ .description('Runtime v2 run inspection');
174
+
175
+ rtRunCmd
176
+ .command('list <taskId>')
177
+ .description('List all runs for a task')
178
+ .action(async (taskId) => {
179
+ await handleRunList({ taskId });
180
+ });
181
+
182
+ rtRunCmd
183
+ .command('show <runId>')
184
+ .description('Show detailed run information')
185
+ .action(async (runId) => {
186
+ await handleRunShow({ id: runId });
187
+ });
188
+
189
+ // ── Runtime v2 trajectory/history/context commands ───────────────────────────
190
+
191
+ const trajectoryCmd = program
192
+ .command('trajectory')
193
+ .description('Runtime v2 trajectory location');
194
+
195
+ trajectoryCmd
196
+ .command('locate')
197
+ .description('Locate a trajectory by task ID, run ID, or time range')
198
+ .option('-t, --task <taskId>', 'Locate by task ID')
199
+ .option('-r, --run <runId>', 'Locate by run ID')
200
+ .option('--from <date>', 'Start of time range (ISO string)')
201
+ .option('--to <date>', 'End of time range (ISO string)')
202
+ .option('-w, --workspace <path>', 'Workspace directory')
203
+ .option('--json', 'Output raw JSON')
204
+ .action(async (opts) => {
205
+ await handleTrajectoryLocate(opts);
206
+ });
207
+
208
+ const historyCmd = program
209
+ .command('history')
210
+ .description('Runtime v2 history query');
211
+
212
+ historyCmd
213
+ .command('query <taskId>')
214
+ .description('Query run history for a task')
215
+ .option('-l, --limit <number>', 'Limit number of entries', parseInt)
216
+ .option('-c, --cursor <cursor>', 'Pagination cursor')
217
+ .option('--from <date>', 'Start of time range (ISO string)')
218
+ .option('--to <date>', 'End of time range (ISO string)')
219
+ .option('-w, --workspace <path>', 'Workspace directory')
220
+ .option('--json', 'Output raw JSON')
221
+ .action(async (taskId, opts) => {
222
+ await handleHistoryQuery(taskId, opts);
223
+ });
224
+
225
+ const contextCmd = program
226
+ .command('context')
227
+ .description('Runtime v2 context assembly');
228
+
229
+ contextCmd
230
+ .command('build <taskId>')
231
+ .description('Assemble diagnostician context for a task')
232
+ .option('-w, --workspace <path>', 'Workspace directory')
233
+ .option('--json', 'Output raw JSON')
234
+ .action(async (taskId, opts) => {
235
+ await handleContextBuild(taskId, opts);
236
+ });
237
+
238
+ // ── Legacy import command ───────────────────────────────────────────────────────
239
+
240
+ const legacyCmd = program
241
+ .command('legacy')
242
+ .description('Legacy data management (import and cleanup)');
243
+
244
+ const importCmd = legacyCmd.command('import');
245
+ importCmd
246
+ .command('openclaw')
247
+ .description(
248
+ 'Import OpenClaw legacy data into PD Runtime v2 SQLite. ' +
249
+ 'Run this once per workspace before using trajectory/history/context commands.',
250
+ )
251
+ .option('-w, --workspace <path>', 'Workspace directory (required)')
252
+ .option('--json', 'Output raw JSON')
253
+ .action(async (opts) => {
254
+ await handleLegacyImportOpenClaw(opts);
255
+ });
256
+
257
+ // ── Diagnostician run/status commands ─────────────────────────────────────
258
+
259
+ const diagnoseCmd = program
260
+ .command('diagnose')
261
+ .description('Diagnostician execution and status inspection');
262
+
263
+ diagnoseCmd
264
+ .command('status')
265
+ .description('Inspect diagnostician task status')
266
+ .requiredOption('-t, --task-id <taskId>', 'Task ID to inspect')
267
+ .option('-w, --workspace <path>', 'Workspace directory')
268
+ .option('--json', 'Output raw JSON')
269
+ .action(async (opts) => {
270
+ await handleDiagnoseStatus(opts);
271
+ });
272
+
273
+ diagnoseCmd
274
+ .command('run')
275
+ .description('Execute diagnostician runner for a task')
276
+ .requiredOption('-t, --task-id <taskId>', 'Task ID to execute')
277
+ .option('-w, --workspace <path>', 'Workspace directory')
278
+ .option('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli', 'test-double', 'pi-ai'")
279
+ .option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
280
+ .option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
281
+ .option('-a, --agent <agentId>', 'Agent ID to invoke')
282
+ .option('--provider <name>', 'LLM provider (e.g., openrouter) — for pi-ai, falls back to policy')
283
+ .option('--model <id>', 'Model ID (e.g., anthropic/claude-sonnet-4) — for pi-ai, falls back to policy')
284
+ .option('--apiKeyEnv <name>', 'Env var name for API key — for pi-ai, falls back to policy')
285
+ .option('--baseUrl <url>', 'Custom base URL — for pi-ai, falls back to policy')
286
+ .option('--maxRetries <n>', 'Max retry attempts for LLM failures — for pi-ai, falls back to policy', parseInt)
287
+ .option('--timeoutMs <ms>', 'Timeout in milliseconds — for pi-ai, falls back to policy', parseInt)
288
+ .option('--no-intake', 'Skip candidate intake after successful diagnosis')
289
+ .option('--json', 'Output raw JSON')
290
+ .action(async (opts) => {
291
+ await handleDiagnoseRun(opts);
292
+ });
293
+
294
+ // ── Runtime probe command (HG-01 HARD GATE) ─────────────────────────────────
295
+
296
+ const runtimeCmd = program
297
+ .command('runtime')
298
+ .description('Runtime inspection and health checks');
299
+
300
+ runtimeCmd
301
+ .command('canary')
302
+ .description('One-shot control plane health canary')
303
+ .option('-w, --workspace <path>', 'Workspace directory')
304
+ .option('--json', 'Output raw JSON')
305
+ .action(async (opts) => {
306
+ await handleRuntimeCanary({ workspace: opts.workspace, json: opts.json });
307
+ });
308
+
309
+ const synthCmd = runtimeCmd
310
+ .command('synthetic')
311
+ .description('Synthetic workload baseline commands');
312
+
313
+ synthCmd
314
+ .command('baseline')
315
+ .description('Run synthetic PD workload baseline (PRI-206) — deterministic, no LLM required')
316
+ .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
317
+ .option('--json', 'Output raw JSON')
318
+ .action(async (opts) => {
319
+ await handleRuntimeSyntheticBaseline({ workspace: opts.workspace, json: opts.json });
320
+ });
321
+
322
+ synthCmd
323
+ .command('flood')
324
+ .description('Run pain flood simulation (PRI-208) — deterministic dedup/stress test, no LLM required')
325
+ .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
326
+ .option('--json', 'Output raw JSON')
327
+ .option('--identical-count <n>', 'Number of identical pain signals (default: 10)', parseInt)
328
+ .option('--similar-count <n>', 'Number of similar pain signals (default: 10)', parseInt)
329
+ .option('--stress-count <n>', 'Number of stress test pain signals (default: 50)', parseInt)
330
+ .action(async (opts) => {
331
+ await handleRuntimePainFlood({
332
+ workspace: opts.workspace,
333
+ json: opts.json,
334
+ identicalCount: opts.identicalCount,
335
+ similarCount: opts.similarCount,
336
+ stressCount: opts.stressCount,
337
+ });
338
+ });
339
+
340
+ synthCmd
341
+ .command('proven-channel')
342
+ .description('Run MVP activation continuity baseline (PRI-240) — deterministic, no LLM required')
343
+ .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
344
+ .option('--json', 'Output raw JSON')
345
+ .option('--channels <channels>', 'Comma-separated channel list (prompt,code_tool_hook,defer_archive)')
346
+ .action(async (opts) => {
347
+ await handleProvenChannelBaseline({
348
+ workspace: opts.workspace,
349
+ json: opts.json,
350
+ channels: opts.channels,
351
+ });
352
+ });
353
+
354
+ runtimeCmd
355
+ .command('features')
356
+ .description('Show feature flag status (PRI-239)')
357
+ .option('-w, --workspace <path>', 'Workspace directory')
358
+ .option('--json', 'Output raw JSON')
359
+ .action(async (opts) => {
360
+ await handleRuntimeFeaturesStatus({
361
+ workspace: opts.workspace,
362
+ json: opts.json,
363
+ });
364
+ });
365
+
366
+ const demoCmd = program
367
+ .command('demo')
368
+ .description('Demo scenarios for MVP validation');
369
+
370
+ demoCmd
371
+ .command('story-a')
372
+ .description('Run Story A\' proven-channel demo (PRI-246) — full evidence→proposal→approval→activation→observation chain')
373
+ .option('-w, --workspace <path>', 'Workspace directory (default: temp workspace)')
374
+ .option('--json', 'Output raw JSON')
375
+ .option('--channels <channels>', 'Comma-separated channel list (prompt,code_tool_hook,defer_archive)')
376
+ .action(async (opts) => {
377
+ await handleDemoStoryA({
378
+ workspace: opts.workspace,
379
+ json: opts.json,
380
+ channels: opts.channels,
381
+ });
382
+ });
383
+
384
+ runtimeCmd
385
+ .command('probe')
386
+ .description('Probe runtime health and capabilities (HG-01 HARD GATE)')
387
+ .requiredOption('-r, --runtime <kind>', "Runtime kind: 'openclaw-cli' or 'pi-ai'")
388
+ .option('--openclaw-local', 'Use local OpenClaw (mutually exclusive with --openclaw-gateway)')
389
+ .option('--openclaw-gateway', 'Use gateway OpenClaw (mutually exclusive with --openclaw-local)')
390
+ .option('-a, --agent <agentId>', 'Agent ID to probe')
391
+ .option('--provider <name>', 'LLM provider (e.g., openrouter) — for pi-ai, falls back to --workspace workflows.yaml')
392
+ .option('--model <id>', 'Model ID (e.g., anthropic/claude-sonnet-4) — for pi-ai, falls back to --workspace workflows.yaml')
393
+ .option('--apiKeyEnv <name>', 'Env var name for API key (e.g., OPENROUTER_API_KEY) — for pi-ai, falls back to --workspace workflows.yaml')
394
+ .option('--baseUrl <url>', 'Custom base URL for OpenAI-compatible providers — for pi-ai, falls back to --workspace workflows.yaml')
395
+ .option('--maxRetries <n>', 'Max retry attempts for LLM failures', parseInt)
396
+ .option('--timeoutMs <ms>', 'Timeout in milliseconds for probe', parseInt)
397
+ .option('-w, --workspace <path>', 'Workspace directory — loads pi-ai policy from .state/workflows.yaml')
398
+ .option('--json', 'Output raw JSON')
399
+ .action(async (opts) => {
400
+ await handleRuntimeProbe(opts);
401
+ });
402
+
403
+ const flowCmd = runtimeCmd
404
+ .command('flow')
405
+ .description('Workflow funnel inspection');
406
+
407
+ flowCmd
408
+ .command('show')
409
+ .description('Show all workflow funnel definitions from workflows.yaml')
410
+ .option('-w, --workspace <path>', 'Workspace directory')
411
+ .option('--json', 'Output raw JSON')
412
+ .action(async (opts) => {
413
+ await handleFlowShow(opts);
414
+ });
415
+
416
+ const traceCmd = runtimeCmd
417
+ .command('trace')
418
+ .description('Trace full pain-to-ledger chain');
419
+
420
+ traceCmd
421
+ .command('show')
422
+ .description('Show full trace for a pain ID')
423
+ .requiredOption('--pain-id <id>', 'Pain ID to trace')
424
+ .option('-w, --workspace <path>', 'Workspace directory')
425
+ .option('--json', 'Output raw JSON')
426
+ .action(async (opts) => {
427
+ await handleTraceShow({ painId: opts.painId, workspace: opts.workspace, json: opts.json });
428
+ });
429
+
430
+ runtimeCmd
431
+ .command('uat')
432
+ .description('Runtime V2 chain UAT baseline runner')
433
+ .option('-w, --workspace <path>', 'Workspace directory')
434
+ .option('--count <n>', 'Number of iterations (default: 5, max: 50)', parseInt)
435
+ .option('--min-success-rate <rate>', 'Minimum success rate threshold (default: 1.0)', parseFloat)
436
+ .option('--json', 'Output machine-readable JSON summary')
437
+ .action(async (opts) => {
438
+ await handleRuntimeUat({
439
+ workspace: opts.workspace,
440
+ count: opts.count,
441
+ minSuccessRate: opts.minSuccessRate,
442
+ json: opts.json,
443
+ });
444
+ });
445
+
446
+ const runtimeHealthCmd = runtimeCmd
447
+ .command('health')
448
+ .description('Runtime V2 health inspection');
449
+
450
+ runtimeHealthCmd
451
+ .command('snapshot')
452
+ .description('Operator health snapshot combining chain, ledger, and pruning status')
453
+ .option('-w, --workspace <path>', 'Workspace directory')
454
+ .option('--json', 'Output raw JSON')
455
+ .action(async (opts) => {
456
+ await handleRuntimeHealthSnapshot({ workspace: opts.workspace, json: opts.json });
457
+ });
458
+
459
+ runtimeHealthCmd
460
+ .command('gfi')
461
+ .description('GFI workspace snapshot — active vs stale session breakdown')
462
+ .option('-w, --workspace <path>', 'Workspace directory')
463
+ .option('--json', 'Output raw JSON')
464
+ .action(async (opts) => {
465
+ await handleRuntimeGfiSnapshot({ workspace: opts.workspace, json: opts.json });
466
+ });
467
+
468
+ // PRI-82: pd runtime gfi snapshot — canonical operator command (alias of runtime health gfi)
469
+ runtimeCmd
470
+ .command('gfi')
471
+ .description('GFI workspace snapshot — active vs stale session breakdown')
472
+ .command('snapshot')
473
+ .description('GFI workspace snapshot for the operator (alias: pd runtime health gfi)')
474
+ .option('-w, --workspace <path>', 'Workspace directory')
475
+ .option('--json', 'Output raw JSON')
476
+ .action(async (opts) => {
477
+ await handleRuntimeGfiSnapshot({ workspace: opts.workspace, json: opts.json });
478
+ });
479
+
480
+ const internalizationCmd = runtimeCmd
481
+ .command('internalization')
482
+ .description('Internalization Engine operator visibility');
483
+
484
+ internalizationCmd
485
+ .command('queue')
486
+ .description('Show PI task queue health snapshot')
487
+ .option('-w, --workspace <path>', 'Workspace directory')
488
+ .option('--json', 'Output raw JSON')
489
+ .action(async (opts) => {
490
+ await handleRuntimeInternalizationQueue({ workspace: opts.workspace, json: opts.json });
491
+ });
492
+
493
+ internalizationCmd
494
+ .command('wake-once')
495
+ .description('Dry-run lease evaluation for the next leasable PI task')
496
+ .option('-w, --workspace <path>', 'Workspace directory')
497
+ .option('--dry-run', 'Evaluate lease without acquiring (required)', false)
498
+ .option('--json', 'Output raw JSON')
499
+ .action(async (opts) => {
500
+ await handleRuntimeInternalizationWakeOnce({ workspace: opts.workspace, dryRun: opts.dryRun, json: opts.json });
501
+ });
502
+
503
+ internalizationCmd
504
+ .command('run-once')
505
+ .description('Wake-and-run: lease the next PI task and execute it')
506
+ .option('-w, --workspace <path>', 'Workspace directory')
507
+ .option('--runner <kind>', 'Runner kind to execute (default: dreamer)', 'dreamer')
508
+ .option('--runtime <kind>', 'Runtime adapter kind: config (from workflows.yaml), pi-ai, openclaw-cli, test-double (default: config)', 'config')
509
+ .option('--allow-test-double', 'Acknowledge that test-double runtime will mutate real queue state')
510
+ .option('--enqueue-next', 'After successful runner execution, commit successor task to queue')
511
+ .option('--timeout-ms <ms>', 'Runner timeout in milliseconds (default: 300000, overrides workflows.yaml)', parseInt)
512
+ .option('--json', 'Output raw JSON')
513
+ .action(async (opts) => {
514
+ await handleRuntimeInternalizationRunOnce({ workspace: opts.workspace, json: opts.json, runtime: opts.runtime, runner: opts.runner, allowTestDouble: opts.allowTestDouble, enqueueNext: opts.enqueueNext, timeoutMs: opts.timeoutMs });
515
+ });
516
+
517
+ internalizationCmd
518
+ .command('integrity')
519
+ .description('Check internalization chain integrity')
520
+ .option('-w, --workspace <path>', 'Workspace directory')
521
+ .option('--json', 'Output raw JSON')
522
+ .action(async (opts) => {
523
+ await handleRuntimeInternalizationIntegrity({ workspace: opts.workspace, json: opts.json });
524
+ });
525
+
526
+ internalizationCmd
527
+ .command('integrity-repair')
528
+ .description('Repair broken internalization chain links (operator repair path)')
529
+ .option('-w, --workspace <path>', 'Workspace directory')
530
+ .option('--dry-run', 'Report only, no modifications')
531
+ .option('--confirm', 'Actually repair broken links')
532
+ .option('--json', 'Output raw JSON')
533
+ .action(async (opts) => {
534
+ await handleRuntimeInternalizationIntegrityRepair({ workspace: opts.workspace, confirm: opts.confirm, dryRun: opts.dryRun, json: opts.json });
535
+ });
536
+
537
+ internalizationCmd
538
+ .command('enqueue-successors')
539
+ .description('Enqueue successor tasks for succeeded internalization tasks missing successors')
540
+ .option('-w, --workspace <path>', 'Workspace directory')
541
+ .option('--dry-run', 'Report only, no modifications (default)')
542
+ .option('--confirm', 'Actually create successor tasks')
543
+ .option('--json', 'Output raw JSON')
544
+ .action(async (opts) => {
545
+ await handleRuntimeInternalizationEnqueueSuccessors({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
546
+ });
547
+
548
+ const activationCmd = runtimeCmd
549
+ .command('activation')
550
+ .description('Activation dispatch operations');
551
+
552
+ activationCmd
553
+ .command('dispatch')
554
+ .description('Dispatch an activation for a rollout-reviewed artifact')
555
+ .requiredOption('-a, --artifact-id <id>', 'PIArtifact ID to activate')
556
+ .option('-w, --workspace <path>', 'Workspace directory')
557
+ .option('-c, --channel <channel>', 'Activation channel (prompt|defer_archive)', 'prompt')
558
+ .option('--dry-run', 'Dry-run mode (default, no writes)')
559
+ .option('--confirm', 'Confirm and write activation record')
560
+ .option('--json', 'Output raw JSON')
561
+ .action(async (opts) => {
562
+ await handleRuntimeActivationDispatch({
563
+ workspace: opts.workspace,
564
+ artifactId: opts.artifactId,
565
+ channel: opts.channel,
566
+ dryRun: opts.dryRun,
567
+ confirm: opts.confirm,
568
+ json: opts.json,
569
+ });
570
+ });
571
+
572
+ const diagnosticsCmd = runtimeCmd
573
+ .command('diagnostics')
574
+ .description('Control plane diagnostic bundle operations');
575
+
576
+ const recoveryCmd = runtimeCmd
577
+ .command('recovery')
578
+ .description('Runtime V2 lease recovery operations');
579
+
580
+ recoveryCmd
581
+ .command('sweep')
582
+ .description('Detect and optionally recover expired leases')
583
+ .option('-w, --workspace <path>', 'Workspace directory')
584
+ .option('--dry-run', 'Report only, no modifications (default)')
585
+ .option('--confirm', 'Actually recover expired leases')
586
+ .option('--json', 'Output raw JSON')
587
+ .action(async (opts) => {
588
+ await handleRuntimeRecoverySweep({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, json: opts.json });
589
+ });
590
+
591
+ diagnosticsCmd
592
+ .command('export')
593
+ .description('Export diagnostic bundle for AI assistant analysis')
594
+ .option('-w, --workspace <path>', 'Workspace directory')
595
+ .option('--out <dir>', 'Output directory (must be within workspace)')
596
+ .option('--json', 'Output raw JSON')
597
+ .action(async (opts) => {
598
+ await handleRuntimeDiagnosticsExport({ workspace: opts.workspace, out: opts.out, json: opts.json });
599
+ });
600
+
601
+ const pruningCmd = runtimeCmd
602
+ .command('pruning')
603
+ .description('Non-destructive pruning metrics and health signals');
604
+
605
+ pruningCmd
606
+ .command('report')
607
+ .description('Show pruning health report — watch/review principle signals')
608
+ .option('-w, --workspace <path>', 'Workspace directory')
609
+ .option('--json', 'Output raw JSON')
610
+ .action((opts) => {
611
+ handlePruningReport({ workspace: opts.workspace, json: opts.json });
612
+ });
613
+
614
+ pruningCmd
615
+ .command('explain')
616
+ .description('Explain why a specific principle was flagged')
617
+ .requiredOption('--principle-id <id>', 'Principle ID to explain')
618
+ .option('-w, --workspace <path>', 'Workspace directory')
619
+ .option('--json', 'Output raw JSON')
620
+ .action((opts) => {
621
+ handlePruningExplain({ principleId: opts.principleId, workspace: opts.workspace, json: opts.json });
622
+ });
623
+
624
+ pruningCmd
625
+ .command('review')
626
+ .description('Record a human pruning decision for a flagged principle')
627
+ .requiredOption('--principle-id <id>', 'Principle ID to review')
628
+ .requiredOption('--decision <decision>', "Decision: keep, defer, or archive-candidate")
629
+ .option('--note <text>', 'Review note (required for archive-candidate)')
630
+ .option('--reviewer <name>', 'Reviewer name', 'operator')
631
+ .option('-w, --workspace <path>', 'Workspace directory')
632
+ .option('--json', 'Output raw JSON')
633
+ .action((opts) => {
634
+ handlePruningReview({
635
+ principleId: opts.principleId,
636
+ decision: opts.decision,
637
+ note: opts.note,
638
+ reviewer: opts.reviewer,
639
+ workspace: opts.workspace,
640
+ json: opts.json,
641
+ });
642
+ });
643
+
644
+ pruningCmd
645
+ .command('rollback')
646
+ .description('Restore a masked principle to injection by overriding archive-candidate')
647
+ .requiredOption('--principle-id <id>', 'Principle ID to restore')
648
+ .option('--note <text>', 'Reason for rollback')
649
+ .option('--reviewer <name>', 'Reviewer name', 'operator')
650
+ .option('-w, --workspace <path>', 'Workspace directory')
651
+ .option('--json', 'Output raw JSON')
652
+ .action((opts) => {
653
+ handlePruningRollback({
654
+ principleId: opts.principleId,
655
+ note: opts.note,
656
+ reviewer: opts.reviewer,
657
+ workspace: opts.workspace,
658
+ json: opts.json,
659
+ });
660
+ });
661
+
662
+ pruningCmd
663
+ .command('orphans')
664
+ .description('List orphan derived candidates not found in state.db')
665
+ .option('-w, --workspace <path>', 'Workspace directory')
666
+ .option('--dry-run', 'Report only, no modifications (default)')
667
+ .option('--confirm', 'Actually remove orphan references from ledger')
668
+ .option('--json', 'Output raw JSON')
669
+ .action((opts) => {
670
+ handlePruningOrphans({
671
+ workspace: opts.workspace,
672
+ dryRun: opts.dryRun,
673
+ confirm: opts.confirm,
674
+ json: opts.json,
675
+ });
676
+ });
677
+
678
+ // ── Candidate inspection commands ───────────────────────────────────────────
679
+
680
+ const candidateCmd = program
681
+ .command('candidate')
682
+ .description('Principle candidate inspection');
683
+
684
+ candidateCmd
685
+ .command('list')
686
+ .description('List principle candidates for a task')
687
+ .requiredOption('-t, --task-id <taskId>', 'Task ID to query')
688
+ .option('-w, --workspace <path>', 'Workspace directory')
689
+ .option('--json', 'Output raw JSON')
690
+ .action(async (opts) => {
691
+ await handleCandidateList(opts);
692
+ });
693
+
694
+ candidateCmd
695
+ .command('show [candidateId]')
696
+ .description('Show detail for a single principle candidate')
697
+ .requiredOption('-w, --workspace <path>', 'Workspace directory')
698
+ .option('--candidate-id <id>', 'Candidate ID (alternative to positional arg)')
699
+ .option('--json', 'Output raw JSON')
700
+ .action(async (candidateId, opts) => {
701
+ const resolvedId = opts.candidateId ?? candidateId;
702
+ if (!resolvedId) {
703
+ console.error('Error: candidate ID is required (positional or --candidate-id)');
704
+ process.exitCode = 1;
705
+ return;
706
+ }
707
+ if (candidateId && opts.candidateId && candidateId !== opts.candidateId) {
708
+ console.error(`Error: conflicting candidate IDs: positional="${candidateId}", --candidate-id="${opts.candidateId}"`);
709
+ process.exitCode = 1;
710
+ return;
711
+ }
712
+ await handleCandidateShow({ candidateId: resolvedId, ...opts });
713
+ });
714
+
715
+ candidateCmd
716
+ .command('intake')
717
+ .description('Intake a principle candidate into the ledger')
718
+ .requiredOption('--candidate-id <id>', 'Candidate ID to intake')
719
+ .option('-w, --workspace <path>', 'Workspace directory')
720
+ .option('--json', 'Output as JSON')
721
+ .option('--dry-run', 'Show what would be written without writing')
722
+ .action(async (opts) => {
723
+ await handleCandidateIntake(opts);
724
+ });
725
+
726
+ candidateCmd
727
+ .command('audit')
728
+ .description('Audit candidate/ledger consistency for Runtime v2')
729
+ .option('-w, --workspace <path>', 'Workspace directory')
730
+ .option('--json', 'Output as JSON')
731
+ .action(async (opts) => {
732
+ await handleCandidateAudit(opts);
733
+ });
734
+
735
+ candidateCmd
736
+ .command('repair')
737
+ .description('Repair consumed candidate with missing ledger entry')
738
+ .requiredOption('--candidate-id <id>', 'Candidate ID to repair')
739
+ .option('-w, --workspace <path>', 'Workspace directory')
740
+ .option('--json', 'Output as JSON')
741
+ .action(async (opts) => {
742
+ await handleCandidateRepair(opts);
743
+ });
744
+
745
+ candidateCmd
746
+ .command('route')
747
+ .description('Show internalization route decision for a candidate')
748
+ .requiredOption('--candidate-id <id>', 'Candidate ID to inspect')
749
+ .option('-w, --workspace <path>', 'Workspace directory')
750
+ .option('--json', 'Output as JSON')
751
+ .action(async (opts) => {
752
+ await handleCandidateRoute(opts);
753
+ });
754
+
755
+ candidateCmd
756
+ .command('internalize')
757
+ .description('Seed internalization Dreamer task from a candidate')
758
+ .requiredOption('--candidate-id <id>', 'Candidate ID to internalize')
759
+ .option('-w, --workspace <path>', 'Workspace directory')
760
+ .option('--json', 'Output as JSON')
761
+ .option('--dry-run', 'Preview without writing to database')
762
+ .action(async (opts) => {
763
+ await handleCandidateInternalize(opts);
764
+ });
765
+
766
+ const candidateInternalizationCmd = candidateCmd
767
+ .command('internalization')
768
+ .description('Internalization pipeline operations for candidates');
769
+
770
+ candidateInternalizationCmd
771
+ .command('backfill')
772
+ .description('Backfill dreamer tasks for consumed candidates created before Internalization Engine')
773
+ .option('-w, --workspace <path>', 'Workspace directory')
774
+ .option('--dry-run', 'Report only, no modifications (default)')
775
+ .option('--confirm', 'Actually create missing dreamer tasks')
776
+ .option('--include-pending', 'Include pending candidates (intake first, then seed dreamer)')
777
+ .option('--json', 'Output as JSON')
778
+ .action(async (opts) => {
779
+ await handleCandidateInternalizationBackfill({ workspace: opts.workspace, dryRun: opts.dryRun, confirm: opts.confirm, includePending: opts.includePending, json: opts.json });
780
+ });
781
+
782
+ // ── Artifact inspection commands ────────────────────────────────────────────
783
+
784
+ const artifactCmd = program
785
+ .command('artifact')
786
+ .description('Artifact registry inspection');
787
+
788
+ artifactCmd
789
+ .command('show <artifactId>')
790
+ .description('Show artifact content and its associated candidates')
791
+ .requiredOption('-w, --workspace <path>', 'Workspace directory')
792
+ .option('--json', 'Output raw JSON')
793
+ .action(async (artifactId, opts) => {
794
+ await handleArtifactShow({ artifactId, ...opts });
795
+ });
796
+
797
+ const _legacyCleanupCmd = legacyCmd
798
+ .command('cleanup')
799
+ .description('Clean legacy empathy/diagnostician artifacts from workspace')
800
+ .requiredOption('-w, --workspace <path>', 'Workspace directory')
801
+ .option('--dry-run', 'Show what would be cleaned without applying', false)
802
+ .option('--apply', 'Actually apply the cleanup', false)
803
+ .action(async (opts) => {
804
+ const apply = opts.apply ?? false;
805
+ if (!apply && !opts.dryRun) {
806
+ console.error('Specify --dry-run or --apply');
807
+ process.exit(1);
808
+ }
809
+ await handleLegacyCleanup(opts.workspace, apply);
810
+ });
811
+
812
+ program
813
+ .command('console')
814
+ .description('Start the pd-console web UI for principle review')
815
+ .option('-w, --workspace <path>', 'Workspace directory')
816
+ .option('-p, --port <port>', 'Port to listen on', '3100')
817
+ .option('--no-auth', 'Disable authentication (local dev only)', false)
818
+ .option('--json', 'Output JSON status', false)
819
+ .action(async (opts) => {
820
+ const { handleConsole } = await import('./commands/console.js');
821
+ await handleConsole({
822
+ workspace: opts.workspace,
823
+ port: opts.port,
824
+ noAuth: opts.noAuth,
825
+ json: opts.json,
826
+ });
827
+ });
828
+
829
+ program.parse();