@tangle-network/agent-knowledge 1.2.0 → 1.3.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.
@@ -0,0 +1,19 @@
1
+ // src/ids.ts
2
+ import { createHash } from "crypto";
3
+ function sha256(text) {
4
+ return createHash("sha256").update(text).digest("hex");
5
+ }
6
+ function slugify(input) {
7
+ const out = input.trim().toLowerCase().normalize("NFKD").replace(/[\u0300-\u036f]/g, "").replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-+|-+$/g, "");
8
+ return out || "untitled";
9
+ }
10
+ function stableId(prefix, content) {
11
+ return `${prefix}_${sha256(content).slice(0, 16)}`;
12
+ }
13
+
14
+ export {
15
+ sha256,
16
+ slugify,
17
+ stableId
18
+ };
19
+ //# sourceMappingURL=chunk-YMKHCTS2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ids.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"],"mappings":";AAAA,SAAS,kBAAkB;AAEpB,SAAS,OAAO,MAAsB;AAC3C,SAAO,WAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK;AACvD;AAEO,SAAS,QAAQ,OAAuB;AAC7C,QAAM,MAAM,MACT,KAAK,EACL,YAAY,EACZ,UAAU,MAAM,EAChB,QAAQ,oBAAoB,EAAE,EAC9B,QAAQ,4BAA4B,GAAG,EACvC,QAAQ,YAAY,EAAE;AACzB,SAAO,OAAO;AAChB;AAEO,SAAS,SAAS,QAAgB,SAAyB;AAChE,SAAO,GAAG,MAAM,IAAI,OAAO,OAAO,EAAE,MAAM,GAAG,EAAE,CAAC;AAClD;","names":[]}
package/dist/cli.js CHANGED
@@ -11,12 +11,13 @@ import {
11
11
  searchKnowledge,
12
12
  validateKnowledgeIndex,
13
13
  writeKnowledgeIndex
14
- } from "./chunk-JLCQ6O7W.js";
14
+ } from "./chunk-HKYD765Q.js";
15
15
  import {
16
16
  detectKnowledgeGaps,
17
17
  findSurprisingConnections,
18
18
  toKnowledgeVizGraph
19
- } from "./chunk-TXNYP4WI.js";
19
+ } from "./chunk-4PNXQ2NT.js";
20
+ import "./chunk-YMKHCTS2.js";
20
21
 
21
22
  // src/cli.ts
22
23
  import { existsSync, readFileSync } from "fs";
@@ -86,9 +87,13 @@ async function main() {
86
87
  }
87
88
  case "index": {
88
89
  const index = await writeKnowledgeIndex(root);
89
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(index, null, 2) + "\n");
90
- else process.stdout.write(`indexed ${index.pages.length} pages, ${index.graph.edges.length} edges
90
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(index, null, 2)}
91
91
  `);
92
+ else
93
+ process.stdout.write(
94
+ `indexed ${index.pages.length} pages, ${index.graph.edges.length} edges
95
+ `
96
+ );
92
97
  return 0;
93
98
  }
94
99
  case "source-add": {
@@ -99,16 +104,20 @@ async function main() {
99
104
  }
100
105
  await initKnowledgeBase(root);
101
106
  const sources = await addSourcePath(root, resolve(path));
102
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(sources, null, 2) + "\n");
107
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(sources, null, 2)}
108
+ `);
103
109
  else for (const source of sources) process.stdout.write(`${source.id} ${source.uri}
104
110
  `);
105
111
  return 0;
106
112
  }
107
113
  case "sources": {
108
114
  const registry = await loadSourceRegistry(root);
109
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(registry.sources, null, 2) + "\n");
115
+ if (args.flags.json === "true")
116
+ process.stdout.write(`${JSON.stringify(registry.sources, null, 2)}
117
+ `);
110
118
  else {
111
- for (const source of registry.sources) process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}
119
+ for (const source of registry.sources)
120
+ process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}
112
121
  `);
113
122
  }
114
123
  return 0;
@@ -122,7 +131,8 @@ async function main() {
122
131
  await initKnowledgeBase(root);
123
132
  const result = await applyKnowledgeWriteBlocksFile(root, resolve(proposalPath));
124
133
  await writeKnowledgeIndex(root);
125
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(result, null, 2) + "\n");
134
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(result, null, 2)}
135
+ `);
126
136
  else {
127
137
  for (const path of result.written) process.stdout.write(`wrote ${path}
128
138
  `);
@@ -134,11 +144,16 @@ async function main() {
134
144
  case "inspect": {
135
145
  const index = await loadOrBuildIndex(root);
136
146
  const inspection = inspectKnowledgeIndex(index);
137
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(inspection, null, 2) + "\n");
138
- else {
139
- process.stdout.write(`pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}
147
+ if (args.flags.json === "true")
148
+ process.stdout.write(`${JSON.stringify(inspection, null, 2)}
140
149
  `);
141
- for (const page of inspection.topPages.slice(0, 5)) process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}
150
+ else {
151
+ process.stdout.write(
152
+ `pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}
153
+ `
154
+ );
155
+ for (const page of inspection.topPages.slice(0, 5))
156
+ process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}
142
157
  `);
143
158
  }
144
159
  return inspection.blockingFindingCount > 0 ? 2 : 0;
@@ -150,17 +165,21 @@ async function main() {
150
165
  return 1;
151
166
  }
152
167
  const explanation = explainKnowledgeTarget(await loadOrBuildIndex(root), target);
153
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(explanation, null, 2) + "\n");
168
+ if (args.flags.json === "true")
169
+ process.stdout.write(`${JSON.stringify(explanation, null, 2)}
170
+ `);
154
171
  else {
155
172
  process.stdout.write(`${explanation.page ? explanation.page.title : target}
156
173
  `);
157
- for (const source of explanation.sources) process.stdout.write(`source ${source.id} ${source.title ?? source.uri}
174
+ for (const source of explanation.sources)
175
+ process.stdout.write(`source ${source.id} ${source.title ?? source.uri}
158
176
  `);
159
177
  for (const link of explanation.links) process.stdout.write(`out ${link}
160
178
  `);
161
179
  for (const inbound of explanation.inbound) process.stdout.write(`in ${inbound}
162
180
  `);
163
- for (const related of explanation.related.slice(0, 5)) process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}
181
+ for (const related of explanation.related.slice(0, 5))
182
+ process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}
164
183
  `);
165
184
  }
166
185
  return 0;
@@ -174,11 +193,14 @@ async function main() {
174
193
  const index = await loadOrBuildIndex(root);
175
194
  const results = searchKnowledge(index, query, Number(args.flags.limit ?? 10));
176
195
  if (args.flags.json === "true") {
177
- process.stdout.write(JSON.stringify(results, null, 2) + "\n");
196
+ process.stdout.write(`${JSON.stringify(results, null, 2)}
197
+ `);
178
198
  } else {
179
199
  for (const result of results) {
180
- process.stdout.write(`${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}
181
- `);
200
+ process.stdout.write(
201
+ `${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}
202
+ `
203
+ );
182
204
  if (result.snippet) process.stdout.write(` ${result.snippet}
183
205
  `);
184
206
  }
@@ -187,31 +209,45 @@ async function main() {
187
209
  }
188
210
  case "graph": {
189
211
  const index = await loadOrBuildIndex(root);
190
- if ((args.flags.format ?? "summary") === "json") process.stdout.write(JSON.stringify(index.graph, null, 2) + "\n");
191
- else process.stdout.write(`nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}
212
+ if ((args.flags.format ?? "summary") === "json")
213
+ process.stdout.write(`${JSON.stringify(index.graph, null, 2)}
192
214
  `);
215
+ else
216
+ process.stdout.write(
217
+ `nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}
218
+ `
219
+ );
193
220
  return 0;
194
221
  }
195
222
  case "lint": {
196
223
  const index = await loadOrBuildIndex(root);
197
224
  const findings = lintKnowledgeIndex(index);
198
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(findings, null, 2) + "\n");
225
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(findings, null, 2)}
226
+ `);
199
227
  else {
200
228
  if (findings.length === 0) process.stdout.write("no findings\n");
201
229
  for (const finding of findings) {
202
- process.stdout.write(`${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ""}: ${finding.message}
203
- `);
230
+ process.stdout.write(
231
+ `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ""}: ${finding.message}
232
+ `
233
+ );
204
234
  }
205
235
  }
206
236
  return findings.some((finding) => finding.severity === "error") ? 2 : 0;
207
237
  }
208
238
  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");
239
+ const result = validateKnowledgeIndex(await loadOrBuildIndex(root), {
240
+ strict: args.flags.strict === "true"
241
+ });
242
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(result, null, 2)}
243
+ `);
211
244
  else {
212
245
  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
- `);
246
+ for (const finding of result.findings)
247
+ process.stdout.write(
248
+ `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ""}: ${finding.message}
249
+ `
250
+ );
215
251
  }
216
252
  return result.ok ? 0 : 2;
217
253
  }
@@ -222,7 +258,8 @@ async function main() {
222
258
  process.stderr.write("export currently supports --format json\n");
223
259
  return 1;
224
260
  }
225
- process.stdout.write(JSON.stringify(index, null, 2) + "\n");
261
+ process.stdout.write(`${JSON.stringify(index, null, 2)}
262
+ `);
226
263
  return 0;
227
264
  }
228
265
  case "viz": {
@@ -233,10 +270,13 @@ async function main() {
233
270
  gaps: detectKnowledgeGaps(viz),
234
271
  surprisingConnections: findSurprisingConnections(viz)
235
272
  };
236
- if (args.flags.json === "true") process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
237
- else {
238
- process.stdout.write(`communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}
273
+ if (args.flags.json === "true") process.stdout.write(`${JSON.stringify(payload, null, 2)}
239
274
  `);
275
+ else {
276
+ process.stdout.write(
277
+ `communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}
278
+ `
279
+ );
240
280
  }
241
281
  return 0;
242
282
  }
@@ -259,12 +299,15 @@ ${HELP}`);
259
299
  }
260
300
  async function loadOrBuildIndex(root) {
261
301
  const path = join(layoutFor(root).cacheDir, "index.json");
262
- if (existsSync(path)) return JSON.parse(readFileSync(path, "utf8"));
302
+ if (existsSync(path))
303
+ return JSON.parse(readFileSync(path, "utf8"));
263
304
  return await writeKnowledgeIndex(root);
264
305
  }
265
306
  main().then((code) => process.exit(code)).catch((err) => {
266
- process.stderr.write(`agent-knowledge error: ${err instanceof Error ? err.stack ?? err.message : String(err)}
267
- `);
307
+ process.stderr.write(
308
+ `agent-knowledge error: ${err instanceof Error ? err.stack ?? err.message : String(err)}
309
+ `
310
+ );
268
311
  process.exit(1);
269
312
  });
270
313
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { buildKnowledgeIndex, writeKnowledgeIndex } from './indexer'\nimport { explainKnowledgeTarget, inspectKnowledgeIndex } from './inspect'\nimport { lintKnowledgeIndex } from './lint'\nimport { applyKnowledgeWriteBlocksFile } from './proposals'\nimport { searchKnowledge } from './search'\nimport { addSourcePath, loadSourceRegistry } from './sources'\nimport { initKnowledgeBase, layoutFor } from './store'\nimport { validateKnowledgeIndex } from './validate'\nimport { detectKnowledgeGaps, findSurprisingConnections, toKnowledgeVizGraph } from './viz/index'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const token = rest[i]!\n if (token.startsWith('--')) {\n const key = token.slice(2)\n const next = rest[i + 1]\n if (next && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else {\n positional.push(token)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-knowledge — source-grounded knowledge graph CLI.\n\nCommands:\n init [--root .]\n Create raw/sources, knowledge, and cache directories.\n index [--root .] [--json]\n Build .agent-knowledge/index.json from knowledge/**/*.md.\n source-add <path> [--root .] [--json]\n Copy a file or directory into raw/sources and register immutable source records.\n sources [--root .] [--json]\n List registered sources.\n apply-write-blocks <proposal-file> [--root .] [--json]\n Apply safe ---FILE: knowledge/...--- blocks emitted by an agent.\n inspect [--root .] [--json]\n Summarize page/source/edge counts, top pages, and lint state.\n explain <page|id|query> [--root .] [--json]\n Explain sources, links, inbound links, and related pages.\n search <query> [--root .] [--limit 10] [--json]\n Fast local token+graph search over the generated knowledge index.\n graph [--root .] [--format summary|json]\n Emit graph summary or JSON.\n lint [--root .] [--json]\n Run deterministic structural lint.\n validate [--root .] [--strict] [--json]\n Run schema + lint validation. Exits non-zero on blocking findings.\n export [--root .] [--format json]\n Export the current index.\n viz [--root .] [--json]\n Emit graph gaps and surprising connections.\n version\n Print package version.\n`\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv.slice(2))\n const root = resolve(args.flags.root ?? '.')\n switch (args.command) {\n case 'init': {\n const layout = await initKnowledgeBase(root)\n process.stdout.write(`initialized knowledge base at ${layout.root}\\n`)\n return 0\n }\n case 'index': {\n const index = await writeKnowledgeIndex(root)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(index, null, 2) + '\\n')\n else process.stdout.write(`indexed ${index.pages.length} pages, ${index.graph.edges.length} edges\\n`)\n return 0\n }\n case 'source-add': {\n const [path] = args.positional\n if (!path) {\n process.stderr.write('source-add requires a file or directory path\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const sources = await addSourcePath(root, resolve(path))\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(sources, null, 2) + '\\n')\n else for (const source of sources) process.stdout.write(`${source.id} ${source.uri}\\n`)\n return 0\n }\n case 'sources': {\n const registry = await loadSourceRegistry(root)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(registry.sources, null, 2) + '\\n')\n else {\n for (const source of registry.sources) process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}\\n`)\n }\n return 0\n }\n case 'apply-write-blocks': {\n const [proposalPath] = args.positional\n if (!proposalPath) {\n process.stderr.write('apply-write-blocks requires a proposal file\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const result = await applyKnowledgeWriteBlocksFile(root, resolve(proposalPath))\n await writeKnowledgeIndex(root)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n else {\n for (const path of result.written) process.stdout.write(`wrote ${path}\\n`)\n for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\\n`)\n }\n return result.warnings.length > 0 ? 2 : 0\n }\n case 'inspect': {\n const index = await loadOrBuildIndex(root)\n const inspection = inspectKnowledgeIndex(index)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(inspection, null, 2) + '\\n')\n else {\n process.stdout.write(`pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}\\n`)\n for (const page of inspection.topPages.slice(0, 5)) process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}\\n`)\n }\n return inspection.blockingFindingCount > 0 ? 2 : 0\n }\n case 'explain': {\n const target = args.positional.join(' ')\n if (!target) {\n process.stderr.write('explain requires a page path, id, title, or query\\n')\n return 1\n }\n const explanation = explainKnowledgeTarget(await loadOrBuildIndex(root), target)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(explanation, null, 2) + '\\n')\n else {\n process.stdout.write(`${explanation.page ? explanation.page.title : target}\\n`)\n for (const source of explanation.sources) process.stdout.write(`source ${source.id} ${source.title ?? source.uri}\\n`)\n for (const link of explanation.links) process.stdout.write(`out ${link}\\n`)\n for (const inbound of explanation.inbound) process.stdout.write(`in ${inbound}\\n`)\n for (const related of explanation.related.slice(0, 5)) process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}\\n`)\n }\n return 0\n }\n case 'search': {\n const query = args.positional.join(' ')\n if (!query) {\n process.stderr.write('search requires a query\\n')\n return 1\n }\n const index = await loadOrBuildIndex(root)\n const results = searchKnowledge(index, query, Number(args.flags.limit ?? 10))\n if (args.flags.json === 'true') {\n process.stdout.write(JSON.stringify(results, null, 2) + '\\n')\n } else {\n for (const result of results) {\n process.stdout.write(`${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}\\n`)\n if (result.snippet) process.stdout.write(` ${result.snippet}\\n`)\n }\n }\n return 0\n }\n case 'graph': {\n const index = await loadOrBuildIndex(root)\n if ((args.flags.format ?? 'summary') === 'json') process.stdout.write(JSON.stringify(index.graph, null, 2) + '\\n')\n else process.stdout.write(`nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}\\n`)\n return 0\n }\n case 'lint': {\n const index = await loadOrBuildIndex(root)\n const findings = lintKnowledgeIndex(index)\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(findings, null, 2) + '\\n')\n else {\n if (findings.length === 0) process.stdout.write('no findings\\n')\n for (const finding of findings) {\n process.stdout.write(`${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`)\n }\n }\n return findings.some((finding) => finding.severity === 'error') ? 2 : 0\n }\n case 'validate': {\n const result = validateKnowledgeIndex(await loadOrBuildIndex(root), { strict: args.flags.strict === 'true' })\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(result, null, 2) + '\\n')\n else {\n process.stdout.write(result.ok ? 'valid\\n' : 'invalid\\n')\n for (const finding of result.findings) process.stdout.write(`${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`)\n }\n return result.ok ? 0 : 2\n }\n case 'export': {\n const index = await loadOrBuildIndex(root)\n const format = args.flags.format ?? 'json'\n if (format !== 'json') {\n process.stderr.write('export currently supports --format json\\n')\n return 1\n }\n process.stdout.write(JSON.stringify(index, null, 2) + '\\n')\n return 0\n }\n case 'viz': {\n const index = await loadOrBuildIndex(root)\n const viz = toKnowledgeVizGraph(index.graph)\n const payload = {\n graph: viz,\n gaps: detectKnowledgeGaps(viz),\n surprisingConnections: findSurprisingConnections(viz),\n }\n if (args.flags.json === 'true') process.stdout.write(JSON.stringify(payload, null, 2) + '\\n')\n else {\n process.stdout.write(`communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}\\n`)\n }\n return 0\n }\n case 'version': {\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version: string }\n process.stdout.write(`${pkg.version}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n process.stdout.write(HELP)\n return 0\n default:\n process.stderr.write(`unknown command: ${args.command}\\n${HELP}`)\n return 1\n }\n}\n\nasync function loadOrBuildIndex(root: string) {\n const path = join(layoutFor(root).cacheDir, 'index.json')\n if (existsSync(path)) return JSON.parse(readFileSync(path, 'utf8')) as Awaited<ReturnType<typeof buildKnowledgeIndex>>\n return await writeKnowledgeIndex(root)\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(`agent-knowledge error: ${err instanceof Error ? err.stack ?? err.message : String(err)}\\n`)\n process.exit(1)\n })\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync } from 'node:fs'\nimport { join, resolve } from 'node:path'\n\nimport { type buildKnowledgeIndex, writeKnowledgeIndex } from './indexer'\nimport { explainKnowledgeTarget, inspectKnowledgeIndex } from './inspect'\nimport { lintKnowledgeIndex } from './lint'\nimport { applyKnowledgeWriteBlocksFile } from './proposals'\nimport { searchKnowledge } from './search'\nimport { addSourcePath, loadSourceRegistry } from './sources'\nimport { initKnowledgeBase, layoutFor } from './store'\nimport { validateKnowledgeIndex } from './validate'\nimport { detectKnowledgeGaps, findSurprisingConnections, toKnowledgeVizGraph } from './viz/index'\n\ninterface Args {\n command: string\n positional: string[]\n flags: Record<string, string>\n}\n\nfunction parseArgs(argv: string[]): Args {\n const [command, ...rest] = argv\n const positional: string[] = []\n const flags: Record<string, string> = {}\n for (let i = 0; i < rest.length; i++) {\n const token = rest[i]!\n if (token.startsWith('--')) {\n const key = token.slice(2)\n const next = rest[i + 1]\n if (next && !next.startsWith('--')) {\n flags[key] = next\n i++\n } else {\n flags[key] = 'true'\n }\n } else {\n positional.push(token)\n }\n }\n return { command: command ?? 'help', positional, flags }\n}\n\nconst HELP = `agent-knowledge — source-grounded knowledge graph CLI.\n\nCommands:\n init [--root .]\n Create raw/sources, knowledge, and cache directories.\n index [--root .] [--json]\n Build .agent-knowledge/index.json from knowledge/**/*.md.\n source-add <path> [--root .] [--json]\n Copy a file or directory into raw/sources and register immutable source records.\n sources [--root .] [--json]\n List registered sources.\n apply-write-blocks <proposal-file> [--root .] [--json]\n Apply safe ---FILE: knowledge/...--- blocks emitted by an agent.\n inspect [--root .] [--json]\n Summarize page/source/edge counts, top pages, and lint state.\n explain <page|id|query> [--root .] [--json]\n Explain sources, links, inbound links, and related pages.\n search <query> [--root .] [--limit 10] [--json]\n Fast local token+graph search over the generated knowledge index.\n graph [--root .] [--format summary|json]\n Emit graph summary or JSON.\n lint [--root .] [--json]\n Run deterministic structural lint.\n validate [--root .] [--strict] [--json]\n Run schema + lint validation. Exits non-zero on blocking findings.\n export [--root .] [--format json]\n Export the current index.\n viz [--root .] [--json]\n Emit graph gaps and surprising connections.\n version\n Print package version.\n`\n\nasync function main(): Promise<number> {\n const args = parseArgs(process.argv.slice(2))\n const root = resolve(args.flags.root ?? '.')\n switch (args.command) {\n case 'init': {\n const layout = await initKnowledgeBase(root)\n process.stdout.write(`initialized knowledge base at ${layout.root}\\n`)\n return 0\n }\n case 'index': {\n const index = await writeKnowledgeIndex(root)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n else\n process.stdout.write(\n `indexed ${index.pages.length} pages, ${index.graph.edges.length} edges\\n`,\n )\n return 0\n }\n case 'source-add': {\n const [path] = args.positional\n if (!path) {\n process.stderr.write('source-add requires a file or directory path\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const sources = await addSourcePath(root, resolve(path))\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(sources, null, 2)}\\n`)\n else for (const source of sources) process.stdout.write(`${source.id} ${source.uri}\\n`)\n return 0\n }\n case 'sources': {\n const registry = await loadSourceRegistry(root)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(registry.sources, null, 2)}\\n`)\n else {\n for (const source of registry.sources)\n process.stdout.write(`${source.id} ${source.title ?? source.uri} ${source.uri}\\n`)\n }\n return 0\n }\n case 'apply-write-blocks': {\n const [proposalPath] = args.positional\n if (!proposalPath) {\n process.stderr.write('apply-write-blocks requires a proposal file\\n')\n return 1\n }\n await initKnowledgeBase(root)\n const result = await applyKnowledgeWriteBlocksFile(root, resolve(proposalPath))\n await writeKnowledgeIndex(root)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n for (const path of result.written) process.stdout.write(`wrote ${path}\\n`)\n for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\\n`)\n }\n return result.warnings.length > 0 ? 2 : 0\n }\n case 'inspect': {\n const index = await loadOrBuildIndex(root)\n const inspection = inspectKnowledgeIndex(index)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(inspection, null, 2)}\\n`)\n else {\n process.stdout.write(\n `pages=${inspection.pageCount} sources=${inspection.sourceCount} edges=${inspection.edgeCount} findings=${inspection.findingCount} blocking=${inspection.blockingFindingCount}\\n`,\n )\n for (const page of inspection.topPages.slice(0, 5))\n process.stdout.write(`${page.degree} ${page.path} sources=${page.sources}\\n`)\n }\n return inspection.blockingFindingCount > 0 ? 2 : 0\n }\n case 'explain': {\n const target = args.positional.join(' ')\n if (!target) {\n process.stderr.write('explain requires a page path, id, title, or query\\n')\n return 1\n }\n const explanation = explainKnowledgeTarget(await loadOrBuildIndex(root), target)\n if (args.flags.json === 'true')\n process.stdout.write(`${JSON.stringify(explanation, null, 2)}\\n`)\n else {\n process.stdout.write(`${explanation.page ? explanation.page.title : target}\\n`)\n for (const source of explanation.sources)\n process.stdout.write(`source ${source.id} ${source.title ?? source.uri}\\n`)\n for (const link of explanation.links) process.stdout.write(`out ${link}\\n`)\n for (const inbound of explanation.inbound) process.stdout.write(`in ${inbound}\\n`)\n for (const related of explanation.related.slice(0, 5))\n process.stdout.write(`related ${related.path} score=${related.score.toFixed(5)}\\n`)\n }\n return 0\n }\n case 'search': {\n const query = args.positional.join(' ')\n if (!query) {\n process.stderr.write('search requires a query\\n')\n return 1\n }\n const index = await loadOrBuildIndex(root)\n const results = searchKnowledge(index, query, Number(args.flags.limit ?? 10))\n if (args.flags.json === 'true') {\n process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`)\n } else {\n for (const result of results) {\n process.stdout.write(\n `${result.rank}. ${result.page.title} (${result.page.path}) score=${result.score.toFixed(5)}\\n`,\n )\n if (result.snippet) process.stdout.write(` ${result.snippet}\\n`)\n }\n }\n return 0\n }\n case 'graph': {\n const index = await loadOrBuildIndex(root)\n if ((args.flags.format ?? 'summary') === 'json')\n process.stdout.write(`${JSON.stringify(index.graph, null, 2)}\\n`)\n else\n process.stdout.write(\n `nodes=${index.graph.nodes.length} edges=${index.graph.edges.length}\\n`,\n )\n return 0\n }\n case 'lint': {\n const index = await loadOrBuildIndex(root)\n const findings = lintKnowledgeIndex(index)\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(findings, null, 2)}\\n`)\n else {\n if (findings.length === 0) process.stdout.write('no findings\\n')\n for (const finding of findings) {\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n }\n return findings.some((finding) => finding.severity === 'error') ? 2 : 0\n }\n case 'validate': {\n const result = validateKnowledgeIndex(await loadOrBuildIndex(root), {\n strict: args.flags.strict === 'true',\n })\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(result, null, 2)}\\n`)\n else {\n process.stdout.write(result.ok ? 'valid\\n' : 'invalid\\n')\n for (const finding of result.findings)\n process.stdout.write(\n `${finding.severity.toUpperCase()} ${finding.type}${finding.page ? ` ${finding.page}` : ''}: ${finding.message}\\n`,\n )\n }\n return result.ok ? 0 : 2\n }\n case 'export': {\n const index = await loadOrBuildIndex(root)\n const format = args.flags.format ?? 'json'\n if (format !== 'json') {\n process.stderr.write('export currently supports --format json\\n')\n return 1\n }\n process.stdout.write(`${JSON.stringify(index, null, 2)}\\n`)\n return 0\n }\n case 'viz': {\n const index = await loadOrBuildIndex(root)\n const viz = toKnowledgeVizGraph(index.graph)\n const payload = {\n graph: viz,\n gaps: detectKnowledgeGaps(viz),\n surprisingConnections: findSurprisingConnections(viz),\n }\n if (args.flags.json === 'true') process.stdout.write(`${JSON.stringify(payload, null, 2)}\\n`)\n else {\n process.stdout.write(\n `communities=${viz.communities.length} gaps=${payload.gaps.length} surprising=${payload.surprisingConnections.length}\\n`,\n )\n }\n return 0\n }\n case 'version': {\n const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as {\n version: string\n }\n process.stdout.write(`${pkg.version}\\n`)\n return 0\n }\n case 'help':\n case '--help':\n case '-h':\n process.stdout.write(HELP)\n return 0\n default:\n process.stderr.write(`unknown command: ${args.command}\\n${HELP}`)\n return 1\n }\n}\n\nasync function loadOrBuildIndex(root: string) {\n const path = join(layoutFor(root).cacheDir, 'index.json')\n if (existsSync(path))\n return JSON.parse(readFileSync(path, 'utf8')) as Awaited<ReturnType<typeof buildKnowledgeIndex>>\n return await writeKnowledgeIndex(root)\n}\n\nmain()\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(\n `agent-knowledge error: ${err instanceof Error ? (err.stack ?? err.message) : String(err)}\\n`,\n )\n process.exit(1)\n })\n"],"mappings":"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","names":[]}