chain-insights 0.3.7 → 0.3.9

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 (34) hide show
  1. package/README.md +5 -0
  2. package/dist/{capabilities-BC3Y5EOi.mjs → capabilities-BCvkTkIu.mjs} +3 -6
  3. package/dist/capabilities-BCvkTkIu.mjs.map +1 -0
  4. package/dist/{capabilities-D5PSx9Hj.cjs → capabilities-DOa6EFO-.cjs} +2 -5
  5. package/dist/cli.cjs +41 -14
  6. package/dist/cli.mjs +41 -14
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/{client-D4JE7fFF.mjs → client-BgmHjBHQ.mjs} +15 -7
  9. package/dist/client-BgmHjBHQ.mjs.map +1 -0
  10. package/dist/{client-Db6IV1tv.cjs → client-Y_zqKqJT.cjs} +19 -5
  11. package/dist/index.cjs +1 -1
  12. package/dist/index.d.cts.map +1 -1
  13. package/dist/index.d.mts.map +1 -1
  14. package/dist/index.mjs +1 -1
  15. package/dist/mcp-proxy.cjs +442 -408
  16. package/dist/mcp-proxy.d.cts +3 -1
  17. package/dist/mcp-proxy.d.cts.map +1 -1
  18. package/dist/mcp-proxy.d.mts +3 -1
  19. package/dist/mcp-proxy.d.mts.map +1 -1
  20. package/dist/mcp-proxy.mjs +442 -409
  21. package/dist/mcp-proxy.mjs.map +1 -1
  22. package/dist/{public-tools-xfVNz9NE.cjs → public-tools-BY3PTw6x.cjs} +59 -31
  23. package/dist/{public-tools-CyUZEz9B.mjs → public-tools-CvlZcysd.mjs} +60 -32
  24. package/dist/public-tools-CvlZcysd.mjs.map +1 -0
  25. package/dist/{runner-DWuSy1Se.mjs → runner-CVnjpqc-.mjs} +2 -2
  26. package/dist/{runner-DWuSy1Se.mjs.map → runner-CVnjpqc-.mjs.map} +1 -1
  27. package/dist/{runner-CVo41fjz.cjs → runner-bLy0pTr_.cjs} +1 -1
  28. package/dist/update-BJoXYucO.cjs +145 -0
  29. package/dist/update-CJUfGCxs.mjs +145 -0
  30. package/dist/update-CJUfGCxs.mjs.map +1 -0
  31. package/package.json +1 -1
  32. package/dist/capabilities-BC3Y5EOi.mjs.map +0 -1
  33. package/dist/client-D4JE7fFF.mjs.map +0 -1
  34. 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
@@ -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
@@ -72,7 +72,7 @@ function optionalNumberArg(value, name) {
72
72
  async function withGraphMcpClient(name, fn) {
73
73
  const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.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");
@@ -92,7 +92,7 @@ function printMcpTextContent(result) {
92
92
  }
93
93
  async function printNetworkCapabilities(opts) {
94
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"));
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));
@@ -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);
@@ -240,6 +265,8 @@ program.command("init").description("Initialize an investigation workspace").arg
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);
@@ -383,7 +410,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
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
412
  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);
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-bLy0pTr_.cjs"));
854
881
  await PlaybookRunner.run(definition, {
855
882
  caseId: opts.case,
856
883
  from: fromN,
package/dist/cli.mjs CHANGED
@@ -70,7 +70,7 @@ function optionalNumberArg(value, name) {
70
70
  async function withGraphMcpClient(name, fn) {
71
71
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
72
72
  const config = await loadConfig();
73
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-D4JE7fFF.mjs").then((n) => n.n);
73
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BgmHjBHQ.mjs").then((n) => n.r);
74
74
  const paymentFetch = await createConfiguredGraphMcpFetch(config);
75
75
  const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
76
76
  const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
@@ -90,7 +90,7 @@ function printMcpTextContent(result) {
90
90
  }
91
91
  async function printNetworkCapabilities(opts) {
92
92
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
93
- const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-BC3Y5EOi.mjs");
93
+ const { fetchNetworkCapabilities, formatNetworkCapabilities } = await import("./capabilities-BCvkTkIu.mjs");
94
94
  const document = await fetchNetworkCapabilities(await loadConfig());
95
95
  if (opts.json) console.log(JSON.stringify(document, null, 2));
96
96
  else console.log(formatNetworkCapabilities(document));
@@ -127,6 +127,31 @@ program.command("status").description("Show toolkit status and configuration").a
127
127
  console.log("Graph MCP:", graphMcpStatus);
128
128
  console.log("Graph endpoint:", config.graphMcpEndpoint);
129
129
  });
130
+ 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) => {
131
+ try {
132
+ const { checkForUpdate, runPackageUpdate } = await import("./update-CJUfGCxs.mjs");
133
+ const result = await checkForUpdate();
134
+ if (result.error) throw new Error(`Could not check npmjs for updates: ${result.error}`);
135
+ if (!result.updateAvailable || !result.latestVersion) {
136
+ console.log(`Chain Insights is up to date (${result.currentVersion}).`);
137
+ return;
138
+ }
139
+ console.log(`Chain Insights ${result.latestVersion} is available (current ${result.currentVersion}).`);
140
+ if (opts.check) {
141
+ console.log(`Run: ${result.updateCommand}`);
142
+ return;
143
+ }
144
+ if (opts.dryRun) {
145
+ console.log(`Would run: ${result.updateCommand}`);
146
+ return;
147
+ }
148
+ console.log(`Running: ${result.updateCommand}`);
149
+ runPackageUpdate(result.packageName);
150
+ } catch (err) {
151
+ console.error(err.message);
152
+ process.exit(1);
153
+ }
154
+ });
130
155
  program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
131
156
  try {
132
157
  const { findActiveWorkspace } = await import("./active-ByNgjuAg.mjs").then((n) => n.n);
@@ -238,6 +263,8 @@ program.command("init").description("Initialize an investigation workspace").arg
238
263
  });
239
264
  console.log(`Workspace initialized: ${result.workspaceRoot}`);
240
265
  console.log(`Files written: ${result.filesWritten.length}`);
266
+ const { maybePromptForUpdate } = await import("./update-CJUfGCxs.mjs");
267
+ await maybePromptForUpdate();
241
268
  } catch (err) {
242
269
  console.error(err.message);
243
270
  process.exit(1);
@@ -381,7 +408,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
381
408
  const { formatToolsTable } = await import("./format-Bq94jSyw.mjs");
382
409
  const { visibleRemoteTools } = await import("./tool-visibility-BpyZHRBi.mjs").then((n) => n.n);
383
410
  const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
384
- const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-D4JE7fFF.mjs").then((n) => n.n);
411
+ const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await import("./client-BgmHjBHQ.mjs").then((n) => n.r);
385
412
  const config = await loadConfig();
386
413
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
387
414
  let tools = opts.refresh ? null : await loadSchema(graphMcpEndpoint);
@@ -420,7 +447,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
420
447
  }));
421
448
  return;
422
449
  }
423
- const { addressRisk } = await import("./public-tools-CyUZEz9B.mjs");
450
+ const { addressRisk } = await import("./public-tools-CvlZcysd.mjs");
424
451
  const result = await addressRisk(client, {
425
452
  address: opts.address,
426
453
  network: opts.network,
@@ -448,7 +475,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
448
475
  }));
449
476
  return;
450
477
  }
451
- const { traceVictimFunds } = await import("./public-tools-CyUZEz9B.mjs");
478
+ const { traceVictimFunds } = await import("./public-tools-CvlZcysd.mjs");
452
479
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
453
480
  const result = await traceVictimFunds(client, config, {
454
481
  victimAddresses: opts.victimAddresses,
@@ -472,7 +499,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
472
499
  const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
473
500
  requireWorkspaceRoot();
474
501
  await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
475
- const { traceSuspectFunds } = await import("./public-tools-CyUZEz9B.mjs");
502
+ const { traceSuspectFunds } = await import("./public-tools-CvlZcysd.mjs");
476
503
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
477
504
  const result = await traceSuspectFunds(client, config, {
478
505
  suspectAddresses: opts.suspectAddresses,
@@ -495,7 +522,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
495
522
  const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
496
523
  requireWorkspaceRoot();
497
524
  await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
498
- const { traceDepositSources } = await import("./public-tools-CyUZEz9B.mjs");
525
+ const { traceDepositSources } = await import("./public-tools-CvlZcysd.mjs");
499
526
  const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
500
527
  const result = await traceDepositSources(client, config, {
501
528
  depositAddresses: opts.depositAddresses,
@@ -513,7 +540,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
513
540
  })).addCommand(new 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) => {
514
541
  try {
515
542
  await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
516
- const { stakeInsights } = await import("./public-tools-CyUZEz9B.mjs");
543
+ const { stakeInsights } = await import("./public-tools-CvlZcysd.mjs");
517
544
  const result = await stakeInsights(client, {
518
545
  network: opts.network,
519
546
  address: opts.address,
@@ -541,7 +568,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
541
568
  assertPublicMcpToolName(tool);
542
569
  await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
543
570
  if (tool === "address_risk") {
544
- const { addressRisk } = await import("./public-tools-CyUZEz9B.mjs");
571
+ const { addressRisk } = await import("./public-tools-CvlZcysd.mjs");
545
572
  const result = await addressRisk(client, {
546
573
  address: String(args["address"] ?? ""),
547
574
  network: String(args["network"] ?? ""),
@@ -551,7 +578,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
551
578
  return;
552
579
  }
553
580
  if (tool === "trace_victim_funds") {
554
- const { traceVictimFunds } = await import("./public-tools-CyUZEz9B.mjs");
581
+ const { traceVictimFunds } = await import("./public-tools-CvlZcysd.mjs");
555
582
  const result = await traceVictimFunds(client, config, {
556
583
  victimAddresses: args["victim_addresses"] ?? "",
557
584
  knownSuspectAddresses: args["known_suspect_addresses"],
@@ -567,7 +594,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
567
594
  return;
568
595
  }
569
596
  if (tool === "trace_suspect_funds") {
570
- const { traceSuspectFunds } = await import("./public-tools-CyUZEz9B.mjs");
597
+ const { traceSuspectFunds } = await import("./public-tools-CvlZcysd.mjs");
571
598
  const result = await traceSuspectFunds(client, config, {
572
599
  suspectAddresses: args["suspect_addresses"] ?? "",
573
600
  network: String(args["network"] ?? ""),
@@ -582,7 +609,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
582
609
  return;
583
610
  }
584
611
  if (tool === "trace_deposit_sources") {
585
- const { traceDepositSources } = await import("./public-tools-CyUZEz9B.mjs");
612
+ const { traceDepositSources } = await import("./public-tools-CvlZcysd.mjs");
586
613
  const result = await traceDepositSources(client, config, {
587
614
  depositAddresses: args["deposit_addresses"] ?? "",
588
615
  network: String(args["network"] ?? ""),
@@ -594,7 +621,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
594
621
  return;
595
622
  }
596
623
  if (tool === "stake_insights") {
597
- const { stakeInsights } = await import("./public-tools-CyUZEz9B.mjs");
624
+ const { stakeInsights } = await import("./public-tools-CvlZcysd.mjs");
598
625
  const result = await stakeInsights(client, {
599
626
  network: String(args["network"] ?? ""),
600
627
  address: args["address"] === void 0 ? void 0 : String(args["address"]),
@@ -848,7 +875,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
848
875
  console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
849
876
  process.exit(1);
850
877
  }
851
- const { PlaybookRunner } = await import("./runner-DWuSy1Se.mjs");
878
+ const { PlaybookRunner } = await import("./runner-CVnjpqc-.mjs");
852
879
  await PlaybookRunner.run(definition, {
853
880
  caseId: opts.case,
854
881
  from: fromN,