@ipation/specbridge 2.3.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";
@@ -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";
@@ -2244,7 +2243,8 @@ var DependencyVerifier = class {
2244
2243
  const sccs = tarjanScc(graph);
2245
2244
  const current = projectFilePath;
2246
2245
  for (const scc of sccs) {
2247
- 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);
2248
2248
  const isCycle = scc.length > 1 || hasSelfLoop;
2249
2249
  if (!isCycle) continue;
2250
2250
  if (!scc.includes(current)) continue;
@@ -2685,10 +2685,36 @@ import { existsSync } from "fs";
2685
2685
  import { join as join5 } from "path";
2686
2686
  import { pathToFileURL } from "url";
2687
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
2688
2713
  var PluginLoader = class {
2689
2714
  plugins = /* @__PURE__ */ new Map();
2690
2715
  loaded = false;
2691
2716
  loadErrors = [];
2717
+ logger = getLogger({ module: "verification.plugins.loader" });
2692
2718
  /**
2693
2719
  * Load all plugins from the specified base path
2694
2720
  *
@@ -2711,15 +2737,15 @@ var PluginLoader = class {
2711
2737
  } catch (error) {
2712
2738
  const message = error instanceof Error ? error.message : String(error);
2713
2739
  this.loadErrors.push({ file, error: message });
2714
- console.warn(`Failed to load plugin from ${file}: ${message}`);
2740
+ this.logger.warn({ file, error: message }, "Failed to load plugin");
2715
2741
  }
2716
2742
  }
2717
2743
  this.loaded = true;
2718
2744
  if (this.plugins.size > 0) {
2719
- console.error(`Loaded ${this.plugins.size} custom verifier(s)`);
2745
+ this.logger.info({ count: this.plugins.size }, "Loaded custom verifier plugins");
2720
2746
  }
2721
2747
  if (this.loadErrors.length > 0) {
2722
- console.warn(`Failed to load ${this.loadErrors.length} plugin(s)`);
2748
+ this.logger.warn({ count: this.loadErrors.length }, "Plugin load failures");
2723
2749
  }
2724
2750
  }
2725
2751
  /**
@@ -2895,8 +2921,9 @@ var builtinVerifiers = {
2895
2921
  };
2896
2922
  var verifierInstances = /* @__PURE__ */ new Map();
2897
2923
  function getVerifier(id) {
2898
- if (verifierInstances.has(id)) {
2899
- return verifierInstances.get(id);
2924
+ const pooled = verifierInstances.get(id);
2925
+ if (pooled) {
2926
+ return pooled;
2900
2927
  }
2901
2928
  const pluginLoader2 = getPluginLoader();
2902
2929
  const customVerifier = pluginLoader2.getVerifier(id);
@@ -3098,6 +3125,7 @@ var VerificationEngine = class {
3098
3125
  astCache;
3099
3126
  resultsCache;
3100
3127
  pluginsLoaded = false;
3128
+ logger = getLogger({ module: "verification.engine" });
3101
3129
  constructor(registry) {
3102
3130
  this.registry = registry || createRegistry();
3103
3131
  this.project = new Project2({
@@ -3271,13 +3299,12 @@ var VerificationEngine = class {
3271
3299
  );
3272
3300
  if (!verifier) {
3273
3301
  const requestedVerifier = constraint.check?.verifier || constraint.verifier || "auto-detected";
3274
- console.warn(
3275
- chalk3.yellow(
3276
- `Warning: No verifier found for ${decision.metadata.id}/${constraint.id}
3277
- Requested: ${requestedVerifier}
3278
- Available: ${getVerifierIds().join(", ")}`
3279
- )
3280
- );
3302
+ this.logger.warn({
3303
+ decisionId: decision.metadata.id,
3304
+ constraintId: constraint.id,
3305
+ requestedVerifier,
3306
+ availableVerifiers: getVerifierIds()
3307
+ }, "No verifier found for constraint");
3281
3308
  warnings.push({
3282
3309
  type: "missing_verifier",
3283
3310
  message: `No verifier found for constraint (requested: ${requestedVerifier})`,
@@ -3383,17 +3410,14 @@ var VerificationEngine = class {
3383
3410
  } catch (error) {
3384
3411
  const errorMessage = error instanceof Error ? error.message : String(error);
3385
3412
  const errorStack = error instanceof Error ? error.stack : void 0;
3386
- console.error(
3387
- chalk3.red(
3388
- `Error: Verifier '${verifier.id}' failed
3389
- File: ${filePath}
3390
- Decision: ${decision.metadata.id}/${constraint.id}
3391
- Error: ${errorMessage}`
3392
- )
3393
- );
3394
- if (errorStack) {
3395
- console.error(chalk3.dim(errorStack));
3396
- }
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");
3397
3421
  errors.push({
3398
3422
  type: "verifier_exception",
3399
3423
  message: `Verifier '${verifier.id}' failed: ${errorMessage}`,
@@ -3509,6 +3533,10 @@ var AutofixEngine = class {
3509
3533
  const edits = [];
3510
3534
  for (const violation of fileViolations) {
3511
3535
  const fix = violation.autofix;
3536
+ if (!fix) {
3537
+ skippedViolations++;
3538
+ continue;
3539
+ }
3512
3540
  if (options.interactive) {
3513
3541
  const ok = await confirmFix(`Apply fix: ${fix.description} (${filePath}:${violation.line ?? 1})?`);
3514
3542
  if (!ok) {
@@ -3555,7 +3583,7 @@ async function getChangedFiles(cwd) {
3555
3583
  }
3556
3584
 
3557
3585
  // src/verification/explain.ts
3558
- import chalk4 from "chalk";
3586
+ import chalk3 from "chalk";
3559
3587
  var ExplainReporter = class {
3560
3588
  entries = [];
3561
3589
  /**
@@ -3569,10 +3597,10 @@ var ExplainReporter = class {
3569
3597
  */
3570
3598
  print() {
3571
3599
  if (this.entries.length === 0) {
3572
- console.log(chalk4.dim("No constraints were evaluated."));
3600
+ console.log(chalk3.dim("No constraints were evaluated."));
3573
3601
  return;
3574
3602
  }
3575
- console.log(chalk4.bold("\n=== Verification Explanation ===\n"));
3603
+ console.log(chalk3.bold("\n=== Verification Explanation ===\n"));
3576
3604
  const byFile = /* @__PURE__ */ new Map();
3577
3605
  for (const entry of this.entries) {
3578
3606
  const existing = byFile.get(entry.file) || [];
@@ -3580,22 +3608,22 @@ var ExplainReporter = class {
3580
3608
  byFile.set(entry.file, existing);
3581
3609
  }
3582
3610
  for (const [file, entries] of byFile) {
3583
- console.log(chalk4.underline(file));
3611
+ console.log(chalk3.underline(file));
3584
3612
  for (const entry of entries) {
3585
- const icon = entry.applied ? chalk4.green("\u2713") : chalk4.dim("\u2298");
3613
+ const icon = entry.applied ? chalk3.green("\u2713") : chalk3.dim("\u2298");
3586
3614
  const constraintId = `${entry.decision.metadata.id}/${entry.constraint.id}`;
3587
3615
  console.log(` ${icon} ${constraintId}`);
3588
- console.log(chalk4.dim(` ${entry.reason}`));
3616
+ console.log(chalk3.dim(` ${entry.reason}`));
3589
3617
  if (entry.applied && entry.selectedVerifier) {
3590
- console.log(chalk4.dim(` Verifier: ${entry.selectedVerifier}`));
3618
+ console.log(chalk3.dim(` Verifier: ${entry.selectedVerifier}`));
3591
3619
  if (entry.verifierOutput) {
3592
3620
  if (entry.verifierOutput.error) {
3593
- console.log(chalk4.red(` Error: ${entry.verifierOutput.error}`));
3621
+ console.log(chalk3.red(` Error: ${entry.verifierOutput.error}`));
3594
3622
  } else {
3595
3623
  const violationText = entry.verifierOutput.violations === 1 ? "1 violation" : `${entry.verifierOutput.violations} violations`;
3596
- const resultColor = entry.verifierOutput.violations > 0 ? chalk4.red : chalk4.green;
3624
+ const resultColor = entry.verifierOutput.violations > 0 ? chalk3.red : chalk3.green;
3597
3625
  console.log(
3598
- 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`)
3599
3627
  );
3600
3628
  }
3601
3629
  }
@@ -3605,9 +3633,9 @@ var ExplainReporter = class {
3605
3633
  }
3606
3634
  const applied = this.entries.filter((e) => e.applied).length;
3607
3635
  const skipped = this.entries.filter((e) => !e.applied).length;
3608
- console.log(chalk4.bold("Summary:"));
3609
- console.log(` Constraints Applied: ${chalk4.green(applied)}`);
3610
- 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)}`);
3611
3639
  }
3612
3640
  /**
3613
3641
  * Get all entries
@@ -3657,7 +3685,7 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3657
3685
  if (fixableCount === 0) {
3658
3686
  spinner.stop();
3659
3687
  if (!options.json) {
3660
- console.log(chalk5.yellow("No auto-fixable violations found"));
3688
+ console.log(chalk4.yellow("No auto-fixable violations found"));
3661
3689
  }
3662
3690
  } else {
3663
3691
  spinner.text = `Applying ${fixableCount} auto-fix(es)...`;
@@ -3682,34 +3710,34 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3682
3710
  console.log(JSON.stringify({ ...result, autofix: fixResult }, null, 2));
3683
3711
  } else {
3684
3712
  if (result.warnings && result.warnings.length > 0) {
3685
- console.log(chalk5.yellow.bold("\nWarnings:"));
3713
+ console.log(chalk4.yellow.bold("\nWarnings:"));
3686
3714
  for (const warning of result.warnings) {
3687
- console.log(chalk5.yellow(` \u26A0 ${warning.message}`));
3688
- 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}`));
3689
3717
  if (warning.file) {
3690
- console.log(chalk5.dim(` File: ${warning.file}`));
3718
+ console.log(chalk4.dim(` File: ${warning.file}`));
3691
3719
  }
3692
3720
  }
3693
3721
  console.log("");
3694
3722
  }
3695
3723
  if (result.errors && result.errors.length > 0) {
3696
- console.log(chalk5.red.bold("\nErrors:"));
3724
+ console.log(chalk4.red.bold("\nErrors:"));
3697
3725
  for (const error of result.errors) {
3698
- console.log(chalk5.red(` \u2717 ${error.message}`));
3726
+ console.log(chalk4.red(` \u2717 ${error.message}`));
3699
3727
  if (error.decisionId && error.constraintId) {
3700
- console.log(chalk5.dim(` ${error.decisionId}/${error.constraintId}`));
3728
+ console.log(chalk4.dim(` ${error.decisionId}/${error.constraintId}`));
3701
3729
  }
3702
3730
  if (error.file) {
3703
- console.log(chalk5.dim(` File: ${error.file}`));
3731
+ console.log(chalk4.dim(` File: ${error.file}`));
3704
3732
  }
3705
3733
  }
3706
3734
  console.log("");
3707
3735
  }
3708
3736
  printResult(result, level);
3709
3737
  if (options.fix && fixResult) {
3710
- console.log(chalk5.green(`\u2713 Applied ${fixResult.applied.length} fix(es)`));
3738
+ console.log(chalk4.green(`\u2713 Applied ${fixResult.applied.length} fix(es)`));
3711
3739
  if (fixResult.skipped > 0) {
3712
- console.log(chalk5.yellow(`\u2298 Skipped ${fixResult.skipped} fix(es)`));
3740
+ console.log(chalk4.yellow(`\u2298 Skipped ${fixResult.skipped} fix(es)`));
3713
3741
  }
3714
3742
  console.log("");
3715
3743
  }
@@ -3728,8 +3756,8 @@ var verifyCommand = new Command3("verify").description("Verify code compliance a
3728
3756
  function printResult(result, level) {
3729
3757
  console.log("");
3730
3758
  if (result.violations.length === 0) {
3731
- console.log(chalk5.green("\u2713 All checks passed!"));
3732
- 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`));
3733
3761
  return;
3734
3762
  }
3735
3763
  const byFile = /* @__PURE__ */ new Map();
@@ -3739,7 +3767,7 @@ function printResult(result, level) {
3739
3767
  byFile.set(violation.file, existing);
3740
3768
  }
3741
3769
  for (const [file, violations] of byFile) {
3742
- console.log(chalk5.underline(file));
3770
+ console.log(chalk4.underline(file));
3743
3771
  for (const v of violations) {
3744
3772
  const typeIcon = getTypeIcon(v.type);
3745
3773
  const severityColor = getSeverityColor(v.severity);
@@ -3747,9 +3775,9 @@ function printResult(result, level) {
3747
3775
  console.log(
3748
3776
  ` ${typeIcon} ${severityColor(`[${v.severity}]`)} ${v.message}`
3749
3777
  );
3750
- console.log(chalk5.dim(` ${v.decisionId}/${v.constraintId}${location}`));
3778
+ console.log(chalk4.dim(` ${v.decisionId}/${v.constraintId}${location}`));
3751
3779
  if (v.suggestion) {
3752
- console.log(chalk5.cyan(` Suggestion: ${v.suggestion}`));
3780
+ console.log(chalk4.cyan(` Suggestion: ${v.suggestion}`));
3753
3781
  }
3754
3782
  }
3755
3783
  console.log("");
@@ -3758,29 +3786,29 @@ function printResult(result, level) {
3758
3786
  const highCount = result.violations.filter((v) => v.severity === "high").length;
3759
3787
  const mediumCount = result.violations.filter((v) => v.severity === "medium").length;
3760
3788
  const lowCount = result.violations.filter((v) => v.severity === "low").length;
3761
- console.log(chalk5.bold("Summary:"));
3789
+ console.log(chalk4.bold("Summary:"));
3762
3790
  console.log(` Files: ${result.checked} checked, ${result.passed} passed, ${result.failed} failed`);
3763
3791
  const violationParts = [];
3764
- if (criticalCount > 0) violationParts.push(chalk5.red(`${criticalCount} critical`));
3765
- if (highCount > 0) violationParts.push(chalk5.yellow(`${highCount} high`));
3766
- if (mediumCount > 0) violationParts.push(chalk5.cyan(`${mediumCount} medium`));
3767
- 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`));
3768
3796
  console.log(` Violations: ${violationParts.join(", ")}`);
3769
3797
  console.log(` Duration: ${result.duration}ms`);
3770
3798
  if (!result.success) {
3771
3799
  console.log("");
3772
3800
  const blockingTypes = level === "commit" ? "invariant or critical" : level === "pr" ? "invariant, critical, or high" : "invariant";
3773
- 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.`));
3774
3802
  }
3775
3803
  }
3776
3804
  function getTypeIcon(type) {
3777
3805
  switch (type) {
3778
3806
  case "invariant":
3779
- return chalk5.red("\u25CF");
3807
+ return chalk4.red("\u25CF");
3780
3808
  case "convention":
3781
- return chalk5.yellow("\u25CF");
3809
+ return chalk4.yellow("\u25CF");
3782
3810
  case "guideline":
3783
- return chalk5.green("\u25CF");
3811
+ return chalk4.green("\u25CF");
3784
3812
  default:
3785
3813
  return "\u25CB";
3786
3814
  }
@@ -3788,15 +3816,15 @@ function getTypeIcon(type) {
3788
3816
  function getSeverityColor(severity) {
3789
3817
  switch (severity) {
3790
3818
  case "critical":
3791
- return chalk5.red;
3819
+ return chalk4.red;
3792
3820
  case "high":
3793
- return chalk5.yellow;
3821
+ return chalk4.yellow;
3794
3822
  case "medium":
3795
- return chalk5.cyan;
3823
+ return chalk4.cyan;
3796
3824
  case "low":
3797
- return chalk5.dim;
3825
+ return chalk4.dim;
3798
3826
  default:
3799
- return chalk5.white;
3827
+ return chalk4.white;
3800
3828
  }
3801
3829
  }
3802
3830
 
@@ -3805,15 +3833,15 @@ import { Command as Command8 } from "commander";
3805
3833
 
3806
3834
  // src/cli/commands/decision/list.ts
3807
3835
  import { Command as Command4 } from "commander";
3808
- import chalk6 from "chalk";
3836
+ import chalk5 from "chalk";
3809
3837
  import { table } from "table";
3810
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) => {
3811
3839
  const registry = createRegistry();
3812
3840
  const result = await registry.load();
3813
3841
  if (result.errors.length > 0) {
3814
- console.warn(chalk6.yellow("\nWarnings:"));
3842
+ console.warn(chalk5.yellow("\nWarnings:"));
3815
3843
  for (const err of result.errors) {
3816
- console.warn(chalk6.yellow(` - ${err.filePath}: ${err.error}`));
3844
+ console.warn(chalk5.yellow(` - ${err.filePath}: ${err.error}`));
3817
3845
  }
3818
3846
  console.log("");
3819
3847
  }
@@ -3826,7 +3854,7 @@ var listDecisions = new Command4("list").description("List all architectural dec
3826
3854
  }
3827
3855
  const decisions = registry.getAll(filter);
3828
3856
  if (decisions.length === 0) {
3829
- console.log(chalk6.yellow("No decisions found."));
3857
+ console.log(chalk5.yellow("No decisions found."));
3830
3858
  return;
3831
3859
  }
3832
3860
  if (options.json) {
@@ -3835,11 +3863,11 @@ var listDecisions = new Command4("list").description("List all architectural dec
3835
3863
  }
3836
3864
  const data = [
3837
3865
  [
3838
- chalk6.bold("ID"),
3839
- chalk6.bold("Title"),
3840
- chalk6.bold("Status"),
3841
- chalk6.bold("Constraints"),
3842
- chalk6.bold("Tags")
3866
+ chalk5.bold("ID"),
3867
+ chalk5.bold("Title"),
3868
+ chalk5.bold("Status"),
3869
+ chalk5.bold("Constraints"),
3870
+ chalk5.bold("Tags")
3843
3871
  ]
3844
3872
  ];
3845
3873
  for (const decision of decisions) {
@@ -3873,20 +3901,20 @@ var listDecisions = new Command4("list").description("List all architectural dec
3873
3901
  },
3874
3902
  drawHorizontalLine: (index) => index === 1
3875
3903
  }));
3876
- console.log(chalk6.dim(`Total: ${decisions.length} decision(s)`));
3904
+ console.log(chalk5.dim(`Total: ${decisions.length} decision(s)`));
3877
3905
  });
3878
3906
  function getStatusColor(status) {
3879
3907
  switch (status) {
3880
3908
  case "active":
3881
- return chalk6.green;
3909
+ return chalk5.green;
3882
3910
  case "draft":
3883
- return chalk6.yellow;
3911
+ return chalk5.yellow;
3884
3912
  case "deprecated":
3885
- return chalk6.gray;
3913
+ return chalk5.gray;
3886
3914
  case "superseded":
3887
- return chalk6.blue;
3915
+ return chalk5.blue;
3888
3916
  default:
3889
- return chalk6.white;
3917
+ return chalk5.white;
3890
3918
  }
3891
3919
  }
3892
3920
  function getConstraintTypeSummary(types) {
@@ -3899,9 +3927,9 @@ function getConstraintTypeSummary(types) {
3899
3927
  counts[type]++;
3900
3928
  }
3901
3929
  const parts = [];
3902
- if (counts.invariant > 0) parts.push(chalk6.red(`${counts.invariant}I`));
3903
- if (counts.convention > 0) parts.push(chalk6.yellow(`${counts.convention}C`));
3904
- 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`));
3905
3933
  return parts.join(" ") || "-";
3906
3934
  }
3907
3935
  function truncate(str, length) {
@@ -3911,7 +3939,7 @@ function truncate(str, length) {
3911
3939
 
3912
3940
  // src/cli/commands/decision/show.ts
3913
3941
  import { Command as Command5 } from "commander";
3914
- import chalk7 from "chalk";
3942
+ import chalk6 from "chalk";
3915
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) => {
3916
3944
  const registry = createRegistry();
3917
3945
  await registry.load();
@@ -3924,74 +3952,74 @@ var showDecision = new Command5("show").description("Show details of a specific
3924
3952
  });
3925
3953
  function printDecision(decision) {
3926
3954
  const { metadata, decision: content, constraints } = decision;
3927
- console.log(chalk7.bold.blue(`
3955
+ console.log(chalk6.bold.blue(`
3928
3956
  ${metadata.title}`));
3929
- console.log(chalk7.dim(`ID: ${metadata.id}`));
3957
+ console.log(chalk6.dim(`ID: ${metadata.id}`));
3930
3958
  console.log("");
3931
- console.log(chalk7.bold("Status:"), getStatusBadge(metadata.status));
3932
- 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(", "));
3933
3961
  if (metadata.tags && metadata.tags.length > 0) {
3934
- 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(", "));
3935
3963
  }
3936
3964
  if (metadata.createdAt) {
3937
- console.log(chalk7.bold("Created:"), metadata.createdAt);
3965
+ console.log(chalk6.bold("Created:"), metadata.createdAt);
3938
3966
  }
3939
3967
  if (metadata.supersededBy) {
3940
- console.log(chalk7.bold("Superseded by:"), chalk7.yellow(metadata.supersededBy));
3968
+ console.log(chalk6.bold("Superseded by:"), chalk6.yellow(metadata.supersededBy));
3941
3969
  }
3942
3970
  console.log("");
3943
- console.log(chalk7.bold.underline("Summary"));
3971
+ console.log(chalk6.bold.underline("Summary"));
3944
3972
  console.log(content.summary);
3945
3973
  console.log("");
3946
- console.log(chalk7.bold.underline("Rationale"));
3974
+ console.log(chalk6.bold.underline("Rationale"));
3947
3975
  console.log(content.rationale);
3948
3976
  console.log("");
3949
3977
  if (content.context) {
3950
- console.log(chalk7.bold.underline("Context"));
3978
+ console.log(chalk6.bold.underline("Context"));
3951
3979
  console.log(content.context);
3952
3980
  console.log("");
3953
3981
  }
3954
3982
  if (content.consequences && content.consequences.length > 0) {
3955
- console.log(chalk7.bold.underline("Consequences"));
3983
+ console.log(chalk6.bold.underline("Consequences"));
3956
3984
  for (const consequence of content.consequences) {
3957
3985
  console.log(` \u2022 ${consequence}`);
3958
3986
  }
3959
3987
  console.log("");
3960
3988
  }
3961
- console.log(chalk7.bold.underline(`Constraints (${constraints.length})`));
3989
+ console.log(chalk6.bold.underline(`Constraints (${constraints.length})`));
3962
3990
  for (const constraint of constraints) {
3963
3991
  const typeIcon = getTypeIcon2(constraint.type);
3964
3992
  const severityBadge = getSeverityBadge(constraint.severity);
3965
3993
  console.log(`
3966
- ${typeIcon} ${chalk7.bold(constraint.id)} ${severityBadge}`);
3994
+ ${typeIcon} ${chalk6.bold(constraint.id)} ${severityBadge}`);
3967
3995
  console.log(` ${constraint.rule}`);
3968
- console.log(chalk7.dim(` Scope: ${constraint.scope}`));
3996
+ console.log(chalk6.dim(` Scope: ${constraint.scope}`));
3969
3997
  if (constraint.verifier) {
3970
- console.log(chalk7.dim(` Verifier: ${constraint.verifier}`));
3998
+ console.log(chalk6.dim(` Verifier: ${constraint.verifier}`));
3971
3999
  }
3972
4000
  if (constraint.exceptions && constraint.exceptions.length > 0) {
3973
- console.log(chalk7.dim(` Exceptions: ${constraint.exceptions.length}`));
4001
+ console.log(chalk6.dim(` Exceptions: ${constraint.exceptions.length}`));
3974
4002
  }
3975
4003
  }
3976
4004
  console.log("");
3977
4005
  if (decision.verification?.automated && decision.verification.automated.length > 0) {
3978
- console.log(chalk7.bold.underline("Automated Verification"));
4006
+ console.log(chalk6.bold.underline("Automated Verification"));
3979
4007
  for (const check of decision.verification.automated) {
3980
4008
  console.log(` \u2022 ${check.check} (${check.frequency})`);
3981
- console.log(chalk7.dim(` Target: ${check.target}`));
4009
+ console.log(chalk6.dim(` Target: ${check.target}`));
3982
4010
  }
3983
4011
  console.log("");
3984
4012
  }
3985
4013
  if (decision.links) {
3986
4014
  const { related, supersedes, references } = decision.links;
3987
4015
  if (related && related.length > 0) {
3988
- console.log(chalk7.bold("Related:"), related.join(", "));
4016
+ console.log(chalk6.bold("Related:"), related.join(", "));
3989
4017
  }
3990
4018
  if (supersedes && supersedes.length > 0) {
3991
- console.log(chalk7.bold("Supersedes:"), supersedes.join(", "));
4019
+ console.log(chalk6.bold("Supersedes:"), supersedes.join(", "));
3992
4020
  }
3993
4021
  if (references && references.length > 0) {
3994
- console.log(chalk7.bold("References:"));
4022
+ console.log(chalk6.bold("References:"));
3995
4023
  for (const ref of references) {
3996
4024
  console.log(` \u2022 ${ref}`);
3997
4025
  }
@@ -4001,13 +4029,13 @@ ${metadata.title}`));
4001
4029
  function getStatusBadge(status) {
4002
4030
  switch (status) {
4003
4031
  case "active":
4004
- return chalk7.bgGreen.black(" ACTIVE ");
4032
+ return chalk6.bgGreen.black(" ACTIVE ");
4005
4033
  case "draft":
4006
- return chalk7.bgYellow.black(" DRAFT ");
4034
+ return chalk6.bgYellow.black(" DRAFT ");
4007
4035
  case "deprecated":
4008
- return chalk7.bgGray.white(" DEPRECATED ");
4036
+ return chalk6.bgGray.white(" DEPRECATED ");
4009
4037
  case "superseded":
4010
- return chalk7.bgBlue.white(" SUPERSEDED ");
4038
+ return chalk6.bgBlue.white(" SUPERSEDED ");
4011
4039
  default:
4012
4040
  return status;
4013
4041
  }
@@ -4015,11 +4043,11 @@ function getStatusBadge(status) {
4015
4043
  function getTypeIcon2(type) {
4016
4044
  switch (type) {
4017
4045
  case "invariant":
4018
- return chalk7.red("\u25CF");
4046
+ return chalk6.red("\u25CF");
4019
4047
  case "convention":
4020
- return chalk7.yellow("\u25CF");
4048
+ return chalk6.yellow("\u25CF");
4021
4049
  case "guideline":
4022
- return chalk7.green("\u25CF");
4050
+ return chalk6.green("\u25CF");
4023
4051
  default:
4024
4052
  return "\u25CB";
4025
4053
  }
@@ -4027,13 +4055,13 @@ function getTypeIcon2(type) {
4027
4055
  function getSeverityBadge(severity) {
4028
4056
  switch (severity) {
4029
4057
  case "critical":
4030
- return chalk7.bgRed.white(" CRITICAL ");
4058
+ return chalk6.bgRed.white(" CRITICAL ");
4031
4059
  case "high":
4032
- return chalk7.bgYellow.black(" HIGH ");
4060
+ return chalk6.bgYellow.black(" HIGH ");
4033
4061
  case "medium":
4034
- return chalk7.bgCyan.black(" MEDIUM ");
4062
+ return chalk6.bgCyan.black(" MEDIUM ");
4035
4063
  case "low":
4036
- return chalk7.bgGray.white(" LOW ");
4064
+ return chalk6.bgGray.white(" LOW ");
4037
4065
  default:
4038
4066
  return severity;
4039
4067
  }
@@ -4041,7 +4069,7 @@ function getSeverityBadge(severity) {
4041
4069
 
4042
4070
  // src/cli/commands/decision/validate.ts
4043
4071
  import { Command as Command6 } from "commander";
4044
- import chalk8 from "chalk";
4072
+ import chalk7 from "chalk";
4045
4073
  import ora4 from "ora";
4046
4074
  import { join as join6 } from "path";
4047
4075
  var validateDecisions = new Command6("validate").description("Validate decision files").option("-f, --file <path>", "Validate a specific file").action(async (options) => {
@@ -4080,14 +4108,14 @@ var validateDecisions = new Command6("validate").description("Validate decision
4080
4108
  }
4081
4109
  spinner.stop();
4082
4110
  if (invalid === 0) {
4083
- 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.`));
4084
4112
  } else {
4085
- 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.
4086
4114
  `));
4087
4115
  for (const { file, errors: fileErrors } of errors) {
4088
- console.log(chalk8.red(`File: ${file}`));
4116
+ console.log(chalk7.red(`File: ${file}`));
4089
4117
  for (const err of fileErrors) {
4090
- console.log(chalk8.dim(` - ${err}`));
4118
+ console.log(chalk7.dim(` - ${err}`));
4091
4119
  }
4092
4120
  console.log("");
4093
4121
  }
@@ -4101,7 +4129,7 @@ var validateDecisions = new Command6("validate").description("Validate decision
4101
4129
 
4102
4130
  // src/cli/commands/decision/create.ts
4103
4131
  import { Command as Command7 } from "commander";
4104
- import chalk9 from "chalk";
4132
+ import chalk8 from "chalk";
4105
4133
  import { join as join7 } from "path";
4106
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) => {
4107
4135
  const cwd = process.cwd();
@@ -4109,13 +4137,13 @@ var createDecision = new Command7("create").description("Create a new decision f
4109
4137
  throw new NotInitializedError();
4110
4138
  }
4111
4139
  if (!/^[a-z0-9-]+$/.test(id)) {
4112
- 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."));
4113
4141
  process.exit(1);
4114
4142
  }
4115
4143
  const decisionsDir = getDecisionsDir(cwd);
4116
4144
  const filePath = join7(decisionsDir, `${id}.decision.yaml`);
4117
4145
  if (await pathExists(filePath)) {
4118
- console.error(chalk9.red(`Error: Decision file already exists: ${filePath}`));
4146
+ console.error(chalk8.red(`Error: Decision file already exists: ${filePath}`));
4119
4147
  process.exit(1);
4120
4148
  }
4121
4149
  const decision = {
@@ -4151,13 +4179,13 @@ var createDecision = new Command7("create").description("Create a new decision f
4151
4179
  }
4152
4180
  };
4153
4181
  await writeTextFile(filePath, stringifyYaml(decision));
4154
- console.log(chalk9.green(`\u2713 Created decision: ${filePath}`));
4182
+ console.log(chalk8.green(`\u2713 Created decision: ${filePath}`));
4155
4183
  console.log("");
4156
- console.log(chalk9.cyan("Next steps:"));
4184
+ console.log(chalk8.cyan("Next steps:"));
4157
4185
  console.log(` 1. Edit the file to add rationale, context, and consequences`);
4158
4186
  console.log(` 2. Define constraints with appropriate scopes`);
4159
- console.log(` 3. Run ${chalk9.bold("specbridge decision validate")} to check syntax`);
4160
- 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`);
4161
4189
  });
4162
4190
 
4163
4191
  // src/cli/commands/decision/index.ts
@@ -4165,7 +4193,7 @@ var decisionCommand = new Command8("decision").description("Manage architectural
4165
4193
 
4166
4194
  // src/cli/commands/hook.ts
4167
4195
  import { Command as Command9 } from "commander";
4168
- import chalk10 from "chalk";
4196
+ import chalk9 from "chalk";
4169
4197
  import ora5 from "ora";
4170
4198
  import { join as join8 } from "path";
4171
4199
  var HOOK_SCRIPT = `#!/bin/sh
@@ -4197,9 +4225,9 @@ function createHookCommand() {
4197
4225
  } else if (options.lefthook) {
4198
4226
  spinner.succeed("Lefthook detected");
4199
4227
  console.log("");
4200
- console.log(chalk10.cyan("Add this to your lefthook.yml:"));
4228
+ console.log(chalk9.cyan("Add this to your lefthook.yml:"));
4201
4229
  console.log("");
4202
- console.log(chalk10.dim(`pre-commit:
4230
+ console.log(chalk9.dim(`pre-commit:
4203
4231
  commands:
4204
4232
  specbridge:
4205
4233
  glob: "*.{ts,tsx}"
@@ -4214,9 +4242,9 @@ function createHookCommand() {
4214
4242
  } else if (await pathExists(join8(cwd, "lefthook.yml"))) {
4215
4243
  spinner.succeed("Lefthook detected");
4216
4244
  console.log("");
4217
- console.log(chalk10.cyan("Add this to your lefthook.yml:"));
4245
+ console.log(chalk9.cyan("Add this to your lefthook.yml:"));
4218
4246
  console.log("");
4219
- console.log(chalk10.dim(`pre-commit:
4247
+ console.log(chalk9.dim(`pre-commit:
4220
4248
  commands:
4221
4249
  specbridge:
4222
4250
  glob: "*.{ts,tsx}"
@@ -4231,7 +4259,7 @@ function createHookCommand() {
4231
4259
  }
4232
4260
  if (await pathExists(hookPath) && !options.force) {
4233
4261
  spinner.fail("Hook already exists");
4234
- console.log(chalk10.yellow(`Use --force to overwrite: ${hookPath}`));
4262
+ console.log(chalk9.yellow(`Use --force to overwrite: ${hookPath}`));
4235
4263
  return;
4236
4264
  }
4237
4265
  await writeTextFile(hookPath, hookContent);
@@ -4241,9 +4269,9 @@ function createHookCommand() {
4241
4269
  } catch {
4242
4270
  }
4243
4271
  spinner.succeed("Pre-commit hook installed");
4244
- console.log(chalk10.dim(` Path: ${hookPath}`));
4272
+ console.log(chalk9.dim(` Path: ${hookPath}`));
4245
4273
  console.log("");
4246
- 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."));
4247
4275
  } catch (error) {
4248
4276
  spinner.fail("Failed to install hook");
4249
4277
  throw error;
@@ -4279,21 +4307,21 @@ function createHookCommand() {
4279
4307
  cwd
4280
4308
  });
4281
4309
  if (result.violations.length === 0) {
4282
- console.log(chalk10.green("\u2713 SpecBridge: All checks passed"));
4310
+ console.log(chalk9.green("\u2713 SpecBridge: All checks passed"));
4283
4311
  process.exit(0);
4284
4312
  }
4285
- 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`));
4286
4314
  console.log("");
4287
4315
  for (const v of result.violations) {
4288
4316
  const location = v.line ? `:${v.line}` : "";
4289
4317
  console.log(` ${v.file}${location}: ${v.message}`);
4290
- console.log(chalk10.dim(` [${v.severity}] ${v.decisionId}/${v.constraintId}`));
4318
+ console.log(chalk9.dim(` [${v.severity}] ${v.decisionId}/${v.constraintId}`));
4291
4319
  }
4292
4320
  console.log("");
4293
- console.log(chalk10.yellow("Run `specbridge verify` for full details."));
4321
+ console.log(chalk9.yellow("Run `specbridge verify` for full details."));
4294
4322
  process.exit(result.success ? 0 : 1);
4295
4323
  } catch (error) {
4296
- console.error(chalk10.red("SpecBridge verification failed"));
4324
+ console.error(chalk9.red("SpecBridge verification failed"));
4297
4325
  console.error(error instanceof Error ? error.message : String(error));
4298
4326
  process.exit(1);
4299
4327
  }
@@ -4332,7 +4360,7 @@ var hookCommand = createHookCommand();
4332
4360
 
4333
4361
  // src/cli/commands/report.ts
4334
4362
  import { Command as Command10 } from "commander";
4335
- import chalk12 from "chalk";
4363
+ import chalk11 from "chalk";
4336
4364
  import ora6 from "ora";
4337
4365
  import { join as join10 } from "path";
4338
4366
 
@@ -4416,54 +4444,54 @@ async function generateReport(config, options = {}) {
4416
4444
  }
4417
4445
 
4418
4446
  // src/reporting/formats/console.ts
4419
- import chalk11 from "chalk";
4447
+ import chalk10 from "chalk";
4420
4448
  import { table as table2 } from "table";
4421
4449
  function formatConsoleReport(report) {
4422
4450
  const lines = [];
4423
4451
  lines.push("");
4424
- lines.push(chalk11.bold.blue("SpecBridge Compliance Report"));
4425
- lines.push(chalk11.dim(`Generated: ${new Date(report.timestamp).toLocaleString()}`));
4426
- 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}`));
4427
4455
  lines.push("");
4428
4456
  const complianceColor = getComplianceColor(report.summary.compliance);
4429
- lines.push(chalk11.bold("Overall Compliance"));
4457
+ lines.push(chalk10.bold("Overall Compliance"));
4430
4458
  lines.push(` ${complianceColor(formatComplianceBar(report.summary.compliance))} ${complianceColor(`${report.summary.compliance}%`)}`);
4431
4459
  lines.push("");
4432
- lines.push(chalk11.bold("Summary"));
4460
+ lines.push(chalk10.bold("Summary"));
4433
4461
  lines.push(` Decisions: ${report.summary.activeDecisions} active / ${report.summary.totalDecisions} total`);
4434
4462
  lines.push(` Constraints: ${report.summary.totalConstraints}`);
4435
4463
  lines.push("");
4436
- lines.push(chalk11.bold("Violations"));
4464
+ lines.push(chalk10.bold("Violations"));
4437
4465
  const { violations } = report.summary;
4438
4466
  const violationParts = [];
4439
4467
  if (violations.critical > 0) {
4440
- violationParts.push(chalk11.red(`${violations.critical} critical`));
4468
+ violationParts.push(chalk10.red(`${violations.critical} critical`));
4441
4469
  }
4442
4470
  if (violations.high > 0) {
4443
- violationParts.push(chalk11.yellow(`${violations.high} high`));
4471
+ violationParts.push(chalk10.yellow(`${violations.high} high`));
4444
4472
  }
4445
4473
  if (violations.medium > 0) {
4446
- violationParts.push(chalk11.cyan(`${violations.medium} medium`));
4474
+ violationParts.push(chalk10.cyan(`${violations.medium} medium`));
4447
4475
  }
4448
4476
  if (violations.low > 0) {
4449
- violationParts.push(chalk11.dim(`${violations.low} low`));
4477
+ violationParts.push(chalk10.dim(`${violations.low} low`));
4450
4478
  }
4451
4479
  if (violationParts.length > 0) {
4452
4480
  lines.push(` ${violationParts.join(" | ")}`);
4453
4481
  } else {
4454
- lines.push(chalk11.green(" No violations"));
4482
+ lines.push(chalk10.green(" No violations"));
4455
4483
  }
4456
4484
  lines.push("");
4457
4485
  if (report.byDecision.length > 0) {
4458
- lines.push(chalk11.bold("By Decision"));
4486
+ lines.push(chalk10.bold("By Decision"));
4459
4487
  lines.push("");
4460
4488
  const tableData = [
4461
4489
  [
4462
- chalk11.bold("Decision"),
4463
- chalk11.bold("Status"),
4464
- chalk11.bold("Constraints"),
4465
- chalk11.bold("Violations"),
4466
- chalk11.bold("Compliance")
4490
+ chalk10.bold("Decision"),
4491
+ chalk10.bold("Status"),
4492
+ chalk10.bold("Constraints"),
4493
+ chalk10.bold("Violations"),
4494
+ chalk10.bold("Compliance")
4467
4495
  ]
4468
4496
  ];
4469
4497
  for (const dec of report.byDecision) {
@@ -4473,7 +4501,7 @@ function formatConsoleReport(report) {
4473
4501
  truncate2(dec.title, 40),
4474
4502
  statusColor(dec.status),
4475
4503
  String(dec.constraints),
4476
- dec.violations > 0 ? chalk11.red(String(dec.violations)) : chalk11.green("0"),
4504
+ dec.violations > 0 ? chalk10.red(String(dec.violations)) : chalk10.green("0"),
4477
4505
  compColor(`${dec.compliance}%`)
4478
4506
  ]);
4479
4507
  }
@@ -4507,23 +4535,23 @@ function formatComplianceBar(compliance) {
4507
4535
  return "\u2588".repeat(filled) + "\u2591".repeat(empty);
4508
4536
  }
4509
4537
  function getComplianceColor(compliance) {
4510
- if (compliance >= 90) return chalk11.green;
4511
- if (compliance >= 70) return chalk11.yellow;
4512
- if (compliance >= 50) return chalk11.hex("#FFA500");
4513
- 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;
4514
4542
  }
4515
4543
  function getStatusColor2(status) {
4516
4544
  switch (status) {
4517
4545
  case "active":
4518
- return chalk11.green;
4546
+ return chalk10.green;
4519
4547
  case "draft":
4520
- return chalk11.yellow;
4548
+ return chalk10.yellow;
4521
4549
  case "deprecated":
4522
- return chalk11.gray;
4550
+ return chalk10.gray;
4523
4551
  case "superseded":
4524
- return chalk11.blue;
4552
+ return chalk10.blue;
4525
4553
  default:
4526
- return chalk11.white;
4554
+ return chalk10.white;
4527
4555
  }
4528
4556
  }
4529
4557
  function truncate2(str, length) {
@@ -4597,6 +4625,7 @@ function formatProgressBar(percentage) {
4597
4625
  import { join as join9 } from "path";
4598
4626
  var ReportStorage = class {
4599
4627
  storageDir;
4628
+ logger = getLogger({ module: "reporting.storage" });
4600
4629
  constructor(basePath) {
4601
4630
  this.storageDir = join9(getSpecBridgeDir(basePath), "reports", "history");
4602
4631
  }
@@ -4655,7 +4684,7 @@ var ReportStorage = class {
4655
4684
  const timestamp = file.replace("report-", "").replace(".json", "");
4656
4685
  return { timestamp, report };
4657
4686
  } catch (error) {
4658
- console.warn(`Warning: Failed to load report ${file}:`, error);
4687
+ this.logger.warn({ file, error }, "Failed to load report file");
4659
4688
  return null;
4660
4689
  }
4661
4690
  });
@@ -4699,7 +4728,7 @@ var ReportStorage = class {
4699
4728
  const fs = await import("fs/promises");
4700
4729
  await fs.unlink(filepath);
4701
4730
  } catch (error) {
4702
- console.warn(`Warning: Failed to delete old report ${file}:`, error);
4731
+ this.logger.warn({ file, error }, "Failed to delete old report file");
4703
4732
  }
4704
4733
  }
4705
4734
  return filesToDelete.length;
@@ -4901,29 +4930,29 @@ var reportCommand = new Command10("report").description("Generate compliance rep
4901
4930
  const storage = new ReportStorage(cwd);
4902
4931
  await storage.save(report);
4903
4932
  if (options.trend) {
4904
- console.log("\n" + chalk12.blue.bold("=== Compliance Trend Analysis ===\n"));
4933
+ console.log("\n" + chalk11.blue.bold("=== Compliance Trend Analysis ===\n"));
4905
4934
  const days = parseInt(options.days || "30", 10);
4906
4935
  const history = await storage.loadHistory(days);
4907
4936
  if (history.length < 2) {
4908
- 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.`));
4909
4938
  } else {
4910
4939
  const trend = await analyzeTrend(history);
4911
- 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)`));
4912
4941
  console.log(`
4913
4942
  Overall Compliance: ${trend.overall.startCompliance}% \u2192 ${trend.overall.endCompliance}% (${trend.overall.change > 0 ? "+" : ""}${trend.overall.change.toFixed(1)}%)`);
4914
4943
  const trendEmoji = trend.overall.trend === "improving" ? "\u{1F4C8}" : trend.overall.trend === "degrading" ? "\u{1F4C9}" : "\u27A1\uFE0F";
4915
- 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;
4916
4945
  console.log(trendColor(`${trendEmoji} Trend: ${trend.overall.trend.toUpperCase()}`));
4917
4946
  const degrading = trend.decisions.filter((d) => d.trend === "degrading").slice(0, 3);
4918
4947
  if (degrading.length > 0) {
4919
- console.log(chalk12.red("\n\u26A0\uFE0F Most Degraded Decisions:"));
4948
+ console.log(chalk11.red("\n\u26A0\uFE0F Most Degraded Decisions:"));
4920
4949
  degrading.forEach((d) => {
4921
4950
  console.log(` \u2022 ${d.title}: ${d.startCompliance}% \u2192 ${d.endCompliance}% (${d.change.toFixed(1)}%)`);
4922
4951
  });
4923
4952
  }
4924
4953
  const improving = trend.decisions.filter((d) => d.trend === "improving").slice(0, 3);
4925
4954
  if (improving.length > 0) {
4926
- console.log(chalk12.green("\n\u2705 Most Improved Decisions:"));
4955
+ console.log(chalk11.green("\n\u2705 Most Improved Decisions:"));
4927
4956
  improving.forEach((d) => {
4928
4957
  console.log(` \u2022 ${d.title}: ${d.startCompliance}% \u2192 ${d.endCompliance}% (+${d.change.toFixed(1)}%)`);
4929
4958
  });
@@ -4932,26 +4961,26 @@ Overall Compliance: ${trend.overall.startCompliance}% \u2192 ${trend.overall.end
4932
4961
  console.log("");
4933
4962
  }
4934
4963
  if (options.drift) {
4935
- console.log("\n" + chalk12.blue.bold("=== Drift Analysis ===\n"));
4964
+ console.log("\n" + chalk11.blue.bold("=== Drift Analysis ===\n"));
4936
4965
  const history = await storage.loadHistory(2);
4937
4966
  if (history.length < 2) {
4938
- 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."));
4939
4968
  } else {
4940
4969
  const currentEntry = history[0];
4941
4970
  const previousEntry = history[1];
4942
4971
  if (!currentEntry || !previousEntry) {
4943
- console.log(chalk12.yellow("Invalid history data."));
4972
+ console.log(chalk11.yellow("Invalid history data."));
4944
4973
  return;
4945
4974
  }
4946
4975
  const drift = await detectDrift(currentEntry.report, previousEntry.report);
4947
- console.log(chalk12.bold(`Comparing: ${previousEntry.timestamp} vs ${currentEntry.timestamp}`));
4976
+ console.log(chalk11.bold(`Comparing: ${previousEntry.timestamp} vs ${currentEntry.timestamp}`));
4948
4977
  console.log(`
4949
4978
  Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceChange.toFixed(1)}%`);
4950
4979
  const driftEmoji = drift.trend === "improving" ? "\u{1F4C8}" : drift.trend === "degrading" ? "\u{1F4C9}" : "\u27A1\uFE0F";
4951
- 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;
4952
4981
  console.log(driftColor(`${driftEmoji} Overall Trend: ${drift.trend.toUpperCase()}`));
4953
4982
  if (drift.summary.newViolations.total > 0) {
4954
- console.log(chalk12.red(`
4983
+ console.log(chalk11.red(`
4955
4984
  \u26A0\uFE0F New Violations: ${drift.summary.newViolations.total}`));
4956
4985
  if (drift.summary.newViolations.critical > 0) {
4957
4986
  console.log(` \u2022 Critical: ${drift.summary.newViolations.critical}`);
@@ -4967,7 +4996,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4967
4996
  }
4968
4997
  }
4969
4998
  if (drift.summary.fixedViolations.total > 0) {
4970
- console.log(chalk12.green(`
4999
+ console.log(chalk11.green(`
4971
5000
  \u2705 Fixed Violations: ${drift.summary.fixedViolations.total}`));
4972
5001
  if (drift.summary.fixedViolations.critical > 0) {
4973
5002
  console.log(` \u2022 Critical: ${drift.summary.fixedViolations.critical}`);
@@ -4983,7 +5012,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4983
5012
  }
4984
5013
  }
4985
5014
  if (drift.mostDegraded.length > 0) {
4986
- console.log(chalk12.red("\n\u{1F4C9} Most Degraded:"));
5015
+ console.log(chalk11.red("\n\u{1F4C9} Most Degraded:"));
4987
5016
  drift.mostDegraded.forEach((d) => {
4988
5017
  console.log(` \u2022 ${d.title}: ${d.previousCompliance}% \u2192 ${d.currentCompliance}% (${d.complianceChange.toFixed(1)}%)`);
4989
5018
  if (d.newViolations > 0) {
@@ -4992,7 +5021,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
4992
5021
  });
4993
5022
  }
4994
5023
  if (drift.mostImproved.length > 0) {
4995
- console.log(chalk12.green("\n\u{1F4C8} Most Improved:"));
5024
+ console.log(chalk11.green("\n\u{1F4C8} Most Improved:"));
4996
5025
  drift.mostImproved.forEach((d) => {
4997
5026
  console.log(` \u2022 ${d.title}: ${d.previousCompliance}% \u2192 ${d.currentCompliance}% (+${d.complianceChange.toFixed(1)}%)`);
4998
5027
  if (d.fixedViolations > 0) {
@@ -5032,7 +5061,7 @@ Compliance Change: ${drift.complianceChange > 0 ? "+" : ""}${drift.complianceCha
5032
5061
  `health-${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}.${extension}`
5033
5062
  );
5034
5063
  await writeTextFile(outputPath, output);
5035
- console.log(chalk12.green(`
5064
+ console.log(chalk11.green(`
5036
5065
  Report saved to: ${outputPath}`));
5037
5066
  if (options.save && !options.output) {
5038
5067
  const latestPath = join10(getReportsDir(cwd), `health-latest.${extension}`);
@@ -5047,7 +5076,7 @@ Report saved to: ${outputPath}`));
5047
5076
 
5048
5077
  // src/cli/commands/context.ts
5049
5078
  import { Command as Command11 } from "commander";
5050
- import chalk13 from "chalk";
5079
+ import chalk12 from "chalk";
5051
5080
 
5052
5081
  // src/agent/context.generator.ts
5053
5082
  async function generateContext(filePath, config, options = {}) {
@@ -5167,12 +5196,12 @@ var contextCommand = new Command11("context").description("Generate architectura
5167
5196
  });
5168
5197
  if (options.output) {
5169
5198
  await writeTextFile(options.output, output);
5170
- console.log(chalk13.green(`Context saved to: ${options.output}`));
5199
+ console.log(chalk12.green(`Context saved to: ${options.output}`));
5171
5200
  } else {
5172
5201
  console.log(output);
5173
5202
  }
5174
5203
  } catch (error) {
5175
- console.error(chalk13.red("Failed to generate context"));
5204
+ console.error(chalk12.red("Failed to generate context"));
5176
5205
  throw error;
5177
5206
  }
5178
5207
  });
@@ -5186,7 +5215,7 @@ import { TextDocument } from "vscode-languageserver-textdocument";
5186
5215
  import { fileURLToPath } from "url";
5187
5216
  import path3 from "path";
5188
5217
  import { Project as Project3 } from "ts-morph";
5189
- import chalk14 from "chalk";
5218
+ import chalk13 from "chalk";
5190
5219
  function severityToDiagnostic(severity) {
5191
5220
  switch (severity) {
5192
5221
  case "critical":
@@ -5297,7 +5326,7 @@ var SpecBridgeLspServer = class {
5297
5326
  if (!await pathExists(getSpecBridgeDir(this.cwd))) {
5298
5327
  const err = new NotInitializedError();
5299
5328
  this.initError = err.message;
5300
- 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));
5301
5330
  return;
5302
5331
  }
5303
5332
  try {
@@ -5306,7 +5335,7 @@ var SpecBridgeLspServer = class {
5306
5335
  await getPluginLoader().loadPlugins(this.cwd);
5307
5336
  } catch (error) {
5308
5337
  const msg = error instanceof Error ? error.message : String(error);
5309
- 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}`));
5310
5339
  }
5311
5340
  this.registry = createRegistry({ basePath: this.cwd });
5312
5341
  await this.registry.load();
@@ -5319,11 +5348,11 @@ var SpecBridgeLspServer = class {
5319
5348
  }
5320
5349
  }
5321
5350
  if (this.options.verbose) {
5322
- 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)`));
5323
5352
  }
5324
5353
  } catch (error) {
5325
5354
  this.initError = error instanceof Error ? error.message : String(error);
5326
- 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));
5327
5356
  }
5328
5357
  }
5329
5358
  async verifyTextDocument(doc) {
@@ -5395,7 +5424,7 @@ var lspCommand = new Command12("lsp").description("Start SpecBridge language ser
5395
5424
 
5396
5425
  // src/cli/commands/watch.ts
5397
5426
  import { Command as Command13 } from "commander";
5398
- import chalk15 from "chalk";
5427
+ import chalk14 from "chalk";
5399
5428
  import chokidar from "chokidar";
5400
5429
  import path4 from "path";
5401
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) => {
@@ -5416,15 +5445,15 @@ var watchCommand = new Command13("watch").description("Watch for changes and ver
5416
5445
  files: [absolutePath],
5417
5446
  cwd
5418
5447
  });
5419
- const prefix = result.success ? chalk15.green("\u2713") : chalk15.red("\u2717");
5448
+ const prefix = result.success ? chalk14.green("\u2713") : chalk14.red("\u2717");
5420
5449
  const summary = `${prefix} ${path4.relative(cwd, absolutePath)}: ${result.violations.length} violation(s)`;
5421
5450
  console.log(summary);
5422
5451
  for (const v of result.violations.slice(0, 20)) {
5423
5452
  const loc = v.line ? `:${v.line}${v.column ? `:${v.column}` : ""}` : "";
5424
- console.log(chalk15.dim(` - ${v.file}${loc}: ${v.message} [${v.severity}]`));
5453
+ console.log(chalk14.dim(` - ${v.file}${loc}: ${v.message} [${v.severity}]`));
5425
5454
  }
5426
5455
  if (result.violations.length > 20) {
5427
- console.log(chalk15.dim(` \u2026 ${result.violations.length - 20} more`));
5456
+ console.log(chalk14.dim(` \u2026 ${result.violations.length - 20} more`));
5428
5457
  }
5429
5458
  };
5430
5459
  const watcher = chokidar.watch(config.project.sourceRoots, {
@@ -5433,7 +5462,7 @@ var watchCommand = new Command13("watch").description("Watch for changes and ver
5433
5462
  ignoreInitial: true,
5434
5463
  persistent: true
5435
5464
  });
5436
- console.log(chalk15.blue("Watching for changes..."));
5465
+ console.log(chalk14.blue("Watching for changes..."));
5437
5466
  watcher.on("change", (changedPath) => {
5438
5467
  pendingPath = changedPath;
5439
5468
  if (timer) clearTimeout(timer);
@@ -5725,7 +5754,7 @@ var promptCommand = new Command15("prompt").description("Generate AI agent promp
5725
5754
 
5726
5755
  // src/cli/commands/analytics.ts
5727
5756
  import { Command as Command16 } from "commander";
5728
- import chalk16 from "chalk";
5757
+ import chalk15 from "chalk";
5729
5758
  import ora7 from "ora";
5730
5759
 
5731
5760
  // src/analytics/engine.ts
@@ -5954,7 +5983,7 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5954
5983
  const history = await storage.loadHistory(days);
5955
5984
  if (history.length === 0) {
5956
5985
  spinner.fail("No historical reports found");
5957
- console.log(chalk16.yellow("\nGenerate reports with: specbridge report"));
5986
+ console.log(chalk15.yellow("\nGenerate reports with: specbridge report"));
5958
5987
  return;
5959
5988
  }
5960
5989
  spinner.succeed(`Loaded ${history.length} historical report(s)`);
@@ -5971,17 +6000,17 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5971
6000
  }
5972
6001
  if (decisionId) {
5973
6002
  const metrics = await engine.analyzeDecision(decisionId, history);
5974
- console.log("\n" + chalk16.blue.bold(`=== Decision Analytics: ${metrics.title} ===
6003
+ console.log("\n" + chalk15.blue.bold(`=== Decision Analytics: ${metrics.title} ===
5975
6004
  `));
5976
- console.log(chalk16.bold("Overview:"));
6005
+ console.log(chalk15.bold("Overview:"));
5977
6006
  console.log(` ID: ${metrics.decisionId}`);
5978
6007
  console.log(` Current Violations: ${metrics.totalViolations}`);
5979
6008
  console.log(` Average Compliance: ${metrics.averageComplianceScore.toFixed(1)}%`);
5980
6009
  const trendEmoji = metrics.trendDirection === "up" ? "\u{1F4C8}" : metrics.trendDirection === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
5981
- 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;
5982
6011
  console.log(` ${trendColor(`${trendEmoji} Trend: ${metrics.trendDirection.toUpperCase()}`)}`);
5983
6012
  if (metrics.history.length > 0) {
5984
- console.log(chalk16.bold("\nCompliance History:"));
6013
+ console.log(chalk15.bold("\nCompliance History:"));
5985
6014
  const recentHistory = metrics.history.slice(-10);
5986
6015
  recentHistory.forEach((h) => {
5987
6016
  const icon = h.violations === 0 ? "\u2705" : "\u26A0\uFE0F";
@@ -5990,58 +6019,58 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
5990
6019
  }
5991
6020
  } else {
5992
6021
  const summary = await engine.generateSummary(history);
5993
- console.log("\n" + chalk16.blue.bold("=== Overall Analytics ===\n"));
5994
- console.log(chalk16.bold("Summary:"));
6022
+ console.log("\n" + chalk15.blue.bold("=== Overall Analytics ===\n"));
6023
+ console.log(chalk15.bold("Summary:"));
5995
6024
  console.log(` Total Decisions: ${summary.totalDecisions}`);
5996
6025
  console.log(` Average Compliance: ${summary.averageCompliance}%`);
5997
6026
  console.log(` Critical Issues: ${summary.criticalIssues}`);
5998
6027
  const trendEmoji = summary.overallTrend === "up" ? "\u{1F4C8}" : summary.overallTrend === "down" ? "\u{1F4C9}" : "\u27A1\uFE0F";
5999
- 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;
6000
6029
  console.log(` ${trendColor(`${trendEmoji} Overall Trend: ${summary.overallTrend.toUpperCase()}`)}`);
6001
6030
  if (summary.topDecisions.length > 0) {
6002
- console.log(chalk16.green("\n\u2705 Top Performing Decisions:"));
6031
+ console.log(chalk15.green("\n\u2705 Top Performing Decisions:"));
6003
6032
  summary.topDecisions.forEach((d, i) => {
6004
6033
  console.log(` ${i + 1}. ${d.title}: ${d.compliance}%`);
6005
6034
  });
6006
6035
  }
6007
6036
  if (summary.bottomDecisions.length > 0) {
6008
- console.log(chalk16.red("\n\u26A0\uFE0F Decisions Needing Attention:"));
6037
+ console.log(chalk15.red("\n\u26A0\uFE0F Decisions Needing Attention:"));
6009
6038
  summary.bottomDecisions.forEach((d, i) => {
6010
6039
  console.log(` ${i + 1}. ${d.title}: ${d.compliance}%`);
6011
6040
  });
6012
6041
  }
6013
6042
  if (options.insights || summary.criticalIssues > 0) {
6014
- console.log(chalk16.blue.bold("\n=== Insights ===\n"));
6043
+ console.log(chalk15.blue.bold("\n=== Insights ===\n"));
6015
6044
  const insights = summary.insights;
6016
6045
  const warnings = insights.filter((i) => i.type === "warning");
6017
6046
  const successes = insights.filter((i) => i.type === "success");
6018
6047
  const infos = insights.filter((i) => i.type === "info");
6019
6048
  if (warnings.length > 0) {
6020
- console.log(chalk16.red("\u26A0\uFE0F Warnings:"));
6049
+ console.log(chalk15.red("\u26A0\uFE0F Warnings:"));
6021
6050
  warnings.forEach((i) => {
6022
6051
  console.log(` \u2022 ${i.message}`);
6023
6052
  if (i.details) {
6024
- console.log(chalk16.gray(` ${i.details}`));
6053
+ console.log(chalk15.gray(` ${i.details}`));
6025
6054
  }
6026
6055
  });
6027
6056
  console.log("");
6028
6057
  }
6029
6058
  if (successes.length > 0) {
6030
- console.log(chalk16.green("\u2705 Positive Trends:"));
6059
+ console.log(chalk15.green("\u2705 Positive Trends:"));
6031
6060
  successes.forEach((i) => {
6032
6061
  console.log(` \u2022 ${i.message}`);
6033
6062
  if (i.details) {
6034
- console.log(chalk16.gray(` ${i.details}`));
6063
+ console.log(chalk15.gray(` ${i.details}`));
6035
6064
  }
6036
6065
  });
6037
6066
  console.log("");
6038
6067
  }
6039
6068
  if (infos.length > 0) {
6040
- console.log(chalk16.blue("\u{1F4A1} Suggestions:"));
6069
+ console.log(chalk15.blue("\u{1F4A1} Suggestions:"));
6041
6070
  infos.forEach((i) => {
6042
6071
  console.log(` \u2022 ${i.message}`);
6043
6072
  if (i.details) {
6044
- console.log(chalk16.gray(` ${i.details}`));
6073
+ console.log(chalk15.gray(` ${i.details}`));
6045
6074
  }
6046
6075
  });
6047
6076
  console.log("");
@@ -6051,10 +6080,10 @@ var analyticsCommand = new Command16("analytics").description("Analyze complianc
6051
6080
  const latestEntry = history[history.length - 1];
6052
6081
  const oldestEntry = history[0];
6053
6082
  if (latestEntry && oldestEntry) {
6054
- console.log(chalk16.gray(`
6083
+ console.log(chalk15.gray(`
6055
6084
  Data range: ${latestEntry.timestamp} to ${oldestEntry.timestamp}`));
6056
6085
  }
6057
- 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
6058
6087
  `));
6059
6088
  } catch (error) {
6060
6089
  spinner.fail("Analytics failed");
@@ -6064,7 +6093,7 @@ Data range: ${latestEntry.timestamp} to ${oldestEntry.timestamp}`));
6064
6093
 
6065
6094
  // src/cli/commands/dashboard.ts
6066
6095
  import { Command as Command17 } from "commander";
6067
- import chalk17 from "chalk";
6096
+ import chalk16 from "chalk";
6068
6097
 
6069
6098
  // src/dashboard/server.ts
6070
6099
  import express from "express";
@@ -6083,6 +6112,7 @@ var DashboardServer = class {
6083
6112
  CACHE_TTL = 6e4;
6084
6113
  // 1 minute
6085
6114
  refreshInterval = null;
6115
+ logger = getLogger({ module: "dashboard.server" });
6086
6116
  constructor(options) {
6087
6117
  this.cwd = options.cwd;
6088
6118
  this.config = options.config;
@@ -6099,7 +6129,11 @@ var DashboardServer = class {
6099
6129
  await this.registry.load();
6100
6130
  await this.refreshCache();
6101
6131
  this.refreshInterval = setInterval(
6102
- () => this.refreshCache().catch(console.error),
6132
+ () => {
6133
+ void this.refreshCache().catch((error) => {
6134
+ this.logger.error({ error }, "Background cache refresh failed");
6135
+ });
6136
+ },
6103
6137
  this.CACHE_TTL
6104
6138
  );
6105
6139
  }
@@ -6122,7 +6156,7 @@ var DashboardServer = class {
6122
6156
  this.cacheTimestamp = Date.now();
6123
6157
  await this.reportStorage.save(report);
6124
6158
  } catch (error) {
6125
- console.error("Cache refresh failed:", error);
6159
+ this.logger.error({ error }, "Cache refresh failed");
6126
6160
  if (!this.cachedReport) {
6127
6161
  try {
6128
6162
  const stored = await this.reportStorage.loadLatest();
@@ -6130,7 +6164,7 @@ var DashboardServer = class {
6130
6164
  this.cachedReport = stored.report;
6131
6165
  }
6132
6166
  } catch (fallbackError) {
6133
- console.error("Failed to load fallback report:", fallbackError);
6167
+ this.logger.error({ error: fallbackError }, "Failed to load fallback report");
6134
6168
  }
6135
6169
  }
6136
6170
  }
@@ -6393,7 +6427,7 @@ var dashboardCommand = new Command17("dashboard").description("Start compliance
6393
6427
  if (!await pathExists(getSpecBridgeDir(cwd))) {
6394
6428
  throw new NotInitializedError();
6395
6429
  }
6396
- console.log(chalk17.blue("Starting SpecBridge dashboard..."));
6430
+ console.log(chalk16.blue("Starting SpecBridge dashboard..."));
6397
6431
  try {
6398
6432
  const config = await loadConfig(cwd);
6399
6433
  const server = createDashboardServer({ cwd, config });
@@ -6401,32 +6435,32 @@ var dashboardCommand = new Command17("dashboard").description("Start compliance
6401
6435
  const port = parseInt(options.port || "3000", 10);
6402
6436
  const host = options.host || "localhost";
6403
6437
  server.getApp().listen(port, host, () => {
6404
- console.log(chalk17.green(`
6438
+ console.log(chalk16.green(`
6405
6439
  \u2713 Dashboard running at http://${host}:${port}`));
6406
- console.log(chalk17.gray(" Press Ctrl+C to stop\n"));
6407
- console.log(chalk17.bold("API Endpoints:"));
6408
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/health`)} - Health check`);
6409
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/report/latest`)} - Latest report (cached)`);
6410
- console.log(` ${chalk17.cyan(`http://${host}:${port}/api/decisions`)} - All decisions`);
6411
- 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`);
6412
6446
  console.log("");
6413
6447
  });
6414
6448
  const shutdown = () => {
6415
- console.log(chalk17.yellow("\n\nShutting down dashboard..."));
6449
+ console.log(chalk16.yellow("\n\nShutting down dashboard..."));
6416
6450
  server.stop();
6417
6451
  process.exit(0);
6418
6452
  };
6419
6453
  process.on("SIGINT", shutdown);
6420
6454
  process.on("SIGTERM", shutdown);
6421
6455
  } catch (error) {
6422
- console.error(chalk17.red("Failed to start dashboard:"), error);
6456
+ console.error(chalk16.red("Failed to start dashboard:"), error);
6423
6457
  throw error;
6424
6458
  }
6425
6459
  });
6426
6460
 
6427
6461
  // src/cli/commands/impact.ts
6428
6462
  import { Command as Command18 } from "commander";
6429
- import chalk18 from "chalk";
6463
+ import chalk17 from "chalk";
6430
6464
  import ora8 from "ora";
6431
6465
 
6432
6466
  // src/propagation/graph.ts
@@ -6513,7 +6547,24 @@ var PropagationEngine = class {
6513
6547
  if (!this.graph) {
6514
6548
  await this.initialize(config, options);
6515
6549
  }
6516
- 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);
6517
6568
  const verificationEngine = createVerificationEngine(this.registry);
6518
6569
  const result = await verificationEngine.verify(config, {
6519
6570
  files: affectedFilePaths,
@@ -6637,8 +6688,8 @@ var impactCommand = new Command18("impact").description("Analyze impact of decis
6637
6688
  const changeType = options.change || "modified";
6638
6689
  if (!["created", "modified", "deprecated"].includes(changeType)) {
6639
6690
  spinner.fail();
6640
- console.error(chalk18.red(`Invalid change type: ${changeType}`));
6641
- 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"));
6642
6693
  process.exit(1);
6643
6694
  }
6644
6695
  spinner.text = `Analyzing impact of ${changeType} decision ${decisionId}...`;
@@ -6656,44 +6707,44 @@ var impactCommand = new Command18("impact").description("Analyze impact of decis
6656
6707
  }
6657
6708
  });
6658
6709
  function printImpactAnalysis(analysis, showSteps) {
6659
- console.log(chalk18.bold(`
6710
+ console.log(chalk17.bold(`
6660
6711
  === Impact Analysis: ${analysis.decision} ===
6661
6712
  `));
6662
- const changeLabel = chalk18.cyan(analysis.change);
6713
+ const changeLabel = chalk17.cyan(analysis.change);
6663
6714
  console.log(`Change Type: ${changeLabel}`);
6664
- 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;
6665
6716
  console.log(`Estimated Effort: ${effortColor(analysis.estimatedEffort.toUpperCase())}
6666
6717
  `);
6667
- console.log(chalk18.bold(`Affected Files: ${analysis.affectedFiles.length}`));
6718
+ console.log(chalk17.bold(`Affected Files: ${analysis.affectedFiles.length}`));
6668
6719
  if (analysis.affectedFiles.length > 0) {
6669
6720
  const displayCount = Math.min(analysis.affectedFiles.length, 10);
6670
6721
  for (let i = 0; i < displayCount; i++) {
6671
6722
  const file = analysis.affectedFiles[i];
6672
6723
  if (!file) continue;
6673
6724
  const violationText = file.violations === 1 ? "1 violation" : `${file.violations} violations`;
6674
- const autoFixText = file.autoFixable > 0 ? chalk18.green(` (${file.autoFixable} auto-fixable)`) : "";
6675
- 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}`);
6676
6727
  }
6677
6728
  if (analysis.affectedFiles.length > displayCount) {
6678
6729
  const remaining = analysis.affectedFiles.length - displayCount;
6679
- console.log(chalk18.dim(` ... and ${remaining} more file(s)`));
6730
+ console.log(chalk17.dim(` ... and ${remaining} more file(s)`));
6680
6731
  }
6681
6732
  } else {
6682
- console.log(chalk18.green(" No violations found"));
6733
+ console.log(chalk17.green(" No violations found"));
6683
6734
  }
6684
6735
  if (showSteps && analysis.migrationSteps && analysis.migrationSteps.length > 0) {
6685
- console.log(chalk18.bold("\nMigration Plan:"));
6736
+ console.log(chalk17.bold("\nMigration Plan:"));
6686
6737
  for (const step of analysis.migrationSteps) {
6687
6738
  const icon = step.automated ? "\u{1F916}" : "\u{1F464}";
6688
- const typeLabel = step.automated ? chalk18.green("[Automated]") : chalk18.yellow("[Manual]");
6739
+ const typeLabel = step.automated ? chalk17.green("[Automated]") : chalk17.yellow("[Manual]");
6689
6740
  console.log(` ${icon} Step ${step.order}: ${step.description} ${typeLabel}`);
6690
6741
  if (step.files.length > 0) {
6691
6742
  const displayFiles = Math.min(step.files.length, 3);
6692
6743
  for (let i = 0; i < displayFiles; i++) {
6693
- console.log(chalk18.dim(` - ${step.files[i]}`));
6744
+ console.log(chalk17.dim(` - ${step.files[i]}`));
6694
6745
  }
6695
6746
  if (step.files.length > displayFiles) {
6696
- 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)`));
6697
6748
  }
6698
6749
  }
6699
6750
  console.log("");
@@ -6702,15 +6753,15 @@ function printImpactAnalysis(analysis, showSteps) {
6702
6753
  const totalViolations = analysis.affectedFiles.reduce((sum, f) => sum + f.violations, 0);
6703
6754
  const totalAutoFixable = analysis.affectedFiles.reduce((sum, f) => sum + f.autoFixable, 0);
6704
6755
  const manualFixes = totalViolations - totalAutoFixable;
6705
- console.log(chalk18.bold("Summary:"));
6756
+ console.log(chalk17.bold("Summary:"));
6706
6757
  console.log(` Total Violations: ${totalViolations}`);
6707
- console.log(` Auto-fixable: ${chalk18.green(totalAutoFixable)}`);
6708
- 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)}`);
6709
6760
  }
6710
6761
 
6711
6762
  // src/cli/commands/migrate.ts
6712
6763
  import { Command as Command19 } from "commander";
6713
- import chalk19 from "chalk";
6764
+ import chalk18 from "chalk";
6714
6765
  import ora9 from "ora";
6715
6766
  import { join as join13 } from "path";
6716
6767
  import { readdir as readdir2, copyFile, mkdir as mkdir2, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
@@ -6721,17 +6772,17 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6721
6772
  }
6722
6773
  const from = options.from || "v1";
6723
6774
  const to = options.to || "v2";
6724
- console.log(chalk19.blue.bold(`
6775
+ console.log(chalk18.blue.bold(`
6725
6776
  === SpecBridge Migration: ${from} \u2192 ${to} ===
6726
6777
  `));
6727
6778
  if (from !== "v1" && from !== "v1.3") {
6728
- console.error(chalk19.red(`Unsupported source version: ${from}`));
6729
- 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"));
6730
6781
  process.exit(1);
6731
6782
  }
6732
6783
  if (to !== "v2" && to !== "v2.0") {
6733
- console.error(chalk19.red(`Unsupported target version: ${to}`));
6734
- 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"));
6735
6786
  process.exit(1);
6736
6787
  }
6737
6788
  const spinner = ora9("Analyzing current configuration...").start();
@@ -6751,7 +6802,7 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6751
6802
  const config = await loadConfig(cwd);
6752
6803
  const v1Report = await generateReport(config, { cwd, legacyCompliance: true });
6753
6804
  v1Compliance = v1Report.summary.compliance;
6754
- } catch (error) {
6805
+ } catch {
6755
6806
  spinner.warn("Could not generate v1 baseline report");
6756
6807
  }
6757
6808
  spinner.text = "Migrating decision files...";
@@ -6773,7 +6824,7 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6773
6824
  v2: v2Compliance,
6774
6825
  difference: v2Compliance - v1Compliance
6775
6826
  };
6776
- } catch (error) {
6827
+ } catch {
6777
6828
  spinner.warn("Could not generate v2 comparison report");
6778
6829
  }
6779
6830
  }
@@ -6782,41 +6833,41 @@ var migrateCommand = new Command19("migrate").description("Migrate SpecBridge co
6782
6833
  report.changes.push("All decisions validated successfully");
6783
6834
  }
6784
6835
  spinner.succeed(options.dryRun ? "Migration preview complete" : "Migration complete");
6785
- console.log(chalk19.green.bold("\n\u2713 Migration Summary:\n"));
6786
- console.log(chalk19.bold("Backup:"));
6836
+ console.log(chalk18.green.bold("\n\u2713 Migration Summary:\n"));
6837
+ console.log(chalk18.bold("Backup:"));
6787
6838
  console.log(` ${report.backupPath}`);
6788
6839
  console.log("");
6789
- console.log(chalk19.bold("Changes:"));
6840
+ console.log(chalk18.bold("Changes:"));
6790
6841
  for (const change of report.changes) {
6791
6842
  console.log(` \u2022 ${change}`);
6792
6843
  }
6793
6844
  console.log("");
6794
6845
  if (report.complianceComparison) {
6795
- console.log(chalk19.bold("Compliance Comparison:"));
6846
+ console.log(chalk18.bold("Compliance Comparison:"));
6796
6847
  console.log(` v1.3 formula: ${report.complianceComparison.v1}%`);
6797
6848
  console.log(` v2.0 formula: ${report.complianceComparison.v2}%`);
6798
6849
  const diff = report.complianceComparison.difference;
6799
- 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;
6800
6851
  console.log(` Difference: ${diffColor(`${diff > 0 ? "+" : ""}${diff.toFixed(1)}%`)}`);
6801
6852
  console.log("");
6802
6853
  if (Math.abs(diff) > 10) {
6803
- console.log(chalk19.yellow("\u26A0\uFE0F Note: Compliance score changed significantly due to severity weighting."));
6804
- 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"));
6805
6856
  }
6806
6857
  }
6807
6858
  if (options.dryRun) {
6808
- console.log(chalk19.yellow("This was a dry run. No changes were applied."));
6809
- 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"));
6810
6861
  } else {
6811
- console.log(chalk19.green("\u2713 Migration successful!"));
6812
- console.log(chalk19.gray(`
6862
+ console.log(chalk18.green("\u2713 Migration successful!"));
6863
+ console.log(chalk18.gray(`
6813
6864
  Rollback: Copy files from ${report.backupPath} back to .specbridge/decisions/
6814
6865
  `));
6815
6866
  }
6816
6867
  } catch (error) {
6817
6868
  spinner.fail("Migration failed");
6818
- console.error(chalk19.red("\nError:"), error instanceof Error ? error.message : error);
6819
- 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."));
6820
6871
  throw error;
6821
6872
  }
6822
6873
  });
@@ -6863,7 +6914,7 @@ async function migrateDecisions(cwd, dryRun) {
6863
6914
  "$1check:\n$1 verifier: $2"
6864
6915
  );
6865
6916
  if (dryRun) {
6866
- console.log(chalk19.gray(` Would migrate: ${file}`));
6917
+ console.log(chalk18.gray(` Would migrate: ${file}`));
6867
6918
  updatedCount++;
6868
6919
  } else {
6869
6920
  await writeFile3(filePath, migratedContent, "utf-8");
@@ -6901,11 +6952,11 @@ program.exitOverride((err) => {
6901
6952
  if (err.code === "commander.version") {
6902
6953
  process.exit(0);
6903
6954
  }
6904
- console.error(chalk20.red(formatError(err)));
6955
+ console.error(chalk19.red(formatError(err)));
6905
6956
  process.exit(1);
6906
6957
  });
6907
6958
  program.parseAsync(process.argv).catch((error) => {
6908
- console.error(chalk20.red(formatError(error)));
6959
+ console.error(chalk19.red(formatError(error)));
6909
6960
  process.exit(1);
6910
6961
  });
6911
6962
  //# sourceMappingURL=cli.js.map