@monadeo.com/grimoire-cli 0.3.6 → 0.3.7
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 +54 -4
- package/dist/index.js.map +2 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -119,6 +119,26 @@ function clearRefreshToken() {
|
|
|
119
119
|
if (existsSync2(credentialsPath()))
|
|
120
120
|
rmSync(credentialsPath());
|
|
121
121
|
}
|
|
122
|
+
function machineTokenPath() {
|
|
123
|
+
return join2(process.env.XDG_CONFIG_HOME ?? join2(homedir2(), ".config"), "grimoire", "machine-token");
|
|
124
|
+
}
|
|
125
|
+
function storeMachineToken(token) {
|
|
126
|
+
const path = machineTokenPath();
|
|
127
|
+
mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
|
|
128
|
+
writeFileSync2(path, token + "\n", { mode: 384 });
|
|
129
|
+
}
|
|
130
|
+
function readMachineToken() {
|
|
131
|
+
try {
|
|
132
|
+
const token = readFileSync2(machineTokenPath(), "utf8").trim();
|
|
133
|
+
return token !== "" ? token : void 0;
|
|
134
|
+
} catch {
|
|
135
|
+
return void 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function clearMachineToken() {
|
|
139
|
+
if (existsSync2(machineTokenPath()))
|
|
140
|
+
rmSync(machineTokenPath());
|
|
141
|
+
}
|
|
122
142
|
function base64url(buf) {
|
|
123
143
|
return buf.toString("base64url");
|
|
124
144
|
}
|
|
@@ -172,7 +192,7 @@ var GrimoireClient = class {
|
|
|
172
192
|
refreshInFlight;
|
|
173
193
|
constructor(opts = {}) {
|
|
174
194
|
this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\/+$/, "");
|
|
175
|
-
this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN;
|
|
195
|
+
this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN ?? readMachineToken();
|
|
176
196
|
}
|
|
177
197
|
async bearer() {
|
|
178
198
|
if (this.machineToken)
|
|
@@ -418,7 +438,7 @@ function setupCodex() {
|
|
|
418
438
|
function hasSession() {
|
|
419
439
|
if (process.env.GRIMOIRE_AUTH_TOKEN) return true;
|
|
420
440
|
try {
|
|
421
|
-
return readRefreshToken() !== void 0;
|
|
441
|
+
return readMachineToken() !== void 0 || readRefreshToken() !== void 0;
|
|
422
442
|
} catch {
|
|
423
443
|
return false;
|
|
424
444
|
}
|
|
@@ -542,7 +562,9 @@ var CONFIG_KEYS = {
|
|
|
542
562
|
parse: (raw) => intInRange("max-response-tokens", raw, 1)
|
|
543
563
|
}
|
|
544
564
|
};
|
|
545
|
-
var
|
|
565
|
+
var AUTH_TOKEN_KEY = "auth-token";
|
|
566
|
+
var MACHINE_TOKEN_RE = /^mt_[0-9a-f]{64}$/;
|
|
567
|
+
var USAGE = "Usage: grimoire config [<key>] [<value>] [--unset] (keys: " + [...Object.keys(CONFIG_KEYS), AUTH_TOKEN_KEY].join(", ") + ")";
|
|
546
568
|
function runConfig(args) {
|
|
547
569
|
const [key, value] = args.positionals;
|
|
548
570
|
if (key === void 0) {
|
|
@@ -554,6 +576,30 @@ function runConfig(args) {
|
|
|
554
576
|
process.stdout.write(`${name} = ${current === void 0 ? "(unset)" : JSON.stringify(current)} # ${spec2.describe}
|
|
555
577
|
`);
|
|
556
578
|
}
|
|
579
|
+
process.stdout.write(
|
|
580
|
+
`${AUTH_TOKEN_KEY} = ${readMachineToken() ? "(set)" : "(unset)"} # machine token, stored 0600 (env GRIMOIRE_AUTH_TOKEN overrides)
|
|
581
|
+
`
|
|
582
|
+
);
|
|
583
|
+
return EXIT.ok;
|
|
584
|
+
}
|
|
585
|
+
if (key === AUTH_TOKEN_KEY) {
|
|
586
|
+
if (args.bools.has("unset")) {
|
|
587
|
+
clearMachineToken();
|
|
588
|
+
process.stdout.write(`${AUTH_TOKEN_KEY} unset
|
|
589
|
+
`);
|
|
590
|
+
return EXIT.ok;
|
|
591
|
+
}
|
|
592
|
+
if (value === void 0) {
|
|
593
|
+
process.stdout.write(`${readMachineToken() ? "(set)" : "(unset)"}
|
|
594
|
+
`);
|
|
595
|
+
return EXIT.ok;
|
|
596
|
+
}
|
|
597
|
+
if (!MACHINE_TOKEN_RE.test(value)) {
|
|
598
|
+
throw new UsageError("auth-token must be a machine token, e.g. mt_<64 hex chars>");
|
|
599
|
+
}
|
|
600
|
+
storeMachineToken(value);
|
|
601
|
+
process.stdout.write(`${AUTH_TOKEN_KEY} set
|
|
602
|
+
`);
|
|
557
603
|
return EXIT.ok;
|
|
558
604
|
}
|
|
559
605
|
const spec = CONFIG_KEYS[key];
|
|
@@ -694,7 +740,7 @@ function parseSourceFlags(values) {
|
|
|
694
740
|
return version ? { source, version } : { source };
|
|
695
741
|
});
|
|
696
742
|
}
|
|
697
|
-
var VERSION = true ? "0.3.
|
|
743
|
+
var VERSION = true ? "0.3.7" : "dev";
|
|
698
744
|
var HELP = `grimoire ${VERSION} \u2014 documentation retrieval for AI agents
|
|
699
745
|
|
|
700
746
|
grimoire login | logout | whoami
|
|
@@ -785,6 +831,10 @@ async function main(argv) {
|
|
|
785
831
|
process.stdout.write("machine token configured (GRIMOIRE_AUTH_TOKEN)\n");
|
|
786
832
|
return EXIT.ok;
|
|
787
833
|
}
|
|
834
|
+
if (readMachineToken()) {
|
|
835
|
+
process.stdout.write("machine token configured (grimoire config auth-token)\n");
|
|
836
|
+
return EXIT.ok;
|
|
837
|
+
}
|
|
788
838
|
if (!readRefreshToken()) {
|
|
789
839
|
process.stderr.write("not logged in \u2014 run `grimoire login`\n");
|
|
790
840
|
return EXIT.authRequired;
|
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", "../src/commands/config.ts", "../src/commands/update.ts", "../src/updatecheck.ts"],
|
|
4
|
-
"sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\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\";\nimport { runConfig } from \"./commands/config.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { notifyIfOutdated, refreshUpdateState } from \"./updatecheck.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\n// Injected by esbuild from package.json at build time (\"dev\" when running\n// unbundled source, e.g. under vitest).\ndeclare const __GRIMOIRE_VERSION__: string | undefined;\nconst VERSION = typeof __GRIMOIRE_VERSION__ === \"string\" ? __GRIMOIRE_VERSION__ : \"dev\";\n\nconst HELP = `grimoire ${VERSION} \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>] [--names|--json]\n grimoire versions <source> [--json]\n grimoire config [<key>] [<value>] [--unset]\n grimoire update\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 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, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\n// Canonical flag names each command accepts; parseArgs rejects anything else.\n// Commands absent from this map skip validation and fall through to the\n// unknown-command error.\nconst COMMAND_FLAGS: Record<string, readonly string[]> = {\n version: [], \"--version\": [], \"-v\": [],\n login: [], logout: [], setup: [], init: [], whoami: [],\n help: [], \"--help\": [], \"-h\": [],\n mcp: [\"http\"],\n config: [\"unset\"],\n update: [],\n search: [\"source\", \"lang\", \"top-k\", \"json\", \"compact\"],\n sources: [\"q\", \"names\", \"json\"],\n versions: [\"json\"],\n doc: [\"window\"],\n report: [\"verdict\", \"note\"],\n ingest: [\"version\", \"private\", \"webhook\", \"watch\"],\n jobs: [\"watch\"],\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 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 \"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 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 // `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 <source>[@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 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, res.rerank_status);\n else printResults(res.results, res.confidence, res.rerank_status);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n const sources = res.sources ?? [];\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.source_id}\\n`);\n } else {\n for (const s of sources) {\n // The precise product version is the identity users care about;\n // crawl-date ids are the fallback when no version is known.\n const latest = s.latest_semver ?? s.latest_version ?? \"-\";\n const vis = s.visibility === \"private\" ? \" (private)\" : \"\";\n const meta = [\n s.latest_chunks != null ? `${s.latest_chunks} chunks` : \"\",\n s.latest_pages != null ? `${s.latest_pages} pages` : \"\",\n s.latest_crawled_at ? `crawled ${s.latest_crawled_at.slice(0, 10)}` : \"\",\n ]\n .filter(Boolean)\n .join(\" \u00B7 \");\n process.stdout.write(\n [`${s.source_id}@${latest}${vis}`, meta, s.origin_url ?? \"\"].filter(Boolean).join(\" \") + \"\\n\",\n );\n }\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 const versions = res.versions ?? [];\n if (json) {\n process.stdout.write(JSON.stringify(versions, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n const available = versions.filter((v) => v.status === \"active\");\n if (available.length === 0) {\n process.stdout.write(`no active versions for ${source}\\n`);\n return EXIT.ok;\n }\n for (const v of available) {\n const label = v.semver ?? v.version_id;\n const parts = [\n label,\n v.is_latest ? \"latest\" : \"\",\n `${v.chunk_count ?? 0} chunks`,\n `crawled ${(v.ingested_at ?? \"\").slice(0, 10)}`,\n v.semver ? `(${v.version_id})` : \"\",\n ].filter(Boolean);\n process.stdout.write(parts.join(\" \") + \"\\n\");\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 // The API explains itself (message, available versions, suggestions) \u2014\n // swallowing that detail leaves agents retrying blind.\n const body = (typeof err.body === \"object\" && err.body !== null ? err.body : {}) as {\n message?: string;\n available?: string[];\n did_you_mean?: string[];\n };\n process.stderr.write(`error: ${err.code}${body.message ? ` \u2014 ${body.message}` : \"\"}\\n`);\n if (body.available?.length) process.stderr.write(`available: ${body.available.join(\", \")}\\n`);\n if (body.did_you_mean?.length) process.stderr.write(`did you mean: ${body.did_you_mean.join(\", \")}\\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\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/..., /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\";\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 { 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 credentialsPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"credentials.json\");\n}\nexport function storeRefreshToken(token) {\n const path = credentialsPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, JSON.stringify({ refresh_token: token }) + \"\\n\", { mode: 0o600 });\n}\nexport function readRefreshToken() {\n try {\n const parsed = JSON.parse(readFileSync(credentialsPath(), \"utf8\"));\n return typeof parsed.refresh_token === \"string\" && parsed.refresh_token !== \"\"\n ? parsed.refresh_token\n : undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearRefreshToken() {\n if (existsSync(credentialsPath()))\n rmSync(credentialsPath());\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\", \"unset\"]);\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", "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\n// First line of every search: whether the cross-encoder actually ordered these\n// results. \"degraded\" means fused order was served because the reranker was\n// unavailable \u2014 scores are not comparable to reranked runs (Astro 2026-07-18).\nfunction noteRerank(status: string | undefined): void {\n if (status === undefined) return;\n const label =\n status === \"used\" ? \"reranker: used\" : status === \"degraded\" ? \"reranker: degraded (fused order)\" : \"reranker: disabled\";\n process.stderr.write(`${label}\\n`);\n}\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, rerankStatus?: string): void {\n noteRerank(rerankStatus);\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, rerankStatus?: string): void {\n noteRerank(rerankStatus);\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\";\nimport { readRefreshToken } 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 readRefreshToken() !== 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 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://grimoire-api.monadeo.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 language: {\n prop: \"defaultLanguage\",\n describe: \"default search language filter\",\n parse: (raw) => {\n if (!raw) throw new UsageError(\"language must be non-empty\");\n return raw;\n },\n },\n \"max-response-tokens\": {\n prop: \"maxResponseTokens\",\n describe: \"search response token budget\",\n parse: (raw) => intInRange(\"max-response-tokens\", raw, 1),\n },\n};\n\nconst USAGE = \"Usage: grimoire config [<key>] [<value>] [--unset] (keys: \" + Object.keys(CONFIG_KEYS).join(\", \") + \")\";\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 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 { 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 } from \"node:fs\";\nimport { join } from \"node:path\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n clearRefreshToken,\n readRefreshToken,\n readMachineToken,\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\";\nimport { runConfig } from \"./commands/config.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { notifyIfOutdated, refreshUpdateState } from \"./updatecheck.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\n// Injected by esbuild from package.json at build time (\"dev\" when running\n// unbundled source, e.g. under vitest).\ndeclare const __GRIMOIRE_VERSION__: string | undefined;\nconst VERSION = typeof __GRIMOIRE_VERSION__ === \"string\" ? __GRIMOIRE_VERSION__ : \"dev\";\n\nconst HELP = `grimoire ${VERSION} \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>] [--names|--json]\n grimoire versions <source> [--json]\n grimoire config [<key>] [<value>] [--unset]\n grimoire update\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 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, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\n// Canonical flag names each command accepts; parseArgs rejects anything else.\n// Commands absent from this map skip validation and fall through to the\n// unknown-command error.\nconst COMMAND_FLAGS: Record<string, readonly string[]> = {\n version: [], \"--version\": [], \"-v\": [],\n login: [], logout: [], setup: [], init: [], whoami: [],\n help: [], \"--help\": [], \"-h\": [],\n mcp: [\"http\"],\n config: [\"unset\"],\n update: [],\n search: [\"source\", \"lang\", \"top-k\", \"json\", \"compact\"],\n sources: [\"q\", \"names\", \"json\"],\n versions: [\"json\"],\n doc: [\"window\"],\n report: [\"verdict\", \"note\"],\n ingest: [\"version\", \"private\", \"webhook\", \"watch\"],\n jobs: [\"watch\"],\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 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 \"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 if (process.env.GRIMOIRE_AUTH_TOKEN) {\n process.stdout.write(\"machine token configured (GRIMOIRE_AUTH_TOKEN)\\n\");\n return EXIT.ok;\n }\n if (readMachineToken()) {\n process.stdout.write(\"machine token configured (grimoire config 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 // `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 <source>[@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 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, res.rerank_status);\n else printResults(res.results, res.confidence, res.rerank_status);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n const sources = res.sources ?? [];\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.source_id}\\n`);\n } else {\n for (const s of sources) {\n // The precise product version is the identity users care about;\n // crawl-date ids are the fallback when no version is known.\n const latest = s.latest_semver ?? s.latest_version ?? \"-\";\n const vis = s.visibility === \"private\" ? \" (private)\" : \"\";\n const meta = [\n s.latest_chunks != null ? `${s.latest_chunks} chunks` : \"\",\n s.latest_pages != null ? `${s.latest_pages} pages` : \"\",\n s.latest_crawled_at ? `crawled ${s.latest_crawled_at.slice(0, 10)}` : \"\",\n ]\n .filter(Boolean)\n .join(\" \u00B7 \");\n process.stdout.write(\n [`${s.source_id}@${latest}${vis}`, meta, s.origin_url ?? \"\"].filter(Boolean).join(\" \") + \"\\n\",\n );\n }\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 const versions = res.versions ?? [];\n if (json) {\n process.stdout.write(JSON.stringify(versions, null, 2) + \"\\n\");\n return EXIT.ok;\n }\n const available = versions.filter((v) => v.status === \"active\");\n if (available.length === 0) {\n process.stdout.write(`no active versions for ${source}\\n`);\n return EXIT.ok;\n }\n for (const v of available) {\n const label = v.semver ?? v.version_id;\n const parts = [\n label,\n v.is_latest ? \"latest\" : \"\",\n `${v.chunk_count ?? 0} chunks`,\n `crawled ${(v.ingested_at ?? \"\").slice(0, 10)}`,\n v.semver ? `(${v.version_id})` : \"\",\n ].filter(Boolean);\n process.stdout.write(parts.join(\" \") + \"\\n\");\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 // The API explains itself (message, available versions, suggestions) \u2014\n // swallowing that detail leaves agents retrying blind.\n const body = (typeof err.body === \"object\" && err.body !== null ? err.body : {}) as {\n message?: string;\n available?: string[];\n did_you_mean?: string[];\n };\n process.stderr.write(`error: ${err.code}${body.message ? ` \u2014 ${body.message}` : \"\"}\\n`);\n if (body.available?.length) process.stderr.write(`available: ${body.available.join(\", \")}\\n`);\n if (body.did_you_mean?.length) process.stderr.write(`did you mean: ${body.did_you_mean.join(\", \")}\\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\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/..., /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\";\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 { 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 credentialsPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"credentials.json\");\n}\nexport function storeRefreshToken(token) {\n const path = credentialsPath();\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n writeFileSync(path, JSON.stringify({ refresh_token: token }) + \"\\n\", { mode: 0o600 });\n}\nexport function readRefreshToken() {\n try {\n const parsed = JSON.parse(readFileSync(credentialsPath(), \"utf8\"));\n return typeof parsed.refresh_token === \"string\" && parsed.refresh_token !== \"\"\n ? parsed.refresh_token\n : undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearRefreshToken() {\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(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"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}\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 { readMachineToken, 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 ?? readMachineToken();\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\", \"unset\"]);\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", "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\n// First line of every search: whether the cross-encoder actually ordered these\n// results. \"degraded\" means fused order was served because the reranker was\n// unavailable \u2014 scores are not comparable to reranked runs (Astro 2026-07-18).\nfunction noteRerank(status: string | undefined): void {\n if (status === undefined) return;\n const label =\n status === \"used\" ? \"reranker: used\" : status === \"degraded\" ? \"reranker: degraded (fused order)\" : \"reranker: disabled\";\n process.stderr.write(`${label}\\n`);\n}\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, rerankStatus?: string): void {\n noteRerank(rerankStatus);\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, rerankStatus?: string): void {\n noteRerank(rerankStatus);\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\";\nimport { readMachineToken, readRefreshToken } 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 || readRefreshToken() !== 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://grimoire-api.monadeo.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 language: {\n prop: \"defaultLanguage\",\n describe: \"default search language filter\",\n parse: (raw) => {\n if (!raw) throw new UsageError(\"language must be non-empty\");\n return raw;\n },\n },\n \"max-response-tokens\": {\n prop: \"maxResponseTokens\",\n describe: \"search response token budget\",\n parse: (raw) => intInRange(\"max-response-tokens\", raw, 1),\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_[0-9a-f]{64}$/;\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, e.g. mt_<64 hex chars>\");\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 { 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", "join", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "join", "homedir", "mkdirSync", "dirname", "writeFileSync", "readFileSync", "existsSync", "openBrowser", "res", "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"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monadeo.com/grimoire-cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.7",
|
|
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.3.
|
|
15
|
+
"@monadeo.com/grimoire-core": "0.3.7"
|
|
16
16
|
},
|
|
17
17
|
"description": "Grimoire CLI — version-correct documentation retrieval for AI coding agents",
|
|
18
18
|
"homepage": "https://grimoire.monadeo.com",
|