kibi-cli 2.0.0 → 2.1.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.
Files changed (217) hide show
  1. package/dist/cli-register-proof.d.ts.map +1 -1
  2. package/dist/cli-register-proof.js +25 -1
  3. package/dist/cli-register-reporting.d.ts.map +1 -1
  4. package/dist/cli-register-reporting.js +6 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +2 -0
  7. package/dist/commands/check-generated.d.ts +7 -0
  8. package/dist/commands/check-generated.d.ts.map +1 -0
  9. package/dist/commands/check-generated.js +192 -0
  10. package/dist/commands/check.d.ts.map +1 -1
  11. package/dist/commands/check.js +3 -2
  12. package/dist/commands/doctor.d.ts.map +1 -1
  13. package/dist/commands/doctor.js +122 -1
  14. package/dist/commands/engine.d.ts.map +1 -1
  15. package/dist/commands/engine.js +3 -1
  16. package/dist/commands/init-helpers.d.ts.map +1 -1
  17. package/dist/commands/init-helpers.js +13 -7
  18. package/dist/commands/proof-explain.d.ts +10 -0
  19. package/dist/commands/proof-explain.d.ts.map +1 -0
  20. package/dist/commands/proof-explain.js +45 -0
  21. package/dist/commands/proof-impact.d.ts +7 -0
  22. package/dist/commands/proof-impact.d.ts.map +1 -0
  23. package/dist/commands/proof-impact.js +39 -0
  24. package/dist/commands/proof-migrate-legacy.js +1 -1
  25. package/dist/commands/proof-prune.js +1 -1
  26. package/dist/commands/prove.js +4 -4
  27. package/dist/commands/report.d.ts.map +1 -1
  28. package/dist/commands/report.js +17 -2
  29. package/dist/commands/sync/manifest.d.ts +1 -0
  30. package/dist/commands/sync/manifest.d.ts.map +1 -1
  31. package/dist/commands/sync/manifest.js +18 -16
  32. package/dist/commands/sync/persistence.d.ts.map +1 -1
  33. package/dist/commands/sync/persistence.js +6 -0
  34. package/dist/engine.d.ts +3 -1
  35. package/dist/engine.d.ts.map +1 -1
  36. package/dist/engine.js +134 -61
  37. package/dist/env/bootstrap.d.ts +84 -0
  38. package/dist/env/bootstrap.d.ts.map +1 -0
  39. package/dist/env/bootstrap.js +310 -0
  40. package/dist/extractors/manifest.d.ts.map +1 -1
  41. package/dist/extractors/manifest.js +1 -1
  42. package/dist/extractors/markdown.d.ts +2 -0
  43. package/dist/extractors/markdown.d.ts.map +1 -1
  44. package/dist/extractors/markdown.js +19 -0
  45. package/dist/extractors/symbols-coordinator.d.ts +8 -0
  46. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  47. package/dist/extractors/symbols-coordinator.js +40 -0
  48. package/dist/extractors/symbols-ts.d.ts +8 -19
  49. package/dist/extractors/symbols-ts.d.ts.map +1 -1
  50. package/dist/extractors/symbols-ts.js +33 -503
  51. package/dist/intent-search.d.ts.map +1 -1
  52. package/dist/intent-search.js +4 -5
  53. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  54. package/dist/operations/modeling/model-requirement.js +4 -0
  55. package/dist/operations/modeling/suggest-predicates.d.ts +1 -1
  56. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  57. package/dist/operations/modeling/suggest-predicates.js +30 -3
  58. package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
  59. package/dist/operations/mutation/symbol-granularity.js +9 -87
  60. package/dist/operations/planning/compile-intent.d.ts +49 -0
  61. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  62. package/dist/operations/planning/compile-intent.js +63 -3
  63. package/dist/operations/proof/baseline-diff.d.ts +41 -0
  64. package/dist/operations/proof/baseline-diff.d.ts.map +1 -0
  65. package/dist/operations/proof/baseline-diff.js +153 -0
  66. package/dist/operations/proof/explain.d.ts +75 -0
  67. package/dist/operations/proof/explain.d.ts.map +1 -0
  68. package/dist/operations/proof/explain.js +294 -0
  69. package/dist/operations/proof/impact.d.ts +45 -0
  70. package/dist/operations/proof/impact.d.ts.map +1 -0
  71. package/dist/operations/proof/impact.js +118 -0
  72. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  73. package/dist/operations/proof/ingest-proof.js +44 -3
  74. package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
  75. package/dist/operations/proof/migrate-legacy-receipts.js +21 -17
  76. package/dist/operations/proof/prune-receipts.js +1 -1
  77. package/dist/operations/proof/receipt-document.js +2 -2
  78. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  79. package/dist/operations/semantic-advisor/analysis-receipt.js +3 -9
  80. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  81. package/dist/operations/semantic-advisor/analyze-prose.js +18 -67
  82. package/dist/operations/semantic-advisor/plugin-orchestration.d.ts +63 -0
  83. package/dist/operations/semantic-advisor/plugin-orchestration.d.ts.map +1 -0
  84. package/dist/operations/semantic-advisor/plugin-orchestration.js +489 -0
  85. package/dist/operations/semantic-advisor/predicate-rules-core.d.ts +15 -2
  86. package/dist/operations/semantic-advisor/predicate-rules-core.d.ts.map +1 -1
  87. package/dist/operations/semantic-advisor/predicate-rules-core.js +7 -140
  88. package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts +11 -12
  89. package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts.map +1 -1
  90. package/dist/operations/semantic-advisor/predicate-rules-launcher.js +6 -94
  91. package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts +16 -0
  92. package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts.map +1 -1
  93. package/dist/operations/semantic-advisor/predicate-rules-policy.js +7 -150
  94. package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts +9 -0
  95. package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts.map +1 -1
  96. package/dist/operations/semantic-advisor/predicate-rules-product-tail.js +7 -102
  97. package/dist/operations/semantic-advisor/predicate-rules-product.d.ts +13 -0
  98. package/dist/operations/semantic-advisor/predicate-rules-product.d.ts.map +1 -1
  99. package/dist/operations/semantic-advisor/predicate-rules-product.js +7 -133
  100. package/dist/operations/semantic-advisor/types.d.ts +1 -0
  101. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  102. package/dist/plugins/compose-ontology-packs.d.ts +51 -0
  103. package/dist/plugins/compose-ontology-packs.d.ts.map +1 -0
  104. package/dist/plugins/compose-ontology-packs.js +257 -0
  105. package/dist/plugins/compose-semantic-classifier.d.ts +42 -0
  106. package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -0
  107. package/dist/plugins/compose-semantic-classifier.js +211 -0
  108. package/dist/plugins/external-allowlist.d.ts +10 -0
  109. package/dist/plugins/external-allowlist.d.ts.map +1 -0
  110. package/dist/plugins/external-allowlist.js +16 -0
  111. package/dist/plugins/index.d.ts +9 -0
  112. package/dist/plugins/index.d.ts.map +1 -0
  113. package/dist/plugins/index.js +33 -0
  114. package/dist/plugins/load-plugin.d.ts +19 -0
  115. package/dist/plugins/load-plugin.d.ts.map +1 -0
  116. package/dist/plugins/load-plugin.js +59 -0
  117. package/dist/plugins/project-config.d.ts +28 -0
  118. package/dist/plugins/project-config.d.ts.map +1 -0
  119. package/dist/plugins/project-config.js +90 -0
  120. package/dist/plugins/registry.d.ts +93 -0
  121. package/dist/plugins/registry.d.ts.map +1 -0
  122. package/dist/plugins/registry.js +338 -0
  123. package/dist/plugins/resolve-package.d.ts +47 -0
  124. package/dist/plugins/resolve-package.d.ts.map +1 -0
  125. package/dist/plugins/resolve-package.js +262 -0
  126. package/dist/plugins/source-analysis-service.d.ts +44 -0
  127. package/dist/plugins/source-analysis-service.d.ts.map +1 -0
  128. package/dist/plugins/source-analysis-service.js +232 -0
  129. package/dist/prolog/janitor.d.ts.map +1 -1
  130. package/dist/prolog/janitor.js +1 -1
  131. package/dist/prolog/store-lock.d.ts +1 -1
  132. package/dist/prolog/store-lock.d.ts.map +1 -1
  133. package/dist/proof/inspect.js +1 -1
  134. package/dist/proof/producers/playwright-case-id.js +2 -2
  135. package/dist/proof/producers/playwright-reporter.js +4 -4
  136. package/dist/public/extractors/symbols-coordinator.d.ts +1 -1
  137. package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
  138. package/dist/public/extractors/symbols-coordinator.js +1 -1
  139. package/dist/public/impact/analyzer.d.ts +1 -1
  140. package/dist/public/impact/analyzer.d.ts.map +1 -1
  141. package/dist/public/impact/analyzer.js +6 -4
  142. package/dist/public/operations/catalog.d.ts +4 -1
  143. package/dist/public/operations/catalog.d.ts.map +1 -1
  144. package/dist/public/operations/check-executor.js +1 -1
  145. package/dist/public/operations/check-helpers.d.ts +1 -1
  146. package/dist/public/operations/check-helpers.d.ts.map +1 -1
  147. package/dist/public/operations/check-helpers.js +1 -1
  148. package/dist/public/operations/contracts.d.ts.map +1 -1
  149. package/dist/public/operations/contracts.js +35 -12
  150. package/dist/public/operations/discovery-entities.d.ts +12 -0
  151. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  152. package/dist/public/operations/discovery-entities.js +34 -0
  153. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  154. package/dist/public/operations/discovery-executors.js +23 -18
  155. package/dist/public/operations/prolog-json.d.ts +1 -1
  156. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  157. package/dist/public/operations/prolog-json.js +7 -7
  158. package/dist/public/operations/runtime-types.d.ts +16 -1
  159. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  160. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  161. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  162. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  163. package/dist/public/operations/specs/check.d.ts +1 -1
  164. package/dist/public/operations/specs/discovery.d.ts +3 -0
  165. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  166. package/dist/public/operations/specs/discovery.js +3 -0
  167. package/dist/public/operations/specs/proof.js +1 -1
  168. package/dist/public/operations/specs/reporting.d.ts +1 -0
  169. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  170. package/dist/public/operations/specs/reporting.js +2 -2
  171. package/dist/public/operations/specs/semantic.d.ts +1 -1
  172. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  173. package/dist/public/operations/specs/semantic.js +54 -4
  174. package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
  175. package/dist/public/operations/symbol-repair-plan.js +3 -1
  176. package/dist/public/operations/types.d.ts +5 -0
  177. package/dist/public/operations/types.d.ts.map +1 -1
  178. package/dist/public/proof-protocol.js +4 -4
  179. package/dist/public/skills/kibi-usage/SKILL.md +4 -1
  180. package/dist/public/skills/kibi-usage/resources/proof.md +45 -0
  181. package/dist/public/symbol-granularity.d.ts +1 -1
  182. package/dist/public/symbol-granularity.d.ts.map +1 -1
  183. package/dist/public/symbol-granularity.generated.d.ts.map +1 -1
  184. package/dist/public/symbol-granularity.generated.js +38 -5
  185. package/dist/report/html-report.css +1239 -281
  186. package/dist/runtime/cli-runtime.d.ts.map +1 -1
  187. package/dist/runtime/cli-runtime.js +18 -0
  188. package/dist/traceability/symbol-extract.d.ts +24 -7
  189. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  190. package/dist/traceability/symbol-extract.js +64 -208
  191. package/dist/utils/rule-registry.generated.d.ts +5 -0
  192. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  193. package/dist/utils/rule-registry.generated.js +6 -0
  194. package/package.json +14 -11
  195. package/src/public/extractors/symbols-coordinator.ts +1 -0
  196. package/src/public/impact/analyzer.ts +15 -12
  197. package/src/public/operations/check-executor.ts +1 -1
  198. package/src/public/operations/check-helpers.ts +2 -2
  199. package/src/public/operations/contracts.ts +40 -12
  200. package/src/public/operations/discovery-entities.ts +46 -0
  201. package/src/public/operations/discovery-executors.ts +39 -26
  202. package/src/public/operations/prolog-json.ts +13 -5
  203. package/src/public/operations/runtime-types.ts +21 -2
  204. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  205. package/src/public/operations/specs/discovery.ts +3 -0
  206. package/src/public/operations/specs/proof.ts +1 -1
  207. package/src/public/operations/specs/reporting.ts +2 -2
  208. package/src/public/operations/specs/semantic.ts +79 -17
  209. package/src/public/operations/symbol-repair-plan.ts +3 -4
  210. package/src/public/operations/types.ts +5 -0
  211. package/src/public/proof-fingerprint.ts +1 -1
  212. package/src/public/proof-protocol-types.d.ts +1 -1
  213. package/src/public/proof-protocol.ts +4 -4
  214. package/src/public/skills/kibi-usage/SKILL.md +4 -1
  215. package/src/public/skills/kibi-usage/resources/proof.md +45 -0
  216. package/src/public/symbol-granularity.generated.ts +45 -12
  217. package/src/public/symbol-granularity.ts +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"cli-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/cli-runtime.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAIV,gBAAgB,EAEhB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,6BAA6B,CAAC;AAErC,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAOR;AA0ED,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,cAAmB,GAC3B,gBAAgB,CAgHlB"}
1
+ {"version":3,"file":"cli-runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/cli-runtime.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAKV,gBAAgB,EAEhB,cAAc,EACf,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,6BAA6B,CAAC;AAErC,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAOR;AAkFD,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,cAAmB,GAC3B,gBAAgB,CAwHlB"}
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { retryAttachAfterBreakingStaleLock } from "../prolog/store-lock.js";
3
3
  import { EngineClient } from "../engine.js";
4
+ import { CapabilityRegistryCache, ensureCapabilityRegistry, } from "../plugins/registry.js";
4
5
  import { nodeFilesystem, nodeGit, nodeNetwork, } from "../public/operations/node-ports.js";
5
6
  import { resolveBranchAttachment, } from "../utils/branch-resolver.js";
6
7
  export function attachmentFailureMessage(attachment) {
@@ -57,9 +58,18 @@ function enginePort(port, signal) {
57
58
  execute: (command, commandSignal) => execute.call(port, command, commandSignal ?? signal),
58
59
  };
59
60
  }
61
+ function resolvePluginsOption(plugins) {
62
+ if (plugins === undefined)
63
+ return undefined;
64
+ if (typeof plugins === "function")
65
+ return plugins;
66
+ return async () => plugins;
67
+ }
60
68
  // implements REQ-kibi-operation-interface-parity
61
69
  export function createCliRuntime(options = {}) {
62
70
  const ownedPrologs = new WeakMap();
71
+ // Per-runtime cache — not a process-global singleton.
72
+ const pluginCache = new CapabilityRegistryCache();
63
73
  return {
64
74
  open: async (spec, invocationOptions = {}) => {
65
75
  const merged = {
@@ -70,6 +80,12 @@ export function createCliRuntime(options = {}) {
70
80
  const signal = merged.signal ?? new AbortController().signal;
71
81
  const clock = merged.clock ?? (() => new Date());
72
82
  const git = merged.git ?? nodeGit;
83
+ const injectedPlugins = resolvePluginsOption(merged.plugins);
84
+ const ensurePlugins = async () => {
85
+ if (injectedPlugins)
86
+ return injectedPlugins();
87
+ return ensureCapabilityRegistry(root, { cache: pluginCache });
88
+ };
73
89
  const contextBase = {
74
90
  workspaceRoot: root,
75
91
  signal,
@@ -77,6 +93,8 @@ export function createCliRuntime(options = {}) {
77
93
  fs: merged.fs ?? nodeFilesystem,
78
94
  git,
79
95
  net: merged.net ?? nodeNetwork,
96
+ ensurePlugins,
97
+ ...(merged.plugins !== undefined ? { plugins: merged.plugins } : {}),
80
98
  };
81
99
  if (!spec.requiresProlog) {
82
100
  // Read-only operations such as status may choose to use an explicitly
@@ -1,6 +1,10 @@
1
- import { Scope } from "ts-morph";
1
+ import type { SourceAnalysisResult as SdkSourceAnalysisResult } from "kibi-plugin-sdk";
2
+ import { isPrivateClassMember } from "../extractors/symbols-ts.js";
2
3
  import { type SymbolKind, type SymbolRole } from "../public/symbol-granularity.js";
3
4
  import type { HunkRange, StagedFile } from "./git-staged.js";
5
+ type SourceAnalysisResult = SdkSourceAnalysisResult & {
6
+ providerId?: string | null;
7
+ };
4
8
  type TraceabilityRelationship = {
5
9
  type: string;
6
10
  to: string;
@@ -25,10 +29,23 @@ export interface ManifestLookupEntry {
25
29
  }
26
30
  export type ManifestLookup = Map<string, ManifestLookupEntry>;
27
31
  export declare function createManifestLookupSentinelKey(manifestPath: string): string;
28
- export declare function extractSymbolsFromStagedFile(stagedFile: StagedFile, manifestLookup?: ManifestLookup): ExtractedSymbol[];
29
- export declare function isPrivateClassMember(member: {
30
- getName?: () => string;
31
- getScope?: () => Scope;
32
- }): boolean;
33
- export {};
32
+ export type ExtractSymbolsOptions = Readonly<{
33
+ /**
34
+ * Host-owned analysis. Prefer SourceAnalysisService / capability registry.
35
+ * When omitted, falls back to the builtin ts-morph provider for parity.
36
+ */
37
+ analyzeText?: (filePath: string, content: string) => SourceAnalysisResult | null | Promise<SourceAnalysisResult | null>;
38
+ }>;
39
+ export declare function extractSymbolsFromStagedFile(stagedFile: StagedFile, manifestLookup?: ManifestLookup, options?: ExtractSymbolsOptions): ExtractedSymbol[];
40
+ /**
41
+ * Async staged symbol extraction. Defaults to deterministic builtin analysis.
42
+ * Pass an explicit `registry` only from allowlisted async surfaces that compose
43
+ * replace/augment/shadow (e.g. symbol repair). Maintenance paths (`check`,
44
+ * impact, sync, status, proof) must omit `registry` so external extractors
45
+ * never participate.
46
+ */
47
+ export declare function extractSymbolsFromStagedFileAsync(stagedFile: StagedFile, manifestLookup: ManifestLookup | undefined, options: ExtractSymbolsOptions & Readonly<{
48
+ registry?: import("../plugins/registry.js").CapabilityRegistry;
49
+ }>): Promise<ExtractedSymbol[]>;
50
+ export { isPrivateClassMember };
34
51
  //# sourceMappingURL=symbol-extract.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,EAA+B,MAAM,UAAU,CAAC;AAEvE,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAU7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG5E;AAmOD,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,EAAE,CA2SnB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE;IAC3C,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,KAAK,CAAC;CACxB,GAAG,OAAO,CASV"}
1
+ {"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,IAAI,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,OAAO,EAEL,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,oBAAoB,GAAG,uBAAuB,GAAG;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAU7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG5E;AAyND,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,oBAAoB,GAAG,IAAI,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACzE,CAAC,CAAC;AAWH,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,EAC/B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,eAAe,EAAE,CAkCnB;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,OAAO,EAAE,qBAAqB,GAC5B,QAAQ,CAAC;IACP,QAAQ,CAAC,EAAE,OAAO,wBAAwB,EAAE,kBAAkB,CAAC;CAChE,CAAC,GACH,OAAO,CAAC,eAAe,EAAE,CAAC,CA8B5B;AAwCD,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
- import { Project, Scope, ScriptKind } from "ts-morph";
3
2
  import { readManifestWithCoordinateOverlay } from "../extractors/manifest.js";
3
+ import { createTsMorphSourceAnalysisProvider, isPrivateClassMember, } from "../extractors/symbols-ts.js";
4
4
  import { inferSymbolRole, } from "../public/symbol-granularity.js";
5
5
  const TRACEABILITY_RELATIONSHIP_TYPES = new Set([
6
6
  "implements",
@@ -122,24 +122,13 @@ function buildSymbolResult(stagedFile, name, kind, span, inlineReqLinks, manifes
122
122
  };
123
123
  }
124
124
  // Simple in-memory cache keyed by blob sha with 30s TTL
125
- const sourceFileCache = new Map();
125
+ const analysisCache = new Map();
126
126
  const CACHE_TTL_MS = 30 * 1000;
127
- const project = new Project({ skipAddingFilesFromTsConfig: true });
128
127
  function computeContentSha(content) {
129
128
  const h = createHash("sha256");
130
129
  h.update(content);
131
130
  return h.digest("hex");
132
131
  }
133
- function chooseScriptKind(path) {
134
- const lower = path.toLowerCase();
135
- if (lower.endsWith(".tsx"))
136
- return ScriptKind.TSX;
137
- if (lower.endsWith(".ts") || lower.endsWith(".mts") || lower.endsWith(".cts"))
138
- return ScriptKind.TS;
139
- if (lower.endsWith(".jsx"))
140
- return ScriptKind.JSX;
141
- return ScriptKind.JS;
142
- }
143
132
  function parseReqDirectives(text) {
144
133
  // look for lines containing implements REQ-123 or implements: REQ-1, REQ-2
145
134
  // Stop at end-of-line and only accept IDs starting with an uppercase letter
@@ -167,210 +156,92 @@ function parseReqDirectives(text) {
167
156
  function rangesIntersect(aStart, aEnd, bStart, bEnd) {
168
157
  return aStart <= bEnd && bStart <= aEnd;
169
158
  }
159
+ function analyzeWithBuiltinFallback(filePath, content) {
160
+ const provider = createTsMorphSourceAnalysisProvider();
161
+ if (!provider.supportsFile(filePath))
162
+ return null;
163
+ return provider.analyzeText(filePath, content);
164
+ }
170
165
  export function extractSymbolsFromStagedFile(
171
166
  // implements REQ-008
172
- stagedFile, manifestLookup) {
167
+ stagedFile, manifestLookup, options) {
173
168
  const content = stagedFile.content ?? "";
174
- const sha = computeContentSha(`${content}|${stagedFile.path}`);
169
+ const sha = computeContentSha(`${content}|${stagedFile.path}|${options?.analyzeText ? "custom" : "builtin"}`);
175
170
  // TTL cache lookup
176
171
  const now = Date.now();
177
- let cached = sourceFileCache.get(sha);
172
+ let cached = analysisCache.get(sha);
178
173
  if (!cached || now - cached.ts > CACHE_TTL_MS) {
179
- // create or recreate SourceFile in project (in-memory)
180
174
  try {
181
- const scriptKind = chooseScriptKind(stagedFile.path);
182
- const sf = project.createSourceFile(`${stagedFile.path}::staged`, content, {
183
- overwrite: true,
184
- scriptKind,
185
- });
186
- cached = { tsf: sf, ts: now };
187
- sourceFileCache.set(sha, cached);
175
+ const analyze = options?.analyzeText ?? analyzeWithBuiltinFallback;
176
+ const raw = analyze(stagedFile.path, content);
177
+ if (raw instanceof Promise) {
178
+ throw new Error("extractSymbolsFromStagedFile received async analyzeText; use extractSymbolsFromStagedFileAsync");
179
+ }
180
+ cached = { result: raw, ts: now };
181
+ analysisCache.set(sha, cached);
188
182
  }
189
- catch (err) {
183
+ catch (error) {
184
+ if (error instanceof Error &&
185
+ error.message.includes("extractSymbolsFromStagedFileAsync")) {
186
+ throw error;
187
+ }
190
188
  // on parse error, cache null to avoid retry storms briefly
191
- cached = { tsf: null, ts: now };
192
- sourceFileCache.set(sha, cached);
193
- }
194
- }
195
- const sf = cached.tsf;
196
- if (!sf)
197
- return [];
198
- const results = [];
199
- // helpers to compute line spans
200
- const getSpan = (startPos, endPos) => {
201
- const start = sf.getLineAndColumnAtPos(startPos);
202
- const end = sf.getLineAndColumnAtPos(endPos);
203
- return { startLine: start.line, endLine: end.line };
204
- };
205
- // Functions
206
- for (const fn of sf.getFunctions()) {
207
- if (!fn.isExported())
208
- continue;
209
- try {
210
- const name = fn.getName() ?? "<anonymous>";
211
- const nameNode = fn.getNameNode();
212
- const start = nameNode ? nameNode.getStart() : fn.getStart();
213
- const end = fn.getEnd();
214
- const span = getSpan(start, end);
215
- const reqLinks = parseReqDirectives(`${fn.getFullText()}\n${fn
216
- .getJsDocs()
217
- .map((d) => d.getFullText())
218
- .join("\n")}`);
219
- results.push(buildSymbolResult(stagedFile, name, "function", span, reqLinks, manifestLookup));
220
- }
221
- catch {
222
- void stagedFile.path;
189
+ cached = { result: null, ts: now };
190
+ analysisCache.set(sha, cached);
223
191
  }
224
192
  }
225
- // Classes
226
- for (const cls of sf.getClasses()) {
227
- if (!cls.isExported())
228
- continue;
193
+ return symbolsFromAnalysis(stagedFile, cached.result, manifestLookup);
194
+ }
195
+ /**
196
+ * Async staged symbol extraction. Defaults to deterministic builtin analysis.
197
+ * Pass an explicit `registry` only from allowlisted async surfaces that compose
198
+ * replace/augment/shadow (e.g. symbol repair). Maintenance paths (`check`,
199
+ * impact, sync, status, proof) must omit `registry` so external extractors
200
+ * never participate.
201
+ */
202
+ // implements REQ-capability-plugin-activation-disclosure-v1
203
+ export async function extractSymbolsFromStagedFileAsync(stagedFile, manifestLookup, options) {
204
+ const content = stagedFile.content ?? "";
205
+ const sha = computeContentSha(`${content}|${stagedFile.path}|async|${options.registry ? "registry" : "custom"}`);
206
+ const now = Date.now();
207
+ let cached = analysisCache.get(sha);
208
+ if (!cached || now - cached.ts > CACHE_TTL_MS) {
229
209
  try {
230
- const name = cls.getName() ?? "<anonymous>";
231
- const start = cls.getNameNode()?.getStart() ?? cls.getStart();
232
- const end = cls.getEnd();
233
- const span = getSpan(start, end);
234
- const reqLinks = parseReqDirectives(getJsDocText(cls.getJsDocs()));
235
- results.push(buildSymbolResult(stagedFile, name, "class", span, reqLinks, manifestLookup));
236
- }
237
- catch {
238
- void stagedFile.path;
239
- }
240
- for (const method of typeof cls.getMethods === "function"
241
- ? cls.getMethods()
242
- : []) {
243
- try {
244
- if (isPrivateClassMember(method))
245
- continue;
246
- const name = formatMethodSymbolName(cls.getName(), method.getName());
247
- const start = method.getNameNode()?.getStart() ?? method.getStart();
248
- const end = method.getEnd();
249
- const span = getSpan(start, end);
250
- const reqLinks = parseReqDirectives(`${method.getFullText()}\n${method
251
- .getJsDocs()
252
- .map((d) => d.getFullText())
253
- .join("\n")}`);
254
- results.push(buildSymbolResult(stagedFile, name, "method", span, reqLinks, manifestLookup));
255
- }
256
- catch {
257
- void stagedFile.path;
258
- }
259
- }
260
- for (const property of typeof cls.getProperties === "function"
261
- ? cls.getProperties()
262
- : []) {
263
- try {
264
- if (isPrivateClassMember(property))
265
- continue;
266
- const name = formatMethodSymbolName(cls.getName(), property.getName());
267
- const start = property.getNameNode()?.getStart() ?? property.getStart();
268
- const end = property.getEnd();
269
- const span = getSpan(start, end);
270
- const reqLinks = parseReqDirectives(`${property.getFullText()}\n${property
271
- .getJsDocs()
272
- .map((d) => d.getFullText())
273
- .join("\n")}`);
274
- results.push(buildSymbolResult(stagedFile, name, "property", span, reqLinks, manifestLookup));
275
- }
276
- catch {
277
- void stagedFile.path;
210
+ let analysis = null;
211
+ if (options.analyzeText) {
212
+ analysis = await options.analyzeText(stagedFile.path, content);
278
213
  }
279
- }
280
- for (const accessor of [
281
- ...(typeof cls.getGetAccessors === "function"
282
- ? cls.getGetAccessors()
283
- : []),
284
- ...(typeof cls.getSetAccessors === "function"
285
- ? cls.getSetAccessors()
286
- : []),
287
- ]) {
288
- try {
289
- if (isPrivateClassMember(accessor))
290
- continue;
291
- const name = formatMethodSymbolName(cls.getName(), accessor.getName());
292
- const start = accessor.getNameNode()?.getStart() ?? accessor.getStart();
293
- const end = accessor.getEnd();
294
- const span = getSpan(start, end);
295
- const reqLinks = parseReqDirectives(`${accessor.getFullText()}\n${accessor
296
- .getJsDocs()
297
- .map((d) => d.getFullText())
298
- .join("\n")}`);
299
- results.push(buildSymbolResult(stagedFile, name, "accessor", span, reqLinks, manifestLookup));
214
+ else if (options.registry) {
215
+ const { createSourceAnalysisService } = await import("../plugins/source-analysis-service.js");
216
+ analysis = await createSourceAnalysisService({
217
+ registry: options.registry,
218
+ }).analyzeText(stagedFile.path, content);
300
219
  }
301
- catch {
302
- void stagedFile.path;
220
+ else {
221
+ analysis = analyzeWithBuiltinFallback(stagedFile.path, content);
303
222
  }
304
- }
305
- }
306
- // Enums
307
- for (const en of sf.getEnums()) {
308
- if (!en.isExported())
309
- continue;
310
- try {
311
- const name = en.getName() ?? "<anonymous>";
312
- const start = en.getNameNode()?.getStart() ?? en.getStart();
313
- const end = en.getEnd();
314
- const span = getSpan(start, end);
315
- const reqLinks = parseReqDirectives(en.getText());
316
- results.push(buildSymbolResult(stagedFile, name, "enum", span, reqLinks, manifestLookup));
317
- }
318
- catch {
319
- void stagedFile.path;
320
- }
321
- }
322
- for (const iface of typeof sf.getInterfaces === "function"
323
- ? sf.getInterfaces()
324
- : []) {
325
- if (!iface.isExported())
326
- continue;
327
- try {
328
- const name = iface.getName();
329
- const start = iface.getNameNode().getStart();
330
- const end = iface.getEnd();
331
- const span = getSpan(start, end);
332
- const reqLinks = parseReqDirectives(iface.getText());
333
- results.push(buildSymbolResult(stagedFile, name, "interface", span, reqLinks, manifestLookup));
223
+ cached = { result: analysis, ts: now };
224
+ analysisCache.set(sha, cached);
334
225
  }
335
226
  catch {
336
- void stagedFile.path;
227
+ cached = { result: null, ts: now };
228
+ analysisCache.set(sha, cached);
337
229
  }
338
230
  }
339
- for (const alias of typeof sf.getTypeAliases === "function"
340
- ? sf.getTypeAliases()
341
- : []) {
342
- if (!alias.isExported())
343
- continue;
231
+ return symbolsFromAnalysis(stagedFile, cached.result, manifestLookup);
232
+ }
233
+ function symbolsFromAnalysis(stagedFile, analysis, manifestLookup) {
234
+ if (!analysis)
235
+ return [];
236
+ const results = [];
237
+ for (const symbol of analysis.symbols) {
344
238
  try {
345
- const name = alias.getName();
346
- const start = alias.getNameNode().getStart();
347
- const end = alias.getEnd();
348
- const span = getSpan(start, end);
349
- const reqLinks = parseReqDirectives(alias.getText());
350
- results.push(buildSymbolResult(stagedFile, name, "type", span, reqLinks, manifestLookup));
239
+ results.push(buildSymbolResult(stagedFile, symbol.name, symbol.kind, { startLine: symbol.startLine, endLine: symbol.endLine }, parseReqDirectives(symbol.directiveText ?? ""), manifestLookup));
351
240
  }
352
241
  catch {
353
242
  void stagedFile.path;
354
243
  }
355
244
  }
356
- // Variable statements (exported)
357
- for (const vs of sf.getVariableStatements()) {
358
- if (!vs.isExported())
359
- continue;
360
- for (const decl of vs.getDeclarations()) {
361
- try {
362
- const name = decl.getName();
363
- const start = decl.getNameNode()?.getStart() ?? decl.getStart();
364
- const end = decl.getEnd();
365
- const span = getSpan(start, end);
366
- const reqLinks = parseReqDirectives(decl.getText());
367
- results.push(buildSymbolResult(stagedFile, name, "variable", span, reqLinks, manifestLookup));
368
- }
369
- catch {
370
- void stagedFile.path;
371
- }
372
- }
373
- }
374
245
  // Filter to only include symbols that intersect with at least one hunk
375
246
  // (unless it's a new file or rename, in which case we include all)
376
247
  const shouldFilterByHunks = stagedFile.status === "M" && stagedFile.hunkRanges.length > 0;
@@ -379,22 +250,7 @@ stagedFile, manifestLookup) {
379
250
  }
380
251
  return results;
381
252
  }
382
- export function isPrivateClassMember(member) {
383
- const name = typeof member.getName === "function" ? member.getName() : "";
384
- if (name.startsWith("#")) {
385
- return true;
386
- }
387
- if (typeof member.getScope === "function") {
388
- return member.getScope() === Scope.Private;
389
- }
390
- return false;
391
- }
392
- function formatMethodSymbolName(className, methodName) {
393
- return className ? `${className}.${methodName}` : methodName;
394
- }
395
- function getJsDocText(jsDocs) {
396
- return jsDocs.map((d) => d.getFullText()).join("\n");
397
- }
253
+ export { isPrivateClassMember };
398
254
  function intersectingHunks(startLine, endLine, hunks) {
399
255
  const out = [];
400
256
  for (const h of hunks) {
@@ -93,5 +93,10 @@ export declare const GENERATED_RULES: readonly [{
93
93
  readonly description: "Every inventoried assertive proposition is modeled or explicitly classified";
94
94
  readonly enforcementClass: "migration";
95
95
  readonly category: "integrity";
96
+ }, {
97
+ readonly name: "proof-contract-symbols";
98
+ readonly description: "Detect unresolved required_proofs.symbol_id values, type-shape required proofs, and proof_bindings.source_file disagreement with the named symbol sourceFile";
99
+ readonly enforcementClass: "advisory";
100
+ readonly category: "integrity";
96
101
  }];
97
102
  //# sourceMappingURL=rule-registry.generated.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmIlB,CAAC"}
1
+ {"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0IlB,CAAC"}
@@ -122,4 +122,10 @@ export const GENERATED_RULES = [
122
122
  enforcementClass: "migration",
123
123
  category: "integrity",
124
124
  },
125
+ {
126
+ name: "proof-contract-symbols",
127
+ description: "Detect unresolved required_proofs.symbol_id values, type-shape required proofs, and proof_bindings.source_file disagreement with the named symbol sourceFile",
128
+ enforcementClass: "advisory",
129
+ category: "integrity",
130
+ },
125
131
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
@@ -10,14 +10,7 @@
10
10
  "bin": {
11
11
  "kibi": "bin/kibi"
12
12
  },
13
- "files": [
14
- "dist",
15
- "bin",
16
- "schema",
17
- "src/schemas",
18
- "src/public",
19
- "templates"
20
- ],
13
+ "files": ["dist", "bin", "schema", "src/schemas", "src/public", "templates"],
21
14
  "scripts": {
22
15
  "build": "tsc -p tsconfig.json && rm -rf dist/public/skills && mkdir -p dist/public/skills dist/report && cp -r src/public/skills/. dist/public/skills/ && cp src/report/html-report.css dist/report/html-report.css && node ../../scripts/generate-entity-schema.mjs --check",
23
16
  "test": "node ../../scripts/run-owned-engine-tests.mjs -- bun test --timeout 15000 .",
@@ -55,6 +48,10 @@
55
48
  "types": "./dist/runtime/cli-runtime.d.ts",
56
49
  "default": "./dist/runtime/cli-runtime.js"
57
50
  },
51
+ "./plugins": {
52
+ "types": "./dist/plugins/index.d.ts",
53
+ "default": "./dist/plugins/index.js"
54
+ },
58
55
  "./operations/node-ports": {
59
56
  "types": "./dist/public/operations/node-ports.d.ts",
60
57
  "default": "./dist/public/operations/node-ports.js"
@@ -216,6 +213,10 @@
216
213
  "types": "./dist/public/ignore-policy.d.ts",
217
214
  "import": "./dist/public/ignore-policy.js",
218
215
  "default": "./dist/public/ignore-policy.js"
216
+ },
217
+ "./env-bootstrap": {
218
+ "types": "./dist/env/bootstrap.d.ts",
219
+ "default": "./dist/env/bootstrap.js"
219
220
  }
220
221
  },
221
222
  "types": "./dist/cli.d.ts",
@@ -226,15 +227,17 @@
226
227
  "fast-glob": "^3.2.12",
227
228
  "gray-matter": "^4.0.3",
228
229
  "js-yaml": "^4.1.0",
229
- "kibi-core": "^0.12.0",
230
+ "kibi-core": "^0.13.0",
231
+ "kibi-plugin-builtin": "^0.2.0",
232
+ "kibi-plugin-sdk": "^0.2.0",
230
233
  "saxes": "^6.0.0",
231
- "ts-morph": "^23.0.0",
232
234
  "ignore": "^5.3.0",
233
235
  "yaml": "^2.9.0"
234
236
  },
235
237
  "devDependencies": {
236
238
  "@types/node": "latest",
237
239
  "semver": "^7.7.4",
240
+ "ts-morph": "^23.0.0",
238
241
  "typescript": "^5.7.0"
239
242
  },
240
243
  "license": "AGPL-3.0-or-later",
@@ -18,6 +18,7 @@
18
18
 
19
19
  export {
20
20
  analyzeSourceText,
21
+ analyzeSourceTextWithRegistry,
21
22
  enrichSymbolCoordinates,
22
23
  type ManifestSymbolEntry,
23
24
  type AnalyzeSourceTextOptions,
@@ -1,6 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import type { ExtractedSymbol } from "../../traceability/symbol-extract.js";
3
- import { extractSymbolsFromStagedFile } from "../../traceability/symbol-extract.js";
3
+ import { extractSymbolsFromStagedFileAsync } from "../../traceability/symbol-extract.js";
4
4
  import {
5
5
  createSemanticReviewDiagnostics,
6
6
  createSymbolGranularityDiagnostics,
@@ -21,9 +21,9 @@ import type {
21
21
  ChangedFileImpactResult,
22
22
  } from "./types.js";
23
23
 
24
- export function analyzeChangedFileImpact(
24
+ export async function analyzeChangedFileImpact(
25
25
  options: ChangedFileImpactOptions,
26
- ): ChangedFileImpactResult {
26
+ ): Promise<ChangedFileImpactResult> {
27
27
  const workspaceRoot = path.resolve(options.workspaceRoot);
28
28
  const sourceChanges = collectSourceChanges({ ...options, workspaceRoot });
29
29
  const sourceFiles = uniqueSorted(sourceChanges.map((change) => change.file));
@@ -34,17 +34,20 @@ export function analyzeChangedFileImpact(
34
34
 
35
35
  for (const change of sourceChanges) {
36
36
  sourceContentByFile.set(change.file, change.content);
37
+ // Maintenance path: builtin-only (do not pass registry / workspaceRoot).
38
+ const extracted = await extractSymbolsFromStagedFileAsync(
39
+ {
40
+ path: change.file,
41
+ status: change.status,
42
+ hunkRanges: [...change.hunkRanges],
43
+ content: change.content,
44
+ },
45
+ manifestLookup,
46
+ {},
47
+ );
37
48
  symbolsByFile.set(
38
49
  change.file,
39
- extractSymbolsFromStagedFile(
40
- {
41
- path: change.file,
42
- status: change.status,
43
- hunkRanges: [...change.hunkRanges],
44
- content: change.content,
45
- },
46
- manifestLookup,
47
- ).filter((symbol) => symbol.hunkRanges.length > 0),
50
+ extracted.filter((symbol) => symbol.hunkRanges.length > 0),
48
51
  );
49
52
  }
50
53
 
@@ -135,7 +135,7 @@ export async function executeCheck(
135
135
  // version. `args.rules` is an invocation-time diagnostic selector only.
136
136
  const rulesAllowlist = resolveCheckRules(args);
137
137
  const hasExplicitRules = args.rules !== undefined;
138
- const impactResult = analyzeKbCheckImpact(workspaceRoot, args);
138
+ const impactResult = await analyzeKbCheckImpact(workspaceRoot, args);
139
139
  const impactQualityDiagnostics = qualityDiagnosticsFromImpact(impactResult);
140
140
  const maxDiagnosticsOption =
141
141
  args.maxDiagnostics !== undefined
@@ -144,10 +144,10 @@ export function hasImpactOptions(args: CheckInput): boolean {
144
144
  }
145
145
 
146
146
  // implements REQ-mcp-tool-check
147
- export function analyzeKbCheckImpact(
147
+ export async function analyzeKbCheckImpact(
148
148
  workspaceRoot: string,
149
149
  args: CheckInput,
150
- ): ChangedFileImpactResult | undefined {
150
+ ): Promise<ChangedFileImpactResult | undefined> {
151
151
  if (!hasImpactOptions(args)) {
152
152
  return undefined;
153
153
  }