kibi-cli 0.12.8 → 0.14.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 (111) hide show
  1. package/dist/cli.js +1 -0
  2. package/dist/commands/check.d.ts +1 -0
  3. package/dist/commands/check.d.ts.map +1 -1
  4. package/dist/commands/check.js +117 -82
  5. package/dist/commands/discovery-shared.d.ts +1 -0
  6. package/dist/commands/discovery-shared.d.ts.map +1 -1
  7. package/dist/commands/discovery-shared.js +2 -191
  8. package/dist/commands/discovery-table.d.ts +3 -0
  9. package/dist/commands/discovery-table.d.ts.map +1 -0
  10. package/dist/commands/discovery-table.js +204 -0
  11. package/dist/commands/sync/discovery.d.ts.map +1 -1
  12. package/dist/commands/sync/discovery.js +8 -1
  13. package/dist/commands/sync/extraction.d.ts +6 -1
  14. package/dist/commands/sync/extraction.d.ts.map +1 -1
  15. package/dist/commands/sync/extraction.js +7 -3
  16. package/dist/commands/sync/persistence.d.ts.map +1 -1
  17. package/dist/commands/sync/persistence.js +29 -1
  18. package/dist/extractors/manifest.d.ts.map +1 -1
  19. package/dist/extractors/manifest.js +18 -0
  20. package/dist/extractors/markdown.d.ts +6 -0
  21. package/dist/extractors/markdown.d.ts.map +1 -1
  22. package/dist/extractors/symbols-coordinator.d.ts +1 -1
  23. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  24. package/dist/extractors/symbols-ts.js +62 -0
  25. package/dist/public/impact/analyzer.d.ts +3 -0
  26. package/dist/public/impact/analyzer.d.ts.map +1 -0
  27. package/dist/public/impact/analyzer.js +54 -0
  28. package/dist/public/impact/coverage-depth-quality.d.ts +4 -0
  29. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -0
  30. package/dist/public/impact/coverage-depth-quality.js +179 -0
  31. package/dist/public/impact/diagnostics.d.ts +7 -0
  32. package/dist/public/impact/diagnostics.d.ts.map +1 -0
  33. package/dist/public/impact/diagnostics.js +122 -0
  34. package/dist/public/impact/diff-meaning.d.ts +2 -0
  35. package/dist/public/impact/diff-meaning.d.ts.map +1 -0
  36. package/dist/public/impact/diff-meaning.js +101 -0
  37. package/dist/public/impact/full-kb-quality.d.ts +10 -0
  38. package/dist/public/impact/full-kb-quality.d.ts.map +1 -0
  39. package/dist/public/impact/full-kb-quality.js +158 -0
  40. package/dist/public/impact/manifest.d.ts +5 -0
  41. package/dist/public/impact/manifest.d.ts.map +1 -0
  42. package/dist/public/impact/manifest.js +43 -0
  43. package/dist/public/impact/requirement-quality.d.ts +4 -0
  44. package/dist/public/impact/requirement-quality.d.ts.map +1 -0
  45. package/dist/public/impact/requirement-quality.js +216 -0
  46. package/dist/public/impact/source-changes.d.ts +5 -0
  47. package/dist/public/impact/source-changes.d.ts.map +1 -0
  48. package/dist/public/impact/source-changes.js +129 -0
  49. package/dist/public/impact/summaries.d.ts +6 -0
  50. package/dist/public/impact/summaries.d.ts.map +1 -0
  51. package/dist/public/impact/summaries.js +68 -0
  52. package/dist/public/impact/symbol-quality-model.d.ts +21 -0
  53. package/dist/public/impact/symbol-quality-model.d.ts.map +1 -0
  54. package/dist/public/impact/symbol-quality-model.js +116 -0
  55. package/dist/public/impact/symbol-quality.d.ts +4 -0
  56. package/dist/public/impact/symbol-quality.d.ts.map +1 -0
  57. package/dist/public/impact/symbol-quality.js +159 -0
  58. package/dist/public/impact/types.d.ts +79 -0
  59. package/dist/public/impact/types.d.ts.map +1 -0
  60. package/dist/public/impact/types.js +1 -0
  61. package/dist/public/impact-diagnostics.d.ts +7 -0
  62. package/dist/public/impact-diagnostics.d.ts.map +1 -0
  63. package/dist/public/impact-diagnostics.js +5 -0
  64. package/dist/public/schemas/entity.d.ts.map +1 -1
  65. package/dist/public/schemas/entity.js +21 -0
  66. package/dist/public/skills/kibi-usage/SKILL.md +13 -5
  67. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  68. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +30 -0
  69. package/dist/public/skills/kibi-usage/resources/workflows.md +14 -0
  70. package/dist/public/symbol-granularity.d.ts +1 -1
  71. package/dist/public/symbol-granularity.d.ts.map +1 -1
  72. package/dist/public/symbol-granularity.js +2 -0
  73. package/dist/traceability/evidence-model.d.ts +1 -1
  74. package/dist/traceability/evidence-model.d.ts.map +1 -1
  75. package/dist/traceability/evidence-model.js +1 -1
  76. package/dist/traceability/staged-diagnostics.d.ts +6 -6
  77. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  78. package/dist/traceability/staged-diagnostics.js +12 -6
  79. package/dist/traceability/staged-impact-contract.js +1 -1
  80. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  81. package/dist/traceability/staged-symbols-manifest.js +23 -1
  82. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  83. package/dist/traceability/symbol-extract.js +41 -0
  84. package/dist/types/entities.d.ts +5 -1
  85. package/dist/types/entities.d.ts.map +1 -1
  86. package/dist/utils/prolog-query-plan-safety.d.ts +8 -0
  87. package/dist/utils/prolog-query-plan-safety.d.ts.map +1 -0
  88. package/dist/utils/prolog-query-plan-safety.js +47 -0
  89. package/dist/utils/rule-registry.d.ts.map +1 -1
  90. package/dist/utils/rule-registry.js +12 -0
  91. package/package.json +6 -2
  92. package/schema/entities.pl +4 -0
  93. package/src/public/impact/analyzer.ts +90 -0
  94. package/src/public/impact/coverage-depth-quality.ts +268 -0
  95. package/src/public/impact/diagnostics.ts +192 -0
  96. package/src/public/impact/diff-meaning.ts +121 -0
  97. package/src/public/impact/full-kb-quality.ts +203 -0
  98. package/src/public/impact/manifest.ts +57 -0
  99. package/src/public/impact/requirement-quality.ts +282 -0
  100. package/src/public/impact/source-changes.ts +180 -0
  101. package/src/public/impact/summaries.ts +100 -0
  102. package/src/public/impact/symbol-quality-model.ts +171 -0
  103. package/src/public/impact/symbol-quality.ts +207 -0
  104. package/src/public/impact/types.ts +99 -0
  105. package/src/public/impact-diagnostics.ts +22 -0
  106. package/src/public/schemas/entity.ts +23 -0
  107. package/src/public/skills/kibi-usage/SKILL.md +13 -5
  108. package/src/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  109. package/src/public/skills/kibi-usage/resources/relationship-directions.md +30 -0
  110. package/src/public/skills/kibi-usage/resources/workflows.md +14 -0
  111. package/src/public/symbol-granularity.ts +4 -0
@@ -0,0 +1,204 @@
1
+ import Table from "cli-table3";
2
+ const EMPTY_FIELDS = Object.freeze({});
3
+ export function renderDiscoveryTable(structured) {
4
+ if (!isFields(structured)) {
5
+ return null;
6
+ }
7
+ const payload = structured;
8
+ if (Array.isArray(payload.results)) {
9
+ return renderSearchTable(payload);
10
+ }
11
+ if (typeof payload.branch === "string" &&
12
+ typeof payload.syncState === "string") {
13
+ return renderStatusTable(payload);
14
+ }
15
+ if (Array.isArray(payload.nodes) && Array.isArray(payload.edges)) {
16
+ return renderGraphTable(payload);
17
+ }
18
+ if (Array.isArray(payload.rows) &&
19
+ payload.summary &&
20
+ typeof payload.summary === "object") {
21
+ return renderCoverageTable(payload);
22
+ }
23
+ if (Array.isArray(payload.rows)) {
24
+ return renderGapsTable(payload);
25
+ }
26
+ return null;
27
+ }
28
+ function renderSearchTable(payload) {
29
+ const rows = Array.isArray(payload.results) ? payload.results : [];
30
+ const table = new Table({
31
+ head: ["ID", "Type", "Title", "Score", "Reasons", "Snippet"],
32
+ wordWrap: true,
33
+ colWidths: [20, 10, 32, 8, 28, 44],
34
+ });
35
+ for (const row of rows) {
36
+ const match = fieldsFrom(row);
37
+ const entity = fieldsFrom(match.entity);
38
+ const reasons = Array.isArray(match.reasons)
39
+ ? match.reasons.join(", ")
40
+ : "";
41
+ table.push([
42
+ stringifyCell(entity.id),
43
+ stringifyCell(entity.type),
44
+ stringifyCell(entity.title),
45
+ stringifyCell(match.score),
46
+ reasons,
47
+ stringifyCell(match.snippet),
48
+ ]);
49
+ }
50
+ return [
51
+ `Search results: ${stringifyCell(payload.count)} total`,
52
+ table.toString(),
53
+ ].join("\n");
54
+ }
55
+ function renderStatusTable(payload) {
56
+ const table = new Table({
57
+ head: ["Field", "Value"],
58
+ colWidths: [18, 72],
59
+ wordWrap: true,
60
+ });
61
+ table.push(["Branch", stringifyCell(payload.branch)], ["Sync State", stringifyCell(payload.syncState)], ["Dirty", stringifyCell(payload.dirty)], ["Snapshot", stringifyCell(payload.snapshotId)], ["Synced At", stringifyCell(payload.syncedAt)], ["KB Path", stringifyCell(payload.kbPath)]);
62
+ return table.toString();
63
+ }
64
+ function renderGapsTable(payload) {
65
+ const rows = Array.isArray(payload.rows) ? payload.rows : [];
66
+ const table = new Table({
67
+ head: ["ID", "Type", "Status", "Missing", "Present", "Source"],
68
+ colWidths: [20, 10, 12, 24, 24, 40],
69
+ wordWrap: true,
70
+ });
71
+ for (const row of rows) {
72
+ const item = fieldsFrom(row);
73
+ table.push([
74
+ stringifyCell(item.id),
75
+ stringifyCell(item.type),
76
+ stringifyCell(item.status),
77
+ joinCells(item.missingRelationships),
78
+ joinCells(item.presentRelationships),
79
+ stringifyCell(item.source),
80
+ ]);
81
+ }
82
+ return [`Gap rows: ${stringifyCell(payload.count)}`, table.toString()].join("\n");
83
+ }
84
+ export function renderCoverageTable(payload) {
85
+ const summary = fieldsFrom(payload.summary);
86
+ const rows = Array.isArray(payload.rows) ? payload.rows : [];
87
+ const summaryTable = new Table({
88
+ head: ["Metric", "Value"],
89
+ colWidths: [24, 16],
90
+ });
91
+ for (const [key, value] of Object.entries(summary)) {
92
+ summaryTable.push([key, stringifyCell(value)]);
93
+ }
94
+ const firstRow = firstFields(rows);
95
+ const isRequirementCoverage = firstRow !== undefined && Object.hasOwn(firstRow, "scenarioCount");
96
+ const table = isRequirementCoverage
97
+ ? new Table({
98
+ head: [
99
+ "ID",
100
+ "Status",
101
+ "Priority",
102
+ "Coverage",
103
+ "Depth",
104
+ "Scen",
105
+ "Tests",
106
+ "Symbols",
107
+ "Gaps",
108
+ ],
109
+ colWidths: [20, 12, 12, 18, 32, 8, 8, 10, 28],
110
+ wordWrap: true,
111
+ })
112
+ : new Table({
113
+ head: ["ID", "Type", "Coverage", "Details", "Gaps"],
114
+ colWidths: [20, 10, 18, 28, 28],
115
+ wordWrap: true,
116
+ });
117
+ for (const row of rows) {
118
+ const item = fieldsFrom(row);
119
+ if (isRequirementCoverage) {
120
+ table.push([
121
+ stringifyCell(item.id),
122
+ stringifyCell(item.status),
123
+ stringifyCell(item.priority),
124
+ stringifyCell(item.coverageStatus),
125
+ stringifyCell(item.coverageDepth),
126
+ stringifyCell(item.scenarioCount),
127
+ stringifyCell(item.testCount),
128
+ stringifyCell(item.transitiveSymbolCount),
129
+ joinCells(item.gaps),
130
+ ]);
131
+ }
132
+ else {
133
+ table.push([
134
+ stringifyCell(item.id),
135
+ stringifyCell(item.type),
136
+ stringifyCell(item.coverageStatus),
137
+ `req=${stringifyCell(item.directRequirementCount)} test=${stringifyCell(item.testCount)} count=${stringifyCell(item.count)}`,
138
+ joinCells(item.gaps),
139
+ ]);
140
+ }
141
+ }
142
+ return [summaryTable.toString(), table.toString()].join("\n\n");
143
+ }
144
+ function renderGraphTable(payload) {
145
+ const nodes = Array.isArray(payload.nodes) ? payload.nodes : [];
146
+ const edges = Array.isArray(payload.edges) ? payload.edges : [];
147
+ const nodeTable = new Table({
148
+ head: ["Node ID", "Type", "Title", "Status"],
149
+ colWidths: [22, 10, 36, 12],
150
+ wordWrap: true,
151
+ });
152
+ for (const row of nodes) {
153
+ const item = fieldsFrom(row);
154
+ nodeTable.push([
155
+ stringifyCell(item.id),
156
+ stringifyCell(item.type),
157
+ stringifyCell(item.title),
158
+ stringifyCell(item.status),
159
+ ]);
160
+ }
161
+ const edgeTable = new Table({
162
+ head: ["Relationship", "From", "To"],
163
+ colWidths: [18, 22, 22],
164
+ wordWrap: true,
165
+ });
166
+ for (const row of edges) {
167
+ const item = fieldsFrom(row);
168
+ edgeTable.push([
169
+ stringifyCell(item.type),
170
+ stringifyCell(item.from),
171
+ stringifyCell(item.to),
172
+ ]);
173
+ }
174
+ return [
175
+ `Nodes: ${nodes.length} Edges: ${edges.length} Truncated: ${stringifyCell(payload.truncated)}`,
176
+ nodeTable.toString(),
177
+ edgeTable.toString(),
178
+ ].join("\n\n");
179
+ }
180
+ function isFields(value) {
181
+ return value !== null && typeof value === "object";
182
+ }
183
+ function fieldsFrom(value) {
184
+ return isFields(value) ? value : EMPTY_FIELDS;
185
+ }
186
+ function firstFields(values) {
187
+ const first = values[0];
188
+ return isFields(first) ? first : undefined;
189
+ }
190
+ function stringifyCell(value) {
191
+ if (value === null || value === undefined || value === "") {
192
+ return "-";
193
+ }
194
+ if (typeof value === "string") {
195
+ return value;
196
+ }
197
+ return String(value);
198
+ }
199
+ function joinCells(value) {
200
+ if (!Array.isArray(value) || value.length === 0) {
201
+ return "-";
202
+ }
203
+ return value.map((item) => stringifyCell(item)).join(", ");
204
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/discovery.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,GAAG,IAAI,CAIf;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IACT,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC,CA0BD"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/discovery.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAI3D,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,GAAG,IAAI,CAIf;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,GACnB,OAAO,CAAC;IACT,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC,CAkCD"}
@@ -18,6 +18,7 @@
18
18
  import * as path from "node:path";
19
19
  import fg from "fast-glob";
20
20
  import { getRelationshipsDir } from "../../extractors/relationships.js";
21
+ const MARKDOWN_DISCOVERY_IGNORE = ["**/README.md"];
21
22
  export function normalizeMarkdownPath(pattern) {
22
23
  if (!pattern)
23
24
  return null;
@@ -38,7 +39,9 @@ export async function discoverSourceFiles(cwd, paths) {
38
39
  const markdownFiles = await fg(markdownPatterns, {
39
40
  cwd,
40
41
  absolute: true,
42
+ ignore: [...MARKDOWN_DISCOVERY_IGNORE],
41
43
  });
44
+ const entityMarkdownFiles = markdownFiles.filter((file) => !file.endsWith("/README.md"));
42
45
  const manifestFiles = paths.symbols
43
46
  ? await fg(paths.symbols, {
44
47
  cwd,
@@ -46,5 +49,9 @@ export async function discoverSourceFiles(cwd, paths) {
46
49
  })
47
50
  : [];
48
51
  const relationshipsDir = getRelationshipsDir(path.join(cwd, ".kb"));
49
- return { markdownFiles, manifestFiles, relationshipsDir };
52
+ return {
53
+ markdownFiles: entityMarkdownFiles,
54
+ manifestFiles,
55
+ relationshipsDir,
56
+ };
50
57
  }
@@ -7,5 +7,10 @@ export interface ExtractionOutput {
7
7
  message: string;
8
8
  }[];
9
9
  }
10
- export declare function processExtractions(changedMarkdownFiles: string[], changedManifestFiles: string[], validateOnly: boolean): Promise<ExtractionOutput>;
10
+ interface ExtractionDependencies {
11
+ extractFromMarkdown: (file: string) => ExtractionResult;
12
+ extractFromManifest: (file: string) => ExtractionResult[];
13
+ }
14
+ export declare function processExtractions(changedMarkdownFiles: string[], changedManifestFiles: string[], validateOnly: boolean, dependencies?: ExtractionDependencies): Promise<ExtractionOutput>;
15
+ export {};
11
16
  //# sourceMappingURL=extraction.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,wBAAsB,kBAAkB,CAEtC,oBAAoB,EAAE,MAAM,EAAE,EAC9B,oBAAoB,EAAE,MAAM,EAAE,EAC9B,YAAY,EAAE,OAAO,GACpB,OAAO,CAAC,gBAAgB,CAAC,CA4C3B"}
1
+ {"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AAED,UAAU,sBAAsB;IAC9B,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;IACxD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,gBAAgB,EAAE,CAAC;CAC3D;AAOD,wBAAsB,kBAAkB,CAEtC,oBAAoB,EAAE,MAAM,EAAE,EAC9B,oBAAoB,EAAE,MAAM,EAAE,EAC9B,YAAY,EAAE,OAAO,EACrB,YAAY,GAAE,sBAAwD,GACrE,OAAO,CAAC,gBAAgB,CAAC,CA4C3B"}
@@ -18,15 +18,19 @@
18
18
  import { extractFromManifest } from "../../extractors/manifest.js";
19
19
  import { FrontmatterError, extractFromMarkdown, } from "../../extractors/markdown.js";
20
20
  import { toCacheKey } from "./cache.js";
21
+ const DEFAULT_EXTRACTION_DEPENDENCIES = {
22
+ extractFromMarkdown,
23
+ extractFromManifest,
24
+ };
21
25
  export async function processExtractions(
22
26
  // implements REQ-003
23
- changedMarkdownFiles, changedManifestFiles, validateOnly) {
27
+ changedMarkdownFiles, changedManifestFiles, validateOnly, dependencies = DEFAULT_EXTRACTION_DEPENDENCIES) {
24
28
  const results = [];
25
29
  const failedCacheKeys = new Set();
26
30
  const errors = [];
27
31
  for (const file of changedMarkdownFiles) {
28
32
  try {
29
- results.push(extractFromMarkdown(file));
33
+ results.push(dependencies.extractFromMarkdown(file));
30
34
  }
31
35
  catch (error) {
32
36
  const message = error instanceof Error ? error.message : String(error);
@@ -46,7 +50,7 @@ changedMarkdownFiles, changedManifestFiles, validateOnly) {
46
50
  }
47
51
  for (const file of changedManifestFiles) {
48
52
  try {
49
- const manifestResults = extractFromManifest(file);
53
+ const manifestResults = dependencies.extractFromManifest(file);
50
54
  results.push(...manifestResults);
51
55
  }
52
56
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0ErD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAqEvD;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,GAC1C,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA+K7D"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0ErD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAoFvD;AA6BD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,GAC1C,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA+K7D"}
@@ -154,6 +154,14 @@ prolog, results, entityIds) {
154
154
  const factFields = serializeTypedFactFields(entity);
155
155
  props.push(...factFields);
156
156
  }
157
+ if (entity.type === "test") {
158
+ if (entity.verification_scope !== undefined) {
159
+ props.push(`verification_scope=${toPrologAtom(entity.verification_scope)}`);
160
+ }
161
+ if (entity.verification_perspective !== undefined) {
162
+ props.push(`verification_perspective=${toPrologAtom(entity.verification_perspective)}`);
163
+ }
164
+ }
157
165
  const propsList = `[${props.join(", ")}]`;
158
166
  const goal = `kb_assert_entity(${entity.type}, ${propsList})`;
159
167
  const result = await prolog.query(goal);
@@ -165,11 +173,31 @@ prolog, results, entityIds) {
165
173
  }
166
174
  catch (error) {
167
175
  const message = error instanceof Error ? error.message : String(error);
168
- throw new Error(`Failed to upsert entity ${entity.id}: ${message}`);
176
+ throw new Error(`Failed to upsert entity ${entity.id}: ${message}${semanticEntityContext(entity, sourceFile ?? entity.source)}`);
169
177
  }
170
178
  }
171
179
  return { entityCount, kbModified };
172
180
  }
181
+ function semanticEntityContext(entity, sourceFile) {
182
+ const displaySource = path.isAbsolute(sourceFile)
183
+ ? path.relative(process.cwd(), sourceFile)
184
+ : sourceFile;
185
+ const details = [`source=${displaySource}`];
186
+ if (entity.type === "fact") {
187
+ const factKind = getEntityField(entity, "fact_kind");
188
+ if (factKind !== undefined && factKind !== null) {
189
+ details.push(`fact_kind=${String(factKind)}`);
190
+ }
191
+ if (factKind === "property_value" &&
192
+ getEntityField(entity, "value_string") === undefined &&
193
+ getEntityField(entity, "value_int") === undefined &&
194
+ getEntityField(entity, "value_number") === undefined &&
195
+ getEntityField(entity, "value_bool") === undefined) {
196
+ details.push("missing value field");
197
+ }
198
+ }
199
+ return ` (${details.join("; ")})`;
200
+ }
173
201
  // implements REQ-core-persistence
174
202
  export async function persistRelationships(prolog, results, shardRelationships) {
175
203
  let relCount = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA6JD,qBAAa,aAAc,SAAQ,KAAK;IAG7B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAK1B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAqID,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAmBpB;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKxE;AAsCD,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,EAAE,CAWxB"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA6JD,qBAAa,aAAc,SAAQ,KAAK;IAG7B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAK1B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAuJD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAmBpB;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKxE;AAsCD,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,EAAE,CAWxB"}
@@ -189,6 +189,24 @@ function extractFromManifestSymbolRecords(manifestSymbols, filePath) {
189
189
  ...(symbol.granularity_reason !== undefined
190
190
  ? { granularity_reason: symbol.granularity_reason }
191
191
  : {}),
192
+ ...(typeof symbol.symbol_kind === "string"
193
+ ? { symbol_kind: symbol.symbol_kind }
194
+ : {}),
195
+ ...(typeof symbol.symbol_role === "string"
196
+ ? { symbol_role: symbol.symbol_role }
197
+ : {}),
198
+ ...(typeof symbol.sourceLine === "number"
199
+ ? { sourceLine: symbol.sourceLine }
200
+ : {}),
201
+ ...(typeof symbol.sourceColumn === "number"
202
+ ? { sourceColumn: symbol.sourceColumn }
203
+ : {}),
204
+ ...(typeof symbol.sourceEndLine === "number"
205
+ ? { sourceEndLine: symbol.sourceEndLine }
206
+ : {}),
207
+ ...(typeof symbol.sourceEndColumn === "number"
208
+ ? { sourceEndColumn: symbol.sourceEndColumn }
209
+ : {}),
192
210
  };
193
211
  const sourceFile = symbol.sourceFile ?? symbol.source;
194
212
  return {
@@ -12,6 +12,12 @@ export interface ExtractedEntity {
12
12
  severity?: string;
13
13
  text_ref?: string;
14
14
  granularity_reason?: string;
15
+ symbol_kind?: string;
16
+ symbol_role?: string;
17
+ sourceLine?: number;
18
+ sourceColumn?: number;
19
+ sourceEndLine?: number;
20
+ sourceEndColumn?: number;
15
21
  verification_scope?: "unit" | "integration" | "end_to_end";
16
22
  verification_perspective?: "internal" | "consumer";
17
23
  fact_kind?: "subject" | "property_value" | "observation" | "meta";
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { type ManifestSymbolEntry, enrichSymbolCoordinatesWithTsMorph } from "./symbols-ts.js";
2
2
  export type { ManifestSymbolEntry };
3
3
  export type SourceAnalysisMode = "parser" | "fallback";
4
- export type SourceSymbolKind = "function" | "class" | "method" | "interface" | "type" | "enum" | "variable" | "unknown";
4
+ export type SourceSymbolKind = "function" | "class" | "method" | "property" | "accessor" | "interface" | "type" | "enum" | "variable" | "unknown";
5
5
  export interface SourceSymbolAnalysis {
6
6
  name: string;
7
7
  kind: SourceSymbolKind;
@@ -1 +1 @@
1
- {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,mBAAmB,EAExB,kCAAkC,EACnC,MAAM,iBAAiB,CAAC;AAazB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,WAAW,GACX,MAAM,GACN,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACtE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,kCAAkC,CAAC;CAChE;AA+BD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAClC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CAAC;AAkCxB,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
1
+ {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,mBAAmB,EAExB,kCAAkC,EACnC,MAAM,iBAAiB,CAAC;AAazB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,UAAU,GACV,WAAW,GACX,MAAM,GACN,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACtE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,kCAAkC,CAAC;CAChE;AA+BD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAClC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CAAC;AAkCxB,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
@@ -194,6 +194,21 @@ function collectSourceSymbols(sourceFile) {
194
194
  .map((doc) => doc.getFullText())
195
195
  .join("\n")}`));
196
196
  }
197
+ for (const property of decl.getProperties()) {
198
+ symbols.push(toSourceSymbolAnalysis(sourceFile, formatMethodSymbolName(decl.getName(), property.getName()), "property", property.getNameNode() ?? property, property, `${property.getFullText()}\n${property
199
+ .getJsDocs()
200
+ .map((doc) => doc.getFullText())
201
+ .join("\n")}`));
202
+ }
203
+ for (const accessor of [
204
+ ...decl.getGetAccessors(),
205
+ ...decl.getSetAccessors(),
206
+ ]) {
207
+ symbols.push(toSourceSymbolAnalysis(sourceFile, formatMethodSymbolName(decl.getName(), accessor.getName()), "accessor", accessor.getNameNode() ?? accessor, accessor, `${accessor.getFullText()}\n${accessor
208
+ .getJsDocs()
209
+ .map((doc) => doc.getFullText())
210
+ .join("\n")}`));
211
+ }
197
212
  }
198
213
  for (const decl of sourceFile.getInterfaces()) {
199
214
  if (!decl.isExported())
@@ -274,6 +289,25 @@ function findNamedDeclaration(sourceFile, title) {
274
289
  continue;
275
290
  return { node: method, getNameNode: () => nameNode };
276
291
  }
292
+ for (const property of cls.getProperties()) {
293
+ if (property.getName() !== qualifiedMethod.methodName)
294
+ continue;
295
+ const nameNode = property.getNameNode();
296
+ if (!nameNode)
297
+ continue;
298
+ return { node: property, getNameNode: () => nameNode };
299
+ }
300
+ for (const accessor of [
301
+ ...cls.getGetAccessors(),
302
+ ...cls.getSetAccessors(),
303
+ ]) {
304
+ if (accessor.getName() !== qualifiedMethod.methodName)
305
+ continue;
306
+ const nameNode = accessor.getNameNode();
307
+ if (!nameNode)
308
+ continue;
309
+ return { node: accessor, getNameNode: () => nameNode };
310
+ }
277
311
  }
278
312
  return null;
279
313
  }
@@ -377,6 +411,34 @@ function findNamedDeclaration(sourceFile, title) {
377
411
  return candidate;
378
412
  }
379
413
  }
414
+ const memberCandidates = [];
415
+ for (const cls of sourceFile.getClasses()) {
416
+ for (const property of cls.getProperties()) {
417
+ if (property.getName() !== title)
418
+ continue;
419
+ const nameNode = property.getNameNode();
420
+ if (!nameNode)
421
+ continue;
422
+ memberCandidates.push({ node: property, getNameNode: () => nameNode });
423
+ }
424
+ for (const accessor of [
425
+ ...cls.getGetAccessors(),
426
+ ...cls.getSetAccessors(),
427
+ ]) {
428
+ if (accessor.getName() !== title)
429
+ continue;
430
+ const nameNode = accessor.getNameNode();
431
+ if (!nameNode)
432
+ continue;
433
+ memberCandidates.push({ node: accessor, getNameNode: () => nameNode });
434
+ }
435
+ }
436
+ if (memberCandidates.length === 1) {
437
+ const candidate = memberCandidates[0];
438
+ if (candidate) {
439
+ return candidate;
440
+ }
441
+ }
380
442
  return null;
381
443
  }
382
444
  candidates.sort((a, b) => a.getNameNode().getStart() - b.getNameNode().getStart());
@@ -0,0 +1,3 @@
1
+ import type { ChangedFileImpactOptions, ChangedFileImpactResult } from "./types.js";
2
+ export declare function analyzeChangedFileImpact(options: ChangedFileImpactOptions): ChangedFileImpactResult;
3
+ //# sourceMappingURL=analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../../../src/public/impact/analyzer.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EACV,wBAAwB,EACxB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,wBAAwB,GAChC,uBAAuB,CAgEzB"}
@@ -0,0 +1,54 @@
1
+ import * as path from "node:path";
2
+ import { extractSymbolsFromStagedFile } from "../../traceability/symbol-extract.js";
3
+ import { createSemanticReviewDiagnostics, createSymbolGranularityDiagnostics, } from "./diagnostics.js";
4
+ import { createImpactManifestLookup, readImpactManifestResults, } from "./manifest.js";
5
+ import { collectSourceChanges, uniqueSorted } from "./source-changes.js";
6
+ import { buildNextActions, collectLinkedEntities, formatExtractedSymbols, } from "./summaries.js";
7
+ import { createSymbolQualityDiagnostics } from "./symbol-quality.js";
8
+ export function analyzeChangedFileImpact(options) {
9
+ const workspaceRoot = path.resolve(options.workspaceRoot);
10
+ const sourceChanges = collectSourceChanges({ ...options, workspaceRoot });
11
+ const sourceFiles = uniqueSorted(sourceChanges.map((change) => change.file));
12
+ const manifestResults = readImpactManifestResults(workspaceRoot);
13
+ const manifestLookup = createImpactManifestLookup(manifestResults);
14
+ const symbolsByFile = new Map();
15
+ const sourceContentByFile = new Map();
16
+ for (const change of sourceChanges) {
17
+ sourceContentByFile.set(change.file, change.content);
18
+ symbolsByFile.set(change.file, extractSymbolsFromStagedFile({
19
+ path: change.file,
20
+ status: change.status,
21
+ hunkRanges: [...change.hunkRanges],
22
+ content: change.content,
23
+ }, manifestLookup).filter((symbol) => symbol.hunkRanges.length > 0));
24
+ }
25
+ const activeSourceFiles = new Set(sourceFiles);
26
+ const activeManifestResults = manifestResults.filter((result) => result.sourceFile !== undefined &&
27
+ activeSourceFiles.has(result.sourceFile));
28
+ const impactDiagnostics = options.includeImpactDiagnostics === false
29
+ ? []
30
+ : [
31
+ ...createSymbolGranularityDiagnostics({
32
+ manifestResults: activeManifestResults,
33
+ symbolsByFile,
34
+ sourceContentByFile,
35
+ workspaceRoot,
36
+ }),
37
+ ...createSymbolQualityDiagnostics({
38
+ manifestResults: activeManifestResults,
39
+ symbolsByFile,
40
+ }),
41
+ ...createSemanticReviewDiagnostics({ symbolsByFile }),
42
+ ];
43
+ const maxDiagnostics = options.maxDiagnostics;
44
+ const cappedDiagnostics = maxDiagnostics !== undefined && maxDiagnostics >= 0
45
+ ? impactDiagnostics.slice(0, maxDiagnostics)
46
+ : impactDiagnostics;
47
+ return {
48
+ impactDiagnostics: cappedDiagnostics,
49
+ sourceFiles,
50
+ extractedSymbols: formatExtractedSymbols(symbolsByFile),
51
+ linkedEntities: collectLinkedEntities(symbolsByFile, manifestResults, activeSourceFiles),
52
+ nextActions: buildNextActions(sourceFiles),
53
+ };
54
+ }
@@ -0,0 +1,4 @@
1
+ import type { ExtractionResult } from "../../extractors/markdown.js";
2
+ import type { QualityDiagnostic } from "./types.js";
3
+ export declare function createCoverageDepthQualityDiagnostics(manifestResults: readonly ExtractionResult[]): readonly QualityDiagnostic[];
4
+ //# sourceMappingURL=coverage-depth-quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-depth-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/coverage-depth-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAwPpD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAC3C,SAAS,iBAAiB,EAAE,CAa9B"}