@monadeo.com/grimoire-cli 0.13.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/dist/index.js +40 -11
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -32,8 +32,8 @@ token instead of logging in. `GRIMOIRE_API_URL` overrides the API origin.
|
|
|
32
32
|
| Command | What it does |
|
|
33
33
|
|---|---|
|
|
34
34
|
| `grimoire search "<query>" [-s nextjs@15 -s react] [--reranker <name>] [--json\|--compact] [--debug] [--verbose]` | Search one or more sources. `--reranker` picks one of the rerankers `grimoire whoami` lists for your account; `--verbose` prints on stderr how long each stage took and which reranker ran. |
|
|
35
|
-
| `grimoire sources [--q <keyword>] [--names\|--json]` | List indexed sources |
|
|
36
|
-
| `grimoire versions <product> [--json]` | Versions indexed for a product |
|
|
35
|
+
| `grimoire sources [--q <keyword>] [--names\|--json]` | List sources with version, stage (queued, crawling n/m, indexing n/m, indexed date, failed) and URL; sources still in progress come first |
|
|
36
|
+
| `grimoire versions <product> [--json]` | Versions indexed for a product, with chunk count and the date each was indexed |
|
|
37
37
|
| `grimoire doc <point_id> [--window 2] [--json]` | A chunk with its neighbours |
|
|
38
38
|
| `grimoire report <point_id> --verdict helpful\|incorrect\|outdated [--note "..."]` | Tell us a result was wrong |
|
|
39
39
|
|
|
@@ -51,11 +51,13 @@ token instead of logging in. `GRIMOIRE_API_URL` overrides the API origin.
|
|
|
51
51
|
|
|
52
52
|
| Command | What it does |
|
|
53
53
|
|---|---|
|
|
54
|
-
| `grimoire ingest <url> --product <name> (--rolling \| --fixed <v> \| --npm <pkg> \| --pypi <pkg> \| --github <owner/repo>) [--include <pattern>]... [--exclude <pattern>]... [--watch]` | Submit a documentation site |
|
|
54
|
+
| `grimoire ingest <url> --product <name> (--rolling \| --fixed <v> \| --npm <pkg> \| --pypi <pkg> \| --github <owner/repo> [--tag-pattern <regex>]) [--include <pattern>]... [--exclude <pattern>]... [--watch]` | Submit a documentation site |
|
|
55
55
|
| `grimoire jobs <job_id> [--watch]` | Follow one job |
|
|
56
56
|
|
|
57
57
|
Every source needs a version rule: `--rolling` for docs without releases, otherwise the
|
|
58
|
-
release probe that tells Grimoire when a new version ships.
|
|
58
|
+
release probe that tells Grimoire when a new version ships. When a GitHub release tag is
|
|
59
|
+
not a plain `v1.2.3`, give `--tag-pattern` a regular expression whose first group is the
|
|
60
|
+
version, for example `--tag-pattern 'release-(\d+\.\d+\.\d+)'` for nginx.
|
|
59
61
|
|
|
60
62
|
## Staff
|
|
61
63
|
|
package/dist/index.js
CHANGED
|
@@ -557,7 +557,7 @@ function requireFlagOneOf(parsed, name, allowed, usage) {
|
|
|
557
557
|
}
|
|
558
558
|
|
|
559
559
|
// src/help.ts
|
|
560
|
-
var VERSION = true ? "0.
|
|
560
|
+
var VERSION = true ? "0.14.0" : "dev";
|
|
561
561
|
var HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents
|
|
562
562
|
|
|
563
563
|
grimoire login [--no-launch-browser] | logout | whoami
|
|
@@ -570,7 +570,7 @@ var HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents
|
|
|
570
570
|
grimoire update
|
|
571
571
|
grimoire doc <point_id> [--window 2] [--json]
|
|
572
572
|
grimoire report <point_id> --verdict helpful|incorrect|outdated [--note "..."]
|
|
573
|
-
grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)
|
|
573
|
+
grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>])
|
|
574
574
|
[--include <pattern>]... [--exclude <pattern>]... [--watch]
|
|
575
575
|
grimoire jobs <job_id> [--watch]
|
|
576
576
|
grimoire staff queue [--json] | approve <job_id> | reject <job_id> --reason "..."
|
|
@@ -582,7 +582,7 @@ var HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents
|
|
|
582
582
|
grimoire staff source <product|id> [--include <pattern>]... [--exclude <pattern>]... [--status active|disabled] [--markdown on|off]
|
|
583
583
|
grimoire staff source <product|id> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)
|
|
584
584
|
grimoire staff urls <product|id> [--state <crawl state>] [--limit 50] [--json]
|
|
585
|
-
grimoire staff create <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>) [--include <pattern>]... [--exclude <pattern>]...
|
|
585
|
+
grimoire staff create <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>]) [--include <pattern>]... [--exclude <pattern>]...
|
|
586
586
|
grimoire staff upload <product|id> <page-url> <file.html>
|
|
587
587
|
grimoire staff recrawl <product|id> | reindex <product|id> | purge <product|id> --yes
|
|
588
588
|
grimoire mcp [--http]
|
|
@@ -612,9 +612,9 @@ var COMMAND_FLAGS = {
|
|
|
612
612
|
versions: ["json"],
|
|
613
613
|
doc: ["window", "json"],
|
|
614
614
|
report: ["verdict", "note"],
|
|
615
|
-
ingest: ["product", "rolling", "fixed", "npm", "pypi", "github", "include", "exclude", "watch"],
|
|
615
|
+
ingest: ["product", "rolling", "fixed", "npm", "pypi", "github", "tag-pattern", "include", "exclude", "watch"],
|
|
616
616
|
jobs: ["watch"],
|
|
617
|
-
staff: ["reason", "name", "quota", "json", "source", "state", "kind", "limit", "include", "exclude", "status", "markdown", "yes", "watch", "rolling", "fixed", "npm", "pypi", "github", "staff", "product"]
|
|
617
|
+
staff: ["reason", "name", "quota", "json", "source", "state", "kind", "limit", "include", "exclude", "status", "markdown", "yes", "watch", "rolling", "fixed", "npm", "pypi", "github", "tag-pattern", "staff", "product"]
|
|
618
618
|
};
|
|
619
619
|
|
|
620
620
|
// src/output.ts
|
|
@@ -944,7 +944,7 @@ function runUpdate() {
|
|
|
944
944
|
|
|
945
945
|
// src/commands/ingest.ts
|
|
946
946
|
function submissionFromArgs(url, args) {
|
|
947
|
-
const usage = "Usage: grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)";
|
|
947
|
+
const usage = "Usage: grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>])";
|
|
948
948
|
const product = args.flags.product?.[0];
|
|
949
949
|
if (!product) throw new UsageError(usage);
|
|
950
950
|
const fixed = args.flags.fixed?.[0];
|
|
@@ -964,7 +964,14 @@ function submissionFromArgs(url, args) {
|
|
|
964
964
|
if (fixed) return { ...body, version_rule: { kind: "fixed", value: fixed } };
|
|
965
965
|
if (npm) return { ...body, version_rule: { kind: "fixed" }, probe: { kind: "npm", package: npm } };
|
|
966
966
|
if (pypi) return { ...body, version_rule: { kind: "fixed" }, probe: { kind: "pypi", package: pypi } };
|
|
967
|
-
if (github)
|
|
967
|
+
if (github) {
|
|
968
|
+
const tagPattern = args.flags["tag-pattern"]?.[0];
|
|
969
|
+
return {
|
|
970
|
+
...body,
|
|
971
|
+
version_rule: { kind: "fixed" },
|
|
972
|
+
probe: { kind: "github", repo: github, ...tagPattern ? { tag_pattern: tagPattern } : {} }
|
|
973
|
+
};
|
|
974
|
+
}
|
|
968
975
|
throw new UsageError(`${usage}
|
|
969
976
|
A version rule is mandatory: --rolling for unversioned docs, --fixed, or a release probe.`);
|
|
970
977
|
}
|
|
@@ -1088,7 +1095,10 @@ function versioningFromArgs(args) {
|
|
|
1088
1095
|
if (fixed) return { version_rule: { kind: "fixed", value: fixed } };
|
|
1089
1096
|
if (npm) return { version_rule: { kind: "fixed" }, probe: { kind: "npm", package: npm } };
|
|
1090
1097
|
if (pypi) return { version_rule: { kind: "fixed" }, probe: { kind: "pypi", package: pypi } };
|
|
1091
|
-
if (github)
|
|
1098
|
+
if (github) {
|
|
1099
|
+
const tagPattern = args.flags["tag-pattern"]?.[0];
|
|
1100
|
+
return { version_rule: { kind: "fixed" }, probe: { kind: "github", repo: github, ...tagPattern ? { tag_pattern: tagPattern } : {} } };
|
|
1101
|
+
}
|
|
1092
1102
|
return {};
|
|
1093
1103
|
}
|
|
1094
1104
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -1113,6 +1123,18 @@ function describeSource(detail) {
|
|
|
1113
1123
|
if (detail.descoped_urls > 0) lines.push(`descoped: ${detail.descoped_urls} url(s) marked missing \u2014 run reindex to drop their chunks`);
|
|
1114
1124
|
return lines.join("\n");
|
|
1115
1125
|
}
|
|
1126
|
+
function describeStage(s) {
|
|
1127
|
+
switch (s.stage) {
|
|
1128
|
+
case "crawling":
|
|
1129
|
+
return `crawling ${s.pages_done}/${s.pages_total}`;
|
|
1130
|
+
case "indexing":
|
|
1131
|
+
return `indexing ${s.pages_indexed}/${s.pages_done}`;
|
|
1132
|
+
case "indexed":
|
|
1133
|
+
return s.indexed_at ? `indexed ${s.indexed_at.slice(0, 10)}` : "indexed";
|
|
1134
|
+
default:
|
|
1135
|
+
return s.stage;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1116
1138
|
function describeJob(job) {
|
|
1117
1139
|
const state = job.stalled ? `${job.state} (stalled, waiting to be picked up)` : job.state;
|
|
1118
1140
|
const extra = [job.reason ? `reason: ${job.reason}` : "", job.source_id ? `source: ${job.source_id}` : ""].filter(Boolean).join(" ");
|
|
@@ -1214,10 +1236,17 @@ async function main(argv) {
|
|
|
1214
1236
|
for (const s of sources) process.stdout.write(`${s.product}
|
|
1215
1237
|
`);
|
|
1216
1238
|
} else {
|
|
1217
|
-
const rows = sources.map((s) => ({
|
|
1239
|
+
const rows = sources.map((s) => ({
|
|
1240
|
+
product: s.product,
|
|
1241
|
+
versions: s.versions.length > 0 ? s.versions.join(", ") : "-",
|
|
1242
|
+
stage: describeStage(s),
|
|
1243
|
+
url: s.base_url,
|
|
1244
|
+
pending: s.stage !== "indexed"
|
|
1245
|
+
})).sort((a, b) => Number(b.pending) - Number(a.pending) || a.product.localeCompare(b.product));
|
|
1218
1246
|
const w1 = Math.max(...rows.map((r) => r.product.length));
|
|
1219
1247
|
const w2 = Math.max(...rows.map((r) => r.versions.length));
|
|
1220
|
-
|
|
1248
|
+
const w3 = Math.max(...rows.map((r) => r.stage.length));
|
|
1249
|
+
for (const r of rows) process.stdout.write(`${r.product.padEnd(w1)} ${r.versions.padEnd(w2)} ${r.stage.padEnd(w3)} ${r.url}
|
|
1221
1250
|
`);
|
|
1222
1251
|
}
|
|
1223
1252
|
return EXIT.ok;
|
|
@@ -1230,7 +1259,7 @@ async function main(argv) {
|
|
|
1230
1259
|
return EXIT.ok;
|
|
1231
1260
|
}
|
|
1232
1261
|
for (const v of res.versions) {
|
|
1233
|
-
process.stdout.write(`${v.version}${v.version === res.latest ? " latest" : ""} ${v.chunk_count} chunks
|
|
1262
|
+
process.stdout.write(`${v.version}${v.version === res.latest ? " latest" : ""} ${v.chunk_count} chunks indexed ${v.indexed_at.slice(0, 10)}
|
|
1234
1263
|
`);
|
|
1235
1264
|
}
|
|
1236
1265
|
return EXIT.ok;
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts", "../../core/dist/config.js", "../../core/dist/auth.js", "../../core/dist/errors.js", "../../core/dist/http.js", "../../core/dist/client.js", "../src/args.ts", "../src/help.ts", "../src/output.ts", "../src/commands/setup.ts", "../src/commands/init.ts", "../src/commands/config.ts", "../src/commands/update.ts", "../src/commands/ingest.ts", "../src/updatecheck.ts"],
|
|
4
|
-
"sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n fetchAuthConfig,\n clearSession,\n readSession,\n readMachineToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type JobOut,\n type SourceDetailOut,\n type SourceScopeIn,\n type SourcePin,\n type SourceSelector,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, requirePositional, requireFlagOneOf, intFlag, UsageError, type ParsedArgs } from \"./args.js\";\nimport { COMMAND_FLAGS, HELP, VERSION } from \"./help.js\";\nimport { printResults, printCompact, printTimings, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runConfig } from \"./commands/config.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { submissionFromArgs } from \"./commands/ingest.js\";\nimport { notifyIfOutdated, refreshUpdateState } from \"./updatecheck.js\";\n\n// The authorization URL is always printed so a user on a headless or remote\n// machine can open it elsewhere; the browser launch is the default convenience.\nfunction loginOpener(launchBrowser: boolean): (url: string) => void {\n return (url: string): void => {\n process.stdout.write(`${url}\\n`);\n if (!launchBrowser) {\n process.stderr.write(\"Open the URL above in a browser to log in; waiting for the callback\u2026\\n\");\n return;\n }\n const cmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n try {\n execFileSync(cmd, [url], { stdio: \"ignore\" });\n } catch {\n process.stderr.write(\"Could not open a browser; open the URL above manually.\\n\");\n }\n };\n}\n\nfunction parseSourceFlags(values: string[] | undefined): SourcePin[] {\n return (values ?? []).map((v) => {\n const [source, version] = v.split(\"@\");\n return version ? { source, version } : { source };\n });\n}\n\nfunction toSelectors(pins: SourcePin[]): SourceSelector[] {\n return pins.map((p) => ({ product: p.source, ...(p.version ? { version: p.version } : {}) }));\n}\n\n// Injected by esbuild from package.json at build time (\"dev\" when running\n// unbundled source, e.g. under vitest).\n\nfunction describeError(err: ApiError): string {\n const detail =\n typeof err.body === \"string\"\n ? err.body\n : err.body !== undefined && err.body !== null\n ? JSON.stringify(err.body)\n : \"\";\n return `error: ${err.code}${detail ? ` \u2014 ${detail}` : \"\"}`;\n}\n\n// \"email (kind subject) staff quota N/day\", or the email with a plain reason\n// when the account has no Grimoire grant yet \u2014 the login itself succeeded.\nasync function describeIdentity(client: GrimoireClient): Promise<string> {\n const email = await client.sessionEmail();\n const who = email ?? \"machine token\";\n try {\n const me = await client.me();\n const level = me.is_staff ? \"staff\" : \"user\";\n const rerankers = me.rerankers ?? [];\n const extra = rerankers.length > 0 ? `\\nrerankers: local, ${rerankers.join(\", \")}` : \"\\nrerankers: local\";\n return `${who}\\nsubject ${me.subject} (${me.kind})\\naccess ${level}, ${me.quota_per_day} searches/day${extra}`;\n } catch (err) {\n if (err instanceof ApiError && err.status === 403) {\n // The subject is what staff needs to grant access, so it must be\n // readable by the person who has none yet.\n const subject = await client.sessionSubject();\n return `${who}\\nsubject ${subject ?? \"unknown\"}\\naccess none \u2014 ask a staff member for: grimoire staff grant ${subject ?? \"<subject>\"} --name \"${email ?? \"your name\"}\"`;\n }\n throw err;\n }\n}\n\n// The same version flags `grimoire ingest` takes, so a rule is corrected with\n// the words it was declared with.\nfunction versioningFromArgs(args: ParsedArgs): Partial<SourceScopeIn> {\n const fixed = args.flags.fixed?.[0];\n const npm = args.flags.npm?.[0];\n const pypi = args.flags.pypi?.[0];\n const github = args.flags.github?.[0];\n if ([npm, pypi, github].filter(Boolean).length > 1) {\n throw new UsageError(\"Pass only one of --npm, --pypi, --github\");\n }\n if (args.bools.has(\"rolling\")) return { version_rule: { kind: \"rolling\" } };\n if (fixed) return { version_rule: { kind: \"fixed\", value: fixed } };\n if (npm) return { version_rule: { kind: \"fixed\" }, probe: { kind: \"npm\", package: npm } };\n if (pypi) return { version_rule: { kind: \"fixed\" }, probe: { kind: \"pypi\", package: pypi } };\n if (github) return { version_rule: { kind: \"fixed\" }, probe: { kind: \"github\", repo: github } };\n return {};\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n// Staff commands take a source id or a product name; the name is looked up.\nasync function resolveSourceId(client: GrimoireClient, ref: string): Promise<string> {\n if (UUID_RE.test(ref)) return ref;\n const match = (await client.listSources()).find((s) => s.product === ref);\n if (!match) throw new UsageError(`No source with product \"${ref}\" \u2014 run \\`grimoire sources\\``);\n return match.id;\n}\n\nfunction describeSource(detail: SourceDetailOut): string {\n const frontier = Object.entries(detail.frontier)\n .map(([status, count]) => `${status}=${count}`)\n .join(\" \");\n const lines = [\n `${detail.product} ${detail.status} ${detail.base_url}`,\n `id: ${detail.id}`,\n `route: ${detail.page_markdown ? \"published page markdown\" : \"browser crawl\"}`,\n `versions: ${detail.versions.length > 0 ? detail.versions.join(\", \") : \"(not indexed yet)\"}`,\n `include: ${detail.include_patterns.join(\" \") || \"(all)\"} exclude: ${detail.exclude_patterns.join(\" \") || \"(none)\"}`,\n `frontier: ${frontier || \"(empty)\"}`,\n `indexed: ${detail.indexed_pages} page(s) at the current config`,\n `job: ${detail.job ? `${detail.job.kind} ${describeJob(detail.job)}` : \"none running\"}`,\n ];\n if (detail.descoped_urls > 0) lines.push(`descoped: ${detail.descoped_urls} url(s) marked missing \u2014 run reindex to drop their chunks`);\n return lines.join(\"\\n\");\n}\n\nfunction describeJob(job: JobOut): string {\n // A job left behind by a restart still says \"running\"; say so plainly.\n const state = job.stalled ? `${job.state} (stalled, waiting to be picked up)` : job.state;\n const extra = [job.reason ? `reason: ${job.reason}` : \"\", job.source_id ? `source: ${job.source_id}` : \"\"]\n .filter(Boolean)\n .join(\" \");\n return `${state}${extra ? ` ${extra}` : \"\"}`;\n}\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" }, command !== undefined ? COMMAND_FLAGS[command] : []);\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"version\":\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${VERSION}\\n`);\n return EXIT.ok;\n case \"login\": {\n const launch = !args.bools.has(\"no-launch-browser\");\n process.stderr.write(launch ? \"Opening your browser to log in\u2026\\n\" : \"Login URL:\\n\");\n await browserLogin(loadGlobalConfig().apiBaseUrl, loginOpener(launch));\n process.stdout.write(`Logged in as ${await describeIdentity(new GrimoireClient())}\\n`);\n return EXIT.ok;\n }\n case \"logout\":\n clearSession();\n process.stdout.write(\"Logged out.\\n\");\n return EXIT.ok;\n case \"setup\":\n return runSetup(args.positionals[0]);\n case \"init\":\n return runInit();\n case \"config\":\n return runConfig(args);\n case \"update\":\n return runUpdate();\n case \"mcp\":\n process.stderr.write(\"Run the MCP server with: npx @monadeo.com/grimoire-mcp\" + (args.bools.has(\"http\") ? \" --http\\n\" : \"\\n\"));\n return EXIT.ok;\n case undefined:\n case \"help\":\n case \"--help\":\n case \"-h\":\n process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n const via = process.env.GRIMOIRE_AUTH_TOKEN\n ? \"GRIMOIRE_AUTH_TOKEN\"\n : readMachineToken()\n ? \"grimoire config auth-token\"\n : readSession()\n ? \"browser login\"\n : undefined;\n if (!via) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n const authConfig = await fetchAuthConfig(loadGlobalConfig().apiBaseUrl);\n process.stdout.write(`${await describeIdentity(client)} via ${via}\\n`);\n process.stdout.write(`server ${authConfig.server_version ?? \"(older than 0.10.2)\"} ${loadGlobalConfig().apiBaseUrl}\\n`);\n return EXIT.ok;\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write('Usage: grimoire search \"<query>\" -s <product>[@version]\\n');\n return EXIT.apiError;\n }\n const explicit = parseSourceFlags(args.flags.source);\n const sources = explicit.length > 0 ? explicit : resolveDefaultSources();\n if (sources.length === 0) {\n // `grimoire init` only helps when there are dependencies to pin from \u2014\n // suggesting it in an infra repo is a dead end (Astro 2026-07-18).\n const initHelps = existsSync(join(process.cwd(), \"package.json\")) || existsSync(join(process.cwd(), \"requirements.txt\"));\n process.stderr.write(\n \"No sources selected. List what is indexed:\\n\" +\n \" grimoire sources\\n\" +\n \"then scope the search:\\n\" +\n ' grimoire search \"<query>\" -s <product>[@version]\\n' +\n (initHelps ? \"or pin this project's sources from its dependencies:\\n grimoire init\\n\" : \"\"),\n );\n return EXIT.apiError;\n }\n const reranker = args.flags.reranker?.[0] ?? loadGlobalConfig().reranker;\n const res = await client.search({\n query,\n sources: toSelectors(sources),\n debug: args.bools.has(\"debug\"),\n ...(reranker && reranker !== \"local\" ? { reranker } : {}),\n });\n if (args.bools.has(\"verbose\")) printTimings(res);\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res);\n else printResults(res);\n return EXIT.ok;\n }\n case \"sources\": {\n const needle = args.flags.q?.[0]?.toLowerCase();\n const sources = (await client.listSources()).filter(\n (s) => !needle || s.product.toLowerCase().includes(needle) || s.base_url.toLowerCase().includes(needle),\n );\n if (json) {\n process.stdout.write(JSON.stringify(sources, null, 2) + \"\\n\");\n } else if (args.bools.has(\"names\")) {\n for (const s of sources) process.stdout.write(`${s.product}\\n`);\n } else {\n // Sources still being ingested first, then the rest by name; columns\n // padded so the eye can run down each one.\n const rows = sources\n .map((s) => ({ product: s.product, versions: s.versions.length > 0 ? s.versions.join(\", \") : \"(not indexed yet)\", url: s.base_url, pending: s.versions.length === 0 }))\n .sort((a, b) => Number(b.pending) - Number(a.pending) || a.product.localeCompare(b.product));\n const w1 = Math.max(...rows.map((r) => r.product.length));\n const w2 = Math.max(...rows.map((r) => r.versions.length));\n for (const r of rows) process.stdout.write(`${r.product.padEnd(w1)} ${r.versions.padEnd(w2)} ${r.url}\\n`);\n }\n return EXIT.ok;\n }\n case \"versions\": {\n const product = requirePositional(args, 0, \"Usage: grimoire versions <product> [--json]\");\n const res = await client.listVersions(product);\n if (json) {\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n for (const v of res.versions) {\n process.stdout.write(`${v.version}${v.version === res.latest ? \" latest\" : \"\"} ${v.chunk_count} chunks\\n`);\n }\n return EXIT.ok;\n }\n case \"doc\": {\n const pointId = requirePositional(args, 0, \"Usage: grimoire doc <point_id> [--window 2] [--json]\");\n const window = intFlag(args, \"window\", { min: 0, max: 5 }) ?? 2;\n const res = await client.getDoc(pointId, window);\n if (json) {\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n process.stderr.write(`${res.product}@${res.version} ${res.heading_path.join(\" \u203A \")}\\n${res.source_url}\\n`);\n process.stdout.write(res.text + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n const usage = 'Usage: grimoire report <point_id> --verdict helpful|incorrect|outdated [--note \"...\"]';\n const pointId = requirePositional(args, 0, usage);\n const verdict = requireFlagOneOf(args, \"verdict\", [\"helpful\", \"incorrect\", \"outdated\"], usage);\n await client.reportResult(pointId, verdict as \"helpful\" | \"incorrect\" | \"outdated\", args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const url = requirePositional(args, 0, \"Usage: grimoire ingest <url> --product <name> --rolling|--fixed|--npm|--pypi|--github\");\n const res = await client.submitSource(submissionFromArgs(url, args));\n process.stdout.write(`Job: ${res.job_id}\\n`);\n if (args.bools.has(\"watch\")) return watchJob(client, res.job_id);\n return EXIT.ok;\n }\n case \"jobs\": {\n const jobId = requirePositional(args, 0, \"Usage: grimoire jobs <job_id> [--watch]\");\n return args.bools.has(\"watch\") ? watchJob(client, jobId) : printJob(client, jobId);\n }\n case \"staff\": {\n const usage =\n 'Usage: grimoire staff queue [--json] | approve <job_id> | reject <job_id> --reason \"...\" | users [--json] | grant <subject> --name \"...\" [--staff on|off] | revoke <subject> | token <name> --quota <per-day> | jobs [--source <s>] [--state <st>] [--kind <k>] [--limit n] | cancel <job_id> | urls <s> [--state st] [--limit n] | create <url> --product <p> (--rolling|--fixed v|--npm p|--pypi p|--github o/r) | upload <s> <page-url> <file.html> | source <s> [--watch] [--include p]... [--exclude p]... [--status active|disabled] [--markdown on|off] [--rolling|--fixed v|--npm p|--pypi p|--github o/r] | recrawl <s> | reindex <s> | purge <s> --yes';\n const [action, jobId] = args.positionals;\n if (action === \"token\") {\n const quota = intFlag(args, \"quota\", { min: 1, max: 1_000_000 });\n if (!jobId || quota === undefined) throw new UsageError(usage);\n const minted = await client.mintToken(jobId, quota);\n // The plain token is shown exactly once; the server keeps only its hash.\n process.stderr.write(`token ${minted.id} ${minted.name} quota ${minted.quota_per_day}/day \u2014 shown once, store it now\\n`);\n process.stdout.write(`${minted.token}\\n`);\n return EXIT.ok;\n }\n if (action === \"create\") {\n // For a site the worker cannot reach: the source exists first, then\n // `staff upload` brings its pages in one by one.\n if (!jobId) throw new UsageError(usage);\n const body = submissionFromArgs(jobId, args);\n const detail = await client.createUploadSource(body);\n process.stdout.write(json ? JSON.stringify(detail, null, 2) + \"\\n\" : `${describeSource(detail)}\\n`);\n return EXIT.ok;\n }\n if (action === \"upload\") {\n const [, ref, pageUrl, file] = args.positionals;\n if (!ref || !pageUrl || !file) throw new UsageError(usage);\n const html = readFileSync(file, \"utf8\");\n const out = await client.uploadPage(await resolveSourceId(client, ref), pageUrl, html);\n process.stdout.write(`${out.url} ${out.bytes} bytes ${out.queued ? \"queued\" : \"stored\"}\\n`);\n return EXIT.ok;\n }\n if (action === \"urls\") {\n if (!jobId) throw new UsageError(usage);\n const urls = await client.listFrontier(await resolveSourceId(client, jobId), {\n status: args.flags.state?.[0],\n limit: intFlag(args, \"limit\", { min: 1, max: 500 }),\n });\n if (json) process.stdout.write(JSON.stringify(urls, null, 2) + \"\\n\");\n else if (urls.length === 0) process.stdout.write(\"no urls\\n\");\n else\n for (const u of urls)\n process.stdout.write(`${u.status} ${u.url}${u.last_error ? ` \u2014 ${u.last_error}` : \"\"}\\n`);\n return EXIT.ok;\n }\n if (action === \"recrawl\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.recrawlSource(await resolveSourceId(client, jobId)))}\\n`);\n return EXIT.ok;\n }\n if (action === \"reindex\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.reindexSource(await resolveSourceId(client, jobId)))}\\n`);\n return EXIT.ok;\n }\n if (action === \"cancel\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.cancelJob(jobId))}\\n`);\n return EXIT.ok;\n }\n if (action === \"jobs\") {\n const sourceRef = args.flags.source?.[0];\n const found = await client.listJobs({\n sourceId: sourceRef ? await resolveSourceId(client, sourceRef) : undefined,\n state: args.flags.state?.[0],\n kind: args.flags.kind?.[0],\n limit: intFlag(args, \"limit\", { min: 1, max: 500 }),\n });\n if (json) process.stdout.write(JSON.stringify(found, null, 2) + \"\\n\");\n else if (found.length === 0) process.stdout.write(\"no jobs\\n\");\n else for (const job of found) process.stdout.write(`${job.created_at} ${job.id} ${job.kind} ${describeJob(job)}\\n`);\n return EXIT.ok;\n }\n if (action === \"source\") {\n if (!jobId) throw new UsageError(usage);\n const sourceId = await resolveSourceId(client, jobId);\n if (args.bools.has(\"watch\")) return watchSource(client, sourceId);\n const status = args.flags.status?.[0];\n if (status !== undefined && status !== \"active\" && status !== \"disabled\") throw new UsageError(usage);\n const markdown = args.flags.markdown?.[0];\n if (markdown !== undefined && markdown !== \"on\" && markdown !== \"off\") throw new UsageError(usage);\n const edit: SourceScopeIn = {};\n if (args.flags.include) edit.include_patterns = args.flags.include;\n if (args.flags.exclude) edit.exclude_patterns = args.flags.exclude;\n if (status) edit.status = status;\n if (markdown) edit.page_markdown = markdown === \"on\";\n Object.assign(edit, versioningFromArgs(args));\n const detail =\n Object.keys(edit).length > 0 ? await client.editSource(sourceId, edit) : await client.sourceDetail(sourceId);\n process.stdout.write(json ? JSON.stringify(detail, null, 2) + \"\\n\" : `${describeSource(detail)}\\n`);\n return EXIT.ok;\n }\n if (action === \"purge\") {\n if (!jobId) throw new UsageError(usage);\n if (!args.bools.has(\"yes\")) {\n throw new UsageError(\"purge deletes the source, its crawl state, and every indexed chunk; add --yes to confirm\");\n }\n const purged = await client.purgeSource(await resolveSourceId(client, jobId));\n process.stdout.write(\n `purged ${purged.product} frontier=${purged.frontier_deleted} jobs=${purged.jobs_deleted} chunks removed by ${purged.points_deleted_by}\\n`,\n );\n return EXIT.ok;\n }\n if (action === \"users\") {\n const users = await client.listUsers();\n if (json) process.stdout.write(JSON.stringify(users, null, 2) + \"\\n\");\n else for (const u of users) process.stdout.write(`${u.subject} ${u.status} ${u.is_staff ? \"staff\" : \"user\"} ${u.name} by ${u.granted_by}\\n`);\n return EXIT.ok;\n }\n if (action === \"grant\") {\n const name = args.flags.name?.[0];\n if (!jobId || !name) throw new UsageError(usage);\n const staff = args.flags.staff?.[0];\n if (staff !== undefined && staff !== \"on\" && staff !== \"off\") throw new UsageError(usage);\n const granted = await client.grantUser(jobId, name, staff === \"on\");\n process.stdout.write(`${granted.subject} ${granted.status} ${granted.is_staff ? \"staff\" : \"user\"} ${granted.name}\\n`);\n return EXIT.ok;\n }\n if (action === \"revoke\") {\n if (!jobId) throw new UsageError(usage);\n const revoked = await client.revokeUser(jobId);\n process.stdout.write(`${revoked.subject} ${revoked.status}\\n`);\n return EXIT.ok;\n }\n if (action === \"queue\") {\n const queue = await client.reviewQueue();\n if (json) process.stdout.write(JSON.stringify(queue, null, 2) + \"\\n\");\n else if (queue.length === 0) process.stdout.write(\"review queue is empty\\n\");\n else for (const job of queue) process.stdout.write(`${job.id} ${describeJob(job)}\\n`);\n return EXIT.ok;\n }\n if (!jobId) throw new UsageError(usage);\n if (action === \"approve\") {\n process.stdout.write(`${describeJob(await client.approveJob(jobId))}\\n`);\n return EXIT.ok;\n }\n if (action === \"reject\") {\n const reason = args.flags.reason?.[0];\n if (!reason) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.rejectJob(jobId, reason))}\\n`);\n return EXIT.ok;\n }\n throw new UsageError(usage);\n }\n default:\n process.stderr.write(`Unknown command: ${command}\\n${HELP}`);\n return EXIT.apiError;\n }\n } catch (err) {\n if (err instanceof ApiError) {\n process.stderr.write(`${describeError(err)}\\n`);\n if (err.status === 401) return EXIT.authRequired;\n if (err.status === 403) return EXIT.authRequired;\n if (err.status === 429) return EXIT.quota;\n if (err.status === 404) return EXIT.notFound;\n return EXIT.apiError;\n }\n throw err;\n }\n}\n\nconst TERMINAL_STATES = [\"accepted\", \"done\", \"rejected\", \"failed\", \"pending_review\"];\nconst FAILED_STATES = [\"rejected\", \"failed\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n process.stdout.write(`${describeJob(job)}\\n`);\n return FAILED_STATES.includes(job.state) ? EXIT.apiError : EXIT.ok;\n}\n\nconst WATCH_POLL_MS = 5_000;\nconst WATCH_BACKOFF_CAP_MS = 30_000;\nconst WATCH_DEADLINE_MS = 30 * 60_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nasync function watchSource(client: GrimoireClient, sourceId: string): Promise<number> {\n // An ingest runs for hours; print a line only when something moved, so the\n // terminal stays readable and a stall is obvious.\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let last = \"\";\n while (Date.now() < deadline) {\n try {\n const detail = await client.sourceDetail(sourceId);\n const line = describeSource(detail);\n if (line !== last) {\n process.stdout.write(`${line}\\n\\n`);\n last = line;\n }\n if (!detail.job) return EXIT.ok;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying\\n`);\n await sleep(WATCH_POLL_MS);\n }\n }\n process.stderr.write(\"stopped watching; the job is still running\\n\");\n return EXIT.ok;\n}\n\nasync function watchJob(client: GrimoireClient, jobId: string): Promise<number> {\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let backoff = WATCH_POLL_MS;\n while (Date.now() < deadline) {\n try {\n const job = await client.getJob(jobId);\n process.stdout.write(`${describeJob(job)}\\n`);\n if (TERMINAL_STATES.includes(job.state)) {\n if (job.state === \"pending_review\") {\n process.stderr.write(\"Parked for staff review: grimoire staff queue\\n\");\n }\n return FAILED_STATES.includes(job.state) ? EXIT.apiError : EXIT.ok;\n }\n backoff = WATCH_POLL_MS;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n // Auth/permission/missing-job failures cannot heal on their own \u2014 bail out;\n // anything else (network, 5xx, timeout) is worth retrying with backoff.\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying in ${backoff / 1000}s\\n`);\n await sleep(backoff);\n backoff = Math.min(backoff * 2, WATCH_BACKOFF_CAP_MS);\n }\n }\n process.stderr.write(\n `Watch deadline (30m) reached; the job is still running. Check later with: grimoire jobs ${jobId}\\n`,\n );\n return EXIT.apiError;\n}\n\nnotifyIfOutdated(VERSION);\nmain(process.argv.slice(2))\n .then(async (code) => {\n await refreshUpdateState(VERSION, loadGlobalConfig().updateCheckHours);\n process.exit(code);\n })\n .catch((err) => {\n if (err instanceof UsageError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(EXIT.apiError);\n }\n process.stderr.write(`fatal: ${(err as Error).message}\\n`);\n process.exit(EXIT.apiError);\n });\n", "import { readFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n// Bare origin \u2014 API paths are absolute (/v1/...), so the base must never carry a\n// path prefix.\nexport const DEFAULT_API_BASE = \"https://cli.grimoire.monadeo.com\";\nexport function globalConfigPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"config.json\");\n}\n// Malformed config must never crash a consumer (the MCP server constructs a client\n// at import time): warn and behave as if the file were absent.\nfunction readJsonConfig(path) {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n }\n catch (err) {\n process.stderr.write(`grimoire: ignoring malformed config at ${path}: ${err.message}\\n`);\n return undefined;\n }\n}\n// Precedence: env var > config file > default \u2014 a per-invocation env override\n// (CI, QA testing) must always beat persisted settings.\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const overrides = existsSync(path) ? readJsonConfig(path) : undefined;\n return {\n apiBaseUrl: DEFAULT_API_BASE,\n ...overrides,\n ...(process.env.GRIMOIRE_API_URL ? { apiBaseUrl: process.env.GRIMOIRE_API_URL } : {}),\n };\n}\nexport function saveGlobalConfig(config) {\n const path = globalConfigPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(config, null, 2));\n}\n// Read-modify-write against the FILE only (never the env-merged view, which\n// would bake a transient GRIMOIRE_API_URL into the file). `undefined` values\n// remove their key.\nexport function updateGlobalConfigFile(patch) {\n const path = globalConfigPath();\n const current = existsSync(path) ? (readJsonConfig(path) ?? {}) : {};\n const merged = { ...current, ...patch };\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key];\n }\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(merged, null, 2));\n return merged;\n}\n// Project config (.grimoire.json in the repo root) pins a codebase's sources and\n// overrides globals \u2014 committed alongside the code it documents.\nexport function findProjectConfig(startDir = process.cwd()) {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".grimoire.json\");\n if (existsSync(candidate)) {\n const parsed = readJsonConfig(candidate);\n if (parsed)\n return parsed;\n }\n const parent = dirname(dir);\n if (parent === dir)\n return undefined;\n dir = parent;\n }\n}\nexport function resolveDefaultSources() {\n return findProjectConfig()?.sources ?? loadGlobalConfig().defaultSources ?? [];\n}\n", "import { createHash, randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { createServer } from \"node:http\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\n// Session storage is a 0600 file, not the OS keychain (Astro 2026-07-14):\n// keychain ACLs are per binary, so every agent runtime spawning the MCP server\n// re-prompted the user \u2014 gcloud and Codex accept the same file-based model.\n// A machine token via GRIMOIRE_AUTH_TOKEN overrides interactive auth (CI only).\nfunction configDir() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\");\n}\nfunction credentialsPath() {\n return join(configDir(), \"credentials.json\");\n}\nexport function storeSession(session) {\n const path = credentialsPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, JSON.stringify(session) + \"\\n\", { mode: 0o600 });\n}\nexport function readSession() {\n try {\n const parsed = JSON.parse(readFileSync(credentialsPath(), \"utf8\"));\n if (typeof parsed.refresh_token === \"string\" &&\n parsed.refresh_token !== \"\" &&\n typeof parsed.supabase_url === \"string\" &&\n typeof parsed.supabase_anon_key === \"string\") {\n return {\n refresh_token: parsed.refresh_token,\n supabase_url: parsed.supabase_url,\n supabase_anon_key: parsed.supabase_anon_key,\n };\n }\n return undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearSession() {\n if (existsSync(credentialsPath()))\n rmSync(credentialsPath());\n}\n// Persisted machine token, for users who want a `mt_` token without exporting\n// GRIMOIRE_AUTH_TOKEN in a shell profile (that env var still overrides). Same\n// 0600 model as credentials.json \u2014 never the world-readable config.json.\nfunction machineTokenPath() {\n return join(configDir(), \"machine-token\");\n}\nexport function storeMachineToken(token) {\n const path = machineTokenPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, token + \"\\n\", { mode: 0o600 });\n}\nexport function readMachineToken() {\n try {\n const token = readFileSync(machineTokenPath(), \"utf8\").trim();\n return token !== \"\" ? token : undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearMachineToken() {\n if (existsSync(machineTokenPath()))\n rmSync(machineTokenPath());\n}\n// The API publishes everything a client needs to log in: the public Supabase\n// URL, its anon key (public by design), the OAuth provider, and the loopback\n// callbacks that are allow-listed for the PKCE flow.\nexport async function fetchAuthConfig(apiBase) {\n const res = await fetchWithTimeout(`${apiBase.replace(/\\/+$/, \"\")}/v1/auth/config`);\n if (!res.ok)\n throw new ApiError(res.status, \"auth_config_unavailable\", await res.text());\n const body = (await res.json());\n if (typeof body.supabase_url !== \"string\" ||\n typeof body.supabase_anon_key !== \"string\" ||\n typeof body.oauth_provider !== \"string\" ||\n !Array.isArray(body.redirect_urls) ||\n body.redirect_urls.length === 0) {\n throw new ApiError(res.status, \"auth_config_malformed\", body);\n }\n return {\n supabase_url: body.supabase_url,\n supabase_anon_key: body.supabase_anon_key,\n oauth_provider: body.oauth_provider,\n redirect_urls: body.redirect_urls.map(String),\n server_version: typeof body.server_version === \"string\" ? body.server_version : undefined,\n };\n}\nfunction parseDetail(text) {\n try {\n return JSON.parse(text);\n }\n catch {\n return text;\n }\n}\n// Supabase Auth (GoTrue) token endpoint: POST /auth/v1/token?grant_type=\u2026, the\n// anon key in the apikey header, JSON body per grant.\nexport async function gotrueToken(supabaseUrl, anonKey, grantType, body) {\n const res = await fetchWithTimeout(`${supabaseUrl.replace(/\\/+$/, \"\")}/auth/v1/token?grant_type=${grantType}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", apikey: anonKey },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new ApiError(res.status, grantType === \"pkce\" ? \"login_failed\" : \"refresh_failed\", parseDetail(text));\n }\n const parsed = JSON.parse(text);\n if (typeof parsed.access_token !== \"string\" ||\n typeof parsed.refresh_token !== \"string\" ||\n typeof parsed.expires_in !== \"number\") {\n throw new ApiError(res.status, \"token_malformed\", parsed);\n }\n return {\n access_token: parsed.access_token,\n refresh_token: parsed.refresh_token,\n expires_in: parsed.expires_in,\n };\n}\nfunction base64url(buf) {\n return buf.toString(\"base64url\");\n}\n// Bind the first free allow-listed loopback callback (IPv4). The bases come\n// from the API, so the client and the Supabase allow list cannot drift.\nasync function bindCallback(server, redirectUrls) {\n for (const candidate of redirectUrls) {\n const port = Number(new URL(candidate).port);\n const bound = await new Promise((resolve) => {\n const onError = () => {\n server.off(\"error\", onError);\n resolve(false);\n };\n server.once(\"error\", onError);\n server.listen(port, \"127.0.0.1\", () => {\n server.off(\"error\", onError);\n resolve(true);\n });\n });\n if (bound)\n return candidate;\n }\n throw new Error(`No free login callback port among: ${redirectUrls.join(\", \")}`);\n}\n// OAuth Authorization Code with PKCE through Supabase Auth: open the provider\n// login in the browser, receive the code on a loopback callback, exchange code +\n// verifier for tokens. No client secret exists anywhere in the client.\n//\n// Supabase Auth's /authorize carries no `state` parameter, so the per-attempt\n// state rides in the callback path (`/callback/<state>`); any other path is a\n// 404 and the server keeps waiting. The allow list holds `/callback/*`.\nexport async function browserLogin(apiBase, openBrowser, timeoutMs = 300_000) {\n const config = await fetchAuthConfig(apiBase);\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n const state = base64url(randomBytes(16));\n const code = await new Promise((resolve, reject) => {\n let timer;\n const finish = (outcome) => {\n if (timer)\n clearTimeout(timer);\n server.closeAllConnections();\n server.close();\n if (\"code\" in outcome)\n resolve(outcome.code);\n else\n reject(outcome.error);\n };\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (req.method !== \"GET\" || url.pathname !== `/callback/${state}`) {\n res.writeHead(404).end();\n return;\n }\n const failure = url.searchParams.get(\"error_description\") ?? url.searchParams.get(\"error\");\n const received = url.searchParams.get(\"code\");\n if (failure || !received) {\n res.writeHead(400, { \"Content-Type\": \"text/plain\" }).end(`Login failed: ${failure ?? \"no code\"}`);\n finish({ error: new Error(`Login failed: ${failure ?? \"no code returned\"}`) });\n return;\n }\n res\n .writeHead(200, { \"Content-Type\": \"text/plain\" })\n .end(\"Logged in to Grimoire. You can close this tab.\");\n finish({ code: received });\n });\n bindCallback(server, config.redirect_urls)\n .then((redirectBase) => {\n timer = setTimeout(() => finish({ error: new Error(\"Login timed out\") }), timeoutMs);\n const authorize = new URL(`${config.supabase_url.replace(/\\/+$/, \"\")}/auth/v1/authorize`);\n authorize.searchParams.set(\"provider\", config.oauth_provider);\n authorize.searchParams.set(\"redirect_to\", `${redirectBase.replace(/\\/+$/, \"\")}/${state}`);\n authorize.searchParams.set(\"code_challenge\", challenge);\n authorize.searchParams.set(\"code_challenge_method\", \"s256\");\n openBrowser(authorize.toString());\n })\n .catch((err) => finish({ error: err }));\n });\n const tokens = await gotrueToken(config.supabase_url, config.supabase_anon_key, \"pkce\", {\n auth_code: code,\n code_verifier: verifier,\n });\n storeSession({\n refresh_token: tokens.refresh_token,\n supabase_url: config.supabase_url,\n supabase_anon_key: config.supabase_anon_key,\n });\n}\n// Claims of an access token, read without verification \u2014 for display only\n// (the API verifies every token it receives).\nexport function tokenClaims(token) {\n const payload = token.split(\".\")[1];\n if (!payload)\n return {};\n try {\n return JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\"));\n }\n catch {\n return {};\n }\n}\n", "export class ApiError extends Error {\n status;\n code;\n body;\n constructor(status, code, body) {\n super(`${code} (${status})`);\n this.status = status;\n this.code = code;\n this.body = body;\n }\n}\n", "import { ApiError } from \"./errors.js\";\nexport const REQUEST_TIMEOUT_MS = 30_000;\nexport async function fetchWithTimeout(url, init = {}) {\n try {\n return await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });\n }\n catch (err) {\n if (err instanceof Error && (err.name === \"TimeoutError\" || err.name === \"AbortError\")) {\n throw new ApiError(408, \"timeout\", `Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);\n }\n // Undici reports DNS/TLS/connection failures as `TypeError: fetch failed` with the\n // useful detail in `cause`; surface both under a consistent ApiError.\n const message = err instanceof Error ? err.message : String(err);\n const cause = err instanceof Error && err.cause instanceof Error ? `: ${err.cause.message}` : \"\";\n throw new ApiError(0, \"network_error\", `${message}${cause}`);\n }\n}\n", "import { gotrueToken, readMachineToken, readSession, storeSession, tokenClaims } from \"./auth.js\";\nimport { loadGlobalConfig } from \"./config.js\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\nexport { ApiError } from \"./errors.js\";\nconst CODES = {\n 401: \"unauthorized\",\n 403: \"forbidden\",\n 404: \"not_found\",\n 422: \"invalid_request\",\n 429: \"quota_exceeded\",\n};\nexport class GrimoireClient {\n baseUrl;\n machineToken;\n cachedAccessToken;\n refreshInFlight;\n constructor(opts = {}) {\n this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\\/+$/, \"\");\n this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN ?? readMachineToken();\n }\n async bearer() {\n if (this.machineToken)\n return this.machineToken;\n if (this.cachedAccessToken && this.cachedAccessToken.expiresAt > Date.now() + 60_000) {\n return this.cachedAccessToken.token;\n }\n this.refreshInFlight ??= this.refreshAccessToken().finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n // Exchange the stored refresh token for a fresh access token. GoTrue rotates\n // refresh tokens, so the new one replaces the stored one every time.\n async refreshAccessToken() {\n const session = readSession();\n if (!session)\n throw new ApiError(401, \"not_logged_in\", \"Run `grimoire login`\");\n let tokens;\n try {\n tokens = await gotrueToken(session.supabase_url, session.supabase_anon_key, \"refresh_token\", {\n refresh_token: session.refresh_token,\n });\n }\n catch (err) {\n if (err instanceof ApiError)\n throw new ApiError(err.status, \"refresh_failed\", \"Run `grimoire login`\");\n throw err;\n }\n storeSession({ ...session, refresh_token: tokens.refresh_token });\n this.cachedAccessToken = {\n token: tokens.access_token,\n expiresAt: Date.now() + tokens.expires_in * 1000,\n };\n return tokens.access_token;\n }\n async refreshSession() {\n await this.bearer();\n }\n // The login email from the session token; undefined for machine tokens.\n /** The account's Supabase subject, readable before any grant exists. */\n async sessionSubject() {\n const claims = tokenClaims(await this.bearer());\n return typeof claims.sub === \"string\" ? claims.sub : undefined;\n }\n async sessionEmail() {\n if (this.machineToken)\n return undefined;\n const email = tokenClaims(await this.bearer()).email;\n return typeof email === \"string\" ? email : undefined;\n }\n async send(path, init, auth) {\n const headers = {\n \"Content-Type\": \"application/json\",\n ...init.headers,\n };\n if (auth)\n headers.Authorization = `Bearer ${await this.bearer()}`;\n return fetchWithTimeout(`${this.baseUrl}${path}`, { ...init, headers });\n }\n async request(path, init = {}, auth = true) {\n let res = await this.send(path, init, auth);\n // A 401 despite a locally-unexpired access token means it was revoked\n // server-side: force one refresh and retry exactly once.\n if (res.status === 401 && auth && !this.machineToken) {\n this.cachedAccessToken = undefined;\n res = await this.send(path, init, auth);\n }\n return this.parseResponse(res);\n }\n // FastAPI errors carry {\"detail\": \"...\"} (string) or {\"detail\": [...]} (422).\n async parseResponse(res) {\n const isJson = res.headers.get(\"content-type\")?.includes(\"json\") ?? false;\n const text = await res.text();\n let body;\n let parsed = false;\n if (isJson && text) {\n try {\n body = JSON.parse(text);\n parsed = true;\n }\n catch {\n parsed = false;\n }\n }\n if (!res.ok) {\n const detail = parsed && typeof body === \"object\" && body !== null ? body.detail : undefined;\n throw new ApiError(res.status, CODES[res.status] ?? \"error\", detail ?? (parsed ? body : text));\n }\n if (isJson)\n return (parsed ? body : {});\n return text;\n }\n search(input) {\n return this.request(\"/v1/search\", { method: \"POST\", body: JSON.stringify(input) });\n }\n listSources() {\n return this.request(\"/v1/sources\");\n }\n listVersions(product) {\n return this.request(`/v1/sources/${encodeURIComponent(product)}/versions`);\n }\n getDoc(pointId, window = 2) {\n return this.request(`/v1/doc/${encodeURIComponent(pointId)}?window=${window}`);\n }\n reportResult(pointId, verdict, note) {\n const body = { point_id: pointId, verdict, ...(note ? { note } : {}) };\n return this.request(\"/v1/report\", { method: \"POST\", body: JSON.stringify(body) });\n }\n submitSource(body) {\n return this.request(\"/v1/sources\", { method: \"POST\", body: JSON.stringify(body) });\n }\n getJob(jobId) {\n return this.request(`/v1/jobs/${encodeURIComponent(jobId)}`);\n }\n me() {\n return this.request(\"/v1/me\");\n }\n reviewQueue() {\n return this.request(\"/v1/staff/review-queue\");\n }\n approveJob(jobId) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/approve`, { method: \"POST\" });\n }\n listUsers() {\n return this.request(\"/v1/staff/users\");\n }\n grantUser(subject, name, staff = false) {\n return this.request(\"/v1/staff/users\", {\n method: \"POST\",\n body: JSON.stringify({ subject, name, staff }),\n });\n }\n revokeUser(subject) {\n return this.request(`/v1/staff/users/${encodeURIComponent(subject)}`, { method: \"DELETE\" });\n }\n mintToken(name, quotaPerDay) {\n return this.request(\"/v1/staff/tokens\", {\n method: \"POST\",\n body: JSON.stringify({ name, quota_per_day: quotaPerDay }),\n });\n }\n recrawlSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/recrawl`, { method: \"POST\" });\n }\n listFrontier(sourceId, filter = {}) {\n const params = new URLSearchParams();\n if (filter.status)\n params.set(\"status\", filter.status);\n if (filter.limit !== undefined)\n params.set(\"limit\", String(filter.limit));\n const query = params.toString();\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/frontier${query ? `?${query}` : \"\"}`);\n }\n createUploadSource(body) {\n return this.request(\"/v1/staff/sources\", { method: \"POST\", body: JSON.stringify(body) });\n }\n uploadPage(sourceId, url, html) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/pages`, {\n method: \"PUT\",\n body: JSON.stringify({ url, html }),\n });\n }\n reindexSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/reindex`, { method: \"POST\" });\n }\n sourceDetail(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`);\n }\n editSource(sourceId, body) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`, {\n method: \"PATCH\",\n body: JSON.stringify(body),\n });\n }\n purgeSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`, { method: \"DELETE\" });\n }\n listJobs(filter) {\n const params = new URLSearchParams();\n if (filter.sourceId)\n params.set(\"source_id\", filter.sourceId);\n if (filter.state)\n params.set(\"state\", filter.state);\n if (filter.kind)\n params.set(\"kind\", filter.kind);\n if (filter.limit !== undefined)\n params.set(\"limit\", String(filter.limit));\n const query = params.toString();\n return this.request(`/v1/staff/jobs${query ? `?${query}` : \"\"}`);\n }\n cancelJob(jobId) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/cancel`, { method: \"POST\" });\n }\n rejectJob(jobId, reason) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/reject`, {\n method: \"POST\",\n body: JSON.stringify({ reason }),\n });\n }\n}\n", "// Minimal flag parser: collects repeated --flag/-f values and positionals.\nexport interface ParsedArgs {\n positionals: string[];\n flags: Record<string, string[]>;\n bools: Set<string>;\n}\n\nexport class UsageError extends Error {}\n\nconst BOOL_FLAGS = new Set([\n \"json\",\n \"yes\",\n \"verbose\",\n \"compact\",\n \"watch\",\n \"names\",\n \"http\",\n \"unset\",\n \"rolling\",\n \"debug\",\n \"no-launch-browser\",\n]);\n\nexport function parseArgs(\n argv: string[],\n aliases: Record<string, string> = {},\n allowed?: readonly string[],\n): ParsedArgs {\n const positionals: string[] = [];\n const flags: Record<string, string[]> = {};\n const bools = new Set<string>();\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg.startsWith(\"--\") || arg.startsWith(\"-\")) {\n const name = aliases[arg] ?? arg.replace(/^--?/, \"\");\n // A misspelled flag silently swallowing its value (`--top 4` when the\n // real flag is --top-k) must fail loudly, not act like it worked.\n if (allowed && !allowed.includes(name)) {\n throw new UsageError(`Unknown flag ${arg} \u2014 run \\`grimoire help\\` for valid flags`);\n }\n if (BOOL_FLAGS.has(name)) {\n bools.add(name);\n } else {\n const value = argv[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n throw new UsageError(`Flag ${arg} requires a value`);\n }\n (flags[name] ??= []).push(value);\n i++;\n }\n } else {\n positionals.push(arg);\n }\n }\n return { positionals, flags, bools };\n}\n\nexport function requirePositional(parsed: ParsedArgs, index: number, usage: string): string {\n const value = parsed.positionals[index];\n if (value === undefined) throw new UsageError(usage);\n return value;\n}\n\nexport function intFlag(\n parsed: ParsedArgs,\n name: string,\n range?: { min: number; max: number },\n): number | undefined {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined) return undefined;\n const value = Number(raw);\n if (!Number.isInteger(value)) throw new UsageError(`Flag --${name} must be an integer`);\n if (range && (value < range.min || value > range.max)) {\n throw new UsageError(`Flag --${name} must be between ${range.min} and ${range.max}`);\n }\n return value;\n}\n\nexport function requireFlagOneOf(\n parsed: ParsedArgs,\n name: string,\n allowed: readonly string[],\n usage: string,\n): string {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined || !allowed.includes(raw)) throw new UsageError(usage);\n return raw;\n}\n", "// The command surface: the help text, the flags each command accepts, and the\n// client version. Kept in its own module so a test can read them without\n// running the CLI. help.test.ts holds this file, the parser, and the readme\n// together \u2014 a new command or flag has to appear in all three.\n\ndeclare const __GRIMOIRE_VERSION__: string | undefined;\nexport const VERSION = typeof __GRIMOIRE_VERSION__ === \"string\" ? __GRIMOIRE_VERSION__ : \"dev\";\n\nexport const HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents\n\n grimoire login [--no-launch-browser] | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--reranker <name>] [--json|--compact] [--debug] [--verbose]\n grimoire sources [--q <kw>] [--names|--json]\n grimoire versions <product> [--json]\n grimoire config [<key>] [<value>] [--unset]\n grimoire update\n grimoire doc <point_id> [--window 2] [--json]\n grimoire report <point_id> --verdict helpful|incorrect|outdated [--note \"...\"]\n grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)\n [--include <pattern>]... [--exclude <pattern>]... [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire staff queue [--json] | approve <job_id> | reject <job_id> --reason \"...\"\n grimoire staff users [--json] | grant <subject> --name \"...\" [--staff on|off] | revoke <subject>\n grimoire staff token <name> --quota <per-day>\n grimoire staff jobs [--source <product|id>] [--state <state>] [--kind <kind>] [--limit 50] [--json]\n grimoire staff cancel <job_id>\n grimoire staff source <product|id> [--watch] [--json]\n grimoire staff source <product|id> [--include <pattern>]... [--exclude <pattern>]... [--status active|disabled] [--markdown on|off]\n grimoire staff source <product|id> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)\n grimoire staff urls <product|id> [--state <crawl state>] [--limit 50] [--json]\n grimoire staff create <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>) [--include <pattern>]... [--exclude <pattern>]...\n grimoire staff upload <product|id> <page-url> <file.html>\n grimoire staff recrawl <product|id> | reindex <product|id> | purge <product|id> --yes\n grimoire mcp [--http]\n grimoire help | --help | -h\n grimoire version | --version | -v\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path\n`;\n\n// Canonical flag names each command accepts; parseArgs rejects anything else.\nexport const COMMAND_FLAGS: Record<string, readonly string[]> = {\n version: [], \"--version\": [], \"-v\": [],\n login: [\"no-launch-browser\"], logout: [], setup: [], init: [], whoami: [],\n help: [], \"--help\": [], \"-h\": [],\n mcp: [\"http\"],\n config: [\"unset\"],\n update: [],\n search: [\"source\", \"json\", \"compact\", \"debug\", \"verbose\", \"reranker\"],\n sources: [\"q\", \"names\", \"json\"],\n versions: [\"json\"],\n doc: [\"window\", \"json\"],\n report: [\"verdict\", \"note\"],\n ingest: [\"product\", \"rolling\", \"fixed\", \"npm\", \"pypi\", \"github\", \"include\", \"exclude\", \"watch\"],\n jobs: [\"watch\"],\n staff: [\"reason\", \"name\", \"quota\", \"json\", \"source\", \"state\", \"kind\", \"limit\", \"include\", \"exclude\", \"status\", \"markdown\", \"yes\", \"watch\", \"rolling\", \"fixed\", \"npm\", \"pypi\", \"github\", \"staff\", \"product\"],\n};\n", "import type { SearchResponse, SearchResult } from \"@monadeo.com/grimoire-core\";\n\n// Exit codes documented for scripting (clients spec).\nexport const EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 } as const;\n\n// The API labels result text as untrusted data; the CLI repeats that on stderr\n// so agents reading stdout never see it as an instruction.\n/** Where the time went, on stderr, so stdout stays the answer. */\nexport function printTimings(res: SearchResponse): void {\n const t = res.timings;\n if (!t) {\n process.stderr.write(`timings: total ${res.latency_ms} ms (server older than 0.21.0 reports no stages)\\n`);\n return;\n }\n process.stderr.write(\n `timings: embed ${t.embed_ms} ms \u00B7 retrieve ${t.retrieve_ms} ms \u00B7 rerank ${t.rerank_ms} ms (${res.reranker ?? \"local\"}) \u00B7 stitch ${t.stitch_ms} ms \u00B7 total ${t.total_ms} ms\\n`,\n );\n}\n\nfunction preamble(res: SearchResponse): void {\n const versions = Object.entries(res.resolved_versions)\n .map(([product, version]) => `${product}@${version}`)\n .join(\", \");\n process.stderr.write(`sources: ${versions} \u00B7 retrievals remaining: ${res.retrievals_remaining}\\n`);\n process.stderr.write(`note: ${res.untrusted_content_notice}\\n`);\n if (res.results.length === 0) {\n process.stderr.write(\"note: no result passed the relevance threshold \u2014 the docs may not cover this.\\n\");\n }\n}\n\nfunction heading(r: SearchResult): string {\n return r.heading_path.join(\" \u203A \");\n}\n\nexport function printResults(res: SearchResponse): void {\n preamble(res);\n for (const r of res.results) {\n process.stdout.write(\n `\\n${r.score.toFixed(3)} ${r.product}@${r.version} ${heading(r)}\\n${r.source_url}\\npoint_id: ${r.point_id}\\n`,\n );\n const preview = r.text.length > 500 ? `${r.text.slice(0, 500)}\u2026` : r.text;\n process.stdout.write(`${preview}\\n`);\n }\n}\n\nexport function printCompact(res: SearchResponse): void {\n preamble(res);\n for (const r of res.results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.product}@${r.version} | ${heading(r)} | ${r.source_url} | ${r.point_id}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { readMachineToken, readSession } from \"@monadeo.com/grimoire-core\";\n\n// One-command agent onboarding (SDD decision 19 / clients spec): writes the MCP\n// registration for the named agent. `npx @monadeo.com/grimoire-mcp` needs no global install.\nconst MCP_ENTRY = { command: \"npx\", args: [\"-y\", \"@monadeo.com/grimoire-mcp\"] };\n\nconst CODEX_TABLE = `[mcp_servers.grimoire]\ncommand = \"npx\"\nargs = [\"-y\", \"@monadeo.com/grimoire-mcp\"]\n`;\n\n// Codex reads ~/.codex/config.toml. Replace our table in place (up to the next\n// [ header or EOF) without a TOML library, so the rest of the user's config\n// passes through byte-for-byte.\nexport function mergeCodexToml(existing: string): string {\n const header = existing.match(/^[ \\t]*\\[mcp_servers\\.grimoire\\][ \\t]*(\\r?\\n|$)/m);\n if (!header || header.index === undefined) {\n if (existing.trim() === \"\") return CODEX_TABLE;\n const sep = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return existing + sep + CODEX_TABLE;\n }\n const afterHeader = header.index + header[0].length;\n const nextHeader = existing.slice(afterHeader).match(/^[ \\t]*\\[/m);\n const end =\n nextHeader && nextHeader.index !== undefined ? afterHeader + nextHeader.index : existing.length;\n return existing.slice(0, header.index) + CODEX_TABLE + existing.slice(end);\n}\n\ninterface JsonAgentTarget {\n path: string;\n apply: (existing: Record<string, unknown>) => Record<string, unknown>;\n}\n\nfunction mcpServersMerge(key: string) {\n return (existing: Record<string, unknown>) => {\n const servers = (existing[key] as Record<string, unknown>) ?? {};\n return { ...existing, [key]: { ...servers, grimoire: MCP_ENTRY } };\n };\n}\n\nconst JSON_AGENTS: Record<string, JsonAgentTarget> = {\n \"claude-code\": { path: join(homedir(), \".claude.json\"), apply: mcpServersMerge(\"mcpServers\") },\n cursor: { path: join(homedir(), \".cursor\", \"mcp.json\"), apply: mcpServersMerge(\"mcpServers\") },\n windsurf: {\n path: join(homedir(), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n apply: mcpServersMerge(\"mcpServers\"),\n },\n};\n\nconst AGENT_NAMES = [...Object.keys(JSON_AGENTS), \"codex\"];\n\nfunction setupCodex(): number {\n const path = join(homedir(), \".codex\", \"config.toml\");\n const existing = existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, mergeCodexToml(existing));\n return finish(\"codex\", path);\n}\n\n// Best-effort session probe: an unreadable credentials file must fall through\n// to the hint, never crash setup.\nfunction hasSession(): boolean {\n if (process.env.GRIMOIRE_AUTH_TOKEN) return true;\n try {\n return readMachineToken() !== undefined || readSession() !== undefined;\n } catch {\n return false;\n }\n}\n\nfunction finish(agent: string, path: string): number {\n process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}\\n`);\n process.stdout.write(hasSession() ? \"Already logged in.\\n\" : \"Run `grimoire login` to authenticate.\\n\");\n return 0;\n}\n\nexport function runSetup(agent: string | undefined): number {\n if (!agent || !AGENT_NAMES.includes(agent)) {\n process.stderr.write(`Usage: grimoire setup <${AGENT_NAMES.join(\"|\")}>\\n`);\n return 1;\n }\n if (agent === \"codex\") return setupCodex();\n const target = JSON_AGENTS[agent];\n let existing: Record<string, unknown> = {};\n if (existsSync(target.path)) {\n try {\n existing = JSON.parse(readFileSync(target.path, \"utf8\")) as Record<string, unknown>;\n } catch (err) {\n process.stderr.write(\n `Cannot parse ${target.path}: ${(err as Error).message}\\nFix or remove the file, then re-run setup.\\n`,\n );\n return 1;\n }\n }\n mkdirSync(dirname(target.path), { recursive: true });\n writeFileSync(target.path, JSON.stringify(target.apply(existing), null, 2));\n return finish(agent, target.path);\n}\n", "import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { SourcePin } from \"@monadeo.com/grimoire-core\";\n\nfunction parseJsonFile<T>(path: string): T {\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as T;\n } catch (err) {\n throw new Error(`Cannot parse ${path}: ${(err as Error).message}`, { cause: err });\n }\n}\n\n// Scan common manifests \u2192 propose .grimoire.json source pins. Alias resolution\n// against the registry (curated to include package-ecosystem names) happens when\n// the sources are actually queried; init proposes candidate names from manifests.\nexport function detectManifestSources(dir = process.cwd()): SourcePin[] {\n const pins: SourcePin[] = [];\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = parseJsonFile<{ dependencies?: Record<string, string> }>(pkgPath);\n for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {\n const major = range.match(/(\\d+)/)?.[1];\n pins.push({ source: name.replace(/^@[^/]+\\//, \"\"), ...(major ? { version: major } : {}) });\n }\n }\n const reqPath = join(dir, \"requirements.txt\");\n if (existsSync(reqPath)) {\n for (const line of readFileSync(reqPath, \"utf8\").split(\"\\n\")) {\n const m = line.match(/^([A-Za-z0-9_.-]+)\\s*==\\s*(\\d+)/);\n if (m) pins.push({ source: m[1].toLowerCase(), version: m[2] });\n }\n }\n return pins;\n}\n\nexport function runInit(): number {\n const path = join(process.cwd(), \".grimoire.json\");\n try {\n const sources = detectManifestSources();\n if (sources.length === 0) {\n process.stderr.write(\"No package.json/requirements.txt dependencies found.\\n\");\n return 1;\n }\n const existing = existsSync(path) ? parseJsonFile<Record<string, unknown>>(path) : {};\n writeFileSync(path, JSON.stringify({ ...existing, sources }, null, 2));\n process.stdout.write(`Wrote ${sources.length} source pins to .grimoire.json\\n`);\n return 0;\n } catch (err) {\n process.stderr.write(`${(err as Error).message}\\n`);\n return 1;\n }\n}\n", "import {\n DEFAULT_API_BASE,\n globalConfigPath,\n loadGlobalConfig,\n updateGlobalConfigFile,\n storeMachineToken,\n readMachineToken,\n clearMachineToken,\n type GlobalConfig,\n} from \"@monadeo.com/grimoire-core\";\nimport { UsageError, type ParsedArgs } from \"../args.js\";\nimport { EXIT } from \"../output.js\";\n\ninterface KeySpec {\n prop: keyof GlobalConfig;\n describe: string;\n parse(raw: string): GlobalConfig[keyof GlobalConfig];\n}\n\nfunction intInRange(name: string, raw: string, min: number): number {\n const value = Number(raw);\n if (!Number.isInteger(value) || value < min) {\n throw new UsageError(`${name} must be an integer >= ${min}`);\n }\n return value;\n}\n\nexport const CONFIG_KEYS: Record<string, KeySpec> = {\n \"api-url\": {\n prop: \"apiBaseUrl\",\n describe: `API origin without a path (default ${DEFAULT_API_BASE}; env GRIMOIRE_API_URL overrides)`,\n parse: (raw) => {\n if (!/^https?:\\/\\/[^/]+$/.test(raw)) {\n throw new UsageError(\"api-url must be a bare origin, e.g. https://api.example.com\");\n }\n return raw;\n },\n },\n \"update-check-hours\": {\n prop: \"updateCheckHours\",\n describe: \"hours between CLI update checks (default 24, 0 disables)\",\n parse: (raw) => intInRange(\"update-check-hours\", raw, 0),\n },\n reranker: {\n prop: \"reranker\",\n describe: \"reranker for every search, one of `grimoire whoami` (default local)\",\n parse: (raw) => {\n if (raw !== \"local\" && !raw.startsWith(\"openrouter/\")) {\n throw new UsageError(\"reranker must be `local` or an `openrouter/...` name from `grimoire whoami`\");\n }\n return raw;\n },\n },\n};\n\n// auth-token is a secret and lives in a 0600 file, not the world-readable\n// config.json \u2014 so it is handled outside the CONFIG_KEYS (GlobalConfig) framework.\nconst AUTH_TOKEN_KEY = \"auth-token\";\nconst MACHINE_TOKEN_RE = /^mt_[A-Za-z0-9_-]{32,}$/;\nconst USAGE =\n \"Usage: grimoire config [<key>] [<value>] [--unset] (keys: \" +\n [...Object.keys(CONFIG_KEYS), AUTH_TOKEN_KEY].join(\", \") +\n \")\";\n\nexport function runConfig(args: ParsedArgs): number {\n const [key, value] = args.positionals;\n if (key === undefined) {\n const resolved = loadGlobalConfig();\n process.stdout.write(`config file: ${globalConfigPath()}\\n`);\n for (const [name, spec] of Object.entries(CONFIG_KEYS)) {\n const current = resolved[spec.prop];\n process.stdout.write(`${name} = ${current === undefined ? \"(unset)\" : JSON.stringify(current)} # ${spec.describe}\\n`);\n }\n process.stdout.write(\n `${AUTH_TOKEN_KEY} = ${readMachineToken() ? \"(set)\" : \"(unset)\"} # machine token, stored 0600 (env GRIMOIRE_AUTH_TOKEN overrides)\\n`,\n );\n return EXIT.ok;\n }\n if (key === AUTH_TOKEN_KEY) {\n if (args.bools.has(\"unset\")) {\n clearMachineToken();\n process.stdout.write(`${AUTH_TOKEN_KEY} unset\\n`);\n return EXIT.ok;\n }\n if (value === undefined) {\n // Never echo the secret \u2014 report presence only.\n process.stdout.write(`${readMachineToken() ? \"(set)\" : \"(unset)\"}\\n`);\n return EXIT.ok;\n }\n if (!MACHINE_TOKEN_RE.test(value)) {\n throw new UsageError(\"auth-token must be a machine token starting with mt_\");\n }\n storeMachineToken(value);\n process.stdout.write(`${AUTH_TOKEN_KEY} set\\n`);\n return EXIT.ok;\n }\n const spec = CONFIG_KEYS[key];\n if (!spec) throw new UsageError(USAGE);\n if (args.bools.has(\"unset\")) {\n updateGlobalConfigFile({ [spec.prop]: undefined });\n process.stdout.write(`${key} unset\\n`);\n return EXIT.ok;\n }\n if (value === undefined) {\n const current = loadGlobalConfig()[spec.prop];\n process.stdout.write(`${current === undefined ? \"\" : JSON.stringify(current)}\\n`);\n return EXIT.ok;\n }\n updateGlobalConfigFile({ [spec.prop]: spec.parse(value) });\n process.stdout.write(`${key} = ${value}\\n`);\n return EXIT.ok;\n}\n", "import { spawnSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { EXIT } from \"../output.js\";\n\nconst BREW_CMD = [\"brew\", \"upgrade\", \"monadeo/tap/grimoire\"];\nconst NPM_CMD = [\"npm\", \"install\", \"-g\", \"@monadeo.com/grimoire-cli\"];\n\n// The running binary's real location tells us who installed it: Homebrew keeps\n// everything under a Cellar/homebrew prefix, npm under a lib/node_modules\n// global prefix. Anything else (pnpm dlx, npx cache, a repo checkout) is not\n// ours to upgrade \u2014 print the choices instead of guessing.\nexport function detectInstallKind(binPath: string): \"brew\" | \"npm\" | undefined {\n let real: string;\n try {\n real = realpathSync(binPath);\n } catch {\n return undefined;\n }\n if (/homebrew|\\/Cellar\\//i.test(real)) return \"brew\";\n if (/\\/lib\\/node_modules\\//.test(real)) return \"npm\";\n return undefined;\n}\n\n// `brew upgrade` reads the LOCAL tap clone \u2014 without pulling it first, brew\n// happily reports \"already installed\" for a version the registry has long\n// superseded (observed 2026-07-18 upgrading 0.3.4\u21920.3.5). Pull just our tap,\n// not `brew update`, which touches every tap and core. Best-effort: a pull\n// failure still proceeds to upgrade with whatever the local tap knows.\nfunction refreshTap(): void {\n const repo = spawnSync(\"brew\", [\"--repository\", \"monadeo/tap\"], { encoding: \"utf8\" });\n const tapPath = repo.status === 0 ? repo.stdout.trim() : \"\";\n if (!tapPath) return;\n spawnSync(\"git\", [\"-C\", tapPath, \"pull\", \"--ff-only\", \"--quiet\"], { stdio: \"inherit\" });\n}\n\nexport function runUpdate(): number {\n const kind = detectInstallKind(process.argv[1] ?? \"\");\n if (!kind) {\n process.stderr.write(\n `Could not detect how grimoire was installed. Update with one of:\\n ${BREW_CMD.join(\" \")}\\n ${NPM_CMD.join(\" \")}\\n`,\n );\n return EXIT.apiError;\n }\n if (kind === \"brew\") refreshTap();\n const cmd = kind === \"brew\" ? BREW_CMD : NPM_CMD;\n process.stdout.write(`${cmd.join(\" \")}\\n`);\n const result = spawnSync(cmd[0], cmd.slice(1), { stdio: \"inherit\" });\n if (result.error) {\n process.stderr.write(`update failed: ${result.error.message}\\n`);\n return EXIT.apiError;\n }\n return result.status === 0 ? EXIT.ok : EXIT.apiError;\n}\n", "import type { SubmissionIn } from \"@monadeo.com/grimoire-core\";\nimport { UsageError, type ParsedArgs } from \"../args.js\";\n\nexport function submissionFromArgs(url: string, args: ParsedArgs): SubmissionIn {\n const usage =\n \"Usage: grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)\";\n const product = args.flags.product?.[0];\n if (!product) throw new UsageError(usage);\n const fixed = args.flags.fixed?.[0];\n const npm = args.flags.npm?.[0];\n const pypi = args.flags.pypi?.[0];\n const github = args.flags.github?.[0];\n const probes = [npm, pypi, github].filter(Boolean).length;\n if (probes > 1) throw new UsageError(\"Pass only one of --npm, --pypi, --github\");\n\n const body: SubmissionIn = {\n url,\n product,\n version_rule: { kind: \"rolling\" },\n include_patterns: args.flags.include ?? [],\n exclude_patterns: args.flags.exclude ?? [],\n };\n if (args.bools.has(\"rolling\")) return body;\n if (fixed) return { ...body, version_rule: { kind: \"fixed\", value: fixed } };\n if (npm) return { ...body, version_rule: { kind: \"fixed\" }, probe: { kind: \"npm\", package: npm } };\n if (pypi) return { ...body, version_rule: { kind: \"fixed\" }, probe: { kind: \"pypi\", package: pypi } };\n if (github) return { ...body, version_rule: { kind: \"fixed\" }, probe: { kind: \"github\", repo: github } };\n throw new UsageError(`${usage}\\nA version rule is mandatory: --rolling for unversioned docs, --fixed, or a release probe.`);\n}\n\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst REGISTRY_URL = \"https://registry.npmjs.org/@monadeo.com%2Fgrimoire-cli\";\nconst DEFAULT_INTERVAL_HOURS = 24;\nconst FETCH_TIMEOUT_MS = 1_500;\n\ninterface UpdateState {\n last_check_at?: string;\n latest?: string;\n}\n\nfunction statePath(): string {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"update-check.json\");\n}\n\nfunction readState(): UpdateState {\n try {\n return JSON.parse(readFileSync(statePath(), \"utf8\")) as UpdateState;\n } catch {\n return {};\n }\n}\n\nexport function newerVersion(a: string, b: string): boolean {\n const A = a.split(\".\").map(Number);\n const B = b.split(\".\").map(Number);\n if (A.some(Number.isNaN) || B.some(Number.isNaN)) return false;\n for (let i = 0; i < 3; i++) {\n const diff = (A[i] ?? 0) - (B[i] ?? 0);\n if (diff !== 0) return diff > 0;\n }\n return false;\n}\n\n// Prints the notice recorded by a PREVIOUS run \u2014 the registry fetch happens\n// after the command finishes, so startup stays instant.\nexport function notifyIfOutdated(current: string): void {\n if (current === \"dev\" || !process.stderr.isTTY) return;\n const { latest } = readState();\n if (latest && newerVersion(latest, current)) {\n process.stderr.write(`grimoire ${latest} is available (you have ${current}) \u2014 run \\`grimoire update\\`\\n`);\n }\n}\n\n// Best-effort, TTY-only, and never slows a command down by more than the fetch\n// timeout: agents in CI (no TTY) and dev builds skip entirely.\nexport async function refreshUpdateState(current: string, configuredHours?: number): Promise<void> {\n const hours = configuredHours ?? DEFAULT_INTERVAL_HOURS;\n if (hours === 0 || current === \"dev\" || !process.stderr.isTTY) return;\n const state = readState();\n const last = state.last_check_at ? Date.parse(state.last_check_at) : 0;\n if (Date.now() - last < hours * 3_600_000) return;\n try {\n const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });\n if (!res.ok) return;\n const body = (await res.json()) as { \"dist-tags\"?: { latest?: string } };\n const latest = body[\"dist-tags\"]?.latest;\n if (!latest) return;\n const path = statePath();\n if (!existsSync(dirname(path))) mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify({ last_check_at: new Date().toISOString(), latest }));\n } catch {\n return;\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n fetchAuthConfig,\n clearSession,\n readSession,\n readMachineToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type JobOut,\n type SourceOut,\n type SourceDetailOut,\n type SourceScopeIn,\n type SourcePin,\n type SourceSelector,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, requirePositional, requireFlagOneOf, intFlag, UsageError, type ParsedArgs } from \"./args.js\";\nimport { COMMAND_FLAGS, HELP, VERSION } from \"./help.js\";\nimport { printResults, printCompact, printTimings, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\nimport { runConfig } from \"./commands/config.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { submissionFromArgs } from \"./commands/ingest.js\";\nimport { notifyIfOutdated, refreshUpdateState } from \"./updatecheck.js\";\n\n// The authorization URL is always printed so a user on a headless or remote\n// machine can open it elsewhere; the browser launch is the default convenience.\nfunction loginOpener(launchBrowser: boolean): (url: string) => void {\n return (url: string): void => {\n process.stdout.write(`${url}\\n`);\n if (!launchBrowser) {\n process.stderr.write(\"Open the URL above in a browser to log in; waiting for the callback\u2026\\n\");\n return;\n }\n const cmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n try {\n execFileSync(cmd, [url], { stdio: \"ignore\" });\n } catch {\n process.stderr.write(\"Could not open a browser; open the URL above manually.\\n\");\n }\n };\n}\n\nfunction parseSourceFlags(values: string[] | undefined): SourcePin[] {\n return (values ?? []).map((v) => {\n const [source, version] = v.split(\"@\");\n return version ? { source, version } : { source };\n });\n}\n\nfunction toSelectors(pins: SourcePin[]): SourceSelector[] {\n return pins.map((p) => ({ product: p.source, ...(p.version ? { version: p.version } : {}) }));\n}\n\n// Injected by esbuild from package.json at build time (\"dev\" when running\n// unbundled source, e.g. under vitest).\n\nfunction describeError(err: ApiError): string {\n const detail =\n typeof err.body === \"string\"\n ? err.body\n : err.body !== undefined && err.body !== null\n ? JSON.stringify(err.body)\n : \"\";\n return `error: ${err.code}${detail ? ` \u2014 ${detail}` : \"\"}`;\n}\n\n// \"email (kind subject) staff quota N/day\", or the email with a plain reason\n// when the account has no Grimoire grant yet \u2014 the login itself succeeded.\nasync function describeIdentity(client: GrimoireClient): Promise<string> {\n const email = await client.sessionEmail();\n const who = email ?? \"machine token\";\n try {\n const me = await client.me();\n const level = me.is_staff ? \"staff\" : \"user\";\n const rerankers = me.rerankers ?? [];\n const extra = rerankers.length > 0 ? `\\nrerankers: local, ${rerankers.join(\", \")}` : \"\\nrerankers: local\";\n return `${who}\\nsubject ${me.subject} (${me.kind})\\naccess ${level}, ${me.quota_per_day} searches/day${extra}`;\n } catch (err) {\n if (err instanceof ApiError && err.status === 403) {\n // The subject is what staff needs to grant access, so it must be\n // readable by the person who has none yet.\n const subject = await client.sessionSubject();\n return `${who}\\nsubject ${subject ?? \"unknown\"}\\naccess none \u2014 ask a staff member for: grimoire staff grant ${subject ?? \"<subject>\"} --name \"${email ?? \"your name\"}\"`;\n }\n throw err;\n }\n}\n\n// The same version flags `grimoire ingest` takes, so a rule is corrected with\n// the words it was declared with.\nfunction versioningFromArgs(args: ParsedArgs): Partial<SourceScopeIn> {\n const fixed = args.flags.fixed?.[0];\n const npm = args.flags.npm?.[0];\n const pypi = args.flags.pypi?.[0];\n const github = args.flags.github?.[0];\n if ([npm, pypi, github].filter(Boolean).length > 1) {\n throw new UsageError(\"Pass only one of --npm, --pypi, --github\");\n }\n if (args.bools.has(\"rolling\")) return { version_rule: { kind: \"rolling\" } };\n if (fixed) return { version_rule: { kind: \"fixed\", value: fixed } };\n if (npm) return { version_rule: { kind: \"fixed\" }, probe: { kind: \"npm\", package: npm } };\n if (pypi) return { version_rule: { kind: \"fixed\" }, probe: { kind: \"pypi\", package: pypi } };\n if (github) {\n const tagPattern = args.flags[\"tag-pattern\"]?.[0];\n return { version_rule: { kind: \"fixed\" }, probe: { kind: \"github\", repo: github, ...(tagPattern ? { tag_pattern: tagPattern } : {}) } };\n }\n return {};\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n// Staff commands take a source id or a product name; the name is looked up.\nasync function resolveSourceId(client: GrimoireClient, ref: string): Promise<string> {\n if (UUID_RE.test(ref)) return ref;\n const match = (await client.listSources()).find((s) => s.product === ref);\n if (!match) throw new UsageError(`No source with product \"${ref}\" \u2014 run \\`grimoire sources\\``);\n return match.id;\n}\n\nfunction describeSource(detail: SourceDetailOut): string {\n const frontier = Object.entries(detail.frontier)\n .map(([status, count]) => `${status}=${count}`)\n .join(\" \");\n const lines = [\n `${detail.product} ${detail.status} ${detail.base_url}`,\n `id: ${detail.id}`,\n `route: ${detail.page_markdown ? \"published page markdown\" : \"browser crawl\"}`,\n `versions: ${detail.versions.length > 0 ? detail.versions.join(\", \") : \"(not indexed yet)\"}`,\n `include: ${detail.include_patterns.join(\" \") || \"(all)\"} exclude: ${detail.exclude_patterns.join(\" \") || \"(none)\"}`,\n `frontier: ${frontier || \"(empty)\"}`,\n `indexed: ${detail.indexed_pages} page(s) at the current config`,\n `job: ${detail.job ? `${detail.job.kind} ${describeJob(detail.job)}` : \"none running\"}`,\n ];\n if (detail.descoped_urls > 0) lines.push(`descoped: ${detail.descoped_urls} url(s) marked missing \u2014 run reindex to drop their chunks`);\n return lines.join(\"\\n\");\n}\n\n// One word for where a source stands, with the count that moves in that stage.\nfunction describeStage(s: SourceOut): string {\n switch (s.stage) {\n case \"crawling\":\n return `crawling ${s.pages_done}/${s.pages_total}`;\n case \"indexing\":\n return `indexing ${s.pages_indexed}/${s.pages_done}`;\n case \"indexed\":\n return s.indexed_at ? `indexed ${s.indexed_at.slice(0, 10)}` : \"indexed\";\n default:\n return s.stage;\n }\n}\n\nfunction describeJob(job: JobOut): string {\n // A job left behind by a restart still says \"running\"; say so plainly.\n const state = job.stalled ? `${job.state} (stalled, waiting to be picked up)` : job.state;\n const extra = [job.reason ? `reason: ${job.reason}` : \"\", job.source_id ? `source: ${job.source_id}` : \"\"]\n .filter(Boolean)\n .join(\" \");\n return `${state}${extra ? ` ${extra}` : \"\"}`;\n}\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" }, command !== undefined ? COMMAND_FLAGS[command] : []);\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"version\":\n case \"--version\":\n case \"-v\":\n process.stdout.write(`${VERSION}\\n`);\n return EXIT.ok;\n case \"login\": {\n const launch = !args.bools.has(\"no-launch-browser\");\n process.stderr.write(launch ? \"Opening your browser to log in\u2026\\n\" : \"Login URL:\\n\");\n await browserLogin(loadGlobalConfig().apiBaseUrl, loginOpener(launch));\n process.stdout.write(`Logged in as ${await describeIdentity(new GrimoireClient())}\\n`);\n return EXIT.ok;\n }\n case \"logout\":\n clearSession();\n process.stdout.write(\"Logged out.\\n\");\n return EXIT.ok;\n case \"setup\":\n return runSetup(args.positionals[0]);\n case \"init\":\n return runInit();\n case \"config\":\n return runConfig(args);\n case \"update\":\n return runUpdate();\n case \"mcp\":\n process.stderr.write(\"Run the MCP server with: npx @monadeo.com/grimoire-mcp\" + (args.bools.has(\"http\") ? \" --http\\n\" : \"\\n\"));\n return EXIT.ok;\n case undefined:\n case \"help\":\n case \"--help\":\n case \"-h\":\n process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n const via = process.env.GRIMOIRE_AUTH_TOKEN\n ? \"GRIMOIRE_AUTH_TOKEN\"\n : readMachineToken()\n ? \"grimoire config auth-token\"\n : readSession()\n ? \"browser login\"\n : undefined;\n if (!via) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n const authConfig = await fetchAuthConfig(loadGlobalConfig().apiBaseUrl);\n process.stdout.write(`${await describeIdentity(client)} via ${via}\\n`);\n process.stdout.write(`server ${authConfig.server_version ?? \"(older than 0.10.2)\"} ${loadGlobalConfig().apiBaseUrl}\\n`);\n return EXIT.ok;\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write('Usage: grimoire search \"<query>\" -s <product>[@version]\\n');\n return EXIT.apiError;\n }\n const explicit = parseSourceFlags(args.flags.source);\n const sources = explicit.length > 0 ? explicit : resolveDefaultSources();\n if (sources.length === 0) {\n // `grimoire init` only helps when there are dependencies to pin from \u2014\n // suggesting it in an infra repo is a dead end (Astro 2026-07-18).\n const initHelps = existsSync(join(process.cwd(), \"package.json\")) || existsSync(join(process.cwd(), \"requirements.txt\"));\n process.stderr.write(\n \"No sources selected. List what is indexed:\\n\" +\n \" grimoire sources\\n\" +\n \"then scope the search:\\n\" +\n ' grimoire search \"<query>\" -s <product>[@version]\\n' +\n (initHelps ? \"or pin this project's sources from its dependencies:\\n grimoire init\\n\" : \"\"),\n );\n return EXIT.apiError;\n }\n const reranker = args.flags.reranker?.[0] ?? loadGlobalConfig().reranker;\n const res = await client.search({\n query,\n sources: toSelectors(sources),\n debug: args.bools.has(\"debug\"),\n ...(reranker && reranker !== \"local\" ? { reranker } : {}),\n });\n if (args.bools.has(\"verbose\")) printTimings(res);\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res);\n else printResults(res);\n return EXIT.ok;\n }\n case \"sources\": {\n const needle = args.flags.q?.[0]?.toLowerCase();\n const sources = (await client.listSources()).filter(\n (s) => !needle || s.product.toLowerCase().includes(needle) || s.base_url.toLowerCase().includes(needle),\n );\n if (json) {\n process.stdout.write(JSON.stringify(sources, null, 2) + \"\\n\");\n } else if (args.bools.has(\"names\")) {\n for (const s of sources) process.stdout.write(`${s.product}\\n`);\n } else {\n // Sources still being ingested first, then the rest by name; columns\n // padded so the eye can run down each one.\n const rows = sources\n .map((s) => ({\n product: s.product,\n versions: s.versions.length > 0 ? s.versions.join(\", \") : \"-\",\n stage: describeStage(s),\n url: s.base_url,\n pending: s.stage !== \"indexed\",\n }))\n .sort((a, b) => Number(b.pending) - Number(a.pending) || a.product.localeCompare(b.product));\n const w1 = Math.max(...rows.map((r) => r.product.length));\n const w2 = Math.max(...rows.map((r) => r.versions.length));\n const w3 = Math.max(...rows.map((r) => r.stage.length));\n for (const r of rows) process.stdout.write(`${r.product.padEnd(w1)} ${r.versions.padEnd(w2)} ${r.stage.padEnd(w3)} ${r.url}\\n`);\n }\n return EXIT.ok;\n }\n case \"versions\": {\n const product = requirePositional(args, 0, \"Usage: grimoire versions <product> [--json]\");\n const res = await client.listVersions(product);\n if (json) {\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n for (const v of res.versions) {\n process.stdout.write(`${v.version}${v.version === res.latest ? \" latest\" : \"\"} ${v.chunk_count} chunks indexed ${v.indexed_at.slice(0, 10)}\\n`);\n }\n return EXIT.ok;\n }\n case \"doc\": {\n const pointId = requirePositional(args, 0, \"Usage: grimoire doc <point_id> [--window 2] [--json]\");\n const window = intFlag(args, \"window\", { min: 0, max: 5 }) ?? 2;\n const res = await client.getDoc(pointId, window);\n if (json) {\n process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n process.stderr.write(`${res.product}@${res.version} ${res.heading_path.join(\" \u203A \")}\\n${res.source_url}\\n`);\n process.stdout.write(res.text + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n const usage = 'Usage: grimoire report <point_id> --verdict helpful|incorrect|outdated [--note \"...\"]';\n const pointId = requirePositional(args, 0, usage);\n const verdict = requireFlagOneOf(args, \"verdict\", [\"helpful\", \"incorrect\", \"outdated\"], usage);\n await client.reportResult(pointId, verdict as \"helpful\" | \"incorrect\" | \"outdated\", args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const url = requirePositional(args, 0, \"Usage: grimoire ingest <url> --product <name> --rolling|--fixed|--npm|--pypi|--github\");\n const res = await client.submitSource(submissionFromArgs(url, args));\n process.stdout.write(`Job: ${res.job_id}\\n`);\n if (args.bools.has(\"watch\")) return watchJob(client, res.job_id);\n return EXIT.ok;\n }\n case \"jobs\": {\n const jobId = requirePositional(args, 0, \"Usage: grimoire jobs <job_id> [--watch]\");\n return args.bools.has(\"watch\") ? watchJob(client, jobId) : printJob(client, jobId);\n }\n case \"staff\": {\n const usage =\n 'Usage: grimoire staff queue [--json] | approve <job_id> | reject <job_id> --reason \"...\" | users [--json] | grant <subject> --name \"...\" [--staff on|off] | revoke <subject> | token <name> --quota <per-day> | jobs [--source <s>] [--state <st>] [--kind <k>] [--limit n] | cancel <job_id> | urls <s> [--state st] [--limit n] | create <url> --product <p> (--rolling|--fixed v|--npm p|--pypi p|--github o/r) | upload <s> <page-url> <file.html> | source <s> [--watch] [--include p]... [--exclude p]... [--status active|disabled] [--markdown on|off] [--rolling|--fixed v|--npm p|--pypi p|--github o/r] | recrawl <s> | reindex <s> | purge <s> --yes';\n const [action, jobId] = args.positionals;\n if (action === \"token\") {\n const quota = intFlag(args, \"quota\", { min: 1, max: 1_000_000 });\n if (!jobId || quota === undefined) throw new UsageError(usage);\n const minted = await client.mintToken(jobId, quota);\n // The plain token is shown exactly once; the server keeps only its hash.\n process.stderr.write(`token ${minted.id} ${minted.name} quota ${minted.quota_per_day}/day \u2014 shown once, store it now\\n`);\n process.stdout.write(`${minted.token}\\n`);\n return EXIT.ok;\n }\n if (action === \"create\") {\n // For a site the worker cannot reach: the source exists first, then\n // `staff upload` brings its pages in one by one.\n if (!jobId) throw new UsageError(usage);\n const body = submissionFromArgs(jobId, args);\n const detail = await client.createUploadSource(body);\n process.stdout.write(json ? JSON.stringify(detail, null, 2) + \"\\n\" : `${describeSource(detail)}\\n`);\n return EXIT.ok;\n }\n if (action === \"upload\") {\n const [, ref, pageUrl, file] = args.positionals;\n if (!ref || !pageUrl || !file) throw new UsageError(usage);\n const html = readFileSync(file, \"utf8\");\n const out = await client.uploadPage(await resolveSourceId(client, ref), pageUrl, html);\n process.stdout.write(`${out.url} ${out.bytes} bytes ${out.queued ? \"queued\" : \"stored\"}\\n`);\n return EXIT.ok;\n }\n if (action === \"urls\") {\n if (!jobId) throw new UsageError(usage);\n const urls = await client.listFrontier(await resolveSourceId(client, jobId), {\n status: args.flags.state?.[0],\n limit: intFlag(args, \"limit\", { min: 1, max: 500 }),\n });\n if (json) process.stdout.write(JSON.stringify(urls, null, 2) + \"\\n\");\n else if (urls.length === 0) process.stdout.write(\"no urls\\n\");\n else\n for (const u of urls)\n process.stdout.write(`${u.status} ${u.url}${u.last_error ? ` \u2014 ${u.last_error}` : \"\"}\\n`);\n return EXIT.ok;\n }\n if (action === \"recrawl\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.recrawlSource(await resolveSourceId(client, jobId)))}\\n`);\n return EXIT.ok;\n }\n if (action === \"reindex\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.reindexSource(await resolveSourceId(client, jobId)))}\\n`);\n return EXIT.ok;\n }\n if (action === \"cancel\") {\n if (!jobId) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.cancelJob(jobId))}\\n`);\n return EXIT.ok;\n }\n if (action === \"jobs\") {\n const sourceRef = args.flags.source?.[0];\n const found = await client.listJobs({\n sourceId: sourceRef ? await resolveSourceId(client, sourceRef) : undefined,\n state: args.flags.state?.[0],\n kind: args.flags.kind?.[0],\n limit: intFlag(args, \"limit\", { min: 1, max: 500 }),\n });\n if (json) process.stdout.write(JSON.stringify(found, null, 2) + \"\\n\");\n else if (found.length === 0) process.stdout.write(\"no jobs\\n\");\n else for (const job of found) process.stdout.write(`${job.created_at} ${job.id} ${job.kind} ${describeJob(job)}\\n`);\n return EXIT.ok;\n }\n if (action === \"source\") {\n if (!jobId) throw new UsageError(usage);\n const sourceId = await resolveSourceId(client, jobId);\n if (args.bools.has(\"watch\")) return watchSource(client, sourceId);\n const status = args.flags.status?.[0];\n if (status !== undefined && status !== \"active\" && status !== \"disabled\") throw new UsageError(usage);\n const markdown = args.flags.markdown?.[0];\n if (markdown !== undefined && markdown !== \"on\" && markdown !== \"off\") throw new UsageError(usage);\n const edit: SourceScopeIn = {};\n if (args.flags.include) edit.include_patterns = args.flags.include;\n if (args.flags.exclude) edit.exclude_patterns = args.flags.exclude;\n if (status) edit.status = status;\n if (markdown) edit.page_markdown = markdown === \"on\";\n Object.assign(edit, versioningFromArgs(args));\n const detail =\n Object.keys(edit).length > 0 ? await client.editSource(sourceId, edit) : await client.sourceDetail(sourceId);\n process.stdout.write(json ? JSON.stringify(detail, null, 2) + \"\\n\" : `${describeSource(detail)}\\n`);\n return EXIT.ok;\n }\n if (action === \"purge\") {\n if (!jobId) throw new UsageError(usage);\n if (!args.bools.has(\"yes\")) {\n throw new UsageError(\"purge deletes the source, its crawl state, and every indexed chunk; add --yes to confirm\");\n }\n const purged = await client.purgeSource(await resolveSourceId(client, jobId));\n process.stdout.write(\n `purged ${purged.product} frontier=${purged.frontier_deleted} jobs=${purged.jobs_deleted} chunks removed by ${purged.points_deleted_by}\\n`,\n );\n return EXIT.ok;\n }\n if (action === \"users\") {\n const users = await client.listUsers();\n if (json) process.stdout.write(JSON.stringify(users, null, 2) + \"\\n\");\n else for (const u of users) process.stdout.write(`${u.subject} ${u.status} ${u.is_staff ? \"staff\" : \"user\"} ${u.name} by ${u.granted_by}\\n`);\n return EXIT.ok;\n }\n if (action === \"grant\") {\n const name = args.flags.name?.[0];\n if (!jobId || !name) throw new UsageError(usage);\n const staff = args.flags.staff?.[0];\n if (staff !== undefined && staff !== \"on\" && staff !== \"off\") throw new UsageError(usage);\n const granted = await client.grantUser(jobId, name, staff === \"on\");\n process.stdout.write(`${granted.subject} ${granted.status} ${granted.is_staff ? \"staff\" : \"user\"} ${granted.name}\\n`);\n return EXIT.ok;\n }\n if (action === \"revoke\") {\n if (!jobId) throw new UsageError(usage);\n const revoked = await client.revokeUser(jobId);\n process.stdout.write(`${revoked.subject} ${revoked.status}\\n`);\n return EXIT.ok;\n }\n if (action === \"queue\") {\n const queue = await client.reviewQueue();\n if (json) process.stdout.write(JSON.stringify(queue, null, 2) + \"\\n\");\n else if (queue.length === 0) process.stdout.write(\"review queue is empty\\n\");\n else for (const job of queue) process.stdout.write(`${job.id} ${describeJob(job)}\\n`);\n return EXIT.ok;\n }\n if (!jobId) throw new UsageError(usage);\n if (action === \"approve\") {\n process.stdout.write(`${describeJob(await client.approveJob(jobId))}\\n`);\n return EXIT.ok;\n }\n if (action === \"reject\") {\n const reason = args.flags.reason?.[0];\n if (!reason) throw new UsageError(usage);\n process.stdout.write(`${describeJob(await client.rejectJob(jobId, reason))}\\n`);\n return EXIT.ok;\n }\n throw new UsageError(usage);\n }\n default:\n process.stderr.write(`Unknown command: ${command}\\n${HELP}`);\n return EXIT.apiError;\n }\n } catch (err) {\n if (err instanceof ApiError) {\n process.stderr.write(`${describeError(err)}\\n`);\n if (err.status === 401) return EXIT.authRequired;\n if (err.status === 403) return EXIT.authRequired;\n if (err.status === 429) return EXIT.quota;\n if (err.status === 404) return EXIT.notFound;\n return EXIT.apiError;\n }\n throw err;\n }\n}\n\nconst TERMINAL_STATES = [\"accepted\", \"done\", \"rejected\", \"failed\", \"pending_review\"];\nconst FAILED_STATES = [\"rejected\", \"failed\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n process.stdout.write(`${describeJob(job)}\\n`);\n return FAILED_STATES.includes(job.state) ? EXIT.apiError : EXIT.ok;\n}\n\nconst WATCH_POLL_MS = 5_000;\nconst WATCH_BACKOFF_CAP_MS = 30_000;\nconst WATCH_DEADLINE_MS = 30 * 60_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nasync function watchSource(client: GrimoireClient, sourceId: string): Promise<number> {\n // An ingest runs for hours; print a line only when something moved, so the\n // terminal stays readable and a stall is obvious.\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let last = \"\";\n while (Date.now() < deadline) {\n try {\n const detail = await client.sourceDetail(sourceId);\n const line = describeSource(detail);\n if (line !== last) {\n process.stdout.write(`${line}\\n\\n`);\n last = line;\n }\n if (!detail.job) return EXIT.ok;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying\\n`);\n await sleep(WATCH_POLL_MS);\n }\n }\n process.stderr.write(\"stopped watching; the job is still running\\n\");\n return EXIT.ok;\n}\n\nasync function watchJob(client: GrimoireClient, jobId: string): Promise<number> {\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let backoff = WATCH_POLL_MS;\n while (Date.now() < deadline) {\n try {\n const job = await client.getJob(jobId);\n process.stdout.write(`${describeJob(job)}\\n`);\n if (TERMINAL_STATES.includes(job.state)) {\n if (job.state === \"pending_review\") {\n process.stderr.write(\"Parked for staff review: grimoire staff queue\\n\");\n }\n return FAILED_STATES.includes(job.state) ? EXIT.apiError : EXIT.ok;\n }\n backoff = WATCH_POLL_MS;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n // Auth/permission/missing-job failures cannot heal on their own \u2014 bail out;\n // anything else (network, 5xx, timeout) is worth retrying with backoff.\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying in ${backoff / 1000}s\\n`);\n await sleep(backoff);\n backoff = Math.min(backoff * 2, WATCH_BACKOFF_CAP_MS);\n }\n }\n process.stderr.write(\n `Watch deadline (30m) reached; the job is still running. Check later with: grimoire jobs ${jobId}\\n`,\n );\n return EXIT.apiError;\n}\n\nnotifyIfOutdated(VERSION);\nmain(process.argv.slice(2))\n .then(async (code) => {\n await refreshUpdateState(VERSION, loadGlobalConfig().updateCheckHours);\n process.exit(code);\n })\n .catch((err) => {\n if (err instanceof UsageError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(EXIT.apiError);\n }\n process.stderr.write(`fatal: ${(err as Error).message}\\n`);\n process.exit(EXIT.apiError);\n });\n", "import { readFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n// Bare origin \u2014 API paths are absolute (/v1/...), so the base must never carry a\n// path prefix.\nexport const DEFAULT_API_BASE = \"https://cli.grimoire.monadeo.com\";\nexport function globalConfigPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"config.json\");\n}\n// Malformed config must never crash a consumer (the MCP server constructs a client\n// at import time): warn and behave as if the file were absent.\nfunction readJsonConfig(path) {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n }\n catch (err) {\n process.stderr.write(`grimoire: ignoring malformed config at ${path}: ${err.message}\\n`);\n return undefined;\n }\n}\n// Precedence: env var > config file > default \u2014 a per-invocation env override\n// (CI, QA testing) must always beat persisted settings.\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const overrides = existsSync(path) ? readJsonConfig(path) : undefined;\n return {\n apiBaseUrl: DEFAULT_API_BASE,\n ...overrides,\n ...(process.env.GRIMOIRE_API_URL ? { apiBaseUrl: process.env.GRIMOIRE_API_URL } : {}),\n };\n}\nexport function saveGlobalConfig(config) {\n const path = globalConfigPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(config, null, 2));\n}\n// Read-modify-write against the FILE only (never the env-merged view, which\n// would bake a transient GRIMOIRE_API_URL into the file). `undefined` values\n// remove their key.\nexport function updateGlobalConfigFile(patch) {\n const path = globalConfigPath();\n const current = existsSync(path) ? (readJsonConfig(path) ?? {}) : {};\n const merged = { ...current, ...patch };\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key];\n }\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(merged, null, 2));\n return merged;\n}\n// Project config (.grimoire.json in the repo root) pins a codebase's sources and\n// overrides globals \u2014 committed alongside the code it documents.\nexport function findProjectConfig(startDir = process.cwd()) {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".grimoire.json\");\n if (existsSync(candidate)) {\n const parsed = readJsonConfig(candidate);\n if (parsed)\n return parsed;\n }\n const parent = dirname(dir);\n if (parent === dir)\n return undefined;\n dir = parent;\n }\n}\nexport function resolveDefaultSources() {\n return findProjectConfig()?.sources ?? loadGlobalConfig().defaultSources ?? [];\n}\n", "import { createHash, randomBytes } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { createServer } from \"node:http\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\n// Session storage is a 0600 file, not the OS keychain (Astro 2026-07-14):\n// keychain ACLs are per binary, so every agent runtime spawning the MCP server\n// re-prompted the user \u2014 gcloud and Codex accept the same file-based model.\n// A machine token via GRIMOIRE_AUTH_TOKEN overrides interactive auth (CI only).\nfunction configDir() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\");\n}\nfunction credentialsPath() {\n return join(configDir(), \"credentials.json\");\n}\nexport function storeSession(session) {\n const path = credentialsPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, JSON.stringify(session) + \"\\n\", { mode: 0o600 });\n}\nexport function readSession() {\n try {\n const parsed = JSON.parse(readFileSync(credentialsPath(), \"utf8\"));\n if (typeof parsed.refresh_token === \"string\" &&\n parsed.refresh_token !== \"\" &&\n typeof parsed.supabase_url === \"string\" &&\n typeof parsed.supabase_anon_key === \"string\") {\n return {\n refresh_token: parsed.refresh_token,\n supabase_url: parsed.supabase_url,\n supabase_anon_key: parsed.supabase_anon_key,\n };\n }\n return undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearSession() {\n if (existsSync(credentialsPath()))\n rmSync(credentialsPath());\n}\n// Persisted machine token, for users who want a `mt_` token without exporting\n// GRIMOIRE_AUTH_TOKEN in a shell profile (that env var still overrides). Same\n// 0600 model as credentials.json \u2014 never the world-readable config.json.\nfunction machineTokenPath() {\n return join(configDir(), \"machine-token\");\n}\nexport function storeMachineToken(token) {\n const path = machineTokenPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, token + \"\\n\", { mode: 0o600 });\n}\nexport function readMachineToken() {\n try {\n const token = readFileSync(machineTokenPath(), \"utf8\").trim();\n return token !== \"\" ? token : undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearMachineToken() {\n if (existsSync(machineTokenPath()))\n rmSync(machineTokenPath());\n}\n// The API publishes everything a client needs to log in: the public Supabase\n// URL, its anon key (public by design), the OAuth provider, and the loopback\n// callbacks that are allow-listed for the PKCE flow.\nexport async function fetchAuthConfig(apiBase) {\n const res = await fetchWithTimeout(`${apiBase.replace(/\\/+$/, \"\")}/v1/auth/config`);\n if (!res.ok)\n throw new ApiError(res.status, \"auth_config_unavailable\", await res.text());\n const body = (await res.json());\n if (typeof body.supabase_url !== \"string\" ||\n typeof body.supabase_anon_key !== \"string\" ||\n typeof body.oauth_provider !== \"string\" ||\n !Array.isArray(body.redirect_urls) ||\n body.redirect_urls.length === 0) {\n throw new ApiError(res.status, \"auth_config_malformed\", body);\n }\n return {\n supabase_url: body.supabase_url,\n supabase_anon_key: body.supabase_anon_key,\n oauth_provider: body.oauth_provider,\n redirect_urls: body.redirect_urls.map(String),\n server_version: typeof body.server_version === \"string\" ? body.server_version : undefined,\n };\n}\nfunction parseDetail(text) {\n try {\n return JSON.parse(text);\n }\n catch {\n return text;\n }\n}\n// Supabase Auth (GoTrue) token endpoint: POST /auth/v1/token?grant_type=\u2026, the\n// anon key in the apikey header, JSON body per grant.\nexport async function gotrueToken(supabaseUrl, anonKey, grantType, body) {\n const res = await fetchWithTimeout(`${supabaseUrl.replace(/\\/+$/, \"\")}/auth/v1/token?grant_type=${grantType}`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", apikey: anonKey },\n body: JSON.stringify(body),\n });\n const text = await res.text();\n if (!res.ok) {\n throw new ApiError(res.status, grantType === \"pkce\" ? \"login_failed\" : \"refresh_failed\", parseDetail(text));\n }\n const parsed = JSON.parse(text);\n if (typeof parsed.access_token !== \"string\" ||\n typeof parsed.refresh_token !== \"string\" ||\n typeof parsed.expires_in !== \"number\") {\n throw new ApiError(res.status, \"token_malformed\", parsed);\n }\n return {\n access_token: parsed.access_token,\n refresh_token: parsed.refresh_token,\n expires_in: parsed.expires_in,\n };\n}\nfunction base64url(buf) {\n return buf.toString(\"base64url\");\n}\n// Bind the first free allow-listed loopback callback (IPv4). The bases come\n// from the API, so the client and the Supabase allow list cannot drift.\nasync function bindCallback(server, redirectUrls) {\n for (const candidate of redirectUrls) {\n const port = Number(new URL(candidate).port);\n const bound = await new Promise((resolve) => {\n const onError = () => {\n server.off(\"error\", onError);\n resolve(false);\n };\n server.once(\"error\", onError);\n server.listen(port, \"127.0.0.1\", () => {\n server.off(\"error\", onError);\n resolve(true);\n });\n });\n if (bound)\n return candidate;\n }\n throw new Error(`No free login callback port among: ${redirectUrls.join(\", \")}`);\n}\n// OAuth Authorization Code with PKCE through Supabase Auth: open the provider\n// login in the browser, receive the code on a loopback callback, exchange code +\n// verifier for tokens. No client secret exists anywhere in the client.\n//\n// Supabase Auth's /authorize carries no `state` parameter, so the per-attempt\n// state rides in the callback path (`/callback/<state>`); any other path is a\n// 404 and the server keeps waiting. The allow list holds `/callback/*`.\nexport async function browserLogin(apiBase, openBrowser, timeoutMs = 300_000) {\n const config = await fetchAuthConfig(apiBase);\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n const state = base64url(randomBytes(16));\n const code = await new Promise((resolve, reject) => {\n let timer;\n const finish = (outcome) => {\n if (timer)\n clearTimeout(timer);\n server.closeAllConnections();\n server.close();\n if (\"code\" in outcome)\n resolve(outcome.code);\n else\n reject(outcome.error);\n };\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n if (req.method !== \"GET\" || url.pathname !== `/callback/${state}`) {\n res.writeHead(404).end();\n return;\n }\n const failure = url.searchParams.get(\"error_description\") ?? url.searchParams.get(\"error\");\n const received = url.searchParams.get(\"code\");\n if (failure || !received) {\n res.writeHead(400, { \"Content-Type\": \"text/plain\" }).end(`Login failed: ${failure ?? \"no code\"}`);\n finish({ error: new Error(`Login failed: ${failure ?? \"no code returned\"}`) });\n return;\n }\n res\n .writeHead(200, { \"Content-Type\": \"text/plain\" })\n .end(\"Logged in to Grimoire. You can close this tab.\");\n finish({ code: received });\n });\n bindCallback(server, config.redirect_urls)\n .then((redirectBase) => {\n timer = setTimeout(() => finish({ error: new Error(\"Login timed out\") }), timeoutMs);\n const authorize = new URL(`${config.supabase_url.replace(/\\/+$/, \"\")}/auth/v1/authorize`);\n authorize.searchParams.set(\"provider\", config.oauth_provider);\n authorize.searchParams.set(\"redirect_to\", `${redirectBase.replace(/\\/+$/, \"\")}/${state}`);\n authorize.searchParams.set(\"code_challenge\", challenge);\n authorize.searchParams.set(\"code_challenge_method\", \"s256\");\n openBrowser(authorize.toString());\n })\n .catch((err) => finish({ error: err }));\n });\n const tokens = await gotrueToken(config.supabase_url, config.supabase_anon_key, \"pkce\", {\n auth_code: code,\n code_verifier: verifier,\n });\n storeSession({\n refresh_token: tokens.refresh_token,\n supabase_url: config.supabase_url,\n supabase_anon_key: config.supabase_anon_key,\n });\n}\n// Claims of an access token, read without verification \u2014 for display only\n// (the API verifies every token it receives).\nexport function tokenClaims(token) {\n const payload = token.split(\".\")[1];\n if (!payload)\n return {};\n try {\n return JSON.parse(Buffer.from(payload, \"base64url\").toString(\"utf8\"));\n }\n catch {\n return {};\n }\n}\n", "export class ApiError extends Error {\n status;\n code;\n body;\n constructor(status, code, body) {\n super(`${code} (${status})`);\n this.status = status;\n this.code = code;\n this.body = body;\n }\n}\n", "import { ApiError } from \"./errors.js\";\nexport const REQUEST_TIMEOUT_MS = 30_000;\nexport async function fetchWithTimeout(url, init = {}) {\n try {\n return await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });\n }\n catch (err) {\n if (err instanceof Error && (err.name === \"TimeoutError\" || err.name === \"AbortError\")) {\n throw new ApiError(408, \"timeout\", `Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);\n }\n // Undici reports DNS/TLS/connection failures as `TypeError: fetch failed` with the\n // useful detail in `cause`; surface both under a consistent ApiError.\n const message = err instanceof Error ? err.message : String(err);\n const cause = err instanceof Error && err.cause instanceof Error ? `: ${err.cause.message}` : \"\";\n throw new ApiError(0, \"network_error\", `${message}${cause}`);\n }\n}\n", "import { gotrueToken, readMachineToken, readSession, storeSession, tokenClaims } from \"./auth.js\";\nimport { loadGlobalConfig } from \"./config.js\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\nexport { ApiError } from \"./errors.js\";\nconst CODES = {\n 401: \"unauthorized\",\n 403: \"forbidden\",\n 404: \"not_found\",\n 422: \"invalid_request\",\n 429: \"quota_exceeded\",\n};\nexport class GrimoireClient {\n baseUrl;\n machineToken;\n cachedAccessToken;\n refreshInFlight;\n constructor(opts = {}) {\n this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\\/+$/, \"\");\n this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN ?? readMachineToken();\n }\n async bearer() {\n if (this.machineToken)\n return this.machineToken;\n if (this.cachedAccessToken && this.cachedAccessToken.expiresAt > Date.now() + 60_000) {\n return this.cachedAccessToken.token;\n }\n this.refreshInFlight ??= this.refreshAccessToken().finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n // Exchange the stored refresh token for a fresh access token. GoTrue rotates\n // refresh tokens, so the new one replaces the stored one every time.\n async refreshAccessToken() {\n const session = readSession();\n if (!session)\n throw new ApiError(401, \"not_logged_in\", \"Run `grimoire login`\");\n let tokens;\n try {\n tokens = await gotrueToken(session.supabase_url, session.supabase_anon_key, \"refresh_token\", {\n refresh_token: session.refresh_token,\n });\n }\n catch (err) {\n if (err instanceof ApiError)\n throw new ApiError(err.status, \"refresh_failed\", \"Run `grimoire login`\");\n throw err;\n }\n storeSession({ ...session, refresh_token: tokens.refresh_token });\n this.cachedAccessToken = {\n token: tokens.access_token,\n expiresAt: Date.now() + tokens.expires_in * 1000,\n };\n return tokens.access_token;\n }\n async refreshSession() {\n await this.bearer();\n }\n // The login email from the session token; undefined for machine tokens.\n /** The account's Supabase subject, readable before any grant exists. */\n async sessionSubject() {\n const claims = tokenClaims(await this.bearer());\n return typeof claims.sub === \"string\" ? claims.sub : undefined;\n }\n async sessionEmail() {\n if (this.machineToken)\n return undefined;\n const email = tokenClaims(await this.bearer()).email;\n return typeof email === \"string\" ? email : undefined;\n }\n async send(path, init, auth) {\n const headers = {\n \"Content-Type\": \"application/json\",\n ...init.headers,\n };\n if (auth)\n headers.Authorization = `Bearer ${await this.bearer()}`;\n return fetchWithTimeout(`${this.baseUrl}${path}`, { ...init, headers });\n }\n async request(path, init = {}, auth = true) {\n let res = await this.send(path, init, auth);\n // A 401 despite a locally-unexpired access token means it was revoked\n // server-side: force one refresh and retry exactly once.\n if (res.status === 401 && auth && !this.machineToken) {\n this.cachedAccessToken = undefined;\n res = await this.send(path, init, auth);\n }\n return this.parseResponse(res);\n }\n // FastAPI errors carry {\"detail\": \"...\"} (string) or {\"detail\": [...]} (422).\n async parseResponse(res) {\n const isJson = res.headers.get(\"content-type\")?.includes(\"json\") ?? false;\n const text = await res.text();\n let body;\n let parsed = false;\n if (isJson && text) {\n try {\n body = JSON.parse(text);\n parsed = true;\n }\n catch {\n parsed = false;\n }\n }\n if (!res.ok) {\n const detail = parsed && typeof body === \"object\" && body !== null ? body.detail : undefined;\n throw new ApiError(res.status, CODES[res.status] ?? \"error\", detail ?? (parsed ? body : text));\n }\n if (isJson)\n return (parsed ? body : {});\n return text;\n }\n search(input) {\n return this.request(\"/v1/search\", { method: \"POST\", body: JSON.stringify(input) });\n }\n listSources() {\n return this.request(\"/v1/sources\");\n }\n listVersions(product) {\n return this.request(`/v1/sources/${encodeURIComponent(product)}/versions`);\n }\n getDoc(pointId, window = 2) {\n return this.request(`/v1/doc/${encodeURIComponent(pointId)}?window=${window}`);\n }\n reportResult(pointId, verdict, note) {\n const body = { point_id: pointId, verdict, ...(note ? { note } : {}) };\n return this.request(\"/v1/report\", { method: \"POST\", body: JSON.stringify(body) });\n }\n submitSource(body) {\n return this.request(\"/v1/sources\", { method: \"POST\", body: JSON.stringify(body) });\n }\n getJob(jobId) {\n return this.request(`/v1/jobs/${encodeURIComponent(jobId)}`);\n }\n me() {\n return this.request(\"/v1/me\");\n }\n reviewQueue() {\n return this.request(\"/v1/staff/review-queue\");\n }\n approveJob(jobId) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/approve`, { method: \"POST\" });\n }\n listUsers() {\n return this.request(\"/v1/staff/users\");\n }\n grantUser(subject, name, staff = false) {\n return this.request(\"/v1/staff/users\", {\n method: \"POST\",\n body: JSON.stringify({ subject, name, staff }),\n });\n }\n revokeUser(subject) {\n return this.request(`/v1/staff/users/${encodeURIComponent(subject)}`, { method: \"DELETE\" });\n }\n mintToken(name, quotaPerDay) {\n return this.request(\"/v1/staff/tokens\", {\n method: \"POST\",\n body: JSON.stringify({ name, quota_per_day: quotaPerDay }),\n });\n }\n recrawlSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/recrawl`, { method: \"POST\" });\n }\n listFrontier(sourceId, filter = {}) {\n const params = new URLSearchParams();\n if (filter.status)\n params.set(\"status\", filter.status);\n if (filter.limit !== undefined)\n params.set(\"limit\", String(filter.limit));\n const query = params.toString();\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/frontier${query ? `?${query}` : \"\"}`);\n }\n createUploadSource(body) {\n return this.request(\"/v1/staff/sources\", { method: \"POST\", body: JSON.stringify(body) });\n }\n uploadPage(sourceId, url, html) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/pages`, {\n method: \"PUT\",\n body: JSON.stringify({ url, html }),\n });\n }\n reindexSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}/reindex`, { method: \"POST\" });\n }\n sourceDetail(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`);\n }\n editSource(sourceId, body) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`, {\n method: \"PATCH\",\n body: JSON.stringify(body),\n });\n }\n purgeSource(sourceId) {\n return this.request(`/v1/staff/sources/${encodeURIComponent(sourceId)}`, { method: \"DELETE\" });\n }\n listJobs(filter) {\n const params = new URLSearchParams();\n if (filter.sourceId)\n params.set(\"source_id\", filter.sourceId);\n if (filter.state)\n params.set(\"state\", filter.state);\n if (filter.kind)\n params.set(\"kind\", filter.kind);\n if (filter.limit !== undefined)\n params.set(\"limit\", String(filter.limit));\n const query = params.toString();\n return this.request(`/v1/staff/jobs${query ? `?${query}` : \"\"}`);\n }\n cancelJob(jobId) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/cancel`, { method: \"POST\" });\n }\n rejectJob(jobId, reason) {\n return this.request(`/v1/staff/jobs/${encodeURIComponent(jobId)}/reject`, {\n method: \"POST\",\n body: JSON.stringify({ reason }),\n });\n }\n}\n", "// Minimal flag parser: collects repeated --flag/-f values and positionals.\nexport interface ParsedArgs {\n positionals: string[];\n flags: Record<string, string[]>;\n bools: Set<string>;\n}\n\nexport class UsageError extends Error {}\n\nconst BOOL_FLAGS = new Set([\n \"json\",\n \"yes\",\n \"verbose\",\n \"compact\",\n \"watch\",\n \"names\",\n \"http\",\n \"unset\",\n \"rolling\",\n \"debug\",\n \"no-launch-browser\",\n]);\n\nexport function parseArgs(\n argv: string[],\n aliases: Record<string, string> = {},\n allowed?: readonly string[],\n): ParsedArgs {\n const positionals: string[] = [];\n const flags: Record<string, string[]> = {};\n const bools = new Set<string>();\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg.startsWith(\"--\") || arg.startsWith(\"-\")) {\n const name = aliases[arg] ?? arg.replace(/^--?/, \"\");\n // A misspelled flag silently swallowing its value (`--top 4` when the\n // real flag is --top-k) must fail loudly, not act like it worked.\n if (allowed && !allowed.includes(name)) {\n throw new UsageError(`Unknown flag ${arg} \u2014 run \\`grimoire help\\` for valid flags`);\n }\n if (BOOL_FLAGS.has(name)) {\n bools.add(name);\n } else {\n const value = argv[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n throw new UsageError(`Flag ${arg} requires a value`);\n }\n (flags[name] ??= []).push(value);\n i++;\n }\n } else {\n positionals.push(arg);\n }\n }\n return { positionals, flags, bools };\n}\n\nexport function requirePositional(parsed: ParsedArgs, index: number, usage: string): string {\n const value = parsed.positionals[index];\n if (value === undefined) throw new UsageError(usage);\n return value;\n}\n\nexport function intFlag(\n parsed: ParsedArgs,\n name: string,\n range?: { min: number; max: number },\n): number | undefined {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined) return undefined;\n const value = Number(raw);\n if (!Number.isInteger(value)) throw new UsageError(`Flag --${name} must be an integer`);\n if (range && (value < range.min || value > range.max)) {\n throw new UsageError(`Flag --${name} must be between ${range.min} and ${range.max}`);\n }\n return value;\n}\n\nexport function requireFlagOneOf(\n parsed: ParsedArgs,\n name: string,\n allowed: readonly string[],\n usage: string,\n): string {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined || !allowed.includes(raw)) throw new UsageError(usage);\n return raw;\n}\n", "// The command surface: the help text, the flags each command accepts, and the\n// client version. Kept in its own module so a test can read them without\n// running the CLI. help.test.ts holds this file, the parser, and the readme\n// together \u2014 a new command or flag has to appear in all three.\n\ndeclare const __GRIMOIRE_VERSION__: string | undefined;\nexport const VERSION = typeof __GRIMOIRE_VERSION__ === \"string\" ? __GRIMOIRE_VERSION__ : \"dev\";\n\nexport const HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents\n\n grimoire login [--no-launch-browser] | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--reranker <name>] [--json|--compact] [--debug] [--verbose]\n grimoire sources [--q <kw>] [--names|--json]\n grimoire versions <product> [--json]\n grimoire config [<key>] [<value>] [--unset]\n grimoire update\n grimoire doc <point_id> [--window 2] [--json]\n grimoire report <point_id> --verdict helpful|incorrect|outdated [--note \"...\"]\n grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>])\n [--include <pattern>]... [--exclude <pattern>]... [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire staff queue [--json] | approve <job_id> | reject <job_id> --reason \"...\"\n grimoire staff users [--json] | grant <subject> --name \"...\" [--staff on|off] | revoke <subject>\n grimoire staff token <name> --quota <per-day>\n grimoire staff jobs [--source <product|id>] [--state <state>] [--kind <kind>] [--limit 50] [--json]\n grimoire staff cancel <job_id>\n grimoire staff source <product|id> [--watch] [--json]\n grimoire staff source <product|id> [--include <pattern>]... [--exclude <pattern>]... [--status active|disabled] [--markdown on|off]\n grimoire staff source <product|id> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo>)\n grimoire staff urls <product|id> [--state <crawl state>] [--limit 50] [--json]\n grimoire staff create <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>]) [--include <pattern>]... [--exclude <pattern>]...\n grimoire staff upload <product|id> <page-url> <file.html>\n grimoire staff recrawl <product|id> | reindex <product|id> | purge <product|id> --yes\n grimoire mcp [--http]\n grimoire help | --help | -h\n grimoire version | --version | -v\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path\n`;\n\n// Canonical flag names each command accepts; parseArgs rejects anything else.\nexport const COMMAND_FLAGS: Record<string, readonly string[]> = {\n version: [], \"--version\": [], \"-v\": [],\n login: [\"no-launch-browser\"], logout: [], setup: [], init: [], whoami: [],\n help: [], \"--help\": [], \"-h\": [],\n mcp: [\"http\"],\n config: [\"unset\"],\n update: [],\n search: [\"source\", \"json\", \"compact\", \"debug\", \"verbose\", \"reranker\"],\n sources: [\"q\", \"names\", \"json\"],\n versions: [\"json\"],\n doc: [\"window\", \"json\"],\n report: [\"verdict\", \"note\"],\n ingest: [\"product\", \"rolling\", \"fixed\", \"npm\", \"pypi\", \"github\", \"tag-pattern\", \"include\", \"exclude\", \"watch\"],\n jobs: [\"watch\"],\n staff: [\"reason\", \"name\", \"quota\", \"json\", \"source\", \"state\", \"kind\", \"limit\", \"include\", \"exclude\", \"status\", \"markdown\", \"yes\", \"watch\", \"rolling\", \"fixed\", \"npm\", \"pypi\", \"github\", \"tag-pattern\", \"staff\", \"product\"],\n};\n", "import type { SearchResponse, SearchResult } from \"@monadeo.com/grimoire-core\";\n\n// Exit codes documented for scripting (clients spec).\nexport const EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 } as const;\n\n// The API labels result text as untrusted data; the CLI repeats that on stderr\n// so agents reading stdout never see it as an instruction.\n/** Where the time went, on stderr, so stdout stays the answer. */\nexport function printTimings(res: SearchResponse): void {\n const t = res.timings;\n if (!t) {\n process.stderr.write(`timings: total ${res.latency_ms} ms (server older than 0.21.0 reports no stages)\\n`);\n return;\n }\n process.stderr.write(\n `timings: embed ${t.embed_ms} ms \u00B7 retrieve ${t.retrieve_ms} ms \u00B7 rerank ${t.rerank_ms} ms (${res.reranker ?? \"local\"}) \u00B7 stitch ${t.stitch_ms} ms \u00B7 total ${t.total_ms} ms\\n`,\n );\n}\n\nfunction preamble(res: SearchResponse): void {\n const versions = Object.entries(res.resolved_versions)\n .map(([product, version]) => `${product}@${version}`)\n .join(\", \");\n process.stderr.write(`sources: ${versions} \u00B7 retrievals remaining: ${res.retrievals_remaining}\\n`);\n process.stderr.write(`note: ${res.untrusted_content_notice}\\n`);\n if (res.results.length === 0) {\n process.stderr.write(\"note: no result passed the relevance threshold \u2014 the docs may not cover this.\\n\");\n }\n}\n\nfunction heading(r: SearchResult): string {\n return r.heading_path.join(\" \u203A \");\n}\n\nexport function printResults(res: SearchResponse): void {\n preamble(res);\n for (const r of res.results) {\n process.stdout.write(\n `\\n${r.score.toFixed(3)} ${r.product}@${r.version} ${heading(r)}\\n${r.source_url}\\npoint_id: ${r.point_id}\\n`,\n );\n const preview = r.text.length > 500 ? `${r.text.slice(0, 500)}\u2026` : r.text;\n process.stdout.write(`${preview}\\n`);\n }\n}\n\nexport function printCompact(res: SearchResponse): void {\n preamble(res);\n for (const r of res.results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.product}@${r.version} | ${heading(r)} | ${r.source_url} | ${r.point_id}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { readMachineToken, readSession } from \"@monadeo.com/grimoire-core\";\n\n// One-command agent onboarding (SDD decision 19 / clients spec): writes the MCP\n// registration for the named agent. `npx @monadeo.com/grimoire-mcp` needs no global install.\nconst MCP_ENTRY = { command: \"npx\", args: [\"-y\", \"@monadeo.com/grimoire-mcp\"] };\n\nconst CODEX_TABLE = `[mcp_servers.grimoire]\ncommand = \"npx\"\nargs = [\"-y\", \"@monadeo.com/grimoire-mcp\"]\n`;\n\n// Codex reads ~/.codex/config.toml. Replace our table in place (up to the next\n// [ header or EOF) without a TOML library, so the rest of the user's config\n// passes through byte-for-byte.\nexport function mergeCodexToml(existing: string): string {\n const header = existing.match(/^[ \\t]*\\[mcp_servers\\.grimoire\\][ \\t]*(\\r?\\n|$)/m);\n if (!header || header.index === undefined) {\n if (existing.trim() === \"\") return CODEX_TABLE;\n const sep = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return existing + sep + CODEX_TABLE;\n }\n const afterHeader = header.index + header[0].length;\n const nextHeader = existing.slice(afterHeader).match(/^[ \\t]*\\[/m);\n const end =\n nextHeader && nextHeader.index !== undefined ? afterHeader + nextHeader.index : existing.length;\n return existing.slice(0, header.index) + CODEX_TABLE + existing.slice(end);\n}\n\ninterface JsonAgentTarget {\n path: string;\n apply: (existing: Record<string, unknown>) => Record<string, unknown>;\n}\n\nfunction mcpServersMerge(key: string) {\n return (existing: Record<string, unknown>) => {\n const servers = (existing[key] as Record<string, unknown>) ?? {};\n return { ...existing, [key]: { ...servers, grimoire: MCP_ENTRY } };\n };\n}\n\nconst JSON_AGENTS: Record<string, JsonAgentTarget> = {\n \"claude-code\": { path: join(homedir(), \".claude.json\"), apply: mcpServersMerge(\"mcpServers\") },\n cursor: { path: join(homedir(), \".cursor\", \"mcp.json\"), apply: mcpServersMerge(\"mcpServers\") },\n windsurf: {\n path: join(homedir(), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n apply: mcpServersMerge(\"mcpServers\"),\n },\n};\n\nconst AGENT_NAMES = [...Object.keys(JSON_AGENTS), \"codex\"];\n\nfunction setupCodex(): number {\n const path = join(homedir(), \".codex\", \"config.toml\");\n const existing = existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, mergeCodexToml(existing));\n return finish(\"codex\", path);\n}\n\n// Best-effort session probe: an unreadable credentials file must fall through\n// to the hint, never crash setup.\nfunction hasSession(): boolean {\n if (process.env.GRIMOIRE_AUTH_TOKEN) return true;\n try {\n return readMachineToken() !== undefined || readSession() !== undefined;\n } catch {\n return false;\n }\n}\n\nfunction finish(agent: string, path: string): number {\n process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}\\n`);\n process.stdout.write(hasSession() ? \"Already logged in.\\n\" : \"Run `grimoire login` to authenticate.\\n\");\n return 0;\n}\n\nexport function runSetup(agent: string | undefined): number {\n if (!agent || !AGENT_NAMES.includes(agent)) {\n process.stderr.write(`Usage: grimoire setup <${AGENT_NAMES.join(\"|\")}>\\n`);\n return 1;\n }\n if (agent === \"codex\") return setupCodex();\n const target = JSON_AGENTS[agent];\n let existing: Record<string, unknown> = {};\n if (existsSync(target.path)) {\n try {\n existing = JSON.parse(readFileSync(target.path, \"utf8\")) as Record<string, unknown>;\n } catch (err) {\n process.stderr.write(\n `Cannot parse ${target.path}: ${(err as Error).message}\\nFix or remove the file, then re-run setup.\\n`,\n );\n return 1;\n }\n }\n mkdirSync(dirname(target.path), { recursive: true });\n writeFileSync(target.path, JSON.stringify(target.apply(existing), null, 2));\n return finish(agent, target.path);\n}\n", "import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { SourcePin } from \"@monadeo.com/grimoire-core\";\n\nfunction parseJsonFile<T>(path: string): T {\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as T;\n } catch (err) {\n throw new Error(`Cannot parse ${path}: ${(err as Error).message}`, { cause: err });\n }\n}\n\n// Scan common manifests \u2192 propose .grimoire.json source pins. Alias resolution\n// against the registry (curated to include package-ecosystem names) happens when\n// the sources are actually queried; init proposes candidate names from manifests.\nexport function detectManifestSources(dir = process.cwd()): SourcePin[] {\n const pins: SourcePin[] = [];\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = parseJsonFile<{ dependencies?: Record<string, string> }>(pkgPath);\n for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {\n const major = range.match(/(\\d+)/)?.[1];\n pins.push({ source: name.replace(/^@[^/]+\\//, \"\"), ...(major ? { version: major } : {}) });\n }\n }\n const reqPath = join(dir, \"requirements.txt\");\n if (existsSync(reqPath)) {\n for (const line of readFileSync(reqPath, \"utf8\").split(\"\\n\")) {\n const m = line.match(/^([A-Za-z0-9_.-]+)\\s*==\\s*(\\d+)/);\n if (m) pins.push({ source: m[1].toLowerCase(), version: m[2] });\n }\n }\n return pins;\n}\n\nexport function runInit(): number {\n const path = join(process.cwd(), \".grimoire.json\");\n try {\n const sources = detectManifestSources();\n if (sources.length === 0) {\n process.stderr.write(\"No package.json/requirements.txt dependencies found.\\n\");\n return 1;\n }\n const existing = existsSync(path) ? parseJsonFile<Record<string, unknown>>(path) : {};\n writeFileSync(path, JSON.stringify({ ...existing, sources }, null, 2));\n process.stdout.write(`Wrote ${sources.length} source pins to .grimoire.json\\n`);\n return 0;\n } catch (err) {\n process.stderr.write(`${(err as Error).message}\\n`);\n return 1;\n }\n}\n", "import {\n DEFAULT_API_BASE,\n globalConfigPath,\n loadGlobalConfig,\n updateGlobalConfigFile,\n storeMachineToken,\n readMachineToken,\n clearMachineToken,\n type GlobalConfig,\n} from \"@monadeo.com/grimoire-core\";\nimport { UsageError, type ParsedArgs } from \"../args.js\";\nimport { EXIT } from \"../output.js\";\n\ninterface KeySpec {\n prop: keyof GlobalConfig;\n describe: string;\n parse(raw: string): GlobalConfig[keyof GlobalConfig];\n}\n\nfunction intInRange(name: string, raw: string, min: number): number {\n const value = Number(raw);\n if (!Number.isInteger(value) || value < min) {\n throw new UsageError(`${name} must be an integer >= ${min}`);\n }\n return value;\n}\n\nexport const CONFIG_KEYS: Record<string, KeySpec> = {\n \"api-url\": {\n prop: \"apiBaseUrl\",\n describe: `API origin without a path (default ${DEFAULT_API_BASE}; env GRIMOIRE_API_URL overrides)`,\n parse: (raw) => {\n if (!/^https?:\\/\\/[^/]+$/.test(raw)) {\n throw new UsageError(\"api-url must be a bare origin, e.g. https://api.example.com\");\n }\n return raw;\n },\n },\n \"update-check-hours\": {\n prop: \"updateCheckHours\",\n describe: \"hours between CLI update checks (default 24, 0 disables)\",\n parse: (raw) => intInRange(\"update-check-hours\", raw, 0),\n },\n reranker: {\n prop: \"reranker\",\n describe: \"reranker for every search, one of `grimoire whoami` (default local)\",\n parse: (raw) => {\n if (raw !== \"local\" && !raw.startsWith(\"openrouter/\")) {\n throw new UsageError(\"reranker must be `local` or an `openrouter/...` name from `grimoire whoami`\");\n }\n return raw;\n },\n },\n};\n\n// auth-token is a secret and lives in a 0600 file, not the world-readable\n// config.json \u2014 so it is handled outside the CONFIG_KEYS (GlobalConfig) framework.\nconst AUTH_TOKEN_KEY = \"auth-token\";\nconst MACHINE_TOKEN_RE = /^mt_[A-Za-z0-9_-]{32,}$/;\nconst USAGE =\n \"Usage: grimoire config [<key>] [<value>] [--unset] (keys: \" +\n [...Object.keys(CONFIG_KEYS), AUTH_TOKEN_KEY].join(\", \") +\n \")\";\n\nexport function runConfig(args: ParsedArgs): number {\n const [key, value] = args.positionals;\n if (key === undefined) {\n const resolved = loadGlobalConfig();\n process.stdout.write(`config file: ${globalConfigPath()}\\n`);\n for (const [name, spec] of Object.entries(CONFIG_KEYS)) {\n const current = resolved[spec.prop];\n process.stdout.write(`${name} = ${current === undefined ? \"(unset)\" : JSON.stringify(current)} # ${spec.describe}\\n`);\n }\n process.stdout.write(\n `${AUTH_TOKEN_KEY} = ${readMachineToken() ? \"(set)\" : \"(unset)\"} # machine token, stored 0600 (env GRIMOIRE_AUTH_TOKEN overrides)\\n`,\n );\n return EXIT.ok;\n }\n if (key === AUTH_TOKEN_KEY) {\n if (args.bools.has(\"unset\")) {\n clearMachineToken();\n process.stdout.write(`${AUTH_TOKEN_KEY} unset\\n`);\n return EXIT.ok;\n }\n if (value === undefined) {\n // Never echo the secret \u2014 report presence only.\n process.stdout.write(`${readMachineToken() ? \"(set)\" : \"(unset)\"}\\n`);\n return EXIT.ok;\n }\n if (!MACHINE_TOKEN_RE.test(value)) {\n throw new UsageError(\"auth-token must be a machine token starting with mt_\");\n }\n storeMachineToken(value);\n process.stdout.write(`${AUTH_TOKEN_KEY} set\\n`);\n return EXIT.ok;\n }\n const spec = CONFIG_KEYS[key];\n if (!spec) throw new UsageError(USAGE);\n if (args.bools.has(\"unset\")) {\n updateGlobalConfigFile({ [spec.prop]: undefined });\n process.stdout.write(`${key} unset\\n`);\n return EXIT.ok;\n }\n if (value === undefined) {\n const current = loadGlobalConfig()[spec.prop];\n process.stdout.write(`${current === undefined ? \"\" : JSON.stringify(current)}\\n`);\n return EXIT.ok;\n }\n updateGlobalConfigFile({ [spec.prop]: spec.parse(value) });\n process.stdout.write(`${key} = ${value}\\n`);\n return EXIT.ok;\n}\n", "import { spawnSync } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport { EXIT } from \"../output.js\";\n\nconst BREW_CMD = [\"brew\", \"upgrade\", \"monadeo/tap/grimoire\"];\nconst NPM_CMD = [\"npm\", \"install\", \"-g\", \"@monadeo.com/grimoire-cli\"];\n\n// The running binary's real location tells us who installed it: Homebrew keeps\n// everything under a Cellar/homebrew prefix, npm under a lib/node_modules\n// global prefix. Anything else (pnpm dlx, npx cache, a repo checkout) is not\n// ours to upgrade \u2014 print the choices instead of guessing.\nexport function detectInstallKind(binPath: string): \"brew\" | \"npm\" | undefined {\n let real: string;\n try {\n real = realpathSync(binPath);\n } catch {\n return undefined;\n }\n if (/homebrew|\\/Cellar\\//i.test(real)) return \"brew\";\n if (/\\/lib\\/node_modules\\//.test(real)) return \"npm\";\n return undefined;\n}\n\n// `brew upgrade` reads the LOCAL tap clone \u2014 without pulling it first, brew\n// happily reports \"already installed\" for a version the registry has long\n// superseded (observed 2026-07-18 upgrading 0.3.4\u21920.3.5). Pull just our tap,\n// not `brew update`, which touches every tap and core. Best-effort: a pull\n// failure still proceeds to upgrade with whatever the local tap knows.\nfunction refreshTap(): void {\n const repo = spawnSync(\"brew\", [\"--repository\", \"monadeo/tap\"], { encoding: \"utf8\" });\n const tapPath = repo.status === 0 ? repo.stdout.trim() : \"\";\n if (!tapPath) return;\n spawnSync(\"git\", [\"-C\", tapPath, \"pull\", \"--ff-only\", \"--quiet\"], { stdio: \"inherit\" });\n}\n\nexport function runUpdate(): number {\n const kind = detectInstallKind(process.argv[1] ?? \"\");\n if (!kind) {\n process.stderr.write(\n `Could not detect how grimoire was installed. Update with one of:\\n ${BREW_CMD.join(\" \")}\\n ${NPM_CMD.join(\" \")}\\n`,\n );\n return EXIT.apiError;\n }\n if (kind === \"brew\") refreshTap();\n const cmd = kind === \"brew\" ? BREW_CMD : NPM_CMD;\n process.stdout.write(`${cmd.join(\" \")}\\n`);\n const result = spawnSync(cmd[0], cmd.slice(1), { stdio: \"inherit\" });\n if (result.error) {\n process.stderr.write(`update failed: ${result.error.message}\\n`);\n return EXIT.apiError;\n }\n return result.status === 0 ? EXIT.ok : EXIT.apiError;\n}\n", "import type { SubmissionIn } from \"@monadeo.com/grimoire-core\";\nimport { UsageError, type ParsedArgs } from \"../args.js\";\n\nexport function submissionFromArgs(url: string, args: ParsedArgs): SubmissionIn {\n const usage =\n \"Usage: grimoire ingest <url> --product <name> (--rolling | --fixed <version> | --npm <pkg> | --pypi <pkg> | --github <owner/repo> [--tag-pattern <regex>])\";\n const product = args.flags.product?.[0];\n if (!product) throw new UsageError(usage);\n const fixed = args.flags.fixed?.[0];\n const npm = args.flags.npm?.[0];\n const pypi = args.flags.pypi?.[0];\n const github = args.flags.github?.[0];\n const probes = [npm, pypi, github].filter(Boolean).length;\n if (probes > 1) throw new UsageError(\"Pass only one of --npm, --pypi, --github\");\n\n const body: SubmissionIn = {\n url,\n product,\n version_rule: { kind: \"rolling\" },\n include_patterns: args.flags.include ?? [],\n exclude_patterns: args.flags.exclude ?? [],\n };\n if (args.bools.has(\"rolling\")) return body;\n if (fixed) return { ...body, version_rule: { kind: \"fixed\", value: fixed } };\n if (npm) return { ...body, version_rule: { kind: \"fixed\" }, probe: { kind: \"npm\", package: npm } };\n if (pypi) return { ...body, version_rule: { kind: \"fixed\" }, probe: { kind: \"pypi\", package: pypi } };\n if (github) {\n // A release tag like `release-1.31.5` or `docker-v29.8.0` needs the pattern\n // whose first group is the version; a plain `v1.2.3` needs nothing.\n const tagPattern = args.flags[\"tag-pattern\"]?.[0];\n return {\n ...body,\n version_rule: { kind: \"fixed\" },\n probe: { kind: \"github\", repo: github, ...(tagPattern ? { tag_pattern: tagPattern } : {}) },\n };\n }\n throw new UsageError(`${usage}\\nA version rule is mandatory: --rolling for unversioned docs, --fixed, or a release probe.`);\n}\n\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\nconst REGISTRY_URL = \"https://registry.npmjs.org/@monadeo.com%2Fgrimoire-cli\";\nconst DEFAULT_INTERVAL_HOURS = 24;\nconst FETCH_TIMEOUT_MS = 1_500;\n\ninterface UpdateState {\n last_check_at?: string;\n latest?: string;\n}\n\nfunction statePath(): string {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"update-check.json\");\n}\n\nfunction readState(): UpdateState {\n try {\n return JSON.parse(readFileSync(statePath(), \"utf8\")) as UpdateState;\n } catch {\n return {};\n }\n}\n\nexport function newerVersion(a: string, b: string): boolean {\n const A = a.split(\".\").map(Number);\n const B = b.split(\".\").map(Number);\n if (A.some(Number.isNaN) || B.some(Number.isNaN)) return false;\n for (let i = 0; i < 3; i++) {\n const diff = (A[i] ?? 0) - (B[i] ?? 0);\n if (diff !== 0) return diff > 0;\n }\n return false;\n}\n\n// Prints the notice recorded by a PREVIOUS run \u2014 the registry fetch happens\n// after the command finishes, so startup stays instant.\nexport function notifyIfOutdated(current: string): void {\n if (current === \"dev\" || !process.stderr.isTTY) return;\n const { latest } = readState();\n if (latest && newerVersion(latest, current)) {\n process.stderr.write(`grimoire ${latest} is available (you have ${current}) \u2014 run \\`grimoire update\\`\\n`);\n }\n}\n\n// Best-effort, TTY-only, and never slows a command down by more than the fetch\n// timeout: agents in CI (no TTY) and dev builds skip entirely.\nexport async function refreshUpdateState(current: string, configuredHours?: number): Promise<void> {\n const hours = configuredHours ?? DEFAULT_INTERVAL_HOURS;\n if (hours === 0 || current === \"dev\" || !process.stderr.isTTY) return;\n const state = readState();\n const last = state.last_check_at ? Date.parse(state.last_check_at) : 0;\n if (Date.now() - last < hours * 3_600_000) return;\n try {\n const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });\n if (!res.ok) return;\n const body = (await res.json()) as { \"dist-tags\"?: { latest?: string } };\n const latest = body[\"dist-tags\"]?.latest;\n if (!latest) return;\n const path = statePath();\n if (!existsSync(dirname(path))) mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify({ last_check_at: new Date().toISOString(), latest }));\n } catch {\n return;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["existsSync", "readFileSync", "join", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "join", "homedir", "mkdirSync", "dirname", "writeFileSync", "readFileSync", "existsSync", "finish", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "join", "homedir", "existsSync", "readFileSync", "mkdirSync", "dirname", "writeFileSync", "existsSync", "readFileSync", "writeFileSync", "join", "spec", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "existsSync", "join", "readFileSync"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monadeo.com/grimoire-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"devDependencies": {
|
|
13
13
|
"@types/node": "^26.1.0",
|
|
14
14
|
"esbuild": "^0.28.1",
|
|
15
|
-
"@monadeo.com/grimoire-core": "0.
|
|
15
|
+
"@monadeo.com/grimoire-core": "0.14.0"
|
|
16
16
|
},
|
|
17
17
|
"description": "Grimoire CLI — version-correct documentation retrieval for AI coding agents",
|
|
18
18
|
"homepage": "https://grimoire.monadeo.com",
|