kibi-cli 0.12.7 → 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 (114) 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 +130 -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 +39 -5
  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/prolog.d.ts.map +1 -1
  26. package/dist/prolog.js +11 -7
  27. package/dist/public/impact/analyzer.d.ts +3 -0
  28. package/dist/public/impact/analyzer.d.ts.map +1 -0
  29. package/dist/public/impact/analyzer.js +54 -0
  30. package/dist/public/impact/coverage-depth-quality.d.ts +4 -0
  31. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -0
  32. package/dist/public/impact/coverage-depth-quality.js +179 -0
  33. package/dist/public/impact/diagnostics.d.ts +7 -0
  34. package/dist/public/impact/diagnostics.d.ts.map +1 -0
  35. package/dist/public/impact/diagnostics.js +122 -0
  36. package/dist/public/impact/diff-meaning.d.ts +2 -0
  37. package/dist/public/impact/diff-meaning.d.ts.map +1 -0
  38. package/dist/public/impact/diff-meaning.js +101 -0
  39. package/dist/public/impact/full-kb-quality.d.ts +10 -0
  40. package/dist/public/impact/full-kb-quality.d.ts.map +1 -0
  41. package/dist/public/impact/full-kb-quality.js +158 -0
  42. package/dist/public/impact/manifest.d.ts +5 -0
  43. package/dist/public/impact/manifest.d.ts.map +1 -0
  44. package/dist/public/impact/manifest.js +43 -0
  45. package/dist/public/impact/requirement-quality.d.ts +4 -0
  46. package/dist/public/impact/requirement-quality.d.ts.map +1 -0
  47. package/dist/public/impact/requirement-quality.js +216 -0
  48. package/dist/public/impact/source-changes.d.ts +5 -0
  49. package/dist/public/impact/source-changes.d.ts.map +1 -0
  50. package/dist/public/impact/source-changes.js +129 -0
  51. package/dist/public/impact/summaries.d.ts +6 -0
  52. package/dist/public/impact/summaries.d.ts.map +1 -0
  53. package/dist/public/impact/summaries.js +68 -0
  54. package/dist/public/impact/symbol-quality-model.d.ts +21 -0
  55. package/dist/public/impact/symbol-quality-model.d.ts.map +1 -0
  56. package/dist/public/impact/symbol-quality-model.js +116 -0
  57. package/dist/public/impact/symbol-quality.d.ts +4 -0
  58. package/dist/public/impact/symbol-quality.d.ts.map +1 -0
  59. package/dist/public/impact/symbol-quality.js +159 -0
  60. package/dist/public/impact/types.d.ts +79 -0
  61. package/dist/public/impact/types.d.ts.map +1 -0
  62. package/dist/public/impact/types.js +1 -0
  63. package/dist/public/impact-diagnostics.d.ts +7 -0
  64. package/dist/public/impact-diagnostics.d.ts.map +1 -0
  65. package/dist/public/impact-diagnostics.js +5 -0
  66. package/dist/public/schemas/entity.d.ts.map +1 -1
  67. package/dist/public/schemas/entity.js +21 -0
  68. package/dist/public/skills/kibi-usage/SKILL.md +20 -5
  69. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  70. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +30 -0
  71. package/dist/public/skills/kibi-usage/resources/workflows.md +14 -0
  72. package/dist/public/symbol-granularity.d.ts +1 -1
  73. package/dist/public/symbol-granularity.d.ts.map +1 -1
  74. package/dist/public/symbol-granularity.js +2 -0
  75. package/dist/traceability/evidence-model.d.ts +1 -1
  76. package/dist/traceability/evidence-model.d.ts.map +1 -1
  77. package/dist/traceability/evidence-model.js +1 -1
  78. package/dist/traceability/staged-diagnostics.d.ts +6 -6
  79. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  80. package/dist/traceability/staged-diagnostics.js +12 -6
  81. package/dist/traceability/staged-impact-contract.js +1 -1
  82. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  83. package/dist/traceability/staged-symbols-manifest.js +23 -1
  84. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  85. package/dist/traceability/symbol-extract.js +41 -0
  86. package/dist/traceability/temp-kb.d.ts.map +1 -1
  87. package/dist/types/entities.d.ts +5 -1
  88. package/dist/types/entities.d.ts.map +1 -1
  89. package/dist/utils/prolog-query-plan-safety.d.ts +8 -0
  90. package/dist/utils/prolog-query-plan-safety.d.ts.map +1 -0
  91. package/dist/utils/prolog-query-plan-safety.js +47 -0
  92. package/dist/utils/rule-registry.d.ts.map +1 -1
  93. package/dist/utils/rule-registry.js +12 -0
  94. package/package.json +7 -9
  95. package/schema/entities.pl +4 -0
  96. package/src/public/impact/analyzer.ts +90 -0
  97. package/src/public/impact/coverage-depth-quality.ts +268 -0
  98. package/src/public/impact/diagnostics.ts +192 -0
  99. package/src/public/impact/diff-meaning.ts +121 -0
  100. package/src/public/impact/full-kb-quality.ts +203 -0
  101. package/src/public/impact/manifest.ts +57 -0
  102. package/src/public/impact/requirement-quality.ts +282 -0
  103. package/src/public/impact/source-changes.ts +180 -0
  104. package/src/public/impact/summaries.ts +100 -0
  105. package/src/public/impact/symbol-quality-model.ts +171 -0
  106. package/src/public/impact/symbol-quality.ts +207 -0
  107. package/src/public/impact/types.ts +99 -0
  108. package/src/public/impact-diagnostics.ts +22 -0
  109. package/src/public/schemas/entity.ts +23 -0
  110. package/src/public/skills/kibi-usage/SKILL.md +20 -5
  111. package/src/public/skills/kibi-usage/resources/fact-lanes.md +5 -5
  112. package/src/public/skills/kibi-usage/resources/relationship-directions.md +30 -0
  113. package/src/public/skills/kibi-usage/resources/workflows.md +14 -0
  114. 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;AAgCD,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;AAED,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,CAwK7D"}
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"}
@@ -91,7 +91,8 @@ function isQueryFailedError(error) {
91
91
  }
92
92
  async function tryResetPrologProcess(prolog) {
93
93
  const maybe = prolog;
94
- if (typeof maybe.terminate !== "function" || typeof maybe.start !== "function") {
94
+ if (typeof maybe.terminate !== "function" ||
95
+ typeof maybe.start !== "function") {
95
96
  return false;
96
97
  }
97
98
  try {
@@ -153,6 +154,14 @@ prolog, results, entityIds) {
153
154
  const factFields = serializeTypedFactFields(entity);
154
155
  props.push(...factFields);
155
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
+ }
156
165
  const propsList = `[${props.join(", ")}]`;
157
166
  const goal = `kb_assert_entity(${entity.type}, ${propsList})`;
158
167
  const result = await prolog.query(goal);
@@ -164,11 +173,32 @@ prolog, results, entityIds) {
164
173
  }
165
174
  catch (error) {
166
175
  const message = error instanceof Error ? error.message : String(error);
167
- 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)}`);
168
177
  }
169
178
  }
170
179
  return { entityCount, kbModified };
171
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
+ }
201
+ // implements REQ-core-persistence
172
202
  export async function persistRelationships(prolog, results, shardRelationships) {
173
203
  let relCount = 0;
174
204
  let kbModified = false;
@@ -271,7 +301,9 @@ export async function persistRelationships(prolog, results, shardRelationships)
271
301
  // If every pending relationship fails with generic query errors, attempt one
272
302
  // best-effort Prolog restart before the next retry pass to recover from a
273
303
  // potentially poisoned interactive session.
274
- if (allLookLikeSessionFailures && !resetAttempted && pass + 1 < retryCount) {
304
+ if (allLookLikeSessionFailures &&
305
+ !resetAttempted &&
306
+ pass + 1 < retryCount) {
275
307
  resetAttempted = true;
276
308
  await tryResetPrologProcess(prolog);
277
309
  }
@@ -295,8 +327,10 @@ export async function persistRelationships(prolog, results, shardRelationships)
295
327
  const missingIds = new Set();
296
328
  for (const { error } of missingEntities) {
297
329
  const match = error.match(/does not exist: (.+)$/);
298
- if (match)
299
- missingIds.add(match[1].trim());
330
+ const missingId = match?.[1];
331
+ if (missingId !== undefined) {
332
+ missingIds.add(missingId.trim());
333
+ }
300
334
  }
301
335
  const idList = [...missingIds].sort().join(", ");
302
336
  console.warn(`\nTip: ${missingEntities.length} relationship(s) reference ${missingIds.size} missing entity/ies: ${idList}.`);
@@ -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;AAqID,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;AAgID,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":"AAwDA,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;IAC5B,kBAAkB,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;IAC3D,wBAAwB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEnD,SAAS,CAAC,EAAE,SAAS,GAAG,gBAAgB,GAAG,aAAa,GAAG,MAAM,CAAC;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACtD,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;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;AAmKD,qBAAa,gBAAiB,SAAQ,KAAK;IAOhC,QAAQ,EAAE,MAAM;IANlB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAYM,QAAQ;CAUlB;AA8DD,wBAAgB,sBAAsB,CAEpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAkDV;AA0RD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAElB;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAatE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE;AASD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQpE"}
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());
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,IAAI,MAAM,CAsCxC;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,cAAc,CACyC;IAC/D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,GAAE,aAAkB;IAKjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAuCd,YAAY;IA0CpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IA0K1D,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IAsGnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IAqDtB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAwCjC"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"AA4BA,wBAAgB,eAAe,IAAI,MAAM,CAsCxC;AACD,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,WAAW,CAAM;IACzB,OAAO,CAAC,KAAK,CAAuC;IACpD,OAAO,CAAC,oBAAoB,CAAoC;IAChE,OAAO,CAAC,kBAAkB,CAA8B;IACxD,OAAO,CAAC,cAAc,CACyC;IAC/D,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,aAAa,CAA6B;gBAEtC,OAAO,GAAE,aAAkB;IAKjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAuCd,YAAY;IA2CpB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC;IAyK1D,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,kBAAkB;YAIZ,YAAY;IA2C1B,OAAO,CAAC,WAAW;IAsGnB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,cAAc;IA6DtB,SAAS,IAAI,OAAO;IAMpB,MAAM,IAAI,MAAM;IAIV,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CAwCjC"}
package/dist/prolog.js CHANGED
@@ -133,6 +133,7 @@ export class PrologProcess {
133
133
  this.outputBuffer = "";
134
134
  this.errorBuffer = "";
135
135
  }
136
+ // implements REQ-core-prolog-process-management
136
137
  async query(goal) {
137
138
  const isSingleGoal = typeof goal === "string";
138
139
  const goalKey = isSingleGoal ? goal : null;
@@ -242,8 +243,7 @@ export class PrologProcess {
242
243
  }
243
244
  // Check errorBuffer first — Prolog catch/3 writes ERROR to stderr
244
245
  // then fail to stdout. If stderr has the real error, surface it.
245
- const errorMessage = this.errorBuffer.length > 0 &&
246
- this.errorBuffer.includes("ERROR")
246
+ const errorMessage = this.errorBuffer.length > 0 && this.errorBuffer.includes("ERROR")
247
247
  ? this.translateError(this.errorBuffer)
248
248
  : "Query failed";
249
249
  resolve({
@@ -441,14 +441,17 @@ export class PrologProcess {
441
441
  }
442
442
  return bindings;
443
443
  }
444
+ // implements REQ-core-prolog-process-management
444
445
  translateError(errorText) {
445
446
  // SWI-Prolog print_message/2 formats errors as human-readable messages,
446
447
  // not raw Prolog terms. Match the actual output format.
447
- if (errorText.includes('does not exist') && /entity [`'"].+?[`'"]/.test(errorText)) {
448
+ if (errorText.includes("does not exist") &&
449
+ /entity [`'"].+?[`'"]/.test(errorText)) {
448
450
  // SWI-Prolog doubles single quotes in formatted messages: ''REQ-TEST''
449
451
  const entityIdMatch = errorText.match(/entity [`'"]+(.+?)[`'"]+ does not exist/);
450
- const entityId = entityIdMatch
451
- ? entityIdMatch[1].replace(/^`?'+|'+`?$/g, "")
452
+ const matchedEntityId = entityIdMatch?.[1];
453
+ const entityId = matchedEntityId !== undefined
454
+ ? matchedEntityId.replace(/^`?'+|'+`?$/g, "")
452
455
  : "unknown";
453
456
  if (errorText.includes("Target entity does not exist")) {
454
457
  return `Target entity does not exist: ${entityId}`;
@@ -460,8 +463,9 @@ export class PrologProcess {
460
463
  }
461
464
  if (errorText.includes("Type error: `relationship' expected")) {
462
465
  const relMatch = errorText.match(/\(Invalid relationship: ([^)]+)\)/);
463
- if (relMatch) {
464
- return `Invalid relationship: ${relMatch[1].trim()}`;
466
+ const invalidRelationship = relMatch?.[1];
467
+ if (invalidRelationship !== undefined) {
468
+ return `Invalid relationship: ${invalidRelationship.trim()}`;
465
469
  }
466
470
  return "Invalid relationship type or direction";
467
471
  }
@@ -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"}