@stjbrown/agent-knowledge 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +44 -0
- package/README.md +212 -0
- package/dist/chunk-3XSOMUQQ.js +131 -0
- package/dist/chunk-3XSOMUQQ.js.map +1 -0
- package/dist/chunk-J4MELCGD.js +114 -0
- package/dist/chunk-J4MELCGD.js.map +1 -0
- package/dist/chunk-YIAVFL7A.js +1732 -0
- package/dist/chunk-YIAVFL7A.js.map +1 -0
- package/dist/headless.js +11 -0
- package/dist/headless.js.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/main.js +373 -0
- package/dist/main.js.map +1 -0
- package/dist/tui-VZVO7UHV.js +521 -0
- package/dist/tui-VZVO7UHV.js.map +1 -0
- package/package.json +72 -0
- package/skills/kb/SKILL.md +54 -0
- package/skills/kb/example-bundle/concepts/customers.md +15 -0
- package/skills/kb/example-bundle/concepts/orders.md +19 -0
- package/skills/kb/example-bundle/index.md +20 -0
- package/skills/kb/example-bundle/log.md +6 -0
- package/skills/kb/example-bundle/spec/conventions.md +36 -0
- package/skills/kb/example-bundle/spec/types.md +23 -0
- package/skills/kb/references/SPEC.md +451 -0
- package/skills/kb/references/glossary.md +61 -0
- package/skills/kb/references/trust-model.md +79 -0
- package/skills/kb/templates/concept.md +22 -0
- package/skills/kb/templates/index.md +17 -0
- package/skills/kb/templates/log.md +13 -0
- package/skills/kb-ingest/SKILL.md +128 -0
- package/skills/kb-init/SKILL.md +79 -0
- package/skills/kb-lint/SKILL.md +77 -0
- package/skills/kb-lint/scripts/conformance.mjs +7537 -0
- package/skills/kb-query/SKILL.md +81 -0
- package/skills/kb-visualize/SKILL.md +72 -0
- package/skills/kb-visualize/scripts/graph.mjs +7520 -0
package/dist/main.js
ADDED
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __janetCreateRequire } from "node:module";
|
|
3
|
+
const require = __janetCreateRequire(import.meta.url);
|
|
4
|
+
import {
|
|
5
|
+
runHeadless
|
|
6
|
+
} from "./chunk-J4MELCGD.js";
|
|
7
|
+
import {
|
|
8
|
+
availableModels,
|
|
9
|
+
loadSettings,
|
|
10
|
+
normalizeModelSelection
|
|
11
|
+
} from "./chunk-3XSOMUQQ.js";
|
|
12
|
+
import {
|
|
13
|
+
GREETING,
|
|
14
|
+
resolveProjectPaths
|
|
15
|
+
} from "./chunk-YIAVFL7A.js";
|
|
16
|
+
|
|
17
|
+
// src/main.ts
|
|
18
|
+
import { existsSync as existsSync2 } from "fs";
|
|
19
|
+
|
|
20
|
+
// ../kb-tools/dist/conformance.js
|
|
21
|
+
import { existsSync, readFileSync, statSync as statSync2 } from "fs";
|
|
22
|
+
import { dirname, join as join2 } from "path";
|
|
23
|
+
|
|
24
|
+
// ../kb-tools/dist/shared.js
|
|
25
|
+
import { readdirSync, statSync } from "fs";
|
|
26
|
+
import { join, relative, sep } from "path";
|
|
27
|
+
import { parseDocument } from "yaml";
|
|
28
|
+
var FM_RE = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)/;
|
|
29
|
+
var RESERVED = /* @__PURE__ */ new Set(["index.md", "log.md"]);
|
|
30
|
+
function collectMarkdown(bundle) {
|
|
31
|
+
const out = [];
|
|
32
|
+
const walk = (dir) => {
|
|
33
|
+
let entries;
|
|
34
|
+
try {
|
|
35
|
+
entries = readdirSync(dir).sort();
|
|
36
|
+
} catch {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
for (const name of entries) {
|
|
40
|
+
const full = join(dir, name);
|
|
41
|
+
let st;
|
|
42
|
+
try {
|
|
43
|
+
st = statSync(full);
|
|
44
|
+
} catch {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (st.isDirectory()) {
|
|
48
|
+
walk(full);
|
|
49
|
+
} else if (name.endsWith(".md")) {
|
|
50
|
+
out.push(relative(bundle, full).split(sep).join("/"));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
walk(bundle);
|
|
55
|
+
return out;
|
|
56
|
+
}
|
|
57
|
+
function frontmatter(text) {
|
|
58
|
+
const m = FM_RE.exec(text);
|
|
59
|
+
return m ? m[1] : null;
|
|
60
|
+
}
|
|
61
|
+
function parseYamlFrontmatter(fm) {
|
|
62
|
+
const document = parseDocument(fm, { uniqueKeys: true });
|
|
63
|
+
const errors = document.errors.map((error) => error.message);
|
|
64
|
+
if (errors.length)
|
|
65
|
+
return { data: null, errors };
|
|
66
|
+
const value = document.toJS();
|
|
67
|
+
if (value === null)
|
|
68
|
+
return { data: {}, errors: [] };
|
|
69
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
70
|
+
return { data: null, errors: ["frontmatter must be a YAML mapping"] };
|
|
71
|
+
}
|
|
72
|
+
return { data: value, errors: [] };
|
|
73
|
+
}
|
|
74
|
+
var NON_ASCII = new RegExp("[" + String.fromCharCode(128) + "-" + String.fromCharCode(65535) + "]", "g");
|
|
75
|
+
function normalizePosix(p) {
|
|
76
|
+
const isAbs = p.startsWith("/");
|
|
77
|
+
const parts = p.split("/");
|
|
78
|
+
const stack = [];
|
|
79
|
+
for (const part of parts) {
|
|
80
|
+
if (part === "" || part === ".")
|
|
81
|
+
continue;
|
|
82
|
+
if (part === "..") {
|
|
83
|
+
if (stack.length && stack[stack.length - 1] !== "..")
|
|
84
|
+
stack.pop();
|
|
85
|
+
else if (!isAbs)
|
|
86
|
+
stack.push("..");
|
|
87
|
+
} else {
|
|
88
|
+
stack.push(part);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const joined = stack.join("/");
|
|
92
|
+
if (isAbs)
|
|
93
|
+
return "/" + joined;
|
|
94
|
+
return joined === "" ? "." : joined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ../kb-tools/dist/conformance.js
|
|
98
|
+
var HEADING_LOG_RE = /^##\s+(.+?)\s*$/gm;
|
|
99
|
+
var ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}$/;
|
|
100
|
+
var LINK_RE = /\]\(([^)#\s]+\.md)(#[^)]*)?\)/g;
|
|
101
|
+
function checkConformance(bundle) {
|
|
102
|
+
const errors = [];
|
|
103
|
+
const warnings = [];
|
|
104
|
+
const md = collectMarkdown(bundle);
|
|
105
|
+
const posixBasename = (rel) => rel.split("/").pop() ?? rel;
|
|
106
|
+
for (const rel of [...md].sort()) {
|
|
107
|
+
const text = readFileSync(join2(bundle, rel), "utf-8");
|
|
108
|
+
const base = posixBasename(rel);
|
|
109
|
+
const fm = frontmatter(text);
|
|
110
|
+
if (RESERVED.has(base)) {
|
|
111
|
+
if (fm !== null) {
|
|
112
|
+
const isRootIndex = rel === "index.md";
|
|
113
|
+
const parsed2 = parseYamlFrontmatter(fm);
|
|
114
|
+
if (!isRootIndex || parsed2.errors.length > 0 || !parsed2.data || !Object.prototype.hasOwnProperty.call(parsed2.data, "okf_version")) {
|
|
115
|
+
errors.push(`${rel}: reserved file must not carry frontmatter`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (base === "log.md") {
|
|
119
|
+
for (const m of text.matchAll(HEADING_LOG_RE)) {
|
|
120
|
+
if (!ISO_DATE_RE.test(m[1])) {
|
|
121
|
+
warnings.push(`${rel}: log date heading not ISO 8601: '${m[1]}'`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (fm === null) {
|
|
128
|
+
errors.push(`${rel}: concept has no parseable frontmatter`);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const parsed = parseYamlFrontmatter(fm);
|
|
132
|
+
if (parsed.errors.length > 0 || !parsed.data) {
|
|
133
|
+
errors.push(`${rel}: concept has no parseable frontmatter`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const type = parsed.data["type"];
|
|
137
|
+
if (typeof type !== "string" || !type.trim()) {
|
|
138
|
+
errors.push(`${rel}: missing or empty required 'type'`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const rel of md) {
|
|
142
|
+
const srcdir = dirname(rel) === "." ? "" : dirname(rel);
|
|
143
|
+
const text = readFileSync(join2(bundle, rel), "utf-8");
|
|
144
|
+
for (const m of text.matchAll(LINK_RE)) {
|
|
145
|
+
const tgt = m[1];
|
|
146
|
+
if (tgt.includes("://"))
|
|
147
|
+
continue;
|
|
148
|
+
const resolved = tgt.startsWith("/") ? tgt.replace(/^\/+/, "") : normalizePosix(srcdir ? `${srcdir}/${tgt}` : tgt);
|
|
149
|
+
if (!existsSync(join2(bundle, resolved))) {
|
|
150
|
+
warnings.push(`${rel}: broken link -> ${tgt}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
bundle,
|
|
156
|
+
concepts: md.filter((f) => !RESERVED.has(posixBasename(f))).length,
|
|
157
|
+
files: md.length,
|
|
158
|
+
errors,
|
|
159
|
+
warnings
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function formatReport(r) {
|
|
163
|
+
const lines = [`${r.bundle}: ${r.files} files, ${r.concepts} concepts`];
|
|
164
|
+
for (const e of r.errors)
|
|
165
|
+
lines.push(` ERROR ${e}`);
|
|
166
|
+
for (const w of r.warnings)
|
|
167
|
+
lines.push(` warn ${w}`);
|
|
168
|
+
const verdict = r.errors.length === 0 ? "CONFORMANT" : "NON-CONFORMANT";
|
|
169
|
+
lines.push(` => ${verdict} (${r.errors.length} errors, ${r.warnings.length} warnings)`);
|
|
170
|
+
return lines.join("\n");
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// ../kb-tools/dist/graph.js
|
|
174
|
+
import { readFileSync as readFileSync2, statSync as statSync3 } from "fs";
|
|
175
|
+
import { dirname as dirname2, join as join3 } from "path";
|
|
176
|
+
|
|
177
|
+
// src/headless/flags.ts
|
|
178
|
+
var VALUE_FLAGS = /* @__PURE__ */ new Set(["model", "dir", "bundle", "thread", "resume", "C"]);
|
|
179
|
+
function parseArgs(argv) {
|
|
180
|
+
const positionals = [];
|
|
181
|
+
const flags = /* @__PURE__ */ new Set();
|
|
182
|
+
const values = {};
|
|
183
|
+
for (let i = 0; i < argv.length; i++) {
|
|
184
|
+
const tok = argv[i];
|
|
185
|
+
if (tok === "--") {
|
|
186
|
+
positionals.push(...argv.slice(i + 1));
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
if (tok.startsWith("--")) {
|
|
190
|
+
const body = tok.slice(2);
|
|
191
|
+
const eq = body.indexOf("=");
|
|
192
|
+
if (eq >= 0) {
|
|
193
|
+
values[body.slice(0, eq)] = body.slice(eq + 1);
|
|
194
|
+
} else if (VALUE_FLAGS.has(body)) {
|
|
195
|
+
values[body] = argv[++i] ?? "";
|
|
196
|
+
} else {
|
|
197
|
+
flags.add(body);
|
|
198
|
+
}
|
|
199
|
+
} else if (tok.startsWith("-") && tok.length > 1) {
|
|
200
|
+
const short = tok.slice(1);
|
|
201
|
+
if (short === "p") flags.add("print");
|
|
202
|
+
else if (short === "h") flags.add("help");
|
|
203
|
+
else if (short === "v") flags.add("version");
|
|
204
|
+
else if (short === "C") values["dir"] = argv[++i] ?? "";
|
|
205
|
+
else flags.add(short);
|
|
206
|
+
} else {
|
|
207
|
+
positionals.push(tok);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
subcommand: positionals[0],
|
|
212
|
+
positionals: positionals.slice(1),
|
|
213
|
+
flags,
|
|
214
|
+
values
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/commands.ts
|
|
219
|
+
var SUBCOMMANDS = ["init", "ingest", "query", "lint", "viz"];
|
|
220
|
+
function isSubcommand(x) {
|
|
221
|
+
return SUBCOMMANDS.includes(x);
|
|
222
|
+
}
|
|
223
|
+
function commandExitCode(command, agentExitCode, conformanceErrors = 0) {
|
|
224
|
+
return command === "lint" && conformanceErrors > 0 ? 1 : agentExitCode;
|
|
225
|
+
}
|
|
226
|
+
function headlessCapabilities(command, flags) {
|
|
227
|
+
return {
|
|
228
|
+
allowEdits: command === "init" || command === "ingest" || command === "viz" || command === "lint" && flags.has("fix"),
|
|
229
|
+
allowExec: flags.has("allow-exec")
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
function buildDirective(cmd, ctx) {
|
|
233
|
+
const bundle = ctx.bundlePath;
|
|
234
|
+
switch (cmd) {
|
|
235
|
+
case "init":
|
|
236
|
+
return `Load and follow the kb-init skill to scaffold a new OKF knowledge bundle at ${bundle}. If it already exists, say so and stop rather than overwriting.`;
|
|
237
|
+
case "ingest": {
|
|
238
|
+
const sources = ctx.args.length ? ctx.args.join(", ") : "(no source given)";
|
|
239
|
+
return `Load and follow the kb-ingest skill to ingest the following source(s) into the bundle at ${bundle}: ${sources}. Integrate per the trust model \u2014 update the index and log.md.`;
|
|
240
|
+
}
|
|
241
|
+
case "query": {
|
|
242
|
+
const q = ctx.args.join(" ").trim();
|
|
243
|
+
return `Load and follow the kb-query skill to answer this question from the bundle at ${bundle}, with citations: ${q || "(no question given)"}`;
|
|
244
|
+
}
|
|
245
|
+
case "lint": {
|
|
246
|
+
const fix = ctx.flags.has("fix") ? " Run in fix mode: repair what is safe." : "";
|
|
247
|
+
return `Load and follow the kb-lint skill to health-check the bundle at ${bundle}. The deterministic conformance pass has already run; focus on the drift audit and report findings by severity.${fix}`;
|
|
248
|
+
}
|
|
249
|
+
case "viz": {
|
|
250
|
+
const scope = ctx.args.join(" ").trim();
|
|
251
|
+
return `Load and follow the kb-visualize skill to render the bundle at ${bundle} as a graph${scope ? ` scoped to: ${scope}` : ""}. Write a self-contained HTML file next to the bundle and give the path.`;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// src/version.ts
|
|
257
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
258
|
+
var packageJsonUrl = new URL("../package.json", import.meta.url);
|
|
259
|
+
function packageVersion() {
|
|
260
|
+
const metadata = JSON.parse(readFileSync3(packageJsonUrl, "utf8"));
|
|
261
|
+
if (typeof metadata !== "object" || metadata === null || !("version" in metadata) || typeof metadata.version !== "string") {
|
|
262
|
+
throw new Error("Janet's package metadata does not contain a version");
|
|
263
|
+
}
|
|
264
|
+
return metadata.version;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/main.ts
|
|
268
|
+
var HELP = `${GREETING}
|
|
269
|
+
|
|
270
|
+
Usage:
|
|
271
|
+
janet Start an interactive session (chat with Janet)
|
|
272
|
+
janet init Scaffold a new knowledge/ bundle here
|
|
273
|
+
janet ingest <src...> Ingest source(s) into the bundle
|
|
274
|
+
janet query "<question>" Answer from the bundle, with citations
|
|
275
|
+
janet lint [--fix] Health-check the bundle (conformance + drift)
|
|
276
|
+
janet viz [scope] Render the bundle as a graph
|
|
277
|
+
|
|
278
|
+
Options:
|
|
279
|
+
-C, --dir <path> Operate on <path> instead of the current directory
|
|
280
|
+
--bundle <path> Bundle location within <dir> (default: knowledge)
|
|
281
|
+
-p, --print Headless: stream to stdout and exit
|
|
282
|
+
--model <provider/id> Model to use (or set JANET_MODEL)
|
|
283
|
+
--thread <id> Resume a thread
|
|
284
|
+
--allow-exec Allow shell commands in a one-shot run
|
|
285
|
+
-h, --help Show this help
|
|
286
|
+
-v, --version Show version
|
|
287
|
+
|
|
288
|
+
Also installed as \`ding\` (you summon Janet with a ding).`;
|
|
289
|
+
function resolveModelId(values) {
|
|
290
|
+
const selected = values["model"] ?? process.env["JANET_MODEL"] ?? loadSettings().defaultModelId ?? void 0;
|
|
291
|
+
return selected ? normalizeModelSelection(selected, availableModels()) : void 0;
|
|
292
|
+
}
|
|
293
|
+
async function main(argv) {
|
|
294
|
+
const parsed = parseArgs(argv);
|
|
295
|
+
if (parsed.flags.has("help") || parsed.subcommand === "help") {
|
|
296
|
+
process.stdout.write(HELP + "\n");
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
if (parsed.flags.has("version")) {
|
|
300
|
+
process.stdout.write(packageVersion() + "\n");
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
const dir = parsed.values["dir"];
|
|
304
|
+
const bundleOverride = parsed.values["bundle"];
|
|
305
|
+
const paths = resolveProjectPaths({ dir, bundle: bundleOverride });
|
|
306
|
+
const modelId = resolveModelId(parsed.values);
|
|
307
|
+
const threadId = parsed.values["thread"] ?? parsed.values["resume"];
|
|
308
|
+
const headless = parsed.flags.has("print") || !process.stdout.isTTY;
|
|
309
|
+
const sub = parsed.subcommand;
|
|
310
|
+
if (!sub) {
|
|
311
|
+
if (!headless) {
|
|
312
|
+
const { runTui } = await import("./tui-VZVO7UHV.js");
|
|
313
|
+
if (modelId && !process.env["JANET_MODEL"]) process.env["JANET_MODEL"] = modelId;
|
|
314
|
+
return runTui({ dir, bundle: bundleOverride, threadId });
|
|
315
|
+
}
|
|
316
|
+
process.stderr.write("No subcommand. Try `janet --help`.\n");
|
|
317
|
+
return 2;
|
|
318
|
+
}
|
|
319
|
+
if (!isSubcommand(sub)) {
|
|
320
|
+
process.stderr.write(`Unknown command: ${sub}
|
|
321
|
+
Try \`janet --help\`.
|
|
322
|
+
`);
|
|
323
|
+
return 2;
|
|
324
|
+
}
|
|
325
|
+
let conformanceErrors = 0;
|
|
326
|
+
if (sub === "lint") {
|
|
327
|
+
if (!existsSync2(paths.bundlePath)) {
|
|
328
|
+
process.stderr.write(
|
|
329
|
+
`No bundle at ${paths.bundlePath}. Run \`janet init\` to scaffold one.
|
|
330
|
+
`
|
|
331
|
+
);
|
|
332
|
+
return 2;
|
|
333
|
+
}
|
|
334
|
+
const report = checkConformance(paths.bundlePath);
|
|
335
|
+
conformanceErrors = report.errors.length;
|
|
336
|
+
process.stdout.write(formatReport(report) + "\n");
|
|
337
|
+
if (!modelId) {
|
|
338
|
+
process.stdout.write(
|
|
339
|
+
"\n(No model configured \u2014 ran the deterministic conformance pass only. Set --model or JANET_MODEL for the drift audit.)\n"
|
|
340
|
+
);
|
|
341
|
+
return report.errors.length ? 1 : 0;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
if (sub !== "init" && !existsSync2(paths.bundlePath)) {
|
|
345
|
+
process.stderr.write(
|
|
346
|
+
`No bundle at ${paths.bundlePath}. Run \`janet init\` to scaffold one.
|
|
347
|
+
`
|
|
348
|
+
);
|
|
349
|
+
return 2;
|
|
350
|
+
}
|
|
351
|
+
const directive = buildDirective(sub, {
|
|
352
|
+
bundlePath: paths.bundlePath,
|
|
353
|
+
args: parsed.positionals,
|
|
354
|
+
flags: parsed.flags
|
|
355
|
+
});
|
|
356
|
+
const capabilities = headlessCapabilities(sub, parsed.flags);
|
|
357
|
+
const result = await runHeadless({
|
|
358
|
+
message: directive,
|
|
359
|
+
dir,
|
|
360
|
+
bundle: bundleOverride,
|
|
361
|
+
modelId,
|
|
362
|
+
threadId,
|
|
363
|
+
...capabilities
|
|
364
|
+
});
|
|
365
|
+
return commandExitCode(sub, result.exitCode, conformanceErrors);
|
|
366
|
+
}
|
|
367
|
+
main(process.argv.slice(2)).then((code) => process.exit(code)).catch((err) => {
|
|
368
|
+
process.stderr.write(`
|
|
369
|
+
Janet hit a snag: ${err?.message ?? err}
|
|
370
|
+
`);
|
|
371
|
+
process.exit(1);
|
|
372
|
+
});
|
|
373
|
+
//# sourceMappingURL=main.js.map
|
package/dist/main.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/main.ts","../../kb-tools/src/conformance.ts","../../kb-tools/src/shared.ts","../../kb-tools/src/graph.ts","../src/headless/flags.ts","../src/commands.ts","../src/version.ts"],"sourcesContent":["import { existsSync } from \"node:fs\";\nimport { checkConformance, formatReport } from \"@agent-knowledge/kb-tools\";\nimport { loadSettings } from \"./onboarding/settings.js\";\nimport { availableModels, normalizeModelSelection } from \"./onboarding/providers.js\";\nimport { parseArgs } from \"./headless/flags.js\";\nimport { runHeadless } from \"./headless/run.js\";\nimport {\n buildDirective,\n commandExitCode,\n headlessCapabilities,\n isSubcommand,\n} from \"./commands.js\";\nimport { resolveProjectPaths } from \"./agent/paths.js\";\nimport { GREETING } from \"./agent/persona.js\";\nimport { packageVersion } from \"./version.js\";\n\nconst HELP = `${GREETING}\n\nUsage:\n janet Start an interactive session (chat with Janet)\n janet init Scaffold a new knowledge/ bundle here\n janet ingest <src...> Ingest source(s) into the bundle\n janet query \"<question>\" Answer from the bundle, with citations\n janet lint [--fix] Health-check the bundle (conformance + drift)\n janet viz [scope] Render the bundle as a graph\n\nOptions:\n -C, --dir <path> Operate on <path> instead of the current directory\n --bundle <path> Bundle location within <dir> (default: knowledge)\n -p, --print Headless: stream to stdout and exit\n --model <provider/id> Model to use (or set JANET_MODEL)\n --thread <id> Resume a thread\n --allow-exec Allow shell commands in a one-shot run\n -h, --help Show this help\n -v, --version Show version\n\nAlso installed as \\`ding\\` (you summon Janet with a ding).`;\n\nfunction resolveModelId(values: Record<string, string>): string | undefined {\n const selected =\n values[\"model\"] ??\n process.env[\"JANET_MODEL\"] ??\n loadSettings().defaultModelId ??\n undefined;\n return selected ? normalizeModelSelection(selected, availableModels()) : undefined;\n}\n\nasync function main(argv: string[]): Promise<number> {\n const parsed = parseArgs(argv);\n\n if (parsed.flags.has(\"help\") || parsed.subcommand === \"help\") {\n process.stdout.write(HELP + \"\\n\");\n return 0;\n }\n if (parsed.flags.has(\"version\")) {\n process.stdout.write(packageVersion() + \"\\n\");\n return 0;\n }\n\n const dir = parsed.values[\"dir\"];\n const bundleOverride = parsed.values[\"bundle\"];\n const paths = resolveProjectPaths({ dir, bundle: bundleOverride });\n const modelId = resolveModelId(parsed.values);\n const threadId = parsed.values[\"thread\"] ?? parsed.values[\"resume\"];\n const headless = parsed.flags.has(\"print\") || !process.stdout.isTTY;\n\n const sub = parsed.subcommand;\n\n // No subcommand → interactive TUI (chat).\n if (!sub) {\n if (!headless) {\n const { runTui } = await import(\"./tui/index.js\");\n if (modelId && !process.env[\"JANET_MODEL\"]) process.env[\"JANET_MODEL\"] = modelId;\n return runTui({ dir, bundle: bundleOverride, threadId });\n }\n process.stderr.write(\"No subcommand. Try `janet --help`.\\n\");\n return 2;\n }\n\n if (!isSubcommand(sub)) {\n process.stderr.write(`Unknown command: ${sub}\\nTry \\`janet --help\\`.\\n`);\n return 2;\n }\n\n // `lint` runs the deterministic conformance check in-process first (no tokens,\n // CI-gateable), then hands the drift audit to the agent.\n let conformanceErrors = 0;\n if (sub === \"lint\") {\n if (!existsSync(paths.bundlePath)) {\n process.stderr.write(\n `No bundle at ${paths.bundlePath}. Run \\`janet init\\` to scaffold one.\\n`,\n );\n return 2;\n }\n const report = checkConformance(paths.bundlePath);\n conformanceErrors = report.errors.length;\n process.stdout.write(formatReport(report) + \"\\n\");\n // If no model is configured, stop after the deterministic pass (still useful\n // and exit-coded for CI).\n if (!modelId) {\n process.stdout.write(\n \"\\n(No model configured — ran the deterministic conformance pass only. \" +\n \"Set --model or JANET_MODEL for the drift audit.)\\n\",\n );\n return report.errors.length ? 1 : 0;\n }\n }\n\n // Bundle must exist for ingest/query/lint/viz (init creates it).\n if (sub !== \"init\" && !existsSync(paths.bundlePath)) {\n process.stderr.write(\n `No bundle at ${paths.bundlePath}. Run \\`janet init\\` to scaffold one.\\n`,\n );\n return 2;\n }\n\n const directive = buildDirective(sub, {\n bundlePath: paths.bundlePath,\n args: parsed.positionals,\n flags: parsed.flags,\n });\n const capabilities = headlessCapabilities(sub, parsed.flags);\n\n const result = await runHeadless({\n message: directive,\n dir,\n bundle: bundleOverride,\n modelId,\n threadId,\n ...capabilities,\n });\n return commandExitCode(sub, result.exitCode, conformanceErrors);\n}\n\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\n .catch((err) => {\n process.stderr.write(`\\nJanet hit a snag: ${err?.message ?? err}\\n`);\n process.exit(1);\n });\n","/**\n * Deterministic OKF v0.1 conformance check for a knowledge bundle (SPEC §9).\n *\n * A TypeScript port of skills/kb-lint/scripts/conformance.py, behaviour-identical.\n * ERRORs fail conformance; broken links and soft-guidance issues are WARN and\n * never fail (SPEC §5.3 / §9 — consumers MUST tolerate them). Structure only;\n * drift is the fuzzy, agent-driven half of kb-lint.\n */\nimport { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport {\n RESERVED,\n collectMarkdown,\n frontmatter,\n normalizePosix,\n parseYamlFrontmatter,\n pythonJson,\n} from \"./shared.js\";\n\nconst HEADING_LOG_RE = /^##\\s+(.+?)\\s*$/gm;\nconst ISO_DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst LINK_RE = /\\]\\(([^)#\\s]+\\.md)(#[^)]*)?\\)/g;\n\nexport interface ConformanceReport {\n bundle: string;\n concepts: number;\n files: number;\n errors: string[];\n warnings: string[];\n}\n\nexport function checkConformance(bundle: string): ConformanceReport {\n const errors: string[] = [];\n const warnings: string[] = [];\n const md = collectMarkdown(bundle);\n\n const posixBasename = (rel: string): string => rel.split(\"/\").pop() ?? rel;\n\n for (const rel of [...md].sort()) {\n const text = readFileSync(join(bundle, rel), \"utf-8\");\n const base = posixBasename(rel);\n const fm = frontmatter(text);\n\n if (RESERVED.has(base)) {\n // Reserved files carry no frontmatter, except the ROOT index.md may\n // declare okf_version (SPEC §6/§11).\n if (fm !== null) {\n const isRootIndex = rel === \"index.md\";\n const parsed = parseYamlFrontmatter(fm);\n if (\n !isRootIndex ||\n parsed.errors.length > 0 ||\n !parsed.data ||\n !Object.prototype.hasOwnProperty.call(parsed.data, \"okf_version\")\n ) {\n errors.push(`${rel}: reserved file must not carry frontmatter`);\n }\n }\n if (base === \"log.md\") {\n for (const m of text.matchAll(HEADING_LOG_RE)) {\n if (!ISO_DATE_RE.test(m[1]!)) {\n warnings.push(`${rel}: log date heading not ISO 8601: '${m[1]}'`);\n }\n }\n }\n continue;\n }\n\n // Concept document: rules 1 & 2.\n if (fm === null) {\n errors.push(`${rel}: concept has no parseable frontmatter`);\n continue;\n }\n const parsed = parseYamlFrontmatter(fm);\n if (parsed.errors.length > 0 || !parsed.data) {\n errors.push(`${rel}: concept has no parseable frontmatter`);\n continue;\n }\n const type = parsed.data[\"type\"];\n if (typeof type !== \"string\" || !type.trim()) {\n errors.push(`${rel}: missing or empty required 'type'`);\n }\n }\n\n // Broken relative links → WARN only (never a conformance failure).\n for (const rel of md) {\n const srcdir = dirname(rel) === \".\" ? \"\" : dirname(rel);\n const text = readFileSync(join(bundle, rel), \"utf-8\");\n for (const m of text.matchAll(LINK_RE)) {\n const tgt = m[1]!;\n if (tgt.includes(\"://\")) continue;\n const resolved = tgt.startsWith(\"/\")\n ? tgt.replace(/^\\/+/, \"\")\n : normalizePosix(srcdir ? `${srcdir}/${tgt}` : tgt);\n if (!existsSync(join(bundle, resolved))) {\n warnings.push(`${rel}: broken link -> ${tgt}`);\n }\n }\n }\n\n return {\n bundle,\n concepts: md.filter((f) => !RESERVED.has(posixBasename(f))).length,\n files: md.length,\n errors,\n warnings,\n };\n}\n\nexport function formatReport(r: ConformanceReport): string {\n const lines = [`${r.bundle}: ${r.files} files, ${r.concepts} concepts`];\n for (const e of r.errors) lines.push(` ERROR ${e}`);\n for (const w of r.warnings) lines.push(` warn ${w}`);\n const verdict = r.errors.length === 0 ? \"CONFORMANT\" : \"NON-CONFORMANT\";\n lines.push(` => ${verdict} (${r.errors.length} errors, ${r.warnings.length} warnings)`);\n return lines.join(\"\\n\");\n}\n\nexport function runCli(argv: string[]): number {\n const args = argv.filter((a) => !a.startsWith(\"--\"));\n const asJson = argv.includes(\"--json\");\n const bundle = args[0] ?? \".\";\n let isDir = false;\n try {\n isDir = statSync(bundle).isDirectory();\n } catch {\n isDir = false;\n }\n if (!isDir) {\n process.stderr.write(`not a directory: ${bundle}\\n`);\n return 2;\n }\n const r = checkConformance(bundle);\n if (asJson) {\n process.stdout.write(pythonJson(r) + \"\\n\");\n } else {\n process.stdout.write(formatReport(r) + \"\\n\");\n }\n return r.errors.length ? 1 : 0;\n}\n","import { readdirSync, statSync } from \"node:fs\";\nimport { join, relative, sep } from \"node:path\";\nimport { parseDocument } from \"yaml\";\n\n/** Frontmatter block at the very top, accepting LF or CRLF. */\nexport const FM_RE = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/;\n\n/** Reserved (non-concept) filenames. */\nexport const RESERVED = new Set([\"index.md\", \"log.md\"]);\n\n/**\n * Recursively collect `.md` files under `bundle`, returned as bundle-relative\n * POSIX paths. Directory entries are sorted so traversal is deterministic\n * across platforms (Python's `sorted(md)` callers rely on this ordering).\n */\nexport function collectMarkdown(bundle: string): string[] {\n const out: string[] = [];\n const walk = (dir: string): void => {\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return;\n }\n for (const name of entries) {\n const full = join(dir, name);\n let st;\n try {\n st = statSync(full);\n } catch {\n continue;\n }\n if (st.isDirectory()) {\n walk(full);\n } else if (name.endsWith(\".md\")) {\n out.push(relative(bundle, full).split(sep).join(\"/\"));\n }\n }\n };\n walk(bundle);\n return out;\n}\n\n/** Extract the raw frontmatter text, or null if none. */\nexport function frontmatter(text: string): string | null {\n const m = FM_RE.exec(text);\n return m ? m[1]! : null;\n}\n\nexport interface YamlFrontmatter {\n data: Record<string, unknown> | null;\n errors: string[];\n}\n\n/** Parse frontmatter as a YAML mapping and retain parser diagnostics. */\nexport function parseYamlFrontmatter(fm: string): YamlFrontmatter {\n const document = parseDocument(fm, { uniqueKeys: true });\n const errors = document.errors.map((error) => error.message);\n if (errors.length) return { data: null, errors };\n const value = document.toJS() as unknown;\n if (value === null) return { data: {}, errors: [] };\n if (typeof value !== \"object\" || Array.isArray(value)) {\n return { data: null, errors: [\"frontmatter must be a YAML mapping\"] };\n }\n return { data: value as Record<string, unknown>, errors: [] };\n}\n\n/** Strip a bundle-relative `.md` path to its concept id. */\nexport function conceptId(rel: string): string {\n return rel.endsWith(\".md\") ? rel.slice(0, -3) : rel;\n}\n\n// Matches any character in U+0080..U+FFFF (built programmatically to keep the\n// source ASCII-clean and unambiguous).\nconst NON_ASCII = new RegExp(\"[\" + String.fromCharCode(0x80) + \"-\" + String.fromCharCode(0xffff) + \"]\", \"g\");\n\n/**\n * JSON.stringify with 2-space indent, escaping non-ASCII as \\uXXXX so output is\n * byte-identical to Python's `json.dumps(..., indent=2)` (ensure_ascii=True).\n */\nexport function pythonJson(value: unknown): string {\n return JSON.stringify(value, null, 2).replace(\n NON_ASCII,\n (c) => \"\\\\u\" + c.charCodeAt(0).toString(16).padStart(4, \"0\"),\n );\n}\n\n/** POSIX path normalize matching Python's posixpath.normpath for our inputs. */\nexport function normalizePosix(p: string): string {\n const isAbs = p.startsWith(\"/\");\n const parts = p.split(\"/\");\n const stack: string[] = [];\n for (const part of parts) {\n if (part === \"\" || part === \".\") continue;\n if (part === \"..\") {\n if (stack.length && stack[stack.length - 1] !== \"..\") stack.pop();\n else if (!isAbs) stack.push(\"..\");\n } else {\n stack.push(part);\n }\n }\n const joined = stack.join(\"/\");\n if (isAbs) return \"/\" + joined;\n return joined === \"\" ? \".\" : joined;\n}\n","/**\n * Extract the graph model of an OKF bundle — the deterministic half of\n * kb-visualize. A TypeScript port of skills/kb-visualize/scripts/graph.py,\n * behaviour-identical. The agent renders this model into a view.\n *\n * Node id = concept id = path within the bundle minus `.md`. Reserved\n * index.md/log.md are excluded. Links are resolved to concept ids; links whose\n * target is not a concept in the bundle are dropped (SPEC §5.3 tolerates them).\n */\nimport { readFileSync, statSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport {\n FM_RE,\n RESERVED,\n collectMarkdown,\n conceptId,\n normalizePosix,\n parseYamlFrontmatter,\n pythonJson,\n} from \"./shared.js\";\n\nconst LINK_RE = /\\[[^\\]]*\\]\\(([^)#\\s]+\\.md)(?:#[^)]*)?\\)/g;\n\nexport interface GraphNode {\n id: string;\n path: string;\n type: string;\n title: string;\n description: string;\n tags: string[];\n resource: string;\n status: string;\n body: string;\n links: string[];\n cited_by: string[];\n}\n\nexport interface GraphModel {\n bundle: string;\n nodes: GraphNode[];\n types: string[];\n edges: { source: string; target: string }[];\n}\n\ntype FrontmatterData = Record<string, unknown>;\n\n/** Parse YAML for graph metadata; malformed frontmatter degrades to an empty map. */\nexport function parseFrontmatter(fm: string): FrontmatterData {\n return parseYamlFrontmatter(fm).data ?? {};\n}\n\nfunction scalar(data: FrontmatterData, k: string, dflt: string): string {\n const v = data[k];\n if (v === undefined) return dflt;\n return typeof v === \"string\" ? v : dflt;\n}\n\n/** Resolve a markdown link target (relative or bundle-absolute) to a concept id. */\nfunction resolve(srcRel: string, target: string): string {\n const resolved = target.startsWith(\"/\")\n ? target.replace(/^\\/+/, \"\")\n : normalizePosix(`${dirname(srcRel) === \".\" ? \"\" : dirname(srcRel)}/${target}`.replace(/^\\//, \"\"));\n return conceptId(resolved);\n}\n\nexport function extractGraph(bundle: string): GraphModel {\n const md = collectMarkdown(bundle);\n const posixBasename = (rel: string): string => rel.split(\"/\").pop() ?? rel;\n\n const ids = new Set<string>();\n for (const rel of md) {\n if (RESERVED.has(posixBasename(rel))) continue;\n ids.add(conceptId(rel));\n }\n\n const nodes = new Map<string, GraphNode>();\n for (const rel of [...md].sort()) {\n if (RESERVED.has(posixBasename(rel))) continue;\n const text = readFileSync(join(bundle, rel), \"utf-8\");\n const m = FM_RE.exec(text);\n const fm = m ? parseFrontmatter(m[1]!) : {};\n const body = m ? text.slice(m[0].length) : text;\n const cid = conceptId(rel);\n\n const links: string[] = [];\n for (const lm of body.matchAll(LINK_RE)) {\n const tgt = lm[1]!;\n if (tgt.includes(\"://\")) continue;\n const rid = resolve(rel, tgt);\n if (ids.has(rid) && rid !== cid && !links.includes(rid)) links.push(rid);\n }\n\n const rawTags = fm[\"tags\"];\n const tags = Array.isArray(rawTags)\n ? rawTags.filter((tag): tag is string => typeof tag === \"string\")\n : typeof rawTags === \"string\"\n ? [rawTags]\n : [];\n\n nodes.set(cid, {\n id: cid,\n path: rel,\n type: scalar(fm, \"type\", \"\"),\n title: scalar(fm, \"title\", cid.split(\"/\").pop() ?? cid),\n description: scalar(fm, \"description\", \"\"),\n tags,\n resource: scalar(fm, \"resource\", \"\"),\n status: scalar(fm, \"status\", \"active\"),\n body: body.trim(),\n links,\n cited_by: [],\n });\n }\n\n const edges: { source: string; target: string }[] = [];\n for (const n of nodes.values()) {\n for (const tgt of n.links) {\n edges.push({ source: n.id, target: tgt });\n nodes.get(tgt)!.cited_by.push(n.id);\n }\n }\n\n const types = [...new Set([...nodes.values()].map((n) => n.type).filter((t) => t))].sort();\n return { bundle, nodes: [...nodes.values()], types, edges };\n}\n\nexport function runCli(argv: string[]): number {\n const bundle = argv.find((a) => !a.startsWith(\"--\")) ?? \".\";\n let isDir = false;\n try {\n isDir = statSync(bundle).isDirectory();\n } catch {\n isDir = false;\n }\n if (!isDir) {\n process.stderr.write(`not a directory: ${bundle}\\n`);\n return 2;\n }\n process.stdout.write(pythonJson(extractGraph(bundle)) + \"\\n\");\n return 0;\n}\n","export interface ParsedArgs {\n /** First positional token (subcommand or undefined). */\n subcommand?: string;\n /** Remaining positional tokens. */\n positionals: string[];\n /** Boolean flags present (e.g. \"fix\", \"print\", \"help\"). */\n flags: Set<string>;\n /** Value flags (e.g. --model x, --dir path, --bundle path, --thread id). */\n values: Record<string, string>;\n}\n\nconst VALUE_FLAGS = new Set([\"model\", \"dir\", \"bundle\", \"thread\", \"resume\", \"C\"]);\n\n/**\n * Minimal arg parser. Supports `--flag`, `--key value`, `--key=value`, short\n * `-p`/`-h`/`-C`, and positionals. Deliberately dependency-free.\n */\nexport function parseArgs(argv: string[]): ParsedArgs {\n const positionals: string[] = [];\n const flags = new Set<string>();\n const values: Record<string, string> = {};\n\n for (let i = 0; i < argv.length; i++) {\n const tok = argv[i]!;\n if (tok === \"--\") {\n positionals.push(...argv.slice(i + 1));\n break;\n }\n if (tok.startsWith(\"--\")) {\n const body = tok.slice(2);\n const eq = body.indexOf(\"=\");\n if (eq >= 0) {\n values[body.slice(0, eq)] = body.slice(eq + 1);\n } else if (VALUE_FLAGS.has(body)) {\n values[body] = argv[++i] ?? \"\";\n } else {\n flags.add(body);\n }\n } else if (tok.startsWith(\"-\") && tok.length > 1) {\n const short = tok.slice(1);\n if (short === \"p\") flags.add(\"print\");\n else if (short === \"h\") flags.add(\"help\");\n else if (short === \"v\") flags.add(\"version\");\n else if (short === \"C\") values[\"dir\"] = argv[++i] ?? \"\";\n else flags.add(short);\n } else {\n positionals.push(tok);\n }\n }\n\n return {\n subcommand: positionals[0],\n positionals: positionals.slice(1),\n flags,\n values,\n };\n}\n","/**\n * Subcommand → skill directive mapping. Each CLI subcommand becomes a message\n * telling Janet to load and follow the matching kb-* skill against the target\n * bundle. The procedures live in the skills; this only routes to them.\n */\nexport type SubcommandName = \"init\" | \"ingest\" | \"query\" | \"lint\" | \"viz\";\n\nexport interface DirectiveContext {\n bundlePath: string;\n /** Positional args after the subcommand (sources, query text, scope, etc.). */\n args: string[];\n /** Flags like --fix. */\n flags: Set<string>;\n}\n\nexport const SUBCOMMANDS: readonly SubcommandName[] = [\"init\", \"ingest\", \"query\", \"lint\", \"viz\"];\n\nexport function isSubcommand(x: string): x is SubcommandName {\n return (SUBCOMMANDS as readonly string[]).includes(x);\n}\n\n/** Preserve deterministic lint failures even when the agent audit itself succeeds. */\nexport function commandExitCode(\n command: SubcommandName,\n agentExitCode: number,\n conformanceErrors: number = 0,\n): number {\n return command === \"lint\" && conformanceErrors > 0 ? 1 : agentExitCode;\n}\n\nexport function headlessCapabilities(command: SubcommandName, flags: Set<string>) {\n return {\n allowEdits:\n command === \"init\" ||\n command === \"ingest\" ||\n command === \"viz\" ||\n (command === \"lint\" && flags.has(\"fix\")),\n allowExec: flags.has(\"allow-exec\"),\n };\n}\n\nexport function buildDirective(cmd: SubcommandName, ctx: DirectiveContext): string {\n const bundle = ctx.bundlePath;\n switch (cmd) {\n case \"init\":\n return `Load and follow the kb-init skill to scaffold a new OKF knowledge bundle at ${bundle}. If it already exists, say so and stop rather than overwriting.`;\n case \"ingest\": {\n const sources = ctx.args.length ? ctx.args.join(\", \") : \"(no source given)\";\n return `Load and follow the kb-ingest skill to ingest the following source(s) into the bundle at ${bundle}: ${sources}. Integrate per the trust model — update the index and log.md.`;\n }\n case \"query\": {\n const q = ctx.args.join(\" \").trim();\n return `Load and follow the kb-query skill to answer this question from the bundle at ${bundle}, with citations: ${q || \"(no question given)\"}`;\n }\n case \"lint\": {\n const fix = ctx.flags.has(\"fix\") ? \" Run in fix mode: repair what is safe.\" : \"\";\n return `Load and follow the kb-lint skill to health-check the bundle at ${bundle}. The deterministic conformance pass has already run; focus on the drift audit and report findings by severity.${fix}`;\n }\n case \"viz\": {\n const scope = ctx.args.join(\" \").trim();\n return `Load and follow the kb-visualize skill to render the bundle at ${bundle} as a graph${scope ? ` scoped to: ${scope}` : \"\"}. Write a self-contained HTML file next to the bundle and give the path.`;\n }\n }\n}\n","import { readFileSync } from \"node:fs\";\n\nconst packageJsonUrl = new URL(\"../package.json\", import.meta.url);\n\nexport function packageVersion(): string {\n const metadata: unknown = JSON.parse(readFileSync(packageJsonUrl, \"utf8\"));\n\n if (\n typeof metadata !== \"object\" ||\n metadata === null ||\n !(\"version\" in metadata) ||\n typeof metadata.version !== \"string\"\n ) {\n throw new Error(\"Janet's package metadata does not contain a version\");\n }\n\n return metadata.version;\n}\n"],"mappings":"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","names":["existsSync","statSync","join","join","parsed","readFileSync","statSync","dirname","join","readFileSync","existsSync"]}
|