@monadeo.com/grimoire-cli 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +61 -15
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -75,7 +75,9 @@ async function fetchWithTimeout(url, init = {}) {
|
|
|
75
75
|
if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) {
|
|
76
76
|
throw new ApiError(408, "timeout", `Request timed out after ${REQUEST_TIMEOUT_MS / 1e3}s`);
|
|
77
77
|
}
|
|
78
|
-
|
|
78
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
79
|
+
const cause = err instanceof Error && err.cause instanceof Error ? `: ${err.cause.message}` : "";
|
|
80
|
+
throw new ApiError(0, "network_error", `${message}${cause}`);
|
|
79
81
|
}
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -117,8 +119,7 @@ async function browserLogin(apiBase, openBrowser2) {
|
|
|
117
119
|
res2.writeHead(404).end();
|
|
118
120
|
return;
|
|
119
121
|
}
|
|
120
|
-
res2.writeHead(
|
|
121
|
-
res2.end("<p>Login complete \u2014 return to your terminal.</p>");
|
|
122
|
+
res2.writeHead(302, { Location: `${broker}/auth/cli/success` }).end();
|
|
122
123
|
clearTimeout(timer);
|
|
123
124
|
server.close();
|
|
124
125
|
resolve(received);
|
|
@@ -141,6 +142,9 @@ async function browserLogin(apiBase, openBrowser2) {
|
|
|
141
142
|
if (!res.ok)
|
|
142
143
|
throw new Error(`Token exchange failed: ${res.status}`);
|
|
143
144
|
const { refresh_token } = await res.json();
|
|
145
|
+
if (typeof refresh_token !== "string" || refresh_token.length === 0) {
|
|
146
|
+
throw new Error("Token exchange succeeded but returned no refresh token");
|
|
147
|
+
}
|
|
144
148
|
storeRefreshToken(refresh_token);
|
|
145
149
|
}
|
|
146
150
|
|
|
@@ -263,7 +267,7 @@ var GrimoireClient = class {
|
|
|
263
267
|
// src/args.ts
|
|
264
268
|
var UsageError = class extends Error {
|
|
265
269
|
};
|
|
266
|
-
var BOOL_FLAGS = /* @__PURE__ */ new Set(["json", "compact", "watch", "private", "names"]);
|
|
270
|
+
var BOOL_FLAGS = /* @__PURE__ */ new Set(["json", "compact", "watch", "private", "names", "http"]);
|
|
267
271
|
function parseArgs(argv, aliases = {}) {
|
|
268
272
|
const positionals = [];
|
|
269
273
|
const flags = {};
|
|
@@ -288,15 +292,38 @@ function parseArgs(argv, aliases = {}) {
|
|
|
288
292
|
}
|
|
289
293
|
return { positionals, flags, bools };
|
|
290
294
|
}
|
|
295
|
+
function requirePositional(parsed, index, usage) {
|
|
296
|
+
const value = parsed.positionals[index];
|
|
297
|
+
if (value === void 0) throw new UsageError(usage);
|
|
298
|
+
return value;
|
|
299
|
+
}
|
|
300
|
+
function intFlag(parsed, name, range) {
|
|
301
|
+
const raw = parsed.flags[name]?.[0];
|
|
302
|
+
if (raw === void 0) return void 0;
|
|
303
|
+
const value = Number(raw);
|
|
304
|
+
if (!Number.isInteger(value)) throw new UsageError(`Flag --${name} must be an integer`);
|
|
305
|
+
if (range && (value < range.min || value > range.max)) {
|
|
306
|
+
throw new UsageError(`Flag --${name} must be between ${range.min} and ${range.max}`);
|
|
307
|
+
}
|
|
308
|
+
return value;
|
|
309
|
+
}
|
|
310
|
+
function requireFlagOneOf(parsed, name, allowed, usage) {
|
|
311
|
+
const raw = parsed.flags[name]?.[0];
|
|
312
|
+
if (raw === void 0 || !allowed.includes(raw)) throw new UsageError(usage);
|
|
313
|
+
return raw;
|
|
314
|
+
}
|
|
291
315
|
|
|
292
316
|
// src/output.ts
|
|
293
317
|
var EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 };
|
|
294
|
-
function
|
|
318
|
+
function warnWeak(confidence) {
|
|
295
319
|
if (confidence === "weak") {
|
|
296
320
|
process.stderr.write(
|
|
297
321
|
"note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\n"
|
|
298
322
|
);
|
|
299
323
|
}
|
|
324
|
+
}
|
|
325
|
+
function printResults(results, confidence) {
|
|
326
|
+
warnWeak(confidence);
|
|
300
327
|
for (const r of results) {
|
|
301
328
|
const path = (r.heading_path ?? []).join(" \u203A ");
|
|
302
329
|
process.stdout.write(`
|
|
@@ -308,7 +335,8 @@ ${r.origin_url}
|
|
|
308
335
|
`);
|
|
309
336
|
}
|
|
310
337
|
}
|
|
311
|
-
function printCompact(results) {
|
|
338
|
+
function printCompact(results, confidence) {
|
|
339
|
+
warnWeak(confidence);
|
|
312
340
|
for (const r of results) {
|
|
313
341
|
process.stdout.write(
|
|
314
342
|
`${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(" \u203A ")} | ${r.origin_url}
|
|
@@ -467,7 +495,7 @@ var HELP = `grimoire \u2014 documentation retrieval for AI agents
|
|
|
467
495
|
grimoire sources [--q <kw>] [--json]
|
|
468
496
|
grimoire versions <source> [--json]
|
|
469
497
|
grimoire doc <chunk_id> [--window 2]
|
|
470
|
-
grimoire report <chunk_id> --verdict incorrect|outdated
|
|
498
|
+
grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note "..."]
|
|
471
499
|
grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]
|
|
472
500
|
grimoire jobs <job_id> [--watch]
|
|
473
501
|
grimoire mcp [--http]
|
|
@@ -483,6 +511,11 @@ async function main(argv) {
|
|
|
483
511
|
case "login": {
|
|
484
512
|
await browserLogin(loadGlobalConfig().apiBaseUrl, openBrowser);
|
|
485
513
|
process.stdout.write("Logged in.\n");
|
|
514
|
+
if (process.platform === "darwin") {
|
|
515
|
+
process.stdout.write(
|
|
516
|
+
'note: macOS may ask to allow keychain access when a tool first uses this session \u2014 choose "Always Allow".\n'
|
|
517
|
+
);
|
|
518
|
+
}
|
|
486
519
|
return EXIT.ok;
|
|
487
520
|
}
|
|
488
521
|
case "logout":
|
|
@@ -541,10 +574,10 @@ async function main(argv) {
|
|
|
541
574
|
query,
|
|
542
575
|
sources,
|
|
543
576
|
language: args.flags.lang?.[0],
|
|
544
|
-
top_k: args
|
|
577
|
+
top_k: intFlag(args, "top-k")
|
|
545
578
|
});
|
|
546
579
|
if (json) process.stdout.write(JSON.stringify(res, null, 2) + "\n");
|
|
547
|
-
else if (args.bools.has("compact")) printCompact(res.results);
|
|
580
|
+
else if (args.bools.has("compact")) printCompact(res.results, res.confidence);
|
|
548
581
|
else printResults(res.results, res.confidence);
|
|
549
582
|
return EXIT.ok;
|
|
550
583
|
}
|
|
@@ -554,23 +587,34 @@ async function main(argv) {
|
|
|
554
587
|
return EXIT.ok;
|
|
555
588
|
}
|
|
556
589
|
case "versions": {
|
|
557
|
-
const
|
|
590
|
+
const source = requirePositional(args, 0, "Usage: grimoire versions <source> [--json]");
|
|
591
|
+
const res = await client.listVersions(source);
|
|
558
592
|
process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + "\n");
|
|
559
593
|
return EXIT.ok;
|
|
560
594
|
}
|
|
561
595
|
case "doc": {
|
|
562
|
-
const
|
|
596
|
+
const chunkId = requirePositional(args, 0, "Usage: grimoire doc <chunk_id> [--window 2]");
|
|
597
|
+
const window = intFlag(args, "window", { min: 0, max: 5 }) ?? 2;
|
|
598
|
+
const res = await client.getContext(chunkId, window);
|
|
563
599
|
process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + "\n");
|
|
564
600
|
return EXIT.ok;
|
|
565
601
|
}
|
|
566
602
|
case "report": {
|
|
567
|
-
|
|
603
|
+
const usage = 'Usage: grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note "..."]';
|
|
604
|
+
const chunkId = requirePositional(args, 0, usage);
|
|
605
|
+
const verdict = requireFlagOneOf(args, "verdict", ["helpful", "incorrect", "outdated"], usage);
|
|
606
|
+
await client.reportResult(chunkId, verdict, args.flags.note?.[0]);
|
|
568
607
|
process.stdout.write("Reported.\n");
|
|
569
608
|
return EXIT.ok;
|
|
570
609
|
}
|
|
571
610
|
case "ingest": {
|
|
611
|
+
const url = requirePositional(
|
|
612
|
+
args,
|
|
613
|
+
0,
|
|
614
|
+
"Usage: grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]"
|
|
615
|
+
);
|
|
572
616
|
const res = await client.submitSource({
|
|
573
|
-
url
|
|
617
|
+
url,
|
|
574
618
|
version: args.flags.version?.[0],
|
|
575
619
|
visibility: args.bools.has("private") ? "private" : "public",
|
|
576
620
|
webhook_url: args.flags.webhook?.[0]
|
|
@@ -580,8 +624,10 @@ async function main(argv) {
|
|
|
580
624
|
if (args.bools.has("watch")) return watchJob(client, res.job_id);
|
|
581
625
|
return EXIT.ok;
|
|
582
626
|
}
|
|
583
|
-
case "jobs":
|
|
584
|
-
|
|
627
|
+
case "jobs": {
|
|
628
|
+
const jobId = requirePositional(args, 0, "Usage: grimoire jobs <job_id> [--watch]");
|
|
629
|
+
return args.bools.has("watch") ? watchJob(client, jobId) : printJob(client, jobId);
|
|
630
|
+
}
|
|
585
631
|
default:
|
|
586
632
|
process.stderr.write(`Unknown command: ${command}
|
|
587
633
|
${HELP}`);
|
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/output.ts", "../src/commands/setup.ts", "../src/commands/init.ts"],
|
|
4
|
-
"sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n clearRefreshToken,\n readRefreshToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type SourcePin,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, UsageError } from \"./args.js\";\nimport { printResults, printCompact, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\n\nfunction openBrowser(url: string): void {\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.stdout.write(`Open this URL to log in:\\n${url}\\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\nconst HELP = `grimoire \u2014 documentation retrieval for AI agents\n\n grimoire login | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--lang en] [--top-k 8] [--json|--compact]\n grimoire sources [--q <kw>] [--json]\n grimoire versions <source> [--json]\n grimoire doc <chunk_id> [--window 2]\n grimoire report <chunk_id> --verdict incorrect|outdated|helpful [--note \"...\"]\n grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire mcp [--http]\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" });\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"login\": {\n await browserLogin(loadGlobalConfig().apiBaseUrl, openBrowser);\n process.stdout.write(\"Logged in.\\n\");\n return EXIT.ok;\n }\n case \"logout\":\n clearRefreshToken();\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 \"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 process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n if (process.env.GRIMOIRE_AUTH_TOKEN) {\n process.stdout.write(\"machine token configured (GRIMOIRE_AUTH_TOKEN)\\n\");\n return EXIT.ok;\n }\n if (!readRefreshToken()) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n try {\n await client.refreshSession();\n process.stdout.write(\"logged in (browser session)\\n\");\n return EXIT.ok;\n } catch (err) {\n const reason = err instanceof ApiError ? err.code : (err as Error).message;\n process.stderr.write(`not logged in (${reason}) \u2014 run \\`grimoire login\\`\\n`);\n return EXIT.authRequired;\n }\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write(\"Usage: grimoire search \\\"<query>\\\" -s <source>\\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 process.stderr.write(\"No sources. Pass -s <source> or run `grimoire init`.\\n\");\n return EXIT.apiError;\n }\n const res = await client.search({\n query,\n sources,\n language: args.flags.lang?.[0],\n top_k: args.flags[\"top-k\"] ? Number(args.flags[\"top-k\"][0]) : undefined,\n });\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res.results);\n else printResults(res.results, res.confidence);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n process.stdout.write(JSON.stringify(res.sources ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"versions\": {\n const res = await client.listVersions(args.positionals[0]);\n process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"doc\": {\n const res = await client.getContext(args.positionals[0], Number(args.flags.window?.[0] ?? 2));\n process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n await client.reportResult(args.positionals[0], args.flags.verdict?.[0] ?? \"incorrect\", args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const res = await client.submitSource({\n url: args.positionals[0],\n version: args.flags.version?.[0],\n visibility: args.bools.has(\"private\") ? \"private\" : \"public\",\n webhook_url: args.flags.webhook?.[0],\n });\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 return args.bools.has(\"watch\") ? watchJob(client, args.positionals[0]) : printJob(client, args.positionals[0]);\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(`error: ${err.code}\\n`);\n if (err.status === 401) 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_STATUSES = [\"complete\", \"failed\", \"rejected\"];\nconst FAILED_STATUSES = [\"failed\", \"rejected\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n return FAILED_STATUSES.includes(status) ? 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 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 const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n if (TERMINAL_STATUSES.includes(status)) {\n return FAILED_STATUSES.includes(status) ? 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\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\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/..., /auth/cli/...), so the base must\n// never carry a path prefix or auth-broker URLs would be built wrong.\nexport const DEFAULT_API_BASE = \"https://grimoire-api.monadeo.com\";\nfunction 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}\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const base = { apiBaseUrl: process.env.GRIMOIRE_API_URL ?? DEFAULT_API_BASE };\n if (!existsSync(path))\n return base;\n const overrides = readJsonConfig(path);\n return overrides ? { ...base, ...overrides } : base;\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// 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 { createServer } from \"node:http\";\nimport { Entry } from \"@napi-rs/keyring\";\nimport { fetchWithTimeout } from \"./http.js\";\n// Credential storage in the OS keychain (maintained @napi-rs/keyring \u2014 keytar is\n// archived). A machine token via GRIMOIRE_AUTH_TOKEN overrides interactive auth (CI only).\nconst SERVICE = \"com.monadeo.grimoire\";\nconst ACCOUNT = \"refresh_token\";\nfunction keyring() {\n return new Entry(SERVICE, ACCOUNT);\n}\nexport function storeRefreshToken(token) {\n keyring().setPassword(token);\n}\nexport function readRefreshToken() {\n try {\n return keyring().getPassword() ?? undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearRefreshToken() {\n try {\n keyring().deletePassword();\n }\n catch {\n /* already gone */\n }\n}\nfunction base64url(buf) {\n return buf.toString(\"base64url\");\n}\n// Browser login via the Grimoire auth broker (Firebase is not an OAuth AS): open\n// the hosted page with a PKCE challenge, receive the one-time code on a loopback\n// callback, exchange it for the Firebase refresh token. The random state binds the\n// callback to this login attempt; anything but GET /callback with that state gets\n// a 404 and the server keeps waiting.\nexport async function browserLogin(apiBase, openBrowser) {\n // The broker lives at the bare origin (/auth/cli/*, no /v1 prefix): normalize\n // away trailing slashes so the URLs are always built against the origin.\n const broker = apiBase.replace(/\\/+$/, \"\");\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 const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const received = url.searchParams.get(\"code\");\n if (req.method !== \"GET\" ||\n url.pathname !== \"/callback\" ||\n url.searchParams.get(\"state\") !== state ||\n !received) {\n res.writeHead(404).end();\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\"<p>Login complete \u2014 return to your terminal.</p>\");\n clearTimeout(timer);\n server.close();\n resolve(received);\n });\n server.listen(0, \"127.0.0.1\", () => {\n const port = server.address().port;\n const redirect = `http://127.0.0.1:${port}/callback`;\n openBrowser(`${broker}/auth/cli/start?code_challenge=${challenge}&code_challenge_method=S256&state=${state}&redirect_uri=${encodeURIComponent(redirect)}`);\n });\n const timer = setTimeout(() => {\n server.close();\n reject(new Error(\"Login timed out\"));\n }, 300_000);\n });\n const res = await fetchWithTimeout(`${broker}/auth/cli/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code, code_verifier: verifier }),\n });\n if (!res.ok)\n throw new Error(`Token exchange failed: ${res.status}`);\n const { refresh_token } = (await res.json());\n storeRefreshToken(refresh_token);\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 throw err;\n }\n}\n", "import { readRefreshToken } from \"./auth.js\";\nimport { loadGlobalConfig } from \"./config.js\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\nexport { ApiError } from \"./errors.js\";\nexport class GrimoireClient {\n baseUrl;\n machineToken;\n cachedIdToken;\n refreshInFlight;\n constructor(opts = {}) {\n this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\\/+$/, \"\");\n this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN;\n }\n async bearer() {\n if (this.machineToken)\n return this.machineToken;\n if (this.cachedIdToken && this.cachedIdToken.expiresAt > Date.now() + 60_000) {\n return this.cachedIdToken.token;\n }\n this.refreshInFlight ??= this.refreshIdToken().finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n // Exchange the Firebase refresh token for a fresh ID token (silent refresh).\n async refreshIdToken() {\n const refresh = readRefreshToken();\n if (!refresh)\n throw new ApiError(401, \"not_logged_in\", \"Run `grimoire login`\");\n const res = await fetchWithTimeout(`${this.baseUrl}/auth/cli/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refresh }),\n });\n if (!res.ok)\n throw new ApiError(res.status, \"refresh_failed\", \"Run `grimoire login`\");\n let payload;\n try {\n payload = await res.json();\n }\n catch {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n const { id_token, expires_in } = payload;\n if (typeof id_token !== \"string\" || typeof expires_in !== \"number\") {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n this.cachedIdToken = { token: id_token, expiresAt: Date.now() + expires_in * 1000 };\n return id_token;\n }\n async refreshSession() {\n await this.bearer();\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 ID token means it was revoked server-side:\n // force one refresh and retry exactly once.\n if (res.status === 401 && auth && !this.machineToken) {\n this.cachedIdToken = undefined;\n res = await this.send(path, init, auth);\n }\n return this.parseResponse(res);\n }\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 code = parsed && typeof body === \"object\" && body !== null\n ? (body.error ?? \"error\")\n : \"error\";\n throw new ApiError(res.status, code, parsed ? body : text);\n }\n if (isJson)\n return (parsed ? body : {});\n return text;\n }\n search(input) {\n return this.request(\"/v1/search\", {\n method: \"POST\",\n body: JSON.stringify(input),\n });\n }\n listSources(q) {\n return this.request(`/v1/sources${q ? `?q=${encodeURIComponent(q)}` : \"\"}`);\n }\n listVersions(sourceId) {\n return this.request(`/v1/sources/${encodeURIComponent(sourceId)}/versions`);\n }\n getContext(chunkId, window = 2) {\n return this.request(`/v1/documents/${encodeURIComponent(chunkId)}/context?window=${window}`);\n }\n reportResult(chunkId, verdict, note) {\n return this.request(\"/v1/feedback\", {\n method: \"POST\",\n body: JSON.stringify({ chunk_id: chunkId, verdict, note }),\n });\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}\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([\"json\", \"compact\", \"watch\", \"private\", \"names\"]);\n\nexport function parseArgs(argv: string[], aliases: Record<string, string> = {}): 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 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", "import type { SearchResultChunk } 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\nexport function printResults(results: SearchResultChunk[], confidence: string): void {\n if (confidence === \"weak\") {\n process.stderr.write(\n \"note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\\n\",\n );\n }\n for (const r of results) {\n const path = (r.heading_path ?? []).join(\" \u203A \");\n process.stdout.write(`\\n${r.score.toFixed(3)} ${r.source}@${r.version} ${path}\\n${r.origin_url}\\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(results: SearchResultChunk[]): void {\n for (const r of results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(\" \u203A \")} | ${r.origin_url}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\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\nfunction finish(agent: string, path: string): number {\n process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}\\n`);\n process.stdout.write(\"Run `grimoire login` if you haven't yet.\\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"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n clearRefreshToken,\n readRefreshToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type SourcePin,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, requirePositional, requireFlagOneOf, intFlag, UsageError } from \"./args.js\";\nimport { printResults, printCompact, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\n\nfunction openBrowser(url: string): void {\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.stdout.write(`Open this URL to log in:\\n${url}\\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\nconst HELP = `grimoire \u2014 documentation retrieval for AI agents\n\n grimoire login | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--lang en] [--top-k 8] [--json|--compact]\n grimoire sources [--q <kw>] [--json]\n grimoire versions <source> [--json]\n grimoire doc <chunk_id> [--window 2]\n grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note \"...\"]\n grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire mcp [--http]\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" });\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"login\": {\n await browserLogin(loadGlobalConfig().apiBaseUrl, openBrowser);\n process.stdout.write(\"Logged in.\\n\");\n if (process.platform === \"darwin\") {\n process.stdout.write(\n \"note: macOS may ask to allow keychain access when a tool first uses this session \u2014 choose \\\"Always Allow\\\".\\n\",\n );\n }\n return EXIT.ok;\n }\n case \"logout\":\n clearRefreshToken();\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 \"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 process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n if (process.env.GRIMOIRE_AUTH_TOKEN) {\n process.stdout.write(\"machine token configured (GRIMOIRE_AUTH_TOKEN)\\n\");\n return EXIT.ok;\n }\n if (!readRefreshToken()) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n try {\n await client.refreshSession();\n process.stdout.write(\"logged in (browser session)\\n\");\n return EXIT.ok;\n } catch (err) {\n const reason = err instanceof ApiError ? err.code : (err as Error).message;\n process.stderr.write(`not logged in (${reason}) \u2014 run \\`grimoire login\\`\\n`);\n return EXIT.authRequired;\n }\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write(\"Usage: grimoire search \\\"<query>\\\" -s <source>\\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 process.stderr.write(\"No sources. Pass -s <source> or run `grimoire init`.\\n\");\n return EXIT.apiError;\n }\n const res = await client.search({\n query,\n sources,\n language: args.flags.lang?.[0],\n top_k: intFlag(args, \"top-k\"),\n });\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res.results, res.confidence);\n else printResults(res.results, res.confidence);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n process.stdout.write(JSON.stringify(res.sources ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"versions\": {\n const source = requirePositional(args, 0, \"Usage: grimoire versions <source> [--json]\");\n const res = await client.listVersions(source);\n process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"doc\": {\n const chunkId = requirePositional(args, 0, \"Usage: grimoire doc <chunk_id> [--window 2]\");\n const window = intFlag(args, \"window\", { min: 0, max: 5 }) ?? 2;\n const res = await client.getContext(chunkId, window);\n process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n const usage = 'Usage: grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note \"...\"]';\n const chunkId = requirePositional(args, 0, usage);\n const verdict = requireFlagOneOf(args, \"verdict\", [\"helpful\", \"incorrect\", \"outdated\"], usage);\n await client.reportResult(chunkId, verdict, args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const url = requirePositional(\n args,\n 0,\n \"Usage: grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\",\n );\n const res = await client.submitSource({\n url,\n version: args.flags.version?.[0],\n visibility: args.bools.has(\"private\") ? \"private\" : \"public\",\n webhook_url: args.flags.webhook?.[0],\n });\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 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(`error: ${err.code}\\n`);\n if (err.status === 401) 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_STATUSES = [\"complete\", \"failed\", \"rejected\"];\nconst FAILED_STATUSES = [\"failed\", \"rejected\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n return FAILED_STATUSES.includes(status) ? 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 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 const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n if (TERMINAL_STATUSES.includes(status)) {\n return FAILED_STATUSES.includes(status) ? 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\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\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/..., /auth/cli/...), so the base must\n// never carry a path prefix or auth-broker URLs would be built wrong.\nexport const DEFAULT_API_BASE = \"https://grimoire-api.monadeo.com\";\nfunction 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}\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const base = { apiBaseUrl: process.env.GRIMOIRE_API_URL ?? DEFAULT_API_BASE };\n if (!existsSync(path))\n return base;\n const overrides = readJsonConfig(path);\n return overrides ? { ...base, ...overrides } : base;\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// 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 { createServer } from \"node:http\";\nimport { Entry } from \"@napi-rs/keyring\";\nimport { fetchWithTimeout } from \"./http.js\";\n// Credential storage in the OS keychain (maintained @napi-rs/keyring \u2014 keytar is\n// archived). A machine token via GRIMOIRE_AUTH_TOKEN overrides interactive auth (CI only).\nconst SERVICE = \"com.monadeo.grimoire\";\nconst ACCOUNT = \"refresh_token\";\nfunction keyring() {\n return new Entry(SERVICE, ACCOUNT);\n}\nexport function storeRefreshToken(token) {\n keyring().setPassword(token);\n}\nexport function readRefreshToken() {\n try {\n return keyring().getPassword() ?? undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearRefreshToken() {\n try {\n keyring().deletePassword();\n }\n catch {\n /* already gone */\n }\n}\nfunction base64url(buf) {\n return buf.toString(\"base64url\");\n}\n// Browser login via the Grimoire auth broker (Firebase is not an OAuth AS): open\n// the hosted page with a PKCE challenge, receive the one-time code on a loopback\n// callback, exchange it for the Firebase refresh token. The random state binds the\n// callback to this login attempt; anything but GET /callback with that state gets\n// a 404 and the server keeps waiting.\nexport async function browserLogin(apiBase, openBrowser) {\n // The broker lives at the bare origin (/auth/cli/*, no /v1 prefix): normalize\n // away trailing slashes so the URLs are always built against the origin.\n const broker = apiBase.replace(/\\/+$/, \"\");\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 const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const received = url.searchParams.get(\"code\");\n if (req.method !== \"GET\" ||\n url.pathname !== \"/callback\" ||\n url.searchParams.get(\"state\") !== state ||\n !received) {\n res.writeHead(404).end();\n return;\n }\n // Land the user on the hosted branded page rather than raw loopback text.\n res.writeHead(302, { Location: `${broker}/auth/cli/success` }).end();\n clearTimeout(timer);\n server.close();\n resolve(received);\n });\n server.listen(0, \"127.0.0.1\", () => {\n const port = server.address().port;\n const redirect = `http://127.0.0.1:${port}/callback`;\n openBrowser(`${broker}/auth/cli/start?code_challenge=${challenge}&code_challenge_method=S256&state=${state}&redirect_uri=${encodeURIComponent(redirect)}`);\n });\n const timer = setTimeout(() => {\n server.close();\n reject(new Error(\"Login timed out\"));\n }, 300_000);\n });\n const res = await fetchWithTimeout(`${broker}/auth/cli/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code, code_verifier: verifier }),\n });\n if (!res.ok)\n throw new Error(`Token exchange failed: ${res.status}`);\n const { refresh_token } = (await res.json());\n if (typeof refresh_token !== \"string\" || refresh_token.length === 0) {\n throw new Error(\"Token exchange succeeded but returned no refresh token\");\n }\n storeRefreshToken(refresh_token);\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 { readRefreshToken } from \"./auth.js\";\nimport { loadGlobalConfig } from \"./config.js\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\nexport { ApiError } from \"./errors.js\";\nexport class GrimoireClient {\n baseUrl;\n machineToken;\n cachedIdToken;\n refreshInFlight;\n constructor(opts = {}) {\n this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\\/+$/, \"\");\n this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN;\n }\n async bearer() {\n if (this.machineToken)\n return this.machineToken;\n if (this.cachedIdToken && this.cachedIdToken.expiresAt > Date.now() + 60_000) {\n return this.cachedIdToken.token;\n }\n this.refreshInFlight ??= this.refreshIdToken().finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n // Exchange the Firebase refresh token for a fresh ID token (silent refresh).\n async refreshIdToken() {\n const refresh = readRefreshToken();\n if (!refresh)\n throw new ApiError(401, \"not_logged_in\", \"Run `grimoire login`\");\n const res = await fetchWithTimeout(`${this.baseUrl}/auth/cli/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refresh }),\n });\n if (!res.ok)\n throw new ApiError(res.status, \"refresh_failed\", \"Run `grimoire login`\");\n let payload;\n try {\n payload = await res.json();\n }\n catch {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n const { id_token, expires_in } = payload;\n if (typeof id_token !== \"string\" || typeof expires_in !== \"number\") {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n this.cachedIdToken = { token: id_token, expiresAt: Date.now() + expires_in * 1000 };\n return id_token;\n }\n async refreshSession() {\n await this.bearer();\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 ID token means it was revoked server-side:\n // force one refresh and retry exactly once.\n if (res.status === 401 && auth && !this.machineToken) {\n this.cachedIdToken = undefined;\n res = await this.send(path, init, auth);\n }\n return this.parseResponse(res);\n }\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 code = parsed && typeof body === \"object\" && body !== null\n ? (body.error ?? \"error\")\n : \"error\";\n throw new ApiError(res.status, code, parsed ? body : text);\n }\n if (isJson)\n return (parsed ? body : {});\n return text;\n }\n search(input) {\n return this.request(\"/v1/search\", {\n method: \"POST\",\n body: JSON.stringify(input),\n });\n }\n listSources(q) {\n return this.request(`/v1/sources${q ? `?q=${encodeURIComponent(q)}` : \"\"}`);\n }\n listVersions(sourceId) {\n return this.request(`/v1/sources/${encodeURIComponent(sourceId)}/versions`);\n }\n getContext(chunkId, window = 2) {\n return this.request(`/v1/documents/${encodeURIComponent(chunkId)}/context?window=${window}`);\n }\n reportResult(chunkId, verdict, note) {\n return this.request(\"/v1/feedback\", {\n method: \"POST\",\n body: JSON.stringify({ chunk_id: chunkId, verdict, note }),\n });\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}\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([\"json\", \"compact\", \"watch\", \"private\", \"names\", \"http\"]);\n\nexport function parseArgs(argv: string[], aliases: Record<string, string> = {}): 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 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", "import type { SearchResultChunk } 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\nfunction warnWeak(confidence: string): void {\n if (confidence === \"weak\") {\n process.stderr.write(\n \"note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\\n\",\n );\n }\n}\n\nexport function printResults(results: SearchResultChunk[], confidence: string): void {\n warnWeak(confidence);\n for (const r of results) {\n const path = (r.heading_path ?? []).join(\" \u203A \");\n process.stdout.write(`\\n${r.score.toFixed(3)} ${r.source}@${r.version} ${path}\\n${r.origin_url}\\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\n// The weak-confidence note goes to stderr in compact mode too \u2014 SKILL.md steers\n// agents to --compact, and the \"don't guess\" signal must survive that path.\nexport function printCompact(results: SearchResultChunk[], confidence: string): void {\n warnWeak(confidence);\n for (const r of results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(\" \u203A \")} | ${r.origin_url}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\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\nfunction finish(agent: string, path: string): number {\n process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}\\n`);\n process.stdout.write(\"Run `grimoire login` if you haven't yet.\\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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["openBrowser", "res", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "existsSync", "readFileSync", "writeFileSync", "join"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monadeo.com/grimoire-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^26.1.0",
|
|
17
17
|
"esbuild": "^0.28.1",
|
|
18
|
-
"@monadeo.com/grimoire-core": "0.2.
|
|
18
|
+
"@monadeo.com/grimoire-core": "0.2.1"
|
|
19
19
|
},
|
|
20
20
|
"description": "Grimoire CLI — version-correct documentation retrieval for AI coding agents",
|
|
21
21
|
"homepage": "https://grimoire.monadeo.com",
|