kibi-cli 0.10.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +2 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +204 -3
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +11 -14
- package/dist/commands/sync/manifest.d.ts +8 -2
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +56 -11
- package/dist/commands/sync.d.ts +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +9 -7
- package/dist/extractors/manifest.d.ts +30 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +60 -7
- package/dist/extractors/symbol-coordinates.d.ts +15 -0
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -0
- package/dist/extractors/symbol-coordinates.js +83 -0
- package/dist/public/extractors/manifest.d.ts +1 -1
- package/dist/public/extractors/manifest.d.ts.map +1 -1
- package/dist/public/extractors/manifest.js +1 -1
- package/dist/traceability/evidence-model.d.ts +142 -0
- package/dist/traceability/evidence-model.d.ts.map +1 -0
- package/dist/traceability/evidence-model.js +70 -0
- package/dist/traceability/git-staged.d.ts +1 -0
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +28 -3
- package/dist/traceability/staged-diagnostics.d.ts +25 -0
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -0
- package/dist/traceability/staged-diagnostics.js +67 -0
- package/dist/traceability/staged-impact-contract.d.ts +57 -0
- package/dist/traceability/staged-impact-contract.d.ts.map +1 -0
- package/dist/traceability/staged-impact-contract.js +202 -0
- package/dist/traceability/staged-symbols-manifest.d.ts +23 -0
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -0
- package/dist/traceability/staged-symbols-manifest.js +269 -0
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +33 -9
- package/dist/utils/manifest-paths.d.ts +8 -0
- package/dist/utils/manifest-paths.d.ts.map +1 -0
- package/dist/utils/manifest-paths.js +62 -0
- package/package.json +1 -1
- package/src/public/extractors/manifest.ts +2 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export declare const KIBI_IMPACT_DIAGNOSTIC_IDS: readonly ["kibi_impact_evidence_missing", "symbols_manifest_stale", "kibi_impact_override_missing_rationale"];
|
|
2
|
+
export type KibiImpactDiagnosticId = (typeof KIBI_IMPACT_DIAGNOSTIC_IDS)[number];
|
|
3
|
+
export type KibiImpactEvidenceKind = "entity_markdown" | "symbols_manifest" | "audited_no_impact";
|
|
4
|
+
export interface KibiImpactDiagnosticContract {
|
|
5
|
+
id: KibiImpactDiagnosticId;
|
|
6
|
+
title: string;
|
|
7
|
+
resolution: [string, string, string];
|
|
8
|
+
}
|
|
9
|
+
export interface KibiImpactEvidenceInput {
|
|
10
|
+
filePath?: string;
|
|
11
|
+
extractionOutputChanged?: boolean;
|
|
12
|
+
overrideDeclared?: boolean;
|
|
13
|
+
overrideRationale?: string | null;
|
|
14
|
+
symbolsManifestPath?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface BehaviorSourceEditInput {
|
|
17
|
+
path: string;
|
|
18
|
+
diffText: string;
|
|
19
|
+
intersectsBehaviorBearingSymbol: boolean;
|
|
20
|
+
knownUserFacingSurface?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ParsedKibiImpactOverride {
|
|
23
|
+
declared: boolean;
|
|
24
|
+
rationale: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface AuditedNoImpactOverrideInput {
|
|
27
|
+
behaviorSourceEdit: boolean;
|
|
28
|
+
override: ParsedKibiImpactOverride;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Staged Kibi impact contract for `kibi check --staged`.
|
|
32
|
+
*
|
|
33
|
+
* This is intentionally a small, stable contract for tests and future staged
|
|
34
|
+
* enforcement wiring:
|
|
35
|
+
* - `behavior_source_edit` is a supported source-file edit whose staged hunks
|
|
36
|
+
* intersect exported or other behavior-bearing/user-facing surfaces and whose
|
|
37
|
+
* changed lines are not comment-only or formatting-only.
|
|
38
|
+
* - `kibi_impact_evidence` is staged entity markdown, staged authored
|
|
39
|
+
* `documentation/symbols.yaml` metadata, refreshed
|
|
40
|
+
* `documentation/symbol-coordinates.yaml` when extraction output changes, or
|
|
41
|
+
* an explicit audited `Kibi-Impact: none` declaration with
|
|
42
|
+
* rationale for false positives/non-behavior-only edits.
|
|
43
|
+
* - `Kibi-Impact: none` never satisfies a genuine behavior change.
|
|
44
|
+
* - Test-only edits do not require new KB evidence unless they introduce
|
|
45
|
+
* executable test symbols that need traceability.
|
|
46
|
+
*
|
|
47
|
+
* This contract deliberately avoids broad semantic diffing and stays
|
|
48
|
+
* conservative so later staged-check enforcement can share exact diagnostic IDs
|
|
49
|
+
* and operator-facing remediation steps.
|
|
50
|
+
*/
|
|
51
|
+
export declare const KIBI_IMPACT_DIAGNOSTICS: Record<KibiImpactDiagnosticId, KibiImpactDiagnosticContract>;
|
|
52
|
+
export declare function classifyKibiImpactEvidence(input: KibiImpactEvidenceInput): KibiImpactEvidenceKind | null;
|
|
53
|
+
export declare function parseKibiImpactOverride(text: string): ParsedKibiImpactOverride;
|
|
54
|
+
export declare function isAuditedNoImpactOverrideAllowed(input: AuditedNoImpactOverrideInput): boolean;
|
|
55
|
+
export declare function isBehaviorSourceEdit(input: BehaviorSourceEditInput): boolean;
|
|
56
|
+
export declare function isSupportedBehaviorSourcePath(filePath: string): boolean;
|
|
57
|
+
//# sourceMappingURL=staged-impact-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staged-impact-contract.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-impact-contract.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,0BAA0B,+GAI7B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAC9B,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,CAAC;AAExB,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B,EAAE,OAAO,CAAC;IACzC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,sBAAsB,EACtB,4BAA4B,CA6B7B,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,GAC7B,sBAAsB,GAAG,IAAI,CAsB/B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,GACX,wBAAwB,CAS1B;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAMT;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CA8B5E;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQvE"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
const SUPPORTED_BEHAVIOR_SOURCE_EXTENSIONS = new Set([
|
|
2
|
+
".ts",
|
|
3
|
+
".tsx",
|
|
4
|
+
".js",
|
|
5
|
+
".jsx",
|
|
6
|
+
".mts",
|
|
7
|
+
".cts",
|
|
8
|
+
".mjs",
|
|
9
|
+
".cjs",
|
|
10
|
+
]);
|
|
11
|
+
const ENTITY_EVIDENCE_SEGMENTS = [
|
|
12
|
+
"/requirements/",
|
|
13
|
+
"/scenarios/",
|
|
14
|
+
"/tests/",
|
|
15
|
+
"/facts/",
|
|
16
|
+
"/adr/",
|
|
17
|
+
"/flags/",
|
|
18
|
+
"/events/",
|
|
19
|
+
];
|
|
20
|
+
export const KIBI_IMPACT_DIAGNOSTIC_IDS = [
|
|
21
|
+
"kibi_impact_evidence_missing",
|
|
22
|
+
"symbols_manifest_stale",
|
|
23
|
+
"kibi_impact_override_missing_rationale",
|
|
24
|
+
];
|
|
25
|
+
/**
|
|
26
|
+
* Staged Kibi impact contract for `kibi check --staged`.
|
|
27
|
+
*
|
|
28
|
+
* This is intentionally a small, stable contract for tests and future staged
|
|
29
|
+
* enforcement wiring:
|
|
30
|
+
* - `behavior_source_edit` is a supported source-file edit whose staged hunks
|
|
31
|
+
* intersect exported or other behavior-bearing/user-facing surfaces and whose
|
|
32
|
+
* changed lines are not comment-only or formatting-only.
|
|
33
|
+
* - `kibi_impact_evidence` is staged entity markdown, staged authored
|
|
34
|
+
* `documentation/symbols.yaml` metadata, refreshed
|
|
35
|
+
* `documentation/symbol-coordinates.yaml` when extraction output changes, or
|
|
36
|
+
* an explicit audited `Kibi-Impact: none` declaration with
|
|
37
|
+
* rationale for false positives/non-behavior-only edits.
|
|
38
|
+
* - `Kibi-Impact: none` never satisfies a genuine behavior change.
|
|
39
|
+
* - Test-only edits do not require new KB evidence unless they introduce
|
|
40
|
+
* executable test symbols that need traceability.
|
|
41
|
+
*
|
|
42
|
+
* This contract deliberately avoids broad semantic diffing and stays
|
|
43
|
+
* conservative so later staged-check enforcement can share exact diagnostic IDs
|
|
44
|
+
* and operator-facing remediation steps.
|
|
45
|
+
*/
|
|
46
|
+
export const KIBI_IMPACT_DIAGNOSTICS = {
|
|
47
|
+
kibi_impact_evidence_missing: {
|
|
48
|
+
id: "kibi_impact_evidence_missing",
|
|
49
|
+
title: "Behavior edit requires staged Kibi impact evidence",
|
|
50
|
+
resolution: [
|
|
51
|
+
"Query Kibi via MCP first: use kb_search for discovery, then kb_query for exact follow-up.",
|
|
52
|
+
"Stage related KB entity markdown, stage authored documentation/symbols.yaml metadata, or refresh coordinates with kibi sync --refresh-symbol-coordinates and stage documentation/symbol-coordinates.yaml documentation/symbols.yaml.",
|
|
53
|
+
"Re-run or let the hook run kibi check --staged.",
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
symbols_manifest_stale: {
|
|
57
|
+
id: "symbols_manifest_stale",
|
|
58
|
+
title: "Symbol coordinates evidence is stale for changed extraction output",
|
|
59
|
+
resolution: [
|
|
60
|
+
"Refresh symbol coordinates for the changed source file with kibi sync --refresh-symbol-coordinates.",
|
|
61
|
+
"Stage documentation/symbol-coordinates.yaml in the same change as the behavior edit, and stage documentation/symbols.yaml only if migration cleanup changed it.",
|
|
62
|
+
"Re-run or let the hook run kibi check --staged.",
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
kibi_impact_override_missing_rationale: {
|
|
66
|
+
id: "kibi_impact_override_missing_rationale",
|
|
67
|
+
title: "Kibi no-impact override requires an explicit rationale",
|
|
68
|
+
resolution: [
|
|
69
|
+
"Use an audited declaration only for false positives or non-behavioral edits.",
|
|
70
|
+
"Include both 'Kibi-Impact: none' and a nearby 'Rationale:' line describing why the edit has no behavior impact.",
|
|
71
|
+
"Re-run or let the hook run kibi check --staged.",
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
export function classifyKibiImpactEvidence(input) {
|
|
76
|
+
if (input.overrideDeclared && hasText(input.overrideRationale)) {
|
|
77
|
+
return "audited_no_impact";
|
|
78
|
+
}
|
|
79
|
+
const filePath = input.filePath ?? "";
|
|
80
|
+
if (!filePath) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
if (isEntityEvidenceMarkdown(filePath)) {
|
|
84
|
+
return "entity_markdown";
|
|
85
|
+
}
|
|
86
|
+
if (isSymbolsManifest(filePath, input.symbolsManifestPath) &&
|
|
87
|
+
input.extractionOutputChanged) {
|
|
88
|
+
return "symbols_manifest";
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
export function parseKibiImpactOverride(text) {
|
|
93
|
+
const declared = /^Kibi-Impact:\s*none\s*$/im.test(text);
|
|
94
|
+
const rationaleMatch = text.match(/^Rationale:\s*(.+)\s*$/im);
|
|
95
|
+
return {
|
|
96
|
+
declared,
|
|
97
|
+
rationale: hasText(rationaleMatch?.[1])
|
|
98
|
+
? (rationaleMatch?.[1]?.trim() ?? null)
|
|
99
|
+
: null,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function isAuditedNoImpactOverrideAllowed(input) {
|
|
103
|
+
return (input.override.declared &&
|
|
104
|
+
hasText(input.override.rationale) &&
|
|
105
|
+
!input.behaviorSourceEdit);
|
|
106
|
+
}
|
|
107
|
+
export function isBehaviorSourceEdit(input) {
|
|
108
|
+
if (!isSupportedBehaviorSourcePath(input.path)) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (!input.intersectsBehaviorBearingSymbol && !input.knownUserFacingSurface) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
const changes = extractChangedLines(input.diffText);
|
|
115
|
+
if (changes.length === 0) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
if (changes.every((line) => isIgnorableChangeLine(line))) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const removed = normalizeChangedLines(changes.filter((line) => line.kind === "remove"));
|
|
122
|
+
const added = normalizeChangedLines(changes.filter((line) => line.kind === "add"));
|
|
123
|
+
if (removed.length > 0 && removed.join("\n") === added.join("\n")) {
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
export function isSupportedBehaviorSourcePath(filePath) {
|
|
129
|
+
for (const extension of SUPPORTED_BEHAVIOR_SOURCE_EXTENSIONS) {
|
|
130
|
+
if (filePath.endsWith(extension)) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
function isEntityEvidenceMarkdown(filePath) {
|
|
137
|
+
if (!filePath.endsWith(".md")) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return ENTITY_EVIDENCE_SEGMENTS.some((segment) => filePath.includes(segment));
|
|
141
|
+
}
|
|
142
|
+
function isSymbolsManifest(filePath, symbolsManifestPath) {
|
|
143
|
+
const candidates = new Set([
|
|
144
|
+
"symbols.yaml",
|
|
145
|
+
"symbols.yml",
|
|
146
|
+
"documentation/symbols.yaml",
|
|
147
|
+
"documentation/symbols.yml",
|
|
148
|
+
]);
|
|
149
|
+
if (symbolsManifestPath) {
|
|
150
|
+
candidates.add(symbolsManifestPath);
|
|
151
|
+
if (symbolsManifestPath.endsWith(".yaml")) {
|
|
152
|
+
candidates.add(`${symbolsManifestPath.slice(0, -5)}.yml`);
|
|
153
|
+
}
|
|
154
|
+
if (symbolsManifestPath.endsWith(".yml")) {
|
|
155
|
+
candidates.add(`${symbolsManifestPath.slice(0, -4)}.yaml`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (candidates.has(filePath)) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return (filePath.endsWith("/symbols.yaml") ||
|
|
162
|
+
filePath.endsWith("/symbols.yml") ||
|
|
163
|
+
filePath === "symbols.yaml" ||
|
|
164
|
+
filePath === "symbols.yml");
|
|
165
|
+
}
|
|
166
|
+
function hasText(value) {
|
|
167
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
168
|
+
}
|
|
169
|
+
function extractChangedLines(diffText) {
|
|
170
|
+
const lines = diffText.split(/\r?\n/);
|
|
171
|
+
const changes = [];
|
|
172
|
+
for (const line of lines) {
|
|
173
|
+
if (line.startsWith("+++") ||
|
|
174
|
+
line.startsWith("---") ||
|
|
175
|
+
line.startsWith("@@")) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (line.startsWith("+")) {
|
|
179
|
+
changes.push({ kind: "add", text: line.slice(1) });
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (line.startsWith("-")) {
|
|
183
|
+
changes.push({ kind: "remove", text: line.slice(1) });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return changes;
|
|
187
|
+
}
|
|
188
|
+
function isIgnorableChangeLine(line) {
|
|
189
|
+
const trimmed = line.text.trim();
|
|
190
|
+
if (!trimmed) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
return (trimmed.startsWith("//") ||
|
|
194
|
+
trimmed.startsWith("/*") ||
|
|
195
|
+
trimmed.startsWith("*/") ||
|
|
196
|
+
trimmed.startsWith("*"));
|
|
197
|
+
}
|
|
198
|
+
function normalizeChangedLines(lines) {
|
|
199
|
+
return lines
|
|
200
|
+
.map((line) => line.text.replace(/\s+/g, ""))
|
|
201
|
+
.filter((line) => line.length > 0);
|
|
202
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { StagedFile } from "./git-staged.js";
|
|
2
|
+
export interface StagedSymbolsManifestAssessment {
|
|
3
|
+
state: "fresh" | "stale" | "missing" | "not_required";
|
|
4
|
+
sourcePaths: string[];
|
|
5
|
+
path: string;
|
|
6
|
+
}
|
|
7
|
+
export interface StagedAuthoredSymbolsManifestEvidence {
|
|
8
|
+
path: string;
|
|
9
|
+
entries: Array<{
|
|
10
|
+
sourcePath: string;
|
|
11
|
+
entityIds: string[];
|
|
12
|
+
}>;
|
|
13
|
+
}
|
|
14
|
+
export declare function assessStagedSymbolsManifest(options: {
|
|
15
|
+
symbolsManifestPath: string;
|
|
16
|
+
sourceFiles: StagedFile[];
|
|
17
|
+
stagedFiles: StagedFile[];
|
|
18
|
+
}): StagedSymbolsManifestAssessment;
|
|
19
|
+
export declare function collectStagedAuthoredSymbolsManifestEvidence(options: {
|
|
20
|
+
sourceFiles: StagedFile[];
|
|
21
|
+
stagedFiles: StagedFile[];
|
|
22
|
+
}): StagedAuthoredSymbolsManifestEvidence;
|
|
23
|
+
//# sourceMappingURL=staged-symbols-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staged-symbols-manifest.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-symbols-manifest.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA8BlD,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,cAAc,CAAC;IACtD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,qCAAqC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CAC7D;AAmQD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,GAAG,+BAA+B,CA0ElC;AAoBD,wBAAgB,4CAA4C,CAAC,OAAO,EAAE;IACpE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B,GAAG,qCAAqC,CA6CxC"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { extractManifestSymbolRecordsString, } from "../extractors/manifest.js";
|
|
4
|
+
import { mergeCoordinatesWithManifest, readCoordinateArtifact, } from "../extractors/symbol-coordinates.js";
|
|
5
|
+
import { analyzeSourceText } from "../extractors/symbols-coordinator.js";
|
|
6
|
+
import { resolveSymbolsManifestPaths } from "../utils/manifest-paths.js";
|
|
7
|
+
function toRepoRelativePath(absoluteOrRelativePath) {
|
|
8
|
+
if (!path.isAbsolute(absoluteOrRelativePath)) {
|
|
9
|
+
return absoluteOrRelativePath.replace(/\\/g, "/");
|
|
10
|
+
}
|
|
11
|
+
const relativePath = path.relative(process.cwd(), absoluteOrRelativePath);
|
|
12
|
+
return relativePath.replace(/\\/g, "/");
|
|
13
|
+
}
|
|
14
|
+
function resolveRelativeManifestPaths(symbolsManifestPath) {
|
|
15
|
+
if (symbolsManifestPath) {
|
|
16
|
+
const normalizedSymbolsPath = toRepoRelativePath(symbolsManifestPath);
|
|
17
|
+
return {
|
|
18
|
+
symbolsPath: normalizedSymbolsPath,
|
|
19
|
+
coordinatesPath: path
|
|
20
|
+
.join(path.dirname(normalizedSymbolsPath), "symbol-coordinates.yaml")
|
|
21
|
+
.replace(/\\/g, "/"),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const { coordinatesPath, symbolsPath } = resolveSymbolsManifestPaths(process.cwd());
|
|
25
|
+
return {
|
|
26
|
+
symbolsPath: toRepoRelativePath(symbolsPath),
|
|
27
|
+
coordinatesPath: toRepoRelativePath(coordinatesPath),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function readHeadFileContent(filePath) {
|
|
31
|
+
try {
|
|
32
|
+
return execSync(`git show HEAD:${filePath}`, {
|
|
33
|
+
encoding: "utf8",
|
|
34
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function parseManifestRecords(content, filePath) {
|
|
42
|
+
if (content === null || content === undefined) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
return extractManifestSymbolRecordsString(content, filePath);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseCoordinateArtifact(content) {
|
|
53
|
+
if (content === null || content === undefined) {
|
|
54
|
+
return { coordinates: {} };
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
return readCoordinateArtifact(content);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function normalizeNumber(value) {
|
|
64
|
+
return typeof value === "number" ? value : null;
|
|
65
|
+
}
|
|
66
|
+
function normalizeLinks(links) {
|
|
67
|
+
if (!Array.isArray(links)) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const normalized = [];
|
|
71
|
+
for (const link of links) {
|
|
72
|
+
if (typeof link === "string") {
|
|
73
|
+
normalized.push(link);
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (link &&
|
|
77
|
+
typeof link === "object" &&
|
|
78
|
+
typeof link.type === "string" &&
|
|
79
|
+
typeof link.target === "string") {
|
|
80
|
+
normalized.push({ type: link.type, target: link.target });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return normalized.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
84
|
+
}
|
|
85
|
+
function normalizeRelationships(relationships) {
|
|
86
|
+
if (!Array.isArray(relationships)) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
return relationships
|
|
90
|
+
.flatMap((relationship) => {
|
|
91
|
+
if (relationship &&
|
|
92
|
+
typeof relationship.type === "string" &&
|
|
93
|
+
typeof relationship.target === "string") {
|
|
94
|
+
return [{ type: relationship.type, target: relationship.target }];
|
|
95
|
+
}
|
|
96
|
+
return [];
|
|
97
|
+
})
|
|
98
|
+
.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
99
|
+
}
|
|
100
|
+
function normalizeManifestSymbolsForSourceFile(records, sourceFile) {
|
|
101
|
+
return records
|
|
102
|
+
.filter((record) => {
|
|
103
|
+
const recordSource = typeof record.sourceFile === "string"
|
|
104
|
+
? record.sourceFile
|
|
105
|
+
: typeof record.source === "string"
|
|
106
|
+
? record.source
|
|
107
|
+
: null;
|
|
108
|
+
return recordSource === sourceFile && typeof record.title === "string";
|
|
109
|
+
})
|
|
110
|
+
.map((record) => ({
|
|
111
|
+
title: record.title,
|
|
112
|
+
sourceFile,
|
|
113
|
+
sourceLine: normalizeNumber(record.sourceLine),
|
|
114
|
+
sourceColumn: normalizeNumber(record.sourceColumn),
|
|
115
|
+
sourceEndLine: normalizeNumber(record.sourceEndLine),
|
|
116
|
+
sourceEndColumn: normalizeNumber(record.sourceEndColumn),
|
|
117
|
+
}))
|
|
118
|
+
.sort(compareNormalizedSymbols);
|
|
119
|
+
}
|
|
120
|
+
function normalizeAuthoredManifestSymbolsForSourceFile(records, sourceFile) {
|
|
121
|
+
return records
|
|
122
|
+
.filter((record) => {
|
|
123
|
+
const recordSource = typeof record.sourceFile === "string"
|
|
124
|
+
? record.sourceFile
|
|
125
|
+
: typeof record.source === "string"
|
|
126
|
+
? record.source
|
|
127
|
+
: null;
|
|
128
|
+
return recordSource === sourceFile && typeof record.title === "string";
|
|
129
|
+
})
|
|
130
|
+
.map((record) => ({
|
|
131
|
+
id: typeof record.id === "string" ? record.id : null,
|
|
132
|
+
title: record.title,
|
|
133
|
+
sourceFile,
|
|
134
|
+
status: typeof record.status === "string" ? record.status : null,
|
|
135
|
+
links: normalizeLinks(record.links),
|
|
136
|
+
relationships: normalizeRelationships(record.relationships),
|
|
137
|
+
tags: Array.isArray(record.tags)
|
|
138
|
+
? record.tags.filter((tag) => typeof tag === "string").sort()
|
|
139
|
+
: [],
|
|
140
|
+
owner: typeof record.owner === "string" ? record.owner : null,
|
|
141
|
+
priority: typeof record.priority === "string" ? record.priority : null,
|
|
142
|
+
severity: typeof record.severity === "string" ? record.severity : null,
|
|
143
|
+
textRef: typeof record.text_ref === "string" ? record.text_ref : null,
|
|
144
|
+
}))
|
|
145
|
+
.sort((left, right) => JSON.stringify(left).localeCompare(JSON.stringify(right)));
|
|
146
|
+
}
|
|
147
|
+
function normalizeExpectedSymbolsForStagedFile(stagedFile) {
|
|
148
|
+
const analysis = analyzeSourceText(stagedFile.path, stagedFile.content ?? "");
|
|
149
|
+
return analysis.symbols
|
|
150
|
+
.map((symbol) => ({
|
|
151
|
+
title: symbol.name,
|
|
152
|
+
sourceFile: stagedFile.path,
|
|
153
|
+
sourceLine: symbol.startLine,
|
|
154
|
+
sourceColumn: symbol.startColumn,
|
|
155
|
+
sourceEndLine: symbol.endLine,
|
|
156
|
+
sourceEndColumn: symbol.endColumn,
|
|
157
|
+
}))
|
|
158
|
+
.sort(compareNormalizedSymbols);
|
|
159
|
+
}
|
|
160
|
+
function compareNormalizedSymbols(left, right) {
|
|
161
|
+
return JSON.stringify(left).localeCompare(JSON.stringify(right));
|
|
162
|
+
}
|
|
163
|
+
function signaturesEqual(left, right) {
|
|
164
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
165
|
+
}
|
|
166
|
+
function uniqueSorted(paths) {
|
|
167
|
+
return Array.from(new Set(paths)).sort();
|
|
168
|
+
}
|
|
169
|
+
function mergeManifestRecordsWithCoordinates(manifestRecords, coordinateArtifact) {
|
|
170
|
+
return mergeCoordinatesWithManifest(manifestRecords ?? [], coordinateArtifact);
|
|
171
|
+
}
|
|
172
|
+
function getEffectiveManifestRecords(options) {
|
|
173
|
+
const { headCoordinateArtifact, headManifestRecords, paths, stagedFiles } = options;
|
|
174
|
+
const stagedManifestFile = stagedFiles.find((file) => file.path === paths.symbolsPath);
|
|
175
|
+
const stagedCoordinatesFile = stagedFiles.find((file) => file.path === paths.coordinatesPath);
|
|
176
|
+
const stagedManifestRecords = stagedManifestFile
|
|
177
|
+
? parseManifestRecords(stagedManifestFile.content, paths.symbolsPath)
|
|
178
|
+
: headManifestRecords;
|
|
179
|
+
const stagedCoordinateArtifact = stagedCoordinatesFile
|
|
180
|
+
? parseCoordinateArtifact(stagedCoordinatesFile.content)
|
|
181
|
+
: headCoordinateArtifact;
|
|
182
|
+
return {
|
|
183
|
+
stagedManifestFile,
|
|
184
|
+
stagedCoordinatesFile,
|
|
185
|
+
stagedManifestRecords,
|
|
186
|
+
stagedCoordinateArtifact,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
export function assessStagedSymbolsManifest(options) {
|
|
190
|
+
const { sourceFiles, stagedFiles, symbolsManifestPath } = options;
|
|
191
|
+
const paths = resolveRelativeManifestPaths(symbolsManifestPath);
|
|
192
|
+
const headManifestRecords = parseManifestRecords(readHeadFileContent(paths.symbolsPath), paths.symbolsPath);
|
|
193
|
+
const headCoordinateArtifact = parseCoordinateArtifact(readHeadFileContent(paths.coordinatesPath));
|
|
194
|
+
const { stagedCoordinatesFile, stagedCoordinateArtifact, stagedManifestRecords, } = getEffectiveManifestRecords({
|
|
195
|
+
stagedFiles,
|
|
196
|
+
paths,
|
|
197
|
+
headManifestRecords,
|
|
198
|
+
headCoordinateArtifact,
|
|
199
|
+
});
|
|
200
|
+
const baselineMergedRecords = mergeManifestRecordsWithCoordinates(headManifestRecords, headCoordinateArtifact);
|
|
201
|
+
const stagedMergedRecords = mergeManifestRecordsWithCoordinates(stagedManifestRecords, stagedCoordinateArtifact);
|
|
202
|
+
const requiredRefreshPaths = [];
|
|
203
|
+
const freshPaths = new Set();
|
|
204
|
+
for (const sourceFile of sourceFiles) {
|
|
205
|
+
const expectedSymbols = normalizeExpectedSymbolsForStagedFile(sourceFile);
|
|
206
|
+
const baselineSymbols = normalizeManifestSymbolsForSourceFile(baselineMergedRecords, sourceFile.path);
|
|
207
|
+
if (signaturesEqual(expectedSymbols, baselineSymbols)) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
requiredRefreshPaths.push(sourceFile.path);
|
|
211
|
+
if (!stagedCoordinatesFile || stagedCoordinateArtifact === null) {
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const stagedSymbols = normalizeManifestSymbolsForSourceFile(stagedMergedRecords, sourceFile.path);
|
|
215
|
+
if (signaturesEqual(expectedSymbols, stagedSymbols)) {
|
|
216
|
+
freshPaths.add(sourceFile.path);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const sourcePaths = uniqueSorted(requiredRefreshPaths);
|
|
220
|
+
if (sourcePaths.length === 0) {
|
|
221
|
+
return { state: "not_required", sourcePaths: [], path: paths.coordinatesPath };
|
|
222
|
+
}
|
|
223
|
+
if (sourcePaths.every((sourcePath) => freshPaths.has(sourcePath))) {
|
|
224
|
+
return { state: "fresh", sourcePaths, path: paths.coordinatesPath };
|
|
225
|
+
}
|
|
226
|
+
if (!stagedCoordinatesFile) {
|
|
227
|
+
return { state: "missing", sourcePaths, path: paths.coordinatesPath };
|
|
228
|
+
}
|
|
229
|
+
return { state: "stale", sourcePaths, path: paths.coordinatesPath };
|
|
230
|
+
}
|
|
231
|
+
function getEntityIdsForSourceFile(records, sourceFile) {
|
|
232
|
+
return records
|
|
233
|
+
.filter((record) => {
|
|
234
|
+
const recordSource = typeof record.sourceFile === "string"
|
|
235
|
+
? record.sourceFile
|
|
236
|
+
: typeof record.source === "string"
|
|
237
|
+
? record.source
|
|
238
|
+
: null;
|
|
239
|
+
return recordSource === sourceFile && typeof record.id === "string";
|
|
240
|
+
})
|
|
241
|
+
.map((record) => record.id)
|
|
242
|
+
.sort();
|
|
243
|
+
}
|
|
244
|
+
export function collectStagedAuthoredSymbolsManifestEvidence(options) {
|
|
245
|
+
const { sourceFiles, stagedFiles } = options;
|
|
246
|
+
const paths = resolveRelativeManifestPaths();
|
|
247
|
+
const stagedManifestFile = stagedFiles.find((file) => file.path === paths.symbolsPath);
|
|
248
|
+
if (!stagedManifestFile) {
|
|
249
|
+
return { path: paths.symbolsPath, entries: [] };
|
|
250
|
+
}
|
|
251
|
+
const headManifestRecords = parseManifestRecords(readHeadFileContent(paths.symbolsPath), paths.symbolsPath) ?? [];
|
|
252
|
+
const stagedManifestRecords = parseManifestRecords(stagedManifestFile.content, paths.symbolsPath);
|
|
253
|
+
if (stagedManifestRecords === null) {
|
|
254
|
+
return { path: paths.symbolsPath, entries: [] };
|
|
255
|
+
}
|
|
256
|
+
const entries = [];
|
|
257
|
+
for (const sourceFile of sourceFiles) {
|
|
258
|
+
const headSymbols = normalizeAuthoredManifestSymbolsForSourceFile(headManifestRecords, sourceFile.path);
|
|
259
|
+
const stagedSymbols = normalizeAuthoredManifestSymbolsForSourceFile(stagedManifestRecords, sourceFile.path);
|
|
260
|
+
if (signaturesEqual(headSymbols, stagedSymbols)) {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
entries.push({
|
|
264
|
+
sourcePath: sourceFile.path,
|
|
265
|
+
entityIds: getEntityIdsForSourceFile(stagedManifestRecords, sourceFile.path),
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return { path: paths.symbolsPath, entries };
|
|
269
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AAGA,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,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7D,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;
|
|
1
|
+
{"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AAGA,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,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7D,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;AA+ND,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,GAC9B,eAAe,EAAE,CA+JnB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { Project, ScriptKind } from "ts-morph";
|
|
3
|
-
import {
|
|
3
|
+
import { readManifestWithCoordinateOverlay } from "../extractors/manifest.js";
|
|
4
4
|
const TRACEABILITY_RELATIONSHIP_TYPES = new Set([
|
|
5
5
|
"implements",
|
|
6
6
|
"covered_by",
|
|
@@ -55,15 +55,12 @@ function resolveSymbolTraceability(filePath, name, manifestLookup) {
|
|
|
55
55
|
}
|
|
56
56
|
for (const manifestPath of candidateManifestPaths) {
|
|
57
57
|
try {
|
|
58
|
-
const
|
|
59
|
-
for (const
|
|
60
|
-
if (
|
|
58
|
+
const records = readManifestWithCoordinateOverlay(manifestPath);
|
|
59
|
+
for (const record of records) {
|
|
60
|
+
if (record.title === name && typeof record.id === "string") {
|
|
61
61
|
return {
|
|
62
|
-
id:
|
|
63
|
-
relationships: filterTraceabilityRelationships(
|
|
64
|
-
type: relationship.type,
|
|
65
|
-
to: relationship.to,
|
|
66
|
-
}))),
|
|
62
|
+
id: record.id,
|
|
63
|
+
relationships: filterTraceabilityRelationships(extractRelationshipsFromManifestRecord(record)),
|
|
67
64
|
};
|
|
68
65
|
}
|
|
69
66
|
}
|
|
@@ -74,6 +71,33 @@ function resolveSymbolTraceability(filePath, name, manifestLookup) {
|
|
|
74
71
|
}
|
|
75
72
|
return { id: createHashFallbackId(filePath, name) };
|
|
76
73
|
}
|
|
74
|
+
function extractRelationshipsFromManifestRecord(record) {
|
|
75
|
+
const relationships = [];
|
|
76
|
+
if (Array.isArray(record.links)) {
|
|
77
|
+
for (const link of record.links) {
|
|
78
|
+
if (typeof link === "string") {
|
|
79
|
+
relationships.push({ type: "implements", to: link });
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (link &&
|
|
83
|
+
typeof link === "object" &&
|
|
84
|
+
typeof link.type === "string" &&
|
|
85
|
+
typeof link.target === "string") {
|
|
86
|
+
relationships.push({ type: link.type, to: link.target });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (Array.isArray(record.relationships)) {
|
|
91
|
+
for (const relationship of record.relationships) {
|
|
92
|
+
if (relationship &&
|
|
93
|
+
typeof relationship.type === "string" &&
|
|
94
|
+
typeof relationship.target === "string") {
|
|
95
|
+
relationships.push({ type: relationship.type, to: relationship.target });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return relationships;
|
|
100
|
+
}
|
|
77
101
|
function buildSymbolResult(stagedFile, name, kind, span, inlineReqLinks, manifestLookup) {
|
|
78
102
|
const { id, relationships } = resolveSymbolTraceability(stagedFile.path, name, manifestLookup);
|
|
79
103
|
const manifestReqLinks = getRequirementLinks(relationships);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const DEFAULT_SYMBOLS_PATH = "documentation/symbols.yaml";
|
|
2
|
+
export declare const DEFAULT_COORDINATES_PATH = "documentation/symbol-coordinates.yaml";
|
|
3
|
+
export declare function resolveSymbolsManifestPaths(workspaceRoot: string, configPath?: string): {
|
|
4
|
+
symbolsPath: string;
|
|
5
|
+
coordinatesPath: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function resolveSymbolsManifestPath(workspaceRoot: string, configPath?: string): string;
|
|
8
|
+
//# sourceMappingURL=manifest-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-paths.d.ts","sourceRoot":"","sources":["../../src/utils/manifest-paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,oBAAoB,+BAA+B,CAAC;AACjE,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;AAuEhF,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAA;CAAE,CASlD;AAGD,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAER"}
|