@neurcode-ai/cli 0.12.0 → 0.15.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 (212) hide show
  1. package/README.md +60 -8
  2. package/dist/api-client.d.ts +284 -0
  3. package/dist/api-client.d.ts.map +1 -1
  4. package/dist/api-client.js +111 -0
  5. package/dist/api-client.js.map +1 -1
  6. package/dist/commands/activate.d.ts +82 -0
  7. package/dist/commands/activate.d.ts.map +1 -0
  8. package/dist/commands/activate.js +551 -0
  9. package/dist/commands/activate.js.map +1 -0
  10. package/dist/commands/admission.d.ts +67 -0
  11. package/dist/commands/admission.d.ts.map +1 -0
  12. package/dist/commands/admission.js +350 -0
  13. package/dist/commands/admission.js.map +1 -0
  14. package/dist/commands/agent.d.ts +3 -0
  15. package/dist/commands/agent.d.ts.map +1 -0
  16. package/dist/commands/agent.js +2045 -0
  17. package/dist/commands/agent.js.map +1 -0
  18. package/dist/commands/demo.d.ts +3 -0
  19. package/dist/commands/demo.d.ts.map +1 -0
  20. package/dist/commands/demo.js +102 -0
  21. package/dist/commands/demo.js.map +1 -0
  22. package/dist/commands/governance.d.ts.map +1 -1
  23. package/dist/commands/governance.js +12 -0
  24. package/dist/commands/governance.js.map +1 -1
  25. package/dist/commands/home.d.ts +21 -0
  26. package/dist/commands/home.d.ts.map +1 -0
  27. package/dist/commands/home.js +253 -0
  28. package/dist/commands/home.js.map +1 -0
  29. package/dist/commands/init.d.ts.map +1 -1
  30. package/dist/commands/init.js +58 -44
  31. package/dist/commands/init.js.map +1 -1
  32. package/dist/commands/login.d.ts +1 -1
  33. package/dist/commands/login.d.ts.map +1 -1
  34. package/dist/commands/login.js +44 -22
  35. package/dist/commands/login.js.map +1 -1
  36. package/dist/commands/profile.d.ts +14 -0
  37. package/dist/commands/profile.d.ts.map +1 -0
  38. package/dist/commands/profile.js +118 -0
  39. package/dist/commands/profile.js.map +1 -0
  40. package/dist/commands/quickstart.d.ts +2 -2
  41. package/dist/commands/quickstart.d.ts.map +1 -1
  42. package/dist/commands/quickstart.js +33 -30
  43. package/dist/commands/quickstart.js.map +1 -1
  44. package/dist/commands/remediate-export.d.ts +6 -1
  45. package/dist/commands/remediate-export.d.ts.map +1 -1
  46. package/dist/commands/remediate-export.js +375 -8
  47. package/dist/commands/remediate-export.js.map +1 -1
  48. package/dist/commands/replay.d.ts.map +1 -1
  49. package/dist/commands/replay.js +84 -0
  50. package/dist/commands/replay.js.map +1 -1
  51. package/dist/commands/run.d.ts +3 -0
  52. package/dist/commands/run.d.ts.map +1 -0
  53. package/dist/commands/run.js +98 -0
  54. package/dist/commands/run.js.map +1 -0
  55. package/dist/commands/runtime-adapter.d.ts +8 -0
  56. package/dist/commands/runtime-adapter.d.ts.map +1 -0
  57. package/dist/commands/runtime-adapter.js +375 -0
  58. package/dist/commands/runtime-adapter.js.map +1 -0
  59. package/dist/commands/runtime-doctor.d.ts +6 -0
  60. package/dist/commands/runtime-doctor.d.ts.map +1 -0
  61. package/dist/commands/runtime-doctor.js +478 -0
  62. package/dist/commands/runtime-doctor.js.map +1 -0
  63. package/dist/commands/runtime-report.d.ts +13 -0
  64. package/dist/commands/runtime-report.d.ts.map +1 -0
  65. package/dist/commands/runtime-report.js +81 -0
  66. package/dist/commands/runtime-report.js.map +1 -0
  67. package/dist/commands/runtime-sync.d.ts +17 -0
  68. package/dist/commands/runtime-sync.d.ts.map +1 -0
  69. package/dist/commands/runtime-sync.js +656 -0
  70. package/dist/commands/runtime-sync.js.map +1 -0
  71. package/dist/commands/runtime.d.ts +16 -0
  72. package/dist/commands/runtime.d.ts.map +1 -0
  73. package/dist/commands/runtime.js +380 -0
  74. package/dist/commands/runtime.js.map +1 -0
  75. package/dist/commands/session-hook.d.ts +35 -0
  76. package/dist/commands/session-hook.d.ts.map +1 -0
  77. package/dist/commands/session-hook.js +1297 -0
  78. package/dist/commands/session-hook.js.map +1 -0
  79. package/dist/commands/session.d.ts +91 -0
  80. package/dist/commands/session.d.ts.map +1 -1
  81. package/dist/commands/session.js +1226 -0
  82. package/dist/commands/session.js.map +1 -1
  83. package/dist/commands/verify-output.d.ts.map +1 -1
  84. package/dist/commands/verify-output.js +22 -0
  85. package/dist/commands/verify-output.js.map +1 -1
  86. package/dist/commands/verify.d.ts.map +1 -1
  87. package/dist/commands/verify.js +21 -3
  88. package/dist/commands/verify.js.map +1 -1
  89. package/dist/commands/whoami.d.ts +7 -4
  90. package/dist/commands/whoami.d.ts.map +1 -1
  91. package/dist/commands/whoami.js +59 -34
  92. package/dist/commands/whoami.js.map +1 -1
  93. package/dist/config.d.ts.map +1 -1
  94. package/dist/config.js +24 -5
  95. package/dist/config.js.map +1 -1
  96. package/dist/daemon/routes.d.ts.map +1 -1
  97. package/dist/daemon/routes.js +8 -0
  98. package/dist/daemon/routes.js.map +1 -1
  99. package/dist/daemon/server.d.ts.map +1 -1
  100. package/dist/daemon/server.js +88 -0
  101. package/dist/daemon/server.js.map +1 -1
  102. package/dist/governance/canonical-pipeline.d.ts.map +1 -1
  103. package/dist/governance/canonical-pipeline.js +29 -3
  104. package/dist/governance/canonical-pipeline.js.map +1 -1
  105. package/dist/governance/impact-analysis.d.ts +27 -0
  106. package/dist/governance/impact-analysis.d.ts.map +1 -0
  107. package/dist/governance/impact-analysis.js +274 -0
  108. package/dist/governance/impact-analysis.js.map +1 -0
  109. package/dist/index.js +484 -29
  110. package/dist/index.js.map +1 -1
  111. package/dist/intent-engine/matcher.d.ts.map +1 -1
  112. package/dist/intent-engine/matcher.js +3 -12
  113. package/dist/intent-engine/matcher.js.map +1 -1
  114. package/dist/utils/admission-artifact.d.ts +59 -0
  115. package/dist/utils/admission-artifact.d.ts.map +1 -0
  116. package/dist/utils/admission-artifact.js +410 -0
  117. package/dist/utils/admission-artifact.js.map +1 -0
  118. package/dist/utils/agent-adapter-setup.d.ts +80 -0
  119. package/dist/utils/agent-adapter-setup.d.ts.map +1 -0
  120. package/dist/utils/agent-adapter-setup.js +577 -0
  121. package/dist/utils/agent-adapter-setup.js.map +1 -0
  122. package/dist/utils/agent-guard-supervisor.d.ts +75 -0
  123. package/dist/utils/agent-guard-supervisor.d.ts.map +1 -0
  124. package/dist/utils/agent-guard-supervisor.js +388 -0
  125. package/dist/utils/agent-guard-supervisor.js.map +1 -0
  126. package/dist/utils/agent-guard.d.ts +92 -0
  127. package/dist/utils/agent-guard.d.ts.map +1 -0
  128. package/dist/utils/agent-guard.js +326 -0
  129. package/dist/utils/agent-guard.js.map +1 -0
  130. package/dist/utils/agent-session-launcher.d.ts +89 -0
  131. package/dist/utils/agent-session-launcher.d.ts.map +1 -0
  132. package/dist/utils/agent-session-launcher.js +308 -0
  133. package/dist/utils/agent-session-launcher.js.map +1 -0
  134. package/dist/utils/bash-command-analysis.d.ts +19 -0
  135. package/dist/utils/bash-command-analysis.d.ts.map +1 -0
  136. package/dist/utils/bash-command-analysis.js +295 -0
  137. package/dist/utils/bash-command-analysis.js.map +1 -0
  138. package/dist/utils/consequence-nudges.d.ts +30 -0
  139. package/dist/utils/consequence-nudges.d.ts.map +1 -0
  140. package/dist/utils/consequence-nudges.js +313 -0
  141. package/dist/utils/consequence-nudges.js.map +1 -0
  142. package/dist/utils/drift-intelligence.d.ts.map +1 -1
  143. package/dist/utils/drift-intelligence.js +29 -7
  144. package/dist/utils/drift-intelligence.js.map +1 -1
  145. package/dist/utils/git-coverage.d.ts +57 -0
  146. package/dist/utils/git-coverage.d.ts.map +1 -0
  147. package/dist/utils/git-coverage.js +302 -0
  148. package/dist/utils/git-coverage.js.map +1 -0
  149. package/dist/utils/gitignore.d.ts.map +1 -1
  150. package/dist/utils/gitignore.js +2 -1
  151. package/dist/utils/gitignore.js.map +1 -1
  152. package/dist/utils/governed-intent.d.ts +10 -0
  153. package/dist/utils/governed-intent.d.ts.map +1 -0
  154. package/dist/utils/governed-intent.js +108 -0
  155. package/dist/utils/governed-intent.js.map +1 -0
  156. package/dist/utils/hook-heartbeat.d.ts +55 -0
  157. package/dist/utils/hook-heartbeat.d.ts.map +1 -0
  158. package/dist/utils/hook-heartbeat.js +116 -0
  159. package/dist/utils/hook-heartbeat.js.map +1 -0
  160. package/dist/utils/intent-continuity.d.ts +21 -0
  161. package/dist/utils/intent-continuity.d.ts.map +1 -0
  162. package/dist/utils/intent-continuity.js +192 -0
  163. package/dist/utils/intent-continuity.js.map +1 -0
  164. package/dist/utils/messages.d.ts +1 -1
  165. package/dist/utils/messages.d.ts.map +1 -1
  166. package/dist/utils/messages.js +35 -23
  167. package/dist/utils/messages.js.map +1 -1
  168. package/dist/utils/runtime-companion.d.ts +137 -0
  169. package/dist/utils/runtime-companion.d.ts.map +1 -0
  170. package/dist/utils/runtime-companion.js +231 -0
  171. package/dist/utils/runtime-companion.js.map +1 -0
  172. package/dist/utils/runtime-connection.d.ts +46 -0
  173. package/dist/utils/runtime-connection.d.ts.map +1 -0
  174. package/dist/utils/runtime-connection.js +148 -0
  175. package/dist/utils/runtime-connection.js.map +1 -0
  176. package/dist/utils/runtime-evidence.d.ts +68 -0
  177. package/dist/utils/runtime-evidence.d.ts.map +1 -0
  178. package/dist/utils/runtime-evidence.js +248 -0
  179. package/dist/utils/runtime-evidence.js.map +1 -0
  180. package/dist/utils/runtime-live.d.ts +33 -0
  181. package/dist/utils/runtime-live.d.ts.map +1 -0
  182. package/dist/utils/runtime-live.js +361 -0
  183. package/dist/utils/runtime-live.js.map +1 -0
  184. package/dist/utils/runtime-outbox.d.ts +76 -0
  185. package/dist/utils/runtime-outbox.d.ts.map +1 -0
  186. package/dist/utils/runtime-outbox.js +410 -0
  187. package/dist/utils/runtime-outbox.js.map +1 -0
  188. package/dist/utils/runtime-receipt.d.ts +50 -0
  189. package/dist/utils/runtime-receipt.d.ts.map +1 -0
  190. package/dist/utils/runtime-receipt.js +223 -0
  191. package/dist/utils/runtime-receipt.js.map +1 -0
  192. package/dist/utils/runtime-state.d.ts +44 -0
  193. package/dist/utils/runtime-state.d.ts.map +1 -0
  194. package/dist/utils/runtime-state.js +151 -0
  195. package/dist/utils/runtime-state.js.map +1 -0
  196. package/dist/utils/state.d.ts +21 -0
  197. package/dist/utils/state.d.ts.map +1 -1
  198. package/dist/utils/state.js +30 -0
  199. package/dist/utils/state.js.map +1 -1
  200. package/dist/utils/structural-understanding.d.ts +334 -0
  201. package/dist/utils/structural-understanding.d.ts.map +1 -0
  202. package/dist/utils/structural-understanding.js +2316 -0
  203. package/dist/utils/structural-understanding.js.map +1 -0
  204. package/dist/utils/v0-governance.d.ts +197 -0
  205. package/dist/utils/v0-governance.d.ts.map +1 -0
  206. package/dist/utils/v0-governance.js +904 -0
  207. package/dist/utils/v0-governance.js.map +1 -0
  208. package/package.json +6 -6
  209. package/dist/utils/box.d.ts +0 -16
  210. package/dist/utils/box.d.ts.map +0 -1
  211. package/dist/utils/box.js +0 -85
  212. package/dist/utils/box.js.map +0 -1
package/dist/index.js CHANGED
@@ -54,6 +54,7 @@ const feedback_1 = require("./commands/feedback");
54
54
  const guard_1 = require("./commands/guard");
55
55
  const bootstrap_1 = require("./commands/bootstrap");
56
56
  const quickstart_1 = require("./commands/quickstart");
57
+ const home_1 = require("./commands/home");
57
58
  const bootstrap_policy_1 = require("./commands/bootstrap-policy");
58
59
  const messages_1 = require("./utils/messages");
59
60
  const config_2 = require("./config");
@@ -65,6 +66,18 @@ const control_plane_1 = require("./commands/control-plane");
65
66
  const workspace_1 = require("./commands/workspace");
66
67
  const replay_1 = require("./commands/replay");
67
68
  const governance_1 = require("./commands/governance");
69
+ const profile_1 = require("./commands/profile");
70
+ const session_hook_1 = require("./commands/session-hook");
71
+ const runtime_adapter_1 = require("./commands/runtime-adapter");
72
+ const agent_1 = require("./commands/agent");
73
+ const activate_1 = require("./commands/activate");
74
+ const run_1 = require("./commands/run");
75
+ const runtime_doctor_1 = require("./commands/runtime-doctor");
76
+ const runtime_report_1 = require("./commands/runtime-report");
77
+ const runtime_sync_1 = require("./commands/runtime-sync");
78
+ const runtime_1 = require("./commands/runtime");
79
+ const admission_1 = require("./commands/admission");
80
+ const demo_1 = require("./commands/demo");
68
81
  const execution_bus_1 = require("./utils/execution-bus");
69
82
  const execution_actions_1 = require("./utils/execution-actions");
70
83
  // Read version from package.json
@@ -80,31 +93,71 @@ catch (error) {
80
93
  const program = new commander_1.Command();
81
94
  const CORE_WORKFLOW_STEPS = [
82
95
  {
83
- command: 'neurcode start "<intent>"',
84
- description: 'Declare governance context and bounded implementation scope',
96
+ command: 'neurcode agent start codex --goal "<task>"',
97
+ description: 'Start a governed session for non-Claude agents using the universal runtime handshake',
85
98
  },
86
99
  {
87
- command: 'neurcode verify --evidence',
88
- description: 'Verify the current diff against intent, policy, and change contracts',
100
+ command: 'neurcode run claude --goal "<task>"',
101
+ description: 'Start a governed AI coding session and print the agent runtime handshake',
89
102
  },
90
103
  {
91
- command: 'neurcode replay --json',
92
- description: 'Inspect deterministic replay and provenance receipts from the last run',
104
+ command: 'neurcode activate claude --connect <token>',
105
+ description: 'Install Claude Code governance hooks, pair the repo, and enable runtime evidence auto-sync',
106
+ },
107
+ {
108
+ command: 'neurcode status',
109
+ description: 'Inspect the active in-flow governance session and latest boundary block',
110
+ },
111
+ {
112
+ command: 'neurcode runtime cloud-status',
113
+ description: 'Read dashboard-visible live session, approval, transport, and ingestion state',
93
114
  },
94
115
  {
95
- command: 'neurcode remediate-export --finding-index 0',
96
- description: 'Export bounded remediation context for an external remediation tool',
116
+ command: 'neurcode report --runtime',
117
+ description: 'Summarize blocked edits, approvals, owners, and replay records across sessions',
97
118
  },
98
119
  {
99
- command: 'neurcode verify --ci',
100
- description: 'Re-verify in CI with deterministic receipts and governance artifacts',
120
+ command: 'neurcode sync --runtime',
121
+ description: 'Manual fallback upload for finished in-flow session records',
122
+ },
123
+ {
124
+ command: 'neurcode admission export',
125
+ description: 'Export the latest source-free runtime admission record for the GitHub Action',
126
+ },
127
+ {
128
+ command: 'neurcode demo rehearse',
129
+ description: 'Print the canonical production demo rehearsal protocol',
130
+ },
131
+ {
132
+ command: 'neurcode login',
133
+ description: 'Connect this machine/runtime to Neurcode with browser approval',
134
+ },
135
+ {
136
+ command: 'neurcode init',
137
+ description: 'Bind this repository to a personal or organization workspace',
138
+ },
139
+ {
140
+ command: 'neurcode start "<intent>"',
141
+ description: 'Declare governance context for a bounded implementation scope',
142
+ },
143
+ {
144
+ command: 'neurcode replay --json',
145
+ description: 'Inspect deterministic replay and source-free runtime receipts',
101
146
  },
102
147
  ];
103
148
  const CANONICAL_OPERATOR_COMMAND_NAMES = new Set([
149
+ 'activate',
150
+ 'agent',
151
+ 'run',
152
+ 'status',
153
+ 'runtime',
154
+ 'sessions',
155
+ 'report',
156
+ 'sync',
157
+ 'admission',
158
+ 'demo',
104
159
  'start',
105
160
  'quickstart',
106
- 'verify',
107
- 'remediate-export',
108
161
  'replay',
109
162
  ]);
110
163
  const ENTERPRISE_OPERATIONS_COMMAND_NAMES = new Set([
@@ -199,12 +252,12 @@ function buildAdvancedLegacyHints(root) {
199
252
  return fallbackCommands.map((commandName) => `neurcode ${commandName}`);
200
253
  }
201
254
  function configurePrimaryHelpView(root) {
202
- const primaryOrder = ['start', 'quickstart', 'verify', 'remediate-export', 'replay'];
255
+ const primaryOrder = ['activate', 'agent', 'run', 'status', 'runtime', 'sessions', 'report', 'sync', 'admission', 'demo', 'login', 'init', 'start', 'quickstart', 'replay'];
203
256
  root.configureHelp({
204
257
  visibleCommands: (command) => {
205
258
  const filtered = command.commands.filter((subcommand) => {
206
259
  const commandName = subcommand.name();
207
- return commandName === 'help' || CANONICAL_OPERATOR_COMMAND_NAMES.has(commandName);
260
+ return commandName === 'help' || commandName === 'login' || commandName === 'init' || CANONICAL_OPERATOR_COMMAND_NAMES.has(commandName);
208
261
  });
209
262
  return filtered.sort((left, right) => {
210
263
  const leftIndex = primaryOrder.indexOf(left.name());
@@ -217,11 +270,21 @@ function configurePrimaryHelpView(root) {
217
270
  });
218
271
  }
219
272
  function printCoreWorkflowGuide() {
220
- console.log(chalk.bold.cyan('\n🛡️ Neurcode Governance Workflow\n'));
221
- console.log(chalk.bold.white('Canonical Workflow:'));
273
+ // Operational lifecycle guide. Same aesthetic as the welcome banner and
274
+ // neurcode home - subtle sophistication, no emoji ornaments, info dense.
275
+ // The lifecycle bar mirrors what the welcome banner shows so identity is
276
+ // coherent across surfaces. (See docs/ux/final-operational-experience-report.md.)
277
+ console.log('');
278
+ console.log(`${chalk.bold('neurcode')}${chalk.dim(' · operational lifecycle')}`);
279
+ console.log('');
280
+ console.log(chalk.dim(' connect repo -> activate agent -> govern session -> approve exact path -> export evidence'));
281
+ console.log('');
282
+ console.log(` ${chalk.bold('Canonical commands')}`);
222
283
  CORE_WORKFLOW_STEPS.forEach((step) => console.log(chalk.dim(formatCoreWorkflowStep(step))));
223
284
  console.log('');
224
- console.log(chalk.dim('Run `neurcode --help` to see enterprise, runtime-engineering, and compatibility commands.\n'));
285
+ console.log(chalk.dim(' See ') + chalk.cyan('neurcode home') + chalk.dim(' for current runtime state. ') +
286
+ chalk.dim('Run ') + chalk.cyan('neurcode whoami') + chalk.dim(' to inspect user/workspace/repo identity.'));
287
+ console.log('');
225
288
  }
226
289
  function formatCommandList(commandNames) {
227
290
  return commandNames.length > 0
@@ -374,9 +437,46 @@ program
374
437
  (0, brain_1.brainCommand)(program);
375
438
  (0, policy_1.policyCommand)(program);
376
439
  (0, governance_1.governanceCommand)(program);
440
+ // V0: in-flow governance
441
+ (0, profile_1.profileCommand)(program);
442
+ (0, session_hook_1.sessionHookCommand)(program);
443
+ (0, runtime_adapter_1.runtimeAdapterCommand)(program);
444
+ (0, agent_1.agentCommand)(program);
445
+ (0, activate_1.activateCommand)(program);
446
+ (0, run_1.runCommand)(program);
447
+ (0, runtime_report_1.reportCommand)(program);
448
+ (0, runtime_sync_1.syncCommand)(program);
449
+ (0, runtime_1.runtimeCommand)(program);
450
+ (0, admission_1.admissionCommand)(program);
451
+ (0, demo_1.demoCommand)(program);
452
+ program
453
+ .command('status')
454
+ .description('Show the active in-flow governance session for this repository')
455
+ .option('--session-id <id>', 'Local governance session ID (default: active session)')
456
+ .option('--dir <path>', 'Repository root (default: current directory)')
457
+ .option('--json', 'Output machine-readable JSON')
458
+ .action((options) => {
459
+ (0, session_1.localGovernanceStatusCommand)({
460
+ sessionId: options.sessionId,
461
+ dir: options.dir,
462
+ json: options.json === true,
463
+ });
464
+ });
465
+ program
466
+ .command('sessions')
467
+ .description('List local in-flow governance sessions for this repository')
468
+ .option('--dir <path>', 'Repository root (default: current directory)')
469
+ .option('--json', 'Output machine-readable JSON')
470
+ .action((options) => {
471
+ (0, session_1.listRuntimeSessionsCommand)({
472
+ dir: options.dir,
473
+ json: options.json === true,
474
+ });
475
+ });
377
476
  (0, control_plane_1.controlPlaneCommand)(program);
378
477
  (0, workspace_1.workspaceCommand)(program);
379
478
  (0, replay_1.replayCommand)(program);
479
+ (0, home_1.homeCommand)(program);
380
480
  // Top-level discoverability alias for `neurcode replay timeline`. Reviewers
381
481
  // asking "what changed and when?" should not need to know the subcommand
382
482
  // hierarchy. Same canonical artifact source, same deterministic output.
@@ -449,16 +549,16 @@ program
449
549
  });
450
550
  program
451
551
  .command('login')
452
- .description('Authenticate CLI with Neurcode (opens browser for approval)')
453
- .option('--org <id>', 'Authenticate for a specific organization (internal UUID)')
552
+ .description('Connect this machine/runtime to a Neurcode workspace')
553
+ .option('--org <id>', 'Connect to a specific workspace/organization (internal UUID)')
454
554
  .action((options) => {
455
555
  (0, login_1.loginCommand)({ orgId: options.org });
456
556
  });
457
557
  program
458
558
  .command('logout')
459
- .description('Log out from Neurcode CLI (removes API key)')
460
- .option('--all', 'Remove all saved API keys (all organizations)')
461
- .option('--org <id>', 'Remove saved API key for a specific organization (internal UUID)')
559
+ .description('Disconnect Neurcode runtime credentials from this machine')
560
+ .option('--all', 'Remove all saved runtime credentials (all workspaces)')
561
+ .option('--org <id>', 'Remove saved runtime credential for a specific workspace/organization')
462
562
  .action((options) => {
463
563
  (0, logout_1.logoutCommand)({
464
564
  all: options.all || false,
@@ -467,8 +567,8 @@ program
467
567
  });
468
568
  program
469
569
  .command('init')
470
- .description('Initialize project configuration (select a project)')
471
- .option('--org <id>', 'Preselect organization by internal UUID')
570
+ .description('Bind this repository to a workspace governance boundary')
571
+ .option('--org <id>', 'Preselect workspace/organization by internal UUID')
472
572
  .option('--project-id <id>', 'Link an existing project by internal UUID (non-interactive)')
473
573
  .option('--create <name>', 'Create and link a new project (non-interactive)')
474
574
  .action((options) => {
@@ -481,8 +581,17 @@ program
481
581
  program
482
582
  .command('doctor')
483
583
  .description('Enterprise readiness diagnostics (config, artifacts, API compatibility, CORS)')
584
+ .option('--runtime', 'Run local in-flow runtime diagnostics for Claude Code governance')
585
+ .option('--dir <path>', 'Repository root for --runtime diagnostics')
484
586
  .option('--json', 'Output machine-readable diagnostics JSON')
485
587
  .action((options) => {
588
+ if (options.runtime === true) {
589
+ (0, runtime_doctor_1.runtimeDoctorCommand)({
590
+ json: options.json === true,
591
+ dir: options.dir,
592
+ });
593
+ return;
594
+ }
486
595
  (0, doctor_1.doctorCommand)({
487
596
  json: options.json,
488
597
  cliVersion: version,
@@ -490,7 +599,7 @@ program
490
599
  });
491
600
  program
492
601
  .command('quickstart')
493
- .description('Guided onboarding first deterministic finding in under 2 minutes (no network required)')
602
+ .description('Local-only governance sandbox for first deterministic finding')
494
603
  .option('--force', 'Overwrite existing starter files')
495
604
  .option('--json', 'Output machine-readable JSON')
496
605
  .action(async (options) => {
@@ -554,7 +663,7 @@ program
554
663
  });
555
664
  program
556
665
  .command('whoami')
557
- .description('Show current identity and project scope')
666
+ .description('Show user, workspace, repo ownership, session, and governance boundary')
558
667
  .action(() => {
559
668
  (0, whoami_1.whoamiCommand)();
560
669
  });
@@ -832,10 +941,68 @@ sessionCmd
832
941
  .description('List all sessions for the current project')
833
942
  .option('--project-id <id>', 'Project ID')
834
943
  .option('--all', 'Show all sessions (including completed)')
944
+ .option('--local', 'List local in-flow governance sessions from .neurcode/sessions')
945
+ .option('--dir <path>', 'Repository root for --local')
946
+ .option('--json', 'Output machine-readable JSON for --local')
835
947
  .action((options) => {
836
948
  (0, session_1.listSessionsCommand)({
837
949
  projectId: options.projectId,
838
950
  all: options.all || false,
951
+ local: options.local === true,
952
+ dir: options.dir,
953
+ json: options.json === true,
954
+ });
955
+ });
956
+ sessionCmd
957
+ .command('show')
958
+ .description('Show one local in-flow governance session record')
959
+ .argument('<session-id>', 'Local governance session ID')
960
+ .option('--dir <path>', 'Repository root (default: current directory)')
961
+ .option('--json', 'Output machine-readable JSON')
962
+ .action((sessionId, options) => {
963
+ (0, session_1.showRuntimeSessionCommand)(sessionId, {
964
+ dir: options.dir,
965
+ json: options.json === true,
966
+ });
967
+ });
968
+ sessionCmd
969
+ .command('record')
970
+ .description('Build the source-free AI Change Record for a governed coding session')
971
+ .option('--session-id <id>', 'Local governance session ID (default: active, then latest)')
972
+ .option('--latest', 'Use the latest local session even if another session is active')
973
+ .option('--dir <path>', 'Repository root (default: current directory)')
974
+ .option('--json', 'Output machine-readable JSON')
975
+ .action((options) => {
976
+ (0, session_1.aiChangeRecordCommand)({
977
+ sessionId: options.sessionId,
978
+ latest: options.latest === true,
979
+ dir: options.dir,
980
+ json: options.json === true,
981
+ });
982
+ });
983
+ sessionCmd
984
+ .command('understanding')
985
+ .description('Build local TypeScript structural understanding for the active governed change')
986
+ .option('--session-id <id>', 'Local governance session ID (default: active, then latest)')
987
+ .option('--latest', 'Use the latest local session even if another session is active')
988
+ .option('--dir <path>', 'Repository root (default: current directory)')
989
+ .option('--staged', 'Analyze staged changes only')
990
+ .option('--head', 'Analyze working tree against HEAD (default)')
991
+ .option('--base <ref>', 'Analyze working tree against a specific git ref')
992
+ .option('--max-program-files <n>', 'Maximum TypeScript/JavaScript files to analyze', (value) => Number.parseInt(value, 10))
993
+ .option('--time-budget-ms <n>', 'Static analysis time budget in milliseconds', (value) => Number.parseInt(value, 10))
994
+ .option('--json', 'Output machine-readable JSON')
995
+ .action((options) => {
996
+ (0, session_1.structuralUnderstandingCommand)({
997
+ sessionId: options.sessionId,
998
+ latest: options.latest === true,
999
+ dir: options.dir,
1000
+ staged: options.staged === true,
1001
+ head: options.head === true,
1002
+ base: options.base,
1003
+ maxProgramFiles: Number.isFinite(options.maxProgramFiles) ? options.maxProgramFiles : undefined,
1004
+ timeBudgetMs: Number.isFinite(options.timeBudgetMs) ? options.timeBudgetMs : undefined,
1005
+ json: options.json === true,
839
1006
  });
840
1007
  });
841
1008
  sessionCmd
@@ -854,10 +1021,262 @@ sessionCmd
854
1021
  .description('Show status of the current session or a specific session')
855
1022
  .option('--session-id <id>', 'Session ID to check (defaults to current session)')
856
1023
  .option('--project-id <id>', 'Project ID')
1024
+ .option('--local', 'Force local in-flow governance session status')
1025
+ .option('--dir <path>', 'Repository root for local in-flow session status')
1026
+ .option('--json', 'Output machine-readable JSON')
857
1027
  .action((options) => {
858
1028
  (0, session_1.sessionStatusCommand)({
859
1029
  sessionId: options.sessionId,
860
1030
  projectId: options.projectId,
1031
+ local: options.local === true,
1032
+ dir: options.dir,
1033
+ json: options.json === true,
1034
+ });
1035
+ });
1036
+ sessionCmd
1037
+ .command('export-admission [sessionId]')
1038
+ .description('Export a source-free runtime admission record into .neurcode-admission/')
1039
+ .option('--dir <path>', 'Repository root (default: current directory)')
1040
+ .option('--receipt <path>', 'Attach source-free backend receipt summary from a receipt/control-plane JSON file')
1041
+ .option('--explain', 'Explain what the record contains, excludes, and how the GitHub Action consumes it')
1042
+ .option('--json', 'Output machine-readable JSON')
1043
+ .action((sessionId, options) => {
1044
+ try {
1045
+ const summary = (0, admission_1.exportAdmissionRecordForCli)({
1046
+ dir: options.dir,
1047
+ sessionId,
1048
+ receiptPath: options.receipt,
1049
+ explain: options.explain === true,
1050
+ json: options.json === true,
1051
+ });
1052
+ if (options.json) {
1053
+ console.log(JSON.stringify(summary, null, 2));
1054
+ return;
1055
+ }
1056
+ console.log('Admission record exported');
1057
+ console.log(` Session: ${summary.sessionId}`);
1058
+ console.log(` PR artifact: ${summary.publicRelativePath}`);
1059
+ console.log(` Trust: ${summary.trustLevel}`);
1060
+ if (summary.receipt.present) {
1061
+ console.log(` Receipt: ${summary.receipt.receiptId || 'attached'} (${summary.receipt.verificationStatus || 'unknown'})`);
1062
+ }
1063
+ console.log(` Note: ${summary.trustLevel === 'backend_signed' ? 'backend-signed metadata is attached; verify the receipt before treating it as enterprise evidence.' : 'self-attested local records are claims, not cryptographic proof.'}`);
1064
+ if (options.explain) {
1065
+ console.log('');
1066
+ console.log('What it contains:');
1067
+ for (const item of summary.contains)
1068
+ console.log(` - ${item}`);
1069
+ console.log('');
1070
+ console.log('What it intentionally excludes:');
1071
+ for (const item of summary.excludes)
1072
+ console.log(` - ${item}`);
1073
+ console.log('');
1074
+ console.log('How the GitHub Action consumes it:');
1075
+ for (const item of summary.actionConsumption)
1076
+ console.log(` - ${item}`);
1077
+ }
1078
+ }
1079
+ catch (error) {
1080
+ const message = error instanceof Error ? error.message : String(error);
1081
+ if (options.json) {
1082
+ console.log(JSON.stringify({ ok: false, error: message }, null, 2));
1083
+ }
1084
+ else {
1085
+ console.error(`Admission export failed: ${message}`);
1086
+ }
1087
+ process.exitCode = 1;
1088
+ }
1089
+ });
1090
+ sessionCmd
1091
+ .command('approve')
1092
+ .description('Approve a file path or glob for the active in-flow governance session')
1093
+ .requiredOption('--path <path>', 'File path or glob to approve')
1094
+ .option('--reason <text>', 'Human-readable approval reason')
1095
+ .option('--session-id <id>', 'Session ID to approve against (default: active session)')
1096
+ .option('--dir <path>', 'Repository root (default: current directory)')
1097
+ .option('--json', 'Output machine-readable JSON')
1098
+ .action(async (options) => {
1099
+ await (0, session_1.approveGovernanceSessionCommand)({
1100
+ path: options.path,
1101
+ reason: options.reason,
1102
+ sessionId: options.sessionId,
1103
+ dir: options.dir,
1104
+ json: options.json === true,
1105
+ });
1106
+ });
1107
+ sessionCmd
1108
+ .command('reset-stale')
1109
+ .description('Finish and clear an abandoned active in-flow governance session')
1110
+ .option('--max-age-minutes <n>', 'Only reset sessions idle at least this many minutes (default: 120)', (value) => Number.parseFloat(value))
1111
+ .option('--force', 'Reset even if the session is fresh or waiting on approval')
1112
+ .option('--dir <path>', 'Repository root (default: current directory)')
1113
+ .option('--json', 'Output machine-readable JSON')
1114
+ .action(async (options) => {
1115
+ await (0, session_1.resetStaleGovernanceSessionCommand)({
1116
+ maxAgeMinutes: Number.isFinite(options.maxAgeMinutes) ? options.maxAgeMinutes : undefined,
1117
+ force: options.force === true,
1118
+ dir: options.dir,
1119
+ json: options.json === true,
1120
+ });
1121
+ });
1122
+ sessionCmd
1123
+ .command('obligations')
1124
+ .description('Show live source-free architecture obligations for the active in-flow session')
1125
+ .option('--session-id <id>', 'Session ID to inspect (default: active session)')
1126
+ .option('--dir <path>', 'Repository root (default: current directory)')
1127
+ .option('--json', 'Output machine-readable JSON')
1128
+ .action((options) => {
1129
+ (0, session_1.showGovernanceObligationsCommand)({
1130
+ sessionId: options.sessionId,
1131
+ dir: options.dir,
1132
+ json: options.json === true,
1133
+ });
1134
+ });
1135
+ sessionCmd
1136
+ .command('waive-obligation')
1137
+ .description('Waive one pending architecture obligation for the active in-flow session')
1138
+ .requiredOption('--id <obligation-id>', 'Architecture obligation ID to waive')
1139
+ .requiredOption('--reason <text>', 'Human-readable waiver reason')
1140
+ .option('--session-id <id>', 'Session ID to update (default: active session)')
1141
+ .option('--expires-at <iso>', 'Absolute waiver expiry timestamp')
1142
+ .option('--ttl-minutes <n>', 'Waiver TTL in minutes (default: 60)', (value) => Number.parseFloat(value))
1143
+ .option('--waived-by <identity>', 'Human identity recording the waiver')
1144
+ .option('--source <source>', 'Waiver source: local_cli | dashboard | mcp | unknown', 'local_cli')
1145
+ .option('--dir <path>', 'Repository root (default: current directory)')
1146
+ .option('--json', 'Output machine-readable JSON')
1147
+ .action(async (options) => {
1148
+ await (0, session_1.waiveGovernanceObligationCommand)({
1149
+ obligationId: options.id,
1150
+ reason: options.reason,
1151
+ sessionId: options.sessionId,
1152
+ expiresAt: options.expiresAt,
1153
+ ttlMinutes: Number.isFinite(options.ttlMinutes) ? options.ttlMinutes : undefined,
1154
+ waivedBy: options.waivedBy,
1155
+ waiverSource: ['local_cli', 'dashboard', 'mcp', 'unknown'].includes(options.source) ? options.source : 'local_cli',
1156
+ dir: options.dir,
1157
+ json: options.json === true,
1158
+ });
1159
+ });
1160
+ function collectOption(value, previous = []) {
1161
+ return [...previous, value];
1162
+ }
1163
+ sessionCmd
1164
+ .command('replan')
1165
+ .description('Amend or replace the active in-flow agent plan')
1166
+ .option('--plan <text>', 'Full replacement plan text')
1167
+ .option('--plan-file <path>', 'Read replacement plan text from a file')
1168
+ .option('--summary <text>', 'Replace the active plan summary')
1169
+ .option('--add-step <text>', 'Add a plan step', collectOption, [])
1170
+ .option('--remove-step <text>', 'Remove a plan step by exact text', collectOption, [])
1171
+ .option('--add-file <path>', 'Add an expected file to the active plan', collectOption, [])
1172
+ .option('--remove-file <path>', 'Remove an expected file from the active plan', collectOption, [])
1173
+ .option('--add-glob <glob>', 'Add an expected glob to the active plan', collectOption, [])
1174
+ .option('--remove-glob <glob>', 'Remove an expected glob from the active plan', collectOption, [])
1175
+ .option('--add-constraint <text>', 'Add a stated plan constraint', collectOption, [])
1176
+ .option('--remove-constraint <text>', 'Remove a stated plan constraint by exact text', collectOption, [])
1177
+ .option('--add-risk <text>', 'Add a stated plan risk/caveat', collectOption, [])
1178
+ .option('--remove-risk <text>', 'Remove a stated plan risk/caveat by exact text', collectOption, [])
1179
+ .option('--reason <text>', 'Why the plan changed')
1180
+ .option('--proposed-by <actor>', 'Proposal actor: human | agent', 'human')
1181
+ .option('--decided-by <identity>', 'Human identity when a human-authored re-plan is applied')
1182
+ .option('--session-id <id>', 'Session ID to update (default: active session)')
1183
+ .option('--dir <path>', 'Repository root (default: current directory)')
1184
+ .option('--json', 'Output machine-readable JSON')
1185
+ .action(async (options) => {
1186
+ await (0, session_1.replanGovernanceSessionCommand)({
1187
+ plan: options.plan,
1188
+ planFile: options.planFile,
1189
+ summary: options.summary,
1190
+ addStep: options.addStep,
1191
+ removeStep: options.removeStep,
1192
+ addFile: options.addFile,
1193
+ removeFile: options.removeFile,
1194
+ addGlob: options.addGlob,
1195
+ removeGlob: options.removeGlob,
1196
+ addConstraint: options.addConstraint,
1197
+ removeConstraint: options.removeConstraint,
1198
+ addRisk: options.addRisk,
1199
+ removeRisk: options.removeRisk,
1200
+ reason: options.reason,
1201
+ proposedBy: options.proposedBy === 'agent' ? 'agent' : 'human',
1202
+ decidedBy: options.decidedBy,
1203
+ sessionId: options.sessionId,
1204
+ dir: options.dir,
1205
+ json: options.json === true,
1206
+ });
1207
+ });
1208
+ // `amend-plan` is the human-facing alias of `replan`, matching the documented
1209
+ // `neurcode session amend-plan --summary "..." --reason "..." --scope "<glob>"`.
1210
+ // It shares the same revisioning engine; `--scope` is sugar for `--add-glob`.
1211
+ sessionCmd
1212
+ .command('amend-plan')
1213
+ .description('Amend the active in-flow agent plan (alias of replan; supports --scope)')
1214
+ .option('--plan <text>', 'Full replacement plan text')
1215
+ .option('--plan-file <path>', 'Read replacement plan text from a file')
1216
+ .option('--summary <text>', 'Replace the active plan summary')
1217
+ .option('--scope <glob>', 'Add an expected scope glob to the active plan', collectOption, [])
1218
+ .option('--add-step <text>', 'Add a plan step', collectOption, [])
1219
+ .option('--remove-step <text>', 'Remove a plan step by exact text', collectOption, [])
1220
+ .option('--add-file <path>', 'Add an expected file to the active plan', collectOption, [])
1221
+ .option('--remove-file <path>', 'Remove an expected file from the active plan', collectOption, [])
1222
+ .option('--add-glob <glob>', 'Add an expected glob to the active plan', collectOption, [])
1223
+ .option('--remove-glob <glob>', 'Remove an expected glob from the active plan', collectOption, [])
1224
+ .option('--add-constraint <text>', 'Add a stated plan constraint', collectOption, [])
1225
+ .option('--remove-constraint <text>', 'Remove a stated plan constraint by exact text', collectOption, [])
1226
+ .option('--add-risk <text>', 'Add a stated plan risk/caveat', collectOption, [])
1227
+ .option('--remove-risk <text>', 'Remove a stated plan risk/caveat by exact text', collectOption, [])
1228
+ .option('--reason <text>', 'Why the plan changed')
1229
+ .option('--proposed-by <actor>', 'Proposal actor: human | agent', 'human')
1230
+ .option('--decided-by <identity>', 'Human identity when a human-authored re-plan is applied')
1231
+ .option('--session-id <id>', 'Session ID to update (default: active session)')
1232
+ .option('--dir <path>', 'Repository root (default: current directory)')
1233
+ .option('--json', 'Output machine-readable JSON')
1234
+ .action(async (options) => {
1235
+ await (0, session_1.replanGovernanceSessionCommand)({
1236
+ plan: options.plan,
1237
+ planFile: options.planFile,
1238
+ summary: options.summary,
1239
+ scope: options.scope,
1240
+ addStep: options.addStep,
1241
+ removeStep: options.removeStep,
1242
+ addFile: options.addFile,
1243
+ removeFile: options.removeFile,
1244
+ addGlob: options.addGlob,
1245
+ removeGlob: options.removeGlob,
1246
+ addConstraint: options.addConstraint,
1247
+ removeConstraint: options.removeConstraint,
1248
+ addRisk: options.addRisk,
1249
+ removeRisk: options.removeRisk,
1250
+ reason: options.reason,
1251
+ proposedBy: options.proposedBy === 'agent' ? 'agent' : 'human',
1252
+ decidedBy: options.decidedBy,
1253
+ sessionId: options.sessionId,
1254
+ dir: options.dir,
1255
+ json: options.json === true,
1256
+ });
1257
+ });
1258
+ sessionCmd
1259
+ .command('replan-decide')
1260
+ .description('Accept or reject a pending agent-authored plan amendment')
1261
+ .requiredOption('--proposal-id <id>', 'Pending plan amendment proposal ID')
1262
+ .requiredOption('--decision <decision>', 'Decision: accept | reject')
1263
+ .option('--reason <text>', 'Human-readable decision reason')
1264
+ .option('--decided-by <identity>', 'Human identity recording the decision')
1265
+ .option('--session-id <id>', 'Session ID to update (default: active session)')
1266
+ .option('--dir <path>', 'Repository root (default: current directory)')
1267
+ .option('--json', 'Output machine-readable JSON')
1268
+ .action(async (options) => {
1269
+ if (options.decision !== 'accept' && options.decision !== 'reject') {
1270
+ throw new Error('decision must be accept or reject');
1271
+ }
1272
+ await (0, session_1.decideGovernanceReplanCommand)({
1273
+ proposalId: options.proposalId,
1274
+ decision: options.decision,
1275
+ reason: options.reason,
1276
+ decidedBy: options.decidedBy,
1277
+ sessionId: options.sessionId,
1278
+ dir: options.dir,
1279
+ json: options.json === true,
861
1280
  });
862
1281
  });
863
1282
  sessionCmd
@@ -970,9 +1389,42 @@ program
970
1389
  .option('--finding-id <id>', 'Alias for --finding (backward compatible)')
971
1390
  .option('--finding-index <n>', 'Export payload for finding at 0-based index')
972
1391
  .option('--all', 'Export payloads for all findings from last verify')
973
- .option('--format <fmt>', 'Output format: json | mcp (default: json)', 'json')
1392
+ .option('--format <fmt>', 'Output format: json | mcp | prompt | markdown (default: json)', 'json')
1393
+ .option('--provider <provider>', 'Provider handoff: claude | codex | cursor | gemini')
1394
+ .option('--out <path>', 'Write output to file instead of stdout')
1395
+ .option('--copy', 'Copy output to clipboard (macOS pbcopy)')
1396
+ .option('--open', 'Open provider workflow when a documented local deep link is available')
1397
+ .option('--verify-output-file <path>', 'Path to verify JSON output (default: .neurcode/last-verify-output.json)')
1398
+ .option('--project-root <path>', 'Project root override')
1399
+ .option('--json', 'Output machine-readable JSON')
1400
+ .action(async (options) => {
1401
+ const finding = options.finding ?? options.findingId;
1402
+ await (0, remediate_export_1.remediateExportCommand)({
1403
+ finding,
1404
+ findingIndex: options.findingIndex,
1405
+ all: options.all === true,
1406
+ format: ['json', 'mcp', 'prompt', 'markdown'].includes(options.format) ? options.format : 'json',
1407
+ provider: ['claude', 'codex', 'cursor', 'gemini'].includes(options.provider) ? options.provider : undefined,
1408
+ out: options.out,
1409
+ copy: options.copy === true,
1410
+ open: options.open === true,
1411
+ json: options.json === true,
1412
+ verifyOutputFile: options.verifyOutputFile,
1413
+ projectRoot: options.projectRoot,
1414
+ });
1415
+ });
1416
+ program
1417
+ .command('remediation-export')
1418
+ .description('Alias for remediate-export.')
1419
+ .option('--finding <id>', 'Export payload for a specific finding ID')
1420
+ .option('--finding-id <id>', 'Alias for --finding (backward compatible)')
1421
+ .option('--finding-index <n>', 'Export payload for finding at 0-based index')
1422
+ .option('--all', 'Export payloads for all findings from last verify')
1423
+ .option('--format <fmt>', 'Output format: json | mcp | prompt | markdown (default: json)', 'json')
1424
+ .option('--provider <provider>', 'Provider handoff: claude | codex | cursor | gemini')
974
1425
  .option('--out <path>', 'Write output to file instead of stdout')
975
1426
  .option('--copy', 'Copy output to clipboard (macOS pbcopy)')
1427
+ .option('--open', 'Open provider workflow when a documented local deep link is available')
976
1428
  .option('--verify-output-file <path>', 'Path to verify JSON output (default: .neurcode/last-verify-output.json)')
977
1429
  .option('--project-root <path>', 'Project root override')
978
1430
  .option('--json', 'Output machine-readable JSON')
@@ -982,9 +1434,11 @@ program
982
1434
  finding,
983
1435
  findingIndex: options.findingIndex,
984
1436
  all: options.all === true,
985
- format: options.format === 'mcp' ? 'mcp' : 'json',
1437
+ format: ['json', 'mcp', 'prompt', 'markdown'].includes(options.format) ? options.format : 'json',
1438
+ provider: ['claude', 'codex', 'cursor', 'gemini'].includes(options.provider) ? options.provider : undefined,
986
1439
  out: options.out,
987
1440
  copy: options.copy === true,
1441
+ open: options.open === true,
988
1442
  json: options.json === true,
989
1443
  verifyOutputFile: options.verifyOutputFile,
990
1444
  projectRoot: options.projectRoot,
@@ -1395,7 +1849,8 @@ program
1395
1849
  });
1396
1850
  if (options.json === true) {
1397
1851
  console.log(JSON.stringify(run.execution, null, 2));
1398
- process.exit(run.execution.result?.success === true ? 0 : 1);
1852
+ process.exitCode = run.execution.result?.success === true ? 0 : 1;
1853
+ return;
1399
1854
  }
1400
1855
  const execution = run.execution;
1401
1856
  const statusIcon = execution.result?.success ? '✅' : '❌';