@contractspec/bundle.workspace 4.0.3 → 4.1.2

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.
@@ -2,8 +2,8 @@
2
2
  * Adapter for UnifiedAgent to work with Workspace AgentOrchestrator.
3
3
  */
4
4
  import { type UnifiedAgentConfig } from '@contractspec/lib.ai-agent/agent/unified-agent';
5
- import type { AgentSpec } from '@contractspec/lib.ai-agent/spec';
6
5
  import type { AgentMode } from '@contractspec/lib.contracts-spec';
6
+ import type { AgentSpec } from '@contractspec/lib.contracts-spec/agent';
7
7
  import type { AgentProvider, AgentResult, AgentTask } from './types';
8
8
  export declare class UnifiedAgentAdapter implements AgentProvider {
9
9
  readonly name: AgentMode;
package/dist/index.js CHANGED
@@ -397,7 +397,6 @@ var DEFAULT_FS_IGNORES = [
397
397
  "**/*.d.ts",
398
398
  "**/importer/**",
399
399
  "**/exporter/**",
400
- "**/docs/**/*.docblock.ts",
401
400
  "**/docs/presentations.ts"
402
401
  ];
403
402
 
@@ -4349,6 +4348,93 @@ async function runDepsChecks(adapters, options) {
4349
4348
  }
4350
4349
  return issues;
4351
4350
  }
4351
+ // src/services/docs/docblock-audit.ts
4352
+ import {
4353
+ analyzePackageDocBlocks
4354
+ } from "@contractspec/module.workspace";
4355
+ var PACKAGE_GLOB_IGNORES = [
4356
+ "**/node_modules/**",
4357
+ "**/dist/**",
4358
+ "**/.turbo/**",
4359
+ "**/.next/**"
4360
+ ];
4361
+ async function discoverWorkspaceDocPackages(fs5, workspaceRoot) {
4362
+ const packageJsonFiles = await fs5.glob({
4363
+ pattern: "packages/**/package.json",
4364
+ cwd: workspaceRoot,
4365
+ ignore: PACKAGE_GLOB_IGNORES
4366
+ });
4367
+ const discovered = new Map;
4368
+ for (const packageJsonFile of packageJsonFiles) {
4369
+ const packageRoot = fs5.dirname(packageJsonFile);
4370
+ const srcRoot = fs5.join(packageRoot, "src");
4371
+ if (!await fs5.exists(srcRoot)) {
4372
+ continue;
4373
+ }
4374
+ try {
4375
+ const packageJson = JSON.parse(await fs5.readFile(packageJsonFile));
4376
+ discovered.set(packageRoot, {
4377
+ packageName: packageJson.name ?? fs5.relative(workspaceRoot, packageRoot),
4378
+ packageRoot,
4379
+ srcRoot
4380
+ });
4381
+ } catch {
4382
+ continue;
4383
+ }
4384
+ }
4385
+ const rootPackageJson = fs5.join(workspaceRoot, "package.json");
4386
+ const rootSrc = fs5.join(workspaceRoot, "src");
4387
+ if (await fs5.exists(rootPackageJson) && await fs5.exists(rootSrc)) {
4388
+ try {
4389
+ const packageJson = JSON.parse(await fs5.readFile(rootPackageJson));
4390
+ discovered.set(workspaceRoot, {
4391
+ packageName: packageJson.name ?? workspaceRoot,
4392
+ packageRoot: workspaceRoot,
4393
+ srcRoot: rootSrc
4394
+ });
4395
+ } catch {}
4396
+ }
4397
+ return [...discovered.values()].sort((left, right) => left.packageRoot.localeCompare(right.packageRoot));
4398
+ }
4399
+ async function analyzeWorkspaceDocBlocks(fs5, workspaceRoot) {
4400
+ const diagnostics = [];
4401
+ const packages = await discoverWorkspaceDocPackages(fs5, workspaceRoot);
4402
+ for (const pkg of packages) {
4403
+ const result = analyzePackageDocBlocks({
4404
+ packageName: pkg.packageName,
4405
+ srcRoot: pkg.srcRoot
4406
+ });
4407
+ for (const diagnostic of result.diagnostics) {
4408
+ diagnostics.push({
4409
+ ...diagnostic,
4410
+ packageName: pkg.packageName,
4411
+ packageRoot: pkg.packageRoot,
4412
+ srcRoot: pkg.srcRoot
4413
+ });
4414
+ }
4415
+ }
4416
+ return diagnostics;
4417
+ }
4418
+
4419
+ // src/services/ci-check/checks/docs.ts
4420
+ async function runDocsChecks(adapters, options) {
4421
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
4422
+ const diagnostics = await analyzeWorkspaceDocBlocks(adapters.fs, workspaceRoot);
4423
+ return diagnostics.map((diagnostic) => ({
4424
+ ruleId: diagnostic.ruleId,
4425
+ severity: diagnostic.severity === "warning" ? "warning" : "error",
4426
+ message: diagnostic.message,
4427
+ category: "docs",
4428
+ file: diagnostic.file,
4429
+ line: diagnostic.line,
4430
+ column: diagnostic.column,
4431
+ context: {
4432
+ packageName: diagnostic.packageName,
4433
+ packageRoot: diagnostic.packageRoot,
4434
+ ...diagnostic.context
4435
+ }
4436
+ }));
4437
+ }
4352
4438
  // src/services/doctor/checks/ai.ts
4353
4439
  async function runAiChecks(fs5, ctx, prompts) {
4354
4440
  const results = [];
@@ -4627,7 +4713,7 @@ function generateContractsrcConfig(options) {
4627
4713
  type: "biome"
4628
4714
  },
4629
4715
  ci: {
4630
- checks: ["structure", "integrity", "deps", "doctor", "policy"],
4716
+ checks: ["structure", "integrity", "deps", "doctor", "docs", "policy"],
4631
4717
  failOnWarnings: false,
4632
4718
  uploadSarif: true
4633
4719
  },
@@ -5437,6 +5523,34 @@ async function checkContractsLibrary(fs5, ctx) {
5437
5523
  };
5438
5524
  }
5439
5525
  }
5526
+ // src/services/doctor/checks/docs.ts
5527
+ async function runDocChecks(fs5, ctx) {
5528
+ const diagnostics = await analyzeWorkspaceDocBlocks(fs5, ctx.workspaceRoot);
5529
+ if (diagnostics.length === 0) {
5530
+ return [
5531
+ {
5532
+ category: "docs",
5533
+ name: "Same-File DocBlocks",
5534
+ status: "pass",
5535
+ message: "All analyzed packages follow the same-file DocBlock rules."
5536
+ }
5537
+ ];
5538
+ }
5539
+ return diagnostics.map((diagnostic) => ({
5540
+ category: "docs",
5541
+ name: `Same-File DocBlocks (${diagnostic.packageName})`,
5542
+ status: diagnostic.severity === "warning" ? "warn" : "fail",
5543
+ message: diagnostic.message,
5544
+ details: fs5.relative(ctx.workspaceRoot, diagnostic.file),
5545
+ context: {
5546
+ ruleId: diagnostic.ruleId,
5547
+ file: diagnostic.file,
5548
+ line: diagnostic.line,
5549
+ column: diagnostic.column,
5550
+ packageName: diagnostic.packageName
5551
+ }
5552
+ }));
5553
+ }
5440
5554
  // src/services/layer-discovery.ts
5441
5555
  import {
5442
5556
  isExampleFile,
@@ -6346,6 +6460,7 @@ var ALL_CHECK_CATEGORIES = [
6346
6460
  "config",
6347
6461
  "mcp",
6348
6462
  "deps",
6463
+ "docs",
6349
6464
  "workspace",
6350
6465
  "ai",
6351
6466
  "layers"
@@ -6355,6 +6470,7 @@ var CHECK_CATEGORY_LABELS = {
6355
6470
  config: "Configuration Files",
6356
6471
  mcp: "MCP Server",
6357
6472
  deps: "Dependencies",
6473
+ docs: "DocBlock Ownership",
6358
6474
  workspace: "Workspace Structure",
6359
6475
  ai: "AI Provider",
6360
6476
  layers: "Contract Layers"
@@ -6367,6 +6483,7 @@ var defaultDoctorDependencies = {
6367
6483
  runConfigChecks,
6368
6484
  runMcpChecks,
6369
6485
  runDepsChecks: runDepsChecks2,
6486
+ runDocChecks,
6370
6487
  runWorkspaceChecks,
6371
6488
  runAiChecks,
6372
6489
  runLayerChecks
@@ -6450,6 +6567,8 @@ async function runCategoryChecks(category, fs5, ctx, prompts, checks) {
6450
6567
  return checks.runMcpChecks(fs5, ctx);
6451
6568
  case "deps":
6452
6569
  return checks.runDepsChecks(fs5, ctx);
6570
+ case "docs":
6571
+ return checks.runDocChecks(fs5, ctx);
6453
6572
  case "workspace":
6454
6573
  return checks.runWorkspaceChecks(fs5, ctx);
6455
6574
  case "ai":
@@ -6532,13 +6651,14 @@ import path3 from "path";
6532
6651
 
6533
6652
  // src/services/generate-artifacts.ts
6534
6653
  import path2 from "path";
6535
-
6536
6654
  // src/services/docs/docs-service.ts
6537
6655
  import {
6538
- defaultDocRegistry
6656
+ packageDocBlocks
6539
6657
  } from "@contractspec/lib.contracts-spec/docs";
6540
6658
  import {
6659
+ buildPackageDocManifest,
6541
6660
  convertSpecToDocBlock,
6661
+ extractModuleDocData,
6542
6662
  loadSpecFromSource,
6543
6663
  scanAllSpecsFromSource as scanAllSpecsFromSource2,
6544
6664
  scanSpecSource as scanSpecSource3
@@ -6628,6 +6748,14 @@ async function generateDocsFromSpecs(specFiles, options, adapters) {
6628
6748
  } catch (_err) {}
6629
6749
  }
6630
6750
  resolver.initialize(scanResults);
6751
+ const authoredEntries = await loadAuthoredDocEntriesFromSourceFiles(specFiles, adapters);
6752
+ for (const authoredEntry of authoredEntries) {
6753
+ blocks.push(authoredEntry.entry.block);
6754
+ logger3.debug(`Loaded authored doc ${authoredEntry.entry.id}`);
6755
+ if (options.outputDir) {
6756
+ await writeDocBlockFile(authoredEntry.entry.block, authoredEntry.filePath, options.outputDir, resolver, fs5);
6757
+ }
6758
+ }
6631
6759
  for (const file of specFiles) {
6632
6760
  try {
6633
6761
  const parsedList = await loadSpecFromSource(file);
@@ -6639,26 +6767,12 @@ async function generateDocsFromSpecs(specFiles, options, adapters) {
6639
6767
  const block = convertSpecToDocBlock(parsed, {
6640
6768
  rootPath: options.rootPath
6641
6769
  });
6642
- defaultDocRegistry.register(block);
6643
6770
  blocks.push(block);
6644
6771
  logger3.debug(`Generated doc for ${block.id}`);
6645
6772
  if (!options.outputDir) {
6646
6773
  continue;
6647
6774
  }
6648
- const moduleDef = resolver.resolve(file);
6649
- let targetDir = options.outputDir;
6650
- if (moduleDef) {
6651
- targetDir = path.join(options.outputDir, moduleDef.key);
6652
- } else {
6653
- targetDir = path.join(options.outputDir, "_common");
6654
- }
6655
- await fs5.mkdir(targetDir);
6656
- const filename = `${block.id}.md`;
6657
- const filePath = path.join(targetDir, filename);
6658
- const generatedContent = `<!-- @generated - This file was generated by ContractSpec. Do not edit manually. -->
6659
-
6660
- ${block.body}`;
6661
- await fs5.writeFile(filePath, generatedContent);
6775
+ await writeDocBlockFile(block, file, options.outputDir, resolver, fs5);
6662
6776
  }
6663
6777
  } catch (error) {
6664
6778
  logger3.error(`Error processing ${file}: ${error instanceof Error ? error.message : String(error)}`);
@@ -6669,6 +6783,36 @@ ${block.body}`;
6669
6783
  }
6670
6784
  return { blocks, count: blocks.length };
6671
6785
  }
6786
+ async function loadAuthoredDocBlocksFromSourceFiles(sourceFiles, adapters) {
6787
+ const entries = await loadAuthoredDocEntriesFromSourceFiles(sourceFiles, adapters);
6788
+ return entries.map(({ entry }) => entry.block);
6789
+ }
6790
+ function loadPackageAuthoredDocBlocks(packageName, srcRoot) {
6791
+ return packageDocBlocks(buildPackageDocManifest({ packageName, srcRoot }));
6792
+ }
6793
+ async function loadAuthoredDocEntriesFromSourceFiles(sourceFiles, adapters) {
6794
+ const uniqueFiles = [...new Set(sourceFiles)].sort((left, right) => left.localeCompare(right));
6795
+ const entries = [];
6796
+ for (const filePath of uniqueFiles) {
6797
+ const sourceText = await adapters.fs.readFile(filePath);
6798
+ const sourceModule = filePath.replace(/\\/g, "/").replace(/\.[cm]?[jt]sx?$/, "");
6799
+ const moduleData = extractModuleDocData(sourceText, filePath, sourceModule);
6800
+ for (const entry of moduleData.entries) {
6801
+ entries.push({ entry, filePath });
6802
+ }
6803
+ }
6804
+ return entries;
6805
+ }
6806
+ async function writeDocBlockFile(block, file, outputDir, resolver, fs5) {
6807
+ const moduleDef = resolver.resolve(file);
6808
+ const targetDir = moduleDef ? path.join(outputDir, moduleDef.key) : path.join(outputDir, "_common");
6809
+ await fs5.mkdir(targetDir);
6810
+ const filePath = path.join(targetDir, `${block.id}.md`);
6811
+ const generatedContent = `<!-- @generated - This file was generated by ContractSpec. Do not edit manually. -->
6812
+
6813
+ ${block.body}`;
6814
+ await fs5.writeFile(filePath, generatedContent);
6815
+ }
6672
6816
  // src/services/generate-artifacts.ts
6673
6817
  async function generateArtifacts(adapters, contractsDir, generatedDir, rootPath) {
6674
6818
  if (!await adapters.fs.exists(contractsDir)) {}
@@ -8156,6 +8300,7 @@ function createCategorySummary(category, issues, durationMs) {
8156
8300
  integrity: "Contract Integrity Analysis",
8157
8301
  deps: "Dependency Analysis",
8158
8302
  doctor: "Installation Health",
8303
+ docs: "DocBlock Ownership",
8159
8304
  policy: "Contract Policy Enforcement",
8160
8305
  handlers: "Handler Implementation",
8161
8306
  tests: "Test Coverage",
@@ -8203,7 +8348,7 @@ async function getGitInfo(fs5) {
8203
8348
  }
8204
8349
  function getChecksToRun(options) {
8205
8350
  const configuredChecks = options.config?.ci?.checks;
8206
- const allCategories = configuredChecks && configuredChecks.length > 0 ? [...configuredChecks] : ["structure", "integrity", "deps", "doctor"];
8351
+ const allCategories = configuredChecks && configuredChecks.length > 0 ? [...configuredChecks] : ["structure", "integrity", "deps", "doctor", "docs"];
8207
8352
  if (options.checkHandlers) {
8208
8353
  allCategories.push("handlers");
8209
8354
  }
@@ -8261,6 +8406,12 @@ async function runCIChecks(adapters, options = {}) {
8261
8406
  issues.push(...doctorIssues);
8262
8407
  categorySummaries.push(createCategorySummary("doctor", doctorIssues, Date.now() - categoryStart));
8263
8408
  }
8409
+ if (checksToRun.includes("docs")) {
8410
+ const categoryStart = Date.now();
8411
+ const docsIssues = await runDocsChecks(adapters, options);
8412
+ issues.push(...docsIssues);
8413
+ categorySummaries.push(createCategorySummary("docs", docsIssues, Date.now() - categoryStart));
8414
+ }
8264
8415
  if (checksToRun.includes("policy")) {
8265
8416
  const categoryStart = Date.now();
8266
8417
  const policyIssues = await runPolicyChecks(adapters, options);
@@ -8339,6 +8490,7 @@ var ALL_CI_CHECK_CATEGORIES = [
8339
8490
  "integrity",
8340
8491
  "deps",
8341
8492
  "doctor",
8493
+ "docs",
8342
8494
  "policy",
8343
8495
  "handlers",
8344
8496
  "tests",
@@ -8353,6 +8505,7 @@ var CI_CHECK_CATEGORY_LABELS = {
8353
8505
  integrity: "Contract Integrity Analysis",
8354
8506
  deps: "Dependency Analysis",
8355
8507
  doctor: "Installation Health",
8508
+ docs: "DocBlock Ownership",
8356
8509
  policy: "Contract Policy Enforcement",
8357
8510
  handlers: "Handler Implementation",
8358
8511
  tests: "Test Coverage",
@@ -11643,7 +11796,8 @@ __export(exports_impact, {
11643
11796
  formatMinimalComment: () => formatMinimalComment,
11644
11797
  formatJson: () => formatJson2,
11645
11798
  formatCheckRun: () => formatCheckRun,
11646
- detectImpact: () => detectImpact
11799
+ detectImpact: () => detectImpact,
11800
+ ImpactDetectionOverviewDocBlock: () => ImpactDetectionOverviewDocBlock
11647
11801
  });
11648
11802
 
11649
11803
  // src/services/impact/formatters.ts
@@ -11870,6 +12024,63 @@ function computeSnapshotDiffs(baseSpecs, headSpecs) {
11870
12024
  }
11871
12025
  return diffs;
11872
12026
  }
12027
+
12028
+ // src/services/impact/index.ts
12029
+ var ImpactDetectionOverviewDocBlock = {
12030
+ id: "feature.impact-detection.overview",
12031
+ title: "Contract Impact Detection",
12032
+ kind: "goal",
12033
+ visibility: "public",
12034
+ route: "/docs/features/impact-detection",
12035
+ body: `
12036
+ # Contract Impact Detection
12037
+
12038
+ Automated detection and classification of breaking changes in ContractSpec APIs.
12039
+
12040
+ ## Features
12041
+
12042
+ - **Snapshot Generation**: Creates canonical, deterministic representations of contracts
12043
+ - **Deep Diff Engine**: Field-level comparison of input/output schemas
12044
+ - **Breaking Change Classification**: Automatic classification using 16 rules
12045
+ - **Multiple Output Formats**: JSON, Markdown, Text, GitHub Check Run
12046
+ - **GitHub Integration**: PR comments and check runs
12047
+ - **CLI Tool**: \`contractspec impact\` command
12048
+
12049
+ ## Quick Start
12050
+
12051
+ ### CLI Usage
12052
+
12053
+ \`\`\`bash
12054
+ # Basic usage
12055
+ contractspec impact
12056
+
12057
+ # Compare against specific baseline
12058
+ contractspec impact --baseline origin/main
12059
+
12060
+ # Get JSON output
12061
+ contractspec impact --format json
12062
+ \`\`\`
12063
+
12064
+ ### GitHub Action
12065
+
12066
+ \`\`\`yaml
12067
+ - uses: lssm-tech/contractspec-action@v1
12068
+ with:
12069
+ mode: impact
12070
+ pr-comment: true
12071
+ fail-on-breaking: true
12072
+ \`\`\`
12073
+
12074
+ ## Architecture
12075
+
12076
+ The system consists of three layers:
12077
+
12078
+ 1. **Analysis Modules** (module package): Snapshot, Deep Diff, Classifier
12079
+ 2. **Impact Service** (bundle package): Orchestration + Formatters
12080
+ 3. **Integrations**: CLI command + GitHub Action
12081
+ `,
12082
+ tags: ["impact-detection", "breaking-changes", "ci-cd"]
12083
+ };
11873
12084
  // src/services/import/import-service.ts
11874
12085
  import {
11875
12086
  detectFramework,
@@ -17715,6 +17926,8 @@ export {
17715
17926
  module,
17716
17927
  mergeMonorepoConfigs,
17717
17928
  loadWorkspaceConfig,
17929
+ loadPackageAuthoredDocBlocks,
17930
+ loadAuthoredDocBlocksFromSourceFiles,
17718
17931
  listTests,
17719
17932
  listSpecsForView,
17720
17933
  listSpecs,
@@ -17838,6 +18051,7 @@ export {
17838
18051
  claudeCodeAdapter,
17839
18052
  cacheKeyToString,
17840
18053
  buildSpec,
18054
+ analyzeWorkspaceDocBlocks,
17841
18055
  analyzeIntegrity,
17842
18056
  analyzeGap,
17843
18057
  analyzeDeps,
@@ -397,7 +397,6 @@ var DEFAULT_FS_IGNORES = [
397
397
  "**/*.d.ts",
398
398
  "**/importer/**",
399
399
  "**/exporter/**",
400
- "**/docs/**/*.docblock.ts",
401
400
  "**/docs/presentations.ts"
402
401
  ];
403
402
 
@@ -4349,6 +4348,93 @@ async function runDepsChecks(adapters, options) {
4349
4348
  }
4350
4349
  return issues;
4351
4350
  }
4351
+ // src/services/docs/docblock-audit.ts
4352
+ import {
4353
+ analyzePackageDocBlocks
4354
+ } from "@contractspec/module.workspace";
4355
+ var PACKAGE_GLOB_IGNORES = [
4356
+ "**/node_modules/**",
4357
+ "**/dist/**",
4358
+ "**/.turbo/**",
4359
+ "**/.next/**"
4360
+ ];
4361
+ async function discoverWorkspaceDocPackages(fs5, workspaceRoot) {
4362
+ const packageJsonFiles = await fs5.glob({
4363
+ pattern: "packages/**/package.json",
4364
+ cwd: workspaceRoot,
4365
+ ignore: PACKAGE_GLOB_IGNORES
4366
+ });
4367
+ const discovered = new Map;
4368
+ for (const packageJsonFile of packageJsonFiles) {
4369
+ const packageRoot = fs5.dirname(packageJsonFile);
4370
+ const srcRoot = fs5.join(packageRoot, "src");
4371
+ if (!await fs5.exists(srcRoot)) {
4372
+ continue;
4373
+ }
4374
+ try {
4375
+ const packageJson = JSON.parse(await fs5.readFile(packageJsonFile));
4376
+ discovered.set(packageRoot, {
4377
+ packageName: packageJson.name ?? fs5.relative(workspaceRoot, packageRoot),
4378
+ packageRoot,
4379
+ srcRoot
4380
+ });
4381
+ } catch {
4382
+ continue;
4383
+ }
4384
+ }
4385
+ const rootPackageJson = fs5.join(workspaceRoot, "package.json");
4386
+ const rootSrc = fs5.join(workspaceRoot, "src");
4387
+ if (await fs5.exists(rootPackageJson) && await fs5.exists(rootSrc)) {
4388
+ try {
4389
+ const packageJson = JSON.parse(await fs5.readFile(rootPackageJson));
4390
+ discovered.set(workspaceRoot, {
4391
+ packageName: packageJson.name ?? workspaceRoot,
4392
+ packageRoot: workspaceRoot,
4393
+ srcRoot: rootSrc
4394
+ });
4395
+ } catch {}
4396
+ }
4397
+ return [...discovered.values()].sort((left, right) => left.packageRoot.localeCompare(right.packageRoot));
4398
+ }
4399
+ async function analyzeWorkspaceDocBlocks(fs5, workspaceRoot) {
4400
+ const diagnostics = [];
4401
+ const packages = await discoverWorkspaceDocPackages(fs5, workspaceRoot);
4402
+ for (const pkg of packages) {
4403
+ const result = analyzePackageDocBlocks({
4404
+ packageName: pkg.packageName,
4405
+ srcRoot: pkg.srcRoot
4406
+ });
4407
+ for (const diagnostic of result.diagnostics) {
4408
+ diagnostics.push({
4409
+ ...diagnostic,
4410
+ packageName: pkg.packageName,
4411
+ packageRoot: pkg.packageRoot,
4412
+ srcRoot: pkg.srcRoot
4413
+ });
4414
+ }
4415
+ }
4416
+ return diagnostics;
4417
+ }
4418
+
4419
+ // src/services/ci-check/checks/docs.ts
4420
+ async function runDocsChecks(adapters, options) {
4421
+ const workspaceRoot = options.workspaceRoot ?? process.cwd();
4422
+ const diagnostics = await analyzeWorkspaceDocBlocks(adapters.fs, workspaceRoot);
4423
+ return diagnostics.map((diagnostic) => ({
4424
+ ruleId: diagnostic.ruleId,
4425
+ severity: diagnostic.severity === "warning" ? "warning" : "error",
4426
+ message: diagnostic.message,
4427
+ category: "docs",
4428
+ file: diagnostic.file,
4429
+ line: diagnostic.line,
4430
+ column: diagnostic.column,
4431
+ context: {
4432
+ packageName: diagnostic.packageName,
4433
+ packageRoot: diagnostic.packageRoot,
4434
+ ...diagnostic.context
4435
+ }
4436
+ }));
4437
+ }
4352
4438
  // src/services/doctor/checks/ai.ts
4353
4439
  async function runAiChecks(fs5, ctx, prompts) {
4354
4440
  const results = [];
@@ -4627,7 +4713,7 @@ function generateContractsrcConfig(options) {
4627
4713
  type: "biome"
4628
4714
  },
4629
4715
  ci: {
4630
- checks: ["structure", "integrity", "deps", "doctor", "policy"],
4716
+ checks: ["structure", "integrity", "deps", "doctor", "docs", "policy"],
4631
4717
  failOnWarnings: false,
4632
4718
  uploadSarif: true
4633
4719
  },
@@ -5437,6 +5523,34 @@ async function checkContractsLibrary(fs5, ctx) {
5437
5523
  };
5438
5524
  }
5439
5525
  }
5526
+ // src/services/doctor/checks/docs.ts
5527
+ async function runDocChecks(fs5, ctx) {
5528
+ const diagnostics = await analyzeWorkspaceDocBlocks(fs5, ctx.workspaceRoot);
5529
+ if (diagnostics.length === 0) {
5530
+ return [
5531
+ {
5532
+ category: "docs",
5533
+ name: "Same-File DocBlocks",
5534
+ status: "pass",
5535
+ message: "All analyzed packages follow the same-file DocBlock rules."
5536
+ }
5537
+ ];
5538
+ }
5539
+ return diagnostics.map((diagnostic) => ({
5540
+ category: "docs",
5541
+ name: `Same-File DocBlocks (${diagnostic.packageName})`,
5542
+ status: diagnostic.severity === "warning" ? "warn" : "fail",
5543
+ message: diagnostic.message,
5544
+ details: fs5.relative(ctx.workspaceRoot, diagnostic.file),
5545
+ context: {
5546
+ ruleId: diagnostic.ruleId,
5547
+ file: diagnostic.file,
5548
+ line: diagnostic.line,
5549
+ column: diagnostic.column,
5550
+ packageName: diagnostic.packageName
5551
+ }
5552
+ }));
5553
+ }
5440
5554
  // src/services/layer-discovery.ts
5441
5555
  import {
5442
5556
  isExampleFile,
@@ -6346,6 +6460,7 @@ var ALL_CHECK_CATEGORIES = [
6346
6460
  "config",
6347
6461
  "mcp",
6348
6462
  "deps",
6463
+ "docs",
6349
6464
  "workspace",
6350
6465
  "ai",
6351
6466
  "layers"
@@ -6355,6 +6470,7 @@ var CHECK_CATEGORY_LABELS = {
6355
6470
  config: "Configuration Files",
6356
6471
  mcp: "MCP Server",
6357
6472
  deps: "Dependencies",
6473
+ docs: "DocBlock Ownership",
6358
6474
  workspace: "Workspace Structure",
6359
6475
  ai: "AI Provider",
6360
6476
  layers: "Contract Layers"
@@ -6367,6 +6483,7 @@ var defaultDoctorDependencies = {
6367
6483
  runConfigChecks,
6368
6484
  runMcpChecks,
6369
6485
  runDepsChecks: runDepsChecks2,
6486
+ runDocChecks,
6370
6487
  runWorkspaceChecks,
6371
6488
  runAiChecks,
6372
6489
  runLayerChecks
@@ -6450,6 +6567,8 @@ async function runCategoryChecks(category, fs5, ctx, prompts, checks) {
6450
6567
  return checks.runMcpChecks(fs5, ctx);
6451
6568
  case "deps":
6452
6569
  return checks.runDepsChecks(fs5, ctx);
6570
+ case "docs":
6571
+ return checks.runDocChecks(fs5, ctx);
6453
6572
  case "workspace":
6454
6573
  return checks.runWorkspaceChecks(fs5, ctx);
6455
6574
  case "ai":
@@ -6532,13 +6651,14 @@ import path3 from "path";
6532
6651
 
6533
6652
  // src/services/generate-artifacts.ts
6534
6653
  import path2 from "path";
6535
-
6536
6654
  // src/services/docs/docs-service.ts
6537
6655
  import {
6538
- defaultDocRegistry
6656
+ packageDocBlocks
6539
6657
  } from "@contractspec/lib.contracts-spec/docs";
6540
6658
  import {
6659
+ buildPackageDocManifest,
6541
6660
  convertSpecToDocBlock,
6661
+ extractModuleDocData,
6542
6662
  loadSpecFromSource,
6543
6663
  scanAllSpecsFromSource as scanAllSpecsFromSource2,
6544
6664
  scanSpecSource as scanSpecSource3
@@ -6628,6 +6748,14 @@ async function generateDocsFromSpecs(specFiles, options, adapters) {
6628
6748
  } catch (_err) {}
6629
6749
  }
6630
6750
  resolver.initialize(scanResults);
6751
+ const authoredEntries = await loadAuthoredDocEntriesFromSourceFiles(specFiles, adapters);
6752
+ for (const authoredEntry of authoredEntries) {
6753
+ blocks.push(authoredEntry.entry.block);
6754
+ logger3.debug(`Loaded authored doc ${authoredEntry.entry.id}`);
6755
+ if (options.outputDir) {
6756
+ await writeDocBlockFile(authoredEntry.entry.block, authoredEntry.filePath, options.outputDir, resolver, fs5);
6757
+ }
6758
+ }
6631
6759
  for (const file of specFiles) {
6632
6760
  try {
6633
6761
  const parsedList = await loadSpecFromSource(file);
@@ -6639,26 +6767,12 @@ async function generateDocsFromSpecs(specFiles, options, adapters) {
6639
6767
  const block = convertSpecToDocBlock(parsed, {
6640
6768
  rootPath: options.rootPath
6641
6769
  });
6642
- defaultDocRegistry.register(block);
6643
6770
  blocks.push(block);
6644
6771
  logger3.debug(`Generated doc for ${block.id}`);
6645
6772
  if (!options.outputDir) {
6646
6773
  continue;
6647
6774
  }
6648
- const moduleDef = resolver.resolve(file);
6649
- let targetDir = options.outputDir;
6650
- if (moduleDef) {
6651
- targetDir = path.join(options.outputDir, moduleDef.key);
6652
- } else {
6653
- targetDir = path.join(options.outputDir, "_common");
6654
- }
6655
- await fs5.mkdir(targetDir);
6656
- const filename = `${block.id}.md`;
6657
- const filePath = path.join(targetDir, filename);
6658
- const generatedContent = `<!-- @generated - This file was generated by ContractSpec. Do not edit manually. -->
6659
-
6660
- ${block.body}`;
6661
- await fs5.writeFile(filePath, generatedContent);
6775
+ await writeDocBlockFile(block, file, options.outputDir, resolver, fs5);
6662
6776
  }
6663
6777
  } catch (error) {
6664
6778
  logger3.error(`Error processing ${file}: ${error instanceof Error ? error.message : String(error)}`);
@@ -6669,6 +6783,36 @@ ${block.body}`;
6669
6783
  }
6670
6784
  return { blocks, count: blocks.length };
6671
6785
  }
6786
+ async function loadAuthoredDocBlocksFromSourceFiles(sourceFiles, adapters) {
6787
+ const entries = await loadAuthoredDocEntriesFromSourceFiles(sourceFiles, adapters);
6788
+ return entries.map(({ entry }) => entry.block);
6789
+ }
6790
+ function loadPackageAuthoredDocBlocks(packageName, srcRoot) {
6791
+ return packageDocBlocks(buildPackageDocManifest({ packageName, srcRoot }));
6792
+ }
6793
+ async function loadAuthoredDocEntriesFromSourceFiles(sourceFiles, adapters) {
6794
+ const uniqueFiles = [...new Set(sourceFiles)].sort((left, right) => left.localeCompare(right));
6795
+ const entries = [];
6796
+ for (const filePath of uniqueFiles) {
6797
+ const sourceText = await adapters.fs.readFile(filePath);
6798
+ const sourceModule = filePath.replace(/\\/g, "/").replace(/\.[cm]?[jt]sx?$/, "");
6799
+ const moduleData = extractModuleDocData(sourceText, filePath, sourceModule);
6800
+ for (const entry of moduleData.entries) {
6801
+ entries.push({ entry, filePath });
6802
+ }
6803
+ }
6804
+ return entries;
6805
+ }
6806
+ async function writeDocBlockFile(block, file, outputDir, resolver, fs5) {
6807
+ const moduleDef = resolver.resolve(file);
6808
+ const targetDir = moduleDef ? path.join(outputDir, moduleDef.key) : path.join(outputDir, "_common");
6809
+ await fs5.mkdir(targetDir);
6810
+ const filePath = path.join(targetDir, `${block.id}.md`);
6811
+ const generatedContent = `<!-- @generated - This file was generated by ContractSpec. Do not edit manually. -->
6812
+
6813
+ ${block.body}`;
6814
+ await fs5.writeFile(filePath, generatedContent);
6815
+ }
6672
6816
  // src/services/generate-artifacts.ts
6673
6817
  async function generateArtifacts(adapters, contractsDir, generatedDir, rootPath) {
6674
6818
  if (!await adapters.fs.exists(contractsDir)) {}
@@ -8156,6 +8300,7 @@ function createCategorySummary(category, issues, durationMs) {
8156
8300
  integrity: "Contract Integrity Analysis",
8157
8301
  deps: "Dependency Analysis",
8158
8302
  doctor: "Installation Health",
8303
+ docs: "DocBlock Ownership",
8159
8304
  policy: "Contract Policy Enforcement",
8160
8305
  handlers: "Handler Implementation",
8161
8306
  tests: "Test Coverage",
@@ -8203,7 +8348,7 @@ async function getGitInfo(fs5) {
8203
8348
  }
8204
8349
  function getChecksToRun(options) {
8205
8350
  const configuredChecks = options.config?.ci?.checks;
8206
- const allCategories = configuredChecks && configuredChecks.length > 0 ? [...configuredChecks] : ["structure", "integrity", "deps", "doctor"];
8351
+ const allCategories = configuredChecks && configuredChecks.length > 0 ? [...configuredChecks] : ["structure", "integrity", "deps", "doctor", "docs"];
8207
8352
  if (options.checkHandlers) {
8208
8353
  allCategories.push("handlers");
8209
8354
  }
@@ -8261,6 +8406,12 @@ async function runCIChecks(adapters, options = {}) {
8261
8406
  issues.push(...doctorIssues);
8262
8407
  categorySummaries.push(createCategorySummary("doctor", doctorIssues, Date.now() - categoryStart));
8263
8408
  }
8409
+ if (checksToRun.includes("docs")) {
8410
+ const categoryStart = Date.now();
8411
+ const docsIssues = await runDocsChecks(adapters, options);
8412
+ issues.push(...docsIssues);
8413
+ categorySummaries.push(createCategorySummary("docs", docsIssues, Date.now() - categoryStart));
8414
+ }
8264
8415
  if (checksToRun.includes("policy")) {
8265
8416
  const categoryStart = Date.now();
8266
8417
  const policyIssues = await runPolicyChecks(adapters, options);
@@ -8339,6 +8490,7 @@ var ALL_CI_CHECK_CATEGORIES = [
8339
8490
  "integrity",
8340
8491
  "deps",
8341
8492
  "doctor",
8493
+ "docs",
8342
8494
  "policy",
8343
8495
  "handlers",
8344
8496
  "tests",
@@ -8353,6 +8505,7 @@ var CI_CHECK_CATEGORY_LABELS = {
8353
8505
  integrity: "Contract Integrity Analysis",
8354
8506
  deps: "Dependency Analysis",
8355
8507
  doctor: "Installation Health",
8508
+ docs: "DocBlock Ownership",
8356
8509
  policy: "Contract Policy Enforcement",
8357
8510
  handlers: "Handler Implementation",
8358
8511
  tests: "Test Coverage",
@@ -11643,7 +11796,8 @@ __export(exports_impact, {
11643
11796
  formatMinimalComment: () => formatMinimalComment,
11644
11797
  formatJson: () => formatJson2,
11645
11798
  formatCheckRun: () => formatCheckRun,
11646
- detectImpact: () => detectImpact
11799
+ detectImpact: () => detectImpact,
11800
+ ImpactDetectionOverviewDocBlock: () => ImpactDetectionOverviewDocBlock
11647
11801
  });
11648
11802
 
11649
11803
  // src/services/impact/formatters.ts
@@ -11870,6 +12024,63 @@ function computeSnapshotDiffs(baseSpecs, headSpecs) {
11870
12024
  }
11871
12025
  return diffs;
11872
12026
  }
12027
+
12028
+ // src/services/impact/index.ts
12029
+ var ImpactDetectionOverviewDocBlock = {
12030
+ id: "feature.impact-detection.overview",
12031
+ title: "Contract Impact Detection",
12032
+ kind: "goal",
12033
+ visibility: "public",
12034
+ route: "/docs/features/impact-detection",
12035
+ body: `
12036
+ # Contract Impact Detection
12037
+
12038
+ Automated detection and classification of breaking changes in ContractSpec APIs.
12039
+
12040
+ ## Features
12041
+
12042
+ - **Snapshot Generation**: Creates canonical, deterministic representations of contracts
12043
+ - **Deep Diff Engine**: Field-level comparison of input/output schemas
12044
+ - **Breaking Change Classification**: Automatic classification using 16 rules
12045
+ - **Multiple Output Formats**: JSON, Markdown, Text, GitHub Check Run
12046
+ - **GitHub Integration**: PR comments and check runs
12047
+ - **CLI Tool**: \`contractspec impact\` command
12048
+
12049
+ ## Quick Start
12050
+
12051
+ ### CLI Usage
12052
+
12053
+ \`\`\`bash
12054
+ # Basic usage
12055
+ contractspec impact
12056
+
12057
+ # Compare against specific baseline
12058
+ contractspec impact --baseline origin/main
12059
+
12060
+ # Get JSON output
12061
+ contractspec impact --format json
12062
+ \`\`\`
12063
+
12064
+ ### GitHub Action
12065
+
12066
+ \`\`\`yaml
12067
+ - uses: lssm-tech/contractspec-action@v1
12068
+ with:
12069
+ mode: impact
12070
+ pr-comment: true
12071
+ fail-on-breaking: true
12072
+ \`\`\`
12073
+
12074
+ ## Architecture
12075
+
12076
+ The system consists of three layers:
12077
+
12078
+ 1. **Analysis Modules** (module package): Snapshot, Deep Diff, Classifier
12079
+ 2. **Impact Service** (bundle package): Orchestration + Formatters
12080
+ 3. **Integrations**: CLI command + GitHub Action
12081
+ `,
12082
+ tags: ["impact-detection", "breaking-changes", "ci-cd"]
12083
+ };
11873
12084
  // src/services/import/import-service.ts
11874
12085
  import {
11875
12086
  detectFramework,
@@ -17715,6 +17926,8 @@ export {
17715
17926
  module,
17716
17927
  mergeMonorepoConfigs,
17717
17928
  loadWorkspaceConfig,
17929
+ loadPackageAuthoredDocBlocks,
17930
+ loadAuthoredDocBlocksFromSourceFiles,
17718
17931
  listTests,
17719
17932
  listSpecsForView,
17720
17933
  listSpecs,
@@ -17838,6 +18051,7 @@ export {
17838
18051
  claudeCodeAdapter,
17839
18052
  cacheKeyToString,
17840
18053
  buildSpec,
18054
+ analyzeWorkspaceDocBlocks,
17841
18055
  analyzeIntegrity,
17842
18056
  analyzeGap,
17843
18057
  analyzeDeps,
@@ -0,0 +1,7 @@
1
+ import type { FsAdapter } from '../../../ports/fs';
2
+ import type { LoggerAdapter } from '../../../ports/logger';
3
+ import type { CICheckOptions, CIIssue } from '../types';
4
+ export declare function runDocsChecks(adapters: {
5
+ fs: FsAdapter;
6
+ logger: LoggerAdapter;
7
+ }, options: CICheckOptions): Promise<CIIssue[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export { runCoverageChecks } from './coverage';
5
5
  export { runDepsChecks } from './deps';
6
+ export { runDocsChecks } from './docs';
6
7
  export { runDoctorChecks } from './doctor';
7
8
  export { runDriftChecks } from './drift';
8
9
  export { runHandlerChecks } from './handlers';
@@ -7,7 +7,7 @@ import type { ContractsrcConfig, ResolvedContractsrcConfig } from '@contractspec
7
7
  /**
8
8
  * Categories of CI checks.
9
9
  */
10
- export type CICheckCategory = 'structure' | 'integrity' | 'deps' | 'doctor' | 'policy' | 'handlers' | 'tests' | 'test-refs' | 'coverage' | 'implementation' | 'layers' | 'drift';
10
+ export type CICheckCategory = 'structure' | 'integrity' | 'deps' | 'doctor' | 'docs' | 'policy' | 'handlers' | 'tests' | 'test-refs' | 'coverage' | 'implementation' | 'layers' | 'drift';
11
11
  /**
12
12
  * All available CI check categories.
13
13
  */
@@ -0,0 +1,8 @@
1
+ import { type DocBlockDiagnostic } from '@contractspec/module.workspace';
2
+ import type { FsAdapter } from '../../ports/fs';
3
+ export interface WorkspaceDocBlockDiagnostic extends DocBlockDiagnostic {
4
+ packageName: string;
5
+ packageRoot: string;
6
+ srcRoot: string;
7
+ }
8
+ export declare function analyzeWorkspaceDocBlocks(fs: FsAdapter, workspaceRoot: string): Promise<WorkspaceDocBlockDiagnostic[]>;
@@ -13,3 +13,5 @@ export interface DocsServiceResult {
13
13
  * Generate documentation from spec files.
14
14
  */
15
15
  export declare function generateDocsFromSpecs(specFiles: string[], options: DocsServiceOptions, adapters: WorkspaceAdapters): Promise<DocsServiceResult>;
16
+ export declare function loadAuthoredDocBlocksFromSourceFiles(sourceFiles: string[], adapters: Pick<WorkspaceAdapters, 'fs'>): Promise<DocBlock[]>;
17
+ export declare function loadPackageAuthoredDocBlocks(packageName: string, srcRoot: string): DocBlock[];
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,2 @@
1
+ export * from './docblock-audit';
1
2
  export * from './docs-service';
@@ -0,0 +1,3 @@
1
+ import type { FsAdapter } from '../../../ports/fs';
2
+ import type { CheckContext, CheckResult } from '../types';
3
+ export declare function runDocChecks(fs: FsAdapter, ctx: CheckContext): Promise<CheckResult[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -5,6 +5,7 @@ export { runAiChecks } from './ai';
5
5
  export { runCliChecks } from './cli';
6
6
  export { runConfigChecks } from './config';
7
7
  export { runDepsChecks } from './deps';
8
+ export { runDocChecks } from './docs';
8
9
  export { runLayerChecks } from './layers';
9
10
  export { runMcpChecks } from './mcp';
10
11
  export { runWorkspaceChecks } from './workspace';
@@ -6,13 +6,14 @@
6
6
  import { findPackageRoot, findWorkspaceRoot, getPackageName, isMonorepo } from '../../adapters/workspace';
7
7
  import type { FsAdapter } from '../../ports/fs';
8
8
  import type { LoggerAdapter } from '../../ports/logger';
9
- import { runAiChecks, runCliChecks, runConfigChecks, runDepsChecks, runLayerChecks, runMcpChecks, runWorkspaceChecks } from './checks/index';
9
+ import { runAiChecks, runCliChecks, runConfigChecks, runDepsChecks, runDocChecks, runLayerChecks, runMcpChecks, runWorkspaceChecks } from './checks/index';
10
10
  import type { CheckResult, DoctorOptions, DoctorPromptCallbacks, DoctorResult } from './types';
11
11
  interface DoctorCheckRunners {
12
12
  runCliChecks: typeof runCliChecks;
13
13
  runConfigChecks: typeof runConfigChecks;
14
14
  runMcpChecks: typeof runMcpChecks;
15
15
  runDepsChecks: typeof runDepsChecks;
16
+ runDocChecks: typeof runDocChecks;
16
17
  runWorkspaceChecks: typeof runWorkspaceChecks;
17
18
  runAiChecks: typeof runAiChecks;
18
19
  runLayerChecks: typeof runLayerChecks;
@@ -6,7 +6,7 @@
6
6
  /**
7
7
  * Categories of health checks.
8
8
  */
9
- export type CheckCategory = 'cli' | 'config' | 'mcp' | 'deps' | 'workspace' | 'ai' | 'layers';
9
+ export type CheckCategory = 'cli' | 'config' | 'mcp' | 'deps' | 'docs' | 'workspace' | 'ai' | 'layers';
10
10
  /**
11
11
  * All available check categories.
12
12
  */
@@ -1,13 +1,16 @@
1
- /**
2
- * Impact detection service.
3
- *
4
- * Orchestrates contract snapshot generation, diff computation,
5
- * and impact classification for CI/CD pipelines.
6
- */
7
1
  import type { FsAdapter } from '../../ports/fs';
8
2
  import type { GitAdapter } from '../../ports/git';
9
3
  import type { LoggerAdapter } from '../../ports/logger';
10
4
  import type { ImpactDetectionOptions, ImpactDetectionResult } from './types';
5
+ export declare const ImpactDetectionRulesDocBlock: {
6
+ id: string;
7
+ title: string;
8
+ kind: "reference";
9
+ visibility: "public";
10
+ route: string;
11
+ body: string;
12
+ tags: string[];
13
+ };
11
14
  /**
12
15
  * Detect the impact of contract changes between baseline and current state.
13
16
  *
@@ -1,6 +1,12 @@
1
- /**
2
- * Impact detection service module.
3
- */
1
+ export declare const ImpactDetectionOverviewDocBlock: {
2
+ id: string;
3
+ title: string;
4
+ kind: "goal";
5
+ visibility: "public";
6
+ route: string;
7
+ body: string;
8
+ tags: string[];
9
+ };
4
10
  export { formatCheckRun, formatJson, formatMinimalComment, formatPrComment, } from './formatters';
5
11
  export { detectImpact } from './impact-detection-service';
6
12
  export * from './types';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contractspec/bundle.workspace",
3
- "version": "4.0.3",
3
+ "version": "4.1.2",
4
4
  "description": "Workspace utilities for monorepo development",
5
5
  "keywords": [
6
6
  "contractspec",
@@ -33,15 +33,15 @@
33
33
  "dependencies": {
34
34
  "@ai-sdk/anthropic": "3.0.58",
35
35
  "@ai-sdk/openai": "3.0.41",
36
- "@contractspec/biome-config": "3.8.2",
37
- "@contractspec/lib.ai-agent": "7.0.10",
38
- "@contractspec/lib.ai-providers": "3.7.8",
39
- "@contractspec/lib.contracts-spec": "4.1.2",
40
- "@contractspec/lib.contracts-integrations": "3.8.2",
41
- "@contractspec/lib.contracts-transformers": "3.7.10",
42
- "@contractspec/lib.source-extractors": "2.7.10",
43
- "@contractspec/module.workspace": "4.0.3",
44
- "@contractspec/lib.utils-typescript": "3.7.8",
36
+ "@contractspec/biome-config": "3.8.4",
37
+ "@contractspec/lib.ai-agent": "8.0.2",
38
+ "@contractspec/lib.ai-providers": "3.7.10",
39
+ "@contractspec/lib.contracts-spec": "5.0.2",
40
+ "@contractspec/lib.contracts-integrations": "3.8.6",
41
+ "@contractspec/lib.contracts-transformers": "3.7.14",
42
+ "@contractspec/lib.source-extractors": "2.7.14",
43
+ "@contractspec/module.workspace": "4.1.1",
44
+ "@contractspec/lib.utils-typescript": "3.7.10",
45
45
  "ai": "6.0.116",
46
46
  "chalk": "^5.6.2",
47
47
  "chokidar": "^5.0.0",
@@ -54,12 +54,12 @@
54
54
  "zod": "^4.3.5"
55
55
  },
56
56
  "devDependencies": {
57
- "@contractspec/tool.typescript": "3.7.8",
57
+ "@contractspec/tool.typescript": "3.7.10",
58
58
  "@types/bun": "^1.3.11",
59
59
  "@types/micromatch": "^4.0.10",
60
60
  "@types/node": "^25.3.5",
61
61
  "typescript": "^5.9.3",
62
- "@contractspec/tool.bun": "3.7.8"
62
+ "@contractspec/tool.bun": "3.7.10"
63
63
  },
64
64
  "exports": {
65
65
  ".": {
@@ -1,9 +0,0 @@
1
- /**
2
- * DocBlock for Contract Impact Detection feature.
3
- *
4
- * Colocated documentation following the DocBlock pattern.
5
- */
6
- import type { DocBlock } from '@contractspec/lib.contracts-spec/docs/types';
7
- export declare const ImpactDetectionOverviewDoc: DocBlock;
8
- export declare const ImpactDetectionRulesDoc: DocBlock;
9
- export declare const ImpactDetectionUsageDoc: DocBlock;