@ipation/specbridge 2.2.0 → 2.4.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/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli/index.ts
4
4
  import { Command as Command20 } from "commander";
5
- import chalk20 from "chalk";
5
+ import chalk19 from "chalk";
6
6
  import { readFileSync as readFileSync2 } from "fs";
7
7
  import { fileURLToPath as fileURLToPath4 } from "url";
8
8
  import { dirname as dirname5, join as join14 } from "path";
@@ -1261,7 +1261,7 @@ async function loadConfig(basePath = process.cwd()) {
1261
1261
  const parsed = parseYaml(content);
1262
1262
  const result = validateConfig(parsed);
1263
1263
  if (!result.success) {
1264
- const errors = result.errors.errors.map((e) => `${e.path.join(".")}: ${e.message}`);
1264
+ const errors = result.errors.issues.map((e) => `${e.path.join(".")}: ${e.message}`);
1265
1265
  throw new ConfigError(`Invalid configuration in ${configPath}`, { errors });
1266
1266
  }
1267
1267
  return result.data;
@@ -1345,12 +1345,11 @@ Detected ${patterns.length} pattern(s):
1345
1345
 
1346
1346
  // src/cli/commands/verify.ts
1347
1347
  import { Command as Command3 } from "commander";
1348
- import chalk5 from "chalk";
1348
+ import chalk4 from "chalk";
1349
1349
  import ora3 from "ora";
1350
1350
 
1351
1351
  // src/verification/engine.ts
1352
1352
  import { Project as Project2 } from "ts-morph";
1353
- import chalk3 from "chalk";
1354
1353
 
1355
1354
  // src/registry/loader.ts
1356
1355
  import { join as join4 } from "path";
@@ -1385,7 +1384,7 @@ var ConstraintExceptionSchema = z2.object({
1385
1384
  });
1386
1385
  var ConstraintCheckSchema = z2.object({
1387
1386
  verifier: z2.string().min(1),
1388
- params: z2.record(z2.unknown()).optional()
1387
+ params: z2.record(z2.string(), z2.unknown()).optional()
1389
1388
  });
1390
1389
  var ConstraintSchema = z2.object({
1391
1390
  id: z2.string().min(1).regex(/^[a-z0-9-]+$/, "Constraint ID must be lowercase alphanumeric with hyphens"),
@@ -1427,7 +1426,7 @@ function validateDecision(data) {
1427
1426
  return { success: false, errors: result.error };
1428
1427
  }
1429
1428
  function formatValidationErrors(errors) {
1430
- return errors.errors.map((err) => {
1429
+ return errors.issues.map((err) => {
1431
1430
  const path5 = err.path.join(".");
1432
1431
  return `${path5}: ${err.message}`;
1433
1432
  });
@@ -2149,7 +2148,10 @@ function buildDependencyGraph(project) {
2149
2148
  const moduleSpec = importDecl.getModuleSpecifierValue();
2150
2149
  const resolved = resolveToSourceFilePath(project, from, moduleSpec);
2151
2150
  if (resolved) {
2152
- graph.get(from).add(normalizeFsPath(resolved));
2151
+ const dependencies = graph.get(from);
2152
+ if (dependencies) {
2153
+ dependencies.add(normalizeFsPath(resolved));
2154
+ }
2153
2155
  }
2154
2156
  }
2155
2157
  }
@@ -2173,9 +2175,17 @@ function tarjanScc(graph) {
2173
2175
  for (const w of edges) {
2174
2176
  if (!indices.has(w)) {
2175
2177
  strongConnect(w);
2176
- lowlink.set(v, Math.min(lowlink.get(v), lowlink.get(w)));
2178
+ const currentLowlink = lowlink.get(v);
2179
+ const childLowlink = lowlink.get(w);
2180
+ if (currentLowlink !== void 0 && childLowlink !== void 0) {
2181
+ lowlink.set(v, Math.min(currentLowlink, childLowlink));
2182
+ }
2177
2183
  } else if (onStack.has(w)) {
2178
- lowlink.set(v, Math.min(lowlink.get(v), indices.get(w)));
2184
+ const currentLowlink = lowlink.get(v);
2185
+ const childIndex = indices.get(w);
2186
+ if (currentLowlink !== void 0 && childIndex !== void 0) {
2187
+ lowlink.set(v, Math.min(currentLowlink, childIndex));
2188
+ }
2179
2189
  }
2180
2190
  }
2181
2191
  if (lowlink.get(v) === indices.get(v)) {
@@ -2197,18 +2207,21 @@ function tarjanScc(graph) {
2197
2207
  }
2198
2208
  function parseMaxImportDepth(rule) {
2199
2209
  const m = rule.match(/maximum\s{1,5}import\s{1,5}depth\s{0,5}[:=]?\s{0,5}(\d+)/i);
2200
- return m ? Number.parseInt(m[1], 10) : null;
2210
+ const depthText = m?.[1];
2211
+ return depthText ? Number.parseInt(depthText, 10) : null;
2201
2212
  }
2202
2213
  function parseBannedDependency(rule) {
2203
2214
  const m = rule.match(/no\s{1,5}dependencies?\s{1,5}on\s{1,5}(?:package\s{1,5})?(.+?)(?:\.|$)/i);
2204
- if (!m) return null;
2205
- const value = m[1].trim();
2215
+ const value = m?.[1]?.trim();
2216
+ if (!value) return null;
2206
2217
  return value.length > 0 ? value : null;
2207
2218
  }
2208
2219
  function parseLayerRule(rule) {
2209
2220
  const m = rule.match(/(\w+)\s{1,5}layer\s{1,5}cannot\s{1,5}depend\s{1,5}on\s{1,5}(\w+)\s{1,5}layer/i);
2210
- if (!m) return null;
2211
- return { fromLayer: m[1].toLowerCase(), toLayer: m[2].toLowerCase() };
2221
+ const fromLayer = m?.[1]?.toLowerCase();
2222
+ const toLayer = m?.[2]?.toLowerCase();
2223
+ if (!fromLayer || !toLayer) return null;
2224
+ return { fromLayer, toLayer };
2212
2225
  }
2213
2226
  function fileInLayer(filePath, layer) {
2214
2227
  const fp = normalizeFsPath(filePath).toLowerCase();
@@ -2230,7 +2243,8 @@ var DependencyVerifier = class {
2230
2243
  const sccs = tarjanScc(graph);
2231
2244
  const current = projectFilePath;
2232
2245
  for (const scc of sccs) {
2233
- const hasSelfLoop = scc.length === 1 && (graph.get(scc[0])?.has(scc[0]) ?? false);
2246
+ const first = scc[0];
2247
+ const hasSelfLoop = first !== void 0 && scc.length === 1 && (graph.get(first)?.has(first) ?? false);
2234
2248
  const isCycle = scc.length > 1 || hasSelfLoop;
2235
2249
  if (!isCycle) continue;
2236
2250
  if (!scc.includes(current)) continue;
@@ -2312,10 +2326,12 @@ var DependencyVerifier = class {
2312
2326
  };
2313
2327
 
2314
2328
  // src/verification/verifiers/complexity.ts
2329
+ import { Node as Node4 } from "ts-morph";
2315
2330
  import { SyntaxKind as SyntaxKind2 } from "ts-morph";
2316
2331
  function parseLimit(rule, pattern) {
2317
2332
  const m = rule.match(pattern);
2318
- return m ? Number.parseInt(m[1], 10) : null;
2333
+ const value = m?.[1];
2334
+ return value ? Number.parseInt(value, 10) : null;
2319
2335
  }
2320
2336
  function getFileLineCount(text) {
2321
2337
  if (text.length === 0) return 0;
@@ -2351,14 +2367,15 @@ function calculateCyclomaticComplexity(fn) {
2351
2367
  return 1 + getDecisionPoints(fn);
2352
2368
  }
2353
2369
  function getFunctionDisplayName(fn) {
2354
- if ("getName" in fn && typeof fn.getName === "function") {
2370
+ if (Node4.isFunctionDeclaration(fn) || Node4.isMethodDeclaration(fn) || Node4.isFunctionExpression(fn)) {
2355
2371
  const name = fn.getName();
2356
- if (typeof name === "string" && name.length > 0) return name;
2372
+ if (typeof name === "string" && name.length > 0) {
2373
+ return name;
2374
+ }
2357
2375
  }
2358
2376
  const parent = fn.getParent();
2359
- if (parent?.getKind() === SyntaxKind2.VariableDeclaration) {
2360
- const vd = parent;
2361
- if (typeof vd.getName === "function") return vd.getName();
2377
+ if (parent && Node4.isVariableDeclaration(parent)) {
2378
+ return parent.getName();
2362
2379
  }
2363
2380
  return "<anonymous>";
2364
2381
  }
@@ -2428,9 +2445,8 @@ var ComplexityVerifier = class {
2428
2445
  }));
2429
2446
  }
2430
2447
  }
2431
- if (maxParams !== null && "getParameters" in fn) {
2432
- const params = fn.getParameters();
2433
- const paramCount = Array.isArray(params) ? params.length : 0;
2448
+ if (maxParams !== null) {
2449
+ const paramCount = fn.getParameters().length;
2434
2450
  if (paramCount > maxParams) {
2435
2451
  violations.push(createViolation({
2436
2452
  decisionId,
@@ -2504,8 +2520,7 @@ var SecurityVerifier = class {
2504
2520
  }));
2505
2521
  }
2506
2522
  for (const pa of sourceFile.getDescendantsOfKind(SyntaxKind3.PropertyAssignment)) {
2507
- const nameNode = pa.getNameNode?.();
2508
- const propName = nameNode?.getText?.() ?? "";
2523
+ const propName = pa.getNameNode().getText();
2509
2524
  if (!SECRET_NAME_RE.test(propName)) continue;
2510
2525
  const init = pa.getInitializer();
2511
2526
  if (!init || !isStringLiteralLike(init)) continue;
@@ -2541,9 +2556,9 @@ var SecurityVerifier = class {
2541
2556
  if (checkXss) {
2542
2557
  for (const bin of sourceFile.getDescendantsOfKind(SyntaxKind3.BinaryExpression)) {
2543
2558
  const left = bin.getLeft();
2544
- if (left.getKind() !== SyntaxKind3.PropertyAccessExpression) continue;
2545
- const pa = left;
2546
- if (pa.getName?.() === "innerHTML") {
2559
+ const propertyAccess = left.asKind(SyntaxKind3.PropertyAccessExpression);
2560
+ if (!propertyAccess) continue;
2561
+ if (propertyAccess.getName() === "innerHTML") {
2547
2562
  violations.push(createViolation({
2548
2563
  decisionId,
2549
2564
  constraintId: constraint.id,
@@ -2572,8 +2587,9 @@ var SecurityVerifier = class {
2572
2587
  if (checkSql) {
2573
2588
  for (const call of sourceFile.getDescendantsOfKind(SyntaxKind3.CallExpression)) {
2574
2589
  const expr = call.getExpression();
2575
- if (expr.getKind() !== SyntaxKind3.PropertyAccessExpression) continue;
2576
- const name = expr.getName?.();
2590
+ const propertyAccess = expr.asKind(SyntaxKind3.PropertyAccessExpression);
2591
+ if (!propertyAccess) continue;
2592
+ const name = propertyAccess.getName();
2577
2593
  if (name !== "query" && name !== "execute") continue;
2578
2594
  const arg = call.getArguments()[0];
2579
2595
  if (!arg) continue;
@@ -2638,12 +2654,14 @@ var ApiVerifier = class {
2638
2654
  if (!enforceKebab) return violations;
2639
2655
  for (const call of sourceFile.getDescendantsOfKind(SyntaxKind4.CallExpression)) {
2640
2656
  const expr = call.getExpression();
2641
- if (expr.getKind() !== SyntaxKind4.PropertyAccessExpression) continue;
2642
- const method = expr.getName?.();
2657
+ const propertyAccess = expr.asKind(SyntaxKind4.PropertyAccessExpression);
2658
+ if (!propertyAccess) continue;
2659
+ const method = propertyAccess.getName();
2643
2660
  if (!method || !HTTP_METHODS.has(String(method))) continue;
2644
2661
  const firstArg = call.getArguments()[0];
2645
- if (!firstArg || firstArg.getKind() !== SyntaxKind4.StringLiteral) continue;
2646
- const pathValue = firstArg.getLiteralValue?.() ?? firstArg.getText().slice(1, -1);
2662
+ const stringLiteral = firstArg?.asKind(SyntaxKind4.StringLiteral);
2663
+ if (!stringLiteral) continue;
2664
+ const pathValue = stringLiteral.getLiteralValue();
2647
2665
  if (typeof pathValue !== "string") continue;
2648
2666
  if (!isKebabPath(pathValue)) {
2649
2667
  violations.push(createViolation({
@@ -2667,10 +2685,36 @@ import { existsSync } from "fs";
2667
2685
  import { join as join5 } from "path";
2668
2686
  import { pathToFileURL } from "url";
2669
2687
  import fg2 from "fast-glob";
2688
+
2689
+ // src/utils/logger.ts
2690
+ import pino from "pino";
2691
+ var defaultOptions = {
2692
+ level: process.env.SPECBRIDGE_LOG_LEVEL || "info",
2693
+ timestamp: pino.stdTimeFunctions.isoTime,
2694
+ base: {
2695
+ service: "specbridge"
2696
+ }
2697
+ };
2698
+ var destination = pino.destination({
2699
+ fd: 2,
2700
+ // stderr
2701
+ sync: false
2702
+ });
2703
+ var rootLogger = pino(defaultOptions, destination);
2704
+ function getLogger(bindings) {
2705
+ if (!bindings) {
2706
+ return rootLogger;
2707
+ }
2708
+ return rootLogger.child(bindings);
2709
+ }
2710
+ var logger = getLogger();
2711
+
2712
+ // src/verification/plugins/loader.ts
2670
2713
  var PluginLoader = class {
2671
2714
  plugins = /* @__PURE__ */ new Map();
2672
2715
  loaded = false;
2673
2716
  loadErrors = [];
2717
+ logger = getLogger({ module: "verification.plugins.loader" });
2674
2718
  /**
2675
2719
  * Load all plugins from the specified base path
2676
2720
  *
@@ -2693,15 +2737,15 @@ var PluginLoader = class {
2693
2737
  } catch (error) {
2694
2738
  const message = error instanceof Error ? error.message : String(error);
2695
2739
  this.loadErrors.push({ file, error: message });
2696
- console.warn(`Failed to load plugin from ${file}: ${message}`);
2740
+ this.logger.warn({ file, error: message }, "Failed to load plugin");
2697
2741
  }
2698
2742
  }
2699
2743
  this.loaded = true;
2700
2744
  if (this.plugins.size > 0) {
2701
- console.error(`Loaded ${this.plugins.size} custom verifier(s)`);
2745
+ this.logger.info({ count: this.plugins.size }, "Loaded custom verifier plugins");
2702
2746
  }
2703
2747
  if (this.loadErrors.length > 0) {
2704
- console.warn(`Failed to load ${this.loadErrors.length} plugin(s)`);
2748
+ this.logger.warn({ count: this.loadErrors.length }, "Plugin load failures");
2705
2749
  }
2706
2750
  }
2707
2751
  /**
@@ -2877,8 +2921,9 @@ var builtinVerifiers = {
2877
2921
  };
2878
2922
  var verifierInstances = /* @__PURE__ */ new Map();
2879
2923
  function getVerifier(id) {
2880
- if (verifierInstances.has(id)) {
2881
- return verifierInstances.get(id);
2924
+ const pooled = verifierInstances.get(id);
2925
+ if (pooled) {
2926
+ return pooled;
2882
2927
  }
2883
2928
  const pluginLoader2 = getPluginLoader();
2884
2929
  const customVerifier = pluginLoader2.getVerifier(id);
@@ -3080,6 +3125,7 @@ var VerificationEngine = class {
3080
3125
  astCache;
3081
3126
  resultsCache;
3082
3127
  pluginsLoaded = false;
3128
+ logger = getLogger({ module: "verification.engine" });
3083
3129
  constructor(registry) {
3084
3130
  this.registry = registry || createRegistry();
3085
3131
  this.project = new Project2({
@@ -3253,13 +3299,12 @@ var VerificationEngine = class {
3253
3299
  );
3254
3300
  if (!verifier) {
3255
3301
  const requestedVerifier = constraint.check?.verifier || constraint.verifier || "auto-detected";
3256
- console.warn(
3257
- chalk3.yellow(
3258
- `Warning: No verifier found for ${decision.metadata.id}/${constraint.id}
3259
- Requested: ${requestedVerifier}
3260
- Available: ${getVerifierIds().join(", ")}`
3261
- )
3262
- );
3302
+ this.logger.warn({
3303
+ decisionId: decision.metadata.id,
3304
+ constraintId: constraint.id,
3305
+ requestedVerifier,
3306
+ availableVerifiers: getVerifierIds()
3307
+ }, "No verifier found for constraint");
3263
3308
  warnings.push({
3264
3309
  type: "missing_verifier",
3265
3310
  message: `No verifier found for constraint (requested: ${requestedVerifier})`,
@@ -3365,17 +3410,14 @@ var VerificationEngine = class {
3365
3410
  } catch (error) {
3366
3411
  const errorMessage = error instanceof Error ? error.message : String(error);
3367
3412
  const errorStack = error instanceof Error ? error.stack : void 0;
3368
- console.error(
3369
- chalk3.red(
3370
- `Error: Verifier '${verifier.id}' failed
3371
- File: ${filePath}
3372
- Decision: ${decision.metadata.id}/${constraint.id}
3373
- Error: ${errorMessage}`
3374
- )
3375
- );
3376
- if (errorStack) {
3377
- console.error(chalk3.dim(errorStack));
3378
- }
3413
+ this.logger.error({
3414
+ verifierId: verifier.id,
3415
+ filePath,
3416
+ decisionId: decision.metadata.id,
3417
+ constraintId: constraint.id,
3418
+ error: errorMessage,
3419
+ stack: errorStack
3420
+ }, "Verifier execution failed");
3379
3421
  errors.push({
3380
3422
  type: "verifier_exception",
3381
3423
  message: `Verifier '${verifier.id}' failed: ${errorMessage}`,
@@ -3491,6 +3533,10 @@ var AutofixEngine = class {
3491
3533
  const edits = [];
3492
3534
  for (const violation of fileViolations) {
3493
3535
  const fix = violation.autofix;
3536
+ if (!fix) {
3537
+ skippedViolations++;
3538
+ continue;
3539
+ }
3494
3540
  if (options.interactive) {
3495
3541
  const ok = await confirmFix(`Apply fix: ${fix.description} (${filePath}:${violation.line ?? 1})?`);
3496
3542
  if (!ok) {
@@ -3537,7 +3583,7 @@ async function getChangedFiles(cwd) {
3537
3583
  }
3538
3584
 
3539
3585
  // src/verification/explain.ts
3540
- import chalk4 from "chalk";
3586
+ import chalk3 from "chalk";
3541
3587
  var ExplainReporter = class {
3542
3588
  entries = [];
3543
3589
  /**
@@ -3551,10 +3597,10 @@ var ExplainReporter = class {
3551
3597
  */
3552
3598
  print() {
3553
3599
  if (this.entries.length === 0) {
3554
- console.log(chalk4.dim("No constraints were evaluated."));
3600
+ console.log(chalk3.dim("No constraints were evaluated."));
3555
3601
  return;
3556
3602
  }
3557
- console.log(chalk4.bold("\n=== Verification Explanation ===\n"));
3603
+ console.log(chalk3.bold("\n=== Verification Explanation ===\n"));
3558
3604
  const byFile = /* @__PURE__ */ new Map();
3559
3605
  for (const entry of this.entries) {
3560
3606
  const existing = byFile.get(entry.file) || [];
@@ -3562,22 +3608,22 @@ var ExplainReporter = class {
3562
3608
  byFile.set(entry.file, existing);
3563
3609
  }
3564
3610
  for (const [file, entries] of byFile) {
3565
- console.log(chalk4.underline(file));
3611
+ console.log(chalk3.underline(file));
3566
3612
  for (const entry of entries) {
3567
- const icon = entry.applied ? chalk4.green("\u2713") : chalk4.dim("\u2298");
3613
+ const icon = entry.applied ? chalk3.green("\u2713") : chalk3.dim("\u2298");
3568
3614
  const constraintId = `${entry.decision.metadata.id}/${entry.constraint.id}`;
3569
3615
  console.log(` ${icon} ${constraintId}`);
3570
- console.log(chalk4.dim(` ${entry.reason}`));
3616
+ console.log(chalk3.dim(` ${entry.reason}`));
3571
3617
  if (entry.applied && entry.selectedVerifier) {
3572
- console.log(chalk4.dim(` Verifier: ${entry.selectedVerifier}`));
3618
+ console.log(chalk3.dim(` Verifier: ${entry.selectedVerifier}`));
3573
3619
  if (entry.verifierOutput) {
3574
3620
  if (entry.verifierOutput.error) {
3575
- console.log(chalk4.red(` Error: ${entry.verifierOutput.error}`));
3621
+ console.log(chalk3.red(` Error: ${entry.verifierOutput.error}`));
3576
3622
  } else {
3577
3623
  const violationText = entry.verifierOutput.violations === 1 ? "1 violation" : `${entry.verifierOutput.violations} violations`;
3578
- const resultColor = entry.verifierOutput.violations > 0 ? chalk4.red : chalk4.green;
3624
+ const resultColor = entry.verifierOutput.violations > 0 ? chalk3.red : chalk3.green;
3579
3625
  console.log(
3580
- chalk4.dim(` Result: `) + resultColor(violationText) + chalk4.dim(` in ${entry.verifierOutput.duration}ms`)
3626
+ chalk3.dim(` Result: `) + resultColor(violationText) + chalk3.dim(` in ${entry.verifierOutput.duration}ms`)
3581
3627
  );
3582
3628
  }
3583
3629
  }
@@ -3587,9 +3633,9 @@ var ExplainReporter = class {
3587
3633
  }
3588
3634
  const applied = this.entries.filter((e) => e.applied).length;
3589
3635
  const skipped = this.entries.filter((e) => !e.applied).length;
3590
- console.log(chalk4.bold("Summary:"));
3591
- console.log(` Constraints Applied: ${chalk4.green(applied)}`);
3592
- console.log(` Constraints Skipped: ${chalk4.dim(skipped)}`);
3636
+ console.log(chalk3.bold("Summary:"));
3637
+ console.log(` Constraints Applied: ${chalk3.green(applied)}`);
3638
+ console.log(` Constraints Skipped: ${chalk3.dim(skipped)}`);
3593
3639
  }
3594
3640
  /**
3595
3641
  * Get all entries
@@ -3639,7 +3685,7 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3639
3685
  if (fixableCount === 0) {
3640
3686
  spinner.stop();
3641
3687
  if (!options.json) {
3642
- console.log(chalk5.yellow("No auto-fixable violations found"));
3688
+ console.log(chalk4.yellow("No auto-fixable violations found"));
3643
3689
  }
3644
3690
  } else {
3645
3691
  spinner.text = `Applying ${fixableCount} auto-fix(es)...`;
@@ -3664,34 +3710,34 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3664
3710
  console.log(JSON.stringify({ ...result, autofix: fixResult }, null, 2));
3665
3711
  } else {
3666
3712
  if (result.warnings && result.warnings.length > 0) {
3667
- console.log(chalk5.yellow.bold("\nWarnings:"));
3713
+ console.log(chalk4.yellow.bold("\nWarnings:"));
3668
3714
  for (const warning of result.warnings) {
3669
- console.log(chalk5.yellow(` \u26A0 ${warning.message}`));
3670
- console.log(chalk5.dim(` ${warning.decisionId}/${warning.constraintId}`));
3715
+ console.log(chalk4.yellow(` \u26A0 ${warning.message}`));
3716
+ console.log(chalk4.dim(` ${warning.decisionId}/${warning.constraintId}`));
3671
3717
  if (warning.file) {
3672
- console.log(chalk5.dim(` File: ${warning.file}`));
3718
+ console.log(chalk4.dim(` File: ${warning.file}`));
3673
3719
  }
3674
3720
  }
3675
3721
  console.log("");
3676
3722
  }
3677
3723
  if (result.errors && result.errors.length > 0) {
3678
- console.log(chalk5.red.bold("\nErrors:"));
3724
+ console.log(chalk4.red.bold("\nErrors:"));
3679
3725
  for (const error of result.errors) {
3680
- console.log(chalk5.red(` \u2717 ${error.message}`));
3726
+ console.log(chalk4.red(` \u2717 ${error.message}`));
3681
3727
  if (error.decisionId && error.constraintId) {
3682
- console.log(chalk5.dim(` ${error.decisionId}/${error.constraintId}`));
3728
+ console.log(chalk4.dim(` ${error.decisionId}/${error.constraintId}`));
3683
3729
  }
3684
3730
  if (error.file) {
3685
- console.log(chalk5.dim(` File: ${error.file}`));
3731
+ console.log(chalk4.dim(` File: ${error.file}`));
3686
3732
  }
3687
3733
  }
3688
3734
  console.log("");
3689
3735
  }
3690
3736
  printResult(result, level);
3691
3737
  if (options.fix && fixResult) {
3692
- console.log(chalk5.green(`\u2713 Applied ${fixResult.applied.length} fix(es)`));
3738
+ console.log(chalk4.green(`\u2713 Applied ${fixResult.applied.length} fix(es)`));
3693
3739
  if (fixResult.skipped > 0) {
3694
- console.log(chalk5.yellow(`\u2298 Skipped ${fixResult.skipped} fix(es)`));
3740
+ console.log(chalk4.yellow(`\u2298 Skipped ${fixResult.skipped} fix(es)`));
3695
3741
  }
3696
3742
  console.log("");
3697
3743
  }
@@ -3710,8 +3756,8 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3710
3756
  function printResult(result, level) {
3711
3757
  console.log("");
3712
3758
  if (result.violations.length === 0) {
3713
- console.log(chalk5.green("\u2713 All checks passed!"));
3714
- console.log(chalk5.dim(` ${result.checked} files checked in ${result.duration}ms`));
3759
+ console.log(chalk4.green("\u2713 All checks passed!"));
3760
+ console.log(chalk4.dim(` ${result.checked} files checked in ${result.duration}ms`));
3715
3761
  return;
3716
3762
  }
3717
3763
  const byFile = /* @__PURE__ */ new Map();
@@ -3721,7 +3767,7 @@ function printResult(result, level) {
3721
3767
  byFile.set(violation.file, existing);
3722
3768
  }
3723
3769
  for (const [file, violations] of byFile) {
3724
- console.log(chalk5.underline(file));
3770
+ console.log(chalk4.underline(file));
3725
3771
  for (const v of violations) {
3726
3772
  const typeIcon = getTypeIcon(v.type);
3727
3773
  const severityColor = getSeverityColor(v.severity);
@@ -3729,9 +3775,9 @@ function printResult(result, level) {
3729
3775
  console.log(
3730
3776
  ` ${typeIcon} ${severityColor(`[${v.severity}]`)} ${v.message}`
3731
3777
  );
3732
- console.log(chalk5.dim(` ${v.decisionId}/${v.constraintId}${location}`));
3778
+ console.log(chalk4.dim(` ${v.decisionId}/${v.constraintId}${location}`));
3733
3779
  if (v.suggestion) {
3734
- console.log(chalk5.cyan(` Suggestion: ${v.suggestion}`));
3780
+ console.log(chalk4.cyan(` Suggestion: ${v.suggestion}`));
3735
3781
  }
3736
3782
  }
3737
3783
  console.log("");
@@ -3740,29 +3786,29 @@ function printResult(result, level) {
3740
3786
  const highCount = result.violations.filter((v) => v.severity === "high").length;
3741
3787
  const mediumCount = result.violations.filter((v) => v.severity === "medium").length;
3742
3788
  const lowCount = result.violations.filter((v) => v.severity === "low").length;
3743
- console.log(chalk5.bold("Summary:"));
3789
+ console.log(chalk4.bold("Summary:"));
3744
3790
  console.log(` Files: ${result.checked} checked, ${result.passed} passed, ${result.failed} failed`);
3745
3791
  const violationParts = [];
3746
- if (criticalCount > 0) violationParts.push(chalk5.red(`${criticalCount} critical`));
3747
- if (highCount > 0) violationParts.push(chalk5.yellow(`${highCount} high`));
3748
- if (mediumCount > 0) violationParts.push(chalk5.cyan(`${mediumCount} medium`));
3749
- if (lowCount > 0) violationParts.push(chalk5.dim(`${lowCount} low`));
3792
+ if (criticalCount > 0) violationParts.push(chalk4.red(`${criticalCount} critical`));
3793
+ if (highCount > 0) violationParts.push(chalk4.yellow(`${highCount} high`));
3794
+ if (mediumCount > 0) violationParts.push(chalk4.cyan(`${mediumCount} medium`));
3795
+ if (lowCount > 0) violationParts.push(chalk4.dim(`${lowCount} low`));
3750
3796
  console.log(` Violations: ${violationParts.join(", ")}`);
3751
3797
  console.log(` Duration: ${result.duration}ms`);
3752
3798
  if (!result.success) {
3753
3799
  console.log("");
3754
3800
  const blockingTypes = level === "commit" ? "invariant or critical" : level === "pr" ? "invariant, critical, or high" : "invariant";
3755
- console.log(chalk5.red(`\u2717 Verification failed. ${blockingTypes} violations must be resolved.`));
3801
+ console.log(chalk4.red(`\u2717 Verification failed. ${blockingTypes} violations must be resolved.`));
3756
3802
  }
3757
3803
  }
3758
3804
  function getTypeIcon(type) {
3759
3805
  switch (type) {
3760
3806
  case "invariant":
3761
- return chalk5.red("\u25CF");
3807
+ return chalk4.red("\u25CF");
3762
3808
  case "convention":
3763
- return chalk5.yellow("\u25CF");
3809
+ return chalk4.yellow("\u25CF");
3764
3810
  case "guideline":
3765
- return chalk5.green("\u25CF");
3811
+ return chalk4.green("\u25CF");
3766
3812
  default:
3767
3813
  return "\u25CB";
3768
3814
  }
@@ -3770,15 +3816,15 @@ function getTypeIcon(type) {
3770
3816
  function getSeverityColor(severity) {
3771
3817
  switch (severity) {
3772
3818
  case "critical":
3773
- return chalk5.red;
3819
+ return chalk4.red;
3774
3820
  case "high":
3775
- return chalk5.yellow;
3821
+ return chalk4.yellow;
3776
3822
  case "medium":
3777
- return chalk5.cyan;
3823
+ return chalk4.cyan;
3778
3824
  case "low":
3779
- return chalk5.dim;
3825
+ return chalk4.dim;
3780
3826
  default:
3781
- return chalk5.white;
3827
+ return chalk4.white;
3782
3828
  }
3783
3829
  }
3784
3830
 
@@ -3787,15 +3833,15 @@ import { Command as Command8 } from "commander";
3787
3833
 
3788
3834
  // src/cli/commands/decision/list.ts
3789
3835
  import { Command as Command4 } from "commander";
3790
- import chalk6 from "chalk";
3836
+ import chalk5 from "chalk";
3791
3837
  import { table } from "table";
3792
3838
  var listDecisions = new Command4("list").description("List all architectural decisions").option("-s, --status <status>", "Filter by status (draft, active, deprecated, superseded)").option("-t, --tag <tag>", "Filter by tag").option("--json", "Output as JSON").action(async (options) => {
3793
3839
  const registry = createRegistry();
3794
3840
  const result = await registry.load();
3795
3841
  if (result.errors.length > 0) {
3796
- console.warn(chalk6.yellow("\nWarnings:"));
3842
+ console.warn(chalk5.yellow("\nWarnings:"));
3797
3843
  for (const err of result.errors) {
3798
- console.warn(chalk6.yellow(` - ${err.filePath}: ${err.error}`));
3844
+ console.warn(chalk5.yellow(` - ${err.filePath}: ${err.error}`));
3799
3845
  }
3800
3846
  console.log("");
3801
3847
  }
@@ -3808,7 +3854,7 @@ var listDecisions = new Command4("list").description("List all architectural dec
3808
3854
  }
3809
3855
  const decisions = registry.getAll(filter);
3810
3856
  if (decisions.length === 0) {
3811
- console.log(chalk6.yellow("No decisions found."));
3857
+ console.log(chalk5.yellow("No decisions found."));
3812
3858
  return;
3813
3859
  }
3814
3860
  if (options.json) {
@@ -3817,11 +3863,11 @@ var listDecisions = new Command4("list").description("List all architectural dec
3817
3863
  }
3818
3864
  const data = [
3819
3865
  [
3820
- chalk6.bold("ID"),
3821
- chalk6.bold("Title"),
3822
- chalk6.bold("Status"),
3823
- chalk6.bold("Constraints"),
3824
- chalk6.bold("Tags")
3866
+ chalk5.bold("ID"),
3867
+ chalk5.bold("Title"),
3868
+ chalk5.bold("Status"),
3869
+ chalk5.bold("Constraints"),
3870
+ chalk5.bold("Tags")
3825
3871
  ]
3826
3872
  ];
3827
3873
  for (const decision of decisions) {
@@ -3855,20 +3901,20 @@ var listDecisions = new Command4("list").description("List all architectural dec
3855
3901
  },
3856
3902
  drawHorizontalLine: (index) => index === 1
3857
3903
  }));
3858
- console.log(chalk6.dim(`Total: ${decisions.length} decision(s)`));
3904
+ console.log(chalk5.dim(`Total: ${decisions.length} decision(s)`));
3859
3905
  });
3860
3906
  function getStatusColor(status) {
3861
3907
  switch (status) {
3862
3908
  case "active":
3863
- return chalk6.green;
3909
+ return chalk5.green;
3864
3910
  case "draft":
3865
- return chalk6.yellow;
3911
+ return chalk5.yellow;
3866
3912
  case "deprecated":
3867
- return chalk6.gray;
3913
+ return chalk5.gray;
3868
3914
  case "superseded":
3869
- return chalk6.blue;
3915
+ return chalk5.blue;
3870
3916
  default:
3871
- return chalk6.white;
3917
+ return chalk5.white;
3872
3918
  }
3873
3919
  }
3874
3920
  function getConstraintTypeSummary(types) {
@@ -3881,9 +3927,9 @@ function getConstraintTypeSummary(types) {
3881
3927
  counts[type]++;
3882
3928
  }
3883
3929
  const parts = [];
3884
- if (counts.invariant > 0) parts.push(chalk6.red(`${counts.invariant}I`));
3885
- if (counts.convention > 0) parts.push(chalk6.yellow(`${counts.convention}C`));
3886
- if (counts.guideline > 0) parts.push(chalk6.green(`${counts.guideline}G`));
3930
+ if (counts.invariant > 0) parts.push(chalk5.red(`${counts.invariant}I`));
3931
+ if (counts.convention > 0) parts.push(chalk5.yellow(`${counts.convention}C`));
3932
+ if (counts.guideline > 0) parts.push(chalk5.green(`${counts.guideline}G`));
3887
3933
  return parts.join(" ") || "-";
3888
3934
  }
3889
3935
  function truncate(str, length) {
@@ -3893,7 +3939,7 @@ function truncate(str, length) {
3893
3939
 
3894
3940
  // src/cli/commands/decision/show.ts
3895
3941
  import { Command as Command5 } from "commander";
3896
- import chalk7 from "chalk";
3942
+ import chalk6 from "chalk";
3897
3943
  var showDecision = new Command5("show").description("Show details of a specific decision").argument("<id>", "Decision ID").option("--json", "Output as JSON").action(async (id, options) => {
3898
3944
  const registry = createRegistry();
3899
3945
  await registry.load();
@@ -3906,74 +3952,74 @@ var showDecision = new Command5("show").description("Show details of a specific
3906
3952
  });
3907
3953
  function printDecision(decision) {
3908
3954
  const { metadata, decision: content, constraints } = decision;
3909
- console.log(chalk7.bold.blue(`
3955
+ console.log(chalk6.bold.blue(`
3910
3956
  ${metadata.title}`));
3911
- console.log(chalk7.dim(`ID: ${metadata.id}`));
3957
+ console.log(chalk6.dim(`ID: ${metadata.id}`));
3912
3958
  console.log("");
3913
- console.log(chalk7.bold("Status:"), getStatusBadge(metadata.status));
3914
- console.log(chalk7.bold("Owners:"), metadata.owners.join(", "));
3959
+ console.log(chalk6.bold("Status:"), getStatusBadge(metadata.status));
3960
+ console.log(chalk6.bold("Owners:"), metadata.owners.join(", "));
3915
3961
  if (metadata.tags && metadata.tags.length > 0) {
3916
- console.log(chalk7.bold("Tags:"), metadata.tags.map((t) => chalk7.cyan(t)).join(", "));
3962
+ console.log(chalk6.bold("Tags:"), metadata.tags.map((t) => chalk6.cyan(t)).join(", "));
3917
3963
  }
3918
3964
  if (metadata.createdAt) {
3919
- console.log(chalk7.bold("Created:"), metadata.createdAt);
3965
+ console.log(chalk6.bold("Created:"), metadata.createdAt);
3920
3966
  }
3921
3967
  if (metadata.supersededBy) {
3922
- console.log(chalk7.bold("Superseded by:"), chalk7.yellow(metadata.supersededBy));
3968
+ console.log(chalk6.bold("Superseded by:"), chalk6.yellow(metadata.supersededBy));
3923
3969
  }
3924
3970
  console.log("");
3925
- console.log(chalk7.bold.underline("Summary"));
3971
+ console.log(chalk6.bold.underline("Summary"));
3926
3972
  console.log(content.summary);
3927
3973
  console.log("");
3928
- console.log(chalk7.bold.underline("Rationale"));
3974
+ console.log(chalk6.bold.underline("Rationale"));
3929
3975
  console.log(content.rationale);
3930
3976
  console.log("");
3931
3977
  if (content.context) {
3932
- console.log(chalk7.bold.underline("Context"));
3978
+ console.log(chalk6.bold.underline("Context"));
3933
3979
  console.log(content.context);
3934
3980
  console.log("");
3935
3981
  }
3936
3982
  if (content.consequences && content.consequences.length > 0) {
3937
- console.log(chalk7.bold.underline("Consequences"));
3983
+ console.log(chalk6.bold.underline("Consequences"));
3938
3984
  for (const consequence of content.consequences) {
3939
3985
  console.log(` \u2022 ${consequence}`);
3940
3986
  }
3941
3987
  console.log("");
3942
3988
  }
3943
- console.log(chalk7.bold.underline(`Constraints (${constraints.length})`));
3989
+ console.log(chalk6.bold.underline(`Constraints (${constraints.length})`));
3944
3990
  for (const constraint of constraints) {
3945
3991
  const typeIcon = getTypeIcon2(constraint.type);
3946
3992
  const severityBadge = getSeverityBadge(constraint.severity);
3947
3993
  console.log(`
3948
- ${typeIcon} ${chalk7.bold(constraint.id)} ${severityBadge}`);
3994
+ ${typeIcon} ${chalk6.bold(constraint.id)} ${severityBadge}`);
3949
3995
  console.log(` ${constraint.rule}`);
3950
- console.log(chalk7.dim(` Scope: ${constraint.scope}`));
3996
+ console.log(chalk6.dim(` Scope: ${constraint.scope}`));
3951
3997
  if (constraint.verifier) {
3952
- console.log(chalk7.dim(` Verifier: ${constraint.verifier}`));
3998
+ console.log(chalk6.dim(` Verifier: ${constraint.verifier}`));
3953
3999
  }
3954
4000
  if (constraint.exceptions && constraint.exceptions.length > 0) {
3955
- console.log(chalk7.dim(` Exceptions: ${constraint.exceptions.length}`));
4001
+ console.log(chalk6.dim(` Exceptions: ${constraint.exceptions.length}`));
3956
4002
  }
3957
4003
  }
3958
4004
  console.log("");
3959
4005
  if (decision.verification?.automated && decision.verification.automated.length > 0) {
3960
- console.log(chalk7.bold.underline("Automated Verification"));
4006
+ console.log(chalk6.bold.underline("Automated Verification"));
3961
4007
  for (const check of decision.verification.automated) {
3962
4008
  console.log(` \u2022 ${check.check} (${check.frequency})`);
3963
- console.log(chalk7.dim(` Target: ${check.target}`));
4009
+ console.log(chalk6.dim(` Target: ${check.target}`));
3964
4010
  }
3965
4011
  console.log("");
3966
4012
  }
3967
4013
  if (decision.links) {
3968
4014
  const { related, supersedes, references } = decision.links;
3969
4015
  if (related && related.length > 0) {
3970
- console.log(chalk7.bold("Related:"), related.join(", "));
4016
+ console.log(chalk6.bold("Related:"), related.join(", "));
3971
4017
  }
3972
4018
  if (supersedes && supersedes.length > 0) {
3973
- console.log(chalk7.bold("Supersedes:"), supersedes.join(", "));
4019
+ console.log(chalk6.bold("Supersedes:"), supersedes.join(", "));
3974
4020
  }
3975
4021
  if (references && references.length > 0) {
3976
- console.log(chalk7.bold("References:"));
4022
+ console.log(chalk6.bold("References:"));
3977
4023
  for (const ref of references) {
3978
4024
  console.log(` \u2022 ${ref}`);
3979
4025
  }
@@ -3983,13 +4029,13 @@ ${metadata.title}`));
3983
4029
  function getStatusBadge(status) {
3984
4030
  switch (status) {
3985
4031
  case "active":
3986
- return chalk7.bgGreen.black(" ACTIVE ");
4032
+ return chalk6.bgGreen.black(" ACTIVE ");
3987
4033
  case "draft":
3988
- return chalk7.bgYellow.black(" DRAFT ");
4034
+ return chalk6.bgYellow.black(" DRAFT ");
3989
4035
  case "deprecated":
3990
- return chalk7.bgGray.white(" DEPRECATED ");
4036
+ return chalk6.bgGray.white(" DEPRECATED ");
3991
4037
  case "superseded":
3992
- return chalk7.bgBlue.white(" SUPERSEDED ");
4038
+ return chalk6.bgBlue.white(" SUPERSEDED ");
3993
4039
  default:
3994
4040
  return status;
3995
4041
  }
@@ -3997,11 +4043,11 @@ function getStatusBadge(status) {
3997
4043
  function getTypeIcon2(type) {
3998
4044
  switch (type) {
3999
4045
  case "invariant":
4000
- return chalk7.red("\u25CF");
4046
+ return chalk6.red("\u25CF");
4001
4047
  case "convention":
4002
- return chalk7.yellow("\u25CF");
4048
+ return chalk6.yellow("\u25CF");
4003
4049
  case "guideline":
4004
- return chalk7.green("\u25CF");
4050
+ return chalk6.green("\u25CF");
4005
4051
  default:
4006
4052
  return "\u25CB";
4007
4053
  }
@@ -4009,13 +4055,13 @@ function getTypeIcon2(type) {
4009
4055
  function getSeverityBadge(severity) {
4010
4056
  switch (severity) {
4011
4057
  case "critical":
4012
- return chalk7.bgRed.white(" CRITICAL ");
4058
+ return chalk6.bgRed.white(" CRITICAL ");
4013
4059
  case "high":
4014
- return chalk7.bgYellow.black(" HIGH ");
4060
+ return chalk6.bgYellow.black(" HIGH ");
4015
4061
  case "medium":
4016
- return chalk7.bgCyan.black(" MEDIUM ");
4062
+ return chalk6.bgCyan.black(" MEDIUM ");
4017
4063
  case "low":
4018
- return chalk7.bgGray.white(" LOW ");
4064
+ return chalk6.bgGray.white(" LOW ");
4019
4065
  default:
4020
4066
  return severity;
4021
4067
  }
@@ -4023,7 +4069,7 @@ function getSeverityBadge(severity) {
4023
4069
 
4024
4070
  // src/cli/commands/decision/validate.ts
4025
4071
  import { Command as Command6 } from "commander";
4026
- import chalk8 from "chalk";
4072
+ import chalk7 from "chalk";
4027
4073
  import ora4 from "ora";
4028
4074
  import { join as join6 } from "path";
4029
4075
  var validateDecisions = new Command6("validate").description("Validate decision files").option("-f, --file <path>", "Validate a specific file").action(async (options) => {
@@ -4062,14 +4108,14 @@ var validateDecisions = new Command6("validate").description("Validate decision
4062
4108
  }
4063
4109
  spinner.stop();
4064
4110
  if (invalid === 0) {
4065
- console.log(chalk8.green(`\u2713 All ${valid} decision file(s) are valid.`));
4111
+ console.log(chalk7.green(`\u2713 All ${valid} decision file(s) are valid.`));
4066
4112
  } else {
4067
- console.log(chalk8.red(`\u2717 ${invalid} of ${files.length} decision file(s) have errors.
4113
+ console.log(chalk7.red(`\u2717 ${invalid} of ${files.length} decision file(s) have errors.
4068
4114
  `));
4069
4115
  for (const { file, errors: fileErrors } of errors) {
4070
- console.log(chalk8.red(`File: ${file}`));
4116
+ console.log(chalk7.red(`File: ${file}`));
4071
4117
  for (const err of fileErrors) {
4072
- console.log(chalk8.dim(` - ${err}`));
4118
+ console.log(chalk7.dim(` - ${err}`));
4073
4119
  }
4074
4120
  console.log("");
4075
4121
  }
@@ -4083,7 +4129,7 @@ var validateDecisions = new Command6("validate").description("Validate decision
4083
4129
 
4084
4130
  // src/cli/commands/decision/create.ts
4085
4131
  import { Command as Command7 } from "commander";
4086
- import chalk9 from "chalk";
4132
+ import chalk8 from "chalk";
4087
4133
  import { join as join7 } from "path";
4088
4134
  var createDecision = new Command7("create").description("Create a new decision file").argument("<id>", "Decision ID (e.g., auth-001)").requiredOption("-t, --title <title>", "Decision title").requiredOption("-s, --summary <summary>", "One-sentence summary").option("--type <type>", "Default constraint type (invariant, convention, guideline)", "convention").option("--severity <severity>", "Default constraint severity (critical, high, medium, low)", "medium").option("--scope <scope>", "Default constraint scope (glob pattern)", "src/**/*.ts").option("-o, --owner <owner>", "Owner name", "team").action(async (id, options) => {
4089
4135
  const cwd = process.cwd();
@@ -4091,13 +4137,13 @@ var createDecision = new Command7("create").description("Create a new decision f
4091
4137
  throw new NotInitializedError();
4092
4138
  }
4093
4139
  if (!/^[a-z0-9-]+$/.test(id)) {
4094
- console.error(chalk9.red("Error: Decision ID must be lowercase alphanumeric with hyphens only."));
4140
+ console.error(chalk8.red("Error: Decision ID must be lowercase alphanumeric with hyphens only."));
4095
4141
  process.exit(1);
4096
4142
  }
4097
4143
  const decisionsDir = getDecisionsDir(cwd);
4098
4144
  const filePath = join7(decisionsDir, `${id}.decision.yaml`);
4099
4145
  if (await pathExists(filePath)) {
4100
- console.error(chalk9.red(`Error: Decision file already exists: ${filePath}`));
4146
+ console.error(chalk8.red(`Error: Decision file already exists: ${filePath}`));
4101
4147
  process.exit(1);
4102
4148
  }
4103
4149
  const decision = {
@@ -4133,13 +4179,13 @@ var createDecision = new Command7("create").description("Create a new decision f
4133
4179
  }
4134
4180
  };
4135
4181
  await writeTextFile(filePath, stringifyYaml(decision));
4136
- console.log(chalk9.green(`\u2713 Created decision: ${filePath}`));
4182
+ console.log(chalk8.green(`\u2713 Created decision: ${filePath}`));
4137
4183
  console.log("");
4138
- console.log(chalk9.cyan("Next steps:"));
4184
+ console.log(chalk8.cyan("Next steps:"));
4139
4185
  console.log(` 1. Edit the file to add rationale, context, and consequences`);
4140
4186
  console.log(` 2. Define constraints with appropriate scopes`);
4141
- console.log(` 3. Run ${chalk9.bold("specbridge decision validate")} to check syntax`);
4142
- console.log(` 4. Change status from ${chalk9.yellow("draft")} to ${chalk9.green("active")} when ready`);
4187
+ console.log(` 3. Run ${chalk8.bold("specbridge decision validate")} to check syntax`);
4188
+ console.log(` 4. Change status from ${chalk8.yellow("draft")} to ${chalk8.green("active")} when ready`);
4143
4189
  });
4144
4190
 
4145
4191
  // src/cli/commands/decision/index.ts
@@ -4147,7 +4193,7 @@ var decisionCommand = new Command8("decision").description("Manage architectural
4147
4193
 
4148
4194
  // src/cli/commands/hook.ts
4149
4195
  import { Command as Command9 } from "commander";
4150
- import chalk10 from "chalk";
4196
+ import chalk9 from "chalk";
4151
4197
  import ora5 from "ora";
4152
4198
  import { join as join8 } from "path";
4153
4199
  var HOOK_SCRIPT = `#!/bin/sh
@@ -4179,9 +4225,9 @@ function createHookCommand() {
4179
4225
  } else if (options.lefthook) {
4180
4226
  spinner.succeed("Lefthook detected");
4181
4227
  console.log("");
4182
- console.log(chalk10.cyan("Add this to your lefthook.yml:"));
4228
+ console.log(chalk9.cyan("Add this to your lefthook.yml:"));
4183
4229
  console.log("");
4184
- console.log(chalk10.dim(`pre-commit:
4230
+ console.log(chalk9.dim(`pre-commit:
4185
4231
  commands:
4186
4232
  specbridge:
4187
4233
  glob: "*.{ts,tsx}"
@@ -4196,9 +4242,9 @@ function createHookCommand() {
4196
4242
  } else if (await pathExists(join8(cwd, "lefthook.yml"))) {
4197
4243
  spinner.succeed("Lefthook detected");
4198
4244
  console.log("");
4199
- console.log(chalk10.cyan("Add this to your lefthook.yml:"));
4245
+ console.log(chalk9.cyan("Add this to your lefthook.yml:"));
4200
4246
  console.log("");
4201
- console.log(chalk10.dim(`pre-commit:
4247
+ console.log(chalk9.dim(`pre-commit:
4202
4248
  commands:
4203
4249
  specbridge:
4204
4250
  glob: "*.{ts,tsx}"
@@ -4213,7 +4259,7 @@ function createHookCommand() {
4213
4259
  }
4214
4260
  if (await pathExists(hookPath) && !options.force) {
4215
4261
  spinner.fail("Hook already exists");
4216
- console.log(chalk10.yellow(`Use --force to overwrite: ${hookPath}`));
4262
+ console.log(chalk9.yellow(`Use --force to overwrite: ${hookPath}`));
4217
4263
  return;
4218
4264
  }
4219
4265
  await writeTextFile(hookPath, hookContent);
@@ -4223,9 +4269,9 @@ function createHookCommand() {
4223
4269
  } catch {
4224
4270
  }
4225
4271
  spinner.succeed("Pre-commit hook installed");
4226
- console.log(chalk10.dim(` Path: ${hookPath}`));
4272
+ console.log(chalk9.dim(` Path: ${hookPath}`));
4227
4273
  console.log("");
4228
- console.log(chalk10.cyan("The hook will run on each commit and verify staged files."));
4274
+ console.log(chalk9.cyan("The hook will run on each commit and verify staged files."));
4229
4275
  } catch (error) {
4230
4276
  spinner.fail("Failed to install hook");
4231
4277
  throw error;
@@ -4261,21 +4307,21 @@ function createHookCommand() {
4261
4307
  cwd
4262
4308
  });
4263
4309
  if (result.violations.length === 0) {
4264
- console.log(chalk10.green("\u2713 SpecBridge: All checks passed"));
4310
+ console.log(chalk9.green("\u2713 SpecBridge: All checks passed"));
4265
4311
  process.exit(0);
4266
4312
  }
4267
- console.log(chalk10.red(`\u2717 SpecBridge: ${result.violations.length} violation(s) found`));
4313
+ console.log(chalk9.red(`\u2717 SpecBridge: ${result.violations.length} violation(s) found`));
4268
4314
  console.log("");
4269
4315
  for (const v of result.violations) {
4270
4316
  const location = v.line ? `:${v.line}` : "";
4271
4317
  console.log(` ${v.file}${location}: ${v.message}`);
4272
- console.log(chalk10.dim(` [${v.severity}] ${v.decisionId}/${v.constraintId}`));
4318
+ console.log(chalk9.dim(` [${v.severity}] ${v.decisionId}/${v.constraintId}`));
4273
4319
  }
4274
4320
  console.log("");
4275
- console.log(chalk10.yellow("Run `specbridge verify` for full details."));
4321
+ console.log(chalk9.yellow("Run `specbridge verify` for full details."));
4276
4322
  process.exit(result.success ? 0 : 1);
4277
4323
  } catch (error) {
4278
- console.error(chalk10.red("SpecBridge verification failed"));
4324
+ console.error(chalk9.red("SpecBridge verification failed"));
4279
4325
  console.error(error instanceof Error ? error.message : String(error));
4280
4326
  process.exit(1);
4281
4327
  }
@@ -4314,7 +4360,7 @@ var hookCommand = createHookCommand();
4314
4360
 
4315
4361
  // src/cli/commands/report.ts
4316
4362
  import { Command as Command10 } from "commander";
4317
- import chalk12 from "chalk";
4363
+ import chalk11 from "chalk";
4318
4364
  import ora6 from "ora";
4319
4365
  import { join as join10 } from "path";
4320
4366
 
@@ -4398,54 +4444,54 @@ async function generateReport(config, options = {}) {
4398
4444
  }
4399
4445
 
4400
4446
  // src/reporting/formats/console.ts
4401
- import chalk11 from "chalk";
4447
+ import chalk10 from "chalk";
4402
4448
  import { table as table2 } from "table";
4403
4449
  function formatConsoleReport(report) {
4404
4450
  const lines = [];
4405
4451
  lines.push("");
4406
- lines.push(chalk11.bold.blue("SpecBridge Compliance Report"));
4407
- lines.push(chalk11.dim(`Generated: ${new Date(report.timestamp).toLocaleString()}`));
4408
- lines.push(chalk11.dim(`Project: ${report.project}`));
4452
+ lines.push(chalk10.bold.blue("SpecBridge Compliance Report"));
4453
+ lines.push(chalk10.dim(`Generated: ${new Date(report.timestamp).toLocaleString()}`));
4454
+ lines.push(chalk10.dim(`Project: ${report.project}`));
4409
4455
  lines.push("");
4410
4456
  const complianceColor = getComplianceColor(report.summary.compliance);
4411
- lines.push(chalk11.bold("Overall Compliance"));
4457
+ lines.push(chalk10.bold("Overall Compliance"));
4412
4458
  lines.push(` ${complianceColor(formatComplianceBar(report.summary.compliance))} ${complianceColor(`${report.summary.compliance}%`)}`);
4413
4459
  lines.push("");
4414
- lines.push(chalk11.bold("Summary"));
4460
+ lines.push(chalk10.bold("Summary"));
4415
4461
  lines.push(` Decisions: ${report.summary.activeDecisions} active / ${report.summary.totalDecisions} total`);
4416
4462
  lines.push(` Constraints: ${report.summary.totalConstraints}`);
4417
4463
  lines.push("");
4418
- lines.push(chalk11.bold("Violations"));
4464
+ lines.push(chalk10.bold("Violations"));
4419
4465
  const { violations } = report.summary;
4420
4466
  const violationParts = [];
4421
4467
  if (violations.critical > 0) {
4422
- violationParts.push(chalk11.red(`${violations.critical} critical`));
4468
+ violationParts.push(chalk10.red(`${violations.critical} critical`));
4423
4469
  }
4424
4470
  if (violations.high > 0) {
4425
- violationParts.push(chalk11.yellow(`${violations.high} high`));
4471
+ violationParts.push(chalk10.yellow(`${violations.high} high`));
4426
4472
  }
4427
4473
  if (violations.medium > 0) {
4428
- violationParts.push(chalk11.cyan(`${violations.medium} medium`));
4474
+ violationParts.push(chalk10.cyan(`${violations.medium} medium`));
4429
4475
  }
4430
4476
  if (violations.low > 0) {
4431
- violationParts.push(chalk11.dim(`${violations.low} low`));
4477
+ violationParts.push(chalk10.dim(`${violations.low} low`));
4432
4478
  }
4433
4479
  if (violationParts.length > 0) {
4434
4480
  lines.push(` ${violationParts.join(" | ")}`);
4435
4481
  } else {
4436
- lines.push(chalk11.green(" No violations"));
4482
+ lines.push(chalk10.green(" No violations"));
4437
4483
  }
4438
4484
  lines.push("");
4439
4485
  if (report.byDecision.length > 0) {
4440
- lines.push(chalk11.bold("By Decision"));
4486
+ lines.push(chalk10.bold("By Decision"));
4441
4487
  lines.push("");
4442
4488
  const tableData = [
4443
4489
  [
4444
- chalk11.bold("Decision"),
4445
- chalk11.bold("Status"),
4446
- chalk11.bold("Constraints"),
4447
- chalk11.bold("Violations"),
4448
- chalk11.bold("Compliance")
4490
+ chalk10.bold("Decision"),
4491
+ chalk10.bold("Status"),
4492
+ chalk10.bold("Constraints"),
4493
+ chalk10.bold("Violations"),
4494
+ chalk10.bold("Compliance")
4449
4495
  ]
4450
4496
  ];
4451
4497
  for (const dec of report.byDecision) {
@@ -4455,7 +4501,7 @@ function formatConsoleReport(report) {
4455
4501
  truncate2(dec.title, 40),
4456
4502
  statusColor(dec.status),
4457
4503
  String(dec.constraints),
4458
- dec.violations > 0 ? chalk11.red(String(dec.violations)) : chalk11.green("0"),
4504
+ dec.violations > 0 ? chalk10.red(String(dec.violations)) : chalk10.green("0"),
4459
4505
  compColor(`${dec.compliance}%`)
4460
4506
  ]);
4461
4507
  }
@@ -4489,23 +4535,23 @@ function formatComplianceBar(compliance) {
4489
4535
  return "\u2588".repeat(filled) + "\u2591".repeat(empty);
4490
4536
  }
4491
4537
  function getComplianceColor(compliance) {
4492
- if (compliance >= 90) return chalk11.green;
4493
- if (compliance >= 70) return chalk11.yellow;
4494
- if (compliance >= 50) return chalk11.hex("#FFA500");
4495
- return chalk11.red;
4538
+ if (compliance >= 90) return chalk10.green;
4539
+ if (compliance >= 70) return chalk10.yellow;
4540
+ if (compliance >= 50) return chalk10.hex("#FFA500");
4541
+ return chalk10.red;
4496
4542
  }
4497
4543
  function getStatusColor2(status) {
4498
4544
  switch (status) {
4499
4545
  case "active":
4500
- return chalk11.green;
4546
+ return chalk10.green;
4501
4547
  case "draft":
4502
- return chalk11.yellow;
4548
+ return chalk10.yellow;
4503
4549
  case "deprecated":
4504
- return chalk11.gray;
4550
+ return chalk10.gray;
4505
4551
  case "superseded":
4506
- return chalk11.blue;
4552
+ return chalk10.blue;
4507
4553
  default:
4508
- return chalk11.white;
4554
+ return chalk10.white;
4509
4555
  }
4510
4556
  }
4511
4557
  function truncate2(str, length) {
@@ -4579,6 +4625,7 @@ function formatProgressBar(percentage) {
4579
4625
  import { join as join9 } from "path";
4580
4626
  var ReportStorage = class {
4581
4627
  storageDir;
4628
+ logger = getLogger({ module: "reporting.storage" });
4582
4629
  constructor(basePath) {
4583
4630
  this.storageDir = join9(getSpecBridgeDir(basePath), "reports", "history");
4584
4631
  }
@@ -4637,7 +4684,7 @@ var ReportStorage = class {
4637
4684
  const timestamp = file.replace("report-", "").replace(".json", "");
4638
4685
  return { timestamp, report };
4639
4686
  } catch (error) {
4640
- console.warn(`Warning: Failed to load report ${file}:`, error);
4687
+ this.logger.warn({ file, error }, "Failed to load report file");
4641
4688
  return null;
4642
4689
  }
4643
4690
  });
@@ -4681,7 +4728,7 @@ var ReportStorage = class {
4681
4728
  const fs = await import("fs/promises");
4682
4729
  await fs.unlink(filepath);
4683
4730
  } catch (error) {
4684
- console.warn(`Warning: Failed to delete old report ${file}:`, error);
4731
+ this.logger.warn({ file, error }, "Failed to delete old report file");
4685
4732
  }
4686
4733
  }
4687
4734
  return filesToDelete.length;
@@ -4805,7 +4852,10 @@ async function analyzeTrend(reports) {
4805
4852
  if (!decisionMap.has(decision.decisionId)) {
4806
4853
  decisionMap.set(decision.decisionId, []);
4807
4854
  }
4808
- decisionMap.get(decision.decisionId).push(decision);
4855
+ const decisionHistory = decisionMap.get(decision.decisionId);
4856
+ if (decisionHistory) {
4857
+ decisionHistory.push(decision);
4858
+ }
4809
4859
  }
4810
4860
  }
4811
4861
  const decisions = Array.from(decisionMap.entries()).map(([decisionId, data]) => {
@@ -4880,29 +4930,29 @@ var reportCommand = new Command10("report").description("Generate compliance rep
4880
4930
  const storage = new ReportStorage(cwd);
4881
4931
  await storage.save(report);
4882
4932
  if (options.trend) {
4883
- console.log("\n" + chalk12.blue.bold("=== Compliance Trend Analysis ===\n"));
4933
+ console.log("\n" + chalk11.blue.bold("=== Compliance Trend Analysis ===\n"));
4884
4934
  const days = parseInt(options.days || "30", 10);
4885
4935
  const history = await storage.loadHistory(days);
4886
4936
  if (history.length < 2) {
4887
- console.log(chalk12.yellow(`Not enough data for trend analysis. Found ${history.length} report(s), need at least 2.`));
4937
+ console.log(chalk11.yellow(`Not enough data for trend analysis. Found ${history.length} report(s), need at least 2.`));
4888
4938
  } else {
4889
4939
  const trend = await analyzeTrend(history);
4890
- console.log(chalk12.bold(`Period: ${trend.period.start} to ${trend.period.end} (${trend.period.days} days)`));
4940
+ console.log(chalk11.bold(`Period: ${trend.period.start} to ${trend.period.end} (${trend.period.days} days)`));
4891
4941
  console.log(`
4892
4942
  Overall Compliance: ${trend.overall.startCompliance}% \u2192 ${trend.overall.endCompliance}% (${trend.overall.change > 0 ? "+" : ""}${trend.overall.change.toFixed(1)}%)`);
4893
4943
  const trendEmoji = trend.overall.trend === "improving" ? "\u{1F4C8}" : trend.overall.trend === "degrading" ? "\u{1F4C9}" : "\u27A1\uFE0F";
4894
- const trendColor = trend.overall.trend === "improving" ? chalk12.green : trend.overall.trend === "degrading" ? chalk12.red : chalk12.yellow;
4944
+ const trendColor = trend.overall.trend === "improving" ? chalk11.green : trend.overall.trend === "degrading" ? chalk11.red : chalk11.yellow;
4895
4945
  console.log(trendColor(`${trendEmoji} Trend: ${trend.overall.trend.toUpperCase()}`));
4896
4946
  const degrading = trend.decisions.filter((d) => d.trend === "degrading").slice(0, 3);
4897
4947
  if (degrading.length > 0) {
4898
- console.log(chalk12.red("\n\u26A0\uFE0F Most Degraded Decisions:"));
4948
+ console.log(chalk11.red("\n\u26A0\uFE0F Most Degraded Decisions:"));
4899
4949
  degrading.forEach((d) => {
4900
4950
  console.log(` \u2022 ${d.title}: ${d.startCompliance}% \u2192 ${d.endCompliance}% (${d.change.toFixed(1)}%)`);
4901
4951
  });
4902
4952
  }
4903
4953
  const improving = trend.decisions.filter((d) => d.trend === "improving").slice(0, 3);
4904
4954
  if (improving.length > 0) {
4905
- console.log(chalk12.green("\n\u2705 Most Improved Decisions:"));
4955
+ console.log(chalk11.green("\n\u2705 Most Improved Decisions:"));
4906
4956
  improving.forEach((d) => {
4907
4957
  console.log(` \u2022 ${d.title}: ${d.startCompliance}% \u2192 ${d.endCompliance}% (+${d.change.toFixed(1)}%)`);
4908
4958
  });
@@ -4911,26 +4961,26 @@ Overall Compliance: ${trend.overall.startCompliance}% \u2192 ${trend.overall.end
4911
4961
  console.log("");
4912
4962
  }
4913
4963
  if (options.drift) {
4914
- console.log("\n" + chalk12.blue.bold("=== Drift Analysis ===\n"));
4964
+ console.log("\n" + chalk11.blue.bold("=== Drift Analysis ===\n"));
4915
4965
  const history = await storage.loadHistory(2);
4916
4966
  if (history.length < 2) {
4917
- console.log(chalk12.yellow("Not enough data for drift analysis. Need at least 2 reports."));
4967
+ console.log(chalk11.yellow("Not enough data for drift analysis. Need at least 2 reports."));
4918
4968
  } else {
4919
4969
  const currentEntry = history[0];
4920
4970
  const previousEntry = history[1];
4921
4971
  if (!currentEntry || !previousEntry) {
4922
- console.log(chalk12.yellow("Invalid history data."));
4972
+ console.log(chalk11.yellow("Invalid history data."));
4923
4973
  return;
4924
4974
  }
4925
4975
  const drift = await detectDrift(currentEntry.report, previousEntry.report);
4926
- console.log(chalk12.bold(`Comparing: ${previousEntry.timestamp} vs ${currentEntry.timestamp}`));
4976
+ console.log(chalk11.bold(`Comparing: ${previousEntry.timestamp} vs ${currentEntry.timestamp}`));
4927
4977
  console.log(`
4928
4978
  Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceChange.toFixed(1)}%`);
4929
4979
  const driftEmoji = drift.trend === "improving" ? "\u{1F4C8}" : drift.trend === "degrading" ? "\u{1F4C9}" : "\u27A1\uFE0F";
4930
- const driftColor = drift.trend === "improving" ? chalk12.green : drift.trend === "degrading" ? chalk12.red : chalk12.yellow;
4980
+ const driftColor = drift.trend === "improving" ? chalk11.green : drift.trend === "degrading" ? chalk11.red : chalk11.yellow;
4931
4981
  console.log(driftColor(`${driftEmoji} Overall Trend: ${drift.trend.toUpperCase()}`));
4932
4982
  if (drift.summary.newViolations.total > 0) {
4933
- console.log(chalk12.red(`
4983
+ console.log(chalk11.red(`
4934
4984
  \u26A0\uFE0F New Violations: ${drift.summary.newViolations.total}`));
4935
4985
  if (drift.summary.newViolations.critical > 0) {
4936
4986
  console.log(` \u2022 Critical: ${drift.summary.newViolations.critical}`);
@@ -4946,7 +4996,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4946
4996
  }
4947
4997
  }
4948
4998
  if (drift.summary.fixedViolations.total > 0) {
4949
- console.log(chalk12.green(`
4999
+ console.log(chalk11.green(`
4950
5000
  \u2705 Fixed Violations: ${drift.summary.fixedViolations.total}`));
4951
5001
  if (drift.summary.fixedViolations.critical > 0) {
4952
5002
  console.log(` \u2022 Critical: ${drift.summary.fixedViolations.critical}`);
@@ -4962,7 +5012,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4962
5012
  }
4963
5013
  }
4964
5014
  if (drift.mostDegraded.length > 0) {
4965
- console.log(chalk12.red("\n\u{1F4C9} Most Degraded:"));
5015
+ console.log(chalk11.red("\n\u{1F4C9} Most Degraded:"));
4966
5016
  drift.mostDegraded.forEach((d) => {
4967
5017
  console.log(` \u2022 ${d.title}: ${d.previousCompliance}% \u2192 ${d.currentCompliance}% (${d.complianceChange.toFixed(1)}%)`);
4968
5018
  if (d.newViolations > 0) {
@@ -4971,7 +5021,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4971
5021
  });
4972
5022
  }
4973
5023
  if (drift.mostImproved.length > 0) {
4974
- console.log(chalk12.green("\n\u{1F4C8} Most Improved:"));
5024
+ console.log(chalk11.green("\n\u{1F4C8} Most Improved:"));
4975
5025
  drift.mostImproved.forEach((d) => {
4976
5026
  console.log(` \u2022 ${d.title}: ${d.previousCompliance}% \u2192 ${d.currentCompliance}% (+${d.complianceChange.toFixed(1)}%)`);
4977
5027
  if (d.fixedViolations > 0) {
@@ -5011,7 +5061,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
5011
5061
  `health-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${extension}`
5012
5062
  );
5013
5063
  await writeTextFile(outputPath, output);
5014
- console.log(chalk12.green(`
5064
+ console.log(chalk11.green(`
5015
5065
  Report saved to: ${outputPath}`));
5016
5066
  if (options.save && !options.output) {
5017
5067
  const latestPath = join10(getReportsDir(cwd), `health-latest.${extension}`);
@@ -5026,7 +5076,7 @@ Report saved to: ${outputPath}`));
5026
5076
 
5027
5077
  // src/cli/commands/context.ts
5028
5078
  import { Command as Command11 } from "commander";
5029
- import chalk13 from "chalk";
5079
+ import chalk12 from "chalk";
5030
5080
 
5031
5081
  // src/agent/context.generator.ts
5032
5082
  async function generateContext(filePath, config, options = {}) {
@@ -5146,12 +5196,12 @@ var contextCommand = new Command11("context").description("Generate architectura
5146
5196
  });
5147
5197
  if (options.output) {
5148
5198
  await writeTextFile(options.output, output);
5149
- console.log(chalk13.green(`Context saved to: ${options.output}`));
5199
+ console.log(chalk12.green(`Context saved to: ${options.output}`));
5150
5200
  } else {
5151
5201
  console.log(output);
5152
5202
  }
5153
5203
  } catch (error) {
5154
- console.error(chalk13.red("Failed to generate context"));
5204
+ console.error(chalk12.red("Failed to generate context"));
5155
5205
  throw error;
5156
5206
  }
5157
5207
  });
@@ -5165,7 +5215,7 @@ import { TextDocument } from "vscode-languageserver-textdocument";
5165
5215
  import { fileURLToPath } from "url";
5166
5216
  import path3 from "path";
5167
5217
  import { Project as Project3 } from "ts-morph";
5168
- import chalk14 from "chalk";
5218
+ import chalk13 from "chalk";
5169
5219
  function severityToDiagnostic(severity) {
5170
5220
  switch (severity) {
5171
5221
  case "critical":
@@ -5247,7 +5297,11 @@ var SpecBridgeLspServer = class {
5247
5297
  const doc = this.documents.get(params.textDocument.uri);
5248
5298
  if (!doc) return [];
5249
5299
  return violations.filter((v) => v.autofix && v.autofix.edits.length > 0).map((v) => {
5250
- const edits = v.autofix.edits.map((edit) => ({
5300
+ const autofix = v.autofix;
5301
+ if (!autofix) {
5302
+ return null;
5303
+ }
5304
+ const edits = autofix.edits.map((edit) => ({
5251
5305
  range: {
5252
5306
  start: doc.positionAt(edit.start),
5253
5307
  end: doc.positionAt(edit.end)
@@ -5255,7 +5309,7 @@ var SpecBridgeLspServer = class {
5255
5309
  newText: edit.text
5256
5310
  }));
5257
5311
  return {
5258
- title: v.autofix.description,
5312
+ title: autofix.description,
5259
5313
  kind: CodeActionKind.QuickFix,
5260
5314
  edit: {
5261
5315
  changes: {
@@ -5263,7 +5317,7 @@ var SpecBridgeLspServer = class {
5263
5317
  }
5264
5318
  }
5265
5319
  };
5266
- });
5320
+ }).filter((action) => action !== null);
5267
5321
  });
5268
5322
  this.documents.listen(this.connection);
5269
5323
  this.connection.listen();
@@ -5272,7 +5326,7 @@ var SpecBridgeLspServer = class {
5272
5326
  if (!await pathExists(getSpecBridgeDir(this.cwd))) {
5273
5327
  const err = new NotInitializedError();
5274
5328
  this.initError = err.message;
5275
- if (this.options.verbose) this.connection.console.error(chalk14.red(this.initError));
5329
+ if (this.options.verbose) this.connection.console.error(chalk13.red(this.initError));
5276
5330
  return;
5277
5331
  }
5278
5332
  try {
@@ -5281,7 +5335,7 @@ var SpecBridgeLspServer = class {
5281
5335
  await getPluginLoader().loadPlugins(this.cwd);
5282
5336
  } catch (error) {
5283
5337
  const msg = error instanceof Error ? error.message : String(error);
5284
- if (this.options.verbose) this.connection.console.error(chalk14.red(`Plugin load failed: ${msg}`));
5338
+ if (this.options.verbose) this.connection.console.error(chalk13.red(`Plugin load failed: ${msg}`));
5285
5339
  }
5286
5340
  this.registry = createRegistry({ basePath: this.cwd });
5287
5341
  await this.registry.load();
@@ -5294,11 +5348,11 @@ var SpecBridgeLspServer = class {
5294
5348
  }
5295
5349
  }
5296
5350
  if (this.options.verbose) {
5297
- this.connection.console.log(chalk14.dim(`Loaded ${this.decisions.length} active decision(s)`));
5351
+ this.connection.console.log(chalk13.dim(`Loaded ${this.decisions.length} active decision(s)`));
5298
5352
  }
5299
5353
  } catch (error) {
5300
5354
  this.initError = error instanceof Error ? error.message : String(error);
5301
- if (this.options.verbose) this.connection.console.error(chalk14.red(this.initError));
5355
+ if (this.options.verbose) this.connection.console.error(chalk13.red(this.initError));
5302
5356
  }
5303
5357
  }
5304
5358
  async verifyTextDocument(doc) {
@@ -5370,7 +5424,7 @@ var lspCommand = new Command12("lsp").description("Start SpecBridge language ser
5370
5424
 
5371
5425
  // src/cli/commands/watch.ts
5372
5426
  import { Command as Command13 } from "commander";
5373
- import chalk15 from "chalk";
5427
+ import chalk14 from "chalk";
5374
5428
  import chokidar from "chokidar";
5375
5429
  import path4 from "path";
5376
5430
  var watchCommand = new Command13("watch").description("Watch for changes and verify files continuously").option("-l, --level <level>", "Verification level (commit, pr, full)", "full").option("--debounce <ms>", "Debounce verify on rapid changes", "150").action(async (options) => {
@@ -5391,15 +5445,15 @@ var watchCommand = new Command13("watch").description("Watch for changes and ver
5391
5445
  files: [absolutePath],
5392
5446
  cwd
5393
5447
  });
5394
- const prefix = result.success ? chalk15.green("\u2713") : chalk15.red("\u2717");
5448
+ const prefix = result.success ? chalk14.green("\u2713") : chalk14.red("\u2717");
5395
5449
  const summary = `${prefix} ${path4.relative(cwd, absolutePath)}: ${result.violations.length} violation(s)`;
5396
5450
  console.log(summary);
5397
5451
  for (const v of result.violations.slice(0, 20)) {
5398
5452
  const loc = v.line ? `:${v.line}${v.column ? `:${v.column}` : ""}` : "";
5399
- console.log(chalk15.dim(` - ${v.file}${loc}: ${v.message} [${v.severity}]`));
5453
+ console.log(chalk14.dim(` - ${v.file}${loc}: ${v.message} [${v.severity}]`));
5400
5454
  }
5401
5455
  if (result.violations.length > 20) {
5402
- console.log(chalk15.dim(` \u2026 ${result.violations.length - 20} more`));
5456
+ console.log(chalk14.dim(` \u2026 ${result.violations.length - 20} more`));
5403
5457
  }
5404
5458
  };
5405
5459
  const watcher = chokidar.watch(config.project.sourceRoots, {
@@ -5408,7 +5462,7 @@ var watchCommand = new Command13("watch").description("Watch for changes and ver
5408
5462
  ignoreInitial: true,
5409
5463
  persistent: true
5410
5464
  });
5411
- console.log(chalk15.blue("Watching for changes..."));
5465
+ console.log(chalk14.blue("Watching for changes..."));
5412
5466
  watcher.on("change", (changedPath) => {
5413
5467
  pendingPath = changedPath;
5414
5468
  if (timer) clearTimeout(timer);
@@ -5700,7 +5754,7 @@ var promptCommand = new Command15("prompt").description("Generate AI agent promp
5700
5754
 
5701
5755
  // src/cli/commands/analytics.ts
5702
5756
  import { Command as Command16 } from "commander";
5703
- import chalk16 from "chalk";
5757
+ import chalk15 from "chalk";
5704
5758
  import ora7 from "ora";
5705
5759
 
5706
5760
  // src/analytics/engine.ts
@@ -5929,7 +5983,7 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5929
5983
  const history = await storage.loadHistory(days);
5930
5984
  if (history.length === 0) {
5931
5985
  spinner.fail("No historical reports found");
5932
- console.log(chalk16.yellow("\nGenerate reports with: specbridge report"));
5986
+ console.log(chalk15.yellow("\nGenerate reports with: specbridge report"));
5933
5987
  return;
5934
5988
  }
5935
5989
  spinner.succeed(`Loaded ${history.length} historical report(s)`);
@@ -5946,17 +6000,17 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5946
6000
  }
5947
6001
  if (decisionId) {
5948
6002
  const metrics = await engine.analyzeDecision(decisionId, history);
5949
- console.log("\n" + chalk16.blue.bold(`=== Decision Analytics: ${metrics.title} ===
6003
+ console.log("\n" + chalk15.blue.bold(`=== Decision Analytics: ${metrics.title} ===
5950
6004
  `));
5951
- console.log(chalk16.bold("Overview:"));
6005
+ console.log(chalk15.bold("Overview:"));
5952
6006
  console.log(` ID: ${metrics.decisionId}`);
5953
6007
  console.log(` Current Violations: ${metrics.totalViolations}`);
5954
6008
  console.log(` Average Compliance: ${metrics.averageComplianceScore.toFixed(1)}%`);
5955
6009
  const trendEmoji = metrics.trendDirection === "up" ? "\u{1F4C8}" : metrics.trendDirection === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
5956
- const trendColor = metrics.trendDirection === "up" ? chalk16.green : metrics.trendDirection === "down" ? chalk16.red : chalk16.yellow;
6010
+ const trendColor = metrics.trendDirection === "up" ? chalk15.green : metrics.trendDirection === "down" ? chalk15.red : chalk15.yellow;
5957
6011
  console.log(` ${trendColor(`${trendEmoji} Trend: ${metrics.trendDirection.toUpperCase()}`)}`);
5958
6012
  if (metrics.history.length > 0) {
5959
- console.log(chalk16.bold("\nCompliance History:"));
6013
+ console.log(chalk15.bold("\nCompliance History:"));
5960
6014
  const recentHistory = metrics.history.slice(-10);
5961
6015
  recentHistory.forEach((h) => {
5962
6016
  const icon = h.violations === 0 ? "\u2705" : "\u26A0\uFE0F";
@@ -5965,58 +6019,58 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5965
6019
  }
5966
6020
  } else {
5967
6021
  const summary = await engine.generateSummary(history);
5968
- console.log("\n" + chalk16.blue.bold("=== Overall Analytics ===\n"));
5969
- console.log(chalk16.bold("Summary:"));
6022
+ console.log("\n" + chalk15.blue.bold("=== Overall Analytics ===\n"));
6023
+ console.log(chalk15.bold("Summary:"));
5970
6024
  console.log(` Total Decisions: ${summary.totalDecisions}`);
5971
6025
  console.log(` Average Compliance: ${summary.averageCompliance}%`);
5972
6026
  console.log(` Critical Issues: ${summary.criticalIssues}`);
5973
6027
  const trendEmoji = summary.overallTrend === "up" ? "\u{1F4C8}" : summary.overallTrend === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
5974
- const trendColor = summary.overallTrend === "up" ? chalk16.green : summary.overallTrend === "down" ? chalk16.red : chalk16.yellow;
6028
+ const trendColor = summary.overallTrend === "up" ? chalk15.green : summary.overallTrend === "down" ? chalk15.red : chalk15.yellow;
5975
6029
  console.log(` ${trendColor(`${trendEmoji} Overall Trend: ${summary.overallTrend.toUpperCase()}`)}`);
5976
6030
  if (summary.topDecisions.length > 0) {
5977
- console.log(chalk16.green("\n\u2705 Top Performing Decisions:"));
6031
+ console.log(chalk15.green("\n\u2705 Top Performing Decisions:"));
5978
6032
  summary.topDecisions.forEach((d, i) => {
5979
6033
  console.log(` ${i + 1}. ${d.title}: ${d.compliance}%`);
5980
6034
  });
5981
6035
  }
5982
6036
  if (summary.bottomDecisions.length > 0) {
5983
- console.log(chalk16.red("\n\u26A0\uFE0F Decisions Needing Attention:"));
6037
+ console.log(chalk15.red("\n\u26A0\uFE0F Decisions Needing Attention:"));
5984
6038
  summary.bottomDecisions.forEach((d, i) => {
5985
6039
  console.log(` ${i + 1}. ${d.title}: ${d.compliance}%`);
5986
6040
  });
5987
6041
  }
5988
6042
  if (options.insights || summary.criticalIssues > 0) {
5989
- console.log(chalk16.blue.bold("\n=== Insights ===\n"));
6043
+ console.log(chalk15.blue.bold("\n=== Insights ===\n"));
5990
6044
  const insights = summary.insights;
5991
6045
  const warnings = insights.filter((i) => i.type === "warning");
5992
6046
  const successes = insights.filter((i) => i.type === "success");
5993
6047
  const infos = insights.filter((i) => i.type === "info");
5994
6048
  if (warnings.length > 0) {
5995
- console.log(chalk16.red("\u26A0\uFE0F Warnings:"));
6049
+ console.log(chalk15.red("\u26A0\uFE0F Warnings:"));
5996
6050
  warnings.forEach((i) => {
5997
6051
  console.log(` \u2022 ${i.message}`);
5998
6052
  if (i.details) {
5999
- console.log(chalk16.gray(` ${i.details}`));
6053
+ console.log(chalk15.gray(` ${i.details}`));
6000
6054
  }
6001
6055
  });
6002
6056
  console.log("");
6003
6057
  }
6004
6058
  if (successes.length > 0) {
6005
- console.log(chalk16.green("\u2705 Positive Trends:"));
6059
+ console.log(chalk15.green("\u2705 Positive Trends:"));
6006
6060
  successes.forEach((i) => {
6007
6061
  console.log(` \u2022 ${i.message}`);
6008
6062
  if (i.details) {
6009
- console.log(chalk16.gray(` ${i.details}`));
6063
+ console.log(chalk15.gray(` ${i.details}`));
6010
6064
  }
6011
6065
  });
6012
6066
  console.log("");
6013
6067
  }
6014
6068
  if (infos.length > 0) {
6015
- console.log(chalk16.blue("\u{1F4A1} Suggestions:"));
6069
+ console.log(chalk15.blue("\u{1F4A1} Suggestions:"));
6016
6070
  infos.forEach((i) => {
6017
6071
  console.log(` \u2022 ${i.message}`);
6018
6072
  if (i.details) {
6019
- console.log(chalk16.gray(` ${i.details}`));
6073
+ console.log(chalk15.gray(` ${i.details}`));
6020
6074
  }
6021
6075
  });
6022
6076
  console.log("");
@@ -6026,10 +6080,10 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
6026
6080
  const latestEntry = history[history.length - 1];
6027
6081
  const oldestEntry = history[0];
6028
6082
  if (latestEntry && oldestEntry) {
6029
- console.log(chalk16.gray(`
6083
+ console.log(chalk15.gray(`
6030
6084
  Data range: ${latestEntry.timestamp} to ${oldestEntry.timestamp}`));
6031
6085
  }
6032
- console.log(chalk16.gray(`Analyzing ${history.length} report(s) over ${days} days
6086
+ console.log(chalk15.gray(`Analyzing ${history.length} report(s) over ${days} days
6033
6087
  `));
6034
6088
  } catch (error) {
6035
6089
  spinner.fail("Analytics failed");
@@ -6039,7 +6093,7 @@ Data range: ${latestEntry.timestamp} to ${oldestEntry.timestamp}`));
6039
6093
 
6040
6094
  // src/cli/commands/dashboard.ts
6041
6095
  import { Command as Command17 } from "commander";
6042
- import chalk17 from "chalk";
6096
+ import chalk16 from "chalk";
6043
6097
 
6044
6098
  // src/dashboard/server.ts
6045
6099
  import express from "express";
@@ -6058,6 +6112,7 @@ var DashboardServer = class {
6058
6112
  CACHE_TTL = 6e4;
6059
6113
  // 1 minute
6060
6114
  refreshInterval = null;
6115
+ logger = getLogger({ module: "dashboard.server" });
6061
6116
  constructor(options) {
6062
6117
  this.cwd = options.cwd;
6063
6118
  this.config = options.config;
@@ -6074,7 +6129,11 @@ var DashboardServer = class {
6074
6129
  await this.registry.load();
6075
6130
  await this.refreshCache();
6076
6131
  this.refreshInterval = setInterval(
6077
- () => this.refreshCache().catch(console.error),
6132
+ () => {
6133
+ void this.refreshCache().catch((error) => {
6134
+ this.logger.error({ error }, "Background cache refresh failed");
6135
+ });
6136
+ },
6078
6137
  this.CACHE_TTL
6079
6138
  );
6080
6139
  }
@@ -6097,7 +6156,7 @@ var DashboardServer = class {
6097
6156
  this.cacheTimestamp = Date.now();
6098
6157
  await this.reportStorage.save(report);
6099
6158
  } catch (error) {
6100
- console.error("Cache refresh failed:", error);
6159
+ this.logger.error({ error }, "Cache refresh failed");
6101
6160
  if (!this.cachedReport) {
6102
6161
  try {
6103
6162
  const stored = await this.reportStorage.loadLatest();
@@ -6105,7 +6164,7 @@ var DashboardServer = class {
6105
6164
  this.cachedReport = stored.report;
6106
6165
  }
6107
6166
  } catch (fallbackError) {
6108
- console.error("Failed to load fallback report:", fallbackError);
6167
+ this.logger.error({ error: fallbackError }, "Failed to load fallback report");
6109
6168
  }
6110
6169
  }
6111
6170
  }
@@ -6178,7 +6237,8 @@ var DashboardServer = class {
6178
6237
  });
6179
6238
  this.app.get("/api/report/:date", async (req, res) => {
6180
6239
  try {
6181
- const date = req.params.date;
6240
+ const dateParam = req.params.date;
6241
+ const date = Array.isArray(dateParam) ? dateParam[0] : dateParam;
6182
6242
  if (!date) {
6183
6243
  res.status(400).json({ error: "Date parameter required" });
6184
6244
  return;
@@ -6214,7 +6274,8 @@ var DashboardServer = class {
6214
6274
  });
6215
6275
  this.app.get("/api/decisions/:id", async (req, res) => {
6216
6276
  try {
6217
- const id = req.params.id;
6277
+ const idParam = req.params.id;
6278
+ const id = Array.isArray(idParam) ? idParam[0] : idParam;
6218
6279
  if (!id) {
6219
6280
  res.status(400).json({ error: "Decision ID required" });
6220
6281
  return;
@@ -6226,6 +6287,10 @@ var DashboardServer = class {
6226
6287
  }
6227
6288
  res.json(decision);
6228
6289
  } catch (error) {
6290
+ if (error instanceof DecisionNotFoundError) {
6291
+ res.status(404).json({ error: "Decision not found" });
6292
+ return;
6293
+ }
6229
6294
  res.status(500).json({
6230
6295
  error: "Failed to load decision",
6231
6296
  message: error instanceof Error ? error.message : "Unknown error"
@@ -6257,7 +6322,8 @@ var DashboardServer = class {
6257
6322
  });
6258
6323
  this.app.get("/api/analytics/decision/:id", async (req, res) => {
6259
6324
  try {
6260
- const id = req.params.id;
6325
+ const idParam = req.params.id;
6326
+ const id = Array.isArray(idParam) ? idParam[0] : idParam;
6261
6327
  if (!id) {
6262
6328
  res.status(400).json({ error: "Decision ID required" });
6263
6329
  return;
@@ -6346,7 +6412,7 @@ var DashboardServer = class {
6346
6412
  // Cache static assets
6347
6413
  etag: true
6348
6414
  }));
6349
- this.app.get("*", (_req, res) => {
6415
+ this.app.get("/{*path}", (_req, res) => {
6350
6416
  res.sendFile(join12(publicDir, "index.html"));
6351
6417
  });
6352
6418
  }
@@ -6361,7 +6427,7 @@ var dashboardCommand = new Command17("dashboard").description("Start compliance
6361
6427
  if (!await pathExists(getSpecBridgeDir(cwd))) {
6362
6428
  throw new NotInitializedError();
6363
6429
  }
6364
- console.log(chalk17.blue("Starting SpecBridge dashboard..."));
6430
+ console.log(chalk16.blue("Starting SpecBridge dashboard..."));
6365
6431
  try {
6366
6432
  const config = await loadConfig(cwd);
6367
6433
  const server = createDashboardServer({ cwd, config });
@@ -6369,36 +6435,37 @@ var dashboardCommand = new Command17("dashboard").description("Start compliance
6369
6435
  const port = parseInt(options.port || "3000", 10);
6370
6436
  const host = options.host || "localhost";
6371
6437
  server.getApp().listen(port, host, () => {
6372
- console.log(chalk17.green(`
6438
+ console.log(chalk16.green(`
6373
6439
  \u2713 Dashboard running at http://${host}:${port}`));
6374
- console.log(chalk17.gray(" Press Ctrl+C to stop\n"));
6375
- console.log(chalk17.bold("API Endpoints:"));
6376
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/health`)} - Health check`);
6377
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/report/latest`)} - Latest report (cached)`);
6378
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/decisions`)} - All decisions`);
6379
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/analytics/summary`)} - Analytics`);
6440
+ console.log(chalk16.gray(" Press Ctrl+C to stop\n"));
6441
+ console.log(chalk16.bold("API Endpoints:"));
6442
+ console.log(` ${chalk16.cyan(`http://${host}:${port}/api/health`)} - Health check`);
6443
+ console.log(` ${chalk16.cyan(`http://${host}:${port}/api/report/latest`)} - Latest report (cached)`);
6444
+ console.log(` ${chalk16.cyan(`http://${host}:${port}/api/decisions`)} - All decisions`);
6445
+ console.log(` ${chalk16.cyan(`http://${host}:${port}/api/analytics/summary`)} - Analytics`);
6380
6446
  console.log("");
6381
6447
  });
6382
6448
  const shutdown = () => {
6383
- console.log(chalk17.yellow("\n\nShutting down dashboard..."));
6449
+ console.log(chalk16.yellow("\n\nShutting down dashboard..."));
6384
6450
  server.stop();
6385
6451
  process.exit(0);
6386
6452
  };
6387
6453
  process.on("SIGINT", shutdown);
6388
6454
  process.on("SIGTERM", shutdown);
6389
6455
  } catch (error) {
6390
- console.error(chalk17.red("Failed to start dashboard:"), error);
6456
+ console.error(chalk16.red("Failed to start dashboard:"), error);
6391
6457
  throw error;
6392
6458
  }
6393
6459
  });
6394
6460
 
6395
6461
  // src/cli/commands/impact.ts
6396
6462
  import { Command as Command18 } from "commander";
6397
- import chalk18 from "chalk";
6463
+ import chalk17 from "chalk";
6398
6464
  import ora8 from "ora";
6399
6465
 
6400
6466
  // src/propagation/graph.ts
6401
- async function buildDependencyGraph2(decisions, files) {
6467
+ async function buildDependencyGraph2(decisions, files, options = {}) {
6468
+ const { cwd } = options;
6402
6469
  const nodes = /* @__PURE__ */ new Map();
6403
6470
  const decisionToFiles = /* @__PURE__ */ new Map();
6404
6471
  const fileToDecisions = /* @__PURE__ */ new Map();
@@ -6413,7 +6480,7 @@ async function buildDependencyGraph2(decisions, files) {
6413
6480
  const constraintId = `constraint:${decision.metadata.id}/${constraint.id}`;
6414
6481
  const matchingFiles = [];
6415
6482
  for (const file of files) {
6416
- if (matchesPattern(file, constraint.scope)) {
6483
+ if (matchesPattern(file, constraint.scope, { cwd })) {
6417
6484
  matchingFiles.push(`file:${file}`);
6418
6485
  const fileDecisions = fileToDecisions.get(file) || /* @__PURE__ */ new Set();
6419
6486
  fileDecisions.add(decision.metadata.id);
@@ -6470,7 +6537,7 @@ var PropagationEngine = class {
6470
6537
  absolute: true
6471
6538
  });
6472
6539
  const decisions = this.registry.getActive();
6473
- this.graph = await buildDependencyGraph2(decisions, files);
6540
+ this.graph = await buildDependencyGraph2(decisions, files, { cwd });
6474
6541
  }
6475
6542
  /**
6476
6543
  * Analyze impact of changing a decision
@@ -6480,7 +6547,24 @@ var PropagationEngine = class {
6480
6547
  if (!this.graph) {
6481
6548
  await this.initialize(config, options);
6482
6549
  }
6483
- const affectedFilePaths = getAffectedFiles(this.graph, decisionId);
6550
+ const graph = this.graph;
6551
+ if (!graph) {
6552
+ return {
6553
+ decision: decisionId,
6554
+ change,
6555
+ affectedFiles: [],
6556
+ estimatedEffort: "low",
6557
+ migrationSteps: [
6558
+ {
6559
+ order: 1,
6560
+ description: "Run verification to confirm all violations resolved",
6561
+ files: [],
6562
+ automated: true
6563
+ }
6564
+ ]
6565
+ };
6566
+ }
6567
+ const affectedFilePaths = getAffectedFiles(graph, decisionId);
6484
6568
  const verificationEngine = createVerificationEngine(this.registry);
6485
6569
  const result = await verificationEngine.verify(config, {
6486
6570
  files: affectedFilePaths,
@@ -6604,8 +6688,8 @@ var impactCommand = new Command18("impact").description("Analyze impact of decis
6604
6688
  const changeType = options.change || "modified";
6605
6689
  if (!["created", "modified", "deprecated"].includes(changeType)) {
6606
6690
  spinner.fail();
6607
- console.error(chalk18.red(`Invalid change type: ${changeType}`));
6608
- console.error(chalk18.dim("Valid types: created, modified, deprecated"));
6691
+ console.error(chalk17.red(`Invalid change type: ${changeType}`));
6692
+ console.error(chalk17.dim("Valid types: created, modified, deprecated"));
6609
6693
  process.exit(1);
6610
6694
  }
6611
6695
  spinner.text = `Analyzing impact of ${changeType} decision ${decisionId}...`;
@@ -6623,44 +6707,44 @@ var impactCommand = new Command18("impact").description("Analyze impact of decis
6623
6707
  }
6624
6708
  });
6625
6709
  function printImpactAnalysis(analysis, showSteps) {
6626
- console.log(chalk18.bold(`
6710
+ console.log(chalk17.bold(`
6627
6711
  === Impact Analysis: ${analysis.decision} ===
6628
6712
  `));
6629
- const changeLabel = chalk18.cyan(analysis.change);
6713
+ const changeLabel = chalk17.cyan(analysis.change);
6630
6714
  console.log(`Change Type: ${changeLabel}`);
6631
- const effortColor = analysis.estimatedEffort === "high" ? chalk18.red : analysis.estimatedEffort === "medium" ? chalk18.yellow : chalk18.green;
6715
+ const effortColor = analysis.estimatedEffort === "high" ? chalk17.red : analysis.estimatedEffort === "medium" ? chalk17.yellow : chalk17.green;
6632
6716
  console.log(`Estimated Effort: ${effortColor(analysis.estimatedEffort.toUpperCase())}
6633
6717
  `);
6634
- console.log(chalk18.bold(`Affected Files: ${analysis.affectedFiles.length}`));
6718
+ console.log(chalk17.bold(`Affected Files: ${analysis.affectedFiles.length}`));
6635
6719
  if (analysis.affectedFiles.length > 0) {
6636
6720
  const displayCount = Math.min(analysis.affectedFiles.length, 10);
6637
6721
  for (let i = 0; i < displayCount; i++) {
6638
6722
  const file = analysis.affectedFiles[i];
6639
6723
  if (!file) continue;
6640
6724
  const violationText = file.violations === 1 ? "1 violation" : `${file.violations} violations`;
6641
- const autoFixText = file.autoFixable > 0 ? chalk18.green(` (${file.autoFixable} auto-fixable)`) : "";
6642
- console.log(` ${chalk18.red("\u25CF")} ${file.path} - ${violationText}${autoFixText}`);
6725
+ const autoFixText = file.autoFixable > 0 ? chalk17.green(` (${file.autoFixable} auto-fixable)`) : "";
6726
+ console.log(` ${chalk17.red("\u25CF")} ${file.path} - ${violationText}${autoFixText}`);
6643
6727
  }
6644
6728
  if (analysis.affectedFiles.length > displayCount) {
6645
6729
  const remaining = analysis.affectedFiles.length - displayCount;
6646
- console.log(chalk18.dim(` ... and ${remaining} more file(s)`));
6730
+ console.log(chalk17.dim(` ... and ${remaining} more file(s)`));
6647
6731
  }
6648
6732
  } else {
6649
- console.log(chalk18.green(" No violations found"));
6733
+ console.log(chalk17.green(" No violations found"));
6650
6734
  }
6651
6735
  if (showSteps && analysis.migrationSteps && analysis.migrationSteps.length > 0) {
6652
- console.log(chalk18.bold("\nMigration Plan:"));
6736
+ console.log(chalk17.bold("\nMigration Plan:"));
6653
6737
  for (const step of analysis.migrationSteps) {
6654
6738
  const icon = step.automated ? "\u{1F916}" : "\u{1F464}";
6655
- const typeLabel = step.automated ? chalk18.green("[Automated]") : chalk18.yellow("[Manual]");
6739
+ const typeLabel = step.automated ? chalk17.green("[Automated]") : chalk17.yellow("[Manual]");
6656
6740
  console.log(` ${icon} Step ${step.order}: ${step.description} ${typeLabel}`);
6657
6741
  if (step.files.length > 0) {
6658
6742
  const displayFiles = Math.min(step.files.length, 3);
6659
6743
  for (let i = 0; i < displayFiles; i++) {
6660
- console.log(chalk18.dim(` - ${step.files[i]}`));
6744
+ console.log(chalk17.dim(` - ${step.files[i]}`));
6661
6745
  }
6662
6746
  if (step.files.length > displayFiles) {
6663
- console.log(chalk18.dim(` ... and ${step.files.length - displayFiles} more file(s)`));
6747
+ console.log(chalk17.dim(` ... and ${step.files.length - displayFiles} more file(s)`));
6664
6748
  }
6665
6749
  }
6666
6750
  console.log("");
@@ -6669,15 +6753,15 @@ function printImpactAnalysis(analysis, showSteps) {
6669
6753
  const totalViolations = analysis.affectedFiles.reduce((sum, f) => sum + f.violations, 0);
6670
6754
  const totalAutoFixable = analysis.affectedFiles.reduce((sum, f) => sum + f.autoFixable, 0);
6671
6755
  const manualFixes = totalViolations - totalAutoFixable;
6672
- console.log(chalk18.bold("Summary:"));
6756
+ console.log(chalk17.bold("Summary:"));
6673
6757
  console.log(` Total Violations: ${totalViolations}`);
6674
- console.log(` Auto-fixable: ${chalk18.green(totalAutoFixable)}`);
6675
- console.log(` Manual Fixes Required: ${manualFixes > 0 ? chalk18.yellow(manualFixes) : chalk18.green(0)}`);
6758
+ console.log(` Auto-fixable: ${chalk17.green(totalAutoFixable)}`);
6759
+ console.log(` Manual Fixes Required: ${manualFixes > 0 ? chalk17.yellow(manualFixes) : chalk17.green(0)}`);
6676
6760
  }
6677
6761
 
6678
6762
  // src/cli/commands/migrate.ts
6679
6763
  import { Command as Command19 } from "commander";
6680
- import chalk19 from "chalk";
6764
+ import chalk18 from "chalk";
6681
6765
  import ora9 from "ora";
6682
6766
  import { join as join13 } from "path";
6683
6767
  import { readdir as readdir2, copyFile, mkdir as mkdir2, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
@@ -6688,17 +6772,17 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6688
6772
  }
6689
6773
  const from = options.from || "v1";
6690
6774
  const to = options.to || "v2";
6691
- console.log(chalk19.blue.bold(`
6775
+ console.log(chalk18.blue.bold(`
6692
6776
  === SpecBridge Migration: ${from} \u2192 ${to} ===
6693
6777
  `));
6694
6778
  if (from !== "v1" && from !== "v1.3") {
6695
- console.error(chalk19.red(`Unsupported source version: ${from}`));
6696
- console.log(chalk19.gray("Supported: v1, v1.3"));
6779
+ console.error(chalk18.red(`Unsupported source version: ${from}`));
6780
+ console.log(chalk18.gray("Supported: v1, v1.3"));
6697
6781
  process.exit(1);
6698
6782
  }
6699
6783
  if (to !== "v2" && to !== "v2.0") {
6700
- console.error(chalk19.red(`Unsupported target version: ${to}`));
6701
- console.log(chalk19.gray("Supported: v2, v2.0"));
6784
+ console.error(chalk18.red(`Unsupported target version: ${to}`));
6785
+ console.log(chalk18.gray("Supported: v2, v2.0"));
6702
6786
  process.exit(1);
6703
6787
  }
6704
6788
  const spinner = ora9("Analyzing current configuration...").start();
@@ -6718,7 +6802,7 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6718
6802
  const config = await loadConfig(cwd);
6719
6803
  const v1Report = await generateReport(config, { cwd, legacyCompliance: true });
6720
6804
  v1Compliance = v1Report.summary.compliance;
6721
- } catch (error) {
6805
+ } catch {
6722
6806
  spinner.warn("Could not generate v1 baseline report");
6723
6807
  }
6724
6808
  spinner.text = "Migrating decision files...";
@@ -6740,7 +6824,7 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6740
6824
  v2: v2Compliance,
6741
6825
  difference: v2Compliance - v1Compliance
6742
6826
  };
6743
- } catch (error) {
6827
+ } catch {
6744
6828
  spinner.warn("Could not generate v2 comparison report");
6745
6829
  }
6746
6830
  }
@@ -6749,41 +6833,41 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6749
6833
  report.changes.push("All decisions validated successfully");
6750
6834
  }
6751
6835
  spinner.succeed(options.dryRun ? "Migration preview complete" : "Migration complete");
6752
- console.log(chalk19.green.bold("\n\u2713 Migration Summary:\n"));
6753
- console.log(chalk19.bold("Backup:"));
6836
+ console.log(chalk18.green.bold("\n\u2713 Migration Summary:\n"));
6837
+ console.log(chalk18.bold("Backup:"));
6754
6838
  console.log(` ${report.backupPath}`);
6755
6839
  console.log("");
6756
- console.log(chalk19.bold("Changes:"));
6840
+ console.log(chalk18.bold("Changes:"));
6757
6841
  for (const change of report.changes) {
6758
6842
  console.log(` \u2022 ${change}`);
6759
6843
  }
6760
6844
  console.log("");
6761
6845
  if (report.complianceComparison) {
6762
- console.log(chalk19.bold("Compliance Comparison:"));
6846
+ console.log(chalk18.bold("Compliance Comparison:"));
6763
6847
  console.log(` v1.3 formula: ${report.complianceComparison.v1}%`);
6764
6848
  console.log(` v2.0 formula: ${report.complianceComparison.v2}%`);
6765
6849
  const diff = report.complianceComparison.difference;
6766
- const diffColor = diff > 0 ? chalk19.green : diff < 0 ? chalk19.red : chalk19.yellow;
6850
+ const diffColor = diff > 0 ? chalk18.green : diff < 0 ? chalk18.red : chalk18.yellow;
6767
6851
  console.log(` Difference: ${diffColor(`${diff > 0 ? "+" : ""}${diff.toFixed(1)}%`)}`);
6768
6852
  console.log("");
6769
6853
  if (Math.abs(diff) > 10) {
6770
- console.log(chalk19.yellow("\u26A0\uFE0F Note: Compliance score changed significantly due to severity weighting."));
6771
- console.log(chalk19.gray(" Consider adjusting CI thresholds if needed.\n"));
6854
+ console.log(chalk18.yellow("\u26A0\uFE0F Note: Compliance score changed significantly due to severity weighting."));
6855
+ console.log(chalk18.gray(" Consider adjusting CI thresholds if needed.\n"));
6772
6856
  }
6773
6857
  }
6774
6858
  if (options.dryRun) {
6775
- console.log(chalk19.yellow("This was a dry run. No changes were applied."));
6776
- console.log(chalk19.gray("Run without --dry-run to apply changes.\n"));
6859
+ console.log(chalk18.yellow("This was a dry run. No changes were applied."));
6860
+ console.log(chalk18.gray("Run without --dry-run to apply changes.\n"));
6777
6861
  } else {
6778
- console.log(chalk19.green("\u2713 Migration successful!"));
6779
- console.log(chalk19.gray(`
6862
+ console.log(chalk18.green("\u2713 Migration successful!"));
6863
+ console.log(chalk18.gray(`
6780
6864
  Rollback: Copy files from ${report.backupPath} back to .specbridge/decisions/
6781
6865
  `));
6782
6866
  }
6783
6867
  } catch (error) {
6784
6868
  spinner.fail("Migration failed");
6785
- console.error(chalk19.red("\nError:"), error instanceof Error ? error.message : error);
6786
- console.log(chalk19.gray("\nNo changes were applied."));
6869
+ console.error(chalk18.red("\nError:"), error instanceof Error ? error.message : error);
6870
+ console.log(chalk18.gray("\nNo changes were applied."));
6787
6871
  throw error;
6788
6872
  }
6789
6873
  });
@@ -6830,7 +6914,7 @@ async function migrateDecisions(cwd, dryRun) {
6830
6914
  "$1check:\n$1 verifier: $2"
6831
6915
  );
6832
6916
  if (dryRun) {
6833
- console.log(chalk19.gray(` Would migrate: ${file}`));
6917
+ console.log(chalk18.gray(` Would migrate: ${file}`));
6834
6918
  updatedCount++;
6835
6919
  } else {
6836
6920
  await writeFile3(filePath, migratedContent, "utf-8");
@@ -6868,11 +6952,11 @@ program.exitOverride((err) => {
6868
6952
  if (err.code === "commander.version") {
6869
6953
  process.exit(0);
6870
6954
  }
6871
- console.error(chalk20.red(formatError(err)));
6955
+ console.error(chalk19.red(formatError(err)));
6872
6956
  process.exit(1);
6873
6957
  });
6874
6958
  program.parseAsync(process.argv).catch((error) => {
6875
- console.error(chalk20.red(formatError(error)));
6959
+ console.error(chalk19.red(formatError(error)));
6876
6960
  process.exit(1);
6877
6961
  });
6878
6962
  //# sourceMappingURL=cli.js.map