@svashevchenko/ez-know 0.1.0 → 0.2.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.
- package/README.md +20 -18
- package/dist/cli.js +1038 -746
- package/dist/cli.js.map +4 -4
- package/dist/rest/server.js +520 -15
- package/dist/rest/server.js.map +4 -4
- package/dist/server.js +584 -292
- package/dist/server.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2393,679 +2393,909 @@ function buildKnowledgeGraphQLText(result) {
|
|
|
2393
2393
|
});
|
|
2394
2394
|
}
|
|
2395
2395
|
|
|
2396
|
-
// packages/core/src/knowledge/
|
|
2397
|
-
import {
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
};
|
|
2417
|
-
})
|
|
2418
|
-
);
|
|
2419
|
-
entries.sort((left, right) => left.path.localeCompare(right.path));
|
|
2420
|
-
return entries;
|
|
2396
|
+
// packages/core/src/knowledge/schema-discovery.ts
|
|
2397
|
+
import {
|
|
2398
|
+
isAbstractType,
|
|
2399
|
+
isCompositeType,
|
|
2400
|
+
isListType,
|
|
2401
|
+
isNonNullType,
|
|
2402
|
+
isObjectType,
|
|
2403
|
+
isScalarType,
|
|
2404
|
+
isUnionType
|
|
2405
|
+
} from "graphql";
|
|
2406
|
+
var KNOWLEDGE_SCHEMA_RESOURCE_URI = "ez-know://schema";
|
|
2407
|
+
var KNOWLEDGE_SCHEMA_LOOKUP_URI = "ez-know://lookup/{target}";
|
|
2408
|
+
function unwrapType(type) {
|
|
2409
|
+
if (isNonNullType(type) || isListType(type)) {
|
|
2410
|
+
return unwrapType(type.ofType);
|
|
2411
|
+
}
|
|
2412
|
+
if (isObjectType(type) || isScalarType(type) || isUnionType(type) || isAbstractType(type)) {
|
|
2413
|
+
return { name: type.name, composite: type };
|
|
2414
|
+
}
|
|
2415
|
+
return { name: "Unknown", composite: type };
|
|
2421
2416
|
}
|
|
2422
|
-
function
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2417
|
+
function describeType(type) {
|
|
2418
|
+
if (isNonNullType(type)) {
|
|
2419
|
+
return `${describeType(type.ofType)}!`;
|
|
2420
|
+
}
|
|
2421
|
+
if (isListType(type)) {
|
|
2422
|
+
return `[${describeType(type.ofType)}]`;
|
|
2423
|
+
}
|
|
2424
|
+
if (isObjectType(type) || isScalarType(type) || isUnionType(type)) {
|
|
2425
|
+
return type.name;
|
|
2426
|
+
}
|
|
2427
|
+
if (isAbstractType(type)) {
|
|
2428
|
+
return type.name;
|
|
2429
|
+
}
|
|
2430
|
+
return "Unknown";
|
|
2428
2431
|
}
|
|
2429
|
-
function
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
affected.add(
|
|
2433
|
-
buildCanonicalPathForCollection(
|
|
2434
|
-
knowledgeRoot,
|
|
2435
|
-
operation.domain,
|
|
2436
|
-
operation.type
|
|
2437
|
-
)
|
|
2438
|
-
);
|
|
2432
|
+
function formatDefaultValue(value) {
|
|
2433
|
+
if (value === void 0 || value === null) {
|
|
2434
|
+
return null;
|
|
2439
2435
|
}
|
|
2440
|
-
return
|
|
2436
|
+
return JSON.stringify(value) ?? String(value);
|
|
2441
2437
|
}
|
|
2442
|
-
function
|
|
2443
|
-
const
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2438
|
+
function summarizeField(field) {
|
|
2439
|
+
const traversedType = unwrapType(field.type).composite;
|
|
2440
|
+
const traversesTo = isCompositeType(traversedType) && !isScalarType(traversedType) ? traversedType.name : null;
|
|
2441
|
+
return {
|
|
2442
|
+
name: field.name,
|
|
2443
|
+
type: describeType(field.type),
|
|
2444
|
+
description: field.description ?? null,
|
|
2445
|
+
arguments: field.args?.map((argument) => ({
|
|
2446
|
+
name: argument.name,
|
|
2447
|
+
type: describeType(argument.type),
|
|
2448
|
+
description: argument.description ?? null,
|
|
2449
|
+
defaultValue: formatDefaultValue(argument.defaultValue)
|
|
2450
|
+
})) ?? [],
|
|
2451
|
+
traversesTo
|
|
2452
|
+
};
|
|
2448
2453
|
}
|
|
2449
|
-
|
|
2450
|
-
const
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
const simulation = simulateKnowledgePatch(
|
|
2458
|
-
effectiveBase.store,
|
|
2459
|
-
operations,
|
|
2460
|
-
patchId
|
|
2461
|
-
);
|
|
2462
|
-
const affectedFiles = buildAffectedFileList(knowledgeRoot, operations);
|
|
2463
|
-
const diagnostics = [
|
|
2464
|
-
...effectiveBase.diagnostics,
|
|
2465
|
-
...simulation.diagnostics
|
|
2466
|
-
];
|
|
2467
|
-
if (diagnostics.length > 0) {
|
|
2468
|
-
return knowledgePatchValidationResultSchema.parse({
|
|
2469
|
-
valid: false,
|
|
2470
|
-
diagnostics,
|
|
2471
|
-
operationCount: operations.length,
|
|
2472
|
-
appliedOperationIds: simulation.appliedOperationIds,
|
|
2473
|
-
affectedFiles
|
|
2474
|
-
});
|
|
2475
|
-
}
|
|
2476
|
-
const sourceFingerprint = await buildSourceFingerprintInput(
|
|
2477
|
-
effectiveBase.store.sourceFiles
|
|
2478
|
-
);
|
|
2479
|
-
const fingerprint = sha256(
|
|
2480
|
-
JSON.stringify({
|
|
2481
|
-
schemaVersion: KNOWLEDGE_PATCH_SCHEMA_VERSION,
|
|
2482
|
-
patch: {
|
|
2483
|
-
id: patch.id,
|
|
2484
|
-
status: patch.status,
|
|
2485
|
-
updatedAt: patch.updatedAt
|
|
2486
|
-
},
|
|
2487
|
-
operations,
|
|
2488
|
-
sourceFingerprint
|
|
2489
|
-
})
|
|
2490
|
-
);
|
|
2491
|
-
return knowledgePatchValidationResultSchema.parse({
|
|
2492
|
-
valid: true,
|
|
2493
|
-
fingerprint,
|
|
2494
|
-
diagnostics,
|
|
2495
|
-
operationCount: operations.length,
|
|
2496
|
-
appliedOperationIds: simulation.appliedOperationIds,
|
|
2497
|
-
affectedFiles
|
|
2498
|
-
});
|
|
2454
|
+
function summarizeObjectType(type) {
|
|
2455
|
+
const fields = Object.values(type.getFields()).map(summarizeField);
|
|
2456
|
+
return {
|
|
2457
|
+
name: type.name,
|
|
2458
|
+
description: type.description ?? null,
|
|
2459
|
+
fields,
|
|
2460
|
+
traversalFields: fields.filter((field) => field.traversesTo !== null).map((field) => field.name)
|
|
2461
|
+
};
|
|
2499
2462
|
}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
const state = await readKnowledgePatch(envValue, patchId, cwd);
|
|
2503
|
-
return computeValidationResult(
|
|
2504
|
-
knowledgeRoot,
|
|
2505
|
-
patchId,
|
|
2506
|
-
state.patch,
|
|
2507
|
-
state.operations
|
|
2508
|
-
);
|
|
2463
|
+
function getObjectTypes(schema) {
|
|
2464
|
+
return Object.values(schema.getTypeMap()).filter((type) => isObjectType(type)).filter((type) => !type.name.startsWith("__")).filter((type) => type.name !== schema.getQueryType()?.name);
|
|
2509
2465
|
}
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
for (const operation of operations) {
|
|
2515
|
-
const filePath = buildCanonicalPathForCollection(
|
|
2516
|
-
knowledgeRoot,
|
|
2517
|
-
operation.domain,
|
|
2518
|
-
operation.type
|
|
2519
|
-
);
|
|
2520
|
-
const records = buildCollectionRecordsForDomain(
|
|
2521
|
-
simulationState,
|
|
2522
|
-
operation.type,
|
|
2523
|
-
operation.domain
|
|
2524
|
-
);
|
|
2525
|
-
if (operation.type === "domains") {
|
|
2526
|
-
if (records.length === 0) {
|
|
2527
|
-
if (existsSync3(filePath)) {
|
|
2528
|
-
await unlink(filePath);
|
|
2529
|
-
}
|
|
2530
|
-
continue;
|
|
2531
|
-
}
|
|
2532
|
-
plannedWrites.set(filePath, `${JSON.stringify(records[0], null, 2)}
|
|
2533
|
-
`);
|
|
2534
|
-
continue;
|
|
2535
|
-
}
|
|
2536
|
-
plannedWrites.set(filePath, `${JSON.stringify(records, null, 2)}
|
|
2537
|
-
`);
|
|
2538
|
-
}
|
|
2539
|
-
for (const filePath of plannedWrites.keys()) {
|
|
2540
|
-
await mkdir2(dirname(filePath), { recursive: true });
|
|
2541
|
-
}
|
|
2542
|
-
for (const [filePath, content] of plannedWrites.entries()) {
|
|
2543
|
-
await writeFile2(filePath, content, "utf8");
|
|
2466
|
+
function buildKnowledgeSchemaDiscoveryDocument(schema) {
|
|
2467
|
+
const queryType2 = schema.getQueryType();
|
|
2468
|
+
if (!queryType2) {
|
|
2469
|
+
throw new Error("Knowledge GraphQL schema has no root query type.");
|
|
2544
2470
|
}
|
|
2471
|
+
return {
|
|
2472
|
+
resource: {
|
|
2473
|
+
uri: KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
2474
|
+
title: "Knowledge GraphQL Schema",
|
|
2475
|
+
description: "Canonical discovery view of the runtime knowledge GraphQL schema."
|
|
2476
|
+
},
|
|
2477
|
+
source: {
|
|
2478
|
+
kind: "runtime-schema",
|
|
2479
|
+
queryType: queryType2.name
|
|
2480
|
+
},
|
|
2481
|
+
rootQuery: summarizeObjectType(queryType2),
|
|
2482
|
+
objectTypes: getObjectTypes(schema).map(summarizeObjectType)
|
|
2483
|
+
};
|
|
2545
2484
|
}
|
|
2546
|
-
|
|
2547
|
-
const
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
envValue,
|
|
2551
|
-
parsedInput.patchId,
|
|
2552
|
-
cwd
|
|
2553
|
-
);
|
|
2554
|
-
const patchState = await loadPatchStateByDir(patchDir);
|
|
2555
|
-
const validation = await computeValidationResult(
|
|
2556
|
-
knowledgeRoot,
|
|
2557
|
-
patchState.patch.id,
|
|
2558
|
-
patchState.patch,
|
|
2559
|
-
patchState.operations
|
|
2560
|
-
);
|
|
2561
|
-
const diagnostics = [...validation.diagnostics];
|
|
2562
|
-
const pendingPatches = (await listKnowledgePatches(envValue, cwd)).filter(
|
|
2563
|
-
(patch) => patch.status === "draft"
|
|
2564
|
-
);
|
|
2565
|
-
const firstPendingPatchId = pendingPatches[0]?.id;
|
|
2566
|
-
if (firstPendingPatchId !== void 0 && firstPendingPatchId !== patchState.patch.id) {
|
|
2567
|
-
diagnostics.push(
|
|
2568
|
-
buildDiagnostic({
|
|
2569
|
-
severity: "error",
|
|
2570
|
-
code: "apply_out_of_order",
|
|
2571
|
-
message: `Patch "${patchState.patch.id}" cannot be applied while earlier pending patch "${firstPendingPatchId}" still exists.`,
|
|
2572
|
-
patchId: patchState.patch.id
|
|
2573
|
-
})
|
|
2574
|
-
);
|
|
2485
|
+
function getLookupMetadata(schema, target) {
|
|
2486
|
+
const queryType2 = schema.getQueryType();
|
|
2487
|
+
if (!queryType2) {
|
|
2488
|
+
throw new Error("Knowledge GraphQL schema has no root query type.");
|
|
2575
2489
|
}
|
|
2576
|
-
if (
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2490
|
+
if (target === queryType2.name) {
|
|
2491
|
+
return {
|
|
2492
|
+
resource: {
|
|
2493
|
+
uri: `ez-know://lookup/${target}`,
|
|
2494
|
+
title: `Knowledge schema lookup: ${target}`,
|
|
2495
|
+
description: "Focused lookup of the root query fields and their arguments."
|
|
2496
|
+
},
|
|
2497
|
+
source: {
|
|
2498
|
+
kind: "runtime-schema",
|
|
2499
|
+
queryType: queryType2.name
|
|
2500
|
+
},
|
|
2501
|
+
lookup: {
|
|
2502
|
+
target: queryType2.name,
|
|
2503
|
+
kind: "root-query"
|
|
2504
|
+
},
|
|
2505
|
+
rootQuery: summarizeObjectType(queryType2)
|
|
2506
|
+
};
|
|
2585
2507
|
}
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
diagnostics.push(
|
|
2589
|
-
buildDiagnostic({
|
|
2590
|
-
severity: "error",
|
|
2591
|
-
code: "stale_validation_fingerprint",
|
|
2592
|
-
message: "Patch validation fingerprint is stale. Revalidate before apply.",
|
|
2593
|
-
patchId: patchState.patch.id
|
|
2594
|
-
})
|
|
2595
|
-
);
|
|
2596
|
-
}
|
|
2508
|
+
const rootField = queryType2.getFields()[target];
|
|
2509
|
+
if (rootField) {
|
|
2597
2510
|
return {
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2511
|
+
resource: {
|
|
2512
|
+
uri: `ez-know://lookup/${target}`,
|
|
2513
|
+
title: `Knowledge schema lookup: ${target}`,
|
|
2514
|
+
description: "Focused lookup of a single root query field and its arguments."
|
|
2515
|
+
},
|
|
2516
|
+
source: {
|
|
2517
|
+
kind: "runtime-schema",
|
|
2518
|
+
queryType: queryType2.name
|
|
2519
|
+
},
|
|
2520
|
+
lookup: {
|
|
2521
|
+
target,
|
|
2522
|
+
kind: "root-field"
|
|
2523
|
+
},
|
|
2524
|
+
field: summarizeField(rootField),
|
|
2525
|
+
parentType: queryType2.name
|
|
2603
2526
|
};
|
|
2604
2527
|
}
|
|
2605
|
-
const
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
patchState.patch.id
|
|
2610
|
-
);
|
|
2611
|
-
if (simulation.diagnostics.length > 0) {
|
|
2528
|
+
const objectType = schema.getType(target);
|
|
2529
|
+
if (objectType && isObjectType(objectType)) {
|
|
2530
|
+
const typeSummary = summarizeObjectType(objectType);
|
|
2531
|
+
const rootFields = Object.values(queryType2.getFields()).filter((field) => unwrapType(field.type).name === target).map((field) => field.name);
|
|
2612
2532
|
return {
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
valid: false,
|
|
2618
|
-
diagnostics: simulation.diagnostics
|
|
2533
|
+
resource: {
|
|
2534
|
+
uri: `ez-know://lookup/${target}`,
|
|
2535
|
+
title: `Knowledge schema lookup: ${target}`,
|
|
2536
|
+
description: "Focused lookup of a single GraphQL type and its nested traversal fields."
|
|
2619
2537
|
},
|
|
2620
|
-
|
|
2621
|
-
|
|
2538
|
+
source: {
|
|
2539
|
+
kind: "runtime-schema",
|
|
2540
|
+
queryType: queryType2.name
|
|
2541
|
+
},
|
|
2542
|
+
lookup: {
|
|
2543
|
+
target,
|
|
2544
|
+
kind: "object-type"
|
|
2545
|
+
},
|
|
2546
|
+
type: typeSummary,
|
|
2547
|
+
rootFields
|
|
2622
2548
|
};
|
|
2623
2549
|
}
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
patchState.operations,
|
|
2627
|
-
simulation.state
|
|
2550
|
+
throw new Error(
|
|
2551
|
+
`Unknown schema lookup target "${target}". Use a root field name, a type name, or "Query".`
|
|
2628
2552
|
);
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
path: diagnostic.path ? [diagnostic.path] : void 0,
|
|
2638
|
-
targetId: diagnostic.id
|
|
2639
|
-
})
|
|
2640
|
-
) : [
|
|
2641
|
-
buildDiagnostic({
|
|
2642
|
-
severity: "critical",
|
|
2643
|
-
code: "reload_failed",
|
|
2644
|
-
message: "Canonical knowledge store reload failed after apply.",
|
|
2645
|
-
patchId: patchState.patch.id
|
|
2646
|
-
})
|
|
2647
|
-
];
|
|
2648
|
-
return {
|
|
2649
|
-
patchId: patchState.patch.id,
|
|
2650
|
-
applied: false,
|
|
2651
|
-
validation,
|
|
2652
|
-
diagnostics: reloadDiagnostics,
|
|
2653
|
-
deletedPatch: false
|
|
2654
|
-
};
|
|
2553
|
+
}
|
|
2554
|
+
function buildKnowledgeSchemaLookupDocument(schema, target) {
|
|
2555
|
+
return getLookupMetadata(schema, target);
|
|
2556
|
+
}
|
|
2557
|
+
function listKnowledgeSchemaTargets(schema) {
|
|
2558
|
+
const queryType2 = schema.getQueryType();
|
|
2559
|
+
if (!queryType2) {
|
|
2560
|
+
throw new Error("Knowledge GraphQL schema has no root query type.");
|
|
2655
2561
|
}
|
|
2656
|
-
|
|
2562
|
+
const objectTypeNames = getObjectTypes(schema).map((type) => type.name);
|
|
2563
|
+
const rootFieldNames = Object.keys(queryType2.getFields());
|
|
2564
|
+
const targetNames = ["Query", ...rootFieldNames, ...objectTypeNames];
|
|
2565
|
+
return Array.from(new Set(targetNames)).sort(
|
|
2566
|
+
(left, right) => left.localeCompare(right)
|
|
2567
|
+
);
|
|
2568
|
+
}
|
|
2569
|
+
|
|
2570
|
+
// packages/core/src/knowledge/resource-catalog.ts
|
|
2571
|
+
var KnowledgeResourceNotFoundError = class extends Error {
|
|
2572
|
+
constructor(uri, message = `Unknown ez-know resource URI "${uri}".`) {
|
|
2573
|
+
super(message);
|
|
2574
|
+
this.uri = uri;
|
|
2575
|
+
this.name = "KnowledgeResourceNotFoundError";
|
|
2576
|
+
}
|
|
2577
|
+
uri;
|
|
2578
|
+
code = "RESOURCE_NOT_FOUND";
|
|
2579
|
+
};
|
|
2580
|
+
var KnowledgeResourceUriError = class extends Error {
|
|
2581
|
+
constructor(uri, message) {
|
|
2582
|
+
super(message);
|
|
2583
|
+
this.uri = uri;
|
|
2584
|
+
this.name = "KnowledgeResourceUriError";
|
|
2585
|
+
}
|
|
2586
|
+
uri;
|
|
2587
|
+
code = "INVALID_RESOURCE_URI";
|
|
2588
|
+
};
|
|
2589
|
+
function createJsonResourceContent(uri, text) {
|
|
2657
2590
|
return {
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
diagnostics: [],
|
|
2662
|
-
deletedPatch: true
|
|
2591
|
+
uri,
|
|
2592
|
+
mimeType: "application/json",
|
|
2593
|
+
text
|
|
2663
2594
|
};
|
|
2664
2595
|
}
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2596
|
+
function createMarkdownResourceContent(uri, text) {
|
|
2597
|
+
return {
|
|
2598
|
+
uri,
|
|
2599
|
+
mimeType: "text/markdown",
|
|
2600
|
+
text
|
|
2601
|
+
};
|
|
2602
|
+
}
|
|
2603
|
+
function createKnowledgeSchemaResourceDefinition() {
|
|
2604
|
+
return {
|
|
2605
|
+
uri: KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
2606
|
+
name: "knowledge-schema",
|
|
2607
|
+
title: "Knowledge GraphQL Schema",
|
|
2608
|
+
description: "Canonical runtime GraphQL schema discovery payload for the knowledge layer.",
|
|
2609
|
+
mimeType: "application/json",
|
|
2610
|
+
read: () => ({
|
|
2611
|
+
resource: {
|
|
2612
|
+
uri: KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
2613
|
+
title: "Knowledge GraphQL Schema",
|
|
2614
|
+
description: "Canonical runtime GraphQL schema discovery payload for the knowledge layer.",
|
|
2615
|
+
mimeType: "application/json"
|
|
2616
|
+
},
|
|
2617
|
+
content: createJsonResourceContent(
|
|
2618
|
+
KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
2619
|
+
createKnowledgeSchemaDiscoveryText()
|
|
2620
|
+
)
|
|
2683
2621
|
})
|
|
2684
|
-
|
|
2685
|
-
uncoveredFiles: z6.array(z6.string()),
|
|
2686
|
-
outOfRootEvidenceFiles: z6.array(z6.string()),
|
|
2687
|
-
message: z6.string()
|
|
2688
|
-
});
|
|
2689
|
-
function toPosixPath(value) {
|
|
2690
|
-
return value.replaceAll(sep2, "/");
|
|
2622
|
+
};
|
|
2691
2623
|
}
|
|
2692
|
-
function
|
|
2693
|
-
return
|
|
2624
|
+
function createKnowledgeExtractionTypesResourceDefinition() {
|
|
2625
|
+
return {
|
|
2626
|
+
uri: KNOWLEDGE_EXTRACTION_TYPES_RESOURCE_URI,
|
|
2627
|
+
name: "knowledge-extraction-types",
|
|
2628
|
+
title: "Knowledge Extraction Types",
|
|
2629
|
+
description: "Canonical registry of knowledge types supported by the extraction workflow.",
|
|
2630
|
+
mimeType: "application/json",
|
|
2631
|
+
read: () => ({
|
|
2632
|
+
resource: {
|
|
2633
|
+
uri: KNOWLEDGE_EXTRACTION_TYPES_RESOURCE_URI,
|
|
2634
|
+
title: "Knowledge Extraction Types",
|
|
2635
|
+
description: "Canonical registry of knowledge types supported by the extraction workflow.",
|
|
2636
|
+
mimeType: "application/json"
|
|
2637
|
+
},
|
|
2638
|
+
content: createJsonResourceContent(
|
|
2639
|
+
KNOWLEDGE_EXTRACTION_TYPES_RESOURCE_URI,
|
|
2640
|
+
JSON.stringify(buildKnowledgeExtractionTypeIndexDocument(), null, 2)
|
|
2641
|
+
)
|
|
2642
|
+
})
|
|
2643
|
+
};
|
|
2694
2644
|
}
|
|
2695
|
-
function
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2645
|
+
function createKnowledgeSchemaLookupTemplateDefinition() {
|
|
2646
|
+
return {
|
|
2647
|
+
uriTemplate: KNOWLEDGE_SCHEMA_LOOKUP_URI,
|
|
2648
|
+
name: "knowledge-schema-lookup",
|
|
2649
|
+
title: "Knowledge Schema Lookup",
|
|
2650
|
+
description: "Focused runtime GraphQL schema lookup for a type name, root field, or Query.",
|
|
2651
|
+
mimeType: "application/json",
|
|
2652
|
+
list: () => listKnowledgeSchemaTargets(knowledgeGraphSchema).map((target) => ({
|
|
2653
|
+
uri: `ez-know://lookup/${target}`,
|
|
2654
|
+
name: target,
|
|
2655
|
+
title: `Knowledge schema lookup: ${target}`,
|
|
2656
|
+
description: target === "Query" ? "Focused lookup of the root query fields." : `Focused lookup of ${target}.`,
|
|
2657
|
+
mimeType: "application/json"
|
|
2658
|
+
})),
|
|
2659
|
+
read: (uri) => {
|
|
2660
|
+
const target = readUriSegment(uri, "ez-know://lookup/");
|
|
2661
|
+
try {
|
|
2662
|
+
return {
|
|
2663
|
+
resource: {
|
|
2664
|
+
uri,
|
|
2665
|
+
title: `Knowledge schema lookup: ${target}`,
|
|
2666
|
+
description: target === "Query" ? "Focused lookup of the root query fields and their arguments." : `Focused lookup of ${target}.`,
|
|
2667
|
+
mimeType: "application/json"
|
|
2668
|
+
},
|
|
2669
|
+
content: createJsonResourceContent(
|
|
2670
|
+
uri,
|
|
2671
|
+
createKnowledgeSchemaLookupText(target)
|
|
2672
|
+
)
|
|
2673
|
+
};
|
|
2674
|
+
} catch (error) {
|
|
2675
|
+
if (error instanceof Error) {
|
|
2676
|
+
throw new KnowledgeResourceUriError(uri, error.message);
|
|
2677
|
+
}
|
|
2678
|
+
throw error;
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
};
|
|
2682
|
+
}
|
|
2683
|
+
function createKnowledgeExtractionSchemaTemplateDefinition() {
|
|
2684
|
+
return {
|
|
2685
|
+
uriTemplate: KNOWLEDGE_EXTRACTION_SCHEMA_RESOURCE_URI,
|
|
2686
|
+
name: "knowledge-extraction-schema",
|
|
2687
|
+
title: "Knowledge Extraction Schema",
|
|
2688
|
+
description: "Runtime JSON-schema discovery for a supported knowledge type.",
|
|
2689
|
+
mimeType: "application/json",
|
|
2690
|
+
list: () => listKnowledgeExtractionResourceTypes().map((definition) => ({
|
|
2691
|
+
uri: `ez-know://extraction/schema/${definition.collection}`,
|
|
2692
|
+
name: definition.collection,
|
|
2693
|
+
title: `${definition.title} Extraction Schema`,
|
|
2694
|
+
description: `Runtime schema discovery for ${definition.title.toLowerCase()}.`,
|
|
2695
|
+
mimeType: "application/json"
|
|
2696
|
+
})),
|
|
2697
|
+
read: (uri) => {
|
|
2698
|
+
const type = readUriSegment(uri, "ez-know://extraction/schema/");
|
|
2699
|
+
try {
|
|
2700
|
+
const document = buildKnowledgeExtractionSchemaDocument(type);
|
|
2701
|
+
return {
|
|
2702
|
+
resource: {
|
|
2703
|
+
uri: `ez-know://extraction/schema/${document.type.collection}`,
|
|
2704
|
+
title: `${document.type.title} Extraction Schema`,
|
|
2705
|
+
description: "Runtime JSON Schema view of the canonical knowledge object model.",
|
|
2706
|
+
mimeType: "application/json"
|
|
2707
|
+
},
|
|
2708
|
+
content: createJsonResourceContent(
|
|
2709
|
+
`ez-know://extraction/schema/${document.type.collection}`,
|
|
2710
|
+
JSON.stringify(document, null, 2)
|
|
2711
|
+
)
|
|
2712
|
+
};
|
|
2713
|
+
} catch (error) {
|
|
2714
|
+
if (error instanceof Error) {
|
|
2715
|
+
throw new KnowledgeResourceUriError(uri, error.message);
|
|
2716
|
+
}
|
|
2717
|
+
throw error;
|
|
2718
|
+
}
|
|
2719
|
+
}
|
|
2720
|
+
};
|
|
2721
|
+
}
|
|
2722
|
+
function createKnowledgeExtractionGuideTemplateDefinition() {
|
|
2723
|
+
return {
|
|
2724
|
+
uriTemplate: KNOWLEDGE_EXTRACTION_GUIDE_RESOURCE_URI,
|
|
2725
|
+
name: "knowledge-extraction-guide",
|
|
2726
|
+
title: "Knowledge Extraction Guide",
|
|
2727
|
+
description: "Checked-in Markdown guidance for a supported knowledge type.",
|
|
2728
|
+
mimeType: "text/markdown",
|
|
2729
|
+
list: () => listKnowledgeExtractionResourceTypes().map((definition) => ({
|
|
2730
|
+
uri: `ez-know://extraction/guide/${definition.collection}`,
|
|
2731
|
+
name: definition.collection,
|
|
2732
|
+
title: `${definition.title} Extraction Guide`,
|
|
2733
|
+
description: `Checked-in extraction guidance for ${definition.title.toLowerCase()}.`,
|
|
2734
|
+
mimeType: "text/markdown"
|
|
2735
|
+
})),
|
|
2736
|
+
read: async (uri) => {
|
|
2737
|
+
const type = readUriSegment(uri, "ez-know://extraction/guide/");
|
|
2738
|
+
try {
|
|
2739
|
+
const document = await buildKnowledgeExtractionGuideDocument(type);
|
|
2740
|
+
return {
|
|
2741
|
+
resource: {
|
|
2742
|
+
uri: `ez-know://extraction/guide/${document.type.collection}`,
|
|
2743
|
+
title: `${document.type.title} Extraction Guide`,
|
|
2744
|
+
description: "Checked-in Markdown guidance for extracting this knowledge type.",
|
|
2745
|
+
mimeType: "text/markdown"
|
|
2746
|
+
},
|
|
2747
|
+
content: createMarkdownResourceContent(
|
|
2748
|
+
`ez-know://extraction/guide/${document.type.collection}`,
|
|
2749
|
+
document.markdown
|
|
2750
|
+
)
|
|
2751
|
+
};
|
|
2752
|
+
} catch (error) {
|
|
2753
|
+
if (error instanceof Error) {
|
|
2754
|
+
throw new KnowledgeResourceUriError(uri, error.message);
|
|
2755
|
+
}
|
|
2756
|
+
throw error;
|
|
2757
|
+
}
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
}
|
|
2761
|
+
function createKnowledgeSchemaDiscoveryText() {
|
|
2762
|
+
return JSON.stringify(buildKnowledgeSchemaDiscoveryDocument(knowledgeGraphSchema), null, 2);
|
|
2763
|
+
}
|
|
2764
|
+
function createKnowledgeSchemaLookupText(target) {
|
|
2765
|
+
return JSON.stringify(
|
|
2766
|
+
buildKnowledgeSchemaLookupDocument(knowledgeGraphSchema, target),
|
|
2767
|
+
null,
|
|
2768
|
+
2
|
|
2699
2769
|
);
|
|
2700
2770
|
}
|
|
2701
|
-
function
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
candidate = resolve5(filePath);
|
|
2705
|
-
} else {
|
|
2706
|
-
const repoRelativeCandidate = resolve5(outputRoot, filePath);
|
|
2707
|
-
candidate = isPathWithinRoot(rootFolder, repoRelativeCandidate) ? repoRelativeCandidate : resolve5(rootFolder, filePath);
|
|
2771
|
+
function readUriSegment(uri, prefix) {
|
|
2772
|
+
if (!uri.startsWith(prefix)) {
|
|
2773
|
+
throw new KnowledgeResourceNotFoundError(uri);
|
|
2708
2774
|
}
|
|
2709
|
-
const
|
|
2710
|
-
if (
|
|
2711
|
-
|
|
2775
|
+
const segment = uri.slice(prefix.length);
|
|
2776
|
+
if (segment.length === 0 || segment.includes("/")) {
|
|
2777
|
+
throw new KnowledgeResourceUriError(
|
|
2778
|
+
uri,
|
|
2779
|
+
`Unsupported ez-know resource URI "${uri}".`
|
|
2780
|
+
);
|
|
2712
2781
|
}
|
|
2713
|
-
return
|
|
2782
|
+
return segment;
|
|
2714
2783
|
}
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2784
|
+
var KNOWLEDGE_RESOURCE_DEFINITIONS = [
|
|
2785
|
+
createKnowledgeSchemaResourceDefinition(),
|
|
2786
|
+
createKnowledgeExtractionTypesResourceDefinition()
|
|
2787
|
+
];
|
|
2788
|
+
var KNOWLEDGE_RESOURCE_TEMPLATE_DEFINITIONS = [
|
|
2789
|
+
createKnowledgeSchemaLookupTemplateDefinition(),
|
|
2790
|
+
createKnowledgeExtractionSchemaTemplateDefinition(),
|
|
2791
|
+
createKnowledgeExtractionGuideTemplateDefinition()
|
|
2792
|
+
];
|
|
2793
|
+
function listKnowledgeResourceEntries() {
|
|
2794
|
+
return KNOWLEDGE_RESOURCE_DEFINITIONS.map(({ read: _read, ...metadata }) => ({
|
|
2795
|
+
...metadata
|
|
2796
|
+
}));
|
|
2797
|
+
}
|
|
2798
|
+
function listKnowledgeResourceTemplateEntries() {
|
|
2799
|
+
return KNOWLEDGE_RESOURCE_TEMPLATE_DEFINITIONS.map(({ list: _list, read: _read, ...metadata }) => ({
|
|
2800
|
+
...metadata
|
|
2801
|
+
}));
|
|
2802
|
+
}
|
|
2803
|
+
function listKnowledgeResourceTemplateResources(uriTemplate) {
|
|
2804
|
+
const template = KNOWLEDGE_RESOURCE_TEMPLATE_DEFINITIONS.find(
|
|
2805
|
+
(entry) => entry.uriTemplate === uriTemplate
|
|
2806
|
+
);
|
|
2807
|
+
if (!template) {
|
|
2808
|
+
throw new KnowledgeResourceNotFoundError(uriTemplate);
|
|
2718
2809
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2810
|
+
return template.list();
|
|
2811
|
+
}
|
|
2812
|
+
function getKnowledgeResourceEntry(uri) {
|
|
2813
|
+
return KNOWLEDGE_RESOURCE_DEFINITIONS.find((entry) => entry.uri === uri);
|
|
2814
|
+
}
|
|
2815
|
+
async function readKnowledgeResourceDocument(uri) {
|
|
2816
|
+
const resource = getKnowledgeResourceEntry(uri);
|
|
2817
|
+
if (resource) {
|
|
2818
|
+
return await resource.read();
|
|
2819
|
+
}
|
|
2820
|
+
if (uri.startsWith("ez-know://lookup/")) {
|
|
2821
|
+
return await createKnowledgeSchemaLookupTemplateDefinition().read(uri);
|
|
2822
|
+
}
|
|
2823
|
+
if (uri.startsWith("ez-know://extraction/schema/")) {
|
|
2824
|
+
return await createKnowledgeExtractionSchemaTemplateDefinition().read(uri);
|
|
2825
|
+
}
|
|
2826
|
+
if (uri.startsWith("ez-know://extraction/guide/")) {
|
|
2827
|
+
return await createKnowledgeExtractionGuideTemplateDefinition().read(uri);
|
|
2828
|
+
}
|
|
2829
|
+
throw new KnowledgeResourceNotFoundError(uri);
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2832
|
+
// packages/core/src/knowledge/patch/apply.ts
|
|
2833
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
2834
|
+
import { mkdir as mkdir2, rm, unlink, writeFile as writeFile2 } from "node:fs/promises";
|
|
2835
|
+
import { dirname } from "node:path";
|
|
2836
|
+
|
|
2837
|
+
// packages/core/src/knowledge/patch/validation.ts
|
|
2838
|
+
import { readFile as readFile4, stat } from "node:fs/promises";
|
|
2839
|
+
import { join as join4 } from "node:path";
|
|
2840
|
+
async function buildSourceFingerprintInput(sourceFiles) {
|
|
2841
|
+
const entries = await Promise.all(
|
|
2842
|
+
sourceFiles.map(async (filePath) => {
|
|
2843
|
+
const [fileStat, content] = await Promise.all([
|
|
2844
|
+
stat(filePath),
|
|
2845
|
+
readFile4(filePath, "utf8")
|
|
2846
|
+
]);
|
|
2847
|
+
return {
|
|
2848
|
+
path: filePath,
|
|
2849
|
+
size: fileStat.size,
|
|
2850
|
+
mtimeMs: fileStat.mtimeMs,
|
|
2851
|
+
contentHash: sha256(content)
|
|
2852
|
+
};
|
|
2853
|
+
})
|
|
2854
|
+
);
|
|
2855
|
+
entries.sort((left, right) => left.path.localeCompare(right.path));
|
|
2856
|
+
return entries;
|
|
2857
|
+
}
|
|
2858
|
+
function buildCanonicalPathForCollection(rootDir, domain, type) {
|
|
2859
|
+
return join4(
|
|
2860
|
+
rootDir,
|
|
2861
|
+
domain,
|
|
2862
|
+
KNOWLEDGE_EXTRACTION_TYPE_REGISTRY[type].storageFile
|
|
2863
|
+
);
|
|
2864
|
+
}
|
|
2865
|
+
function buildAffectedFileList(knowledgeRoot, operations) {
|
|
2866
|
+
const affected = /* @__PURE__ */ new Set();
|
|
2867
|
+
for (const operation of operations) {
|
|
2868
|
+
affected.add(
|
|
2869
|
+
buildCanonicalPathForCollection(
|
|
2870
|
+
knowledgeRoot,
|
|
2871
|
+
operation.domain,
|
|
2872
|
+
operation.type
|
|
2873
|
+
)
|
|
2874
|
+
);
|
|
2741
2875
|
}
|
|
2742
|
-
return
|
|
2876
|
+
return [...affected].sort((left, right) => left.localeCompare(right));
|
|
2743
2877
|
}
|
|
2744
|
-
|
|
2745
|
-
const
|
|
2746
|
-
|
|
2747
|
-
const auditedRoot = normalizeAuditedRoot(
|
|
2748
|
-
parsedInput.rootFolder ?? patchState.patch.rootFolder
|
|
2878
|
+
function buildCollectionRecordsForDomain(state, type, domain) {
|
|
2879
|
+
const records = [...state.byCollection[type].values()].filter(
|
|
2880
|
+
(record2) => inferDomainForRecord(record2) === domain
|
|
2749
2881
|
);
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2882
|
+
records.sort((left, right) => left.id.localeCompare(right.id));
|
|
2883
|
+
return records;
|
|
2884
|
+
}
|
|
2885
|
+
async function computeValidationResult(knowledgeRoot, patchId, patch, operations) {
|
|
2886
|
+
const effectiveBase = await loadEffectiveKnowledgeStoreFromRoot(
|
|
2887
|
+
knowledgeRoot,
|
|
2753
2888
|
{
|
|
2754
|
-
selectedPatchId:
|
|
2889
|
+
selectedPatchId: patchId,
|
|
2890
|
+
includeSelectedPatch: false
|
|
2755
2891
|
}
|
|
2756
2892
|
);
|
|
2757
|
-
const
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
const provenance = effectiveState.provenance.get(evidence.id);
|
|
2762
|
-
if (!provenance?.patchIds.some((patchId) => effectivePatchIds.has(patchId))) {
|
|
2763
|
-
continue;
|
|
2764
|
-
}
|
|
2765
|
-
const sourcePath = evidence.location?.path;
|
|
2766
|
-
if (!sourcePath) {
|
|
2767
|
-
continue;
|
|
2768
|
-
}
|
|
2769
|
-
const normalized = normalizePathWithinRoot(
|
|
2770
|
-
auditedRoot,
|
|
2771
|
-
sourcePath,
|
|
2772
|
-
repositoryRoot
|
|
2773
|
-
);
|
|
2774
|
-
if (normalized) {
|
|
2775
|
-
coveredFiles.add(normalized);
|
|
2776
|
-
continue;
|
|
2777
|
-
}
|
|
2778
|
-
outOfRootEvidenceFiles.add(sourcePath);
|
|
2779
|
-
}
|
|
2780
|
-
const omittedFiles = patchState.patch.omittedFiles.map((entry) => ({
|
|
2781
|
-
path: entry.path,
|
|
2782
|
-
reason: entry.reason
|
|
2783
|
-
}));
|
|
2784
|
-
const omittedFileSet = new Set(omittedFiles.map((entry) => entry.path));
|
|
2785
|
-
const patchStorageRoot = resolve5(auditedRoot, KNOWLEDGE_PATCH_FOLDER_NAME);
|
|
2786
|
-
const scopeFiles = (await collectScopeFiles(
|
|
2787
|
-
auditedRoot,
|
|
2788
|
-
auditedRoot,
|
|
2789
|
-
patchStorageRoot,
|
|
2790
|
-
repositoryRoot
|
|
2791
|
-
)).sort((left, right) => left.localeCompare(right));
|
|
2792
|
-
const uncoveredFiles = scopeFiles.filter(
|
|
2793
|
-
(filePath) => !coveredFiles.has(filePath) && !omittedFileSet.has(filePath)
|
|
2893
|
+
const simulation = simulateKnowledgePatch(
|
|
2894
|
+
effectiveBase.store,
|
|
2895
|
+
operations,
|
|
2896
|
+
patchId
|
|
2794
2897
|
);
|
|
2795
|
-
const
|
|
2796
|
-
|
|
2898
|
+
const affectedFiles = buildAffectedFileList(knowledgeRoot, operations);
|
|
2899
|
+
const diagnostics = [
|
|
2900
|
+
...effectiveBase.diagnostics,
|
|
2901
|
+
...simulation.diagnostics
|
|
2902
|
+
];
|
|
2903
|
+
if (diagnostics.length > 0) {
|
|
2904
|
+
return knowledgePatchValidationResultSchema.parse({
|
|
2905
|
+
valid: false,
|
|
2906
|
+
diagnostics,
|
|
2907
|
+
operationCount: operations.length,
|
|
2908
|
+
appliedOperationIds: simulation.appliedOperationIds,
|
|
2909
|
+
affectedFiles
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
const sourceFingerprint = await buildSourceFingerprintInput(
|
|
2913
|
+
effectiveBase.store.sourceFiles
|
|
2797
2914
|
);
|
|
2798
|
-
const
|
|
2799
|
-
|
|
2915
|
+
const fingerprint = sha256(
|
|
2916
|
+
JSON.stringify({
|
|
2917
|
+
schemaVersion: KNOWLEDGE_PATCH_SCHEMA_VERSION,
|
|
2918
|
+
patch: {
|
|
2919
|
+
id: patch.id,
|
|
2920
|
+
status: patch.status,
|
|
2921
|
+
updatedAt: patch.updatedAt
|
|
2922
|
+
},
|
|
2923
|
+
operations,
|
|
2924
|
+
sourceFingerprint
|
|
2925
|
+
})
|
|
2800
2926
|
);
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
uncoveredFiles,
|
|
2809
|
-
outOfRootEvidenceFiles: sortedOutOfRootEvidenceFiles,
|
|
2810
|
-
message
|
|
2927
|
+
return knowledgePatchValidationResultSchema.parse({
|
|
2928
|
+
valid: true,
|
|
2929
|
+
fingerprint,
|
|
2930
|
+
diagnostics,
|
|
2931
|
+
operationCount: operations.length,
|
|
2932
|
+
appliedOperationIds: simulation.appliedOperationIds,
|
|
2933
|
+
affectedFiles
|
|
2811
2934
|
});
|
|
2812
2935
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
return readKnowledgePatch(envValue, input.patchId, cwd);
|
|
2823
|
-
case "add_operation":
|
|
2824
|
-
return addKnowledgePatchOperation(
|
|
2825
|
-
envValue,
|
|
2826
|
-
input.patchId,
|
|
2827
|
-
input.operation,
|
|
2828
|
-
cwd
|
|
2829
|
-
);
|
|
2830
|
-
case "update_operation":
|
|
2831
|
-
return updateKnowledgePatchOperation(
|
|
2832
|
-
envValue,
|
|
2833
|
-
input.patchId,
|
|
2834
|
-
input.update,
|
|
2835
|
-
cwd
|
|
2836
|
-
);
|
|
2837
|
-
case "update_metadata":
|
|
2838
|
-
return updateKnowledgePatchMetadata(
|
|
2839
|
-
envValue,
|
|
2840
|
-
input.patchId,
|
|
2841
|
-
input.metadata,
|
|
2842
|
-
cwd
|
|
2843
|
-
);
|
|
2844
|
-
case "delete_operation":
|
|
2845
|
-
return deleteKnowledgePatchOperation(
|
|
2846
|
-
envValue,
|
|
2847
|
-
input.patchId,
|
|
2848
|
-
input.operationId,
|
|
2849
|
-
cwd
|
|
2850
|
-
);
|
|
2851
|
-
case "validate":
|
|
2852
|
-
return validateKnowledgePatch(envValue, input.patchId, cwd);
|
|
2853
|
-
case "close":
|
|
2854
|
-
return closeKnowledgePatch(envValue, input.patchId, cwd);
|
|
2855
|
-
}
|
|
2856
|
-
}
|
|
2857
|
-
function buildKnowledgePatchToolText(result) {
|
|
2858
|
-
return JSON.stringify(result, null, 2);
|
|
2936
|
+
async function validateKnowledgePatch(envValue, patchId, cwd = process.cwd()) {
|
|
2937
|
+
const knowledgeRoot = resolveKnowledgeRoot2(envValue, cwd);
|
|
2938
|
+
const state = await readKnowledgePatch(envValue, patchId, cwd);
|
|
2939
|
+
return computeValidationResult(
|
|
2940
|
+
knowledgeRoot,
|
|
2941
|
+
patchId,
|
|
2942
|
+
state.patch,
|
|
2943
|
+
state.operations
|
|
2944
|
+
);
|
|
2859
2945
|
}
|
|
2860
2946
|
|
|
2861
|
-
// packages/core/src/knowledge/
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
}
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
}
|
|
2889
|
-
if (isObjectType(type) || isScalarType(type) || isUnionType(type)) {
|
|
2890
|
-
return type.name;
|
|
2891
|
-
}
|
|
2892
|
-
if (isAbstractType(type)) {
|
|
2893
|
-
return type.name;
|
|
2947
|
+
// packages/core/src/knowledge/patch/apply.ts
|
|
2948
|
+
async function writeCanonicalFilesFromSimulation(knowledgeRoot, operations, simulationState) {
|
|
2949
|
+
const plannedWrites = /* @__PURE__ */ new Map();
|
|
2950
|
+
for (const operation of operations) {
|
|
2951
|
+
const filePath = buildCanonicalPathForCollection(
|
|
2952
|
+
knowledgeRoot,
|
|
2953
|
+
operation.domain,
|
|
2954
|
+
operation.type
|
|
2955
|
+
);
|
|
2956
|
+
const records = buildCollectionRecordsForDomain(
|
|
2957
|
+
simulationState,
|
|
2958
|
+
operation.type,
|
|
2959
|
+
operation.domain
|
|
2960
|
+
);
|
|
2961
|
+
if (operation.type === "domains") {
|
|
2962
|
+
if (records.length === 0) {
|
|
2963
|
+
if (existsSync3(filePath)) {
|
|
2964
|
+
await unlink(filePath);
|
|
2965
|
+
}
|
|
2966
|
+
continue;
|
|
2967
|
+
}
|
|
2968
|
+
plannedWrites.set(filePath, `${JSON.stringify(records[0], null, 2)}
|
|
2969
|
+
`);
|
|
2970
|
+
continue;
|
|
2971
|
+
}
|
|
2972
|
+
plannedWrites.set(filePath, `${JSON.stringify(records, null, 2)}
|
|
2973
|
+
`);
|
|
2894
2974
|
}
|
|
2895
|
-
|
|
2896
|
-
}
|
|
2897
|
-
function formatDefaultValue(value) {
|
|
2898
|
-
if (value === void 0 || value === null) {
|
|
2899
|
-
return null;
|
|
2975
|
+
for (const filePath of plannedWrites.keys()) {
|
|
2976
|
+
await mkdir2(dirname(filePath), { recursive: true });
|
|
2900
2977
|
}
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
function summarizeField(field) {
|
|
2904
|
-
const traversedType = unwrapType(field.type).composite;
|
|
2905
|
-
const traversesTo = isCompositeType(traversedType) && !isScalarType(traversedType) ? traversedType.name : null;
|
|
2906
|
-
return {
|
|
2907
|
-
name: field.name,
|
|
2908
|
-
type: describeType(field.type),
|
|
2909
|
-
description: field.description ?? null,
|
|
2910
|
-
arguments: field.args?.map((argument) => ({
|
|
2911
|
-
name: argument.name,
|
|
2912
|
-
type: describeType(argument.type),
|
|
2913
|
-
description: argument.description ?? null,
|
|
2914
|
-
defaultValue: formatDefaultValue(argument.defaultValue)
|
|
2915
|
-
})) ?? [],
|
|
2916
|
-
traversesTo
|
|
2917
|
-
};
|
|
2918
|
-
}
|
|
2919
|
-
function summarizeObjectType(type) {
|
|
2920
|
-
const fields = Object.values(type.getFields()).map(summarizeField);
|
|
2921
|
-
return {
|
|
2922
|
-
name: type.name,
|
|
2923
|
-
description: type.description ?? null,
|
|
2924
|
-
fields,
|
|
2925
|
-
traversalFields: fields.filter((field) => field.traversesTo !== null).map((field) => field.name)
|
|
2926
|
-
};
|
|
2927
|
-
}
|
|
2928
|
-
function getObjectTypes(schema) {
|
|
2929
|
-
return Object.values(schema.getTypeMap()).filter((type) => isObjectType(type)).filter((type) => !type.name.startsWith("__")).filter((type) => type.name !== schema.getQueryType()?.name);
|
|
2930
|
-
}
|
|
2931
|
-
function buildKnowledgeSchemaDiscoveryDocument(schema) {
|
|
2932
|
-
const queryType2 = schema.getQueryType();
|
|
2933
|
-
if (!queryType2) {
|
|
2934
|
-
throw new Error("Knowledge GraphQL schema has no root query type.");
|
|
2978
|
+
for (const [filePath, content] of plannedWrites.entries()) {
|
|
2979
|
+
await writeFile2(filePath, content, "utf8");
|
|
2935
2980
|
}
|
|
2936
|
-
return {
|
|
2937
|
-
resource: {
|
|
2938
|
-
uri: KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
2939
|
-
title: "Knowledge GraphQL Schema",
|
|
2940
|
-
description: "Canonical discovery view of the runtime knowledge GraphQL schema."
|
|
2941
|
-
},
|
|
2942
|
-
source: {
|
|
2943
|
-
kind: "runtime-schema",
|
|
2944
|
-
queryType: queryType2.name
|
|
2945
|
-
},
|
|
2946
|
-
rootQuery: summarizeObjectType(queryType2),
|
|
2947
|
-
objectTypes: getObjectTypes(schema).map(summarizeObjectType)
|
|
2948
|
-
};
|
|
2949
2981
|
}
|
|
2950
|
-
function
|
|
2951
|
-
const
|
|
2952
|
-
|
|
2953
|
-
|
|
2982
|
+
async function applyKnowledgePatch(envValue, input, cwd = process.cwd()) {
|
|
2983
|
+
const parsedInput = knowledgePatchApplyToolInputSchema.parse(input);
|
|
2984
|
+
const knowledgeRoot = resolveKnowledgeRoot2(envValue, cwd);
|
|
2985
|
+
const patchDir = resolveKnowledgePatchDirectory(
|
|
2986
|
+
envValue,
|
|
2987
|
+
parsedInput.patchId,
|
|
2988
|
+
cwd
|
|
2989
|
+
);
|
|
2990
|
+
const patchState = await loadPatchStateByDir(patchDir);
|
|
2991
|
+
const validation = await computeValidationResult(
|
|
2992
|
+
knowledgeRoot,
|
|
2993
|
+
patchState.patch.id,
|
|
2994
|
+
patchState.patch,
|
|
2995
|
+
patchState.operations
|
|
2996
|
+
);
|
|
2997
|
+
const diagnostics = [...validation.diagnostics];
|
|
2998
|
+
const pendingPatches = (await listKnowledgePatches(envValue, cwd)).filter(
|
|
2999
|
+
(patch) => patch.status === "draft"
|
|
3000
|
+
);
|
|
3001
|
+
const firstPendingPatchId = pendingPatches[0]?.id;
|
|
3002
|
+
if (firstPendingPatchId !== void 0 && firstPendingPatchId !== patchState.patch.id) {
|
|
3003
|
+
diagnostics.push(
|
|
3004
|
+
buildDiagnostic({
|
|
3005
|
+
severity: "error",
|
|
3006
|
+
code: "apply_out_of_order",
|
|
3007
|
+
message: `Patch "${patchState.patch.id}" cannot be applied while earlier pending patch "${firstPendingPatchId}" still exists.`,
|
|
3008
|
+
patchId: patchState.patch.id
|
|
3009
|
+
})
|
|
3010
|
+
);
|
|
2954
3011
|
}
|
|
2955
|
-
if (
|
|
3012
|
+
if (!parsedInput.approval.approved) {
|
|
3013
|
+
diagnostics.push(
|
|
3014
|
+
buildDiagnostic({
|
|
3015
|
+
severity: "error",
|
|
3016
|
+
code: "approval_required",
|
|
3017
|
+
message: "Patch apply requires explicit approval.",
|
|
3018
|
+
patchId: patchState.patch.id
|
|
3019
|
+
})
|
|
3020
|
+
);
|
|
3021
|
+
}
|
|
3022
|
+
if (firstPendingPatchId !== void 0 && firstPendingPatchId !== patchState.patch.id || !parsedInput.approval.approved || !validation.valid || parsedInput.approval.validationFingerprint !== validation.fingerprint) {
|
|
3023
|
+
if (validation.valid && parsedInput.approval.validationFingerprint !== validation.fingerprint) {
|
|
3024
|
+
diagnostics.push(
|
|
3025
|
+
buildDiagnostic({
|
|
3026
|
+
severity: "error",
|
|
3027
|
+
code: "stale_validation_fingerprint",
|
|
3028
|
+
message: "Patch validation fingerprint is stale. Revalidate before apply.",
|
|
3029
|
+
patchId: patchState.patch.id
|
|
3030
|
+
})
|
|
3031
|
+
);
|
|
3032
|
+
}
|
|
2956
3033
|
return {
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
source: {
|
|
2963
|
-
kind: "runtime-schema",
|
|
2964
|
-
queryType: queryType2.name
|
|
2965
|
-
},
|
|
2966
|
-
lookup: {
|
|
2967
|
-
target: queryType2.name,
|
|
2968
|
-
kind: "root-query"
|
|
2969
|
-
},
|
|
2970
|
-
rootQuery: summarizeObjectType(queryType2)
|
|
3034
|
+
patchId: patchState.patch.id,
|
|
3035
|
+
applied: false,
|
|
3036
|
+
validation,
|
|
3037
|
+
diagnostics,
|
|
3038
|
+
deletedPatch: false
|
|
2971
3039
|
};
|
|
2972
3040
|
}
|
|
2973
|
-
const
|
|
2974
|
-
|
|
3041
|
+
const store = await loadKnowledgeStoreFromRoot(knowledgeRoot);
|
|
3042
|
+
const simulation = simulateKnowledgePatch(
|
|
3043
|
+
store,
|
|
3044
|
+
patchState.operations,
|
|
3045
|
+
patchState.patch.id
|
|
3046
|
+
);
|
|
3047
|
+
if (simulation.diagnostics.length > 0) {
|
|
2975
3048
|
return {
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
kind: "runtime-schema",
|
|
2983
|
-
queryType: queryType2.name
|
|
2984
|
-
},
|
|
2985
|
-
lookup: {
|
|
2986
|
-
target,
|
|
2987
|
-
kind: "root-field"
|
|
3049
|
+
patchId: patchState.patch.id,
|
|
3050
|
+
applied: false,
|
|
3051
|
+
validation: {
|
|
3052
|
+
...validation,
|
|
3053
|
+
valid: false,
|
|
3054
|
+
diagnostics: simulation.diagnostics
|
|
2988
3055
|
},
|
|
2989
|
-
|
|
2990
|
-
|
|
3056
|
+
diagnostics: simulation.diagnostics,
|
|
3057
|
+
deletedPatch: false
|
|
2991
3058
|
};
|
|
2992
3059
|
}
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
3060
|
+
await writeCanonicalFilesFromSimulation(
|
|
3061
|
+
knowledgeRoot,
|
|
3062
|
+
patchState.operations,
|
|
3063
|
+
simulation.state
|
|
3064
|
+
);
|
|
3065
|
+
try {
|
|
3066
|
+
await loadKnowledgeStoreFromRoot(knowledgeRoot);
|
|
3067
|
+
} catch (error) {
|
|
3068
|
+
const reloadDiagnostics = error instanceof KnowledgeStoreLoadError ? error.diagnostics.map(
|
|
3069
|
+
(diagnostic) => buildDiagnostic({
|
|
3070
|
+
severity: "critical",
|
|
3071
|
+
code: diagnostic.kind,
|
|
3072
|
+
message: diagnostic.message,
|
|
3073
|
+
path: diagnostic.path ? [diagnostic.path] : void 0,
|
|
3074
|
+
targetId: diagnostic.id
|
|
3075
|
+
})
|
|
3076
|
+
) : [
|
|
3077
|
+
buildDiagnostic({
|
|
3078
|
+
severity: "critical",
|
|
3079
|
+
code: "reload_failed",
|
|
3080
|
+
message: "Canonical knowledge store reload failed after apply.",
|
|
3081
|
+
patchId: patchState.patch.id
|
|
3082
|
+
})
|
|
3083
|
+
];
|
|
2997
3084
|
return {
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
source: {
|
|
3004
|
-
kind: "runtime-schema",
|
|
3005
|
-
queryType: queryType2.name
|
|
3006
|
-
},
|
|
3007
|
-
lookup: {
|
|
3008
|
-
target,
|
|
3009
|
-
kind: "object-type"
|
|
3010
|
-
},
|
|
3011
|
-
type: typeSummary,
|
|
3012
|
-
rootFields
|
|
3085
|
+
patchId: patchState.patch.id,
|
|
3086
|
+
applied: false,
|
|
3087
|
+
validation,
|
|
3088
|
+
diagnostics: reloadDiagnostics,
|
|
3089
|
+
deletedPatch: false
|
|
3013
3090
|
};
|
|
3014
3091
|
}
|
|
3015
|
-
|
|
3016
|
-
|
|
3092
|
+
await rm(patchDir, { recursive: true, force: true });
|
|
3093
|
+
return {
|
|
3094
|
+
patchId: patchState.patch.id,
|
|
3095
|
+
applied: true,
|
|
3096
|
+
validation,
|
|
3097
|
+
diagnostics: [],
|
|
3098
|
+
deletedPatch: true
|
|
3099
|
+
};
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
// packages/core/src/knowledge/patch/scope-audit.ts
|
|
3103
|
+
import { readdir as readdir2 } from "node:fs/promises";
|
|
3104
|
+
import { isAbsolute as isAbsolute2, relative, resolve as resolve5, sep as sep2 } from "node:path";
|
|
3105
|
+
import { z as z6 } from "zod/v4";
|
|
3106
|
+
var compareScopeWithEvidenceInputSchema = z6.object({
|
|
3107
|
+
patchId: z6.string().min(1),
|
|
3108
|
+
rootFolder: z6.string().trim().min(1).optional()
|
|
3109
|
+
});
|
|
3110
|
+
var compareScopeWithEvidenceResultSchema = z6.object({
|
|
3111
|
+
patchId: z6.string().min(1),
|
|
3112
|
+
rootFolder: z6.string().min(1),
|
|
3113
|
+
scopeFiles: z6.array(z6.string()),
|
|
3114
|
+
coveredFiles: z6.array(z6.string()),
|
|
3115
|
+
omittedFiles: z6.array(
|
|
3116
|
+
z6.object({
|
|
3117
|
+
path: z6.string(),
|
|
3118
|
+
reason: z6.string()
|
|
3119
|
+
})
|
|
3120
|
+
),
|
|
3121
|
+
uncoveredFiles: z6.array(z6.string()),
|
|
3122
|
+
outOfRootEvidenceFiles: z6.array(z6.string()),
|
|
3123
|
+
message: z6.string()
|
|
3124
|
+
});
|
|
3125
|
+
function toPosixPath(value) {
|
|
3126
|
+
return value.replaceAll(sep2, "/");
|
|
3127
|
+
}
|
|
3128
|
+
function normalizeAuditedRoot(rootFolder) {
|
|
3129
|
+
return resolve5(rootFolder);
|
|
3130
|
+
}
|
|
3131
|
+
function isPathWithinRoot(rootFolder, filePath) {
|
|
3132
|
+
const relativePath = toPosixPath(relative(rootFolder, filePath));
|
|
3133
|
+
return Boolean(
|
|
3134
|
+
relativePath && relativePath !== ".." && !relativePath.startsWith("../")
|
|
3017
3135
|
);
|
|
3018
3136
|
}
|
|
3019
|
-
function
|
|
3020
|
-
|
|
3137
|
+
function normalizePathWithinRoot(rootFolder, filePath, outputRoot = rootFolder) {
|
|
3138
|
+
let candidate;
|
|
3139
|
+
if (isAbsolute2(filePath)) {
|
|
3140
|
+
candidate = resolve5(filePath);
|
|
3141
|
+
} else {
|
|
3142
|
+
const repoRelativeCandidate = resolve5(outputRoot, filePath);
|
|
3143
|
+
candidate = isPathWithinRoot(rootFolder, repoRelativeCandidate) ? repoRelativeCandidate : resolve5(rootFolder, filePath);
|
|
3144
|
+
}
|
|
3145
|
+
const relativePath = toPosixPath(relative(outputRoot, candidate));
|
|
3146
|
+
if (!relativePath || relativePath === ".." || relativePath.startsWith("../")) {
|
|
3147
|
+
return null;
|
|
3148
|
+
}
|
|
3149
|
+
return relativePath;
|
|
3021
3150
|
}
|
|
3022
|
-
function
|
|
3023
|
-
|
|
3151
|
+
async function collectScopeFiles(currentDir, auditedRoot, patchStorageRoot, outputRoot) {
|
|
3152
|
+
if (currentDir === patchStorageRoot) {
|
|
3153
|
+
return [];
|
|
3154
|
+
}
|
|
3155
|
+
const entries = await readdir2(currentDir, { withFileTypes: true });
|
|
3156
|
+
const files = [];
|
|
3157
|
+
for (const entry of entries) {
|
|
3158
|
+
const entryPath = resolve5(currentDir, entry.name);
|
|
3159
|
+
if (entry.isDirectory()) {
|
|
3160
|
+
files.push(
|
|
3161
|
+
...await collectScopeFiles(
|
|
3162
|
+
entryPath,
|
|
3163
|
+
auditedRoot,
|
|
3164
|
+
patchStorageRoot,
|
|
3165
|
+
outputRoot
|
|
3166
|
+
)
|
|
3167
|
+
);
|
|
3168
|
+
continue;
|
|
3169
|
+
}
|
|
3170
|
+
if (!entry.isFile()) {
|
|
3171
|
+
continue;
|
|
3172
|
+
}
|
|
3173
|
+
const normalized = normalizePathWithinRoot(auditedRoot, entryPath, outputRoot);
|
|
3174
|
+
if (normalized) {
|
|
3175
|
+
files.push(normalized);
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
return files;
|
|
3024
3179
|
}
|
|
3025
|
-
function
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3180
|
+
async function compareScopeWithEvidence(envValue, input, cwd = process.cwd()) {
|
|
3181
|
+
const parsedInput = compareScopeWithEvidenceInputSchema.parse(input);
|
|
3182
|
+
const patchState = await readKnowledgePatch(envValue, parsedInput.patchId, cwd);
|
|
3183
|
+
const auditedRoot = normalizeAuditedRoot(
|
|
3184
|
+
parsedInput.rootFolder ?? patchState.patch.rootFolder
|
|
3030
3185
|
);
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3186
|
+
const repositoryRoot = resolve5(cwd);
|
|
3187
|
+
const effectiveState = await loadEffectiveKnowledgeStoreFromRoot(
|
|
3188
|
+
resolveKnowledgeRoot2(envValue, cwd),
|
|
3189
|
+
{
|
|
3190
|
+
selectedPatchId: parsedInput.patchId
|
|
3191
|
+
}
|
|
3192
|
+
);
|
|
3193
|
+
const effectivePatchIds = new Set(effectiveState.patchIds);
|
|
3194
|
+
const coveredFiles = /* @__PURE__ */ new Set();
|
|
3195
|
+
const outOfRootEvidenceFiles = /* @__PURE__ */ new Set();
|
|
3196
|
+
for (const evidence of effectiveState.store.evidence) {
|
|
3197
|
+
const provenance = effectiveState.provenance.get(evidence.id);
|
|
3198
|
+
if (!provenance?.patchIds.some((patchId) => effectivePatchIds.has(patchId))) {
|
|
3199
|
+
continue;
|
|
3200
|
+
}
|
|
3201
|
+
const sourcePath = evidence.location?.path;
|
|
3202
|
+
if (!sourcePath) {
|
|
3203
|
+
continue;
|
|
3204
|
+
}
|
|
3205
|
+
const normalized = normalizePathWithinRoot(
|
|
3206
|
+
auditedRoot,
|
|
3207
|
+
sourcePath,
|
|
3208
|
+
repositoryRoot
|
|
3209
|
+
);
|
|
3210
|
+
if (normalized) {
|
|
3211
|
+
coveredFiles.add(normalized);
|
|
3212
|
+
continue;
|
|
3213
|
+
}
|
|
3214
|
+
outOfRootEvidenceFiles.add(sourcePath);
|
|
3036
3215
|
}
|
|
3037
|
-
const
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3216
|
+
const omittedFiles = patchState.patch.omittedFiles.map((entry) => ({
|
|
3217
|
+
path: entry.path,
|
|
3218
|
+
reason: entry.reason
|
|
3219
|
+
}));
|
|
3220
|
+
const omittedFileSet = new Set(omittedFiles.map((entry) => entry.path));
|
|
3221
|
+
const patchStorageRoot = resolve5(auditedRoot, KNOWLEDGE_PATCH_FOLDER_NAME);
|
|
3222
|
+
const scopeFiles = (await collectScopeFiles(
|
|
3223
|
+
auditedRoot,
|
|
3224
|
+
auditedRoot,
|
|
3225
|
+
patchStorageRoot,
|
|
3226
|
+
repositoryRoot
|
|
3227
|
+
)).sort((left, right) => left.localeCompare(right));
|
|
3228
|
+
const uncoveredFiles = scopeFiles.filter(
|
|
3229
|
+
(filePath) => !coveredFiles.has(filePath) && !omittedFileSet.has(filePath)
|
|
3230
|
+
);
|
|
3231
|
+
const sortedCoveredFiles = [...coveredFiles].sort(
|
|
3232
|
+
(left, right) => left.localeCompare(right)
|
|
3233
|
+
);
|
|
3234
|
+
const sortedOutOfRootEvidenceFiles = [...outOfRootEvidenceFiles].sort(
|
|
3041
3235
|
(left, right) => left.localeCompare(right)
|
|
3042
3236
|
);
|
|
3237
|
+
const message = uncoveredFiles.length > 0 ? `Recheck ${uncoveredFiles.length} uncovered file(s): add evidence-backed knowledge or mark them omitted with a reason.` : "Scope audit complete. No uncovered files remain.";
|
|
3238
|
+
return compareScopeWithEvidenceResultSchema.parse({
|
|
3239
|
+
patchId: parsedInput.patchId,
|
|
3240
|
+
rootFolder: auditedRoot,
|
|
3241
|
+
scopeFiles,
|
|
3242
|
+
coveredFiles: sortedCoveredFiles,
|
|
3243
|
+
omittedFiles,
|
|
3244
|
+
uncoveredFiles,
|
|
3245
|
+
outOfRootEvidenceFiles: sortedOutOfRootEvidenceFiles,
|
|
3246
|
+
message
|
|
3247
|
+
});
|
|
3043
3248
|
}
|
|
3044
3249
|
|
|
3045
|
-
// packages/
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3250
|
+
// packages/core/src/knowledge/patch/index.ts
|
|
3251
|
+
async function executeKnowledgePatchAction(envValue, input, cwd = process.cwd()) {
|
|
3252
|
+
switch (input.action) {
|
|
3253
|
+
case "create":
|
|
3254
|
+
return createKnowledgePatch(envValue, input.patch, cwd);
|
|
3255
|
+
case "list":
|
|
3256
|
+
return listKnowledgePatches(envValue, cwd);
|
|
3257
|
+
case "get":
|
|
3258
|
+
return readKnowledgePatch(envValue, input.patchId, cwd);
|
|
3259
|
+
case "add_operation":
|
|
3260
|
+
return addKnowledgePatchOperation(
|
|
3261
|
+
envValue,
|
|
3262
|
+
input.patchId,
|
|
3263
|
+
input.operation,
|
|
3264
|
+
cwd
|
|
3265
|
+
);
|
|
3266
|
+
case "update_operation":
|
|
3267
|
+
return updateKnowledgePatchOperation(
|
|
3268
|
+
envValue,
|
|
3269
|
+
input.patchId,
|
|
3270
|
+
input.update,
|
|
3271
|
+
cwd
|
|
3272
|
+
);
|
|
3273
|
+
case "update_metadata":
|
|
3274
|
+
return updateKnowledgePatchMetadata(
|
|
3275
|
+
envValue,
|
|
3276
|
+
input.patchId,
|
|
3277
|
+
input.metadata,
|
|
3278
|
+
cwd
|
|
3279
|
+
);
|
|
3280
|
+
case "delete_operation":
|
|
3281
|
+
return deleteKnowledgePatchOperation(
|
|
3282
|
+
envValue,
|
|
3283
|
+
input.patchId,
|
|
3284
|
+
input.operationId,
|
|
3285
|
+
cwd
|
|
3286
|
+
);
|
|
3287
|
+
case "validate":
|
|
3288
|
+
return validateKnowledgePatch(envValue, input.patchId, cwd);
|
|
3289
|
+
case "close":
|
|
3290
|
+
return closeKnowledgePatch(envValue, input.patchId, cwd);
|
|
3291
|
+
}
|
|
3057
3292
|
}
|
|
3058
|
-
function
|
|
3059
|
-
return
|
|
3060
|
-
contents: [
|
|
3061
|
-
{
|
|
3062
|
-
uri,
|
|
3063
|
-
mimeType: "text/markdown",
|
|
3064
|
-
text
|
|
3065
|
-
}
|
|
3066
|
-
]
|
|
3067
|
-
};
|
|
3293
|
+
function buildKnowledgePatchToolText(result) {
|
|
3294
|
+
return JSON.stringify(result, null, 2);
|
|
3068
3295
|
}
|
|
3296
|
+
|
|
3297
|
+
// packages/mcp/src/resources/knowledge-extraction.ts
|
|
3298
|
+
import { ResourceTemplate } from "@modelcontextprotocol/server";
|
|
3069
3299
|
function listExtractionTypeNames() {
|
|
3070
3300
|
return listKnowledgeExtractionResourceTypes().flatMap((definition) => [
|
|
3071
3301
|
definition.collection,
|
|
@@ -3073,30 +3303,29 @@ function listExtractionTypeNames() {
|
|
|
3073
3303
|
]);
|
|
3074
3304
|
}
|
|
3075
3305
|
function registerKnowledgeExtractionResources(server) {
|
|
3306
|
+
const resource = getKnowledgeResourceEntry(KNOWLEDGE_EXTRACTION_TYPES_RESOURCE_URI);
|
|
3307
|
+
if (!resource) {
|
|
3308
|
+
throw new Error("Knowledge extraction resource metadata is missing.");
|
|
3309
|
+
}
|
|
3076
3310
|
server.registerResource(
|
|
3077
|
-
|
|
3311
|
+
resource.name,
|
|
3078
3312
|
KNOWLEDGE_EXTRACTION_TYPES_RESOURCE_URI,
|
|
3079
3313
|
{
|
|
3080
|
-
title:
|
|
3081
|
-
description:
|
|
3082
|
-
mimeType:
|
|
3314
|
+
title: resource.title,
|
|
3315
|
+
description: resource.description,
|
|
3316
|
+
mimeType: resource.mimeType
|
|
3083
3317
|
},
|
|
3084
|
-
async (uri) =>
|
|
3085
|
-
uri.href
|
|
3086
|
-
|
|
3087
|
-
)
|
|
3318
|
+
async (uri) => ({
|
|
3319
|
+
contents: [(await readKnowledgeResourceDocument(uri.href)).content]
|
|
3320
|
+
})
|
|
3088
3321
|
);
|
|
3089
3322
|
server.registerResource(
|
|
3090
3323
|
"knowledge-extraction-schema",
|
|
3091
3324
|
new ResourceTemplate(KNOWLEDGE_EXTRACTION_SCHEMA_RESOURCE_URI, {
|
|
3092
3325
|
list: async () => ({
|
|
3093
|
-
resources:
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
title: `${definition.title} Extraction Schema`,
|
|
3097
|
-
description: `Runtime schema discovery for ${definition.title.toLowerCase()}.`,
|
|
3098
|
-
mimeType: "application/json"
|
|
3099
|
-
}))
|
|
3326
|
+
resources: listKnowledgeResourceTemplateResources(
|
|
3327
|
+
KNOWLEDGE_EXTRACTION_SCHEMA_RESOURCE_URI
|
|
3328
|
+
)
|
|
3100
3329
|
}),
|
|
3101
3330
|
complete: {
|
|
3102
3331
|
type: async (value) => listExtractionTypeNames().filter(
|
|
@@ -3109,29 +3338,17 @@ function registerKnowledgeExtractionResources(server) {
|
|
|
3109
3338
|
description: "Runtime JSON-schema discovery for a supported knowledge type.",
|
|
3110
3339
|
mimeType: "application/json"
|
|
3111
3340
|
},
|
|
3112
|
-
async (
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
throw new Error("Resource type is required.");
|
|
3116
|
-
}
|
|
3117
|
-
const document = buildKnowledgeExtractionSchemaDocument(type);
|
|
3118
|
-
return createJsonResourceContent(
|
|
3119
|
-
`ez-know://extraction/schema/${document.type.collection}`,
|
|
3120
|
-
JSON.stringify(document, null, 2)
|
|
3121
|
-
);
|
|
3122
|
-
}
|
|
3341
|
+
async (uri) => ({
|
|
3342
|
+
contents: [(await readKnowledgeResourceDocument(uri.href)).content]
|
|
3343
|
+
})
|
|
3123
3344
|
);
|
|
3124
3345
|
server.registerResource(
|
|
3125
3346
|
"knowledge-extraction-guide",
|
|
3126
3347
|
new ResourceTemplate(KNOWLEDGE_EXTRACTION_GUIDE_RESOURCE_URI, {
|
|
3127
3348
|
list: async () => ({
|
|
3128
|
-
resources:
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
title: `${definition.title} Extraction Guide`,
|
|
3132
|
-
description: `Checked-in extraction guidance for ${definition.title.toLowerCase()}.`,
|
|
3133
|
-
mimeType: "text/markdown"
|
|
3134
|
-
}))
|
|
3349
|
+
resources: listKnowledgeResourceTemplateResources(
|
|
3350
|
+
KNOWLEDGE_EXTRACTION_GUIDE_RESOURCE_URI
|
|
3351
|
+
)
|
|
3135
3352
|
}),
|
|
3136
3353
|
complete: {
|
|
3137
3354
|
type: async (value) => listExtractionTypeNames().filter(
|
|
@@ -3144,17 +3361,9 @@ function registerKnowledgeExtractionResources(server) {
|
|
|
3144
3361
|
description: "Checked-in Markdown guidance for a supported knowledge type.",
|
|
3145
3362
|
mimeType: "text/markdown"
|
|
3146
3363
|
},
|
|
3147
|
-
async (
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
throw new Error("Resource type is required.");
|
|
3151
|
-
}
|
|
3152
|
-
const document = await buildKnowledgeExtractionGuideDocument(type);
|
|
3153
|
-
return createMarkdownResourceContent(
|
|
3154
|
-
`ez-know://extraction/guide/${document.type.collection}`,
|
|
3155
|
-
document.markdown
|
|
3156
|
-
);
|
|
3157
|
-
}
|
|
3364
|
+
async (uri) => ({
|
|
3365
|
+
contents: [(await readKnowledgeResourceDocument(uri.href)).content]
|
|
3366
|
+
})
|
|
3158
3367
|
);
|
|
3159
3368
|
}
|
|
3160
3369
|
|
|
@@ -3218,6 +3427,104 @@ function registerKnowledgeGraphTool(server, getStore) {
|
|
|
3218
3427
|
);
|
|
3219
3428
|
}
|
|
3220
3429
|
|
|
3430
|
+
// packages/mcp/src/tools/legacy-resource-tools.ts
|
|
3431
|
+
import * as z8 from "zod/v4";
|
|
3432
|
+
function createTextToolResult(payload) {
|
|
3433
|
+
return {
|
|
3434
|
+
content: [
|
|
3435
|
+
{
|
|
3436
|
+
type: "text",
|
|
3437
|
+
text: JSON.stringify(payload, null, 2)
|
|
3438
|
+
}
|
|
3439
|
+
]
|
|
3440
|
+
};
|
|
3441
|
+
}
|
|
3442
|
+
function serializeResourceError(error, uri) {
|
|
3443
|
+
if (error instanceof KnowledgeResourceNotFoundError || error instanceof KnowledgeResourceUriError) {
|
|
3444
|
+
return {
|
|
3445
|
+
error: {
|
|
3446
|
+
code: error.code,
|
|
3447
|
+
message: error.message,
|
|
3448
|
+
uri: error.uri
|
|
3449
|
+
}
|
|
3450
|
+
};
|
|
3451
|
+
}
|
|
3452
|
+
if (error instanceof Error) {
|
|
3453
|
+
return {
|
|
3454
|
+
error: {
|
|
3455
|
+
code: "RESOURCE_READ_FAILED",
|
|
3456
|
+
message: error.message,
|
|
3457
|
+
uri
|
|
3458
|
+
}
|
|
3459
|
+
};
|
|
3460
|
+
}
|
|
3461
|
+
return {
|
|
3462
|
+
error: {
|
|
3463
|
+
code: "RESOURCE_READ_FAILED",
|
|
3464
|
+
message: "Unknown resource read failure.",
|
|
3465
|
+
uri
|
|
3466
|
+
}
|
|
3467
|
+
};
|
|
3468
|
+
}
|
|
3469
|
+
function isLegacyResourceToolsEnabled(value = process.env.EZ_KNOW_LEGACY_RESOURCES) {
|
|
3470
|
+
if (value === void 0) {
|
|
3471
|
+
return false;
|
|
3472
|
+
}
|
|
3473
|
+
const normalized = value.trim().toLowerCase();
|
|
3474
|
+
if (normalized.length === 0) {
|
|
3475
|
+
return false;
|
|
3476
|
+
}
|
|
3477
|
+
return !["0", "false", "off", "no"].includes(normalized);
|
|
3478
|
+
}
|
|
3479
|
+
function registerLegacyResourceTools(server) {
|
|
3480
|
+
server.registerTool(
|
|
3481
|
+
"list_mcp_resources",
|
|
3482
|
+
{
|
|
3483
|
+
title: "Legacy MCP Resource List",
|
|
3484
|
+
description: "Lists the ez-know resources exposed through the legacy tool fallback.",
|
|
3485
|
+
inputSchema: z8.object({})
|
|
3486
|
+
},
|
|
3487
|
+
async () => createTextToolResult({
|
|
3488
|
+
resources: listKnowledgeResourceEntries()
|
|
3489
|
+
})
|
|
3490
|
+
);
|
|
3491
|
+
server.registerTool(
|
|
3492
|
+
"list_mcp_resource_templates",
|
|
3493
|
+
{
|
|
3494
|
+
title: "Legacy MCP Resource Templates",
|
|
3495
|
+
description: "Lists the ez-know resource templates exposed through the legacy tool fallback.",
|
|
3496
|
+
inputSchema: z8.object({})
|
|
3497
|
+
},
|
|
3498
|
+
async () => createTextToolResult({
|
|
3499
|
+
resourceTemplates: listKnowledgeResourceTemplateEntries()
|
|
3500
|
+
})
|
|
3501
|
+
);
|
|
3502
|
+
server.registerTool(
|
|
3503
|
+
"read_mcp_resource",
|
|
3504
|
+
{
|
|
3505
|
+
title: "Legacy MCP Resource Read",
|
|
3506
|
+
description: "Reads a single ez-know resource by URI through the legacy tool fallback.",
|
|
3507
|
+
inputSchema: z8.object({
|
|
3508
|
+
uri: z8.string().min(1)
|
|
3509
|
+
})
|
|
3510
|
+
},
|
|
3511
|
+
async (input) => {
|
|
3512
|
+
const parsedInput = z8.object({ uri: z8.string().min(1) }).parse(input);
|
|
3513
|
+
try {
|
|
3514
|
+
const result = await readKnowledgeResourceDocument(parsedInput.uri);
|
|
3515
|
+
return createTextToolResult({
|
|
3516
|
+
resource: result.resource,
|
|
3517
|
+
contents: [result.content]
|
|
3518
|
+
});
|
|
3519
|
+
} catch (error) {
|
|
3520
|
+
return createTextToolResult(
|
|
3521
|
+
serializeResourceError(error, parsedInput.uri)
|
|
3522
|
+
);
|
|
3523
|
+
}
|
|
3524
|
+
}
|
|
3525
|
+
);
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3221
3528
|
// packages/mcp/src/tools/knowledge-patch-apply.ts
|
|
3222
3529
|
function registerKnowledgePatchApplyTool(server) {
|
|
3223
3530
|
server.registerTool(
|
|
@@ -3274,43 +3581,29 @@ function registerKnowledgePatchTool(server) {
|
|
|
3274
3581
|
|
|
3275
3582
|
// packages/mcp/src/resources/knowledge-schema.ts
|
|
3276
3583
|
import { ResourceTemplate as ResourceTemplate2 } from "@modelcontextprotocol/server";
|
|
3277
|
-
function createJsonResourceContent2(uri, text) {
|
|
3278
|
-
return {
|
|
3279
|
-
contents: [
|
|
3280
|
-
{
|
|
3281
|
-
uri,
|
|
3282
|
-
mimeType: "application/json",
|
|
3283
|
-
text
|
|
3284
|
-
}
|
|
3285
|
-
]
|
|
3286
|
-
};
|
|
3287
|
-
}
|
|
3288
3584
|
function registerKnowledgeSchemaResources(server) {
|
|
3585
|
+
const resource = getKnowledgeResourceEntry(KNOWLEDGE_SCHEMA_RESOURCE_URI);
|
|
3586
|
+
if (!resource) {
|
|
3587
|
+
throw new Error("Knowledge schema resource metadata is missing.");
|
|
3588
|
+
}
|
|
3289
3589
|
server.registerResource(
|
|
3290
|
-
|
|
3590
|
+
resource.name,
|
|
3291
3591
|
KNOWLEDGE_SCHEMA_RESOURCE_URI,
|
|
3292
3592
|
{
|
|
3293
|
-
title:
|
|
3294
|
-
description:
|
|
3295
|
-
mimeType:
|
|
3593
|
+
title: resource.title,
|
|
3594
|
+
description: resource.description,
|
|
3595
|
+
mimeType: resource.mimeType
|
|
3296
3596
|
},
|
|
3297
|
-
async (uri) =>
|
|
3298
|
-
uri.href
|
|
3299
|
-
|
|
3300
|
-
)
|
|
3597
|
+
async (uri) => ({
|
|
3598
|
+
contents: [(await readKnowledgeResourceDocument(uri.href)).content]
|
|
3599
|
+
})
|
|
3301
3600
|
);
|
|
3302
3601
|
server.registerResource(
|
|
3303
3602
|
"knowledge-schema-lookup",
|
|
3304
3603
|
new ResourceTemplate2(KNOWLEDGE_SCHEMA_LOOKUP_URI, {
|
|
3305
3604
|
list: async () => ({
|
|
3306
|
-
resources:
|
|
3307
|
-
|
|
3308
|
-
uri: `knowledge-schema://lookup/${target}`,
|
|
3309
|
-
name: target,
|
|
3310
|
-
title: `Knowledge schema lookup: ${target}`,
|
|
3311
|
-
description: target === "Query" ? "Focused lookup of the root query fields." : `Focused lookup of ${target}.`,
|
|
3312
|
-
mimeType: "application/json"
|
|
3313
|
-
})
|
|
3605
|
+
resources: listKnowledgeResourceTemplateResources(
|
|
3606
|
+
KNOWLEDGE_SCHEMA_LOOKUP_URI
|
|
3314
3607
|
)
|
|
3315
3608
|
}),
|
|
3316
3609
|
complete: {
|
|
@@ -3324,27 +3617,19 @@ function registerKnowledgeSchemaResources(server) {
|
|
|
3324
3617
|
description: "Focused runtime GraphQL schema lookup for a type name, root field, or Query.",
|
|
3325
3618
|
mimeType: "application/json"
|
|
3326
3619
|
},
|
|
3327
|
-
async (
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
throw new Error("Resource target is required.");
|
|
3331
|
-
}
|
|
3332
|
-
return createJsonResourceContent2(
|
|
3333
|
-
`knowledge-schema://lookup/${target}`,
|
|
3334
|
-
createKnowledgeSchemaLookupText(knowledgeGraphSchema, target)
|
|
3335
|
-
);
|
|
3336
|
-
}
|
|
3620
|
+
async (uri) => ({
|
|
3621
|
+
contents: [(await readKnowledgeResourceDocument(uri.href)).content]
|
|
3622
|
+
})
|
|
3337
3623
|
);
|
|
3338
3624
|
}
|
|
3339
3625
|
|
|
3340
3626
|
// packages/mcp/src/run.ts
|
|
3341
|
-
|
|
3342
|
-
const server = new McpServer({
|
|
3343
|
-
name: "ez-know",
|
|
3344
|
-
version: "0.1.0"
|
|
3345
|
-
});
|
|
3627
|
+
function registerMcpServerCapabilities(server) {
|
|
3346
3628
|
registerKnowledgeSchemaResources(server);
|
|
3347
3629
|
registerKnowledgeExtractionResources(server);
|
|
3630
|
+
if (isLegacyResourceToolsEnabled()) {
|
|
3631
|
+
registerLegacyResourceTools(server);
|
|
3632
|
+
}
|
|
3348
3633
|
registerKnowledgeGraphTool(server, async () => {
|
|
3349
3634
|
const effectiveState = await loadEffectiveKnowledgeStoreFromEnv(
|
|
3350
3635
|
process.env.EZ_KNOW_ROOT
|
|
@@ -3354,6 +3639,13 @@ async function startMcpServer() {
|
|
|
3354
3639
|
registerKnowledgePatchTool(server);
|
|
3355
3640
|
registerKnowledgePatchApplyTool(server);
|
|
3356
3641
|
registerCompareScopeWithEvidenceTool(server);
|
|
3642
|
+
}
|
|
3643
|
+
async function startMcpServer() {
|
|
3644
|
+
const server = new McpServer({
|
|
3645
|
+
name: "ez-know",
|
|
3646
|
+
version: "0.1.0"
|
|
3647
|
+
});
|
|
3648
|
+
registerMcpServerCapabilities(server);
|
|
3357
3649
|
const transport = new StdioServerTransport();
|
|
3358
3650
|
await server.connect(transport);
|
|
3359
3651
|
}
|
|
@@ -3448,7 +3740,7 @@ import {
|
|
|
3448
3740
|
OpenAPIRegistry,
|
|
3449
3741
|
OpenApiGeneratorV3
|
|
3450
3742
|
} from "@asteasolutions/zod-to-openapi";
|
|
3451
|
-
import { z as
|
|
3743
|
+
import { z as z9 } from "zod/v4";
|
|
3452
3744
|
|
|
3453
3745
|
// packages/rest/src/schema-registry.ts
|
|
3454
3746
|
var REST_COLLECTION_SCHEMA_REGISTRY = {
|
|
@@ -3526,14 +3818,14 @@ var REST_CONFIDENCE_SCHEMA = confidenceSchema;
|
|
|
3526
3818
|
var REST_CERTAINTY_SCHEMA = certaintySchema;
|
|
3527
3819
|
|
|
3528
3820
|
// packages/rest/src/openapi.ts
|
|
3529
|
-
extendZodWithOpenApi2(
|
|
3821
|
+
extendZodWithOpenApi2(z9);
|
|
3530
3822
|
var openApiRegistry = new OpenAPIRegistry();
|
|
3531
3823
|
var restErrorResponseSchema = openApiRegistry.register(
|
|
3532
3824
|
"RestErrorResponse",
|
|
3533
|
-
|
|
3534
|
-
error:
|
|
3535
|
-
code:
|
|
3536
|
-
message:
|
|
3825
|
+
z9.object({
|
|
3826
|
+
error: z9.object({
|
|
3827
|
+
code: z9.string(),
|
|
3828
|
+
message: z9.string()
|
|
3537
3829
|
})
|
|
3538
3830
|
}).openapi({
|
|
3539
3831
|
description: "Standard REST error envelope."
|
|
@@ -3541,51 +3833,51 @@ var restErrorResponseSchema = openApiRegistry.register(
|
|
|
3541
3833
|
);
|
|
3542
3834
|
var restHealthResponseSchema = openApiRegistry.register(
|
|
3543
3835
|
"RestHealthResponse",
|
|
3544
|
-
|
|
3545
|
-
service:
|
|
3546
|
-
status:
|
|
3547
|
-
storeAvailable:
|
|
3836
|
+
z9.object({
|
|
3837
|
+
service: z9.string(),
|
|
3838
|
+
status: z9.literal("ok"),
|
|
3839
|
+
storeAvailable: z9.boolean()
|
|
3548
3840
|
}).openapi({
|
|
3549
3841
|
description: "Service health payload."
|
|
3550
3842
|
})
|
|
3551
3843
|
);
|
|
3552
3844
|
var restPatchSummarySchema = openApiRegistry.register(
|
|
3553
3845
|
"RestPatchSummary",
|
|
3554
|
-
|
|
3555
|
-
id:
|
|
3556
|
-
status:
|
|
3557
|
-
title:
|
|
3558
|
-
description:
|
|
3559
|
-
rootFolder:
|
|
3560
|
-
omittedFiles:
|
|
3561
|
-
|
|
3562
|
-
path:
|
|
3563
|
-
reason:
|
|
3846
|
+
z9.object({
|
|
3847
|
+
id: z9.string(),
|
|
3848
|
+
status: z9.string(),
|
|
3849
|
+
title: z9.string(),
|
|
3850
|
+
description: z9.string().optional(),
|
|
3851
|
+
rootFolder: z9.string(),
|
|
3852
|
+
omittedFiles: z9.array(
|
|
3853
|
+
z9.object({
|
|
3854
|
+
path: z9.string(),
|
|
3855
|
+
reason: z9.string()
|
|
3564
3856
|
})
|
|
3565
3857
|
),
|
|
3566
|
-
operationCount:
|
|
3567
|
-
createdAt:
|
|
3568
|
-
updatedAt:
|
|
3858
|
+
operationCount: z9.number().int().min(0),
|
|
3859
|
+
createdAt: z9.string(),
|
|
3860
|
+
updatedAt: z9.string()
|
|
3569
3861
|
}).openapi({
|
|
3570
3862
|
description: "Patch inventory summary."
|
|
3571
3863
|
})
|
|
3572
3864
|
);
|
|
3573
3865
|
var restPatchProvenanceEntrySchema = openApiRegistry.register(
|
|
3574
3866
|
"RestPatchProvenanceEntry",
|
|
3575
|
-
|
|
3576
|
-
patchIds:
|
|
3577
|
-
patched:
|
|
3867
|
+
z9.object({
|
|
3868
|
+
patchIds: z9.array(z9.string()),
|
|
3869
|
+
patched: z9.boolean()
|
|
3578
3870
|
}).openapi({
|
|
3579
3871
|
description: "Patch provenance for a previewed record."
|
|
3580
3872
|
})
|
|
3581
3873
|
);
|
|
3582
3874
|
var restPatchFacetItemSchema = openApiRegistry.register(
|
|
3583
3875
|
"RestPatchFacetItem",
|
|
3584
|
-
|
|
3585
|
-
id:
|
|
3586
|
-
label:
|
|
3587
|
-
patched:
|
|
3588
|
-
provenancePatchIds:
|
|
3876
|
+
z9.object({
|
|
3877
|
+
id: z9.string(),
|
|
3878
|
+
label: z9.string(),
|
|
3879
|
+
patched: z9.boolean(),
|
|
3880
|
+
provenancePatchIds: z9.array(z9.string())
|
|
3589
3881
|
}).openapi({
|
|
3590
3882
|
description: "Patch-aware facet option."
|
|
3591
3883
|
})
|
|
@@ -3600,7 +3892,7 @@ var certaintyRef = openApiRegistry.register(
|
|
|
3600
3892
|
);
|
|
3601
3893
|
var restOpenApiDocumentSchema = openApiRegistry.register(
|
|
3602
3894
|
"RestOpenApiDocument",
|
|
3603
|
-
|
|
3895
|
+
z9.record(z9.string(), z9.unknown())
|
|
3604
3896
|
);
|
|
3605
3897
|
var previewCollectionResponseSchemas = /* @__PURE__ */ new Map();
|
|
3606
3898
|
for (const collection of REST_COLLECTIONS) {
|
|
@@ -3621,24 +3913,24 @@ for (const collection of REST_COLLECTIONS) {
|
|
|
3621
3913
|
const previewItemSchema = openApiRegistry.register(
|
|
3622
3914
|
`${schemaDefinition.itemName}PreviewRecord`,
|
|
3623
3915
|
itemSchemaSource.extend({
|
|
3624
|
-
patched:
|
|
3625
|
-
provenancePatchIds:
|
|
3916
|
+
patched: z9.boolean(),
|
|
3917
|
+
provenancePatchIds: z9.array(z9.string())
|
|
3626
3918
|
})
|
|
3627
3919
|
);
|
|
3628
3920
|
const collectionResponseSchema = openApiRegistry.register(
|
|
3629
3921
|
schemaDefinition.collectionResponseName,
|
|
3630
|
-
|
|
3631
|
-
items:
|
|
3632
|
-
count:
|
|
3922
|
+
z9.object({
|
|
3923
|
+
items: z9.array(itemSchema),
|
|
3924
|
+
count: z9.number().int().min(0)
|
|
3633
3925
|
}).openapi({
|
|
3634
3926
|
description: `${schemaDefinition.itemName} collection response.`
|
|
3635
3927
|
})
|
|
3636
3928
|
);
|
|
3637
3929
|
const previewCollectionResponseSchema = openApiRegistry.register(
|
|
3638
3930
|
`${schemaDefinition.itemName}PreviewCollectionResponse`,
|
|
3639
|
-
|
|
3640
|
-
items:
|
|
3641
|
-
count:
|
|
3931
|
+
z9.object({
|
|
3932
|
+
items: z9.array(previewItemSchema),
|
|
3933
|
+
count: z9.number().int().min(0)
|
|
3642
3934
|
}).openapi({
|
|
3643
3935
|
description: `${schemaDefinition.itemName} preview collection response.`
|
|
3644
3936
|
})
|
|
@@ -3649,7 +3941,7 @@ for (const collection of REST_COLLECTIONS) {
|
|
|
3649
3941
|
);
|
|
3650
3942
|
const itemResponseSchema = openApiRegistry.register(
|
|
3651
3943
|
schemaDefinition.itemResponseName,
|
|
3652
|
-
|
|
3944
|
+
z9.object({
|
|
3653
3945
|
item: itemSchema
|
|
3654
3946
|
}).openapi({
|
|
3655
3947
|
description: `${schemaDefinition.itemName} item response.`
|
|
@@ -3691,8 +3983,8 @@ for (const collection of REST_COLLECTIONS) {
|
|
|
3691
3983
|
path: `${REST_V1_PREFIX}/${collection.route}/{id}`,
|
|
3692
3984
|
summary: `Get ${collection.label.toLowerCase()} by id`,
|
|
3693
3985
|
request: {
|
|
3694
|
-
params:
|
|
3695
|
-
id:
|
|
3986
|
+
params: z9.object({
|
|
3987
|
+
id: z9.string()
|
|
3696
3988
|
})
|
|
3697
3989
|
},
|
|
3698
3990
|
responses: {
|
|
@@ -3725,25 +4017,25 @@ for (const collection of REST_COLLECTIONS) {
|
|
|
3725
4017
|
}
|
|
3726
4018
|
var restPatchInventoryResponseSchema = openApiRegistry.register(
|
|
3727
4019
|
"RestPatchInventoryResponse",
|
|
3728
|
-
|
|
3729
|
-
items:
|
|
3730
|
-
count:
|
|
4020
|
+
z9.object({
|
|
4021
|
+
items: z9.array(restPatchSummarySchema),
|
|
4022
|
+
count: z9.number().int().min(0)
|
|
3731
4023
|
}).openapi({
|
|
3732
4024
|
description: "Patch inventory response."
|
|
3733
4025
|
})
|
|
3734
4026
|
);
|
|
3735
4027
|
var restPatchPreviewResponseSchema = openApiRegistry.register(
|
|
3736
4028
|
"RestPatchPreviewResponse",
|
|
3737
|
-
|
|
3738
|
-
selectedPatchId:
|
|
3739
|
-
prefixPatchIds:
|
|
3740
|
-
patches:
|
|
3741
|
-
provenance:
|
|
3742
|
-
facets:
|
|
3743
|
-
domains:
|
|
3744
|
-
entities:
|
|
4029
|
+
z9.object({
|
|
4030
|
+
selectedPatchId: z9.string(),
|
|
4031
|
+
prefixPatchIds: z9.array(z9.string()),
|
|
4032
|
+
patches: z9.array(restPatchSummarySchema),
|
|
4033
|
+
provenance: z9.record(z9.string(), restPatchProvenanceEntrySchema),
|
|
4034
|
+
facets: z9.object({
|
|
4035
|
+
domains: z9.array(restPatchFacetItemSchema),
|
|
4036
|
+
entities: z9.array(restPatchFacetItemSchema)
|
|
3745
4037
|
}).strict(),
|
|
3746
|
-
collections:
|
|
4038
|
+
collections: z9.object({
|
|
3747
4039
|
domains: previewCollectionResponseSchemas.get("domains"),
|
|
3748
4040
|
entities: previewCollectionResponseSchemas.get("entities"),
|
|
3749
4041
|
relationships: previewCollectionResponseSchemas.get("relationships"),
|
|
@@ -3788,8 +4080,8 @@ openApiRegistry.registerPath({
|
|
|
3788
4080
|
path: `${REST_V1_PREFIX}/${REST_PATCH_PREVIEW_PATH}`,
|
|
3789
4081
|
summary: "Preview a patch prefix",
|
|
3790
4082
|
request: {
|
|
3791
|
-
params:
|
|
3792
|
-
patchId:
|
|
4083
|
+
params: z9.object({
|
|
4084
|
+
patchId: z9.string()
|
|
3793
4085
|
})
|
|
3794
4086
|
},
|
|
3795
4087
|
responses: {
|
|
@@ -3858,7 +4150,7 @@ openApiRegistry.registerPath({
|
|
|
3858
4150
|
description: "Default Response",
|
|
3859
4151
|
content: {
|
|
3860
4152
|
"text/html": {
|
|
3861
|
-
schema:
|
|
4153
|
+
schema: z9.string()
|
|
3862
4154
|
}
|
|
3863
4155
|
}
|
|
3864
4156
|
}
|
|
@@ -4612,7 +4904,7 @@ function renderHelpText() {
|
|
|
4612
4904
|
"",
|
|
4613
4905
|
"Launch modes:",
|
|
4614
4906
|
" init",
|
|
4615
|
-
" Prompts for a skills folder and installs bundled
|
|
4907
|
+
" Prompts for a skills folder and installs bundled ez-know skills.",
|
|
4616
4908
|
" Config: interactive terminal",
|
|
4617
4909
|
"",
|
|
4618
4910
|
" mcp",
|