chain-insights 0.3.7 → 0.3.11

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.
Files changed (56) hide show
  1. package/README.md +5 -0
  2. package/dist/{app-BxojXjtB.cjs → app-DjJn3irw.cjs} +1 -1
  3. package/dist/{app-CRd39JJ8.mjs → app-norpwdou.mjs} +2 -2
  4. package/dist/{app-CRd39JJ8.mjs.map → app-norpwdou.mjs.map} +1 -1
  5. package/dist/{artifact-server-XbN16DwU.cjs → artifact-server-C6_gtIql.cjs} +1 -1
  6. package/dist/{artifact-server-CP6LXQ9d.mjs → artifact-server-DHPM0lxS.mjs} +2 -2
  7. package/dist/{artifact-server-CP6LXQ9d.mjs.map → artifact-server-DHPM0lxS.mjs.map} +1 -1
  8. package/dist/{capabilities-BC3Y5EOi.mjs → capabilities-BCvkTkIu.mjs} +3 -6
  9. package/dist/capabilities-BCvkTkIu.mjs.map +1 -0
  10. package/dist/{capabilities-D5PSx9Hj.cjs → capabilities-DOa6EFO-.cjs} +2 -5
  11. package/dist/cli.cjs +58 -31
  12. package/dist/cli.mjs +58 -31
  13. package/dist/cli.mjs.map +1 -1
  14. package/dist/{client-D4JE7fFF.mjs → client-BgmHjBHQ.mjs} +15 -7
  15. package/dist/client-BgmHjBHQ.mjs.map +1 -0
  16. package/dist/{client-Db6IV1tv.cjs → client-Y_zqKqJT.cjs} +19 -5
  17. package/dist/{config-Drgc2HuF.mjs → config-C6zM8Xir.mjs} +3 -3
  18. package/dist/{config-Drgc2HuF.mjs.map → config-C6zM8Xir.mjs.map} +1 -1
  19. package/dist/{config-BwVx19Og.cjs → config-CkW404Cs.cjs} +2 -2
  20. package/dist/index.cjs +4 -4
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.mts.map +1 -1
  23. package/dist/index.mjs +4 -4
  24. package/dist/{init-CKQ6F07J.mjs → init-uAmPfio2.mjs} +2 -2
  25. package/dist/{init-CKQ6F07J.mjs.map → init-uAmPfio2.mjs.map} +1 -1
  26. package/dist/{init-Dhw8F23z.cjs → init-vj2v5PMP.cjs} +1 -1
  27. package/dist/{mcp-endpoint-DHs1cRFH.mjs → mcp-endpoint-QQ5Lbqc2.mjs} +5 -2
  28. package/dist/mcp-endpoint-QQ5Lbqc2.mjs.map +1 -0
  29. package/dist/{mcp-endpoint-BaV8h_lq.cjs → mcp-endpoint-cQIZSjkK.cjs} +4 -1
  30. package/dist/mcp-proxy.cjs +444 -410
  31. package/dist/mcp-proxy.d.cts +3 -1
  32. package/dist/mcp-proxy.d.cts.map +1 -1
  33. package/dist/mcp-proxy.d.mts +3 -1
  34. package/dist/mcp-proxy.d.mts.map +1 -1
  35. package/dist/mcp-proxy.mjs +444 -411
  36. package/dist/mcp-proxy.mjs.map +1 -1
  37. package/dist/{public-tools-xfVNz9NE.cjs → public-tools-BY3PTw6x.cjs} +59 -31
  38. package/dist/{public-tools-CyUZEz9B.mjs → public-tools-CvlZcysd.mjs} +60 -32
  39. package/dist/public-tools-CvlZcysd.mjs.map +1 -0
  40. package/dist/{runner-DWuSy1Se.mjs → runner-B9fXAP0t.mjs} +3 -3
  41. package/dist/{runner-DWuSy1Se.mjs.map → runner-B9fXAP0t.mjs.map} +1 -1
  42. package/dist/{runner-CVo41fjz.cjs → runner-CcZCrrkn.cjs} +2 -2
  43. package/dist/{schema-BFEWhzg7.mjs → schema-D_qwaQA5.mjs} +2 -2
  44. package/dist/{schema-BFEWhzg7.mjs.map → schema-D_qwaQA5.mjs.map} +1 -1
  45. package/dist/{schema-Vl9yuOFO.cjs → schema-Dr6JXSOF.cjs} +1 -1
  46. package/dist/{server-BXLX2j_A.mjs → server-86dyCsJO.mjs} +2 -2
  47. package/dist/{server-BXLX2j_A.mjs.map → server-86dyCsJO.mjs.map} +1 -1
  48. package/dist/{server-BqVdWath.cjs → server-B2NFmnCM.cjs} +1 -1
  49. package/dist/update-BJoXYucO.cjs +145 -0
  50. package/dist/update-CJUfGCxs.mjs +145 -0
  51. package/dist/update-CJUfGCxs.mjs.map +1 -0
  52. package/package.json +1 -1
  53. package/dist/capabilities-BC3Y5EOi.mjs.map +0 -1
  54. package/dist/client-D4JE7fFF.mjs.map +0 -1
  55. package/dist/mcp-endpoint-DHs1cRFH.mjs.map +0 -1
  56. package/dist/public-tools-CyUZEz9B.mjs.map +0 -1
package/README.md CHANGED
@@ -35,8 +35,13 @@ Check the CLI:
35
35
 
36
36
  ```bash
37
37
  cia --version
38
+ cia update --check
38
39
  ```
39
40
 
41
+ Run `cia update` to update a global npm install from the public npmjs registry.
42
+ `cia init` also checks for a newer npm release in interactive terminals and
43
+ prompts before updating.
44
+
40
45
  From a local checkout:
41
46
 
42
47
  ```bash
@@ -100,7 +100,7 @@ function createApp() {
100
100
  ts: Date.now()
101
101
  }));
102
102
  app.get("/status", async (c) => {
103
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
103
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
104
104
  const config = await loadConfig();
105
105
  return c.json({
106
106
  dataDir: config.dataDir,
@@ -97,7 +97,7 @@ function createApp() {
97
97
  ts: Date.now()
98
98
  }));
99
99
  app.get("/status", async (c) => {
100
- const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
100
+ const { loadConfig } = await import("./config-C6zM8Xir.mjs").then((n) => n.t);
101
101
  const config = await loadConfig();
102
102
  return c.json({
103
103
  dataDir: config.dataDir,
@@ -152,4 +152,4 @@ function createApp() {
152
152
  //#endregion
153
153
  export { createApp as t };
154
154
 
155
- //# sourceMappingURL=app-CRd39JJ8.mjs.map
155
+ //# sourceMappingURL=app-norpwdou.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"app-CRd39JJ8.mjs","names":[],"sources":["../src/server/app.ts"],"sourcesContent":["import { Hono } from 'hono'\nimport { lstat, readFile, readdir, realpath } from 'node:fs/promises'\nimport path from 'node:path'\nimport os from 'node:os'\n\nconst WORKSPACE_TREE_ROOTS = ['cases', 'reports', '.chain-insights/schema']\nconst WORKSPACE_TREE_MAX_DEPTH = 4\n\ninterface WorkspaceTreeEntry {\n path: string\n type: 'file' | 'directory' | 'symlink'\n size?: number\n}\n\nfunction withinRoot(root: string, target: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(target))\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))\n}\n\nasync function realPathWithinRoot(root: string, target: string): Promise<boolean> {\n try {\n const [realRoot, realTarget] = await Promise.all([realpath(root), realpath(target)])\n return withinRoot(realRoot, realTarget)\n } catch {\n return false\n }\n}\n\nfunction toWorkspaceRelative(root: string, target: string): string {\n return path.relative(root, target).split(path.sep).join('/')\n}\n\nasync function listWorkspaceEntries(\n workspaceRoot: string,\n roots = WORKSPACE_TREE_ROOTS,\n maxDepth = WORKSPACE_TREE_MAX_DEPTH\n): Promise<WorkspaceTreeEntry[]> {\n const entries: WorkspaceTreeEntry[] = []\n const root = path.resolve(workspaceRoot)\n\n async function visit(target: string, depth: number): Promise<void> {\n const resolved = path.resolve(target)\n if (!withinRoot(root, resolved)) return\n\n let info: Awaited<ReturnType<typeof lstat>>\n try {\n info = await lstat(resolved)\n } catch {\n return\n }\n\n const type = info.isSymbolicLink() ? 'symlink' : info.isDirectory() ? 'directory' : info.isFile() ? 'file' : null\n if (!type) return\n\n const entry: WorkspaceTreeEntry = {\n path: toWorkspaceRelative(root, resolved),\n type,\n }\n if (type === 'file') entry.size = info.size\n entries.push(entry)\n\n if (type !== 'directory' || depth >= maxDepth) return\n if (!await realPathWithinRoot(root, resolved)) return\n\n let children: string[]\n try {\n children = await readdir(resolved)\n } catch {\n return\n }\n\n for (const child of children.sort()) {\n await visit(path.join(resolved, child), depth + 1)\n }\n }\n\n for (const rootName of roots) {\n const target = path.resolve(root, rootName)\n if (withinRoot(root, target)) await visit(target, 0)\n }\n\n return entries\n}\n\nasync function findVizHtml(vizId: string): Promise<string | null> {\n const home = os.homedir()\n const filename = `${vizId}.html`\n\n // 1. Check central standalone directory first (fast, single path)\n const centralPath = path.join(home, '.chain-insights', 'viz', filename)\n try {\n return await readFile(centralPath, 'utf-8')\n } catch { /* not found here, continue */ }\n\n // 2. Check per-case directory using vizId prefix (case-based vizs use <caseId>_<timestamp>)\n // The vizId for case-based vizs is formatted as <case-id>_<timestamp>,\n // so extract the case-id prefix to check its directory first.\n const underscoreIdx = vizId.lastIndexOf('_')\n if (underscoreIdx > 0) {\n const possibleCaseId = vizId.substring(0, underscoreIdx)\n const casePath = path.join(home, '.chain-insights', 'cases', possibleCaseId, 'viz', filename)\n try {\n return await readFile(casePath, 'utf-8')\n } catch { /* not found here, continue */ }\n }\n\n // 3. Fallback: scan all case directories (CONTEXT.md: ~/.chain-insights/cases/<case-id>/viz/)\n const casesDir = path.join(home, '.chain-insights', 'cases')\n try {\n const cases = await readdir(casesDir)\n for (const caseId of cases) {\n const casePath = path.join(casesDir, caseId, 'viz', filename)\n try {\n return await readFile(casePath, 'utf-8')\n } catch { /* not in this case dir */ }\n }\n } catch { /* cases dir doesn't exist */ }\n\n return null\n}\n\nfunction isSafeGraphReportFilename(filename: string): boolean {\n return (\n filename.endsWith('.graph.json') &&\n /^[A-Za-z0-9._-]+$/.test(filename) &&\n !filename.includes('..') &&\n !filename.includes('/') &&\n !filename.includes('\\\\')\n )\n}\n\nexport function createApp(): Hono {\n const app = new Hono()\n\n app.get('/health', (c) => c.json({ ok: true, ts: Date.now() }))\n\n app.get('/status', async (c) => {\n const { loadConfig } = await import('../config/index.js')\n const config = await loadConfig()\n return c.json({\n dataDir: config.dataDir,\n graphMcpMode: config.graphMcpMode,\n server: 'running',\n })\n })\n\n app.get('/viz/:id', async (c) => {\n const id = c.req.param('id')\n if (!/^[a-zA-Z0-9_-]+$/.test(id)) {\n return c.json({ error: 'Invalid visualization ID' }, 400)\n }\n const html = await findVizHtml(id)\n if (!html) {\n return c.json({ error: 'Visualization not found' }, 404)\n }\n return c.html(html)\n })\n\n app.get('/graph-reports/:filename', async (c) => {\n const filename = c.req.param('filename')\n if (!isSafeGraphReportFilename(filename)) {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n }\n\n const { workspaceOutputPaths } = await import('../workspace/output-root.js')\n const paths = workspaceOutputPaths()\n const graphPath = path.resolve(paths.reportGraphsRoot, filename)\n if (!withinRoot(paths.reportGraphsRoot, graphPath)) {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n }\n if (!await realPathWithinRoot(paths.reportGraphsRoot, graphPath)) {\n return c.json({ error: 'Graph report not found' }, 404)\n }\n\n try {\n const graph = await readFile(graphPath, 'utf-8')\n return c.body(graph, 200, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n } catch {\n return c.json({ error: 'Graph report not found' }, 404)\n }\n })\n\n app.get('/graph-reports/*', (c) => {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n })\n\n app.get('/workspace/tree', async (c) => {\n const { workspaceOutputPaths } = await import('../workspace/output-root.js')\n const paths = workspaceOutputPaths()\n const entries = await listWorkspaceEntries(paths.root, WORKSPACE_TREE_ROOTS)\n return c.json({\n schema: 'chain-insights.workspace-tree.v1',\n root: paths.root,\n entries,\n })\n })\n\n app.onError((err, c) => {\n console.error(err)\n return c.json({ error: 'Internal server error' }, 500)\n })\n\n return app\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"app-norpwdou.mjs","names":[],"sources":["../src/server/app.ts"],"sourcesContent":["import { Hono } from 'hono'\nimport { lstat, readFile, readdir, realpath } from 'node:fs/promises'\nimport path from 'node:path'\nimport os from 'node:os'\n\nconst WORKSPACE_TREE_ROOTS = ['cases', 'reports', '.chain-insights/schema']\nconst WORKSPACE_TREE_MAX_DEPTH = 4\n\ninterface WorkspaceTreeEntry {\n path: string\n type: 'file' | 'directory' | 'symlink'\n size?: number\n}\n\nfunction withinRoot(root: string, target: string): boolean {\n const relative = path.relative(path.resolve(root), path.resolve(target))\n return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))\n}\n\nasync function realPathWithinRoot(root: string, target: string): Promise<boolean> {\n try {\n const [realRoot, realTarget] = await Promise.all([realpath(root), realpath(target)])\n return withinRoot(realRoot, realTarget)\n } catch {\n return false\n }\n}\n\nfunction toWorkspaceRelative(root: string, target: string): string {\n return path.relative(root, target).split(path.sep).join('/')\n}\n\nasync function listWorkspaceEntries(\n workspaceRoot: string,\n roots = WORKSPACE_TREE_ROOTS,\n maxDepth = WORKSPACE_TREE_MAX_DEPTH\n): Promise<WorkspaceTreeEntry[]> {\n const entries: WorkspaceTreeEntry[] = []\n const root = path.resolve(workspaceRoot)\n\n async function visit(target: string, depth: number): Promise<void> {\n const resolved = path.resolve(target)\n if (!withinRoot(root, resolved)) return\n\n let info: Awaited<ReturnType<typeof lstat>>\n try {\n info = await lstat(resolved)\n } catch {\n return\n }\n\n const type = info.isSymbolicLink() ? 'symlink' : info.isDirectory() ? 'directory' : info.isFile() ? 'file' : null\n if (!type) return\n\n const entry: WorkspaceTreeEntry = {\n path: toWorkspaceRelative(root, resolved),\n type,\n }\n if (type === 'file') entry.size = info.size\n entries.push(entry)\n\n if (type !== 'directory' || depth >= maxDepth) return\n if (!await realPathWithinRoot(root, resolved)) return\n\n let children: string[]\n try {\n children = await readdir(resolved)\n } catch {\n return\n }\n\n for (const child of children.sort()) {\n await visit(path.join(resolved, child), depth + 1)\n }\n }\n\n for (const rootName of roots) {\n const target = path.resolve(root, rootName)\n if (withinRoot(root, target)) await visit(target, 0)\n }\n\n return entries\n}\n\nasync function findVizHtml(vizId: string): Promise<string | null> {\n const home = os.homedir()\n const filename = `${vizId}.html`\n\n // 1. Check central standalone directory first (fast, single path)\n const centralPath = path.join(home, '.chain-insights', 'viz', filename)\n try {\n return await readFile(centralPath, 'utf-8')\n } catch { /* not found here, continue */ }\n\n // 2. Check per-case directory using vizId prefix (case-based vizs use <caseId>_<timestamp>)\n // The vizId for case-based vizs is formatted as <case-id>_<timestamp>,\n // so extract the case-id prefix to check its directory first.\n const underscoreIdx = vizId.lastIndexOf('_')\n if (underscoreIdx > 0) {\n const possibleCaseId = vizId.substring(0, underscoreIdx)\n const casePath = path.join(home, '.chain-insights', 'cases', possibleCaseId, 'viz', filename)\n try {\n return await readFile(casePath, 'utf-8')\n } catch { /* not found here, continue */ }\n }\n\n // 3. Fallback: scan all case directories (CONTEXT.md: ~/.chain-insights/cases/<case-id>/viz/)\n const casesDir = path.join(home, '.chain-insights', 'cases')\n try {\n const cases = await readdir(casesDir)\n for (const caseId of cases) {\n const casePath = path.join(casesDir, caseId, 'viz', filename)\n try {\n return await readFile(casePath, 'utf-8')\n } catch { /* not in this case dir */ }\n }\n } catch { /* cases dir doesn't exist */ }\n\n return null\n}\n\nfunction isSafeGraphReportFilename(filename: string): boolean {\n return (\n filename.endsWith('.graph.json') &&\n /^[A-Za-z0-9._-]+$/.test(filename) &&\n !filename.includes('..') &&\n !filename.includes('/') &&\n !filename.includes('\\\\')\n )\n}\n\nexport function createApp(): Hono {\n const app = new Hono()\n\n app.get('/health', (c) => c.json({ ok: true, ts: Date.now() }))\n\n app.get('/status', async (c) => {\n const { loadConfig } = await import('../config/index.js')\n const config = await loadConfig()\n return c.json({\n dataDir: config.dataDir,\n graphMcpMode: config.graphMcpMode,\n server: 'running',\n })\n })\n\n app.get('/viz/:id', async (c) => {\n const id = c.req.param('id')\n if (!/^[a-zA-Z0-9_-]+$/.test(id)) {\n return c.json({ error: 'Invalid visualization ID' }, 400)\n }\n const html = await findVizHtml(id)\n if (!html) {\n return c.json({ error: 'Visualization not found' }, 404)\n }\n return c.html(html)\n })\n\n app.get('/graph-reports/:filename', async (c) => {\n const filename = c.req.param('filename')\n if (!isSafeGraphReportFilename(filename)) {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n }\n\n const { workspaceOutputPaths } = await import('../workspace/output-root.js')\n const paths = workspaceOutputPaths()\n const graphPath = path.resolve(paths.reportGraphsRoot, filename)\n if (!withinRoot(paths.reportGraphsRoot, graphPath)) {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n }\n if (!await realPathWithinRoot(paths.reportGraphsRoot, graphPath)) {\n return c.json({ error: 'Graph report not found' }, 404)\n }\n\n try {\n const graph = await readFile(graphPath, 'utf-8')\n return c.body(graph, 200, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n } catch {\n return c.json({ error: 'Graph report not found' }, 404)\n }\n })\n\n app.get('/graph-reports/*', (c) => {\n return c.json({ error: 'Invalid graph report filename' }, 400)\n })\n\n app.get('/workspace/tree', async (c) => {\n const { workspaceOutputPaths } = await import('../workspace/output-root.js')\n const paths = workspaceOutputPaths()\n const entries = await listWorkspaceEntries(paths.root, WORKSPACE_TREE_ROOTS)\n return c.json({\n schema: 'chain-insights.workspace-tree.v1',\n root: paths.root,\n entries,\n })\n })\n\n app.onError((err, c) => {\n console.error(err)\n return c.json({ error: 'Internal server error' }, 500)\n })\n\n return app\n}\n"],"mappings":";;;;;AAKA,MAAM,uBAAuB;CAAC;CAAS;CAAW;AAAwB;AAC1E,MAAM,2BAA2B;AAQjC,SAAS,WAAW,MAAc,QAAyB;CACzD,MAAM,WAAW,KAAK,SAAS,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,MAAM,CAAC;CACvE,OAAO,aAAa,MAAO,CAAC,SAAS,WAAW,IAAI,KAAK,CAAC,KAAK,WAAW,QAAQ;AACpF;AAEA,eAAe,mBAAmB,MAAc,QAAkC;CAChF,IAAI;EACF,MAAM,CAAC,UAAU,cAAc,MAAM,QAAQ,IAAI,CAAC,SAAS,IAAI,GAAG,SAAS,MAAM,CAAC,CAAC;EACnF,OAAO,WAAW,UAAU,UAAU;CACxC,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,oBAAoB,MAAc,QAAwB;CACjE,OAAO,KAAK,SAAS,MAAM,MAAM,EAAE,MAAM,KAAK,GAAG,EAAE,KAAK,GAAG;AAC7D;AAEA,eAAe,qBACb,eACA,QAAQ,sBACR,WAAW,0BACoB;CAC/B,MAAM,UAAgC,CAAC;CACvC,MAAM,OAAO,KAAK,QAAQ,aAAa;CAEvC,eAAe,MAAM,QAAgB,OAA8B;EACjE,MAAM,WAAW,KAAK,QAAQ,MAAM;EACpC,IAAI,CAAC,WAAW,MAAM,QAAQ,GAAG;EAEjC,IAAI;EACJ,IAAI;GACF,OAAO,MAAM,MAAM,QAAQ;EAC7B,QAAQ;GACN;EACF;EAEA,MAAM,OAAO,KAAK,eAAe,IAAI,YAAY,KAAK,YAAY,IAAI,cAAc,KAAK,OAAO,IAAI,SAAS;EAC7G,IAAI,CAAC,MAAM;EAEX,MAAM,QAA4B;GAChC,MAAM,oBAAoB,MAAM,QAAQ;GACxC;EACF;EACA,IAAI,SAAS,QAAQ,MAAM,OAAO,KAAK;EACvC,QAAQ,KAAK,KAAK;EAElB,IAAI,SAAS,eAAe,SAAS,UAAU;EAC/C,IAAI,CAAC,MAAM,mBAAmB,MAAM,QAAQ,GAAG;EAE/C,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,QAAQ,QAAQ;EACnC,QAAQ;GACN;EACF;EAEA,KAAK,MAAM,SAAS,SAAS,KAAK,GAChC,MAAM,MAAM,KAAK,KAAK,UAAU,KAAK,GAAG,QAAQ,CAAC;CAErD;CAEA,KAAK,MAAM,YAAY,OAAO;EAC5B,MAAM,SAAS,KAAK,QAAQ,MAAM,QAAQ;EAC1C,IAAI,WAAW,MAAM,MAAM,GAAG,MAAM,MAAM,QAAQ,CAAC;CACrD;CAEA,OAAO;AACT;AAEA,eAAe,YAAY,OAAuC;CAChE,MAAM,OAAO,GAAG,QAAQ;CACxB,MAAM,WAAW,GAAG,MAAM;CAG1B,MAAM,cAAc,KAAK,KAAK,MAAM,mBAAmB,OAAO,QAAQ;CACtE,IAAI;EACF,OAAO,MAAM,SAAS,aAAa,OAAO;CAC5C,QAAQ,CAAiC;CAKzC,MAAM,gBAAgB,MAAM,YAAY,GAAG;CAC3C,IAAI,gBAAgB,GAAG;EACrB,MAAM,iBAAiB,MAAM,UAAU,GAAG,aAAa;EACvD,MAAM,WAAW,KAAK,KAAK,MAAM,mBAAmB,SAAS,gBAAgB,OAAO,QAAQ;EAC5F,IAAI;GACF,OAAO,MAAM,SAAS,UAAU,OAAO;EACzC,QAAQ,CAAiC;CAC3C;CAGA,MAAM,WAAW,KAAK,KAAK,MAAM,mBAAmB,OAAO;CAC3D,IAAI;EACF,MAAM,QAAQ,MAAM,QAAQ,QAAQ;EACpC,KAAK,MAAM,UAAU,OAAO;GAC1B,MAAM,WAAW,KAAK,KAAK,UAAU,QAAQ,OAAO,QAAQ;GAC5D,IAAI;IACF,OAAO,MAAM,SAAS,UAAU,OAAO;GACzC,QAAQ,CAA6B;EACvC;CACF,QAAQ,CAAgC;CAExC,OAAO;AACT;AAEA,SAAS,0BAA0B,UAA2B;CAC5D,OACE,SAAS,SAAS,aAAa,KAC/B,oBAAoB,KAAK,QAAQ,KACjC,CAAC,SAAS,SAAS,IAAI,KACvB,CAAC,SAAS,SAAS,GAAG,KACtB,CAAC,SAAS,SAAS,IAAI;AAE3B;AAEA,SAAgB,YAAkB;CAChC,MAAM,MAAM,IAAI,KAAK;CAErB,IAAI,IAAI,YAAY,MAAM,EAAE,KAAK;EAAE,IAAI;EAAM,IAAI,KAAK,IAAI;CAAE,CAAC,CAAC;CAE9D,IAAI,IAAI,WAAW,OAAO,MAAM;EAC9B,MAAM,EAAE,eAAe,MAAM,OAAO,yBAAA,MAAA,MAAA,EAAA,CAAA;EACpC,MAAM,SAAS,MAAM,WAAW;EAChC,OAAO,EAAE,KAAK;GACZ,SAAS,OAAO;GAChB,cAAc,OAAO;GACrB,QAAQ;EACV,CAAC;CACH,CAAC;CAED,IAAI,IAAI,YAAY,OAAO,MAAM;EAC/B,MAAM,KAAK,EAAE,IAAI,MAAM,IAAI;EAC3B,IAAI,CAAC,mBAAmB,KAAK,EAAE,GAC7B,OAAO,EAAE,KAAK,EAAE,OAAO,2BAA2B,GAAG,GAAG;EAE1D,MAAM,OAAO,MAAM,YAAY,EAAE;EACjC,IAAI,CAAC,MACH,OAAO,EAAE,KAAK,EAAE,OAAO,0BAA0B,GAAG,GAAG;EAEzD,OAAO,EAAE,KAAK,IAAI;CACpB,CAAC;CAED,IAAI,IAAI,4BAA4B,OAAO,MAAM;EAC/C,MAAM,WAAW,EAAE,IAAI,MAAM,UAAU;EACvC,IAAI,CAAC,0BAA0B,QAAQ,GACrC,OAAO,EAAE,KAAK,EAAE,OAAO,gCAAgC,GAAG,GAAG;EAG/D,MAAM,EAAE,yBAAyB,MAAM,OAAO,8BAAA,MAAA,MAAA,EAAA,CAAA;EAC9C,MAAM,QAAQ,qBAAqB;EACnC,MAAM,YAAY,KAAK,QAAQ,MAAM,kBAAkB,QAAQ;EAC/D,IAAI,CAAC,WAAW,MAAM,kBAAkB,SAAS,GAC/C,OAAO,EAAE,KAAK,EAAE,OAAO,gCAAgC,GAAG,GAAG;EAE/D,IAAI,CAAC,MAAM,mBAAmB,MAAM,kBAAkB,SAAS,GAC7D,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;EAGxD,IAAI;GACF,MAAM,QAAQ,MAAM,SAAS,WAAW,OAAO;GAC/C,OAAO,EAAE,KAAK,OAAO,KAAK;IACxB,gBAAgB;IAChB,+BAA+B;GACjC,CAAC;EACH,QAAQ;GACN,OAAO,EAAE,KAAK,EAAE,OAAO,yBAAyB,GAAG,GAAG;EACxD;CACF,CAAC;CAED,IAAI,IAAI,qBAAqB,MAAM;EACjC,OAAO,EAAE,KAAK,EAAE,OAAO,gCAAgC,GAAG,GAAG;CAC/D,CAAC;CAED,IAAI,IAAI,mBAAmB,OAAO,MAAM;EACtC,MAAM,EAAE,yBAAyB,MAAM,OAAO,8BAAA,MAAA,MAAA,EAAA,CAAA;EAC9C,MAAM,QAAQ,qBAAqB;EACnC,MAAM,UAAU,MAAM,qBAAqB,MAAM,MAAM,oBAAoB;EAC3E,OAAO,EAAE,KAAK;GACZ,QAAQ;GACR,MAAM,MAAM;GACZ;EACF,CAAC;CACH,CAAC;CAED,IAAI,SAAS,KAAK,MAAM;EACtB,QAAQ,MAAM,GAAG;EACjB,OAAO,EAAE,KAAK,EAAE,OAAO,wBAAwB,GAAG,GAAG;CACvD,CAAC;CAED,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- const require_app = require("./app-BxojXjtB.cjs");
1
+ const require_app = require("./app-DjJn3irw.cjs");
2
2
  let _hono_node_server = require("@hono/node-server");
3
3
  let node_timers_promises = require("node:timers/promises");
4
4
  //#region src/mcp/artifact-server.ts
@@ -1,4 +1,4 @@
1
- import { t as createApp } from "./app-CRd39JJ8.mjs";
1
+ import { t as createApp } from "./app-norpwdou.mjs";
2
2
  import { serve } from "@hono/node-server";
3
3
  import { setTimeout as setTimeout$1 } from "node:timers/promises";
4
4
  //#region src/mcp/artifact-server.ts
@@ -45,4 +45,4 @@ async function ensureArtifactServer(port) {
45
45
  //#endregion
46
46
  export { ensureArtifactServer };
47
47
 
48
- //# sourceMappingURL=artifact-server-CP6LXQ9d.mjs.map
48
+ //# sourceMappingURL=artifact-server-DHPM0lxS.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-server-CP6LXQ9d.mjs","names":["delay"],"sources":["../src/mcp/artifact-server.ts"],"sourcesContent":["import { serve } from '@hono/node-server'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { createApp } from '../server/app.js'\n\ntype ArtifactServer = ReturnType<typeof serve>\n\nconst servers = new Map<number, ArtifactServer>()\n\nasync function isHealthy(port: number): Promise<boolean> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 500)\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: controller.signal,\n })\n return response.ok\n } catch {\n return false\n } finally {\n clearTimeout(timeout)\n }\n}\n\nasync function waitUntilHealthy(port: number): Promise<void> {\n for (let attempt = 0; attempt < 20; attempt += 1) {\n if (await isHealthy(port)) return\n await delay(50)\n }\n throw new Error(`Graph report server did not become healthy on 127.0.0.1:${port}`)\n}\n\nexport async function ensureArtifactServer(port: number): Promise<void> {\n if (servers.has(port)) return\n if (await isHealthy(port)) return\n\n const app = createApp()\n const server = serve({\n fetch: app.fetch,\n hostname: '127.0.0.1',\n port,\n })\n servers.set(port, server)\n server.on('error', (err) => {\n servers.delete(port)\n process.stderr.write(`Chain Insights graph report server failed on 127.0.0.1:${port}: ${(err as Error).message}\\n`)\n })\n\n try {\n await waitUntilHealthy(port)\n } catch (err) {\n servers.delete(port)\n server.close()\n throw err\n }\n}\n\nexport function closeArtifactServers(): void {\n for (const [port, server] of servers.entries()) {\n server.close()\n servers.delete(port)\n }\n}\n"],"mappings":";;;;AAMA,MAAM,0BAAU,IAAI,IAA4B;AAEhD,eAAe,UAAU,MAAgC;CACvD,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,UAAU,iBAAiB,WAAW,MAAM,GAAG,GAAG;CACxD,IAAI;EAIF,QAAO,MAHgB,MAAM,oBAAoB,KAAK,UAAU,EAC9D,QAAQ,WAAW,OACrB,CAAC,GACe;CAClB,QAAQ;EACN,OAAO;CACT,UAAU;EACR,aAAa,OAAO;CACtB;AACF;AAEA,eAAe,iBAAiB,MAA6B;CAC3D,KAAK,IAAI,UAAU,GAAG,UAAU,IAAI,WAAW,GAAG;EAChD,IAAI,MAAM,UAAU,IAAI,GAAG;EAC3B,MAAMA,aAAM,EAAE;CAChB;CACA,MAAM,IAAI,MAAM,2DAA2D,MAAM;AACnF;AAEA,eAAsB,qBAAqB,MAA6B;CACtE,IAAI,QAAQ,IAAI,IAAI,GAAG;CACvB,IAAI,MAAM,UAAU,IAAI,GAAG;CAG3B,MAAM,SAAS,MAAM;EACnB,OAFU,UAED,EAAE;EACX,UAAU;EACV;CACF,CAAC;CACD,QAAQ,IAAI,MAAM,MAAM;CACxB,OAAO,GAAG,UAAU,QAAQ;EAC1B,QAAQ,OAAO,IAAI;EACnB,QAAQ,OAAO,MAAM,0DAA0D,KAAK,IAAK,IAAc,QAAQ,GAAG;CACpH,CAAC;CAED,IAAI;EACF,MAAM,iBAAiB,IAAI;CAC7B,SAAS,KAAK;EACZ,QAAQ,OAAO,IAAI;EACnB,OAAO,MAAM;EACb,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"artifact-server-DHPM0lxS.mjs","names":["delay"],"sources":["../src/mcp/artifact-server.ts"],"sourcesContent":["import { serve } from '@hono/node-server'\nimport { setTimeout as delay } from 'node:timers/promises'\nimport { createApp } from '../server/app.js'\n\ntype ArtifactServer = ReturnType<typeof serve>\n\nconst servers = new Map<number, ArtifactServer>()\n\nasync function isHealthy(port: number): Promise<boolean> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 500)\n try {\n const response = await fetch(`http://127.0.0.1:${port}/health`, {\n signal: controller.signal,\n })\n return response.ok\n } catch {\n return false\n } finally {\n clearTimeout(timeout)\n }\n}\n\nasync function waitUntilHealthy(port: number): Promise<void> {\n for (let attempt = 0; attempt < 20; attempt += 1) {\n if (await isHealthy(port)) return\n await delay(50)\n }\n throw new Error(`Graph report server did not become healthy on 127.0.0.1:${port}`)\n}\n\nexport async function ensureArtifactServer(port: number): Promise<void> {\n if (servers.has(port)) return\n if (await isHealthy(port)) return\n\n const app = createApp()\n const server = serve({\n fetch: app.fetch,\n hostname: '127.0.0.1',\n port,\n })\n servers.set(port, server)\n server.on('error', (err) => {\n servers.delete(port)\n process.stderr.write(`Chain Insights graph report server failed on 127.0.0.1:${port}: ${(err as Error).message}\\n`)\n })\n\n try {\n await waitUntilHealthy(port)\n } catch (err) {\n servers.delete(port)\n server.close()\n throw err\n }\n}\n\nexport function closeArtifactServers(): void {\n for (const [port, server] of servers.entries()) {\n server.close()\n servers.delete(port)\n }\n}\n"],"mappings":";;;;AAMA,MAAM,0BAAU,IAAI,IAA4B;AAEhD,eAAe,UAAU,MAAgC;CACvD,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,UAAU,iBAAiB,WAAW,MAAM,GAAG,GAAG;CACxD,IAAI;EAIF,QAAO,MAHgB,MAAM,oBAAoB,KAAK,UAAU,EAC9D,QAAQ,WAAW,OACrB,CAAC,GACe;CAClB,QAAQ;EACN,OAAO;CACT,UAAU;EACR,aAAa,OAAO;CACtB;AACF;AAEA,eAAe,iBAAiB,MAA6B;CAC3D,KAAK,IAAI,UAAU,GAAG,UAAU,IAAI,WAAW,GAAG;EAChD,IAAI,MAAM,UAAU,IAAI,GAAG;EAC3B,MAAMA,aAAM,EAAE;CAChB;CACA,MAAM,IAAI,MAAM,2DAA2D,MAAM;AACnF;AAEA,eAAsB,qBAAqB,MAA6B;CACtE,IAAI,QAAQ,IAAI,IAAI,GAAG;CACvB,IAAI,MAAM,UAAU,IAAI,GAAG;CAG3B,MAAM,SAAS,MAAM;EACnB,OAFU,UAED,EAAE;EACX,UAAU;EACV;CACF,CAAC;CACD,QAAQ,IAAI,MAAM,MAAM;CACxB,OAAO,GAAG,UAAU,QAAQ;EAC1B,QAAQ,OAAO,IAAI;EACnB,QAAQ,OAAO,MAAM,0DAA0D,KAAK,IAAK,IAAc,QAAQ,GAAG;CACpH,CAAC;CAED,IAAI;EACF,MAAM,iBAAiB,IAAI;CAC7B,SAAS,KAAK;EACZ,QAAQ,OAAO,IAAI;EACnB,OAAO,MAAM;EACb,MAAM;CACR;AACF"}
@@ -1,4 +1,4 @@
1
- import { a as resolveGraphMcpEndpoint } from "./client-D4JE7fFF.mjs";
1
+ import { n as applyMcpAuthHeaders, o as resolveGraphMcpEndpoint } from "./client-BgmHjBHQ.mjs";
2
2
  //#region src/mcp/capabilities.ts
3
3
  function metadataNetworksUrl(endpoint) {
4
4
  const url = new URL(endpoint);
@@ -11,10 +11,7 @@ async function fetchNetworkCapabilities(config) {
11
11
  const request = metadataNetworksUrl(resolveGraphMcpEndpoint(config));
12
12
  const headers = new Headers();
13
13
  const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim();
14
- if (token) {
15
- headers.set("X-MCP-Debug-Token", token);
16
- headers.set("Authorization", `Bearer ${token}`);
17
- }
14
+ if (token) applyMcpAuthHeaders(headers, token);
18
15
  let response;
19
16
  try {
20
17
  response = await fetch(request, { headers });
@@ -81,4 +78,4 @@ function formatNetworkCapabilities(document) {
81
78
  //#endregion
82
79
  export { fetchNetworkCapabilities, formatNetworkCapabilities };
83
80
 
84
- //# sourceMappingURL=capabilities-BC3Y5EOi.mjs.map
81
+ //# sourceMappingURL=capabilities-BCvkTkIu.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities-BCvkTkIu.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkRetention {\n mode: 'full_history' | 'rolling_window' | 'expanding_then_rolling' | 'bounded_range' | 'unknown' | string\n window_days?: number\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n started_at?: string\n rolls_after_at?: string\n current_window_seconds?: number\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n retention?: NetworkRetention | null\n}\n\nexport interface NetworkCapability {\n network: string\n display_name?: string\n status: string\n default?: boolean\n layers: Record<string, NetworkLayerCapability>\n tools: Record<string, string>\n coverage?: {\n from_block?: number\n to_block?: number\n from_timestamp?: string\n to_timestamp?: string\n chain_tip_block?: number\n blocks_behind_tip?: number\n }\n freshness?: {\n last_processed_at?: string\n last_successful_sync_at?: string\n max_data_age_seconds?: number\n last_processing_duration_seconds?: number\n }\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nfunction metadataNetworksUrl(endpoint: string): URL {\n const url = new URL(endpoint)\n url.pathname = '/metadata/networks'\n url.search = ''\n url.hash = ''\n return url\n}\n\nexport async function fetchNetworkCapabilities(\n config: Pick<InvestigatorConfig, 'mcpAuthToken' | 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint' | 'mcpEndpoint'>,\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim()\n if (token) {\n applyMcpAuthHeaders(headers, token)\n }\n let response: Response\n try {\n response = await fetch(request, { headers })\n } catch (err) {\n throw new Error(`network capabilities unavailable at ${request}: ${(err as Error).message}`)\n }\n if (!response.ok) {\n throw new Error(`network capabilities unavailable at ${request}: HTTP ${response.status}`)\n }\n const parsed = await response.json() as NetworkCapabilitiesDocument\n if (parsed.schema !== 'chain-insights.network-capabilities.v1' || !Array.isArray(parsed.networks)) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return parsed\n}\n\nfunction layerValue(network: NetworkCapability, layer: string): string {\n const capability = network.layers[layer]\n if (!capability?.enabled) return 'no'\n return 'yes'\n}\n\nfunction availableToolsLabel(network: NetworkCapability): string {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.length > 0 ? tools.join(', ') : 'none'\n}\n\nfunction shortDate(value?: string): string {\n if (!value) return ''\n return value.slice(0, 10)\n}\n\nfunction datasetLabel(network: NetworkCapability): string {\n const coverage = network.coverage\n if (!coverage) return 'unknown'\n const blockRange = coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange = coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : 'dates unknown'\n if (blockRange === 'blocks unknown' && dateRange === 'dates unknown') return 'unknown'\n return `${blockRange} / ${dateRange}`\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const headers = ['Network', 'Topology', 'Facts', 'Risk', 'Dataset', 'Available tools']\n const widths = [14, 10, 8, 8, 38, 64]\n const row = (values: string[]) => values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [\n row(headers),\n widths.map((width) => '-'.repeat(width)).join(' '),\n ...document.networks.map((network) => row([\n network.display_name || network.network,\n layerValue(network, 'topology'),\n layerValue(network, 'facts'),\n layerValue(network, 'risk'),\n datasetLabel(network),\n availableToolsLabel(network),\n ])),\n ].join('\\n')\n}\n"],"mappings":";;AAgDA,SAAS,oBAAoB,UAAuB;CAClD,MAAM,MAAM,IAAI,IAAI,QAAQ;CAC5B,IAAI,WAAW;CACf,IAAI,SAAS;CACb,IAAI,OAAO;CACX,OAAO;AACT;AAEA,eAAsB,yBACpB,QACsC;CAEtC,MAAM,UAAU,oBADC,wBAAwB,MACE,CAAC;CAC5C,MAAM,UAAU,IAAI,QAAQ;CAC5B,MAAM,QAAQ,OAAO,mBAAmB,KAAK,KAAK,OAAO,cAAc,KAAK;CAC5E,IAAI,OACF,oBAAoB,SAAS,KAAK;CAEpC,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,MAAM,SAAS,EAAE,QAAQ,CAAC;CAC7C,SAAS,KAAK;EACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,IAAK,IAAc,SAAS;CAC7F;CACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uCAAuC,QAAQ,SAAS,SAAS,QAAQ;CAE3F,MAAM,SAAS,MAAM,SAAS,KAAK;CACnC,IAAI,OAAO,WAAW,4CAA4C,CAAC,MAAM,QAAQ,OAAO,QAAQ,GAC9F,MAAM,IAAI,MAAM,sDAAsD;CAExE,OAAO;AACT;AAEA,SAAS,WAAW,SAA4B,OAAuB;CAErE,IAAI,CADe,QAAQ,OAAO,QACjB,SAAS,OAAO;CACjC,OAAO;AACT;AAEA,SAAS,oBAAoB,SAAoC;CAC/D,MAAM,QAAQ,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAC7C,QAAQ,GAAG,YAAY,WAAW,WAAW,EAC7C,KAAK,CAAC,UAAU,IAAI;CACvB,OAAO,MAAM,SAAS,IAAI,MAAM,KAAK,IAAI,IAAI;AAC/C;AAEA,SAAS,UAAU,OAAwB;CACzC,IAAI,CAAC,OAAO,OAAO;CACnB,OAAO,MAAM,MAAM,GAAG,EAAE;AAC1B;AAEA,SAAS,aAAa,SAAoC;CACxD,MAAM,WAAW,QAAQ;CACzB,IAAI,CAAC,UAAU,OAAO;CACtB,MAAM,aAAa,SAAS,eAAe,KAAA,KAAa,SAAS,aAAa,KAAA,IAC1E,GAAG,SAAS,WAAW,IAAI,SAAS,aACpC;CACJ,MAAM,YAAY,SAAS,kBAAkB,SAAS,eAClD,GAAG,UAAU,SAAS,cAAc,EAAE,IAAI,UAAU,SAAS,YAAY,MACzE;CACJ,IAAI,eAAe,oBAAoB,cAAc,iBAAiB,OAAO;CAC7E,OAAO,GAAG,WAAW,KAAK;AAC5B;AAEA,SAAgB,0BAA0B,UAA+C;CACvF,IAAI,SAAS,SAAS,WAAW,GAAG,OAAO;CAC3C,MAAM,UAAU;EAAC;EAAW;EAAY;EAAS;EAAQ;EAAW;CAAiB;CACrF,MAAM,SAAS;EAAC;EAAI;EAAI;EAAG;EAAG;EAAI;CAAE;CACpC,MAAM,OAAO,WAAqB,OAAO,KAAK,OAAO,UAAU,MAAM,OAAO,OAAO,MAAO,CAAC,EAAE,KAAK,IAAI;CACtG,OAAO;EACL,IAAI,OAAO;EACX,OAAO,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,IAAI;EAClD,GAAG,SAAS,SAAS,KAAK,YAAY,IAAI;GACxC,QAAQ,gBAAgB,QAAQ;GAChC,WAAW,SAAS,UAAU;GAC9B,WAAW,SAAS,OAAO;GAC3B,WAAW,SAAS,MAAM;GAC1B,aAAa,OAAO;GACpB,oBAAoB,OAAO;EAC7B,CAAC,CAAC;CACJ,EAAE,KAAK,IAAI;AACb"}
@@ -1,4 +1,4 @@
1
- const require_client = require("./client-Db6IV1tv.cjs");
1
+ const require_client = require("./client-Y_zqKqJT.cjs");
2
2
  //#region src/mcp/capabilities.ts
3
3
  function metadataNetworksUrl(endpoint) {
4
4
  const url = new URL(endpoint);
@@ -11,10 +11,7 @@ async function fetchNetworkCapabilities(config) {
11
11
  const request = metadataNetworksUrl(require_client.resolveGraphMcpEndpoint(config));
12
12
  const headers = new Headers();
13
13
  const token = config.graphMcpAuthToken?.trim() || config.mcpAuthToken?.trim();
14
- if (token) {
15
- headers.set("X-MCP-Debug-Token", token);
16
- headers.set("Authorization", `Bearer ${token}`);
17
- }
14
+ if (token) require_client.applyMcpAuthHeaders(headers, token);
18
15
  let response;
19
16
  try {
20
17
  response = await fetch(request, { headers });
package/dist/cli.cjs CHANGED
@@ -70,9 +70,9 @@ function optionalNumberArg(value, name) {
70
70
  throw new Error(`Invalid number for ${name}: ${String(value)}`);
71
71
  }
72
72
  async function withGraphMcpClient(name, fn) {
73
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
73
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
74
74
  const config = await loadConfig();
75
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Db6IV1tv.cjs")).then((n) => n.client_exports);
75
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Y_zqKqJT.cjs")).then((n) => n.client_exports);
76
76
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
77
77
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
78
78
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -91,8 +91,8 @@ function printMcpTextContent(result) {
91
91
  for (const item of result.content ?? []) if (item.type === "text") console.log(item.text);
92
92
  }
93
93
  async function printNetworkCapabilities(opts) {
94
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
95
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-D5PSx9Hj.cjs"));
94
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
95
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-DOa6EFO-.cjs"));
96
96
  const document = await fetchNetworkCapabilities(await loadConfig());
97
97
  if (opts.json) console.log(JSON.stringify(document, null, 2));
98
98
  else console.log(formatNetworkCapabilities(document));
@@ -109,7 +109,7 @@ program.command("serve").description("Start local visualization server").option(
109
109
  try {
110
110
  const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
111
111
  const workspaceRoot = requireWorkspaceRoot();
112
- const { startServer } = await Promise.resolve().then(() => require("./server-BqVdWath.cjs")).then((n) => n.server_exports);
112
+ const { startServer } = await Promise.resolve().then(() => require("./server-B2NFmnCM.cjs")).then((n) => n.server_exports);
113
113
  console.log(`Workspace: ${workspaceRoot}`);
114
114
  startServer(parseInt(opts.port, 10));
115
115
  } catch (err) {
@@ -118,7 +118,7 @@ program.command("serve").description("Start local visualization server").option(
118
118
  }
119
119
  });
120
120
  program.command("status").description("Show toolkit status and configuration").action(async () => {
121
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
121
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
122
122
  const { findActiveWorkspace, activeDataDir } = await Promise.resolve().then(() => require("./active-BVr55kvW.cjs")).then((n) => n.active_exports);
123
123
  const config = await loadConfig();
124
124
  const workspace = findActiveWorkspace();
@@ -129,6 +129,31 @@ program.command("status").description("Show toolkit status and configuration").a
129
129
  console.log("Graph MCP:", graphMcpStatus);
130
130
  console.log("Graph endpoint:", config.graphMcpEndpoint);
131
131
  });
132
+ program.command("update").description("Check npmjs for a newer Chain Insights release and update this CLI").option("--check", "Only check for a newer release").option("--dry-run", "Print the update command without running it").action(async (opts) => {
133
+ try {
134
+ const { checkForUpdate, runPackageUpdate } = await Promise.resolve().then(() => require("./update-BJoXYucO.cjs"));
135
+ const result = await checkForUpdate();
136
+ if (result.error) throw new Error(`Could not check npmjs for updates: ${result.error}`);
137
+ if (!result.updateAvailable || !result.latestVersion) {
138
+ console.log(`Chain Insights is up to date (${result.currentVersion}).`);
139
+ return;
140
+ }
141
+ console.log(`Chain Insights ${result.latestVersion} is available (current ${result.currentVersion}).`);
142
+ if (opts.check) {
143
+ console.log(`Run: ${result.updateCommand}`);
144
+ return;
145
+ }
146
+ if (opts.dryRun) {
147
+ console.log(`Would run: ${result.updateCommand}`);
148
+ return;
149
+ }
150
+ console.log(`Running: ${result.updateCommand}`);
151
+ runPackageUpdate(result.packageName);
152
+ } catch (err) {
153
+ console.error(err.message);
154
+ process.exit(1);
155
+ }
156
+ });
132
157
  program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new commander.Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
133
158
  try {
134
159
  const { findActiveWorkspace } = await Promise.resolve().then(() => require("./active-BVr55kvW.cjs")).then((n) => n.active_exports);
@@ -150,7 +175,7 @@ program.command("obsidian").description("Manage the local Obsidian investigation
150
175
  }));
151
176
  program.command("debug").description("Configure Graph MCP debug mode").addCommand(new commander.Command("on").description("Enable Graph MCP debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Graph MCP endpoint").action(async (opts) => {
152
177
  try {
153
- const { saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
178
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
154
179
  await saveConfig({
155
180
  graphMcpMode: "debug",
156
181
  graphMcpAuthToken: opts.token,
@@ -165,7 +190,7 @@ program.command("debug").description("Configure Graph MCP debug mode").addComman
165
190
  }
166
191
  })).addCommand(new commander.Command("off").description("Disable Graph MCP debug mode and use paid x402 calls").action(async () => {
167
192
  try {
168
- const { saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
193
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
169
194
  await saveConfig({
170
195
  graphMcpMode: "paid",
171
196
  graphMcpAuthToken: ""
@@ -178,7 +203,7 @@ program.command("debug").description("Configure Graph MCP debug mode").addComman
178
203
  }
179
204
  })).addCommand(new commander.Command("status").description("Show Graph MCP payment/debug mode").action(async () => {
180
205
  try {
181
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
206
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
182
207
  const config = await loadConfig();
183
208
  console.log(`Graph MCP mode: ${config.graphMcpMode}`);
184
209
  console.log(`Graph endpoint: ${config.graphMcpEndpoint}`);
@@ -193,7 +218,7 @@ program.command("access-key").description("Configure Graph MCP test access key m
193
218
  try {
194
219
  const normalizedKey = key.trim();
195
220
  if (!normalizedKey) throw new Error("Test access key is required");
196
- const { saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
221
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
197
222
  await saveConfig({
198
223
  graphMcpMode: "debug",
199
224
  graphMcpAuthToken: normalizedKey,
@@ -208,7 +233,7 @@ program.command("access-key").description("Configure Graph MCP test access key m
208
233
  }
209
234
  })).addCommand(new commander.Command("clear").description("Remove the Graph MCP test access key and use paid x402 calls").action(async () => {
210
235
  try {
211
- const { saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
236
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
212
237
  await saveConfig({
213
238
  graphMcpMode: "paid",
214
239
  graphMcpAuthToken: ""
@@ -221,7 +246,7 @@ program.command("access-key").description("Configure Graph MCP test access key m
221
246
  }
222
247
  })).addCommand(new commander.Command("status").description("Show Graph MCP test access key status").action(async () => {
223
248
  try {
224
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
249
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
225
250
  const config = await loadConfig();
226
251
  console.log(`Graph endpoint: ${config.graphMcpEndpoint}`);
227
252
  console.log(`Access key: ${config.graphMcpAuthToken?.trim() ? "configured" : "not configured"}`);
@@ -233,13 +258,15 @@ program.command("access-key").description("Configure Graph MCP test access key m
233
258
  }));
234
259
  program.command("init").description("Initialize an investigation workspace").argument("[dir]", "Workspace directory to initialize", ".").option("--force", "Overwrite existing workspace files").action(async (dir, opts) => {
235
260
  try {
236
- const { initWorkspace } = await Promise.resolve().then(() => require("./init-Dhw8F23z.cjs"));
261
+ const { initWorkspace } = await Promise.resolve().then(() => require("./init-vj2v5PMP.cjs"));
237
262
  const result = await initWorkspace({
238
263
  targetDir: dir,
239
264
  force: opts.force
240
265
  });
241
266
  console.log(`Workspace initialized: ${result.workspaceRoot}`);
242
267
  console.log(`Files written: ${result.filesWritten.length}`);
268
+ const { maybePromptForUpdate } = await Promise.resolve().then(() => require("./update-BJoXYucO.cjs"));
269
+ await maybePromptForUpdate();
243
270
  } catch (err) {
244
271
  console.error(err.message);
245
272
  process.exit(1);
@@ -268,8 +295,8 @@ program.command("setup").description("Configure external MCP clients").addComman
268
295
  }
269
296
  }));
270
297
  program.command("config").description("Read or write configuration values").addCommand(new commander.Command("get").argument("<key>", "Config key to read").action(async (key) => {
271
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
272
- const { CONFIG_KEYS } = await Promise.resolve().then(() => require("./schema-Vl9yuOFO.cjs")).then((n) => n.schema_exports);
298
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
299
+ const { CONFIG_KEYS } = await Promise.resolve().then(() => require("./schema-Dr6JXSOF.cjs")).then((n) => n.schema_exports);
273
300
  if (!CONFIG_KEYS.includes(key)) {
274
301
  console.error(`Unknown config key: ${key}`);
275
302
  process.exit(1);
@@ -289,8 +316,8 @@ program.command("config").description("Read or write configuration values").addC
289
316
  }
290
317
  return;
291
318
  }
292
- const { loadConfig, saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
293
- const { CONFIG_KEYS, DEFAULT_CONFIG } = await Promise.resolve().then(() => require("./schema-Vl9yuOFO.cjs")).then((n) => n.schema_exports);
319
+ const { loadConfig, saveConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
320
+ const { CONFIG_KEYS, DEFAULT_CONFIG } = await Promise.resolve().then(() => require("./schema-Dr6JXSOF.cjs")).then((n) => n.schema_exports);
294
321
  const current = await loadConfig();
295
322
  if (!CONFIG_KEYS.includes(key)) {
296
323
  console.error(`Unknown config key: ${key}`);
@@ -382,8 +409,8 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
382
409
  const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-CJk1EL3L.cjs"));
383
410
  const { formatToolsTable } = await Promise.resolve().then(() => require("./format-9NLBykEL.cjs"));
384
411
  const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-Buq7YdUZ.cjs")).then((n) => n.tool_visibility_exports);
385
- const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
386
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Db6IV1tv.cjs")).then((n) => n.client_exports);
412
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CkW404Cs.cjs")).then((n) => n.config_exports);
413
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Y_zqKqJT.cjs")).then((n) => n.client_exports);
387
414
  const config = await loadConfig();
388
415
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
389
416
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -422,7 +449,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
422
449
  }));
423
450
  return;
424
451
  }
425
- const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
452
+ const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
426
453
  const result = await addressRisk(client, {
427
454
  address: opts.address,
428
455
  network: opts.network,
@@ -450,7 +477,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
450
477
  }));
451
478
  return;
452
479
  }
453
- const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
480
+ const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
454
481
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
455
482
  const result = await traceVictimFunds(client, config, {
456
483
  victimAddresses: opts.victimAddresses,
@@ -474,7 +501,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
474
501
  const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
475
502
  requireWorkspaceRoot();
476
503
  await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
477
- const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
504
+ const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
478
505
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
479
506
  const result = await traceSuspectFunds(client, config, {
480
507
  suspectAddresses: opts.suspectAddresses,
@@ -497,7 +524,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
497
524
  const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
498
525
  requireWorkspaceRoot();
499
526
  await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
500
- const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
527
+ const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
501
528
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
502
529
  const result = await traceDepositSources(client, config, {
503
530
  depositAddresses: opts.depositAddresses,
@@ -515,7 +542,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
515
542
  })).addCommand(new commander.Command("stake-insights").description("Explain Bittensor staking behavior around an address, coldkey, or hotkey").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--address <address>", "Full Bittensor address to inspect as either coldkey or hotkey").option("--coldkey <address>", "Full Bittensor coldkey address to inspect").option("--hotkey <address>", "Full Bittensor hotkey address to inspect").option("--netuid <number>", "Optional subnet netuid filter").option("--start-timestamp-ms <milliseconds>", "Optional inclusive lower activity timestamp bound").option("--end-timestamp-ms <milliseconds>", "Optional inclusive upper activity timestamp bound").option("--start-block <number>", "Optional start block. Current stake graph parity may require timestamp windows instead.").option("--end-block <number>", "Optional end block. Current stake graph parity may require timestamp windows instead.").option("--depth <number>", "Optional expansion depth limit, default 1, max 3").action(async (opts) => {
516
543
  try {
517
544
  await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
518
- const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
545
+ const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
519
546
  const result = await stakeInsights(client, {
520
547
  network: opts.network,
521
548
  address: opts.address,
@@ -543,7 +570,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
543
570
  assertPublicMcpToolName(tool);
544
571
  await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
545
572
  if (tool === "address_risk") {
546
- const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
573
+ const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
547
574
  const result = await addressRisk(client, {
548
575
  address: String(args["address"] ?? ""),
549
576
  network: String(args["network"] ?? ""),
@@ -553,7 +580,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
553
580
  return;
554
581
  }
555
582
  if (tool === "trace_victim_funds") {
556
- const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
583
+ const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
557
584
  const result = await traceVictimFunds(client, config, {
558
585
  victimAddresses: args["victim_addresses"] ?? "",
559
586
  knownSuspectAddresses: args["known_suspect_addresses"],
@@ -569,7 +596,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
569
596
  return;
570
597
  }
571
598
  if (tool === "trace_suspect_funds") {
572
- const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
599
+ const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
573
600
  const result = await traceSuspectFunds(client, config, {
574
601
  suspectAddresses: args["suspect_addresses"] ?? "",
575
602
  network: String(args["network"] ?? ""),
@@ -584,7 +611,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
584
611
  return;
585
612
  }
586
613
  if (tool === "trace_deposit_sources") {
587
- const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
614
+ const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
588
615
  const result = await traceDepositSources(client, config, {
589
616
  depositAddresses: args["deposit_addresses"] ?? "",
590
617
  network: String(args["network"] ?? ""),
@@ -596,7 +623,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
596
623
  return;
597
624
  }
598
625
  if (tool === "stake_insights") {
599
- const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
626
+ const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-BY3PTw6x.cjs"));
600
627
  const result = await stakeInsights(client, {
601
628
  network: String(args["network"] ?? ""),
602
629
  address: args["address"] === void 0 ? void 0 : String(args["address"]),
@@ -850,7 +877,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
850
877
  console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
851
878
  process.exit(1);
852
879
  }
853
- const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-CVo41fjz.cjs"));
880
+ const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-CcZCrrkn.cjs"));
854
881
  await PlaybookRunner.run(definition, {
855
882
  caseId: opts.case,
856
883
  from: fromN,
@@ -905,7 +932,7 @@ program.command("viz").description("Generate money flow visualization").argument
905
932
  caseId,
906
933
  dataFile: opts.data
907
934
  });
908
- const { startServer } = await Promise.resolve().then(() => require("./server-BqVdWath.cjs")).then((n) => n.server_exports);
935
+ const { startServer } = await Promise.resolve().then(() => require("./server-B2NFmnCM.cjs")).then((n) => n.server_exports);
909
936
  const port = parseInt(opts.port, 10);
910
937
  startServer(port);
911
938
  const url = `http://127.0.0.1:${port}/viz/${result.vizId}`;