@neurcode-ai/cli 0.9.50 → 0.9.59
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/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +307 -31
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +264 -13
- package/dist/commands/verify.js.map +1 -1
- package/dist/daemon/server.d.ts +23 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +222 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/intent-engine/coverage.d.ts +69 -0
- package/dist/intent-engine/coverage.d.ts.map +1 -0
- package/dist/intent-engine/coverage.js +140 -0
- package/dist/intent-engine/coverage.js.map +1 -0
- package/dist/intent-engine/flow-rules.d.ts +21 -0
- package/dist/intent-engine/flow-rules.d.ts.map +1 -0
- package/dist/intent-engine/flow-rules.js +83 -0
- package/dist/intent-engine/flow-rules.js.map +1 -0
- package/dist/intent-engine/flow-validator.d.ts +29 -0
- package/dist/intent-engine/flow-validator.d.ts.map +1 -0
- package/dist/intent-engine/flow-validator.js +202 -0
- package/dist/intent-engine/flow-validator.js.map +1 -0
- package/dist/intent-engine/graph.d.ts +33 -0
- package/dist/intent-engine/graph.d.ts.map +1 -0
- package/dist/intent-engine/graph.js +67 -0
- package/dist/intent-engine/graph.js.map +1 -0
- package/dist/intent-engine/index.d.ts +35 -0
- package/dist/intent-engine/index.d.ts.map +1 -0
- package/dist/intent-engine/index.js +94 -0
- package/dist/intent-engine/index.js.map +1 -0
- package/dist/intent-engine/indexer.d.ts +18 -0
- package/dist/intent-engine/indexer.d.ts.map +1 -0
- package/dist/intent-engine/indexer.js +100 -0
- package/dist/intent-engine/indexer.js.map +1 -0
- package/dist/intent-engine/matcher.d.ts +35 -0
- package/dist/intent-engine/matcher.d.ts.map +1 -0
- package/dist/intent-engine/matcher.js +522 -0
- package/dist/intent-engine/matcher.js.map +1 -0
- package/dist/intent-engine/parser.d.ts +12 -0
- package/dist/intent-engine/parser.d.ts.map +1 -0
- package/dist/intent-engine/parser.js +93 -0
- package/dist/intent-engine/parser.js.map +1 -0
- package/dist/intent-engine/regression.d.ts +32 -0
- package/dist/intent-engine/regression.d.ts.map +1 -0
- package/dist/intent-engine/regression.js +166 -0
- package/dist/intent-engine/regression.js.map +1 -0
- package/dist/intent-engine/requirements.d.ts +22 -0
- package/dist/intent-engine/requirements.d.ts.map +1 -0
- package/dist/intent-engine/requirements.js +147 -0
- package/dist/intent-engine/requirements.js.map +1 -0
- package/dist/intent-engine/state.d.ts +44 -0
- package/dist/intent-engine/state.d.ts.map +1 -0
- package/dist/intent-engine/state.js +83 -0
- package/dist/intent-engine/state.js.map +1 -0
- package/dist/utils/ai-debt-budget.d.ts +3 -2
- package/dist/utils/ai-debt-budget.d.ts.map +1 -1
- package/dist/utils/ai-debt-budget.js +83 -2
- package/dist/utils/ai-debt-budget.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/verify.js
CHANGED
|
@@ -56,6 +56,7 @@ const project_root_1 = require("../utils/project-root");
|
|
|
56
56
|
const brain_context_1 = require("../utils/brain-context");
|
|
57
57
|
const scope_telemetry_1 = require("../utils/scope-telemetry");
|
|
58
58
|
const plan_sync_1 = require("../utils/plan-sync");
|
|
59
|
+
const intent_engine_1 = require("../intent-engine");
|
|
59
60
|
const policy_packs_1 = require("../utils/policy-packs");
|
|
60
61
|
const custom_policy_rules_1 = require("../utils/custom-policy-rules");
|
|
61
62
|
const policy_exceptions_1 = require("../utils/policy-exceptions");
|
|
@@ -952,9 +953,79 @@ function toCanonicalVerifyOutput(payload) {
|
|
|
952
953
|
source: 'expedite',
|
|
953
954
|
})),
|
|
954
955
|
]);
|
|
955
|
-
|
|
956
|
-
const
|
|
956
|
+
// ── Intent issues and summary from engine ───────────────────────────────
|
|
957
|
+
const rawIntentIssues = Array.isArray(payload.intentIssues) ? payload.intentIssues : [];
|
|
958
|
+
const intentDomains = Array.isArray(payload.intentDomains) ? payload.intentDomains : [];
|
|
959
|
+
const intentSummary = (payload.intentSummary ?? null);
|
|
960
|
+
const rawFlowIssues = Array.isArray(payload.flowIssues) ? payload.flowIssues : [];
|
|
961
|
+
const rawRegressions = Array.isArray(payload.regressions) ? payload.regressions : [];
|
|
962
|
+
// High-severity intent issues become blocking; medium become advisory.
|
|
963
|
+
const intentBlockingTriageItems = rawIntentIssues
|
|
964
|
+
.filter((i) => i.severity === 'high')
|
|
965
|
+
.map((i) => ({
|
|
966
|
+
file: (i.files?.[0]) ?? 'intent-analysis',
|
|
967
|
+
message: i.message,
|
|
968
|
+
policy: i.rule,
|
|
969
|
+
severity: 'high',
|
|
970
|
+
source: 'violation',
|
|
971
|
+
}));
|
|
972
|
+
const intentAdvisoryTriageItems = rawIntentIssues
|
|
973
|
+
.filter((i) => i.severity === 'medium')
|
|
974
|
+
.map((i) => ({
|
|
975
|
+
file: (i.files?.[0]) ?? 'intent-analysis',
|
|
976
|
+
message: i.message,
|
|
977
|
+
policy: i.rule,
|
|
978
|
+
severity: 'warning',
|
|
979
|
+
source: 'warning',
|
|
980
|
+
}));
|
|
981
|
+
// V5: flow issues — high → blocking, medium → advisory
|
|
982
|
+
const flowBlockingTriageItems = rawFlowIssues
|
|
983
|
+
.filter((i) => i.severity === 'high')
|
|
984
|
+
.map((i) => ({
|
|
985
|
+
file: (i.files?.[0]) ?? 'flow-analysis',
|
|
986
|
+
message: i.message,
|
|
987
|
+
policy: i.rule,
|
|
988
|
+
severity: 'high',
|
|
989
|
+
source: 'violation',
|
|
990
|
+
}));
|
|
991
|
+
const flowAdvisoryTriageItems = rawFlowIssues
|
|
992
|
+
.filter((i) => i.severity === 'medium')
|
|
993
|
+
.map((i) => ({
|
|
994
|
+
file: (i.files?.[0]) ?? 'flow-analysis',
|
|
995
|
+
message: i.message,
|
|
996
|
+
policy: i.rule,
|
|
997
|
+
severity: 'warning',
|
|
998
|
+
source: 'warning',
|
|
999
|
+
}));
|
|
1000
|
+
let blockingItems = expediteModeUsed ? expediteBlockingItems : defaultBlockingItems;
|
|
1001
|
+
let advisoryItems = expediteModeUsed ? expediteItems : defaultAdvisoryItems;
|
|
1002
|
+
if (intentBlockingTriageItems.length > 0) {
|
|
1003
|
+
blockingItems = dedupeTriageItems([...blockingItems, ...intentBlockingTriageItems]);
|
|
1004
|
+
}
|
|
1005
|
+
if (intentAdvisoryTriageItems.length > 0) {
|
|
1006
|
+
advisoryItems = dedupeTriageItems([...advisoryItems, ...intentAdvisoryTriageItems]);
|
|
1007
|
+
}
|
|
1008
|
+
if (flowBlockingTriageItems.length > 0) {
|
|
1009
|
+
blockingItems = dedupeTriageItems([...blockingItems, ...flowBlockingTriageItems]);
|
|
1010
|
+
}
|
|
1011
|
+
if (flowAdvisoryTriageItems.length > 0) {
|
|
1012
|
+
advisoryItems = dedupeTriageItems([...advisoryItems, ...flowAdvisoryTriageItems]);
|
|
1013
|
+
}
|
|
1014
|
+
// V6: regressions — always blocking
|
|
1015
|
+
const regressionBlockingTriageItems = rawRegressions.map((r) => ({
|
|
1016
|
+
file: 'regression-analysis',
|
|
1017
|
+
message: r.message,
|
|
1018
|
+
policy: r.rule,
|
|
1019
|
+
severity: 'high',
|
|
1020
|
+
source: 'violation',
|
|
1021
|
+
}));
|
|
1022
|
+
if (regressionBlockingTriageItems.length > 0) {
|
|
1023
|
+
blockingItems = dedupeTriageItems([...regressionBlockingTriageItems, ...blockingItems]);
|
|
1024
|
+
}
|
|
1025
|
+
const grade = verdict === 'PASS' ? 'A' : verdict === 'WARN' ? 'C' : 'F';
|
|
957
1026
|
return {
|
|
1027
|
+
grade,
|
|
1028
|
+
score: violations.length === 0 && warnings.length === 0 && scopeIssues.length === 0 ? 100 : 0,
|
|
958
1029
|
verdict,
|
|
959
1030
|
summary: {
|
|
960
1031
|
totalFilesChanged,
|
|
@@ -969,6 +1040,11 @@ function toCanonicalVerifyOutput(payload) {
|
|
|
969
1040
|
advisoryCount: advisoryItems.length,
|
|
970
1041
|
blockingItems,
|
|
971
1042
|
advisoryItems,
|
|
1043
|
+
intentIssues: rawIntentIssues,
|
|
1044
|
+
intentDomains,
|
|
1045
|
+
intentSummary,
|
|
1046
|
+
flowIssues: rawFlowIssues,
|
|
1047
|
+
regressions: rawRegressions,
|
|
972
1048
|
expediteModeUsed,
|
|
973
1049
|
expediteCount: expediteModeUsed ? expediteItems.length : 0,
|
|
974
1050
|
expediteItems: expediteModeUsed ? expediteItems : [],
|
|
@@ -1090,20 +1166,32 @@ function toAiDebtSummary(evaluation) {
|
|
|
1090
1166
|
observed: item.observed,
|
|
1091
1167
|
budget: item.budget,
|
|
1092
1168
|
message: item.message,
|
|
1169
|
+
...(item.files && item.files.length > 0 ? { files: item.files } : {}),
|
|
1093
1170
|
})),
|
|
1094
1171
|
};
|
|
1095
1172
|
}
|
|
1173
|
+
const ARCH_VIOLATION_CODES = new Set(['db_in_ui', 'missing_validation']);
|
|
1096
1174
|
function toAiDebtReportViolations(summary) {
|
|
1097
1175
|
if (summary.mode === 'off' || summary.violations.length === 0) {
|
|
1098
1176
|
return [];
|
|
1099
1177
|
}
|
|
1100
|
-
const
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
severity
|
|
1105
|
-
|
|
1106
|
-
|
|
1178
|
+
const defaultSeverity = summary.mode === 'enforce' ? 'block' : 'warn';
|
|
1179
|
+
const result = [];
|
|
1180
|
+
for (const item of summary.violations) {
|
|
1181
|
+
// Architectural violations are always advisory (warn) — heuristic detection, not a hard block
|
|
1182
|
+
const severity = ARCH_VIOLATION_CODES.has(item.code) ? 'warn' : defaultSeverity;
|
|
1183
|
+
const rule = ARCH_VIOLATION_CODES.has(item.code) ? item.code : `ai_debt:${item.code}`;
|
|
1184
|
+
const files = item.files && item.files.length > 0 ? item.files : null;
|
|
1185
|
+
if (files) {
|
|
1186
|
+
for (const file of files) {
|
|
1187
|
+
result.push({ rule, file, severity, message: item.message });
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
else {
|
|
1191
|
+
result.push({ rule, file: '.neurcode/ai-debt-budget.json', severity, message: item.message });
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
return result;
|
|
1107
1195
|
}
|
|
1108
1196
|
function parseSigningKeyRing(raw) {
|
|
1109
1197
|
if (!raw || !raw.trim()) {
|
|
@@ -1902,6 +1990,14 @@ async function verifyCommand(options) {
|
|
|
1902
1990
|
emitCanonicalVerifyJson({
|
|
1903
1991
|
...payload,
|
|
1904
1992
|
expediteMode: expediteModeEnabled,
|
|
1993
|
+
// Intent engine results injected so every code-path gets them.
|
|
1994
|
+
intentIssues: payload.intentIssues ?? intentEngineIssues,
|
|
1995
|
+
intentDomains: payload.intentDomains ?? intentEngineDomains,
|
|
1996
|
+
intentSummary: payload.intentSummary ?? intentEngineSummary,
|
|
1997
|
+
// V5: flow issues injected alongside intent issues
|
|
1998
|
+
flowIssues: payload.flowIssues ?? intentEngineFlowIssues,
|
|
1999
|
+
// V6: regressions always injected
|
|
2000
|
+
regressions: payload.regressions ?? intentEngineRegressions,
|
|
1905
2001
|
});
|
|
1906
2002
|
};
|
|
1907
2003
|
if (!isGitRepository(projectRoot)) {
|
|
@@ -2939,6 +3035,11 @@ async function verifyCommand(options) {
|
|
|
2939
3035
|
let governanceResult = null;
|
|
2940
3036
|
let planFilesForVerification = [];
|
|
2941
3037
|
let intentConstraintsForVerification;
|
|
3038
|
+
let intentEngineIssues = [];
|
|
3039
|
+
let intentEngineDomains = [];
|
|
3040
|
+
let intentEngineSummary = null;
|
|
3041
|
+
let intentEngineFlowIssues = [];
|
|
3042
|
+
let intentEngineRegressions = [];
|
|
2942
3043
|
try {
|
|
2943
3044
|
// Step A: Get Modified Files (already have from diffFiles)
|
|
2944
3045
|
const modifiedFiles = diffFiles.map(f => f.path);
|
|
@@ -2982,6 +3083,23 @@ async function verifyCommand(options) {
|
|
|
2982
3083
|
}
|
|
2983
3084
|
planFilesForVerification = [...new Set([...planFiles, ...localPlanExpectedFiles])];
|
|
2984
3085
|
intentConstraintsForVerification = originalIntent || undefined;
|
|
3086
|
+
// ── Intent-Aware Engine ─────────────────────────────────────────────
|
|
3087
|
+
// Run once we have both diffFiles and the resolved intent text.
|
|
3088
|
+
// Stored in outer scope so all emitCanonicalVerifyJson call sites can
|
|
3089
|
+
// include the result in their payloads without repeating the computation.
|
|
3090
|
+
if (intentConstraintsForVerification && diffFiles.length > 0) {
|
|
3091
|
+
try {
|
|
3092
|
+
const engineResult = (0, intent_engine_1.runIntentEngine)(intentConstraintsForVerification, diffFiles, projectRoot);
|
|
3093
|
+
intentEngineIssues = engineResult.intentIssues;
|
|
3094
|
+
intentEngineDomains = engineResult.checkedDomains;
|
|
3095
|
+
intentEngineSummary = engineResult.intentSummary;
|
|
3096
|
+
intentEngineFlowIssues = engineResult.flowIssues;
|
|
3097
|
+
intentEngineRegressions = engineResult.regressions;
|
|
3098
|
+
}
|
|
3099
|
+
catch {
|
|
3100
|
+
// Non-fatal: intent engine errors must never break verification
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
2985
3103
|
governanceResult = (0, governance_1.evaluateGovernance)({
|
|
2986
3104
|
projectRoot,
|
|
2987
3105
|
task: governanceTask,
|
|
@@ -3085,6 +3203,9 @@ async function verifyCommand(options) {
|
|
|
3085
3203
|
mode: 'plan_enforced',
|
|
3086
3204
|
policyOnly: false,
|
|
3087
3205
|
aiDebt: aiDebtSummaryForScope,
|
|
3206
|
+
intentIssues: intentEngineIssues,
|
|
3207
|
+
intentDomains: intentEngineDomains,
|
|
3208
|
+
intentSummary: intentEngineSummary,
|
|
3088
3209
|
...(expediteModeEnabled ? { expediteMode: true } : {}),
|
|
3089
3210
|
...(governanceResult
|
|
3090
3211
|
? buildGovernancePayload(governanceResult, orgGovernanceSettings, {
|
|
@@ -3160,6 +3281,42 @@ async function verifyCommand(options) {
|
|
|
3160
3281
|
if (governanceResult) {
|
|
3161
3282
|
displayGovernanceInsights(governanceResult, { explain: options.explain });
|
|
3162
3283
|
}
|
|
3284
|
+
// ── Intent Status in scope-violation path ──────────────────────
|
|
3285
|
+
if (intentEngineSummary) {
|
|
3286
|
+
const s = intentEngineSummary;
|
|
3287
|
+
const domainLabel = s.domain.charAt(0).toUpperCase() + s.domain.slice(1);
|
|
3288
|
+
const confColor = s.confidence === 'HIGH' ? chalk.green : s.confidence === 'MEDIUM' ? chalk.yellow : chalk.red;
|
|
3289
|
+
const wCovPct = s.weightedCoverage != null ? Math.round(s.weightedCoverage * 100) : s.coveragePct;
|
|
3290
|
+
const filled = Math.round((wCovPct / 100) * 20);
|
|
3291
|
+
const bar = chalk.cyan('█'.repeat(filled)) + chalk.dim('░'.repeat(20 - filled));
|
|
3292
|
+
const sysStatus = s.status;
|
|
3293
|
+
const statusLabel = sysStatus === 'CRITICAL' ? chalk.bold.red('[CRITICAL]') : sysStatus === 'AT RISK' ? chalk.bold.yellow('[AT RISK]') : chalk.bold.green('[SECURE]');
|
|
3294
|
+
console.log(chalk.bold('\n━━━ INTENT STATUS ━━━━━━━━━━━━━━━━━━━━━━'));
|
|
3295
|
+
console.log(` ${statusLabel} ${chalk.bold(`${domainLabel} Implementation:`)} ${bar} ${chalk.bold(`${wCovPct}%`)} (weighted)`);
|
|
3296
|
+
console.log(` Confidence: ${confColor(s.confidence)}`);
|
|
3297
|
+
const critMissing = s.criticalMissing ?? [];
|
|
3298
|
+
const otherMissing = s.missing.filter((k) => !critMissing.includes(k));
|
|
3299
|
+
if (critMissing.length > 0) {
|
|
3300
|
+
console.log(` ${chalk.bold.red('Critical missing:')}`);
|
|
3301
|
+
critMissing.forEach((k) => { const label = k.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' '); console.log(chalk.red(` ✗ ${label}`)); });
|
|
3302
|
+
}
|
|
3303
|
+
if (otherMissing.length > 0) {
|
|
3304
|
+
console.log(` ${chalk.bold.yellow('Missing:')}`);
|
|
3305
|
+
otherMissing.forEach((k) => { const label = k.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' '); console.log(chalk.yellow(` • ${label}`)); });
|
|
3306
|
+
}
|
|
3307
|
+
if (critMissing.length === 0 && otherMissing.length === 0) {
|
|
3308
|
+
console.log(` Missing: ${chalk.green('none — all components detected')}`);
|
|
3309
|
+
}
|
|
3310
|
+
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
3311
|
+
}
|
|
3312
|
+
if (intentEngineRegressions.length > 0) {
|
|
3313
|
+
console.log(chalk.bold.red('\n━━━ REGRESSION ANALYSIS ━━━━━━━━━━━━━━━━━'));
|
|
3314
|
+
intentEngineRegressions.forEach((reg) => {
|
|
3315
|
+
const icon = reg.type === 'coverage-regression' ? '📉' : reg.type === 'critical-regression' ? '🔴' : reg.type === 'flow-regression' ? '⛓' : '⚠';
|
|
3316
|
+
console.log(` ${chalk.red('[REGRESSION]')} ${icon} ${reg.message}`);
|
|
3317
|
+
});
|
|
3318
|
+
console.log(chalk.bold.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
3319
|
+
}
|
|
3163
3320
|
console.log('');
|
|
3164
3321
|
await recordVerificationIfRequested(options, config, {
|
|
3165
3322
|
grade: 'F',
|
|
@@ -4014,7 +4171,7 @@ async function verifyCommand(options) {
|
|
|
4014
4171
|
message: effectiveMessage,
|
|
4015
4172
|
bloatFiles: displayBloatFiles,
|
|
4016
4173
|
bloatCount: displayBloatFiles.length,
|
|
4017
|
-
}, policyViolations, expediteModeEnabled);
|
|
4174
|
+
}, policyViolations, expediteModeEnabled, intentEngineIssues, intentEngineSummary, intentEngineFlowIssues, intentEngineRegressions);
|
|
4018
4175
|
if (governanceResult) {
|
|
4019
4176
|
displayGovernanceInsights(governanceResult, { explain: options.explain });
|
|
4020
4177
|
}
|
|
@@ -4544,7 +4701,7 @@ function displayChangeContractDrift(summary, options = { advisory: false }) {
|
|
|
4544
4701
|
/**
|
|
4545
4702
|
* Display verification results in a formatted report card
|
|
4546
4703
|
*/
|
|
4547
|
-
function displayVerifyResults(result, policyViolations, expediteModeUsed = false) {
|
|
4704
|
+
function displayVerifyResults(result, policyViolations, expediteModeUsed = false, intentIssuesForDisplay = [], intentSummaryForDisplay = null, flowIssuesForDisplay = [], regressionsForDisplay = []) {
|
|
4548
4705
|
// ── Header ────────────────────────────────────────────────────────────────
|
|
4549
4706
|
const headerLabel = result.verdict === 'PASS'
|
|
4550
4707
|
? chalk.bold.green('\n✅ VERIFICATION PASSED')
|
|
@@ -4552,6 +4709,60 @@ function displayVerifyResults(result, policyViolations, expediteModeUsed = false
|
|
|
4552
4709
|
? chalk.bold.yellow('\n⚠️ VERIFICATION PASSED WITH WARNINGS')
|
|
4553
4710
|
: chalk.bold.red('\n❌ VERIFICATION FAILED');
|
|
4554
4711
|
console.log(headerLabel);
|
|
4712
|
+
// ── Intent Status block ──────────────────────────────────────────────────
|
|
4713
|
+
if (intentSummaryForDisplay) {
|
|
4714
|
+
const s = intentSummaryForDisplay;
|
|
4715
|
+
const domainLabel = s.domain.charAt(0).toUpperCase() + s.domain.slice(1);
|
|
4716
|
+
const confColor = s.confidence === 'HIGH'
|
|
4717
|
+
? chalk.green
|
|
4718
|
+
: s.confidence === 'MEDIUM'
|
|
4719
|
+
? chalk.yellow
|
|
4720
|
+
: chalk.red;
|
|
4721
|
+
// V4: weighted coverage bar
|
|
4722
|
+
const wCovPct = s.weightedCoverage != null
|
|
4723
|
+
? Math.round(s.weightedCoverage * 100)
|
|
4724
|
+
: s.coveragePct;
|
|
4725
|
+
const barWidth = 20;
|
|
4726
|
+
const filled = Math.round((wCovPct / 100) * barWidth);
|
|
4727
|
+
const bar = chalk.cyan('█'.repeat(filled)) + chalk.dim('░'.repeat(barWidth - filled));
|
|
4728
|
+
// V4: system status label
|
|
4729
|
+
const sysStatus = s.status;
|
|
4730
|
+
const statusLabel = sysStatus === 'CRITICAL'
|
|
4731
|
+
? chalk.bold.red('[CRITICAL]')
|
|
4732
|
+
: sysStatus === 'AT RISK'
|
|
4733
|
+
? chalk.bold.yellow('[AT RISK]')
|
|
4734
|
+
: chalk.bold.green('[SECURE]');
|
|
4735
|
+
console.log(chalk.bold('\n━━━ INTENT STATUS ━━━━━━━━━━━━━━━━━━━━━━'));
|
|
4736
|
+
console.log(` ${statusLabel} ${chalk.bold(`${domainLabel} Implementation:`)} ${bar} ${chalk.bold(`${wCovPct}%`)} (weighted)`);
|
|
4737
|
+
console.log(` Confidence: ${confColor(s.confidence)}`);
|
|
4738
|
+
if (s.foundList.length > 0) {
|
|
4739
|
+
const foundLabels = s.foundList
|
|
4740
|
+
.map((k) => k.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' '))
|
|
4741
|
+
.slice(0, 4);
|
|
4742
|
+
console.log(` Found: ${chalk.green(foundLabels.join(', '))}${s.foundList.length > 4 ? chalk.dim(` +${s.foundList.length - 4} more`) : ''}`);
|
|
4743
|
+
}
|
|
4744
|
+
// V4: show critical missing and non-critical missing separately
|
|
4745
|
+
const critMissing = s.criticalMissing ?? [];
|
|
4746
|
+
const otherMissing = s.missing.filter((k) => !critMissing.includes(k));
|
|
4747
|
+
if (critMissing.length > 0) {
|
|
4748
|
+
console.log(` ${chalk.bold.red('Critical missing:')}`);
|
|
4749
|
+
critMissing.forEach((k) => {
|
|
4750
|
+
const label = k.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
4751
|
+
console.log(chalk.red(` ✗ ${label}`));
|
|
4752
|
+
});
|
|
4753
|
+
}
|
|
4754
|
+
if (otherMissing.length > 0) {
|
|
4755
|
+
console.log(` ${chalk.bold.yellow('Missing:')}`);
|
|
4756
|
+
otherMissing.forEach((k) => {
|
|
4757
|
+
const label = k.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
4758
|
+
console.log(chalk.yellow(` • ${label}`));
|
|
4759
|
+
});
|
|
4760
|
+
}
|
|
4761
|
+
if (critMissing.length === 0 && otherMissing.length === 0) {
|
|
4762
|
+
console.log(` Missing: ${chalk.green('none — all components detected')}`);
|
|
4763
|
+
}
|
|
4764
|
+
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
4765
|
+
}
|
|
4555
4766
|
// ── Triage items ──────────────────────────────────────────────────────────
|
|
4556
4767
|
const maxBlockingItems = 20;
|
|
4557
4768
|
const maxAdvisoryItems = 8;
|
|
@@ -4667,11 +4878,51 @@ function displayVerifyResults(result, policyViolations, expediteModeUsed = false
|
|
|
4667
4878
|
});
|
|
4668
4879
|
console.log(chalk.dim(' Note: Expedite Mode used'));
|
|
4669
4880
|
}
|
|
4670
|
-
|
|
4881
|
+
// ── Intent issues ─────────────────────────────────────────────────────────
|
|
4882
|
+
if (intentIssuesForDisplay.length > 0) {
|
|
4883
|
+
console.log(chalk.magenta(`\nINTENT ISSUES (${intentIssuesForDisplay.length})`));
|
|
4884
|
+
intentIssuesForDisplay.forEach((issue) => {
|
|
4885
|
+
const label = issue.severity === 'high' ? chalk.red('[HIGH]') : chalk.yellow('[MEDIUM]');
|
|
4886
|
+
const typeLabel = issue.type === 'missing' ? 'Missing' : issue.type === 'misplaced' ? 'Misplaced' : 'Partial';
|
|
4887
|
+
console.log(` ${label} ${typeLabel}: ${issue.message}`);
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4890
|
+
// ── Flow Validation ───────────────────────────────────────────────────────
|
|
4891
|
+
if (flowIssuesForDisplay.length > 0) {
|
|
4892
|
+
console.log(chalk.bold('\n━━━ FLOW VALIDATION ━━━━━━━━━━━━━━━━━━━━━'));
|
|
4893
|
+
flowIssuesForDisplay.forEach((issue) => {
|
|
4894
|
+
const label = issue.severity === 'high' ? chalk.red('[HIGH]') : chalk.yellow('[MEDIUM]');
|
|
4895
|
+
const typeIcon = issue.type === 'missing-flow' ? '⛓' : issue.type === 'misplaced-flow' ? '⚠' : '⊘';
|
|
4896
|
+
console.log(` ${label} ${typeIcon} ${issue.message}`);
|
|
4897
|
+
if (issue.files && issue.files.length > 0) {
|
|
4898
|
+
const display = issue.files.slice(0, 3);
|
|
4899
|
+
console.log(chalk.dim(` → ${display.join(', ')}${issue.files.length > 3 ? ` +${issue.files.length - 3} more` : ''}`));
|
|
4900
|
+
}
|
|
4901
|
+
});
|
|
4902
|
+
console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
4903
|
+
}
|
|
4904
|
+
// ── Regression Analysis ───────────────────────────────────────────────────
|
|
4905
|
+
if (regressionsForDisplay.length > 0) {
|
|
4906
|
+
console.log(chalk.bold.red('\n━━━ REGRESSION ANALYSIS ━━━━━━━━━━━━━━━━━'));
|
|
4907
|
+
regressionsForDisplay.forEach((reg) => {
|
|
4908
|
+
const icon = reg.type === 'coverage-regression' ? '📉' :
|
|
4909
|
+
reg.type === 'critical-regression' ? '🔴' :
|
|
4910
|
+
reg.type === 'flow-regression' ? '⛓' : '⚠';
|
|
4911
|
+
console.log(` ${chalk.red('[REGRESSION]')} ${icon} ${reg.message}`);
|
|
4912
|
+
});
|
|
4913
|
+
console.log(chalk.bold.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
4914
|
+
}
|
|
4915
|
+
const hasAnyIssue = blockingItems.length > 0 ||
|
|
4916
|
+
advisoryItems.length > 0 ||
|
|
4917
|
+
expediteItems.length > 0 ||
|
|
4918
|
+
intentIssuesForDisplay.length > 0 ||
|
|
4919
|
+
flowIssuesForDisplay.length > 0 ||
|
|
4920
|
+
regressionsForDisplay.length > 0;
|
|
4921
|
+
if (!hasAnyIssue) {
|
|
4671
4922
|
console.log(chalk.green('\nNo issues detected.'));
|
|
4672
4923
|
}
|
|
4673
4924
|
// ── Next step ─────────────────────────────────────────────────────────────
|
|
4674
|
-
if (
|
|
4925
|
+
if (hasAnyIssue) {
|
|
4675
4926
|
console.log(chalk.bold('\nNext step:'));
|
|
4676
4927
|
console.log(` ${chalk.cyan('neurcode fix')}`);
|
|
4677
4928
|
console.log(chalk.dim(' or: neurcode fix --apply-safe (auto-apply high-confidence patches)'));
|