@monadeo.com/grimoire-cli 0.2.0 → 0.2.2

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 CHANGED
@@ -50,8 +50,10 @@ function resolveDefaultSources() {
50
50
 
51
51
  // ../core/dist/auth.js
52
52
  import { createHash, randomBytes } from "node:crypto";
53
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
53
54
  import { createServer } from "node:http";
54
- import { Entry } from "@napi-rs/keyring";
55
+ import { homedir as homedir2 } from "node:os";
56
+ import { dirname as dirname2, join as join2 } from "node:path";
55
57
 
56
58
  // ../core/dist/errors.js
57
59
  var ApiError = class extends Error {
@@ -75,31 +77,32 @@ async function fetchWithTimeout(url, init = {}) {
75
77
  if (err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError")) {
76
78
  throw new ApiError(408, "timeout", `Request timed out after ${REQUEST_TIMEOUT_MS / 1e3}s`);
77
79
  }
78
- throw err;
80
+ const message = err instanceof Error ? err.message : String(err);
81
+ const cause = err instanceof Error && err.cause instanceof Error ? `: ${err.cause.message}` : "";
82
+ throw new ApiError(0, "network_error", `${message}${cause}`);
79
83
  }
80
84
  }
81
85
 
82
86
  // ../core/dist/auth.js
83
- var SERVICE = "com.monadeo.grimoire";
84
- var ACCOUNT = "refresh_token";
85
- function keyring() {
86
- return new Entry(SERVICE, ACCOUNT);
87
+ function credentialsPath() {
88
+ return join2(process.env.XDG_CONFIG_HOME ?? join2(homedir2(), ".config"), "grimoire", "credentials.json");
87
89
  }
88
90
  function storeRefreshToken(token) {
89
- keyring().setPassword(token);
91
+ const path = credentialsPath();
92
+ mkdirSync2(dirname2(path), { recursive: true, mode: 448 });
93
+ writeFileSync2(path, JSON.stringify({ refresh_token: token }) + "\n", { mode: 384 });
90
94
  }
91
95
  function readRefreshToken() {
92
96
  try {
93
- return keyring().getPassword() ?? void 0;
97
+ const parsed = JSON.parse(readFileSync2(credentialsPath(), "utf8"));
98
+ return typeof parsed.refresh_token === "string" && parsed.refresh_token !== "" ? parsed.refresh_token : void 0;
94
99
  } catch {
95
100
  return void 0;
96
101
  }
97
102
  }
98
103
  function clearRefreshToken() {
99
- try {
100
- keyring().deletePassword();
101
- } catch {
102
- }
104
+ if (existsSync2(credentialsPath()))
105
+ rmSync(credentialsPath());
103
106
  }
104
107
  function base64url(buf) {
105
108
  return buf.toString("base64url");
@@ -117,8 +120,7 @@ async function browserLogin(apiBase, openBrowser2) {
117
120
  res2.writeHead(404).end();
118
121
  return;
119
122
  }
120
- res2.writeHead(200, { "Content-Type": "text/html" });
121
- res2.end("<p>Login complete \u2014 return to your terminal.</p>");
123
+ res2.writeHead(302, { Location: `${broker}/auth/cli/success` }).end();
122
124
  clearTimeout(timer);
123
125
  server.close();
124
126
  resolve(received);
@@ -141,6 +143,9 @@ async function browserLogin(apiBase, openBrowser2) {
141
143
  if (!res.ok)
142
144
  throw new Error(`Token exchange failed: ${res.status}`);
143
145
  const { refresh_token } = await res.json();
146
+ if (typeof refresh_token !== "string" || refresh_token.length === 0) {
147
+ throw new Error("Token exchange succeeded but returned no refresh token");
148
+ }
144
149
  storeRefreshToken(refresh_token);
145
150
  }
146
151
 
@@ -263,7 +268,7 @@ var GrimoireClient = class {
263
268
  // src/args.ts
264
269
  var UsageError = class extends Error {
265
270
  };
266
- var BOOL_FLAGS = /* @__PURE__ */ new Set(["json", "compact", "watch", "private", "names"]);
271
+ var BOOL_FLAGS = /* @__PURE__ */ new Set(["json", "compact", "watch", "private", "names", "http"]);
267
272
  function parseArgs(argv, aliases = {}) {
268
273
  const positionals = [];
269
274
  const flags = {};
@@ -288,15 +293,38 @@ function parseArgs(argv, aliases = {}) {
288
293
  }
289
294
  return { positionals, flags, bools };
290
295
  }
296
+ function requirePositional(parsed, index, usage) {
297
+ const value = parsed.positionals[index];
298
+ if (value === void 0) throw new UsageError(usage);
299
+ return value;
300
+ }
301
+ function intFlag(parsed, name, range) {
302
+ const raw = parsed.flags[name]?.[0];
303
+ if (raw === void 0) return void 0;
304
+ const value = Number(raw);
305
+ if (!Number.isInteger(value)) throw new UsageError(`Flag --${name} must be an integer`);
306
+ if (range && (value < range.min || value > range.max)) {
307
+ throw new UsageError(`Flag --${name} must be between ${range.min} and ${range.max}`);
308
+ }
309
+ return value;
310
+ }
311
+ function requireFlagOneOf(parsed, name, allowed, usage) {
312
+ const raw = parsed.flags[name]?.[0];
313
+ if (raw === void 0 || !allowed.includes(raw)) throw new UsageError(usage);
314
+ return raw;
315
+ }
291
316
 
292
317
  // src/output.ts
293
318
  var EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 };
294
- function printResults(results, confidence) {
319
+ function warnWeak(confidence) {
295
320
  if (confidence === "weak") {
296
321
  process.stderr.write(
297
322
  "note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\n"
298
323
  );
299
324
  }
325
+ }
326
+ function printResults(results, confidence) {
327
+ warnWeak(confidence);
300
328
  for (const r of results) {
301
329
  const path = (r.heading_path ?? []).join(" \u203A ");
302
330
  process.stdout.write(`
@@ -308,7 +336,8 @@ ${r.origin_url}
308
336
  `);
309
337
  }
310
338
  }
311
- function printCompact(results) {
339
+ function printCompact(results, confidence) {
340
+ warnWeak(confidence);
312
341
  for (const r of results) {
313
342
  process.stdout.write(
314
343
  `${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(" \u203A ")} | ${r.origin_url}
@@ -318,9 +347,9 @@ function printCompact(results) {
318
347
  }
319
348
 
320
349
  // src/commands/setup.ts
321
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
322
- import { homedir as homedir2 } from "node:os";
323
- import { dirname as dirname2, join as join2 } from "node:path";
350
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
351
+ import { homedir as homedir3 } from "node:os";
352
+ import { dirname as dirname3, join as join3 } from "node:path";
324
353
  var MCP_ENTRY = { command: "npx", args: ["-y", "@monadeo.com/grimoire-mcp"] };
325
354
  var CODEX_TABLE = `[mcp_servers.grimoire]
326
355
  command = "npx"
@@ -345,25 +374,33 @@ function mcpServersMerge(key) {
345
374
  };
346
375
  }
347
376
  var JSON_AGENTS = {
348
- "claude-code": { path: join2(homedir2(), ".claude.json"), apply: mcpServersMerge("mcpServers") },
349
- cursor: { path: join2(homedir2(), ".cursor", "mcp.json"), apply: mcpServersMerge("mcpServers") },
377
+ "claude-code": { path: join3(homedir3(), ".claude.json"), apply: mcpServersMerge("mcpServers") },
378
+ cursor: { path: join3(homedir3(), ".cursor", "mcp.json"), apply: mcpServersMerge("mcpServers") },
350
379
  windsurf: {
351
- path: join2(homedir2(), ".codeium", "windsurf", "mcp_config.json"),
380
+ path: join3(homedir3(), ".codeium", "windsurf", "mcp_config.json"),
352
381
  apply: mcpServersMerge("mcpServers")
353
382
  }
354
383
  };
355
384
  var AGENT_NAMES = [...Object.keys(JSON_AGENTS), "codex"];
356
385
  function setupCodex() {
357
- const path = join2(homedir2(), ".codex", "config.toml");
358
- const existing = existsSync2(path) ? readFileSync2(path, "utf8") : "";
359
- mkdirSync2(dirname2(path), { recursive: true });
360
- writeFileSync2(path, mergeCodexToml(existing));
386
+ const path = join3(homedir3(), ".codex", "config.toml");
387
+ const existing = existsSync3(path) ? readFileSync3(path, "utf8") : "";
388
+ mkdirSync3(dirname3(path), { recursive: true });
389
+ writeFileSync3(path, mergeCodexToml(existing));
361
390
  return finish("codex", path);
362
391
  }
392
+ function hasSession() {
393
+ if (process.env.GRIMOIRE_AUTH_TOKEN) return true;
394
+ try {
395
+ return readRefreshToken() !== void 0;
396
+ } catch {
397
+ return false;
398
+ }
399
+ }
363
400
  function finish(agent, path) {
364
401
  process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}
365
402
  `);
366
- process.stdout.write("Run `grimoire login` if you haven't yet.\n");
403
+ process.stdout.write(hasSession() ? "Already logged in.\n" : "Run `grimoire login` to authenticate.\n");
367
404
  return 0;
368
405
  }
369
406
  function runSetup(agent) {
@@ -375,9 +412,9 @@ function runSetup(agent) {
375
412
  if (agent === "codex") return setupCodex();
376
413
  const target = JSON_AGENTS[agent];
377
414
  let existing = {};
378
- if (existsSync2(target.path)) {
415
+ if (existsSync3(target.path)) {
379
416
  try {
380
- existing = JSON.parse(readFileSync2(target.path, "utf8"));
417
+ existing = JSON.parse(readFileSync3(target.path, "utf8"));
381
418
  } catch (err) {
382
419
  process.stderr.write(
383
420
  `Cannot parse ${target.path}: ${err.message}
@@ -387,34 +424,34 @@ Fix or remove the file, then re-run setup.
387
424
  return 1;
388
425
  }
389
426
  }
390
- mkdirSync2(dirname2(target.path), { recursive: true });
391
- writeFileSync2(target.path, JSON.stringify(target.apply(existing), null, 2));
427
+ mkdirSync3(dirname3(target.path), { recursive: true });
428
+ writeFileSync3(target.path, JSON.stringify(target.apply(existing), null, 2));
392
429
  return finish(agent, target.path);
393
430
  }
394
431
 
395
432
  // src/commands/init.ts
396
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
397
- import { join as join3 } from "node:path";
433
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "node:fs";
434
+ import { join as join4 } from "node:path";
398
435
  function parseJsonFile(path) {
399
436
  try {
400
- return JSON.parse(readFileSync3(path, "utf8"));
437
+ return JSON.parse(readFileSync4(path, "utf8"));
401
438
  } catch (err) {
402
439
  throw new Error(`Cannot parse ${path}: ${err.message}`, { cause: err });
403
440
  }
404
441
  }
405
442
  function detectManifestSources(dir = process.cwd()) {
406
443
  const pins = [];
407
- const pkgPath = join3(dir, "package.json");
408
- if (existsSync3(pkgPath)) {
444
+ const pkgPath = join4(dir, "package.json");
445
+ if (existsSync4(pkgPath)) {
409
446
  const pkg = parseJsonFile(pkgPath);
410
447
  for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {
411
448
  const major = range.match(/(\d+)/)?.[1];
412
449
  pins.push({ source: name.replace(/^@[^/]+\//, ""), ...major ? { version: major } : {} });
413
450
  }
414
451
  }
415
- const reqPath = join3(dir, "requirements.txt");
416
- if (existsSync3(reqPath)) {
417
- for (const line of readFileSync3(reqPath, "utf8").split("\n")) {
452
+ const reqPath = join4(dir, "requirements.txt");
453
+ if (existsSync4(reqPath)) {
454
+ for (const line of readFileSync4(reqPath, "utf8").split("\n")) {
418
455
  const m = line.match(/^([A-Za-z0-9_.-]+)\s*==\s*(\d+)/);
419
456
  if (m) pins.push({ source: m[1].toLowerCase(), version: m[2] });
420
457
  }
@@ -422,15 +459,15 @@ function detectManifestSources(dir = process.cwd()) {
422
459
  return pins;
423
460
  }
424
461
  function runInit() {
425
- const path = join3(process.cwd(), ".grimoire.json");
462
+ const path = join4(process.cwd(), ".grimoire.json");
426
463
  try {
427
464
  const sources = detectManifestSources();
428
465
  if (sources.length === 0) {
429
466
  process.stderr.write("No package.json/requirements.txt dependencies found.\n");
430
467
  return 1;
431
468
  }
432
- const existing = existsSync3(path) ? parseJsonFile(path) : {};
433
- writeFileSync3(path, JSON.stringify({ ...existing, sources }, null, 2));
469
+ const existing = existsSync4(path) ? parseJsonFile(path) : {};
470
+ writeFileSync4(path, JSON.stringify({ ...existing, sources }, null, 2));
434
471
  process.stdout.write(`Wrote ${sources.length} source pins to .grimoire.json
435
472
  `);
436
473
  return 0;
@@ -467,7 +504,7 @@ var HELP = `grimoire \u2014 documentation retrieval for AI agents
467
504
  grimoire sources [--q <kw>] [--json]
468
505
  grimoire versions <source> [--json]
469
506
  grimoire doc <chunk_id> [--window 2]
470
- grimoire report <chunk_id> --verdict incorrect|outdated|helpful [--note "..."]
507
+ grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note "..."]
471
508
  grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]
472
509
  grimoire jobs <job_id> [--watch]
473
510
  grimoire mcp [--http]
@@ -541,10 +578,10 @@ async function main(argv) {
541
578
  query,
542
579
  sources,
543
580
  language: args.flags.lang?.[0],
544
- top_k: args.flags["top-k"] ? Number(args.flags["top-k"][0]) : void 0
581
+ top_k: intFlag(args, "top-k")
545
582
  });
546
583
  if (json) process.stdout.write(JSON.stringify(res, null, 2) + "\n");
547
- else if (args.bools.has("compact")) printCompact(res.results);
584
+ else if (args.bools.has("compact")) printCompact(res.results, res.confidence);
548
585
  else printResults(res.results, res.confidence);
549
586
  return EXIT.ok;
550
587
  }
@@ -554,23 +591,34 @@ async function main(argv) {
554
591
  return EXIT.ok;
555
592
  }
556
593
  case "versions": {
557
- const res = await client.listVersions(args.positionals[0]);
594
+ const source = requirePositional(args, 0, "Usage: grimoire versions <source> [--json]");
595
+ const res = await client.listVersions(source);
558
596
  process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + "\n");
559
597
  return EXIT.ok;
560
598
  }
561
599
  case "doc": {
562
- const res = await client.getContext(args.positionals[0], Number(args.flags.window?.[0] ?? 2));
600
+ const chunkId = requirePositional(args, 0, "Usage: grimoire doc <chunk_id> [--window 2]");
601
+ const window = intFlag(args, "window", { min: 0, max: 5 }) ?? 2;
602
+ const res = await client.getContext(chunkId, window);
563
603
  process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + "\n");
564
604
  return EXIT.ok;
565
605
  }
566
606
  case "report": {
567
- await client.reportResult(args.positionals[0], args.flags.verdict?.[0] ?? "incorrect", args.flags.note?.[0]);
607
+ const usage = 'Usage: grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note "..."]';
608
+ const chunkId = requirePositional(args, 0, usage);
609
+ const verdict = requireFlagOneOf(args, "verdict", ["helpful", "incorrect", "outdated"], usage);
610
+ await client.reportResult(chunkId, verdict, args.flags.note?.[0]);
568
611
  process.stdout.write("Reported.\n");
569
612
  return EXIT.ok;
570
613
  }
571
614
  case "ingest": {
615
+ const url = requirePositional(
616
+ args,
617
+ 0,
618
+ "Usage: grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]"
619
+ );
572
620
  const res = await client.submitSource({
573
- url: args.positionals[0],
621
+ url,
574
622
  version: args.flags.version?.[0],
575
623
  visibility: args.bools.has("private") ? "private" : "public",
576
624
  webhook_url: args.flags.webhook?.[0]
@@ -580,8 +628,10 @@ async function main(argv) {
580
628
  if (args.bools.has("watch")) return watchJob(client, res.job_id);
581
629
  return EXIT.ok;
582
630
  }
583
- case "jobs":
584
- return args.bools.has("watch") ? watchJob(client, args.positionals[0]) : printJob(client, args.positionals[0]);
631
+ case "jobs": {
632
+ const jobId = requirePositional(args, 0, "Usage: grimoire jobs <job_id> [--watch]");
633
+ return args.bools.has("watch") ? watchJob(client, jobId) : printJob(client, jobId);
634
+ }
585
635
  default:
586
636
  process.stderr.write(`Unknown command: ${command}
587
637
  ${HELP}`);
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../../core/dist/config.js", "../../core/dist/auth.js", "../../core/dist/errors.js", "../../core/dist/http.js", "../../core/dist/client.js", "../src/args.ts", "../src/output.ts", "../src/commands/setup.ts", "../src/commands/init.ts"],
4
- "sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n clearRefreshToken,\n readRefreshToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type SourcePin,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, UsageError } from \"./args.js\";\nimport { printResults, printCompact, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\n\nfunction openBrowser(url: string): void {\n const cmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n try {\n execFileSync(cmd, [url], { stdio: \"ignore\" });\n } catch {\n process.stdout.write(`Open this URL to log in:\\n${url}\\n`);\n }\n}\n\nfunction parseSourceFlags(values: string[] | undefined): SourcePin[] {\n return (values ?? []).map((v) => {\n const [source, version] = v.split(\"@\");\n return version ? { source, version } : { source };\n });\n}\n\nconst HELP = `grimoire \u2014 documentation retrieval for AI agents\n\n grimoire login | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--lang en] [--top-k 8] [--json|--compact]\n grimoire sources [--q <kw>] [--json]\n grimoire versions <source> [--json]\n grimoire doc <chunk_id> [--window 2]\n grimoire report <chunk_id> --verdict incorrect|outdated|helpful [--note \"...\"]\n grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire mcp [--http]\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" });\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"login\": {\n await browserLogin(loadGlobalConfig().apiBaseUrl, openBrowser);\n process.stdout.write(\"Logged in.\\n\");\n return EXIT.ok;\n }\n case \"logout\":\n clearRefreshToken();\n process.stdout.write(\"Logged out.\\n\");\n return EXIT.ok;\n case \"setup\":\n return runSetup(args.positionals[0]);\n case \"init\":\n return runInit();\n case \"mcp\":\n process.stderr.write(\"Run the MCP server with: npx @monadeo.com/grimoire-mcp\" + (args.bools.has(\"http\") ? \" --http\\n\" : \"\\n\"));\n return EXIT.ok;\n case undefined:\n case \"help\":\n case \"--help\":\n process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n if (process.env.GRIMOIRE_AUTH_TOKEN) {\n process.stdout.write(\"machine token configured (GRIMOIRE_AUTH_TOKEN)\\n\");\n return EXIT.ok;\n }\n if (!readRefreshToken()) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n try {\n await client.refreshSession();\n process.stdout.write(\"logged in (browser session)\\n\");\n return EXIT.ok;\n } catch (err) {\n const reason = err instanceof ApiError ? err.code : (err as Error).message;\n process.stderr.write(`not logged in (${reason}) \u2014 run \\`grimoire login\\`\\n`);\n return EXIT.authRequired;\n }\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write(\"Usage: grimoire search \\\"<query>\\\" -s <source>\\n\");\n return EXIT.apiError;\n }\n const explicit = parseSourceFlags(args.flags.source);\n const sources = explicit.length > 0 ? explicit : resolveDefaultSources();\n if (sources.length === 0) {\n process.stderr.write(\"No sources. Pass -s <source> or run `grimoire init`.\\n\");\n return EXIT.apiError;\n }\n const res = await client.search({\n query,\n sources,\n language: args.flags.lang?.[0],\n top_k: args.flags[\"top-k\"] ? Number(args.flags[\"top-k\"][0]) : undefined,\n });\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res.results);\n else printResults(res.results, res.confidence);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n process.stdout.write(JSON.stringify(res.sources ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"versions\": {\n const res = await client.listVersions(args.positionals[0]);\n process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"doc\": {\n const res = await client.getContext(args.positionals[0], Number(args.flags.window?.[0] ?? 2));\n process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n await client.reportResult(args.positionals[0], args.flags.verdict?.[0] ?? \"incorrect\", args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const res = await client.submitSource({\n url: args.positionals[0],\n version: args.flags.version?.[0],\n visibility: args.bools.has(\"private\") ? \"private\" : \"public\",\n webhook_url: args.flags.webhook?.[0],\n });\n process.stdout.write(`Job: ${res.job_id}\\n`);\n if (args.bools.has(\"watch\")) return watchJob(client, res.job_id);\n return EXIT.ok;\n }\n case \"jobs\":\n return args.bools.has(\"watch\") ? watchJob(client, args.positionals[0]) : printJob(client, args.positionals[0]);\n default:\n process.stderr.write(`Unknown command: ${command}\\n${HELP}`);\n return EXIT.apiError;\n }\n } catch (err) {\n if (err instanceof ApiError) {\n process.stderr.write(`error: ${err.code}\\n`);\n if (err.status === 401) return EXIT.authRequired;\n if (err.status === 429) return EXIT.quota;\n if (err.status === 404) return EXIT.notFound;\n return EXIT.apiError;\n }\n throw err;\n }\n}\n\nconst TERMINAL_STATUSES = [\"complete\", \"failed\", \"rejected\"];\nconst FAILED_STATUSES = [\"failed\", \"rejected\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n return FAILED_STATUSES.includes(status) ? EXIT.apiError : EXIT.ok;\n}\n\nconst WATCH_POLL_MS = 5_000;\nconst WATCH_BACKOFF_CAP_MS = 30_000;\nconst WATCH_DEADLINE_MS = 30 * 60_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nasync function watchJob(client: GrimoireClient, jobId: string): Promise<number> {\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let backoff = WATCH_POLL_MS;\n while (Date.now() < deadline) {\n try {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n if (TERMINAL_STATUSES.includes(status)) {\n return FAILED_STATUSES.includes(status) ? EXIT.apiError : EXIT.ok;\n }\n backoff = WATCH_POLL_MS;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n // Auth/permission/missing-job failures cannot heal on their own \u2014 bail out;\n // anything else (network, 5xx, timeout) is worth retrying with backoff.\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying in ${backoff / 1000}s\\n`);\n await sleep(backoff);\n backoff = Math.min(backoff * 2, WATCH_BACKOFF_CAP_MS);\n }\n }\n process.stderr.write(\n `Watch deadline (30m) reached; the job is still running. Check later with: grimoire jobs ${jobId}\\n`,\n );\n return EXIT.apiError;\n}\n\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\n .catch((err) => {\n if (err instanceof UsageError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(EXIT.apiError);\n }\n process.stderr.write(`fatal: ${(err as Error).message}\\n`);\n process.exit(EXIT.apiError);\n });\n", "import { readFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n// Bare origin \u2014 API paths are absolute (/v1/..., /auth/cli/...), so the base must\n// never carry a path prefix or auth-broker URLs would be built wrong.\nexport const DEFAULT_API_BASE = \"https://grimoire-api.monadeo.com\";\nfunction globalConfigPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"config.json\");\n}\n// Malformed config must never crash a consumer (the MCP server constructs a client\n// at import time): warn and behave as if the file were absent.\nfunction readJsonConfig(path) {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n }\n catch (err) {\n process.stderr.write(`grimoire: ignoring malformed config at ${path}: ${err.message}\\n`);\n return undefined;\n }\n}\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const base = { apiBaseUrl: process.env.GRIMOIRE_API_URL ?? DEFAULT_API_BASE };\n if (!existsSync(path))\n return base;\n const overrides = readJsonConfig(path);\n return overrides ? { ...base, ...overrides } : base;\n}\nexport function saveGlobalConfig(config) {\n const path = globalConfigPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(config, null, 2));\n}\n// Project config (.grimoire.json in the repo root) pins a codebase's sources and\n// overrides globals \u2014 committed alongside the code it documents.\nexport function findProjectConfig(startDir = process.cwd()) {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".grimoire.json\");\n if (existsSync(candidate)) {\n const parsed = readJsonConfig(candidate);\n if (parsed)\n return parsed;\n }\n const parent = dirname(dir);\n if (parent === dir)\n return undefined;\n dir = parent;\n }\n}\nexport function resolveDefaultSources() {\n return findProjectConfig()?.sources ?? loadGlobalConfig().defaultSources ?? [];\n}\n", "import { createHash, randomBytes } from \"node:crypto\";\nimport { createServer } from \"node:http\";\nimport { Entry } from \"@napi-rs/keyring\";\nimport { fetchWithTimeout } from \"./http.js\";\n// Credential storage in the OS keychain (maintained @napi-rs/keyring \u2014 keytar is\n// archived). A machine token via GRIMOIRE_AUTH_TOKEN overrides interactive auth (CI only).\nconst SERVICE = \"com.monadeo.grimoire\";\nconst ACCOUNT = \"refresh_token\";\nfunction keyring() {\n return new Entry(SERVICE, ACCOUNT);\n}\nexport function storeRefreshToken(token) {\n keyring().setPassword(token);\n}\nexport function readRefreshToken() {\n try {\n return keyring().getPassword() ?? undefined;\n }\n catch {\n return undefined;\n }\n}\nexport function clearRefreshToken() {\n try {\n keyring().deletePassword();\n }\n catch {\n /* already gone */\n }\n}\nfunction base64url(buf) {\n return buf.toString(\"base64url\");\n}\n// Browser login via the Grimoire auth broker (Firebase is not an OAuth AS): open\n// the hosted page with a PKCE challenge, receive the one-time code on a loopback\n// callback, exchange it for the Firebase refresh token. The random state binds the\n// callback to this login attempt; anything but GET /callback with that state gets\n// a 404 and the server keeps waiting.\nexport async function browserLogin(apiBase, openBrowser) {\n // The broker lives at the bare origin (/auth/cli/*, no /v1 prefix): normalize\n // away trailing slashes so the URLs are always built against the origin.\n const broker = apiBase.replace(/\\/+$/, \"\");\n const verifier = base64url(randomBytes(32));\n const challenge = base64url(createHash(\"sha256\").update(verifier).digest());\n const state = base64url(randomBytes(16));\n const code = await new Promise((resolve, reject) => {\n const server = createServer((req, res) => {\n const url = new URL(req.url ?? \"/\", \"http://127.0.0.1\");\n const received = url.searchParams.get(\"code\");\n if (req.method !== \"GET\" ||\n url.pathname !== \"/callback\" ||\n url.searchParams.get(\"state\") !== state ||\n !received) {\n res.writeHead(404).end();\n return;\n }\n res.writeHead(200, { \"Content-Type\": \"text/html\" });\n res.end(\"<p>Login complete \u2014 return to your terminal.</p>\");\n clearTimeout(timer);\n server.close();\n resolve(received);\n });\n server.listen(0, \"127.0.0.1\", () => {\n const port = server.address().port;\n const redirect = `http://127.0.0.1:${port}/callback`;\n openBrowser(`${broker}/auth/cli/start?code_challenge=${challenge}&code_challenge_method=S256&state=${state}&redirect_uri=${encodeURIComponent(redirect)}`);\n });\n const timer = setTimeout(() => {\n server.close();\n reject(new Error(\"Login timed out\"));\n }, 300_000);\n });\n const res = await fetchWithTimeout(`${broker}/auth/cli/exchange`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ code, code_verifier: verifier }),\n });\n if (!res.ok)\n throw new Error(`Token exchange failed: ${res.status}`);\n const { refresh_token } = (await res.json());\n storeRefreshToken(refresh_token);\n}\n", "export class ApiError extends Error {\n status;\n code;\n body;\n constructor(status, code, body) {\n super(`${code} (${status})`);\n this.status = status;\n this.code = code;\n this.body = body;\n }\n}\n", "import { ApiError } from \"./errors.js\";\nexport const REQUEST_TIMEOUT_MS = 30_000;\nexport async function fetchWithTimeout(url, init = {}) {\n try {\n return await fetch(url, { ...init, signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS) });\n }\n catch (err) {\n if (err instanceof Error && (err.name === \"TimeoutError\" || err.name === \"AbortError\")) {\n throw new ApiError(408, \"timeout\", `Request timed out after ${REQUEST_TIMEOUT_MS / 1000}s`);\n }\n throw err;\n }\n}\n", "import { readRefreshToken } from \"./auth.js\";\nimport { loadGlobalConfig } from \"./config.js\";\nimport { ApiError } from \"./errors.js\";\nimport { fetchWithTimeout } from \"./http.js\";\nexport { ApiError } from \"./errors.js\";\nexport class GrimoireClient {\n baseUrl;\n machineToken;\n cachedIdToken;\n refreshInFlight;\n constructor(opts = {}) {\n this.baseUrl = (opts.baseUrl ?? loadGlobalConfig().apiBaseUrl).replace(/\\/+$/, \"\");\n this.machineToken = opts.machineToken ?? process.env.GRIMOIRE_AUTH_TOKEN;\n }\n async bearer() {\n if (this.machineToken)\n return this.machineToken;\n if (this.cachedIdToken && this.cachedIdToken.expiresAt > Date.now() + 60_000) {\n return this.cachedIdToken.token;\n }\n this.refreshInFlight ??= this.refreshIdToken().finally(() => {\n this.refreshInFlight = undefined;\n });\n return this.refreshInFlight;\n }\n // Exchange the Firebase refresh token for a fresh ID token (silent refresh).\n async refreshIdToken() {\n const refresh = readRefreshToken();\n if (!refresh)\n throw new ApiError(401, \"not_logged_in\", \"Run `grimoire login`\");\n const res = await fetchWithTimeout(`${this.baseUrl}/auth/cli/refresh`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ refresh_token: refresh }),\n });\n if (!res.ok)\n throw new ApiError(res.status, \"refresh_failed\", \"Run `grimoire login`\");\n let payload;\n try {\n payload = await res.json();\n }\n catch {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n const { id_token, expires_in } = payload;\n if (typeof id_token !== \"string\" || typeof expires_in !== \"number\") {\n throw new ApiError(res.status, \"refresh_failed\", \"Malformed refresh response\");\n }\n this.cachedIdToken = { token: id_token, expiresAt: Date.now() + expires_in * 1000 };\n return id_token;\n }\n async refreshSession() {\n await this.bearer();\n }\n async send(path, init, auth) {\n const headers = {\n \"Content-Type\": \"application/json\",\n ...init.headers,\n };\n if (auth)\n headers.Authorization = `Bearer ${await this.bearer()}`;\n return fetchWithTimeout(`${this.baseUrl}${path}`, { ...init, headers });\n }\n async request(path, init = {}, auth = true) {\n let res = await this.send(path, init, auth);\n // A 401 despite a locally-unexpired ID token means it was revoked server-side:\n // force one refresh and retry exactly once.\n if (res.status === 401 && auth && !this.machineToken) {\n this.cachedIdToken = undefined;\n res = await this.send(path, init, auth);\n }\n return this.parseResponse(res);\n }\n async parseResponse(res) {\n const isJson = res.headers.get(\"content-type\")?.includes(\"json\") ?? false;\n const text = await res.text();\n let body;\n let parsed = false;\n if (isJson && text) {\n try {\n body = JSON.parse(text);\n parsed = true;\n }\n catch {\n parsed = false;\n }\n }\n if (!res.ok) {\n const code = parsed && typeof body === \"object\" && body !== null\n ? (body.error ?? \"error\")\n : \"error\";\n throw new ApiError(res.status, code, parsed ? body : text);\n }\n if (isJson)\n return (parsed ? body : {});\n return text;\n }\n search(input) {\n return this.request(\"/v1/search\", {\n method: \"POST\",\n body: JSON.stringify(input),\n });\n }\n listSources(q) {\n return this.request(`/v1/sources${q ? `?q=${encodeURIComponent(q)}` : \"\"}`);\n }\n listVersions(sourceId) {\n return this.request(`/v1/sources/${encodeURIComponent(sourceId)}/versions`);\n }\n getContext(chunkId, window = 2) {\n return this.request(`/v1/documents/${encodeURIComponent(chunkId)}/context?window=${window}`);\n }\n reportResult(chunkId, verdict, note) {\n return this.request(\"/v1/feedback\", {\n method: \"POST\",\n body: JSON.stringify({ chunk_id: chunkId, verdict, note }),\n });\n }\n submitSource(body) {\n return this.request(\"/v1/sources\", { method: \"POST\", body: JSON.stringify(body) });\n }\n getJob(jobId) {\n return this.request(`/v1/jobs/${encodeURIComponent(jobId)}`);\n }\n}\n", "// Minimal flag parser: collects repeated --flag/-f values and positionals.\nexport interface ParsedArgs {\n positionals: string[];\n flags: Record<string, string[]>;\n bools: Set<string>;\n}\n\nexport class UsageError extends Error {}\n\nconst BOOL_FLAGS = new Set([\"json\", \"compact\", \"watch\", \"private\", \"names\"]);\n\nexport function parseArgs(argv: string[], aliases: Record<string, string> = {}): ParsedArgs {\n const positionals: string[] = [];\n const flags: Record<string, string[]> = {};\n const bools = new Set<string>();\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg.startsWith(\"--\") || arg.startsWith(\"-\")) {\n const name = aliases[arg] ?? arg.replace(/^--?/, \"\");\n if (BOOL_FLAGS.has(name)) {\n bools.add(name);\n } else {\n const value = argv[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n throw new UsageError(`Flag ${arg} requires a value`);\n }\n (flags[name] ??= []).push(value);\n i++;\n }\n } else {\n positionals.push(arg);\n }\n }\n return { positionals, flags, bools };\n}\n", "import type { SearchResultChunk } from \"@monadeo.com/grimoire-core\";\n\n// Exit codes documented for scripting (clients spec).\nexport const EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 } as const;\n\nexport function printResults(results: SearchResultChunk[], confidence: string): void {\n if (confidence === \"weak\") {\n process.stderr.write(\n \"note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\\n\",\n );\n }\n for (const r of results) {\n const path = (r.heading_path ?? []).join(\" \u203A \");\n process.stdout.write(`\\n${r.score.toFixed(3)} ${r.source}@${r.version} ${path}\\n${r.origin_url}\\n`);\n const preview = r.text.length > 500 ? `${r.text.slice(0, 500)}\u2026` : r.text;\n process.stdout.write(`${preview}\\n`);\n }\n}\n\nexport function printCompact(results: SearchResultChunk[]): void {\n for (const r of results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(\" \u203A \")} | ${r.origin_url}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n// One-command agent onboarding (SDD decision 19 / clients spec): writes the MCP\n// registration for the named agent. `npx @monadeo.com/grimoire-mcp` needs no global install.\nconst MCP_ENTRY = { command: \"npx\", args: [\"-y\", \"@monadeo.com/grimoire-mcp\"] };\n\nconst CODEX_TABLE = `[mcp_servers.grimoire]\ncommand = \"npx\"\nargs = [\"-y\", \"@monadeo.com/grimoire-mcp\"]\n`;\n\n// Codex reads ~/.codex/config.toml. Replace our table in place (up to the next\n// [ header or EOF) without a TOML library, so the rest of the user's config\n// passes through byte-for-byte.\nexport function mergeCodexToml(existing: string): string {\n const header = existing.match(/^[ \\t]*\\[mcp_servers\\.grimoire\\][ \\t]*(\\r?\\n|$)/m);\n if (!header || header.index === undefined) {\n if (existing.trim() === \"\") return CODEX_TABLE;\n const sep = existing.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n return existing + sep + CODEX_TABLE;\n }\n const afterHeader = header.index + header[0].length;\n const nextHeader = existing.slice(afterHeader).match(/^[ \\t]*\\[/m);\n const end =\n nextHeader && nextHeader.index !== undefined ? afterHeader + nextHeader.index : existing.length;\n return existing.slice(0, header.index) + CODEX_TABLE + existing.slice(end);\n}\n\ninterface JsonAgentTarget {\n path: string;\n apply: (existing: Record<string, unknown>) => Record<string, unknown>;\n}\n\nfunction mcpServersMerge(key: string) {\n return (existing: Record<string, unknown>) => {\n const servers = (existing[key] as Record<string, unknown>) ?? {};\n return { ...existing, [key]: { ...servers, grimoire: MCP_ENTRY } };\n };\n}\n\nconst JSON_AGENTS: Record<string, JsonAgentTarget> = {\n \"claude-code\": { path: join(homedir(), \".claude.json\"), apply: mcpServersMerge(\"mcpServers\") },\n cursor: { path: join(homedir(), \".cursor\", \"mcp.json\"), apply: mcpServersMerge(\"mcpServers\") },\n windsurf: {\n path: join(homedir(), \".codeium\", \"windsurf\", \"mcp_config.json\"),\n apply: mcpServersMerge(\"mcpServers\"),\n },\n};\n\nconst AGENT_NAMES = [...Object.keys(JSON_AGENTS), \"codex\"];\n\nfunction setupCodex(): number {\n const path = join(homedir(), \".codex\", \"config.toml\");\n const existing = existsSync(path) ? readFileSync(path, \"utf8\") : \"\";\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, mergeCodexToml(existing));\n return finish(\"codex\", path);\n}\n\nfunction finish(agent: string, path: string): number {\n process.stdout.write(`Configured grimoire MCP for ${agent} at ${path}\\n`);\n process.stdout.write(\"Run `grimoire login` if you haven't yet.\\n\");\n return 0;\n}\n\nexport function runSetup(agent: string | undefined): number {\n if (!agent || !AGENT_NAMES.includes(agent)) {\n process.stderr.write(`Usage: grimoire setup <${AGENT_NAMES.join(\"|\")}>\\n`);\n return 1;\n }\n if (agent === \"codex\") return setupCodex();\n const target = JSON_AGENTS[agent];\n let existing: Record<string, unknown> = {};\n if (existsSync(target.path)) {\n try {\n existing = JSON.parse(readFileSync(target.path, \"utf8\")) as Record<string, unknown>;\n } catch (err) {\n process.stderr.write(\n `Cannot parse ${target.path}: ${(err as Error).message}\\nFix or remove the file, then re-run setup.\\n`,\n );\n return 1;\n }\n }\n mkdirSync(dirname(target.path), { recursive: true });\n writeFileSync(target.path, JSON.stringify(target.apply(existing), null, 2));\n return finish(agent, target.path);\n}\n", "import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { SourcePin } from \"@monadeo.com/grimoire-core\";\n\nfunction parseJsonFile<T>(path: string): T {\n try {\n return JSON.parse(readFileSync(path, \"utf8\")) as T;\n } catch (err) {\n throw new Error(`Cannot parse ${path}: ${(err as Error).message}`, { cause: err });\n }\n}\n\n// Scan common manifests \u2192 propose .grimoire.json source pins. Alias resolution\n// against the registry (curated to include package-ecosystem names) happens when\n// the sources are actually queried; init proposes candidate names from manifests.\nexport function detectManifestSources(dir = process.cwd()): SourcePin[] {\n const pins: SourcePin[] = [];\n const pkgPath = join(dir, \"package.json\");\n if (existsSync(pkgPath)) {\n const pkg = parseJsonFile<{ dependencies?: Record<string, string> }>(pkgPath);\n for (const [name, range] of Object.entries(pkg.dependencies ?? {})) {\n const major = range.match(/(\\d+)/)?.[1];\n pins.push({ source: name.replace(/^@[^/]+\\//, \"\"), ...(major ? { version: major } : {}) });\n }\n }\n const reqPath = join(dir, \"requirements.txt\");\n if (existsSync(reqPath)) {\n for (const line of readFileSync(reqPath, \"utf8\").split(\"\\n\")) {\n const m = line.match(/^([A-Za-z0-9_.-]+)\\s*==\\s*(\\d+)/);\n if (m) pins.push({ source: m[1].toLowerCase(), version: m[2] });\n }\n }\n return pins;\n}\n\nexport function runInit(): number {\n const path = join(process.cwd(), \".grimoire.json\");\n try {\n const sources = detectManifestSources();\n if (sources.length === 0) {\n process.stderr.write(\"No package.json/requirements.txt dependencies found.\\n\");\n return 1;\n }\n const existing = existsSync(path) ? parseJsonFile<Record<string, unknown>>(path) : {};\n writeFileSync(path, JSON.stringify({ ...existing, sources }, null, 2));\n process.stdout.write(`Wrote ${sources.length} source pins to .grimoire.json\\n`);\n return 0;\n } catch (err) {\n process.stderr.write(`${(err as Error).message}\\n`);\n return 1;\n }\n}\n"],
5
- "mappings": ";;;;AAAA,SAAS,oBAAoB;;;ACA7B,SAAS,cAAc,YAAY,WAAW,qBAAqB;AACnE,SAAS,eAAe;AACxB,SAAS,SAAS,YAAY;AAGvB,IAAM,mBAAmB;AAChC,SAAS,mBAAmB;AACxB,SAAO,KAAK,QAAQ,IAAI,mBAAmB,KAAK,QAAQ,GAAG,SAAS,GAAG,YAAY,aAAa;AACpG;AAGA,SAAS,eAAe,MAAM;AAC1B,MAAI;AACA,WAAO,KAAK,MAAM,aAAa,MAAM,MAAM,CAAC;AAAA,EAChD,SACO,KAAK;AACR,YAAQ,OAAO,MAAM,0CAA0C,IAAI,KAAK,IAAI,OAAO;AAAA,CAAI;AACvF,WAAO;AAAA,EACX;AACJ;AACO,SAAS,mBAAmB;AAC/B,QAAM,OAAO,iBAAiB;AAC9B,QAAM,OAAO,EAAE,YAAY,QAAQ,IAAI,oBAAoB,iBAAiB;AAC5E,MAAI,CAAC,WAAW,IAAI;AAChB,WAAO;AACX,QAAM,YAAY,eAAe,IAAI;AACrC,SAAO,YAAY,EAAE,GAAG,MAAM,GAAG,UAAU,IAAI;AACnD;AAQO,SAAS,kBAAkB,WAAW,QAAQ,IAAI,GAAG;AACxD,MAAI,MAAM;AACV,aAAS;AACL,UAAM,YAAY,KAAK,KAAK,gBAAgB;AAC5C,QAAI,WAAW,SAAS,GAAG;AACvB,YAAM,SAAS,eAAe,SAAS;AACvC,UAAI;AACA,eAAO;AAAA,IACf;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW;AACX,aAAO;AACX,UAAM;AAAA,EACV;AACJ;AACO,SAAS,wBAAwB;AACpC,SAAO,kBAAkB,GAAG,WAAW,iBAAiB,EAAE,kBAAkB,CAAC;AACjF;;;ACpDA,SAAS,YAAY,mBAAmB;AACxC,SAAS,oBAAoB;AAC7B,SAAS,aAAa;;;ACFf,IAAM,WAAN,cAAuB,MAAM;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,QAAQ,MAAM,MAAM;AAC5B,UAAM,GAAG,IAAI,KAAK,MAAM,GAAG;AAC3B,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EAChB;AACJ;;;ACTO,IAAM,qBAAqB;AAClC,eAAsB,iBAAiB,KAAK,OAAO,CAAC,GAAG;AACnD,MAAI;AACA,WAAO,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,QAAQ,YAAY,QAAQ,kBAAkB,EAAE,CAAC;AAAA,EACxF,SACO,KAAK;AACR,QAAI,eAAe,UAAU,IAAI,SAAS,kBAAkB,IAAI,SAAS,eAAe;AACpF,YAAM,IAAI,SAAS,KAAK,WAAW,2BAA2B,qBAAqB,GAAI,GAAG;AAAA,IAC9F;AACA,UAAM;AAAA,EACV;AACJ;;;AFNA,IAAM,UAAU;AAChB,IAAM,UAAU;AAChB,SAAS,UAAU;AACf,SAAO,IAAI,MAAM,SAAS,OAAO;AACrC;AACO,SAAS,kBAAkB,OAAO;AACrC,UAAQ,EAAE,YAAY,KAAK;AAC/B;AACO,SAAS,mBAAmB;AAC/B,MAAI;AACA,WAAO,QAAQ,EAAE,YAAY,KAAK;AAAA,EACtC,QACM;AACF,WAAO;AAAA,EACX;AACJ;AACO,SAAS,oBAAoB;AAChC,MAAI;AACA,YAAQ,EAAE,eAAe;AAAA,EAC7B,QACM;AAAA,EAEN;AACJ;AACA,SAAS,UAAU,KAAK;AACpB,SAAO,IAAI,SAAS,WAAW;AACnC;AAMA,eAAsB,aAAa,SAASA,cAAa;AAGrD,QAAM,SAAS,QAAQ,QAAQ,QAAQ,EAAE;AACzC,QAAM,WAAW,UAAU,YAAY,EAAE,CAAC;AAC1C,QAAM,YAAY,UAAU,WAAW,QAAQ,EAAE,OAAO,QAAQ,EAAE,OAAO,CAAC;AAC1E,QAAM,QAAQ,UAAU,YAAY,EAAE,CAAC;AACvC,QAAM,OAAO,MAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AAChD,UAAM,SAAS,aAAa,CAAC,KAAKC,SAAQ;AACtC,YAAM,MAAM,IAAI,IAAI,IAAI,OAAO,KAAK,kBAAkB;AACtD,YAAM,WAAW,IAAI,aAAa,IAAI,MAAM;AAC5C,UAAI,IAAI,WAAW,SACf,IAAI,aAAa,eACjB,IAAI,aAAa,IAAI,OAAO,MAAM,SAClC,CAAC,UAAU;AACX,QAAAA,KAAI,UAAU,GAAG,EAAE,IAAI;AACvB;AAAA,MACJ;AACA,MAAAA,KAAI,UAAU,KAAK,EAAE,gBAAgB,YAAY,CAAC;AAClD,MAAAA,KAAI,IAAI,uDAAkD;AAC1D,mBAAa,KAAK;AAClB,aAAO,MAAM;AACb,cAAQ,QAAQ;AAAA,IACpB,CAAC;AACD,WAAO,OAAO,GAAG,aAAa,MAAM;AAChC,YAAM,OAAO,OAAO,QAAQ,EAAE;AAC9B,YAAM,WAAW,oBAAoB,IAAI;AACzC,MAAAD,aAAY,GAAG,MAAM,kCAAkC,SAAS,qCAAqC,KAAK,iBAAiB,mBAAmB,QAAQ,CAAC,EAAE;AAAA,IAC7J,CAAC;AACD,UAAM,QAAQ,WAAW,MAAM;AAC3B,aAAO,MAAM;AACb,aAAO,IAAI,MAAM,iBAAiB,CAAC;AAAA,IACvC,GAAG,GAAO;AAAA,EACd,CAAC;AACD,QAAM,MAAM,MAAM,iBAAiB,GAAG,MAAM,sBAAsB;AAAA,IAC9D,QAAQ;AAAA,IACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,IAC9C,MAAM,KAAK,UAAU,EAAE,MAAM,eAAe,SAAS,CAAC;AAAA,EAC1D,CAAC;AACD,MAAI,CAAC,IAAI;AACL,UAAM,IAAI,MAAM,0BAA0B,IAAI,MAAM,EAAE;AAC1D,QAAM,EAAE,cAAc,IAAK,MAAM,IAAI,KAAK;AAC1C,oBAAkB,aAAa;AACnC;;;AG5EO,IAAM,iBAAN,MAAqB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY,OAAO,CAAC,GAAG;AACnB,SAAK,WAAW,KAAK,WAAW,iBAAiB,EAAE,YAAY,QAAQ,QAAQ,EAAE;AACjF,SAAK,eAAe,KAAK,gBAAgB,QAAQ,IAAI;AAAA,EACzD;AAAA,EACA,MAAM,SAAS;AACX,QAAI,KAAK;AACL,aAAO,KAAK;AAChB,QAAI,KAAK,iBAAiB,KAAK,cAAc,YAAY,KAAK,IAAI,IAAI,KAAQ;AAC1E,aAAO,KAAK,cAAc;AAAA,IAC9B;AACA,SAAK,oBAAoB,KAAK,eAAe,EAAE,QAAQ,MAAM;AACzD,WAAK,kBAAkB;AAAA,IAC3B,CAAC;AACD,WAAO,KAAK;AAAA,EAChB;AAAA;AAAA,EAEA,MAAM,iBAAiB;AACnB,UAAM,UAAU,iBAAiB;AACjC,QAAI,CAAC;AACD,YAAM,IAAI,SAAS,KAAK,iBAAiB,sBAAsB;AACnE,UAAM,MAAM,MAAM,iBAAiB,GAAG,KAAK,OAAO,qBAAqB;AAAA,MACnE,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,EAAE,eAAe,QAAQ,CAAC;AAAA,IACnD,CAAC;AACD,QAAI,CAAC,IAAI;AACL,YAAM,IAAI,SAAS,IAAI,QAAQ,kBAAkB,sBAAsB;AAC3E,QAAI;AACJ,QAAI;AACA,gBAAU,MAAM,IAAI,KAAK;AAAA,IAC7B,QACM;AACF,YAAM,IAAI,SAAS,IAAI,QAAQ,kBAAkB,4BAA4B;AAAA,IACjF;AACA,UAAM,EAAE,UAAU,WAAW,IAAI;AACjC,QAAI,OAAO,aAAa,YAAY,OAAO,eAAe,UAAU;AAChE,YAAM,IAAI,SAAS,IAAI,QAAQ,kBAAkB,4BAA4B;AAAA,IACjF;AACA,SAAK,gBAAgB,EAAE,OAAO,UAAU,WAAW,KAAK,IAAI,IAAI,aAAa,IAAK;AAClF,WAAO;AAAA,EACX;AAAA,EACA,MAAM,iBAAiB;AACnB,UAAM,KAAK,OAAO;AAAA,EACtB;AAAA,EACA,MAAM,KAAK,MAAM,MAAM,MAAM;AACzB,UAAM,UAAU;AAAA,MACZ,gBAAgB;AAAA,MAChB,GAAG,KAAK;AAAA,IACZ;AACA,QAAI;AACA,cAAQ,gBAAgB,UAAU,MAAM,KAAK,OAAO,CAAC;AACzD,WAAO,iBAAiB,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI,EAAE,GAAG,MAAM,QAAQ,CAAC;AAAA,EAC1E;AAAA,EACA,MAAM,QAAQ,MAAM,OAAO,CAAC,GAAG,OAAO,MAAM;AACxC,QAAI,MAAM,MAAM,KAAK,KAAK,MAAM,MAAM,IAAI;AAG1C,QAAI,IAAI,WAAW,OAAO,QAAQ,CAAC,KAAK,cAAc;AAClD,WAAK,gBAAgB;AACrB,YAAM,MAAM,KAAK,KAAK,MAAM,MAAM,IAAI;AAAA,IAC1C;AACA,WAAO,KAAK,cAAc,GAAG;AAAA,EACjC;AAAA,EACA,MAAM,cAAc,KAAK;AACrB,UAAM,SAAS,IAAI,QAAQ,IAAI,cAAc,GAAG,SAAS,MAAM,KAAK;AACpE,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI;AACJ,QAAI,SAAS;AACb,QAAI,UAAU,MAAM;AAChB,UAAI;AACA,eAAO,KAAK,MAAM,IAAI;AACtB,iBAAS;AAAA,MACb,QACM;AACF,iBAAS;AAAA,MACb;AAAA,IACJ;AACA,QAAI,CAAC,IAAI,IAAI;AACT,YAAM,OAAO,UAAU,OAAO,SAAS,YAAY,SAAS,OACrD,KAAK,SAAS,UACf;AACN,YAAM,IAAI,SAAS,IAAI,QAAQ,MAAM,SAAS,OAAO,IAAI;AAAA,IAC7D;AACA,QAAI;AACA,aAAQ,SAAS,OAAO,CAAC;AAC7B,WAAO;AAAA,EACX;AAAA,EACA,OAAO,OAAO;AACV,WAAO,KAAK,QAAQ,cAAc;AAAA,MAC9B,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,KAAK;AAAA,IAC9B,CAAC;AAAA,EACL;AAAA,EACA,YAAY,GAAG;AACX,WAAO,KAAK,QAAQ,cAAc,IAAI,MAAM,mBAAmB,CAAC,CAAC,KAAK,EAAE,EAAE;AAAA,EAC9E;AAAA,EACA,aAAa,UAAU;AACnB,WAAO,KAAK,QAAQ,eAAe,mBAAmB,QAAQ,CAAC,WAAW;AAAA,EAC9E;AAAA,EACA,WAAW,SAAS,SAAS,GAAG;AAC5B,WAAO,KAAK,QAAQ,iBAAiB,mBAAmB,OAAO,CAAC,mBAAmB,MAAM,EAAE;AAAA,EAC/F;AAAA,EACA,aAAa,SAAS,SAAS,MAAM;AACjC,WAAO,KAAK,QAAQ,gBAAgB;AAAA,MAChC,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,UAAU,SAAS,SAAS,KAAK,CAAC;AAAA,IAC7D,CAAC;AAAA,EACL;AAAA,EACA,aAAa,MAAM;AACf,WAAO,KAAK,QAAQ,eAAe,EAAE,QAAQ,QAAQ,MAAM,KAAK,UAAU,IAAI,EAAE,CAAC;AAAA,EACrF;AAAA,EACA,OAAO,OAAO;AACV,WAAO,KAAK,QAAQ,YAAY,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAC/D;AACJ;;;ACrHO,IAAM,aAAN,cAAyB,MAAM;AAAC;AAEvC,IAAM,aAAa,oBAAI,IAAI,CAAC,QAAQ,WAAW,SAAS,WAAW,OAAO,CAAC;AAEpE,SAAS,UAAU,MAAgB,UAAkC,CAAC,GAAe;AAC1F,QAAM,cAAwB,CAAC;AAC/B,QAAM,QAAkC,CAAC;AACzC,QAAM,QAAQ,oBAAI,IAAY;AAC9B,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAClB,QAAI,IAAI,WAAW,IAAI,KAAK,IAAI,WAAW,GAAG,GAAG;AAC/C,YAAM,OAAO,QAAQ,GAAG,KAAK,IAAI,QAAQ,QAAQ,EAAE;AACnD,UAAI,WAAW,IAAI,IAAI,GAAG;AACxB,cAAM,IAAI,IAAI;AAAA,MAChB,OAAO;AACL,cAAM,QAAQ,KAAK,IAAI,CAAC;AACxB,YAAI,UAAU,UAAa,MAAM,WAAW,GAAG,GAAG;AAChD,gBAAM,IAAI,WAAW,QAAQ,GAAG,mBAAmB;AAAA,QACrD;AACA,SAAC,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,KAAK;AAC/B;AAAA,MACF;AAAA,IACF,OAAO;AACL,kBAAY,KAAK,GAAG;AAAA,IACtB;AAAA,EACF;AACA,SAAO,EAAE,aAAa,OAAO,MAAM;AACrC;;;AC/BO,IAAM,OAAO,EAAE,IAAI,GAAG,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,UAAU,EAAE;AAE1E,SAAS,aAAa,SAA8B,YAA0B;AACnF,MAAI,eAAe,QAAQ;AACzB,YAAQ,OAAO;AAAA,MACb;AAAA,IACF;AAAA,EACF;AACA,aAAW,KAAK,SAAS;AACvB,UAAM,QAAQ,EAAE,gBAAgB,CAAC,GAAG,KAAK,UAAK;AAC9C,YAAQ,OAAO,MAAM;AAAA,EAAK,EAAE,MAAM,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,KAAK,IAAI;AAAA,EAAK,EAAE,UAAU;AAAA,CAAI;AACpG,UAAM,UAAU,EAAE,KAAK,SAAS,MAAM,GAAG,EAAE,KAAK,MAAM,GAAG,GAAG,CAAC,WAAM,EAAE;AACrE,YAAQ,OAAO,MAAM,GAAG,OAAO;AAAA,CAAI;AAAA,EACrC;AACF;AAEO,SAAS,aAAa,SAAoC;AAC/D,aAAW,KAAK,SAAS;AACvB,YAAQ,OAAO;AAAA,MACb,GAAG,EAAE,MAAM,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,gBAAgB,CAAC,GAAG,KAAK,UAAK,CAAC,MAAM,EAAE,UAAU;AAAA;AAAA,IAC5G;AAAA,EACF;AACF;;;ACzBA,SAAS,cAAAE,aAAY,aAAAC,YAAW,gBAAAC,eAAc,iBAAAC,sBAAqB;AACnE,SAAS,WAAAC,gBAAe;AACxB,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAI9B,IAAM,YAAY,EAAE,SAAS,OAAO,MAAM,CAAC,MAAM,2BAA2B,EAAE;AAE9E,IAAM,cAAc;AAAA;AAAA;AAAA;AAQb,SAAS,eAAe,UAA0B;AACvD,QAAM,SAAS,SAAS,MAAM,kDAAkD;AAChF,MAAI,CAAC,UAAU,OAAO,UAAU,QAAW;AACzC,QAAI,SAAS,KAAK,MAAM,GAAI,QAAO;AACnC,UAAM,MAAM,SAAS,SAAS,IAAI,IAAI,OAAO;AAC7C,WAAO,WAAW,MAAM;AAAA,EAC1B;AACA,QAAM,cAAc,OAAO,QAAQ,OAAO,CAAC,EAAE;AAC7C,QAAM,aAAa,SAAS,MAAM,WAAW,EAAE,MAAM,YAAY;AACjE,QAAM,MACJ,cAAc,WAAW,UAAU,SAAY,cAAc,WAAW,QAAQ,SAAS;AAC3F,SAAO,SAAS,MAAM,GAAG,OAAO,KAAK,IAAI,cAAc,SAAS,MAAM,GAAG;AAC3E;AAOA,SAAS,gBAAgB,KAAa;AACpC,SAAO,CAAC,aAAsC;AAC5C,UAAM,UAAW,SAAS,GAAG,KAAiC,CAAC;AAC/D,WAAO,EAAE,GAAG,UAAU,CAAC,GAAG,GAAG,EAAE,GAAG,SAAS,UAAU,UAAU,EAAE;AAAA,EACnE;AACF;AAEA,IAAM,cAA+C;AAAA,EACnD,eAAe,EAAE,MAAMA,MAAKF,SAAQ,GAAG,cAAc,GAAG,OAAO,gBAAgB,YAAY,EAAE;AAAA,EAC7F,QAAQ,EAAE,MAAME,MAAKF,SAAQ,GAAG,WAAW,UAAU,GAAG,OAAO,gBAAgB,YAAY,EAAE;AAAA,EAC7F,UAAU;AAAA,IACR,MAAME,MAAKF,SAAQ,GAAG,YAAY,YAAY,iBAAiB;AAAA,IAC/D,OAAO,gBAAgB,YAAY;AAAA,EACrC;AACF;AAEA,IAAM,cAAc,CAAC,GAAG,OAAO,KAAK,WAAW,GAAG,OAAO;AAEzD,SAAS,aAAqB;AAC5B,QAAM,OAAOE,MAAKF,SAAQ,GAAG,UAAU,aAAa;AACpD,QAAM,WAAWJ,YAAW,IAAI,IAAIE,cAAa,MAAM,MAAM,IAAI;AACjE,EAAAD,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,EAAAF,eAAc,MAAM,eAAe,QAAQ,CAAC;AAC5C,SAAO,OAAO,SAAS,IAAI;AAC7B;AAEA,SAAS,OAAO,OAAe,MAAsB;AACnD,UAAQ,OAAO,MAAM,+BAA+B,KAAK,OAAO,IAAI;AAAA,CAAI;AACxE,UAAQ,OAAO,MAAM,4CAA4C;AACjE,SAAO;AACT;AAEO,SAAS,SAAS,OAAmC;AAC1D,MAAI,CAAC,SAAS,CAAC,YAAY,SAAS,KAAK,GAAG;AAC1C,YAAQ,OAAO,MAAM,0BAA0B,YAAY,KAAK,GAAG,CAAC;AAAA,CAAK;AACzE,WAAO;AAAA,EACT;AACA,MAAI,UAAU,QAAS,QAAO,WAAW;AACzC,QAAM,SAAS,YAAY,KAAK;AAChC,MAAI,WAAoC,CAAC;AACzC,MAAIH,YAAW,OAAO,IAAI,GAAG;AAC3B,QAAI;AACF,iBAAW,KAAK,MAAME,cAAa,OAAO,MAAM,MAAM,CAAC;AAAA,IACzD,SAAS,KAAK;AACZ,cAAQ,OAAO;AAAA,QACb,gBAAgB,OAAO,IAAI,KAAM,IAAc,OAAO;AAAA;AAAA;AAAA,MACxD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,EAAAD,WAAUI,SAAQ,OAAO,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AACnD,EAAAF,eAAc,OAAO,MAAM,KAAK,UAAU,OAAO,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC;AAC1E,SAAO,OAAO,OAAO,OAAO,IAAI;AAClC;;;ACxFA,SAAS,cAAAI,aAAY,gBAAAC,eAAc,iBAAAC,sBAAqB;AACxD,SAAS,QAAAC,aAAY;AAGrB,SAAS,cAAiB,MAAiB;AACzC,MAAI;AACF,WAAO,KAAK,MAAMF,cAAa,MAAM,MAAM,CAAC;AAAA,EAC9C,SAAS,KAAK;AACZ,UAAM,IAAI,MAAM,gBAAgB,IAAI,KAAM,IAAc,OAAO,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,EACnF;AACF;AAKO,SAAS,sBAAsB,MAAM,QAAQ,IAAI,GAAgB;AACtE,QAAM,OAAoB,CAAC;AAC3B,QAAM,UAAUE,MAAK,KAAK,cAAc;AACxC,MAAIH,YAAW,OAAO,GAAG;AACvB,UAAM,MAAM,cAAyD,OAAO;AAC5E,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,IAAI,gBAAgB,CAAC,CAAC,GAAG;AAClE,YAAM,QAAQ,MAAM,MAAM,OAAO,IAAI,CAAC;AACtC,WAAK,KAAK,EAAE,QAAQ,KAAK,QAAQ,aAAa,EAAE,GAAG,GAAI,QAAQ,EAAE,SAAS,MAAM,IAAI,CAAC,EAAG,CAAC;AAAA,IAC3F;AAAA,EACF;AACA,QAAM,UAAUG,MAAK,KAAK,kBAAkB;AAC5C,MAAIH,YAAW,OAAO,GAAG;AACvB,eAAW,QAAQC,cAAa,SAAS,MAAM,EAAE,MAAM,IAAI,GAAG;AAC5D,YAAM,IAAI,KAAK,MAAM,iCAAiC;AACtD,UAAI,EAAG,MAAK,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,GAAG,SAAS,EAAE,CAAC,EAAE,CAAC;AAAA,IAChE;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,UAAkB;AAChC,QAAM,OAAOE,MAAK,QAAQ,IAAI,GAAG,gBAAgB;AACjD,MAAI;AACF,UAAM,UAAU,sBAAsB;AACtC,QAAI,QAAQ,WAAW,GAAG;AACxB,cAAQ,OAAO,MAAM,wDAAwD;AAC7E,aAAO;AAAA,IACT;AACA,UAAM,WAAWH,YAAW,IAAI,IAAI,cAAuC,IAAI,IAAI,CAAC;AACpF,IAAAE,eAAc,MAAM,KAAK,UAAU,EAAE,GAAG,UAAU,QAAQ,GAAG,MAAM,CAAC,CAAC;AACrE,YAAQ,OAAO,MAAM,SAAS,QAAQ,MAAM;AAAA,CAAkC;AAC9E,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,YAAQ,OAAO,MAAM,GAAI,IAAc,OAAO;AAAA,CAAI;AAClD,WAAO;AAAA,EACT;AACF;;;ATnCA,SAAS,YAAY,KAAmB;AACtC,QAAM,MAAM,QAAQ,aAAa,WAAW,SAAS,QAAQ,aAAa,UAAU,UAAU;AAC9F,MAAI;AACF,iBAAa,KAAK,CAAC,GAAG,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,EAC9C,QAAQ;AACN,YAAQ,OAAO,MAAM;AAAA,EAA6B,GAAG;AAAA,CAAI;AAAA,EAC3D;AACF;AAEA,SAAS,iBAAiB,QAA2C;AACnE,UAAQ,UAAU,CAAC,GAAG,IAAI,CAAC,MAAM;AAC/B,UAAM,CAAC,QAAQ,OAAO,IAAI,EAAE,MAAM,GAAG;AACrC,WAAO,UAAU,EAAE,QAAQ,QAAQ,IAAI,EAAE,OAAO;AAAA,EAClD,CAAC;AACH;AAEA,IAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBb,eAAe,KAAK,MAAiC;AACnD,QAAM,CAAC,SAAS,GAAG,IAAI,IAAI;AAC3B,QAAM,OAAO,UAAU,MAAM,EAAE,MAAM,UAAU,MAAM,IAAI,CAAC;AAC1D,QAAM,OAAO,KAAK,MAAM,IAAI,MAAM;AAElC,UAAQ,SAAS;AAAA,IACf,KAAK,SAAS;AACZ,YAAM,aAAa,iBAAiB,EAAE,YAAY,WAAW;AAC7D,cAAQ,OAAO,MAAM,cAAc;AACnC,aAAO,KAAK;AAAA,IACd;AAAA,IACA,KAAK;AACH,wBAAkB;AAClB,cAAQ,OAAO,MAAM,eAAe;AACpC,aAAO,KAAK;AAAA,IACd,KAAK;AACH,aAAO,SAAS,KAAK,YAAY,CAAC,CAAC;AAAA,IACrC,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,cAAQ,OAAO,MAAM,4DAA4D,KAAK,MAAM,IAAI,MAAM,IAAI,cAAc,KAAK;AAC7H,aAAO,KAAK;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,cAAQ,OAAO,MAAM,IAAI;AACzB,aAAO,KAAK;AAAA,EAChB;AAEA,QAAM,SAAS,IAAI,eAAe;AAClC,MAAI;AACF,YAAQ,SAAS;AAAA,MACf,KAAK,UAAU;AACb,YAAI,QAAQ,IAAI,qBAAqB;AACnC,kBAAQ,OAAO,MAAM,kDAAkD;AACvE,iBAAO,KAAK;AAAA,QACd;AACA,YAAI,CAAC,iBAAiB,GAAG;AACvB,kBAAQ,OAAO,MAAM,6CAAwC;AAC7D,iBAAO,KAAK;AAAA,QACd;AACA,YAAI;AACF,gBAAM,OAAO,eAAe;AAC5B,kBAAQ,OAAO,MAAM,+BAA+B;AACpD,iBAAO,KAAK;AAAA,QACd,SAAS,KAAK;AACZ,gBAAM,SAAS,eAAe,WAAW,IAAI,OAAQ,IAAc;AACnE,kBAAQ,OAAO,MAAM,kBAAkB,MAAM;AAAA,CAA8B;AAC3E,iBAAO,KAAK;AAAA,QACd;AAAA,MACF;AAAA,MACA,KAAK,UAAU;AACb,cAAM,QAAQ,KAAK,YAAY,CAAC;AAChC,YAAI,CAAC,OAAO;AACV,kBAAQ,OAAO,MAAM,gDAAkD;AACvE,iBAAO,KAAK;AAAA,QACd;AACA,cAAM,WAAW,iBAAiB,KAAK,MAAM,MAAM;AACnD,cAAM,UAAU,SAAS,SAAS,IAAI,WAAW,sBAAsB;AACvE,YAAI,QAAQ,WAAW,GAAG;AACxB,kBAAQ,OAAO,MAAM,wDAAwD;AAC7E,iBAAO,KAAK;AAAA,QACd;AACA,cAAM,MAAM,MAAM,OAAO,OAAO;AAAA,UAC9B;AAAA,UACA;AAAA,UACA,UAAU,KAAK,MAAM,OAAO,CAAC;AAAA,UAC7B,OAAO,KAAK,MAAM,OAAO,IAAI,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI;AAAA,QAChE,CAAC;AACD,YAAI,KAAM,SAAQ,OAAO,MAAM,KAAK,UAAU,KAAK,MAAM,CAAC,IAAI,IAAI;AAAA,iBACzD,KAAK,MAAM,IAAI,SAAS,EAAG,cAAa,IAAI,OAAO;AAAA,YACvD,cAAa,IAAI,SAAS,IAAI,UAAU;AAC7C,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK,WAAW;AACd,cAAM,MAAM,MAAM,OAAO,YAAY,KAAK,MAAM,IAAI,CAAC,CAAC;AACtD,gBAAQ,OAAO,MAAM,KAAK,UAAU,IAAI,WAAW,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC,IAAI,IAAI;AACjF,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK,YAAY;AACf,cAAM,MAAM,MAAM,OAAO,aAAa,KAAK,YAAY,CAAC,CAAC;AACzD,gBAAQ,OAAO,MAAM,KAAK,UAAU,IAAI,YAAY,CAAC,GAAG,MAAM,OAAO,IAAI,CAAC,IAAI,IAAI;AAClF,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK,OAAO;AACV,cAAM,MAAM,MAAM,OAAO,WAAW,KAAK,YAAY,CAAC,GAAG,OAAO,KAAK,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;AAC5F,gBAAQ,OAAO,MAAM,KAAK,UAAU,IAAI,UAAU,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI;AACrE,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK,UAAU;AACb,cAAM,OAAO,aAAa,KAAK,YAAY,CAAC,GAAG,KAAK,MAAM,UAAU,CAAC,KAAK,aAAa,KAAK,MAAM,OAAO,CAAC,CAAC;AAC3G,gBAAQ,OAAO,MAAM,aAAa;AAClC,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK,UAAU;AACb,cAAM,MAAM,MAAM,OAAO,aAAa;AAAA,UACpC,KAAK,KAAK,YAAY,CAAC;AAAA,UACvB,SAAS,KAAK,MAAM,UAAU,CAAC;AAAA,UAC/B,YAAY,KAAK,MAAM,IAAI,SAAS,IAAI,YAAY;AAAA,UACpD,aAAa,KAAK,MAAM,UAAU,CAAC;AAAA,QACrC,CAAC;AACD,gBAAQ,OAAO,MAAM,QAAQ,IAAI,MAAM;AAAA,CAAI;AAC3C,YAAI,KAAK,MAAM,IAAI,OAAO,EAAG,QAAO,SAAS,QAAQ,IAAI,MAAM;AAC/D,eAAO,KAAK;AAAA,MACd;AAAA,MACA,KAAK;AACH,eAAO,KAAK,MAAM,IAAI,OAAO,IAAI,SAAS,QAAQ,KAAK,YAAY,CAAC,CAAC,IAAI,SAAS,QAAQ,KAAK,YAAY,CAAC,CAAC;AAAA,MAC/G;AACE,gBAAQ,OAAO,MAAM,oBAAoB,OAAO;AAAA,EAAK,IAAI,EAAE;AAC3D,eAAO,KAAK;AAAA,IAChB;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,UAAU;AAC3B,cAAQ,OAAO,MAAM,UAAU,IAAI,IAAI;AAAA,CAAI;AAC3C,UAAI,IAAI,WAAW,IAAK,QAAO,KAAK;AACpC,UAAI,IAAI,WAAW,IAAK,QAAO,KAAK;AACpC,UAAI,IAAI,WAAW,IAAK,QAAO,KAAK;AACpC,aAAO,KAAK;AAAA,IACd;AACA,UAAM;AAAA,EACR;AACF;AAEA,IAAM,oBAAoB,CAAC,YAAY,UAAU,UAAU;AAC3D,IAAM,kBAAkB,CAAC,UAAU,UAAU;AAE7C,eAAe,SAAS,QAAwB,OAAgC;AAC9E,QAAM,MAAM,MAAM,OAAO,OAAO,KAAK;AACrC,QAAM,SAAS,IAAI,UAAU;AAC7B,UAAQ,OAAO,MAAM,GAAG,MAAM,IAAI,KAAK,UAAU,IAAI,YAAY,CAAC,CAAC,CAAC;AAAA,CAAI;AACxE,SAAO,gBAAgB,SAAS,MAAM,IAAI,KAAK,WAAW,KAAK;AACjE;AAEA,IAAM,gBAAgB;AACtB,IAAM,uBAAuB;AAC7B,IAAM,oBAAoB,KAAK;AAE/B,SAAS,MAAM,IAA2B;AACxC,SAAO,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC7C;AAEA,eAAe,SAAS,QAAwB,OAAgC;AAC9E,QAAM,WAAW,KAAK,IAAI,IAAI;AAC9B,MAAI,UAAU;AACd,SAAO,KAAK,IAAI,IAAI,UAAU;AAC5B,QAAI;AACF,YAAM,MAAM,MAAM,OAAO,OAAO,KAAK;AACrC,YAAM,SAAS,IAAI,UAAU;AAC7B,cAAQ,OAAO,MAAM,GAAG,MAAM,IAAI,KAAK,UAAU,IAAI,YAAY,CAAC,CAAC,CAAC;AAAA,CAAI;AACxE,UAAI,kBAAkB,SAAS,MAAM,GAAG;AACtC,eAAO,gBAAgB,SAAS,MAAM,IAAI,KAAK,WAAW,KAAK;AAAA,MACjE;AACA,gBAAU;AACV,YAAM,MAAM,aAAa;AAAA,IAC3B,SAAS,KAAK;AAGZ,UAAI,eAAe,YAAY,CAAC,KAAK,KAAK,GAAG,EAAE,SAAS,IAAI,MAAM,EAAG,OAAM;AAC3E,YAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,cAAQ,OAAO,MAAM,gBAAgB,MAAM,kBAAkB,UAAU,GAAI;AAAA,CAAK;AAChF,YAAM,MAAM,OAAO;AACnB,gBAAU,KAAK,IAAI,UAAU,GAAG,oBAAoB;AAAA,IACtD;AAAA,EACF;AACA,UAAQ,OAAO;AAAA,IACb,2FAA2F,KAAK;AAAA;AAAA,EAClG;AACA,SAAO,KAAK;AACd;AAEA,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC,EACvB,KAAK,CAAC,SAAS,QAAQ,KAAK,IAAI,CAAC,EACjC,MAAM,CAAC,QAAQ;AACd,MAAI,eAAe,YAAY;AAC7B,YAAQ,OAAO,MAAM,GAAG,IAAI,OAAO;AAAA,CAAI;AACvC,YAAQ,KAAK,KAAK,QAAQ;AAAA,EAC5B;AACA,UAAQ,OAAO,MAAM,UAAW,IAAc,OAAO;AAAA,CAAI;AACzD,UAAQ,KAAK,KAAK,QAAQ;AAC5B,CAAC;",
6
- "names": ["openBrowser", "res", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "homedir", "dirname", "join", "existsSync", "readFileSync", "writeFileSync", "join"]
4
+ "sourcesContent": ["import { execFileSync } from \"node:child_process\";\nimport {\n GrimoireClient,\n ApiError,\n browserLogin,\n clearRefreshToken,\n readRefreshToken,\n resolveDefaultSources,\n loadGlobalConfig,\n type SourcePin,\n} from \"@monadeo.com/grimoire-core\";\nimport { parseArgs, requirePositional, requireFlagOneOf, intFlag, UsageError } from \"./args.js\";\nimport { printResults, printCompact, EXIT } from \"./output.js\";\nimport { runSetup } from \"./commands/setup.js\";\nimport { runInit } from \"./commands/init.js\";\n\nfunction openBrowser(url: string): void {\n const cmd = process.platform === \"darwin\" ? \"open\" : process.platform === \"win32\" ? \"start\" : \"xdg-open\";\n try {\n execFileSync(cmd, [url], { stdio: \"ignore\" });\n } catch {\n process.stdout.write(`Open this URL to log in:\\n${url}\\n`);\n }\n}\n\nfunction parseSourceFlags(values: string[] | undefined): SourcePin[] {\n return (values ?? []).map((v) => {\n const [source, version] = v.split(\"@\");\n return version ? { source, version } : { source };\n });\n}\n\nconst HELP = `grimoire \u2014 documentation retrieval for AI agents\n\n grimoire login | logout | whoami\n grimoire setup <claude-code|cursor|windsurf|codex>\n grimoire init\n grimoire search \"<query>\" [-s nextjs@15 -s react] [--lang en] [--top-k 8] [--json|--compact]\n grimoire sources [--q <kw>] [--json]\n grimoire versions <source> [--json]\n grimoire doc <chunk_id> [--window 2]\n grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note \"...\"]\n grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\n grimoire jobs <job_id> [--watch]\n grimoire mcp [--http]\n\n env: GRIMOIRE_AUTH_TOKEN \u2014 machine token (CI, instead of login)\n GRIMOIRE_API_URL \u2014 API origin without a path, e.g. https://grimoire-api-qa.monadeo.com\n`;\n\nasync function main(argv: string[]): Promise<number> {\n const [command, ...rest] = argv;\n const args = parseArgs(rest, { \"-s\": \"source\", \"-q\": \"q\" });\n const json = args.bools.has(\"json\");\n\n switch (command) {\n case \"login\": {\n await browserLogin(loadGlobalConfig().apiBaseUrl, openBrowser);\n process.stdout.write(\"Logged in.\\n\");\n return EXIT.ok;\n }\n case \"logout\":\n clearRefreshToken();\n process.stdout.write(\"Logged out.\\n\");\n return EXIT.ok;\n case \"setup\":\n return runSetup(args.positionals[0]);\n case \"init\":\n return runInit();\n case \"mcp\":\n process.stderr.write(\"Run the MCP server with: npx @monadeo.com/grimoire-mcp\" + (args.bools.has(\"http\") ? \" --http\\n\" : \"\\n\"));\n return EXIT.ok;\n case undefined:\n case \"help\":\n case \"--help\":\n process.stdout.write(HELP);\n return EXIT.ok;\n }\n\n const client = new GrimoireClient();\n try {\n switch (command) {\n case \"whoami\": {\n if (process.env.GRIMOIRE_AUTH_TOKEN) {\n process.stdout.write(\"machine token configured (GRIMOIRE_AUTH_TOKEN)\\n\");\n return EXIT.ok;\n }\n if (!readRefreshToken()) {\n process.stderr.write(\"not logged in \u2014 run `grimoire login`\\n\");\n return EXIT.authRequired;\n }\n try {\n await client.refreshSession();\n process.stdout.write(\"logged in (browser session)\\n\");\n return EXIT.ok;\n } catch (err) {\n const reason = err instanceof ApiError ? err.code : (err as Error).message;\n process.stderr.write(`not logged in (${reason}) \u2014 run \\`grimoire login\\`\\n`);\n return EXIT.authRequired;\n }\n }\n case \"search\": {\n const query = args.positionals[0];\n if (!query) {\n process.stderr.write(\"Usage: grimoire search \\\"<query>\\\" -s <source>\\n\");\n return EXIT.apiError;\n }\n const explicit = parseSourceFlags(args.flags.source);\n const sources = explicit.length > 0 ? explicit : resolveDefaultSources();\n if (sources.length === 0) {\n process.stderr.write(\"No sources. Pass -s <source> or run `grimoire init`.\\n\");\n return EXIT.apiError;\n }\n const res = await client.search({\n query,\n sources,\n language: args.flags.lang?.[0],\n top_k: intFlag(args, \"top-k\"),\n });\n if (json) process.stdout.write(JSON.stringify(res, null, 2) + \"\\n\");\n else if (args.bools.has(\"compact\")) printCompact(res.results, res.confidence);\n else printResults(res.results, res.confidence);\n return EXIT.ok;\n }\n case \"sources\": {\n const res = await client.listSources(args.flags.q?.[0]);\n process.stdout.write(JSON.stringify(res.sources ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"versions\": {\n const source = requirePositional(args, 0, \"Usage: grimoire versions <source> [--json]\");\n const res = await client.listVersions(source);\n process.stdout.write(JSON.stringify(res.versions ?? [], null, json ? 2 : 0) + \"\\n\");\n return EXIT.ok;\n }\n case \"doc\": {\n const chunkId = requirePositional(args, 0, \"Usage: grimoire doc <chunk_id> [--window 2]\");\n const window = intFlag(args, \"window\", { min: 0, max: 5 }) ?? 2;\n const res = await client.getContext(chunkId, window);\n process.stdout.write(JSON.stringify(res.chunks ?? [], null, 2) + \"\\n\");\n return EXIT.ok;\n }\n case \"report\": {\n const usage = 'Usage: grimoire report <chunk_id> --verdict helpful|incorrect|outdated [--note \"...\"]';\n const chunkId = requirePositional(args, 0, usage);\n const verdict = requireFlagOneOf(args, \"verdict\", [\"helpful\", \"incorrect\", \"outdated\"], usage);\n await client.reportResult(chunkId, verdict, args.flags.note?.[0]);\n process.stdout.write(\"Reported.\\n\");\n return EXIT.ok;\n }\n case \"ingest\": {\n const url = requirePositional(\n args,\n 0,\n \"Usage: grimoire ingest <url> [--version 15.2] [--private] [--webhook URL] [--watch]\",\n );\n const res = await client.submitSource({\n url,\n version: args.flags.version?.[0],\n visibility: args.bools.has(\"private\") ? \"private\" : \"public\",\n webhook_url: args.flags.webhook?.[0],\n });\n process.stdout.write(`Job: ${res.job_id}\\n`);\n if (args.bools.has(\"watch\")) return watchJob(client, res.job_id);\n return EXIT.ok;\n }\n case \"jobs\": {\n const jobId = requirePositional(args, 0, \"Usage: grimoire jobs <job_id> [--watch]\");\n return args.bools.has(\"watch\") ? watchJob(client, jobId) : printJob(client, jobId);\n }\n default:\n process.stderr.write(`Unknown command: ${command}\\n${HELP}`);\n return EXIT.apiError;\n }\n } catch (err) {\n if (err instanceof ApiError) {\n process.stderr.write(`error: ${err.code}\\n`);\n if (err.status === 401) return EXIT.authRequired;\n if (err.status === 429) return EXIT.quota;\n if (err.status === 404) return EXIT.notFound;\n return EXIT.apiError;\n }\n throw err;\n }\n}\n\nconst TERMINAL_STATUSES = [\"complete\", \"failed\", \"rejected\"];\nconst FAILED_STATUSES = [\"failed\", \"rejected\"];\n\nasync function printJob(client: GrimoireClient, jobId: string): Promise<number> {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n return FAILED_STATUSES.includes(status) ? EXIT.apiError : EXIT.ok;\n}\n\nconst WATCH_POLL_MS = 5_000;\nconst WATCH_BACKOFF_CAP_MS = 30_000;\nconst WATCH_DEADLINE_MS = 30 * 60_000;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nasync function watchJob(client: GrimoireClient, jobId: string): Promise<number> {\n const deadline = Date.now() + WATCH_DEADLINE_MS;\n let backoff = WATCH_POLL_MS;\n while (Date.now() < deadline) {\n try {\n const job = await client.getJob(jobId);\n const status = job.status ?? \"unknown\";\n process.stdout.write(`${status} ${JSON.stringify(job.counters ?? {})}\\n`);\n if (TERMINAL_STATUSES.includes(status)) {\n return FAILED_STATUSES.includes(status) ? EXIT.apiError : EXIT.ok;\n }\n backoff = WATCH_POLL_MS;\n await sleep(WATCH_POLL_MS);\n } catch (err) {\n // Auth/permission/missing-job failures cannot heal on their own \u2014 bail out;\n // anything else (network, 5xx, timeout) is worth retrying with backoff.\n if (err instanceof ApiError && [401, 403, 404].includes(err.status)) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n process.stderr.write(`poll failed (${reason}); retrying in ${backoff / 1000}s\\n`);\n await sleep(backoff);\n backoff = Math.min(backoff * 2, WATCH_BACKOFF_CAP_MS);\n }\n }\n process.stderr.write(\n `Watch deadline (30m) reached; the job is still running. Check later with: grimoire jobs ${jobId}\\n`,\n );\n return EXIT.apiError;\n}\n\nmain(process.argv.slice(2))\n .then((code) => process.exit(code))\n .catch((err) => {\n if (err instanceof UsageError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(EXIT.apiError);\n }\n process.stderr.write(`fatal: ${(err as Error).message}\\n`);\n process.exit(EXIT.apiError);\n });\n", "import { readFileSync, existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n// Bare origin \u2014 API paths are absolute (/v1/..., /auth/cli/...), so the base must\n// never carry a path prefix or auth-broker URLs would be built wrong.\nexport const DEFAULT_API_BASE = \"https://grimoire-api.monadeo.com\";\nfunction globalConfigPath() {\n return join(process.env.XDG_CONFIG_HOME ?? join(homedir(), \".config\"), \"grimoire\", \"config.json\");\n}\n// Malformed config must never crash a consumer (the MCP server constructs a client\n// at import time): warn and behave as if the file were absent.\nfunction readJsonConfig(path) {\n try {\n return JSON.parse(readFileSync(path, \"utf8\"));\n }\n catch (err) {\n process.stderr.write(`grimoire: ignoring malformed config at ${path}: ${err.message}\\n`);\n return undefined;\n }\n}\nexport function loadGlobalConfig() {\n const path = globalConfigPath();\n const base = { apiBaseUrl: process.env.GRIMOIRE_API_URL ?? DEFAULT_API_BASE };\n if (!existsSync(path))\n return base;\n const overrides = readJsonConfig(path);\n return overrides ? { ...base, ...overrides } : base;\n}\nexport function saveGlobalConfig(config) {\n const path = globalConfigPath();\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(config, null, 2));\n}\n// Project config (.grimoire.json in the repo root) pins a codebase's sources and\n// overrides globals \u2014 committed alongside the code it documents.\nexport function findProjectConfig(startDir = process.cwd()) {\n let dir = startDir;\n for (;;) {\n const candidate = join(dir, \".grimoire.json\");\n if (existsSync(candidate)) {\n const parsed = readJsonConfig(candidate);\n if (parsed)\n return parsed;\n }\n const parent = dirname(dir);\n if (parent === dir)\n return undefined;\n dir = parent;\n }\n}\nexport function resolveDefaultSources() {\n return findProjectConfig()?.sources ?? loadGlobalConfig().defaultSources ?? [];\n}\n", "import { createHash, randomBytes } from \"node:crypto\";\nimport { 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\"]);\n\nexport function parseArgs(argv: string[], aliases: Record<string, string> = {}): ParsedArgs {\n const positionals: string[] = [];\n const flags: Record<string, string[]> = {};\n const bools = new Set<string>();\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg.startsWith(\"--\") || arg.startsWith(\"-\")) {\n const name = aliases[arg] ?? arg.replace(/^--?/, \"\");\n if (BOOL_FLAGS.has(name)) {\n bools.add(name);\n } else {\n const value = argv[i + 1];\n if (value === undefined || value.startsWith(\"-\")) {\n throw new UsageError(`Flag ${arg} requires a value`);\n }\n (flags[name] ??= []).push(value);\n i++;\n }\n } else {\n positionals.push(arg);\n }\n }\n return { positionals, flags, bools };\n}\n\nexport function requirePositional(parsed: ParsedArgs, index: number, usage: string): string {\n const value = parsed.positionals[index];\n if (value === undefined) throw new UsageError(usage);\n return value;\n}\n\nexport function intFlag(\n parsed: ParsedArgs,\n name: string,\n range?: { min: number; max: number },\n): number | undefined {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined) return undefined;\n const value = Number(raw);\n if (!Number.isInteger(value)) throw new UsageError(`Flag --${name} must be an integer`);\n if (range && (value < range.min || value > range.max)) {\n throw new UsageError(`Flag --${name} must be between ${range.min} and ${range.max}`);\n }\n return value;\n}\n\nexport function requireFlagOneOf(\n parsed: ParsedArgs,\n name: string,\n allowed: readonly string[],\n usage: string,\n): string {\n const raw = parsed.flags[name]?.[0];\n if (raw === undefined || !allowed.includes(raw)) throw new UsageError(usage);\n return raw;\n}\n", "import type { SearchResultChunk } from \"@monadeo.com/grimoire-core\";\n\n// Exit codes documented for scripting (clients spec).\nexport const EXIT = { ok: 0, apiError: 1, authRequired: 2, quota: 3, notFound: 4 } as const;\n\nfunction warnWeak(confidence: string): void {\n if (confidence === \"weak\") {\n process.stderr.write(\n \"note: low-confidence results \u2014 the docs may not cover this; tell the user rather than guessing.\\n\",\n );\n }\n}\n\nexport function printResults(results: SearchResultChunk[], confidence: string): void {\n warnWeak(confidence);\n for (const r of results) {\n const path = (r.heading_path ?? []).join(\" \u203A \");\n process.stdout.write(`\\n${r.score.toFixed(3)} ${r.source}@${r.version} ${path}\\n${r.origin_url}\\n`);\n const preview = r.text.length > 500 ? `${r.text.slice(0, 500)}\u2026` : r.text;\n process.stdout.write(`${preview}\\n`);\n }\n}\n\n// The weak-confidence note goes to stderr in compact mode too \u2014 SKILL.md steers\n// agents to --compact, and the \"don't guess\" signal must survive that path.\nexport function printCompact(results: SearchResultChunk[], confidence: string): void {\n warnWeak(confidence);\n for (const r of results) {\n process.stdout.write(\n `${r.score.toFixed(3)} | ${r.source}@${r.version} | ${(r.heading_path ?? []).join(\" \u203A \")} | ${r.origin_url}\\n`,\n );\n }\n}\n", "import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\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"],
5
+ "mappings": "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",
6
+ "names": ["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"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monadeo.com/grimoire-cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
@@ -9,13 +9,10 @@
9
9
  "files": [
10
10
  "dist"
11
11
  ],
12
- "dependencies": {
13
- "@napi-rs/keyring": "^1.3.0"
14
- },
15
12
  "devDependencies": {
16
13
  "@types/node": "^26.1.0",
17
14
  "esbuild": "^0.28.1",
18
- "@monadeo.com/grimoire-core": "0.2.0"
15
+ "@monadeo.com/grimoire-core": "0.2.2"
19
16
  },
20
17
  "description": "Grimoire CLI — version-correct documentation retrieval for AI coding agents",
21
18
  "homepage": "https://grimoire.monadeo.com",