@tangle-network/agent-knowledge 0.1.0 → 1.0.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/AGENTS.md +60 -0
- package/README.md +7 -0
- package/dist/{chunk-XDXIBHPS.js → chunk-WCUKMCAY.js} +228 -68
- package/dist/chunk-WCUKMCAY.js.map +1 -0
- package/dist/cli.js +26 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +275 -4
- package/dist/index.js +178 -1
- package/dist/index.js.map +1 -1
- package/dist/{types-C1FBNRIN.d.ts → types-CFylueZb.d.ts} +20 -2
- package/dist/viz/index.d.ts +1 -1
- package/docs/architecture.md +8 -0
- package/package.json +3 -2
- package/dist/chunk-XDXIBHPS.js.map +0 -1
package/AGENTS.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Agent Knowledge Operator Guide
|
|
2
|
+
|
|
3
|
+
Use this package when an agent needs persistent, source-grounded knowledge that improves over time.
|
|
4
|
+
|
|
5
|
+
## Rules
|
|
6
|
+
|
|
7
|
+
- Register sources before citing them: `agent-knowledge source-add <path>`.
|
|
8
|
+
- Generated pages live under `knowledge/`.
|
|
9
|
+
- Raw evidence lives under `raw/sources/` and should not be edited.
|
|
10
|
+
- Run `agent-knowledge index` after page changes.
|
|
11
|
+
- Run `agent-knowledge lint` before trusting or promoting knowledge.
|
|
12
|
+
- Treat `missing-source` lint findings as blocking.
|
|
13
|
+
- Use `--json` for automation.
|
|
14
|
+
|
|
15
|
+
## Common Commands
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
agent-knowledge init
|
|
19
|
+
agent-knowledge source-add ./source.md --json
|
|
20
|
+
agent-knowledge apply-write-blocks ./proposal.txt
|
|
21
|
+
agent-knowledge index --json
|
|
22
|
+
agent-knowledge search "query" --json
|
|
23
|
+
agent-knowledge inspect --json
|
|
24
|
+
agent-knowledge explain knowledge/concepts/example.md --json
|
|
25
|
+
agent-knowledge lint --json
|
|
26
|
+
agent-knowledge validate --strict --json
|
|
27
|
+
agent-knowledge viz --json
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Write Proposal Format
|
|
31
|
+
|
|
32
|
+
Agents should stage generated edits as FILE blocks:
|
|
33
|
+
|
|
34
|
+
```txt
|
|
35
|
+
---FILE: knowledge/concepts/example.md---
|
|
36
|
+
---
|
|
37
|
+
id: example
|
|
38
|
+
title: Example
|
|
39
|
+
sources:
|
|
40
|
+
- src_abc123
|
|
41
|
+
---
|
|
42
|
+
# Example
|
|
43
|
+
|
|
44
|
+
Sourced knowledge with links to [[Related Page]].
|
|
45
|
+
---END FILE---
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The parser rejects absolute paths, `..`, control characters, and writes outside `knowledge/`.
|
|
49
|
+
|
|
50
|
+
## Eval Boundary
|
|
51
|
+
|
|
52
|
+
Use `runKnowledgeBaseOptimization()` when comparing candidate knowledge bases on an actual task corpus. It delegates to `@tangle-network/agent-eval` multi-shot optimization, so single-turn and multi-turn agents share the same path.
|
|
53
|
+
|
|
54
|
+
Use `knowledgeReleaseReportFromOptimization()` before promotion. It projects optimizer traces and `RunRecord` rows into `agent-eval` release confidence evidence.
|
|
55
|
+
|
|
56
|
+
## Integration Boundaries
|
|
57
|
+
|
|
58
|
+
- Use `KbStore` for storage. Implement D1 in the consuming app when needed.
|
|
59
|
+
- Use `KnowledgeDiscoveryDispatcher` for research workers. Production apps should wire this to their own swarm/fleet runtime.
|
|
60
|
+
- Do not bypass `lint` or `validate` before using generated knowledge in an agent.
|
package/README.md
CHANGED
|
@@ -23,6 +23,8 @@ agent-knowledge inspect --root .
|
|
|
23
23
|
agent-knowledge explain knowledge/concepts/risk.md --root .
|
|
24
24
|
agent-knowledge graph --root . --format json
|
|
25
25
|
agent-knowledge lint --root .
|
|
26
|
+
agent-knowledge validate --strict --root .
|
|
27
|
+
agent-knowledge export --root . --format json
|
|
26
28
|
agent-knowledge viz --root .
|
|
27
29
|
```
|
|
28
30
|
|
|
@@ -47,6 +49,9 @@ knowledge/
|
|
|
47
49
|
- Lint fails on pages that cite unknown source IDs.
|
|
48
50
|
- Text sources get deterministic anchors (`all`, `l1`, `l51`, ...) for precise citations like `[^src_id#all]`.
|
|
49
51
|
- Agent write proposals can be safely applied with `apply-write-blocks`.
|
|
52
|
+
- `KbStore` keeps storage consumer-owned; use `MemoryKbStore`, `FileSystemKbStore`, or implement D1 in the app.
|
|
53
|
+
- Discovery uses worker/dispatcher contracts, with a local dispatcher for dev and tests.
|
|
54
|
+
- Zod schemas define the stable wire shape.
|
|
50
55
|
- Graph/search/lint are deterministic and fast.
|
|
51
56
|
- Optimization uses `@tangle-network/agent-eval` internally instead of reimplementing eval gates.
|
|
52
57
|
|
|
@@ -55,3 +60,5 @@ The `/viz` subpath exports graph insight helpers without UI dependencies.
|
|
|
55
60
|
## Agent-Eval Integration
|
|
56
61
|
|
|
57
62
|
Use `runKnowledgeBaseOptimization()` when the question is whether a candidate knowledge base actually improves agent task success. The candidate is passed through `runMultiShotOptimization`, so `n=1` single-turn tasks and variable-length multi-turn traces use the same path.
|
|
63
|
+
|
|
64
|
+
Use `knowledgeReleaseReportFromOptimization()` to turn optimizer output into release confidence evidence using `agent-eval` release gates and `RunRecord` validation.
|
|
@@ -215,6 +215,176 @@ async function applyKnowledgeWriteBlocksFile(root, proposalPath) {
|
|
|
215
215
|
return applyKnowledgeWriteBlocks(root, await readFile(proposalPath, "utf8"));
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
+
// src/schemas.ts
|
|
219
|
+
import { z } from "zod";
|
|
220
|
+
var SourceAnchorSchema = z.object({
|
|
221
|
+
id: z.string().min(1),
|
|
222
|
+
sourceId: z.string().min(1),
|
|
223
|
+
label: z.string().optional(),
|
|
224
|
+
page: z.number().int().positive().optional(),
|
|
225
|
+
lineStart: z.number().int().positive().optional(),
|
|
226
|
+
lineEnd: z.number().int().positive().optional(),
|
|
227
|
+
charStart: z.number().int().nonnegative().optional(),
|
|
228
|
+
charEnd: z.number().int().nonnegative().optional(),
|
|
229
|
+
timestampMs: z.number().nonnegative().optional(),
|
|
230
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
231
|
+
});
|
|
232
|
+
var SourceRecordSchema = z.object({
|
|
233
|
+
id: z.string().min(1),
|
|
234
|
+
uri: z.string().min(1),
|
|
235
|
+
title: z.string().optional(),
|
|
236
|
+
mediaType: z.string().optional(),
|
|
237
|
+
contentHash: z.string().min(16),
|
|
238
|
+
text: z.string().optional(),
|
|
239
|
+
anchors: z.array(SourceAnchorSchema).optional(),
|
|
240
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
241
|
+
createdAt: z.string().min(1)
|
|
242
|
+
});
|
|
243
|
+
var KnowledgePageSchema = z.object({
|
|
244
|
+
id: z.string().min(1),
|
|
245
|
+
path: z.string().min(1),
|
|
246
|
+
title: z.string().min(1),
|
|
247
|
+
text: z.string(),
|
|
248
|
+
frontmatter: z.record(z.string(), z.unknown()),
|
|
249
|
+
sourceIds: z.array(z.string()),
|
|
250
|
+
tags: z.array(z.string()),
|
|
251
|
+
outLinks: z.array(z.string())
|
|
252
|
+
});
|
|
253
|
+
var KnowledgeGraphNodeSchema = z.object({
|
|
254
|
+
id: z.string(),
|
|
255
|
+
title: z.string(),
|
|
256
|
+
path: z.string(),
|
|
257
|
+
tags: z.array(z.string()),
|
|
258
|
+
sourceIds: z.array(z.string()),
|
|
259
|
+
outDegree: z.number().int().nonnegative(),
|
|
260
|
+
inDegree: z.number().int().nonnegative()
|
|
261
|
+
});
|
|
262
|
+
var KnowledgeGraphEdgeSchema = z.object({
|
|
263
|
+
source: z.string(),
|
|
264
|
+
target: z.string(),
|
|
265
|
+
weight: z.number(),
|
|
266
|
+
reasons: z.array(z.string())
|
|
267
|
+
});
|
|
268
|
+
var KnowledgeIndexSchema = z.object({
|
|
269
|
+
root: z.string(),
|
|
270
|
+
generatedAt: z.string(),
|
|
271
|
+
sources: z.array(SourceRecordSchema),
|
|
272
|
+
pages: z.array(KnowledgePageSchema),
|
|
273
|
+
graph: z.object({
|
|
274
|
+
nodes: z.array(KnowledgeGraphNodeSchema),
|
|
275
|
+
edges: z.array(KnowledgeGraphEdgeSchema)
|
|
276
|
+
})
|
|
277
|
+
});
|
|
278
|
+
var KnowledgeEventSchema = z.object({
|
|
279
|
+
id: z.string().min(1),
|
|
280
|
+
type: z.enum(["source.added", "proposal.applied", "index.built", "lint.run", "optimization.run", "release.promoted", "release.rejected"]),
|
|
281
|
+
createdAt: z.string().min(1),
|
|
282
|
+
actor: z.string().optional(),
|
|
283
|
+
target: z.string().optional(),
|
|
284
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
285
|
+
});
|
|
286
|
+
var KnowledgeBaseCandidateSchema = z.object({
|
|
287
|
+
id: z.string().min(1),
|
|
288
|
+
units: z.array(z.object({
|
|
289
|
+
id: z.string().min(1),
|
|
290
|
+
title: z.string().min(1),
|
|
291
|
+
text: z.string(),
|
|
292
|
+
claims: z.array(z.object({
|
|
293
|
+
id: z.string().min(1),
|
|
294
|
+
text: z.string().min(1),
|
|
295
|
+
refs: z.array(z.object({
|
|
296
|
+
sourceId: z.string().min(1),
|
|
297
|
+
anchorId: z.string().optional(),
|
|
298
|
+
quote: z.string().optional()
|
|
299
|
+
})),
|
|
300
|
+
confidence: z.number().min(0).max(1).optional(),
|
|
301
|
+
status: z.enum(["draft", "active", "superseded", "rejected"]).optional(),
|
|
302
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
303
|
+
})).optional(),
|
|
304
|
+
relations: z.array(z.object({
|
|
305
|
+
sourceId: z.string(),
|
|
306
|
+
targetId: z.string(),
|
|
307
|
+
predicate: z.string(),
|
|
308
|
+
weight: z.number().optional(),
|
|
309
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
310
|
+
})).optional(),
|
|
311
|
+
sourceIds: z.array(z.string()).optional(),
|
|
312
|
+
tags: z.array(z.string()).optional(),
|
|
313
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
314
|
+
updatedAt: z.string().optional()
|
|
315
|
+
})),
|
|
316
|
+
retrievalPolicy: z.string().optional(),
|
|
317
|
+
synthesisPolicy: z.string().optional(),
|
|
318
|
+
questionPolicy: z.string().optional(),
|
|
319
|
+
updatePolicy: z.string().optional(),
|
|
320
|
+
metadata: z.record(z.string(), z.unknown()).optional()
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// src/graph.ts
|
|
324
|
+
function buildKnowledgeGraph(pages) {
|
|
325
|
+
const byId = /* @__PURE__ */ new Map();
|
|
326
|
+
const bySlug = /* @__PURE__ */ new Map();
|
|
327
|
+
for (const page of pages) {
|
|
328
|
+
byId.set(page.id, page);
|
|
329
|
+
bySlug.set(normalizeLinkTarget(page.id), page);
|
|
330
|
+
bySlug.set(normalizeLinkTarget(page.title), page);
|
|
331
|
+
bySlug.set(normalizeLinkTarget(page.path.split("/").pop().replace(/\.md$/, "")), page);
|
|
332
|
+
}
|
|
333
|
+
const incoming = /* @__PURE__ */ new Map();
|
|
334
|
+
const outgoing = /* @__PURE__ */ new Map();
|
|
335
|
+
const edgesByKey = /* @__PURE__ */ new Map();
|
|
336
|
+
for (const page of pages) {
|
|
337
|
+
outgoing.set(page.id, 0);
|
|
338
|
+
incoming.set(page.id, 0);
|
|
339
|
+
}
|
|
340
|
+
for (const page of pages) {
|
|
341
|
+
for (const raw of page.outLinks) {
|
|
342
|
+
const target = bySlug.get(normalizeLinkTarget(raw));
|
|
343
|
+
if (!target || target.id === page.id) continue;
|
|
344
|
+
const key = `${page.id}->${target.id}`;
|
|
345
|
+
const edge = edgesByKey.get(key);
|
|
346
|
+
if (edge) edge.weight += 1;
|
|
347
|
+
else edgesByKey.set(key, { source: page.id, target: target.id, weight: 1, reasons: ["wikilink"] });
|
|
348
|
+
outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1);
|
|
349
|
+
incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
addSourceOverlapEdges(pages, edgesByKey);
|
|
353
|
+
const nodes = pages.map((page) => ({
|
|
354
|
+
id: page.id,
|
|
355
|
+
title: page.title,
|
|
356
|
+
path: page.path,
|
|
357
|
+
tags: page.tags,
|
|
358
|
+
sourceIds: page.sourceIds,
|
|
359
|
+
outDegree: outgoing.get(page.id) ?? 0,
|
|
360
|
+
inDegree: incoming.get(page.id) ?? 0
|
|
361
|
+
}));
|
|
362
|
+
return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) };
|
|
363
|
+
}
|
|
364
|
+
function addSourceOverlapEdges(pages, edges) {
|
|
365
|
+
for (let i = 0; i < pages.length; i++) {
|
|
366
|
+
for (let j = i + 1; j < pages.length; j++) {
|
|
367
|
+
const a = pages[i];
|
|
368
|
+
const b = pages[j];
|
|
369
|
+
const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source));
|
|
370
|
+
if (overlap.length === 0) continue;
|
|
371
|
+
const key = `${a.id}->${b.id}`;
|
|
372
|
+
const edge = edges.get(key);
|
|
373
|
+
if (edge) {
|
|
374
|
+
edge.weight += overlap.length * 0.5;
|
|
375
|
+
edge.reasons.push("shared-source");
|
|
376
|
+
} else {
|
|
377
|
+
edges.set(key, {
|
|
378
|
+
source: a.id,
|
|
379
|
+
target: b.id,
|
|
380
|
+
weight: overlap.length * 0.5,
|
|
381
|
+
reasons: ["shared-source"]
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
218
388
|
// src/store.ts
|
|
219
389
|
import { mkdir as mkdir2, readFile as readFile2, readdir, stat, writeFile as writeFile2 } from "fs/promises";
|
|
220
390
|
import { dirname as dirname2, join as join2, relative } from "path";
|
|
@@ -400,71 +570,6 @@ function textPreview(fileName, bytes) {
|
|
|
400
570
|
return bytes.toString("utf8").slice(0, 2e5);
|
|
401
571
|
}
|
|
402
572
|
|
|
403
|
-
// src/graph.ts
|
|
404
|
-
function buildKnowledgeGraph(pages) {
|
|
405
|
-
const byId = /* @__PURE__ */ new Map();
|
|
406
|
-
const bySlug = /* @__PURE__ */ new Map();
|
|
407
|
-
for (const page of pages) {
|
|
408
|
-
byId.set(page.id, page);
|
|
409
|
-
bySlug.set(normalizeLinkTarget(page.id), page);
|
|
410
|
-
bySlug.set(normalizeLinkTarget(page.title), page);
|
|
411
|
-
bySlug.set(normalizeLinkTarget(page.path.split("/").pop().replace(/\.md$/, "")), page);
|
|
412
|
-
}
|
|
413
|
-
const incoming = /* @__PURE__ */ new Map();
|
|
414
|
-
const outgoing = /* @__PURE__ */ new Map();
|
|
415
|
-
const edgesByKey = /* @__PURE__ */ new Map();
|
|
416
|
-
for (const page of pages) {
|
|
417
|
-
outgoing.set(page.id, 0);
|
|
418
|
-
incoming.set(page.id, 0);
|
|
419
|
-
}
|
|
420
|
-
for (const page of pages) {
|
|
421
|
-
for (const raw of page.outLinks) {
|
|
422
|
-
const target = bySlug.get(normalizeLinkTarget(raw));
|
|
423
|
-
if (!target || target.id === page.id) continue;
|
|
424
|
-
const key = `${page.id}->${target.id}`;
|
|
425
|
-
const edge = edgesByKey.get(key);
|
|
426
|
-
if (edge) edge.weight += 1;
|
|
427
|
-
else edgesByKey.set(key, { source: page.id, target: target.id, weight: 1, reasons: ["wikilink"] });
|
|
428
|
-
outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1);
|
|
429
|
-
incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1);
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
addSourceOverlapEdges(pages, edgesByKey);
|
|
433
|
-
const nodes = pages.map((page) => ({
|
|
434
|
-
id: page.id,
|
|
435
|
-
title: page.title,
|
|
436
|
-
path: page.path,
|
|
437
|
-
tags: page.tags,
|
|
438
|
-
sourceIds: page.sourceIds,
|
|
439
|
-
outDegree: outgoing.get(page.id) ?? 0,
|
|
440
|
-
inDegree: incoming.get(page.id) ?? 0
|
|
441
|
-
}));
|
|
442
|
-
return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) };
|
|
443
|
-
}
|
|
444
|
-
function addSourceOverlapEdges(pages, edges) {
|
|
445
|
-
for (let i = 0; i < pages.length; i++) {
|
|
446
|
-
for (let j = i + 1; j < pages.length; j++) {
|
|
447
|
-
const a = pages[i];
|
|
448
|
-
const b = pages[j];
|
|
449
|
-
const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source));
|
|
450
|
-
if (overlap.length === 0) continue;
|
|
451
|
-
const key = `${a.id}->${b.id}`;
|
|
452
|
-
const edge = edges.get(key);
|
|
453
|
-
if (edge) {
|
|
454
|
-
edge.weight += overlap.length * 0.5;
|
|
455
|
-
edge.reasons.push("shared-source");
|
|
456
|
-
} else {
|
|
457
|
-
edges.set(key, {
|
|
458
|
-
source: a.id,
|
|
459
|
-
target: b.id,
|
|
460
|
-
weight: overlap.length * 0.5,
|
|
461
|
-
reasons: ["shared-source"]
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
573
|
// src/search.ts
|
|
469
574
|
var RRF_K = 60;
|
|
470
575
|
var STOP_WORDS = /* @__PURE__ */ new Set(["the", "is", "a", "an", "what", "how", "are", "was", "were", "to", "for", "of", "with", "by", "in", "on", "and"]);
|
|
@@ -579,13 +684,19 @@ function lintKnowledgeIndex(index) {
|
|
|
579
684
|
const titles = /* @__PURE__ */ new Map();
|
|
580
685
|
const sourceIds = new Set(index.sources.map((source) => source.id));
|
|
581
686
|
const anchorIds = new Map(index.sources.map((source) => [source.id, new Set((source.anchors ?? []).map((anchor) => anchor.id))]));
|
|
687
|
+
const pageIds = /* @__PURE__ */ new Map();
|
|
688
|
+
const sourceHashes = /* @__PURE__ */ new Map();
|
|
582
689
|
for (const page of index.pages) {
|
|
690
|
+
pageIds.set(page.id, [...pageIds.get(page.id) ?? [], page.path]);
|
|
583
691
|
byTarget.add(normalizeLinkTarget(page.id));
|
|
584
692
|
byTarget.add(normalizeLinkTarget(page.title));
|
|
585
693
|
byTarget.add(normalizeLinkTarget(page.path.split("/").pop().replace(/\.md$/, "")));
|
|
586
694
|
const titleKey = page.title.toLowerCase();
|
|
587
695
|
titles.set(titleKey, [...titles.get(titleKey) ?? [], page.path]);
|
|
588
696
|
}
|
|
697
|
+
for (const source of index.sources) {
|
|
698
|
+
sourceHashes.set(source.contentHash, [...sourceHashes.get(source.contentHash) ?? [], source.id]);
|
|
699
|
+
}
|
|
589
700
|
const inbound = /* @__PURE__ */ new Map();
|
|
590
701
|
for (const page of index.pages) inbound.set(page.id, 0);
|
|
591
702
|
for (const page of index.pages) {
|
|
@@ -624,6 +735,16 @@ function lintKnowledgeIndex(index) {
|
|
|
624
735
|
findings.push({ type: "duplicate-title", severity: "warning", message: `Duplicate title "${title}" in ${paths.join(", ")}.`, metadata: { paths } });
|
|
625
736
|
}
|
|
626
737
|
}
|
|
738
|
+
for (const [id, paths] of pageIds) {
|
|
739
|
+
if (id && paths.length > 1) {
|
|
740
|
+
findings.push({ type: "duplicate-page-id", severity: "error", message: `Duplicate page id "${id}" in ${paths.join(", ")}.`, metadata: { paths } });
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
for (const [hash, ids] of sourceHashes) {
|
|
744
|
+
if (hash && ids.length > 1) {
|
|
745
|
+
findings.push({ type: "duplicate-source-hash", severity: "warning", message: `Duplicate source content hash across ${ids.join(", ")}.`, metadata: { sourceIds: ids } });
|
|
746
|
+
}
|
|
747
|
+
}
|
|
627
748
|
return findings;
|
|
628
749
|
}
|
|
629
750
|
function isStructural(path) {
|
|
@@ -667,6 +788,36 @@ function explainKnowledgeTarget(index, target) {
|
|
|
667
788
|
};
|
|
668
789
|
}
|
|
669
790
|
|
|
791
|
+
// src/validate.ts
|
|
792
|
+
function validateKnowledgeIndex(index, options = {}) {
|
|
793
|
+
const findings = [...lintKnowledgeIndex(index)];
|
|
794
|
+
const parsed = KnowledgeIndexSchema.safeParse(index);
|
|
795
|
+
if (!parsed.success) {
|
|
796
|
+
findings.push({
|
|
797
|
+
type: "missing-frontmatter",
|
|
798
|
+
severity: "error",
|
|
799
|
+
message: parsed.error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join("; ")
|
|
800
|
+
});
|
|
801
|
+
}
|
|
802
|
+
if (options.strict) {
|
|
803
|
+
for (const page of index.pages) {
|
|
804
|
+
if (isStructuralPage(page.path)) continue;
|
|
805
|
+
if (!page.frontmatter.id || !page.frontmatter.title) {
|
|
806
|
+
findings.push({
|
|
807
|
+
type: "missing-frontmatter",
|
|
808
|
+
severity: "error",
|
|
809
|
+
page: page.path,
|
|
810
|
+
message: "Strict mode requires id and title frontmatter."
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
return { ok: !findings.some((finding) => finding.severity === "error"), findings };
|
|
816
|
+
}
|
|
817
|
+
function isStructuralPage(path) {
|
|
818
|
+
return path === "knowledge/index.md" || path === "knowledge/log.md" || path.endsWith("/index.md") || path.endsWith("/log.md");
|
|
819
|
+
}
|
|
820
|
+
|
|
670
821
|
export {
|
|
671
822
|
sha256,
|
|
672
823
|
slugify,
|
|
@@ -682,6 +833,15 @@ export {
|
|
|
682
833
|
mediaTypeFor,
|
|
683
834
|
applyKnowledgeWriteBlocks,
|
|
684
835
|
applyKnowledgeWriteBlocksFile,
|
|
836
|
+
SourceAnchorSchema,
|
|
837
|
+
SourceRecordSchema,
|
|
838
|
+
KnowledgePageSchema,
|
|
839
|
+
KnowledgeGraphNodeSchema,
|
|
840
|
+
KnowledgeGraphEdgeSchema,
|
|
841
|
+
KnowledgeIndexSchema,
|
|
842
|
+
KnowledgeEventSchema,
|
|
843
|
+
KnowledgeBaseCandidateSchema,
|
|
844
|
+
buildKnowledgeGraph,
|
|
685
845
|
layoutFor,
|
|
686
846
|
initKnowledgeBase,
|
|
687
847
|
loadKnowledgePages,
|
|
@@ -690,7 +850,6 @@ export {
|
|
|
690
850
|
writeSourceRegistry,
|
|
691
851
|
addSourcePath,
|
|
692
852
|
sourceRegistryPath,
|
|
693
|
-
buildKnowledgeGraph,
|
|
694
853
|
searchKnowledge,
|
|
695
854
|
tokenizeQuery,
|
|
696
855
|
reciprocalRankFusion,
|
|
@@ -698,6 +857,7 @@ export {
|
|
|
698
857
|
writeKnowledgeIndex,
|
|
699
858
|
lintKnowledgeIndex,
|
|
700
859
|
inspectKnowledgeIndex,
|
|
701
|
-
explainKnowledgeTarget
|
|
860
|
+
explainKnowledgeTarget,
|
|
861
|
+
validateKnowledgeIndex
|
|
702
862
|
};
|
|
703
|
-
//# sourceMappingURL=chunk-
|
|
863
|
+
//# sourceMappingURL=chunk-WCUKMCAY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ids.ts","../src/frontmatter.ts","../src/wikilinks.ts","../src/write-protocol.ts","../src/adapters.ts","../src/proposals.ts","../src/schemas.ts","../src/graph.ts","../src/store.ts","../src/sources.ts","../src/search.ts","../src/indexer.ts","../src/lint.ts","../src/inspect.ts","../src/validate.ts"],"sourcesContent":["import { createHash } from 'node:crypto'\n\nexport function sha256(text: string): string {\n return createHash('sha256').update(text).digest('hex')\n}\n\nexport function slugify(input: string): string {\n const out = input\n .trim()\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/[^a-z0-9\\u4e00-\\u9fff]+/g, '-')\n .replace(/^-+|-+$/g, '')\n return out || 'untitled'\n}\n\nexport function stableId(prefix: string, content: string): string {\n return `${prefix}_${sha256(content).slice(0, 16)}`\n}\n","export interface ParsedFrontmatter {\n frontmatter: Record<string, unknown>\n body: string\n}\n\nexport function parseFrontmatter(content: string): ParsedFrontmatter {\n const normalized = content.replace(/\\r\\n/g, '\\n')\n if (!normalized.startsWith('---\\n')) return { frontmatter: {}, body: normalized }\n const end = normalized.indexOf('\\n---', 4)\n if (end < 0) return { frontmatter: {}, body: normalized }\n const raw = normalized.slice(4, end)\n const after = normalized.slice(end).replace(/^\\n---\\s*\\n?/, '')\n return { frontmatter: parseSimpleYaml(raw), body: after }\n}\n\nexport function formatFrontmatter(frontmatter: Record<string, unknown>, body: string): string {\n const lines = Object.entries(frontmatter)\n .filter(([, value]) => value !== undefined)\n .flatMap(([key, value]) => formatYamlField(key, value))\n if (lines.length === 0) return body\n return `---\\n${lines.join('\\n')}\\n---\\n${body.replace(/^\\n+/, '')}`\n}\n\nfunction parseSimpleYaml(raw: string): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n const lines = raw.split('\\n')\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i]!\n const scalar = /^([A-Za-z0-9_-]+):\\s*(.*)$/.exec(line)\n if (!scalar) continue\n const key = scalar[1]!\n const rest = scalar[2]!.trim()\n if (rest === '') {\n const items: string[] = []\n while (i + 1 < lines.length) {\n const item = /^\\s*-\\s*(.+?)\\s*$/.exec(lines[i + 1]!)\n if (!item) break\n items.push(unquote(item[1]!))\n i++\n }\n out[key] = items\n continue\n }\n if (rest.startsWith('[') && rest.endsWith(']')) {\n out[key] = rest.slice(1, -1).split(',').map((part) => unquote(part.trim())).filter(Boolean)\n } else if (rest === 'true' || rest === 'false') {\n out[key] = rest === 'true'\n } else if (/^-?\\d+(?:\\.\\d+)?$/.test(rest)) {\n out[key] = Number(rest)\n } else {\n out[key] = unquote(rest)\n }\n }\n return out\n}\n\nfunction formatYamlField(key: string, value: unknown): string[] {\n if (Array.isArray(value)) {\n return [key + ':', ...value.map((item) => ` - ${String(item)}`)]\n }\n if (typeof value === 'string') return [`${key}: ${value}`]\n if (typeof value === 'number' || typeof value === 'boolean') return [`${key}: ${String(value)}`]\n return [`${key}: ${JSON.stringify(value)}`]\n}\n\nfunction unquote(value: string): string {\n return value.replace(/^['\"]|['\"]$/g, '')\n}\n","export const WIKILINK_REGEX = /\\[\\[([^\\]|]+?)(?:\\|[^\\]]+?)?\\]\\]/g\n\nexport function extractWikilinks(content: string): string[] {\n const links: string[] = []\n const regex = new RegExp(WIKILINK_REGEX.source, 'g')\n let match: RegExpExecArray | null\n while ((match = regex.exec(content)) !== null) {\n links.push(match[1]!.trim())\n }\n return [...new Set(links)]\n}\n\nexport function normalizeLinkTarget(target: string): string {\n return target.trim().replace(/\\.md$/i, '').toLowerCase().replace(/\\s+/g, '-')\n}\n","import type { KnowledgeWriteParseResult } from './types'\n\nconst OPENER_LINE = /^---\\s*FILE:\\s*(.+?)\\s*---\\s*$/i\nconst CLOSER_LINE = /^---\\s*END\\s+FILE\\s*---\\s*$/i\nconst FENCE_LINE = /^\\s{0,3}(```+|~~~+)/\n\nexport function isSafeKnowledgePath(path: string, allowedPrefixes = ['knowledge/']): boolean {\n if (typeof path !== 'string' || path.trim() === '') return false\n if (/[\\x00-\\x1f]/.test(path)) return false\n if (path.startsWith('/') || path.startsWith('\\\\')) return false\n if (/^[a-zA-Z]:/.test(path)) return false\n const normalized = path.replace(/\\\\/g, '/')\n if (normalized.split('/').some((part) => part === '..')) return false\n return allowedPrefixes.some((prefix) => normalized.startsWith(prefix))\n}\n\nexport function parseKnowledgeWriteBlocks(text: string, allowedPrefixes = ['knowledge/']): KnowledgeWriteParseResult {\n const lines = text.replace(/\\r\\n/g, '\\n').split('\\n')\n const blocks: KnowledgeWriteParseResult['blocks'] = []\n const warnings: string[] = []\n let i = 0\n\n while (i < lines.length) {\n const opener = OPENER_LINE.exec(lines[i]!)\n if (!opener) {\n i++\n continue\n }\n const path = opener[1]!.trim()\n i++\n const contentLines: string[] = []\n let fenceMarker: string | null = null\n let fenceLen = 0\n let closed = false\n\n while (i < lines.length) {\n const line = lines[i]!\n const fence = FENCE_LINE.exec(line)\n if (fence) {\n const run = fence[1]!\n const char = run[0]!\n if (fenceMarker === null) {\n fenceMarker = char\n fenceLen = run.length\n } else if (char === fenceMarker && run.length >= fenceLen) {\n fenceMarker = null\n fenceLen = 0\n }\n contentLines.push(line)\n i++\n continue\n }\n if (fenceMarker === null && CLOSER_LINE.test(line)) {\n closed = true\n i++\n break\n }\n contentLines.push(line)\n i++\n }\n\n if (!closed) {\n warnings.push(`FILE block \"${path || '(empty)'}\" was not closed before end of stream.`)\n continue\n }\n if (!isSafeKnowledgePath(path, allowedPrefixes)) {\n warnings.push(`FILE block with unsafe path \"${path}\" rejected.`)\n continue\n }\n blocks.push({ path, content: contentLines.join('\\n') })\n }\n\n return { blocks, warnings }\n}\n","import type { SourceRecord } from './types'\n\nexport interface SourceAdapterInput {\n uri: string\n bytes?: Uint8Array\n text?: string\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapterOutput {\n title?: string\n mediaType?: string\n text?: string\n anchors?: SourceRecord['anchors']\n metadata?: Record<string, unknown>\n}\n\nexport interface SourceAdapter {\n id: string\n canLoad(input: SourceAdapterInput): boolean\n load(input: SourceAdapterInput): Promise<SourceAdapterOutput> | SourceAdapterOutput\n}\n\nexport const textSourceAdapter: SourceAdapter = {\n id: 'text',\n canLoad: (input) => Boolean(input.text) || /\\.(md|txt|json|csv)$/i.test(input.uri),\n load: (input) => ({\n title: input.uri.split('/').pop(),\n mediaType: mediaTypeFor(input.uri),\n text: decodeText(input),\n anchors: anchorsForText(input.uri, decodeText(input)),\n metadata: input.metadata,\n }),\n}\n\nexport function mediaTypeFor(uri: string): string {\n const lower = uri.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction decodeText(input: SourceAdapterInput): string | undefined {\n return input.text ?? (input.bytes ? new TextDecoder().decode(input.bytes).slice(0, 200_000) : undefined)\n}\n\nfunction anchorsForText(uri: string, text: string | undefined): SourceAdapterOutput['anchors'] {\n if (!text) return []\n const lines = text.split('\\n')\n const anchors: NonNullable<SourceAdapterOutput['anchors']> = [{ id: 'all', sourceId: '', label: 'Full source', lineStart: 1, lineEnd: lines.length }]\n for (let i = 0; i < lines.length; i += 50) {\n anchors.push({\n id: `l${i + 1}`,\n sourceId: '',\n label: `${uri}:${i + 1}`,\n lineStart: i + 1,\n lineEnd: Math.min(lines.length, i + 50),\n })\n }\n return anchors\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { dirname, join } from 'node:path'\nimport { parseKnowledgeWriteBlocks } from './write-protocol'\n\nexport interface ApplyWriteBlocksResult {\n written: string[]\n warnings: string[]\n}\n\nexport async function applyKnowledgeWriteBlocks(\n root: string,\n proposalText: string,\n): Promise<ApplyWriteBlocksResult> {\n const parsed = parseKnowledgeWriteBlocks(proposalText)\n const written: string[] = []\n for (const block of parsed.blocks) {\n const path = join(root, block.path)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, block.content.endsWith('\\n') ? block.content : `${block.content}\\n`, 'utf8')\n written.push(block.path)\n }\n return { written, warnings: parsed.warnings }\n}\n\nexport async function applyKnowledgeWriteBlocksFile(root: string, proposalPath: string): Promise<ApplyWriteBlocksResult> {\n return applyKnowledgeWriteBlocks(root, await readFile(proposalPath, 'utf8'))\n}\n","import { z } from 'zod'\n\nexport const SourceAnchorSchema = z.object({\n id: z.string().min(1),\n sourceId: z.string().min(1),\n label: z.string().optional(),\n page: z.number().int().positive().optional(),\n lineStart: z.number().int().positive().optional(),\n lineEnd: z.number().int().positive().optional(),\n charStart: z.number().int().nonnegative().optional(),\n charEnd: z.number().int().nonnegative().optional(),\n timestampMs: z.number().nonnegative().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const SourceRecordSchema = z.object({\n id: z.string().min(1),\n uri: z.string().min(1),\n title: z.string().optional(),\n mediaType: z.string().optional(),\n contentHash: z.string().min(16),\n text: z.string().optional(),\n anchors: z.array(SourceAnchorSchema).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n createdAt: z.string().min(1),\n})\n\nexport const KnowledgePageSchema = z.object({\n id: z.string().min(1),\n path: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n frontmatter: z.record(z.string(), z.unknown()),\n sourceIds: z.array(z.string()),\n tags: z.array(z.string()),\n outLinks: z.array(z.string()),\n})\n\nexport const KnowledgeGraphNodeSchema = z.object({\n id: z.string(),\n title: z.string(),\n path: z.string(),\n tags: z.array(z.string()),\n sourceIds: z.array(z.string()),\n outDegree: z.number().int().nonnegative(),\n inDegree: z.number().int().nonnegative(),\n})\n\nexport const KnowledgeGraphEdgeSchema = z.object({\n source: z.string(),\n target: z.string(),\n weight: z.number(),\n reasons: z.array(z.string()),\n})\n\nexport const KnowledgeIndexSchema = z.object({\n root: z.string(),\n generatedAt: z.string(),\n sources: z.array(SourceRecordSchema),\n pages: z.array(KnowledgePageSchema),\n graph: z.object({\n nodes: z.array(KnowledgeGraphNodeSchema),\n edges: z.array(KnowledgeGraphEdgeSchema),\n }),\n})\n\nexport const KnowledgeEventSchema = z.object({\n id: z.string().min(1),\n type: z.enum(['source.added', 'proposal.applied', 'index.built', 'lint.run', 'optimization.run', 'release.promoted', 'release.rejected']),\n createdAt: z.string().min(1),\n actor: z.string().optional(),\n target: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n\nexport const KnowledgeBaseCandidateSchema = z.object({\n id: z.string().min(1),\n units: z.array(z.object({\n id: z.string().min(1),\n title: z.string().min(1),\n text: z.string(),\n claims: z.array(z.object({\n id: z.string().min(1),\n text: z.string().min(1),\n refs: z.array(z.object({\n sourceId: z.string().min(1),\n anchorId: z.string().optional(),\n quote: z.string().optional(),\n })),\n confidence: z.number().min(0).max(1).optional(),\n status: z.enum(['draft', 'active', 'superseded', 'rejected']).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n relations: z.array(z.object({\n sourceId: z.string(),\n targetId: z.string(),\n predicate: z.string(),\n weight: z.number().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n })).optional(),\n sourceIds: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n updatedAt: z.string().optional(),\n })),\n retrievalPolicy: z.string().optional(),\n synthesisPolicy: z.string().optional(),\n questionPolicy: z.string().optional(),\n updatePolicy: z.string().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n})\n","import type { KnowledgeGraph, KnowledgeGraphEdge, KnowledgeGraphNode, KnowledgePage } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function buildKnowledgeGraph(pages: KnowledgePage[]): KnowledgeGraph {\n const byId = new Map<string, KnowledgePage>()\n const bySlug = new Map<string, KnowledgePage>()\n for (const page of pages) {\n byId.set(page.id, page)\n bySlug.set(normalizeLinkTarget(page.id), page)\n bySlug.set(normalizeLinkTarget(page.title), page)\n bySlug.set(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')), page)\n }\n\n const incoming = new Map<string, number>()\n const outgoing = new Map<string, number>()\n const edgesByKey = new Map<string, KnowledgeGraphEdge>()\n for (const page of pages) {\n outgoing.set(page.id, 0)\n incoming.set(page.id, 0)\n }\n\n for (const page of pages) {\n for (const raw of page.outLinks) {\n const target = bySlug.get(normalizeLinkTarget(raw))\n if (!target || target.id === page.id) continue\n const key = `${page.id}->${target.id}`\n const edge = edgesByKey.get(key)\n if (edge) edge.weight += 1\n else edgesByKey.set(key, { source: page.id, target: target.id, weight: 1, reasons: ['wikilink'] })\n outgoing.set(page.id, (outgoing.get(page.id) ?? 0) + 1)\n incoming.set(target.id, (incoming.get(target.id) ?? 0) + 1)\n }\n }\n\n addSourceOverlapEdges(pages, edgesByKey)\n\n const nodes: KnowledgeGraphNode[] = pages.map((page) => ({\n id: page.id,\n title: page.title,\n path: page.path,\n tags: page.tags,\n sourceIds: page.sourceIds,\n outDegree: outgoing.get(page.id) ?? 0,\n inDegree: incoming.get(page.id) ?? 0,\n }))\n return { nodes, edges: [...edgesByKey.values()].sort((a, b) => b.weight - a.weight) }\n}\n\nfunction addSourceOverlapEdges(pages: KnowledgePage[], edges: Map<string, KnowledgeGraphEdge>): void {\n for (let i = 0; i < pages.length; i++) {\n for (let j = i + 1; j < pages.length; j++) {\n const a = pages[i]!\n const b = pages[j]!\n const overlap = a.sourceIds.filter((source) => b.sourceIds.includes(source))\n if (overlap.length === 0) continue\n const key = `${a.id}->${b.id}`\n const edge = edges.get(key)\n if (edge) {\n edge.weight += overlap.length * 0.5\n edge.reasons.push('shared-source')\n } else {\n edges.set(key, {\n source: a.id,\n target: b.id,\n weight: overlap.length * 0.5,\n reasons: ['shared-source'],\n })\n }\n }\n }\n}\n","import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { dirname, join, relative } from 'node:path'\nimport type { KnowledgePage } from './types'\nimport { parseFrontmatter } from './frontmatter'\nimport { slugify } from './ids'\nimport { extractWikilinks, normalizeLinkTarget } from './wikilinks'\n\nexport interface KnowledgeLayout {\n root: string\n knowledgeDir: string\n rawSourcesDir: string\n sourceRegistryPath: string\n indexPath: string\n logPath: string\n cacheDir: string\n}\n\nexport function layoutFor(root: string): KnowledgeLayout {\n return {\n root,\n knowledgeDir: join(root, 'knowledge'),\n rawSourcesDir: join(root, 'raw', 'sources'),\n sourceRegistryPath: join(root, '.agent-knowledge', 'sources.json'),\n indexPath: join(root, 'knowledge', 'index.md'),\n logPath: join(root, 'knowledge', 'log.md'),\n cacheDir: join(root, '.agent-knowledge'),\n }\n}\n\nexport async function initKnowledgeBase(root: string): Promise<KnowledgeLayout> {\n const layout = layoutFor(root)\n await mkdir(layout.knowledgeDir, { recursive: true })\n await mkdir(layout.rawSourcesDir, { recursive: true })\n await mkdir(layout.cacheDir, { recursive: true })\n await writeIfMissing(layout.indexPath, '# Knowledge Index\\n\\n')\n await writeIfMissing(layout.logPath, '# Knowledge Log\\n\\n')\n await writeIfMissing(layout.sourceRegistryPath, '{\\n \"generatedAt\": \"1970-01-01T00:00:00.000Z\",\\n \"sources\": []\\n}\\n')\n return layout\n}\n\nexport async function loadKnowledgePages(root: string): Promise<KnowledgePage[]> {\n const layout = layoutFor(root)\n const files = await listMarkdownFiles(layout.knowledgeDir)\n const pages: KnowledgePage[] = []\n for (const file of files) {\n const content = await readFile(file, 'utf8')\n const { frontmatter, body } = parseFrontmatter(content)\n const rel = relative(root, file).replace(/\\\\/g, '/')\n const title = stringField(frontmatter.title) ?? firstHeading(body) ?? rel.split('/').pop()!.replace(/\\.md$/, '')\n const sourceIds = arrayField(frontmatter.sources)\n const tags = arrayField(frontmatter.tags)\n pages.push({\n id: stringField(frontmatter.id) ?? slugify(rel.replace(/^knowledge\\//, '').replace(/\\.md$/, '')),\n path: rel,\n title,\n text: body,\n frontmatter,\n sourceIds,\n tags,\n outLinks: extractWikilinks(body).map(normalizeLinkTarget),\n })\n }\n pages.sort((a, b) => a.path.localeCompare(b.path))\n return pages\n}\n\nexport async function writeJson(path: string, value: unknown): Promise<void> {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(value, null, 2) + '\\n', 'utf8')\n}\n\nasync function writeIfMissing(path: string, content: string): Promise<void> {\n try {\n await stat(path)\n } catch {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, content, 'utf8')\n }\n}\n\nasync function listMarkdownFiles(root: string): Promise<string[]> {\n try {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listMarkdownFiles(full))\n else if (entry.isFile() && entry.name.endsWith('.md')) out.push(full)\n }\n return out\n } catch {\n return []\n }\n}\n\nfunction stringField(value: unknown): string | undefined {\n return typeof value === 'string' && value.trim() !== '' ? value.trim() : undefined\n}\n\nfunction arrayField(value: unknown): string[] {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : []\n}\n\nfunction firstHeading(body: string): string | undefined {\n return /^#\\s+(.+)$/m.exec(body)?.[1]?.trim()\n}\n","import { copyFile, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { basename, dirname, join, relative } from 'node:path'\nimport { textSourceAdapter, type SourceAdapter } from './adapters'\nimport type { SourceRecord, SourceRegistry } from './types'\nimport { sha256, slugify, stableId } from './ids'\nimport { layoutFor } from './store'\n\nexport interface AddSourceOptions {\n copyIntoRaw?: boolean\n adapters?: SourceAdapter[]\n now?: () => Date\n}\n\nexport async function loadSourceRegistry(root: string): Promise<SourceRegistry> {\n const path = sourceRegistryPath(root)\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as SourceRegistry\n return {\n generatedAt: typeof parsed.generatedAt === 'string' ? parsed.generatedAt : new Date(0).toISOString(),\n sources: Array.isArray(parsed.sources) ? parsed.sources : [],\n }\n } catch {\n return { generatedAt: new Date(0).toISOString(), sources: [] }\n }\n}\n\nexport async function writeSourceRegistry(root: string, registry: SourceRegistry): Promise<void> {\n const path = sourceRegistryPath(root)\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, JSON.stringify(registry, null, 2) + '\\n', 'utf8')\n}\n\nexport async function addSourcePath(root: string, sourcePath: string, options: AddSourceOptions = {}): Promise<SourceRecord[]> {\n const s = await stat(sourcePath)\n if (s.isDirectory()) {\n const out: SourceRecord[] = []\n for (const file of await listFiles(sourcePath)) {\n out.push(...await addSourcePath(root, file, options))\n }\n return out\n }\n\n const layout = layoutFor(root)\n await mkdir(layout.rawSourcesDir, { recursive: true })\n const bytes = await readFile(sourcePath)\n const contentHash = sha256(bytes.toString('base64'))\n const fileName = basename(sourcePath)\n const adapters = options.adapters ?? [textSourceAdapter]\n const adapter = adapters.find((candidate) => candidate.canLoad({ uri: sourcePath, bytes }))\n const loaded = adapter ? await adapter.load({ uri: sourcePath, bytes }) : {}\n const id = stableId('src', `${contentHash}:${fileName}`)\n const targetRel = join('raw', 'sources', `${slugify(fileName.replace(/\\.[^.]+$/, ''))}-${contentHash.slice(0, 8)}${ext(fileName)}`).replace(/\\\\/g, '/')\n const targetAbs = join(root, targetRel)\n\n if (options.copyIntoRaw ?? true) {\n await mkdir(dirname(targetAbs), { recursive: true })\n await copyFile(sourcePath, targetAbs)\n }\n\n const existing = await loadSourceRegistry(root)\n const record: SourceRecord = {\n id,\n uri: targetRel,\n title: loaded.title ?? fileName,\n mediaType: loaded.mediaType ?? mediaTypeFor(fileName),\n contentHash,\n text: loaded.text ?? textPreview(fileName, bytes),\n anchors: (loaded.anchors ?? []).map((anchor) => ({ ...anchor, sourceId: id })),\n createdAt: (options.now ?? (() => new Date()))().toISOString(),\n metadata: {\n ...(loaded.metadata ?? {}),\n originalPath: sourcePath,\n sizeBytes: bytes.length,\n projectRelativePath: relative(root, sourcePath).replace(/\\\\/g, '/'),\n },\n }\n const next: SourceRegistry = {\n generatedAt: new Date().toISOString(),\n sources: [record, ...existing.sources.filter((source) => source.id !== id)],\n }\n await writeSourceRegistry(root, next)\n return [record]\n}\n\nexport function sourceRegistryPath(root: string): string {\n return join(layoutFor(root).cacheDir, 'sources.json')\n}\n\nasync function listFiles(root: string): Promise<string[]> {\n const entries = await readdir(root, { withFileTypes: true })\n const out: string[] = []\n for (const entry of entries) {\n const full = join(root, entry.name)\n if (entry.isDirectory()) out.push(...await listFiles(full))\n else if (entry.isFile()) out.push(full)\n }\n return out\n}\n\nfunction ext(fileName: string): string {\n const idx = fileName.lastIndexOf('.')\n return idx >= 0 ? fileName.slice(idx) : ''\n}\n\nfunction mediaTypeFor(fileName: string): string {\n const lower = fileName.toLowerCase()\n if (lower.endsWith('.md')) return 'text/markdown'\n if (lower.endsWith('.txt')) return 'text/plain'\n if (lower.endsWith('.json')) return 'application/json'\n if (lower.endsWith('.csv')) return 'text/csv'\n if (lower.endsWith('.pdf')) return 'application/pdf'\n return 'application/octet-stream'\n}\n\nfunction textPreview(fileName: string, bytes: Buffer): string | undefined {\n const mediaType = mediaTypeFor(fileName)\n if (!mediaType.startsWith('text/') && mediaType !== 'application/json') return undefined\n return bytes.toString('utf8').slice(0, 200_000)\n}\n","import type { KnowledgeIndex, KnowledgePage, KnowledgeSearchResult } from './types'\n\nconst RRF_K = 60\nconst STOP_WORDS = new Set(['the', 'is', 'a', 'an', 'what', 'how', 'are', 'was', 'were', 'to', 'for', 'of', 'with', 'by', 'in', 'on', 'and'])\n\nexport function searchKnowledge(index: KnowledgeIndex, query: string, limit = 10): KnowledgeSearchResult[] {\n const trimmed = query.trim()\n if (trimmed === '') return []\n const tokenRanked = rankByTokens(index.pages, trimmed)\n const graphRanked = rankByGraph(index.pages, tokenRanked)\n const scores = reciprocalRankFusion([tokenRanked.map((p) => p.id), graphRanked.map((p) => p.id)])\n const byId = new Map(index.pages.map((page) => [page.id, page]))\n\n return [...scores.entries()]\n .map(([id, score]) => ({ page: byId.get(id), score }))\n .filter((item): item is { page: KnowledgePage; score: number } => Boolean(item.page))\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .slice(0, limit)\n .map((item, i) => ({\n page: item.page,\n score: item.score,\n rank: i + 1,\n snippet: buildSnippet(item.page.text, trimmed),\n reasons: reasonsFor(item.page, trimmed),\n }))\n}\n\nexport function tokenizeQuery(query: string): string[] {\n const raw = query\n .toLowerCase()\n .split(/[\\s,,。!?、;:\"\"''()()\\-_/\\\\·~~…]+/)\n .filter((token) => token.length > 1 && !STOP_WORDS.has(token))\n const tokens: string[] = []\n for (const token of raw) {\n if (/[\\u4e00-\\u9fff\\u3400-\\u4dbf]/.test(token) && token.length > 2) {\n const chars = [...token]\n for (let i = 0; i < chars.length - 1; i++) tokens.push(chars[i]! + chars[i + 1]!)\n tokens.push(...chars)\n }\n tokens.push(token)\n }\n return [...new Set(tokens)]\n}\n\nexport function reciprocalRankFusion(rankLists: string[][], k = RRF_K): Map<string, number> {\n const scores = new Map<string, number>()\n for (const list of rankLists) {\n list.forEach((id, idx) => {\n scores.set(id, (scores.get(id) ?? 0) + 1 / (k + idx + 1))\n })\n }\n return scores\n}\n\nfunction rankByTokens(pages: KnowledgePage[], query: string): KnowledgePage[] {\n const tokens = tokenizeQuery(query)\n const effective = tokens.length > 0 ? tokens : [query.toLowerCase()]\n return pages\n .map((page) => ({ page, score: tokenScore(page, query, effective) }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction rankByGraph(pages: KnowledgePage[], tokenRanked: KnowledgePage[]): KnowledgePage[] {\n if (tokenRanked.length === 0) return []\n const seeds = new Set(tokenRanked.slice(0, 5).map((page) => page.id))\n return pages\n .map((page) => ({\n page,\n score: page.outLinks.filter((link) => seeds.has(link)).length + page.sourceIds.filter((source) => tokenRanked.some((seed) => seed.sourceIds.includes(source))).length,\n }))\n .filter((item) => item.score > 0)\n .sort((a, b) => b.score - a.score || a.page.path.localeCompare(b.page.path))\n .map((item) => item.page)\n}\n\nfunction tokenScore(page: KnowledgePage, query: string, tokens: string[]): number {\n const title = page.title.toLowerCase()\n const path = page.path.toLowerCase()\n const body = page.text.toLowerCase()\n const phrase = query.toLowerCase()\n let score = 0\n if (path.endsWith(`${phrase}.md`) || title === phrase) score += 200\n if (title.includes(phrase)) score += 50\n if (body.includes(phrase)) score += 20\n for (const token of tokens) {\n if (title.includes(token)) score += 5\n if (body.includes(token)) score += 1\n if (path.includes(token)) score += 3\n }\n return score\n}\n\nfunction buildSnippet(text: string, query: string): string {\n const compact = text.replace(/\\s+/g, ' ').trim()\n const idx = compact.toLowerCase().indexOf(query.toLowerCase())\n if (idx < 0) return compact.slice(0, 180)\n return compact.slice(Math.max(0, idx - 80), Math.min(compact.length, idx + query.length + 100))\n}\n\nfunction reasonsFor(page: KnowledgePage, query: string): string[] {\n const lower = `${page.title}\\n${page.text}`.toLowerCase()\n const reasons: string[] = []\n if (lower.includes(query.toLowerCase())) reasons.push('phrase')\n if (page.sourceIds.length > 0) reasons.push('sourced')\n if (page.outLinks.length > 0) reasons.push('linked')\n return reasons\n}\n","import { join } from 'node:path'\nimport type { KnowledgeIndex } from './types'\nimport { buildKnowledgeGraph } from './graph'\nimport { loadSourceRegistry } from './sources'\nimport { layoutFor, loadKnowledgePages, writeJson } from './store'\n\nexport async function buildKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const [pages, sourceRegistry] = await Promise.all([\n loadKnowledgePages(root),\n loadSourceRegistry(root),\n ])\n const index: KnowledgeIndex = {\n root,\n generatedAt: new Date().toISOString(),\n sources: sourceRegistry.sources,\n pages,\n graph: buildKnowledgeGraph(pages),\n }\n return index\n}\n\nexport async function writeKnowledgeIndex(root: string): Promise<KnowledgeIndex> {\n const index = await buildKnowledgeIndex(root)\n await writeJson(join(layoutFor(root).cacheDir, 'index.json'), index)\n return index\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { normalizeLinkTarget } from './wikilinks'\n\nexport function lintKnowledgeIndex(index: KnowledgeIndex): KnowledgeLintFinding[] {\n const findings: KnowledgeLintFinding[] = []\n const byTarget = new Set<string>()\n const titles = new Map<string, string[]>()\n const sourceIds = new Set(index.sources.map((source) => source.id))\n const anchorIds = new Map(index.sources.map((source) => [source.id, new Set((source.anchors ?? []).map((anchor) => anchor.id))]))\n const pageIds = new Map<string, string[]>()\n const sourceHashes = new Map<string, string[]>()\n for (const page of index.pages) {\n pageIds.set(page.id, [...(pageIds.get(page.id) ?? []), page.path])\n byTarget.add(normalizeLinkTarget(page.id))\n byTarget.add(normalizeLinkTarget(page.title))\n byTarget.add(normalizeLinkTarget(page.path.split('/').pop()!.replace(/\\.md$/, '')))\n const titleKey = page.title.toLowerCase()\n titles.set(titleKey, [...(titles.get(titleKey) ?? []), page.path])\n }\n for (const source of index.sources) {\n sourceHashes.set(source.contentHash, [...(sourceHashes.get(source.contentHash) ?? []), source.id])\n }\n\n const inbound = new Map<string, number>()\n for (const page of index.pages) inbound.set(page.id, 0)\n for (const page of index.pages) {\n if (page.outLinks.length === 0 && !isStructural(page.path)) {\n findings.push({ type: 'no-outlinks', severity: 'info', page: page.path, message: 'Page has no wikilinks to other knowledge pages.' })\n }\n for (const link of page.outLinks) {\n if (!byTarget.has(normalizeLinkTarget(link))) {\n findings.push({ type: 'broken-link', severity: 'warning', page: page.path, message: `Broken wikilink [[${link}]].` })\n }\n }\n }\n\n for (const edge of index.graph.edges) inbound.set(edge.target, (inbound.get(edge.target) ?? 0) + 1)\n for (const page of index.pages) {\n if (!isStructural(page.path) && (inbound.get(page.id) ?? 0) === 0) {\n findings.push({ type: 'orphan', severity: 'info', page: page.path, message: 'No other page links to this page.' })\n }\n if (/\\bclaim\\b/i.test(page.text) && page.sourceIds.length === 0) {\n findings.push({ type: 'uncited-claim', severity: 'warning', page: page.path, message: 'Page appears to contain claims but has no sources frontmatter.' })\n }\n for (const sourceId of page.sourceIds) {\n if (!sourceIds.has(sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${sourceId}\".`, metadata: { sourceId } })\n }\n }\n for (const ref of extractSourceRefs(page.text)) {\n if (!sourceIds.has(ref.sourceId)) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source \"${ref.sourceId}\".`, metadata: ref })\n } else if (ref.anchorId && !(anchorIds.get(ref.sourceId)?.has(ref.anchorId))) {\n findings.push({ type: 'missing-source', severity: 'error', page: page.path, message: `Page cites unknown source anchor \"${ref.sourceId}#${ref.anchorId}\".`, metadata: ref })\n }\n }\n }\n\n for (const [title, paths] of titles) {\n if (title && paths.length > 1) {\n findings.push({ type: 'duplicate-title', severity: 'warning', message: `Duplicate title \"${title}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [id, paths] of pageIds) {\n if (id && paths.length > 1) {\n findings.push({ type: 'duplicate-page-id', severity: 'error', message: `Duplicate page id \"${id}\" in ${paths.join(', ')}.`, metadata: { paths } })\n }\n }\n for (const [hash, ids] of sourceHashes) {\n if (hash && ids.length > 1) {\n findings.push({ type: 'duplicate-source-hash', severity: 'warning', message: `Duplicate source content hash across ${ids.join(', ')}.`, metadata: { sourceIds: ids } })\n }\n }\n return findings\n}\n\nfunction isStructural(path: string): boolean {\n return path.endsWith('/index.md') || path.endsWith('/log.md') || path === 'knowledge/index.md' || path === 'knowledge/log.md'\n}\n\nfunction extractSourceRefs(text: string): Array<{ sourceId: string; anchorId?: string }> {\n const refs: Array<{ sourceId: string; anchorId?: string }> = []\n const regex = /\\[\\^([A-Za-z0-9_-]+)(?:#([A-Za-z0-9_.:-]+))?\\]/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(text)) !== null) {\n refs.push({ sourceId: match[1]!, anchorId: match[2] })\n }\n return refs\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding, KnowledgePage } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { searchKnowledge } from './search'\n\nexport interface KnowledgeInspection {\n pageCount: number\n sourceCount: number\n edgeCount: number\n findingCount: number\n blockingFindingCount: number\n topPages: Array<{ path: string; title: string; degree: number; sources: number }>\n findings: KnowledgeLintFinding[]\n}\n\nexport function inspectKnowledgeIndex(index: KnowledgeIndex): KnowledgeInspection {\n const findings = lintKnowledgeIndex(index)\n const degree = new Map(index.graph.nodes.map((node) => [node.id, node.inDegree + node.outDegree]))\n return {\n pageCount: index.pages.length,\n sourceCount: index.sources.length,\n edgeCount: index.graph.edges.length,\n findingCount: findings.length,\n blockingFindingCount: findings.filter((finding) => finding.severity === 'error').length,\n topPages: [...index.pages]\n .sort((a, b) => (degree.get(b.id) ?? 0) - (degree.get(a.id) ?? 0))\n .slice(0, 10)\n .map((page) => ({ path: page.path, title: page.title, degree: degree.get(page.id) ?? 0, sources: page.sourceIds.length })),\n findings,\n }\n}\n\nexport interface KnowledgeExplanation {\n target: string\n page?: KnowledgePage\n sources: Array<{ id: string; title?: string; uri: string }>\n links: string[]\n inbound: string[]\n related: Array<{ path: string; title: string; score: number }>\n}\n\nexport function explainKnowledgeTarget(index: KnowledgeIndex, target: string): KnowledgeExplanation {\n const page = index.pages.find((candidate) => candidate.path === target || candidate.id === target || candidate.title.toLowerCase() === target.toLowerCase())\n const inbound = page\n ? index.graph.edges.filter((edge) => edge.target === page.id).map((edge) => index.pages.find((candidate) => candidate.id === edge.source)?.path ?? edge.source)\n : []\n const related = page\n ? searchKnowledge(index, `${page.title} ${page.tags.join(' ')}`, 6)\n .filter((result) => result.page.id !== page.id)\n .map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n : searchKnowledge(index, target, 6).map((result) => ({ path: result.page.path, title: result.page.title, score: result.score }))\n return {\n target,\n page,\n sources: page ? index.sources.filter((source) => page.sourceIds.includes(source.id)).map((source) => ({ id: source.id, title: source.title, uri: source.uri })) : [],\n links: page?.outLinks ?? [],\n inbound,\n related,\n }\n}\n","import type { KnowledgeIndex, KnowledgeLintFinding } from './types'\nimport { lintKnowledgeIndex } from './lint'\nimport { KnowledgeIndexSchema } from './schemas'\n\nexport interface ValidateKnowledgeOptions {\n strict?: boolean\n}\n\nexport interface ValidateKnowledgeResult {\n ok: boolean\n findings: KnowledgeLintFinding[]\n}\n\nexport function validateKnowledgeIndex(index: KnowledgeIndex, options: ValidateKnowledgeOptions = {}): ValidateKnowledgeResult {\n const findings = [...lintKnowledgeIndex(index)]\n const parsed = KnowledgeIndexSchema.safeParse(index)\n if (!parsed.success) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n message: parsed.error.issues.map((issue) => `${issue.path.join('.')}: ${issue.message}`).join('; '),\n })\n }\n if (options.strict) {\n for (const page of index.pages) {\n if (isStructuralPage(page.path)) continue\n if (!page.frontmatter.id || !page.frontmatter.title) {\n findings.push({\n type: 'missing-frontmatter',\n severity: 'error',\n page: page.path,\n message: 'Strict mode requires id and title frontmatter.',\n })\n }\n }\n }\n return { ok: !findings.some((finding) => finding.severity === 'error'), findings }\n}\n\nfunction isStructuralPage(path: string): boolean {\n return path === 'knowledge/index.md' || path === 'knowledge/log.md' || path.endsWith('/index.md') || path.endsWith('/log.md')\n}\n"],"mappings":"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","names":["mkdir","readFile","writeFile","dirname","join","join","mkdir","readFile","dirname","writeFile","mkdir","readFile","readdir","stat","writeFile","dirname","join","relative","readFile","mkdir","dirname","writeFile","stat","join","mediaTypeFor","relative","readdir","join","join"]}
|
package/dist/cli.js
CHANGED
|
@@ -9,8 +9,9 @@ import {
|
|
|
9
9
|
lintKnowledgeIndex,
|
|
10
10
|
loadSourceRegistry,
|
|
11
11
|
searchKnowledge,
|
|
12
|
+
validateKnowledgeIndex,
|
|
12
13
|
writeKnowledgeIndex
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-WCUKMCAY.js";
|
|
14
15
|
import {
|
|
15
16
|
detectKnowledgeGaps,
|
|
16
17
|
findSurprisingConnections,
|
|
@@ -64,6 +65,10 @@ Commands:
|
|
|
64
65
|
Emit graph summary or JSON.
|
|
65
66
|
lint [--root .] [--json]
|
|
66
67
|
Run deterministic structural lint.
|
|
68
|
+
validate [--root .] [--strict] [--json]
|
|
69
|
+
Run schema + lint validation. Exits non-zero on blocking findings.
|
|
70
|
+
export [--root .] [--format json]
|
|
71
|
+
Export the current index.
|
|
67
72
|
viz [--root .] [--json]
|
|
68
73
|
Emit graph gaps and surprising connections.
|
|
69
74
|
version
|
|
@@ -200,6 +205,26 @@ async function main() {
|
|
|
200
205
|
}
|
|
201
206
|
return findings.some((finding) => finding.severity === "error") ? 2 : 0;
|
|
202
207
|
}
|
|
208
|
+
case "validate": {
|
|
209
|
+
const result = validateKnowledgeIndex(await loadOrBuildIndex(root), { strict: args.flags.strict === "true" });
|
|
210
|
+
if (args.flags.json === "true") process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
211
|
+
else {
|
|
212
|
+
process.stdout.write(result.ok ? "valid\n" : "invalid\n");
|
|
213
|
+
for (const finding of result.findings) process.stdout.write(`${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ""}: ${finding.message}
|
|
214
|
+
`);
|
|
215
|
+
}
|
|
216
|
+
return result.ok ? 0 : 2;
|
|
217
|
+
}
|
|
218
|
+
case "export": {
|
|
219
|
+
const index = await loadOrBuildIndex(root);
|
|
220
|
+
const format = args.flags.format ?? "json";
|
|
221
|
+
if (format !== "json") {
|
|
222
|
+
process.stderr.write("export currently supports --format json\n");
|
|
223
|
+
return 1;
|
|
224
|
+
}
|
|
225
|
+
process.stdout.write(JSON.stringify(index, null, 2) + "\n");
|
|
226
|
+
return 0;
|
|
227
|
+
}
|
|
203
228
|
case "viz": {
|
|
204
229
|
const index = await loadOrBuildIndex(root);
|
|
205
230
|
const viz = toKnowledgeVizGraph(index.graph);
|