@neurcode-ai/cli 0.14.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.
- package/README.md +60 -8
- package/dist/api-client.d.ts +284 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +111 -0
- package/dist/api-client.js.map +1 -1
- package/dist/commands/activate.d.ts +82 -0
- package/dist/commands/activate.d.ts.map +1 -0
- package/dist/commands/activate.js +551 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/admission.d.ts +67 -0
- package/dist/commands/admission.d.ts.map +1 -0
- package/dist/commands/admission.js +350 -0
- package/dist/commands/admission.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +2045 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/demo.d.ts +3 -0
- package/dist/commands/demo.d.ts.map +1 -0
- package/dist/commands/demo.js +102 -0
- package/dist/commands/demo.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +58 -44
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +44 -22
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/profile.d.ts +14 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +118 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/quickstart.d.ts +2 -2
- package/dist/commands/quickstart.d.ts.map +1 -1
- package/dist/commands/quickstart.js +31 -30
- package/dist/commands/quickstart.js.map +1 -1
- package/dist/commands/remediate-export.d.ts +6 -1
- package/dist/commands/remediate-export.d.ts.map +1 -1
- package/dist/commands/remediate-export.js +359 -7
- package/dist/commands/remediate-export.js.map +1 -1
- package/dist/commands/replay.d.ts.map +1 -1
- package/dist/commands/replay.js +84 -0
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +98 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/runtime-adapter.d.ts +8 -0
- package/dist/commands/runtime-adapter.d.ts.map +1 -0
- package/dist/commands/runtime-adapter.js +375 -0
- package/dist/commands/runtime-adapter.js.map +1 -0
- package/dist/commands/runtime-doctor.d.ts +6 -0
- package/dist/commands/runtime-doctor.d.ts.map +1 -0
- package/dist/commands/runtime-doctor.js +478 -0
- package/dist/commands/runtime-doctor.js.map +1 -0
- package/dist/commands/runtime-report.d.ts +13 -0
- package/dist/commands/runtime-report.d.ts.map +1 -0
- package/dist/commands/runtime-report.js +81 -0
- package/dist/commands/runtime-report.js.map +1 -0
- package/dist/commands/runtime-sync.d.ts +17 -0
- package/dist/commands/runtime-sync.d.ts.map +1 -0
- package/dist/commands/runtime-sync.js +656 -0
- package/dist/commands/runtime-sync.js.map +1 -0
- package/dist/commands/runtime.d.ts +16 -0
- package/dist/commands/runtime.d.ts.map +1 -0
- package/dist/commands/runtime.js +380 -0
- package/dist/commands/runtime.js.map +1 -0
- package/dist/commands/session-hook.d.ts +35 -0
- package/dist/commands/session-hook.d.ts.map +1 -0
- package/dist/commands/session-hook.js +1297 -0
- package/dist/commands/session-hook.js.map +1 -0
- package/dist/commands/session.d.ts +91 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +1226 -0
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/whoami.d.ts +7 -4
- package/dist/commands/whoami.d.ts.map +1 -1
- package/dist/commands/whoami.js +59 -34
- package/dist/commands/whoami.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +24 -5
- package/dist/config.js.map +1 -1
- package/dist/daemon/routes.d.ts.map +1 -1
- package/dist/daemon/routes.js +8 -0
- package/dist/daemon/routes.js.map +1 -1
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +88 -0
- package/dist/daemon/server.js.map +1 -1
- package/dist/governance/impact-analysis.d.ts +27 -0
- package/dist/governance/impact-analysis.d.ts.map +1 -0
- package/dist/governance/impact-analysis.js +274 -0
- package/dist/governance/impact-analysis.js.map +1 -0
- package/dist/index.js +472 -29
- package/dist/index.js.map +1 -1
- package/dist/intent-engine/matcher.d.ts.map +1 -1
- package/dist/intent-engine/matcher.js +3 -12
- package/dist/intent-engine/matcher.js.map +1 -1
- package/dist/utils/admission-artifact.d.ts +59 -0
- package/dist/utils/admission-artifact.d.ts.map +1 -0
- package/dist/utils/admission-artifact.js +410 -0
- package/dist/utils/admission-artifact.js.map +1 -0
- package/dist/utils/agent-adapter-setup.d.ts +80 -0
- package/dist/utils/agent-adapter-setup.d.ts.map +1 -0
- package/dist/utils/agent-adapter-setup.js +577 -0
- package/dist/utils/agent-adapter-setup.js.map +1 -0
- package/dist/utils/agent-guard-supervisor.d.ts +75 -0
- package/dist/utils/agent-guard-supervisor.d.ts.map +1 -0
- package/dist/utils/agent-guard-supervisor.js +388 -0
- package/dist/utils/agent-guard-supervisor.js.map +1 -0
- package/dist/utils/agent-guard.d.ts +92 -0
- package/dist/utils/agent-guard.d.ts.map +1 -0
- package/dist/utils/agent-guard.js +326 -0
- package/dist/utils/agent-guard.js.map +1 -0
- package/dist/utils/agent-session-launcher.d.ts +89 -0
- package/dist/utils/agent-session-launcher.d.ts.map +1 -0
- package/dist/utils/agent-session-launcher.js +308 -0
- package/dist/utils/agent-session-launcher.js.map +1 -0
- package/dist/utils/bash-command-analysis.d.ts +19 -0
- package/dist/utils/bash-command-analysis.d.ts.map +1 -0
- package/dist/utils/bash-command-analysis.js +295 -0
- package/dist/utils/bash-command-analysis.js.map +1 -0
- package/dist/utils/consequence-nudges.d.ts +30 -0
- package/dist/utils/consequence-nudges.d.ts.map +1 -0
- package/dist/utils/consequence-nudges.js +313 -0
- package/dist/utils/consequence-nudges.js.map +1 -0
- package/dist/utils/drift-intelligence.d.ts.map +1 -1
- package/dist/utils/drift-intelligence.js +29 -7
- package/dist/utils/drift-intelligence.js.map +1 -1
- package/dist/utils/git-coverage.d.ts +57 -0
- package/dist/utils/git-coverage.d.ts.map +1 -0
- package/dist/utils/git-coverage.js +302 -0
- package/dist/utils/git-coverage.js.map +1 -0
- package/dist/utils/gitignore.d.ts.map +1 -1
- package/dist/utils/gitignore.js +2 -1
- package/dist/utils/gitignore.js.map +1 -1
- package/dist/utils/governed-intent.d.ts +10 -0
- package/dist/utils/governed-intent.d.ts.map +1 -0
- package/dist/utils/governed-intent.js +108 -0
- package/dist/utils/governed-intent.js.map +1 -0
- package/dist/utils/hook-heartbeat.d.ts +55 -0
- package/dist/utils/hook-heartbeat.d.ts.map +1 -0
- package/dist/utils/hook-heartbeat.js +116 -0
- package/dist/utils/hook-heartbeat.js.map +1 -0
- package/dist/utils/intent-continuity.d.ts +21 -0
- package/dist/utils/intent-continuity.d.ts.map +1 -0
- package/dist/utils/intent-continuity.js +192 -0
- package/dist/utils/intent-continuity.js.map +1 -0
- package/dist/utils/messages.d.ts +1 -1
- package/dist/utils/messages.d.ts.map +1 -1
- package/dist/utils/messages.js +24 -21
- package/dist/utils/messages.js.map +1 -1
- package/dist/utils/runtime-companion.d.ts +137 -0
- package/dist/utils/runtime-companion.d.ts.map +1 -0
- package/dist/utils/runtime-companion.js +231 -0
- package/dist/utils/runtime-companion.js.map +1 -0
- package/dist/utils/runtime-connection.d.ts +46 -0
- package/dist/utils/runtime-connection.d.ts.map +1 -0
- package/dist/utils/runtime-connection.js +148 -0
- package/dist/utils/runtime-connection.js.map +1 -0
- package/dist/utils/runtime-evidence.d.ts +68 -0
- package/dist/utils/runtime-evidence.d.ts.map +1 -0
- package/dist/utils/runtime-evidence.js +248 -0
- package/dist/utils/runtime-evidence.js.map +1 -0
- package/dist/utils/runtime-live.d.ts +33 -0
- package/dist/utils/runtime-live.d.ts.map +1 -0
- package/dist/utils/runtime-live.js +361 -0
- package/dist/utils/runtime-live.js.map +1 -0
- package/dist/utils/runtime-outbox.d.ts +76 -0
- package/dist/utils/runtime-outbox.d.ts.map +1 -0
- package/dist/utils/runtime-outbox.js +410 -0
- package/dist/utils/runtime-outbox.js.map +1 -0
- package/dist/utils/runtime-receipt.d.ts +50 -0
- package/dist/utils/runtime-receipt.d.ts.map +1 -0
- package/dist/utils/runtime-receipt.js +223 -0
- package/dist/utils/runtime-receipt.js.map +1 -0
- package/dist/utils/state.d.ts +21 -0
- package/dist/utils/state.d.ts.map +1 -1
- package/dist/utils/state.js +30 -0
- package/dist/utils/state.js.map +1 -1
- package/dist/utils/structural-understanding.d.ts +334 -0
- package/dist/utils/structural-understanding.d.ts.map +1 -0
- package/dist/utils/structural-understanding.js +2316 -0
- package/dist/utils/structural-understanding.js.map +1 -0
- package/dist/utils/v0-governance.d.ts +197 -0
- package/dist/utils/v0-governance.d.ts.map +1 -0
- package/dist/utils/v0-governance.js +904 -0
- package/dist/utils/v0-governance.js.map +1 -0
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -66,6 +66,18 @@ const control_plane_1 = require("./commands/control-plane");
|
|
|
66
66
|
const workspace_1 = require("./commands/workspace");
|
|
67
67
|
const replay_1 = require("./commands/replay");
|
|
68
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");
|
|
69
81
|
const execution_bus_1 = require("./utils/execution-bus");
|
|
70
82
|
const execution_actions_1 = require("./utils/execution-actions");
|
|
71
83
|
// Read version from package.json
|
|
@@ -81,31 +93,71 @@ catch (error) {
|
|
|
81
93
|
const program = new commander_1.Command();
|
|
82
94
|
const CORE_WORKFLOW_STEPS = [
|
|
83
95
|
{
|
|
84
|
-
command: 'neurcode start "<
|
|
85
|
-
description: '
|
|
96
|
+
command: 'neurcode agent start codex --goal "<task>"',
|
|
97
|
+
description: 'Start a governed session for non-Claude agents using the universal runtime handshake',
|
|
86
98
|
},
|
|
87
99
|
{
|
|
88
|
-
command: 'neurcode
|
|
89
|
-
description: '
|
|
100
|
+
command: 'neurcode run claude --goal "<task>"',
|
|
101
|
+
description: 'Start a governed AI coding session and print the agent runtime handshake',
|
|
90
102
|
},
|
|
91
103
|
{
|
|
92
|
-
command: 'neurcode
|
|
93
|
-
description: '
|
|
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',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
command: 'neurcode report --runtime',
|
|
117
|
+
description: 'Summarize blocked edits, approvals, owners, and replay records across sessions',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
command: 'neurcode sync --runtime',
|
|
121
|
+
description: 'Manual fallback upload for finished in-flow session records',
|
|
94
122
|
},
|
|
95
123
|
{
|
|
96
|
-
command: 'neurcode
|
|
97
|
-
description: 'Export
|
|
124
|
+
command: 'neurcode admission export',
|
|
125
|
+
description: 'Export the latest source-free runtime admission record for the GitHub Action',
|
|
98
126
|
},
|
|
99
127
|
{
|
|
100
|
-
command: 'neurcode
|
|
101
|
-
description: '
|
|
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',
|
|
102
146
|
},
|
|
103
147
|
];
|
|
104
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',
|
|
105
159
|
'start',
|
|
106
160
|
'quickstart',
|
|
107
|
-
'verify',
|
|
108
|
-
'remediate-export',
|
|
109
161
|
'replay',
|
|
110
162
|
]);
|
|
111
163
|
const ENTERPRISE_OPERATIONS_COMMAND_NAMES = new Set([
|
|
@@ -200,12 +252,12 @@ function buildAdvancedLegacyHints(root) {
|
|
|
200
252
|
return fallbackCommands.map((commandName) => `neurcode ${commandName}`);
|
|
201
253
|
}
|
|
202
254
|
function configurePrimaryHelpView(root) {
|
|
203
|
-
const primaryOrder = ['
|
|
255
|
+
const primaryOrder = ['activate', 'agent', 'run', 'status', 'runtime', 'sessions', 'report', 'sync', 'admission', 'demo', 'login', 'init', 'start', 'quickstart', 'replay'];
|
|
204
256
|
root.configureHelp({
|
|
205
257
|
visibleCommands: (command) => {
|
|
206
258
|
const filtered = command.commands.filter((subcommand) => {
|
|
207
259
|
const commandName = subcommand.name();
|
|
208
|
-
return commandName === 'help' || CANONICAL_OPERATOR_COMMAND_NAMES.has(commandName);
|
|
260
|
+
return commandName === 'help' || commandName === 'login' || commandName === 'init' || CANONICAL_OPERATOR_COMMAND_NAMES.has(commandName);
|
|
209
261
|
});
|
|
210
262
|
return filtered.sort((left, right) => {
|
|
211
263
|
const leftIndex = primaryOrder.indexOf(left.name());
|
|
@@ -219,19 +271,19 @@ function configurePrimaryHelpView(root) {
|
|
|
219
271
|
}
|
|
220
272
|
function printCoreWorkflowGuide() {
|
|
221
273
|
// Operational lifecycle guide. Same aesthetic as the welcome banner and
|
|
222
|
-
// neurcode home
|
|
274
|
+
// neurcode home - subtle sophistication, no emoji ornaments, info dense.
|
|
223
275
|
// The lifecycle bar mirrors what the welcome banner shows so identity is
|
|
224
276
|
// coherent across surfaces. (See docs/ux/final-operational-experience-report.md.)
|
|
225
277
|
console.log('');
|
|
226
278
|
console.log(`${chalk.bold('neurcode')}${chalk.dim(' · operational lifecycle')}`);
|
|
227
279
|
console.log('');
|
|
228
|
-
console.log(chalk.dim('
|
|
280
|
+
console.log(chalk.dim(' connect repo -> activate agent -> govern session -> approve exact path -> export evidence'));
|
|
229
281
|
console.log('');
|
|
230
282
|
console.log(` ${chalk.bold('Canonical commands')}`);
|
|
231
283
|
CORE_WORKFLOW_STEPS.forEach((step) => console.log(chalk.dim(formatCoreWorkflowStep(step))));
|
|
232
284
|
console.log('');
|
|
233
285
|
console.log(chalk.dim(' See ') + chalk.cyan('neurcode home') + chalk.dim(' for current runtime state. ') +
|
|
234
|
-
chalk.dim('Run ') + chalk.cyan('neurcode
|
|
286
|
+
chalk.dim('Run ') + chalk.cyan('neurcode whoami') + chalk.dim(' to inspect user/workspace/repo identity.'));
|
|
235
287
|
console.log('');
|
|
236
288
|
}
|
|
237
289
|
function formatCommandList(commandNames) {
|
|
@@ -385,6 +437,42 @@ program
|
|
|
385
437
|
(0, brain_1.brainCommand)(program);
|
|
386
438
|
(0, policy_1.policyCommand)(program);
|
|
387
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
|
+
});
|
|
388
476
|
(0, control_plane_1.controlPlaneCommand)(program);
|
|
389
477
|
(0, workspace_1.workspaceCommand)(program);
|
|
390
478
|
(0, replay_1.replayCommand)(program);
|
|
@@ -461,16 +549,16 @@ program
|
|
|
461
549
|
});
|
|
462
550
|
program
|
|
463
551
|
.command('login')
|
|
464
|
-
.description('
|
|
465
|
-
.option('--org <id>', '
|
|
552
|
+
.description('Connect this machine/runtime to a Neurcode workspace')
|
|
553
|
+
.option('--org <id>', 'Connect to a specific workspace/organization (internal UUID)')
|
|
466
554
|
.action((options) => {
|
|
467
555
|
(0, login_1.loginCommand)({ orgId: options.org });
|
|
468
556
|
});
|
|
469
557
|
program
|
|
470
558
|
.command('logout')
|
|
471
|
-
.description('
|
|
472
|
-
.option('--all', 'Remove all saved
|
|
473
|
-
.option('--org <id>', 'Remove saved
|
|
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')
|
|
474
562
|
.action((options) => {
|
|
475
563
|
(0, logout_1.logoutCommand)({
|
|
476
564
|
all: options.all || false,
|
|
@@ -479,8 +567,8 @@ program
|
|
|
479
567
|
});
|
|
480
568
|
program
|
|
481
569
|
.command('init')
|
|
482
|
-
.description('
|
|
483
|
-
.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')
|
|
484
572
|
.option('--project-id <id>', 'Link an existing project by internal UUID (non-interactive)')
|
|
485
573
|
.option('--create <name>', 'Create and link a new project (non-interactive)')
|
|
486
574
|
.action((options) => {
|
|
@@ -493,8 +581,17 @@ program
|
|
|
493
581
|
program
|
|
494
582
|
.command('doctor')
|
|
495
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')
|
|
496
586
|
.option('--json', 'Output machine-readable diagnostics JSON')
|
|
497
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
|
+
}
|
|
498
595
|
(0, doctor_1.doctorCommand)({
|
|
499
596
|
json: options.json,
|
|
500
597
|
cliVersion: version,
|
|
@@ -502,7 +599,7 @@ program
|
|
|
502
599
|
});
|
|
503
600
|
program
|
|
504
601
|
.command('quickstart')
|
|
505
|
-
.description('
|
|
602
|
+
.description('Local-only governance sandbox for first deterministic finding')
|
|
506
603
|
.option('--force', 'Overwrite existing starter files')
|
|
507
604
|
.option('--json', 'Output machine-readable JSON')
|
|
508
605
|
.action(async (options) => {
|
|
@@ -566,7 +663,7 @@ program
|
|
|
566
663
|
});
|
|
567
664
|
program
|
|
568
665
|
.command('whoami')
|
|
569
|
-
.description('Show
|
|
666
|
+
.description('Show user, workspace, repo ownership, session, and governance boundary')
|
|
570
667
|
.action(() => {
|
|
571
668
|
(0, whoami_1.whoamiCommand)();
|
|
572
669
|
});
|
|
@@ -844,10 +941,68 @@ sessionCmd
|
|
|
844
941
|
.description('List all sessions for the current project')
|
|
845
942
|
.option('--project-id <id>', 'Project ID')
|
|
846
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')
|
|
847
947
|
.action((options) => {
|
|
848
948
|
(0, session_1.listSessionsCommand)({
|
|
849
949
|
projectId: options.projectId,
|
|
850
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,
|
|
851
1006
|
});
|
|
852
1007
|
});
|
|
853
1008
|
sessionCmd
|
|
@@ -866,10 +1021,262 @@ sessionCmd
|
|
|
866
1021
|
.description('Show status of the current session or a specific session')
|
|
867
1022
|
.option('--session-id <id>', 'Session ID to check (defaults to current session)')
|
|
868
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')
|
|
869
1027
|
.action((options) => {
|
|
870
1028
|
(0, session_1.sessionStatusCommand)({
|
|
871
1029
|
sessionId: options.sessionId,
|
|
872
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,
|
|
873
1280
|
});
|
|
874
1281
|
});
|
|
875
1282
|
sessionCmd
|
|
@@ -982,9 +1389,11 @@ program
|
|
|
982
1389
|
.option('--finding-id <id>', 'Alias for --finding (backward compatible)')
|
|
983
1390
|
.option('--finding-index <n>', 'Export payload for finding at 0-based index')
|
|
984
1391
|
.option('--all', 'Export payloads for all findings from last verify')
|
|
985
|
-
.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')
|
|
986
1394
|
.option('--out <path>', 'Write output to file instead of stdout')
|
|
987
1395
|
.option('--copy', 'Copy output to clipboard (macOS pbcopy)')
|
|
1396
|
+
.option('--open', 'Open provider workflow when a documented local deep link is available')
|
|
988
1397
|
.option('--verify-output-file <path>', 'Path to verify JSON output (default: .neurcode/last-verify-output.json)')
|
|
989
1398
|
.option('--project-root <path>', 'Project root override')
|
|
990
1399
|
.option('--json', 'Output machine-readable JSON')
|
|
@@ -994,9 +1403,42 @@ program
|
|
|
994
1403
|
finding,
|
|
995
1404
|
findingIndex: options.findingIndex,
|
|
996
1405
|
all: options.all === true,
|
|
997
|
-
format:
|
|
1406
|
+
format: ['json', 'mcp', 'prompt', 'markdown'].includes(options.format) ? options.format : 'json',
|
|
1407
|
+
provider: ['claude', 'codex', 'cursor', 'gemini'].includes(options.provider) ? options.provider : undefined,
|
|
998
1408
|
out: options.out,
|
|
999
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')
|
|
1425
|
+
.option('--out <path>', 'Write output to file instead of stdout')
|
|
1426
|
+
.option('--copy', 'Copy output to clipboard (macOS pbcopy)')
|
|
1427
|
+
.option('--open', 'Open provider workflow when a documented local deep link is available')
|
|
1428
|
+
.option('--verify-output-file <path>', 'Path to verify JSON output (default: .neurcode/last-verify-output.json)')
|
|
1429
|
+
.option('--project-root <path>', 'Project root override')
|
|
1430
|
+
.option('--json', 'Output machine-readable JSON')
|
|
1431
|
+
.action(async (options) => {
|
|
1432
|
+
const finding = options.finding ?? options.findingId;
|
|
1433
|
+
await (0, remediate_export_1.remediateExportCommand)({
|
|
1434
|
+
finding,
|
|
1435
|
+
findingIndex: options.findingIndex,
|
|
1436
|
+
all: options.all === true,
|
|
1437
|
+
format: ['json', 'mcp', 'prompt', 'markdown'].includes(options.format) ? options.format : 'json',
|
|
1438
|
+
provider: ['claude', 'codex', 'cursor', 'gemini'].includes(options.provider) ? options.provider : undefined,
|
|
1439
|
+
out: options.out,
|
|
1440
|
+
copy: options.copy === true,
|
|
1441
|
+
open: options.open === true,
|
|
1000
1442
|
json: options.json === true,
|
|
1001
1443
|
verifyOutputFile: options.verifyOutputFile,
|
|
1002
1444
|
projectRoot: options.projectRoot,
|
|
@@ -1407,7 +1849,8 @@ program
|
|
|
1407
1849
|
});
|
|
1408
1850
|
if (options.json === true) {
|
|
1409
1851
|
console.log(JSON.stringify(run.execution, null, 2));
|
|
1410
|
-
process.
|
|
1852
|
+
process.exitCode = run.execution.result?.success === true ? 0 : 1;
|
|
1853
|
+
return;
|
|
1411
1854
|
}
|
|
1412
1855
|
const execution = run.execution;
|
|
1413
1856
|
const statusIcon = execution.result?.success ? '✅' : '❌';
|