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
package/dist/cli.js
CHANGED
|
@@ -66,10 +66,12 @@ program
|
|
|
66
66
|
.command("sync")
|
|
67
67
|
.description("Sync entities from documents")
|
|
68
68
|
.option("--validate-only", "Perform validation without mutations")
|
|
69
|
+
.option("--refresh-symbol-coordinates", "Refresh generated symbol coordinates")
|
|
69
70
|
.option("--rebuild", "Rebuild branch snapshot from scratch (discards current KB)")
|
|
70
71
|
.action(withExitCode(async (options) => {
|
|
71
72
|
return syncCommand(options);
|
|
72
73
|
}));
|
|
74
|
+
program;
|
|
73
75
|
program
|
|
74
76
|
.command("query [type]")
|
|
75
77
|
.description("Query knowledge base")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AA8EA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+UD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmU/B"}
|
package/dist/commands/check.js
CHANGED
|
@@ -22,8 +22,12 @@ import { extractFromManifest, extractFromManifestString, } from "../extractors/m
|
|
|
22
22
|
import { extractFromMarkdownString, } from "../extractors/markdown.js";
|
|
23
23
|
import { PrologProcess } from "../prolog.js";
|
|
24
24
|
import { escapeAtom, parseTriples, parseViolationRows, } from "../prolog/codec.js";
|
|
25
|
-
import { getStagedFiles } from "../traceability/git-staged.js";
|
|
25
|
+
import { getStagedFiles, } from "../traceability/git-staged.js";
|
|
26
|
+
import { KIBI_NO_IMPACT_DECLARATION, KIBI_SYMBOLS_MANIFEST_PATH, } from "../traceability/evidence-model.js";
|
|
26
27
|
import { validateStagedMarkdown } from "../traceability/markdown-validate.js";
|
|
28
|
+
import { collectStagedKibiDiagnostics, } from "../traceability/staged-diagnostics.js";
|
|
29
|
+
import { classifyKibiImpactEvidence, isBehaviorSourceEdit, parseKibiImpactOverride, } from "../traceability/staged-impact-contract.js";
|
|
30
|
+
import { assessStagedSymbolsManifest, collectStagedAuthoredSymbolsManifestEvidence, } from "../traceability/staged-symbols-manifest.js";
|
|
27
31
|
import { createManifestLookupSentinelKey, extractSymbolsFromStagedFile, } from "../traceability/symbol-extract.js";
|
|
28
32
|
import { cleanupTempKb, consultOverlay, createOverlayFacts, createTempKb, projectStagedEntities, } from "../traceability/temp-kb.js";
|
|
29
33
|
import { formatViolations as formatStagedViolations, validateStagedSymbols, } from "../traceability/validate.js";
|
|
@@ -112,6 +116,173 @@ function buildManifestLookup(stagedFiles) {
|
|
|
112
116
|
}
|
|
113
117
|
return { manifestLookup, manifestResults };
|
|
114
118
|
}
|
|
119
|
+
const KIBI_ENTITY_TYPES = new Set([
|
|
120
|
+
"req",
|
|
121
|
+
"scenario",
|
|
122
|
+
"test",
|
|
123
|
+
"adr",
|
|
124
|
+
"flag",
|
|
125
|
+
"event",
|
|
126
|
+
"symbol",
|
|
127
|
+
"fact",
|
|
128
|
+
]);
|
|
129
|
+
function isKibiEntityType(value) {
|
|
130
|
+
return KIBI_ENTITY_TYPES.has(value);
|
|
131
|
+
}
|
|
132
|
+
function isStagedManifestPath(filePath) {
|
|
133
|
+
if (filePath.endsWith("/symbols.yaml") ||
|
|
134
|
+
filePath.endsWith("/symbols.yml") ||
|
|
135
|
+
filePath.endsWith("/symbol-coordinates.yaml") ||
|
|
136
|
+
filePath === "symbols.yaml" ||
|
|
137
|
+
filePath === "symbols.yml" ||
|
|
138
|
+
filePath === "symbol-coordinates.yaml") {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const config = loadConfig(process.cwd());
|
|
143
|
+
if (config.paths.symbols) {
|
|
144
|
+
const relSymbols = config.paths.symbols;
|
|
145
|
+
const configuredBase = relSymbols.split(/[\\/]/).pop();
|
|
146
|
+
if (filePath === relSymbols ||
|
|
147
|
+
(configuredBase && filePath.endsWith(`/${configuredBase}`))) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// ignore config read errors
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
function isTestOnlySourcePath(filePath) {
|
|
158
|
+
return (filePath.startsWith("tests/") ||
|
|
159
|
+
filePath.includes("/tests/") ||
|
|
160
|
+
filePath.endsWith(".test.ts") ||
|
|
161
|
+
filePath.endsWith(".test.tsx") ||
|
|
162
|
+
filePath.endsWith(".test.js") ||
|
|
163
|
+
filePath.endsWith(".test.jsx") ||
|
|
164
|
+
filePath.endsWith(".spec.ts") ||
|
|
165
|
+
filePath.endsWith(".spec.tsx") ||
|
|
166
|
+
filePath.endsWith(".spec.js") ||
|
|
167
|
+
filePath.endsWith(".spec.jsx"));
|
|
168
|
+
}
|
|
169
|
+
function getStagedDiffText(stagedFile) {
|
|
170
|
+
return stagedFile.diffText ?? "";
|
|
171
|
+
}
|
|
172
|
+
function formatStagedKibiDiagnostics(diagnostics) {
|
|
173
|
+
return diagnostics
|
|
174
|
+
.map((diagnostic) => {
|
|
175
|
+
const lines = [`[${diagnostic.id}] ${diagnostic.message}`];
|
|
176
|
+
if (diagnostic.files.length > 0) {
|
|
177
|
+
lines.push(` Files: ${diagnostic.files.join(", ")}`);
|
|
178
|
+
}
|
|
179
|
+
if (diagnostic.docs.length > 0) {
|
|
180
|
+
lines.push(` Docs: ${diagnostic.docs.join(", ")}`);
|
|
181
|
+
}
|
|
182
|
+
lines.push(` Suggestion: ${diagnostic.suggestion}`);
|
|
183
|
+
return lines.join("\n");
|
|
184
|
+
})
|
|
185
|
+
.join("\n\n");
|
|
186
|
+
}
|
|
187
|
+
function uniqueSorted(values) {
|
|
188
|
+
return Array.from(new Set(values)).sort();
|
|
189
|
+
}
|
|
190
|
+
function buildStagedKibiImpactEvidence(options) {
|
|
191
|
+
const { stagedFiles, sourceFiles, markdownFiles, markdownResults, symbolsByFile, symbolsManifestPath, } = options;
|
|
192
|
+
const sourceChanges = sourceFiles.map((file) => {
|
|
193
|
+
const symbolsForFile = symbolsByFile.get(file.path) ?? [];
|
|
194
|
+
const behaviorCandidate = !isTestOnlySourcePath(file.path) &&
|
|
195
|
+
isBehaviorSourceEdit({
|
|
196
|
+
path: file.path,
|
|
197
|
+
diffText: getStagedDiffText(file),
|
|
198
|
+
intersectsBehaviorBearingSymbol: symbolsForFile.length > 0,
|
|
199
|
+
knownUserFacingSurface: false,
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
path: file.path,
|
|
203
|
+
kind: behaviorCandidate
|
|
204
|
+
? "behavior_source_edit"
|
|
205
|
+
: "non_behavior_source_edit",
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
const behaviorSourcePaths = sourceChanges
|
|
209
|
+
.filter((change) => change.kind === "behavior_source_edit")
|
|
210
|
+
.map((change) => change.path);
|
|
211
|
+
const allSourcePaths = sourceChanges.map((change) => change.path);
|
|
212
|
+
const behaviorSourceFiles = sourceFiles.filter((file) => behaviorSourcePaths.includes(file.path));
|
|
213
|
+
const stagedSymbolsManifest = assessStagedSymbolsManifest({
|
|
214
|
+
symbolsManifestPath,
|
|
215
|
+
stagedFiles,
|
|
216
|
+
sourceFiles: behaviorSourceFiles,
|
|
217
|
+
});
|
|
218
|
+
const stagedAuthoredSymbolsEvidence = collectStagedAuthoredSymbolsManifestEvidence({
|
|
219
|
+
stagedFiles,
|
|
220
|
+
sourceFiles: behaviorSourceFiles,
|
|
221
|
+
});
|
|
222
|
+
const markdownResultsByPath = new Map();
|
|
223
|
+
for (const [index, file] of markdownFiles.entries()) {
|
|
224
|
+
const result = markdownResults[index];
|
|
225
|
+
if (result) {
|
|
226
|
+
markdownResultsByPath.set(file.path, result);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
const resolvedKbArtifacts = [];
|
|
230
|
+
let override = null;
|
|
231
|
+
for (const file of markdownFiles) {
|
|
232
|
+
const parsedOverride = parseKibiImpactOverride(file.content ?? "");
|
|
233
|
+
const evidenceKind = classifyKibiImpactEvidence({
|
|
234
|
+
filePath: file.path,
|
|
235
|
+
extractionOutputChanged: false,
|
|
236
|
+
overrideDeclared: parsedOverride.declared,
|
|
237
|
+
overrideRationale: parsedOverride.rationale,
|
|
238
|
+
});
|
|
239
|
+
if (evidenceKind === "entity_markdown") {
|
|
240
|
+
const result = markdownResultsByPath.get(file.path);
|
|
241
|
+
if (result && isKibiEntityType(result.entity.type)) {
|
|
242
|
+
resolvedKbArtifacts.push({
|
|
243
|
+
kind: "entity_markdown",
|
|
244
|
+
path: file.path,
|
|
245
|
+
entityTypes: [result.entity.type],
|
|
246
|
+
entityIds: [result.entity.id],
|
|
247
|
+
sourcePaths: [...behaviorSourcePaths],
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (!parsedOverride.declared || override !== null) {
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
override = {
|
|
256
|
+
declaration: KIBI_NO_IMPACT_DECLARATION,
|
|
257
|
+
path: file.path,
|
|
258
|
+
sourcePaths: [...allSourcePaths],
|
|
259
|
+
reason: "non_behavioral_source_edit",
|
|
260
|
+
rationale: parsedOverride.rationale ?? "",
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
if (stagedAuthoredSymbolsEvidence.entries.length > 0) {
|
|
264
|
+
resolvedKbArtifacts.push({
|
|
265
|
+
kind: "symbols_manifest",
|
|
266
|
+
path: stagedAuthoredSymbolsEvidence.path,
|
|
267
|
+
entityTypes: ["symbol"],
|
|
268
|
+
entityIds: uniqueSorted(stagedAuthoredSymbolsEvidence.entries.flatMap((entry) => entry.entityIds)),
|
|
269
|
+
sourcePaths: uniqueSorted(stagedAuthoredSymbolsEvidence.entries.map((entry) => entry.sourcePath)),
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
sourceChanges,
|
|
274
|
+
symbolsManifest: {
|
|
275
|
+
path: stagedSymbolsManifest.path,
|
|
276
|
+
state: stagedSymbolsManifest.state,
|
|
277
|
+
sourcePaths: stagedSymbolsManifest.sourcePaths,
|
|
278
|
+
},
|
|
279
|
+
mode: resolvedKbArtifacts.length > 0
|
|
280
|
+
? { kind: "kb_changes", kbArtifacts: resolvedKbArtifacts }
|
|
281
|
+
: override
|
|
282
|
+
? { kind: "no_impact_override", override }
|
|
283
|
+
: { kind: "missing" },
|
|
284
|
+
};
|
|
285
|
+
}
|
|
115
286
|
// implements REQ-006
|
|
116
287
|
export async function checkCommand(options) {
|
|
117
288
|
let prolog = null;
|
|
@@ -147,7 +318,8 @@ export async function checkCommand(options) {
|
|
|
147
318
|
return { exitCode: 0 };
|
|
148
319
|
}
|
|
149
320
|
const { manifestLookup, manifestResults } = buildManifestLookup(stagedFiles);
|
|
150
|
-
const
|
|
321
|
+
const symbolsManifestPath = loadConfig(process.cwd()).paths.symbols ?? KIBI_SYMBOLS_MANIFEST_PATH;
|
|
322
|
+
const sourceFiles = stagedFiles.filter((file) => !file.path.endsWith(".md") && !isStagedManifestPath(file.path));
|
|
151
323
|
const markdownFiles = stagedFiles.filter((f) => f.path.endsWith(".md"));
|
|
152
324
|
const markdownErrors = [];
|
|
153
325
|
for (const f of markdownFiles) {
|
|
@@ -168,9 +340,11 @@ export async function checkCommand(options) {
|
|
|
168
340
|
return { exitCode: 1 };
|
|
169
341
|
}
|
|
170
342
|
const allSymbols = [];
|
|
171
|
-
|
|
343
|
+
const symbolsByFile = new Map();
|
|
344
|
+
for (const f of sourceFiles) {
|
|
172
345
|
try {
|
|
173
346
|
const symbols = extractSymbolsFromStagedFile(f, manifestLookup);
|
|
347
|
+
symbolsByFile.set(f.path, symbols);
|
|
174
348
|
if (symbols?.length) {
|
|
175
349
|
allSymbols.push(...symbols);
|
|
176
350
|
}
|
|
@@ -184,11 +358,27 @@ export async function checkCommand(options) {
|
|
|
184
358
|
...manifestResults,
|
|
185
359
|
...markdownResults,
|
|
186
360
|
];
|
|
361
|
+
const stagedKibiEvidence = buildStagedKibiImpactEvidence({
|
|
362
|
+
stagedFiles,
|
|
363
|
+
sourceFiles,
|
|
364
|
+
markdownFiles,
|
|
365
|
+
markdownResults,
|
|
366
|
+
symbolsByFile,
|
|
367
|
+
symbolsManifestPath,
|
|
368
|
+
});
|
|
369
|
+
const stagedKibiDiagnostics = collectStagedKibiDiagnostics(stagedKibiEvidence);
|
|
187
370
|
if (allSymbols.length === 0 && stagedEntityResults.length === 0) {
|
|
188
371
|
console.log("No exported symbols or staged entities found in staged files.");
|
|
189
372
|
return { exitCode: 0 };
|
|
190
373
|
}
|
|
191
374
|
if (allSymbols.length === 0) {
|
|
375
|
+
if (stagedKibiDiagnostics.length > 0) {
|
|
376
|
+
console.log(formatStagedKibiDiagnostics(stagedKibiDiagnostics));
|
|
377
|
+
if (options.dryRun) {
|
|
378
|
+
return { exitCode: 0 };
|
|
379
|
+
}
|
|
380
|
+
return { exitCode: 1 };
|
|
381
|
+
}
|
|
192
382
|
console.log("✓ No violations found in staged files.");
|
|
193
383
|
return { exitCode: 0 };
|
|
194
384
|
}
|
|
@@ -207,6 +397,10 @@ export async function checkCommand(options) {
|
|
|
207
397
|
prolog: tempCtx.prolog,
|
|
208
398
|
});
|
|
209
399
|
const violationsFormatted = formatStagedViolations(violationsRaw);
|
|
400
|
+
if (stagedKibiDiagnostics.length > 0) {
|
|
401
|
+
console.log(formatStagedKibiDiagnostics(stagedKibiDiagnostics));
|
|
402
|
+
console.log();
|
|
403
|
+
}
|
|
210
404
|
if (violationsRaw && violationsRaw.length > 0) {
|
|
211
405
|
console.log(violationsFormatted);
|
|
212
406
|
await cleanupTempKb(tempCtx.tempDir);
|
|
@@ -215,6 +409,13 @@ export async function checkCommand(options) {
|
|
|
215
409
|
}
|
|
216
410
|
return { exitCode: 1 };
|
|
217
411
|
}
|
|
412
|
+
if (stagedKibiDiagnostics.length > 0) {
|
|
413
|
+
await cleanupTempKb(tempCtx.tempDir);
|
|
414
|
+
if (options.dryRun) {
|
|
415
|
+
return { exitCode: 0 };
|
|
416
|
+
}
|
|
417
|
+
return { exitCode: 1 };
|
|
418
|
+
}
|
|
218
419
|
console.log("✓ No violations found in staged symbols.");
|
|
219
420
|
await cleanupTempKb(tempCtx.tempDir);
|
|
220
421
|
return { exitCode: 0 };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AAoGA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAsBjD;AAGD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3D;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAkCnE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiBpD"}
|
|
@@ -27,6 +27,8 @@ const POST_CHECKOUT_HOOK = `#!/bin/sh
|
|
|
27
27
|
# branch_flag is 1 for branch checkout, 0 for file checkout
|
|
28
28
|
# Refresh branch/worktree assumptions after checkout so advisory plugin state
|
|
29
29
|
# starts from synced KB data instead of stale in-memory cache assumptions.
|
|
30
|
+
# Uses default non-coordinate-writing sync to avoid writing
|
|
31
|
+
# committed symbol artifacts during automatic hook execution.
|
|
30
32
|
|
|
31
33
|
old_ref=$1
|
|
32
34
|
new_ref=$2
|
|
@@ -48,6 +50,8 @@ const POST_MERGE_HOOK = `#!/bin/sh
|
|
|
48
50
|
# post-merge hook for kibi
|
|
49
51
|
# Parameter: squash_flag (not used)
|
|
50
52
|
# Refresh KB state after merge so branch-level assumptions remain current.
|
|
53
|
+
# Uses default non-coordinate-writing sync to avoid writing
|
|
54
|
+
# committed symbol artifacts during automatic hook execution.
|
|
51
55
|
|
|
52
56
|
kibi sync
|
|
53
57
|
`;
|
|
@@ -55,6 +59,8 @@ const POST_REWRITE_HOOK = `#!/bin/sh
|
|
|
55
59
|
# post-rewrite hook for kibi
|
|
56
60
|
# Triggered after git rebase, git commit --amend, etc.
|
|
57
61
|
# Parameter: rewrite_type (rebase or amend)
|
|
62
|
+
# Uses default non-coordinate-writing sync to avoid writing
|
|
63
|
+
# committed symbol artifacts during automatic hook execution.
|
|
58
64
|
|
|
59
65
|
rewrite_type=$1
|
|
60
66
|
|
|
@@ -66,23 +72,14 @@ const PRE_COMMIT_HOOK = `#!/bin/sh
|
|
|
66
72
|
# pre-commit hook for kibi
|
|
67
73
|
# Hard enforcement boundary: commits are blocked only here via kibi check.
|
|
68
74
|
# The OpenCode plugin remains advisory and must not replace this gate.
|
|
75
|
+
# Behavior-changing source edits require staged Kibi impact evidence
|
|
76
|
+
# (KB entity docs, authored symbols metadata, or refreshed symbol
|
|
77
|
+
# coordinates). Test-only and docs-only edits are exempt.
|
|
78
|
+
# Refresh with:
|
|
79
|
+
# kibi sync --refresh-symbol-coordinates && git add documentation/symbol-coordinates.yaml documentation/symbols.yaml
|
|
69
80
|
|
|
70
81
|
set -e
|
|
71
82
|
|
|
72
|
-
symbols_manifest="documentation/symbols.yaml"
|
|
73
|
-
|
|
74
|
-
if [ ! -f "$symbols_manifest" ]; then
|
|
75
|
-
echo "Kibi symbols manifest is missing: $symbols_manifest" >&2
|
|
76
|
-
echo "Run 'kibi init' to create it, then stage and commit it." >&2
|
|
77
|
-
exit 1
|
|
78
|
-
fi
|
|
79
|
-
|
|
80
|
-
if ! git diff --quiet -- "$symbols_manifest"; then
|
|
81
|
-
echo "Kibi symbols manifest has unstaged changes: $symbols_manifest" >&2
|
|
82
|
-
echo "Stage and commit documentation/symbols.yaml with the code changes that refreshed it." >&2
|
|
83
|
-
exit 1
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
83
|
kibi check --staged
|
|
87
84
|
`;
|
|
88
85
|
export async function getCurrentBranch(cwd = process.cwd()) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { dump as dumpYAML, load as parseYAML } from "js-yaml";
|
|
3
3
|
import { type ManifestSymbolEntry, enrichSymbolCoordinates } from "../../extractors/symbols-coordinator.js";
|
|
4
|
+
import { writeCoordinateArtifact } from "../../extractors/symbol-coordinates.js";
|
|
5
|
+
import { resolveSymbolsManifestPaths } from "../../utils/manifest-paths.js";
|
|
4
6
|
interface ManifestDeps {
|
|
5
7
|
dumpYAML: typeof dumpYAML;
|
|
6
8
|
enrichSymbolCoordinates: typeof enrichSymbolCoordinates;
|
|
@@ -8,9 +10,13 @@ interface ManifestDeps {
|
|
|
8
10
|
parseYAML: typeof parseYAML;
|
|
9
11
|
readFileSync: typeof readFileSync;
|
|
10
12
|
writeFileSync: typeof writeFileSync;
|
|
13
|
+
writeCoordinateArtifact: typeof writeCoordinateArtifact;
|
|
14
|
+
resolveSymbolsManifestPaths: typeof resolveSymbolsManifestPaths;
|
|
11
15
|
}
|
|
12
|
-
export declare const SYMBOLS_MANIFEST_COMMENT_BLOCK = "# symbols.yaml\n# AUTHORED fields (edit freely):\n# id, title, sourceFile, links, status, tags, owner, priority\n# GENERATED fields (never edit manually \u2014 overwritten by kibi sync and kb.symbols.refresh):\n# sourceLine, sourceColumn, sourceEndLine, sourceEndColumn
|
|
13
|
-
export declare function refreshManifestCoordinates(manifestPath: string, workspaceRoot: string, deps?: Partial<ManifestDeps>
|
|
16
|
+
export declare const SYMBOLS_MANIFEST_COMMENT_BLOCK = "# symbols.yaml\n# AUTHORED fields (edit freely):\n# id, title, sourceFile, links, status, tags, owner, priority\n# GENERATED fields (never edit manually \u2014 overwritten by kibi sync and kb.symbols.refresh):\n# sourceLine, sourceColumn, sourceEndLine, sourceEndColumn\n# Run `kibi sync` or call the `kb.symbols.refresh` MCP tool to refresh coordinates.\n";
|
|
17
|
+
export declare function refreshManifestCoordinates(manifestPath: string, workspaceRoot: string, deps?: Partial<ManifestDeps> & {
|
|
18
|
+
refreshSymbolCoordinates?: boolean;
|
|
19
|
+
}): Promise<void>;
|
|
14
20
|
export declare function hasAllGeneratedCoordinates(entry: ManifestSymbolEntry): boolean;
|
|
15
21
|
export declare function isEligibleForCoordinateRefresh(sourceFile: string | undefined, workspaceRoot: string, deps?: Partial<ManifestDeps>): boolean;
|
|
16
22
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE5E,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;CACjE;AAgBD,eAAO,MAAM,8BAA8B,6WAM1C,CAAC;AAoBF,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;IAAE,wBAAwB,CAAC,EAAE,OAAO,CAAA;CAAE,GACpE,OAAO,CAAC,IAAI,CAAC,CAmIf;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAOT;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAUT"}
|
|
@@ -14,11 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
|
|
17
|
+
*/
|
|
18
18
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
20
|
import { dump as dumpYAML, load as parseYAML } from "js-yaml";
|
|
21
21
|
import { enrichSymbolCoordinates, } from "../../extractors/symbols-coordinator.js";
|
|
22
|
+
import { writeCoordinateArtifact } from "../../extractors/symbol-coordinates.js";
|
|
23
|
+
import { resolveSymbolsManifestPaths } from "../../utils/manifest-paths.js";
|
|
22
24
|
function resolveDeps(overrides) {
|
|
23
25
|
return {
|
|
24
26
|
dumpYAML,
|
|
@@ -27,6 +29,8 @@ function resolveDeps(overrides) {
|
|
|
27
29
|
parseYAML,
|
|
28
30
|
readFileSync,
|
|
29
31
|
writeFileSync,
|
|
32
|
+
writeCoordinateArtifact,
|
|
33
|
+
resolveSymbolsManifestPaths,
|
|
30
34
|
...overrides,
|
|
31
35
|
};
|
|
32
36
|
}
|
|
@@ -34,7 +38,7 @@ export const SYMBOLS_MANIFEST_COMMENT_BLOCK = `# symbols.yaml
|
|
|
34
38
|
# AUTHORED fields (edit freely):
|
|
35
39
|
# id, title, sourceFile, links, status, tags, owner, priority
|
|
36
40
|
# GENERATED fields (never edit manually — overwritten by kibi sync and kb.symbols.refresh):
|
|
37
|
-
# sourceLine, sourceColumn, sourceEndLine, sourceEndColumn
|
|
41
|
+
# sourceLine, sourceColumn, sourceEndLine, sourceEndColumn
|
|
38
42
|
# Run \`kibi sync\` or call the \`kb.symbols.refresh\` MCP tool to refresh coordinates.
|
|
39
43
|
`;
|
|
40
44
|
const SYMBOL_COORD_EXTENSIONS = new Set([
|
|
@@ -52,12 +56,12 @@ const GENERATED_COORD_FIELDS = [
|
|
|
52
56
|
"sourceColumn",
|
|
53
57
|
"sourceEndLine",
|
|
54
58
|
"sourceEndColumn",
|
|
55
|
-
"coordinatesGeneratedAt",
|
|
56
59
|
];
|
|
57
60
|
export async function refreshManifestCoordinates(
|
|
58
61
|
// implements REQ-003
|
|
59
62
|
manifestPath, workspaceRoot, deps) {
|
|
60
63
|
const resolved = resolveDeps(deps);
|
|
64
|
+
const shouldRefreshCoordinates = deps?.refreshSymbolCoordinates ?? false;
|
|
61
65
|
const rawContent = resolved.readFileSync(manifestPath, "utf8");
|
|
62
66
|
const parsed = resolved.parseYAML(rawContent);
|
|
63
67
|
if (!isRecord(parsed)) {
|
|
@@ -69,11 +73,54 @@ manifestPath, workspaceRoot, deps) {
|
|
|
69
73
|
console.warn(`Warning: symbols manifest ${manifestPath} has no symbols array; skipping coordinate refresh`);
|
|
70
74
|
return;
|
|
71
75
|
}
|
|
72
|
-
const before = rawSymbols.map((entry) => isRecord(entry)
|
|
73
|
-
? { ...entry }
|
|
74
|
-
: {});
|
|
76
|
+
const before = rawSymbols.map((entry) => isRecord(entry) ? { ...entry } : {});
|
|
75
77
|
const enriched = await resolved.enrichSymbolCoordinates(before, workspaceRoot);
|
|
76
|
-
|
|
78
|
+
// Build coordinates map keyed by symbol id
|
|
79
|
+
const coordinatesMap = {};
|
|
80
|
+
for (const entry of enriched) {
|
|
81
|
+
const id = typeof entry?.id === "string" ? entry.id : undefined;
|
|
82
|
+
if (!id)
|
|
83
|
+
continue;
|
|
84
|
+
if (typeof entry.sourceFile === "string" &&
|
|
85
|
+
typeof entry.sourceLine === "number" &&
|
|
86
|
+
typeof entry.sourceColumn === "number" &&
|
|
87
|
+
typeof entry.sourceEndLine === "number" &&
|
|
88
|
+
typeof entry.sourceEndColumn === "number") {
|
|
89
|
+
coordinatesMap[id] = {
|
|
90
|
+
sourceFile: entry.sourceFile,
|
|
91
|
+
sourceLine: entry.sourceLine,
|
|
92
|
+
sourceColumn: entry.sourceColumn,
|
|
93
|
+
sourceEndLine: entry.sourceEndLine,
|
|
94
|
+
sourceEndColumn: entry.sourceEndColumn,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Optionally write the coordinate artifact to the coordinates path when explicitly requested
|
|
99
|
+
if (shouldRefreshCoordinates) {
|
|
100
|
+
try {
|
|
101
|
+
const coordinatesPath = resolved.resolveSymbolsManifestPaths(workspaceRoot).coordinatesPath;
|
|
102
|
+
const artifactContent = resolved.writeCoordinateArtifact(coordinatesMap);
|
|
103
|
+
resolved.writeFileSync(coordinatesPath, artifactContent, "utf8");
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.warn(`Warning: Failed to write symbol-coordinates artifact: ${String(err)}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Strip generated fields from symbols.yaml entries only if original had them
|
|
110
|
+
const strippedEnriched = enriched.map((current, idx) => {
|
|
111
|
+
const prev = before[idx] ?? {};
|
|
112
|
+
const out = { ...current };
|
|
113
|
+
const originalHadGenerated = GENERATED_COORD_FIELDS.some((f) => prev[f] !== undefined);
|
|
114
|
+
if (originalHadGenerated) {
|
|
115
|
+
for (const field of GENERATED_COORD_FIELDS) {
|
|
116
|
+
delete out[field];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Ensure we never write coordinatesGeneratedAt
|
|
120
|
+
delete out["coordinatesGeneratedAt"];
|
|
121
|
+
return out;
|
|
122
|
+
});
|
|
123
|
+
parsed.symbols = strippedEnriched;
|
|
77
124
|
let refreshed = 0;
|
|
78
125
|
let failed = 0;
|
|
79
126
|
let unchanged = 0;
|
|
@@ -106,7 +153,7 @@ manifestPath, workspaceRoot, deps) {
|
|
|
106
153
|
if (rawContent !== nextContent) {
|
|
107
154
|
resolved.writeFileSync(manifestPath, nextContent, "utf8");
|
|
108
155
|
}
|
|
109
|
-
console.log(
|
|
156
|
+
console.log(`\u2713 Refreshed symbol coordinates in ${path.relative(workspaceRoot, manifestPath)} (refreshed=${refreshed}, unchanged=${unchanged}, failed=${failed})`);
|
|
110
157
|
}
|
|
111
158
|
export function hasAllGeneratedCoordinates(
|
|
112
159
|
// implements REQ-003
|
|
@@ -114,9 +161,7 @@ entry) {
|
|
|
114
161
|
return (typeof entry.sourceLine === "number" &&
|
|
115
162
|
typeof entry.sourceColumn === "number" &&
|
|
116
163
|
typeof entry.sourceEndLine === "number" &&
|
|
117
|
-
typeof entry.sourceEndColumn === "number"
|
|
118
|
-
typeof entry.coordinatesGeneratedAt === "string" &&
|
|
119
|
-
entry.coordinatesGeneratedAt.length > 0);
|
|
164
|
+
typeof entry.sourceEndColumn === "number");
|
|
120
165
|
}
|
|
121
166
|
export function isEligibleForCoordinateRefresh(
|
|
122
167
|
// implements REQ-003
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ interface SyncCommandRuntime {
|
|
|
25
25
|
export declare function syncCommand(options?: {
|
|
26
26
|
validateOnly?: boolean;
|
|
27
27
|
rebuild?: boolean;
|
|
28
|
+
refreshSymbolCoordinates?: boolean;
|
|
28
29
|
}, runtime?: SyncCommandRuntime): Promise<SyncResult>;
|
|
29
30
|
export { normalizeMarkdownPath } from "./sync/discovery.js";
|
|
30
31
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAejE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA4B7C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAGD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;CAChE;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAejE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA4B7C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAGD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;CAChE;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,wBAAwB,CAAC,EAAE,OAAO,CAAA;CAAO,EAC/F,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAkbrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -140,13 +140,15 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
142
|
if (!validateOnly) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
143
|
+
if (options.refreshSymbolCoordinates) {
|
|
144
|
+
for (const file of manifestFiles) {
|
|
145
|
+
try {
|
|
146
|
+
await refreshManifestCoordinates(file, process.cwd(), { refreshSymbolCoordinates: options.refreshSymbolCoordinates });
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
150
|
+
console.warn(`Warning: Failed to refresh symbol coordinates in ${file}: ${message}`);
|
|
151
|
+
}
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
154
|
}
|
|
@@ -27,6 +27,36 @@ export declare class ManifestError extends Error {
|
|
|
27
27
|
filePath: string;
|
|
28
28
|
constructor(message: string, filePath: string);
|
|
29
29
|
}
|
|
30
|
+
export interface ManifestSymbolRecord {
|
|
31
|
+
id?: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
source?: string;
|
|
34
|
+
sourceFile?: string;
|
|
35
|
+
status?: string;
|
|
36
|
+
tags?: string[];
|
|
37
|
+
owner?: string;
|
|
38
|
+
priority?: string;
|
|
39
|
+
severity?: string;
|
|
40
|
+
text_ref?: string;
|
|
41
|
+
created_at?: string;
|
|
42
|
+
updated_at?: string;
|
|
43
|
+
links?: Array<string | {
|
|
44
|
+
type: string;
|
|
45
|
+
target: string;
|
|
46
|
+
}>;
|
|
47
|
+
relationships?: Array<{
|
|
48
|
+
type: string;
|
|
49
|
+
target: string;
|
|
50
|
+
}>;
|
|
51
|
+
sourceLine?: number;
|
|
52
|
+
sourceColumn?: number;
|
|
53
|
+
sourceEndLine?: number;
|
|
54
|
+
sourceEndColumn?: number;
|
|
55
|
+
coordinatesGeneratedAt?: string;
|
|
56
|
+
[key: string]: unknown;
|
|
57
|
+
}
|
|
30
58
|
export declare function extractFromManifestString(content: string, filePath: string): ExtractionResult[];
|
|
59
|
+
export declare function extractManifestSymbolRecordsString(content: string, filePath: string): ManifestSymbolRecord[];
|
|
31
60
|
export declare function extractFromManifest(filePath: string): ExtractionResult[];
|
|
61
|
+
export declare function readManifestWithCoordinateOverlay(manifestPath: string, coordinatesPath?: string): ManifestSymbolRecord[];
|
|
32
62
|
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"
|
|
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;CACnB;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,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,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,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;AAmHD,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"}
|