@neurcode-ai/cli 0.9.35 → 0.9.37
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 +4 -2
- package/dist/api-client.d.ts +345 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +237 -9
- package/dist/api-client.js.map +1 -1
- package/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +133 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/contract.d.ts +3 -0
- package/dist/commands/contract.d.ts.map +1 -0
- package/dist/commands/contract.js +235 -0
- package/dist/commands/contract.js.map +1 -0
- package/dist/commands/feedback.d.ts +3 -0
- package/dist/commands/feedback.d.ts.map +1 -0
- package/dist/commands/feedback.js +208 -0
- package/dist/commands/feedback.js.map +1 -0
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +19 -3
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/policy.d.ts.map +1 -1
- package/dist/commands/policy.js +611 -26
- package/dist/commands/policy.js.map +1 -1
- package/dist/commands/remediate.d.ts +17 -0
- package/dist/commands/remediate.d.ts.map +1 -0
- package/dist/commands/remediate.js +252 -0
- package/dist/commands/remediate.js.map +1 -0
- package/dist/commands/ship.d.ts.map +1 -1
- package/dist/commands/ship.js +67 -14
- package/dist/commands/ship.js.map +1 -1
- package/dist/commands/verify.d.ts +14 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +564 -14
- package/dist/commands/verify.js.map +1 -1
- package/dist/index.js +94 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/artifact-signature.d.ts +34 -0
- package/dist/utils/artifact-signature.d.ts.map +1 -0
- package/dist/utils/artifact-signature.js +229 -0
- package/dist/utils/artifact-signature.js.map +1 -0
- package/dist/utils/change-contract.d.ts +2 -0
- package/dist/utils/change-contract.d.ts.map +1 -1
- package/dist/utils/change-contract.js +21 -1
- package/dist/utils/change-contract.js.map +1 -1
- package/dist/utils/policy-compiler.d.ts +2 -0
- package/dist/utils/policy-compiler.d.ts.map +1 -1
- package/dist/utils/policy-compiler.js +15 -0
- package/dist/utils/policy-compiler.js.map +1 -1
- package/dist/utils/policy-exceptions.d.ts +11 -1
- package/dist/utils/policy-exceptions.d.ts.map +1 -1
- package/dist/utils/policy-exceptions.js +94 -6
- package/dist/utils/policy-exceptions.js.map +1 -1
- package/dist/utils/policy-governance.d.ts +22 -1
- package/dist/utils/policy-governance.d.ts.map +1 -1
- package/dist/utils/policy-governance.js +178 -14
- package/dist/utils/policy-governance.js.map +1 -1
- package/dist/utils/policy-packs.d.ts +1 -1
- package/dist/utils/policy-packs.d.ts.map +1 -1
- package/dist/utils/policy-packs.js +185 -0
- package/dist/utils/policy-packs.js.map +1 -1
- package/package.json +15 -13
- package/LICENSE +0 -201
package/dist/commands/ship.js
CHANGED
|
@@ -180,7 +180,7 @@ function shellTailLines(text, limit) {
|
|
|
180
180
|
.join('\n');
|
|
181
181
|
}
|
|
182
182
|
function emitShipJson(payload) {
|
|
183
|
-
|
|
183
|
+
process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
|
|
184
184
|
}
|
|
185
185
|
function inferStepStatus(run) {
|
|
186
186
|
if (!run)
|
|
@@ -219,6 +219,7 @@ function runCliCommand(cwd, args, extraEnv, execution) {
|
|
|
219
219
|
const timeoutMs = execution?.timeoutMs ?? getPlanTimeoutMs();
|
|
220
220
|
const heartbeatMs = execution?.heartbeatMs ?? getHeartbeatIntervalMs();
|
|
221
221
|
const commandLabel = execution?.label || `neurcode ${args.join(' ')}`;
|
|
222
|
+
const streamOutput = execution?.streamOutput !== false;
|
|
222
223
|
const child = (0, child_process_1.spawn)(process.execPath, [getCliEntryPath(), ...args], {
|
|
223
224
|
cwd,
|
|
224
225
|
env: {
|
|
@@ -288,12 +289,16 @@ function runCliCommand(cwd, args, extraEnv, execution) {
|
|
|
288
289
|
child.stdout.on('data', (chunk) => {
|
|
289
290
|
const text = chunk.toString();
|
|
290
291
|
stdout += text;
|
|
291
|
-
|
|
292
|
+
if (streamOutput) {
|
|
293
|
+
process.stdout.write(text);
|
|
294
|
+
}
|
|
292
295
|
});
|
|
293
296
|
child.stderr.on('data', (chunk) => {
|
|
294
297
|
const text = chunk.toString();
|
|
295
298
|
stderr += text;
|
|
296
|
-
|
|
299
|
+
if (streamOutput) {
|
|
300
|
+
process.stderr.write(text);
|
|
301
|
+
}
|
|
297
302
|
});
|
|
298
303
|
child.on('error', (error) => {
|
|
299
304
|
stderr += `${error instanceof Error ? error.message : String(error)}\n`;
|
|
@@ -314,6 +319,7 @@ function runShellCommand(cwd, command, execution) {
|
|
|
314
319
|
const timeoutMs = execution?.timeoutMs ?? getTestTimeoutMs();
|
|
315
320
|
const heartbeatMs = execution?.heartbeatMs ?? getHeartbeatIntervalMs();
|
|
316
321
|
const commandLabel = execution?.label || command;
|
|
322
|
+
const streamOutput = execution?.streamOutput !== false;
|
|
317
323
|
const child = (0, child_process_1.spawn)(command, {
|
|
318
324
|
cwd,
|
|
319
325
|
env: {
|
|
@@ -382,12 +388,16 @@ function runShellCommand(cwd, command, execution) {
|
|
|
382
388
|
child.stdout.on('data', (chunk) => {
|
|
383
389
|
const text = chunk.toString();
|
|
384
390
|
stdout += text;
|
|
385
|
-
|
|
391
|
+
if (streamOutput) {
|
|
392
|
+
process.stdout.write(text);
|
|
393
|
+
}
|
|
386
394
|
});
|
|
387
395
|
child.stderr.on('data', (chunk) => {
|
|
388
396
|
const text = chunk.toString();
|
|
389
397
|
stderr += text;
|
|
390
|
-
|
|
398
|
+
if (streamOutput) {
|
|
399
|
+
process.stderr.write(text);
|
|
400
|
+
}
|
|
391
401
|
});
|
|
392
402
|
child.on('error', (error) => {
|
|
393
403
|
stderr += `${error instanceof Error ? error.message : String(error)}\n`;
|
|
@@ -413,20 +423,46 @@ function extractPlanId(output) {
|
|
|
413
423
|
}
|
|
414
424
|
function extractLastJsonObject(output) {
|
|
415
425
|
const clean = stripAnsi(output).trim();
|
|
416
|
-
|
|
417
|
-
if (end < 0)
|
|
426
|
+
if (!clean)
|
|
418
427
|
return null;
|
|
419
|
-
|
|
428
|
+
// Fast path for strict JSON mode outputs (single payload, no human preamble).
|
|
429
|
+
try {
|
|
430
|
+
return JSON.parse(clean);
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// Fall through to mixed-output recovery.
|
|
434
|
+
}
|
|
435
|
+
const firstBrace = clean.indexOf('{');
|
|
436
|
+
const end = clean.lastIndexOf('}');
|
|
437
|
+
if (firstBrace >= 0 && end > firstBrace) {
|
|
438
|
+
const envelope = clean.slice(firstBrace, end + 1).trim();
|
|
439
|
+
try {
|
|
440
|
+
return JSON.parse(envelope);
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
// Continue with fallback scanning.
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Fallback: recover the longest parseable object near the tail.
|
|
447
|
+
let bestMatch = null;
|
|
448
|
+
let bestLen = -1;
|
|
449
|
+
const safeEnd = end >= 0 ? end : clean.length - 1;
|
|
450
|
+
let start = clean.lastIndexOf('{', safeEnd);
|
|
420
451
|
while (start >= 0) {
|
|
421
|
-
const candidate = clean.slice(start,
|
|
452
|
+
const candidate = clean.slice(start, safeEnd + 1).trim();
|
|
422
453
|
try {
|
|
423
|
-
|
|
454
|
+
const parsed = JSON.parse(candidate);
|
|
455
|
+
if (candidate.length > bestLen) {
|
|
456
|
+
bestLen = candidate.length;
|
|
457
|
+
bestMatch = parsed;
|
|
458
|
+
}
|
|
424
459
|
}
|
|
425
460
|
catch {
|
|
426
|
-
|
|
461
|
+
// Ignore parse failures and continue searching.
|
|
427
462
|
}
|
|
463
|
+
start = clean.lastIndexOf('{', start - 1);
|
|
428
464
|
}
|
|
429
|
-
return
|
|
465
|
+
return bestMatch;
|
|
430
466
|
}
|
|
431
467
|
function parseVerifyPayload(output) {
|
|
432
468
|
const parsed = extractLastJsonObject(output);
|
|
@@ -1337,6 +1373,7 @@ async function runPlanAndApply(cwd, intent, projectId, controls) {
|
|
|
1337
1373
|
}, {
|
|
1338
1374
|
timeoutMs: getPlanTimeoutMs(),
|
|
1339
1375
|
label: 'ship:plan',
|
|
1376
|
+
streamOutput: controls?.streamOutput !== false,
|
|
1340
1377
|
});
|
|
1341
1378
|
const planOutput = `${planRun.stdout}\n${planRun.stderr}`;
|
|
1342
1379
|
const parsedPlan = parsePlanPayload(planOutput);
|
|
@@ -1366,6 +1403,7 @@ async function runPlanAndApply(cwd, intent, projectId, controls) {
|
|
|
1366
1403
|
const applyRun = await runCliCommand(cwd, applyArgs, undefined, {
|
|
1367
1404
|
timeoutMs: getApplyTimeoutMs(),
|
|
1368
1405
|
label: 'ship:apply',
|
|
1406
|
+
streamOutput: controls?.streamOutput !== false,
|
|
1369
1407
|
});
|
|
1370
1408
|
const applyOutput = `${applyRun.stdout}\n${applyRun.stderr}`;
|
|
1371
1409
|
const parsedApply = parseApplyPayload(applyOutput);
|
|
@@ -1380,6 +1418,11 @@ async function runPlanAndApply(cwd, intent, projectId, controls) {
|
|
|
1380
1418
|
return { planId, planRun, applyRun: normalizedApplyRun, writtenFiles };
|
|
1381
1419
|
}
|
|
1382
1420
|
async function shipCommand(goal, options) {
|
|
1421
|
+
if (options.json === true) {
|
|
1422
|
+
console.log = (() => undefined);
|
|
1423
|
+
console.warn = (() => undefined);
|
|
1424
|
+
}
|
|
1425
|
+
const streamStepOutput = options.json !== true;
|
|
1383
1426
|
const resumedStart = options.resumeStartedAtIso ? Date.parse(options.resumeStartedAtIso) : NaN;
|
|
1384
1427
|
const startedAt = Number.isFinite(resumedStart) && resumedStart > 0 ? resumedStart : Date.now();
|
|
1385
1428
|
const startedAtIso = new Date(startedAt).toISOString();
|
|
@@ -1565,6 +1608,7 @@ async function shipCommand(goal, options) {
|
|
|
1565
1608
|
let planningAttempt = 1;
|
|
1566
1609
|
let initial = await runPlanAndApply(cwd, scopedGoal, options.projectId, {
|
|
1567
1610
|
enforceDocumentationScope: documentationOnlyGoal,
|
|
1611
|
+
streamOutput: streamStepOutput,
|
|
1568
1612
|
});
|
|
1569
1613
|
recordRunStep(auditSteps, {
|
|
1570
1614
|
stage: 'plan',
|
|
@@ -1590,6 +1634,7 @@ async function shipCommand(goal, options) {
|
|
|
1590
1634
|
planningAttempt += 1;
|
|
1591
1635
|
initial = await runPlanAndApply(cwd, strictGoal, options.projectId, {
|
|
1592
1636
|
enforceDocumentationScope: true,
|
|
1637
|
+
streamOutput: streamStepOutput,
|
|
1593
1638
|
});
|
|
1594
1639
|
recordRunStep(auditSteps, {
|
|
1595
1640
|
stage: 'plan',
|
|
@@ -1670,6 +1715,7 @@ async function shipCommand(goal, options) {
|
|
|
1670
1715
|
: undefined, {
|
|
1671
1716
|
timeoutMs: getVerifyTimeoutMs(),
|
|
1672
1717
|
label: 'ship:verify',
|
|
1718
|
+
streamOutput: streamStepOutput,
|
|
1673
1719
|
});
|
|
1674
1720
|
verifyTotalMs += verifyRun.durationMs;
|
|
1675
1721
|
verifyExitCode = verifyRun.code;
|
|
@@ -1745,7 +1791,9 @@ async function shipCommand(goal, options) {
|
|
|
1745
1791
|
}
|
|
1746
1792
|
console.log(chalk.dim(' Falling back to constrained repair plan...'));
|
|
1747
1793
|
const repairIntent = buildVerifyRepairIntent(normalizedGoal, currentPlanId, verifiedPayload, remediationAttemptsUsed);
|
|
1748
|
-
const repair = await runPlanAndApply(cwd, repairIntent, options.projectId
|
|
1794
|
+
const repair = await runPlanAndApply(cwd, repairIntent, options.projectId, {
|
|
1795
|
+
streamOutput: streamStepOutput,
|
|
1796
|
+
});
|
|
1749
1797
|
recordRunStep(auditSteps, {
|
|
1750
1798
|
stage: 'plan',
|
|
1751
1799
|
attempt: remediationAttemptsUsed + 1,
|
|
@@ -1889,6 +1937,7 @@ async function shipCommand(goal, options) {
|
|
|
1889
1937
|
const testRun = await runShellCommand(cwd, testCommand, {
|
|
1890
1938
|
timeoutMs: getTestTimeoutMs(),
|
|
1891
1939
|
label: 'ship:tests',
|
|
1940
|
+
streamOutput: streamStepOutput,
|
|
1892
1941
|
});
|
|
1893
1942
|
testsTotalMs += testRun.durationMs;
|
|
1894
1943
|
testsExitCode = testRun.code;
|
|
@@ -1911,7 +1960,9 @@ async function shipCommand(goal, options) {
|
|
|
1911
1960
|
});
|
|
1912
1961
|
console.log(chalk.yellow(`⚠️ Test failure auto-remediation attempt ${remediationAttemptsUsed}/${maxFixAttempts}`));
|
|
1913
1962
|
const repairIntent = buildTestRepairIntent(normalizedGoal, currentPlanId, testOutput, remediationAttemptsUsed);
|
|
1914
|
-
const repair = await runPlanAndApply(cwd, repairIntent, options.projectId
|
|
1963
|
+
const repair = await runPlanAndApply(cwd, repairIntent, options.projectId, {
|
|
1964
|
+
streamOutput: streamStepOutput,
|
|
1965
|
+
});
|
|
1915
1966
|
recordRunStep(auditSteps, {
|
|
1916
1967
|
stage: 'plan',
|
|
1917
1968
|
attempt: remediationAttemptsUsed + 1,
|
|
@@ -1956,6 +2007,7 @@ async function shipCommand(goal, options) {
|
|
|
1956
2007
|
: undefined, {
|
|
1957
2008
|
timeoutMs: getVerifyTimeoutMs(),
|
|
1958
2009
|
label: 'ship:verify',
|
|
2010
|
+
streamOutput: streamStepOutput,
|
|
1959
2011
|
});
|
|
1960
2012
|
verifyTotalMs += verifyAfterTestRepair.durationMs;
|
|
1961
2013
|
recordRunStep(auditSteps, {
|
|
@@ -1982,6 +2034,7 @@ async function shipCommand(goal, options) {
|
|
|
1982
2034
|
const finalTestRun = await runShellCommand(cwd, testCommand, {
|
|
1983
2035
|
timeoutMs: getTestTimeoutMs(),
|
|
1984
2036
|
label: 'ship:tests',
|
|
2037
|
+
streamOutput: streamStepOutput,
|
|
1985
2038
|
});
|
|
1986
2039
|
testsTotalMs += finalTestRun.durationMs;
|
|
1987
2040
|
testsExitCode = finalTestRun.code;
|