chain-insights 0.37.2 → 0.40.0

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 (69) hide show
  1. package/README.md +25 -1
  2. package/bin/install.cjs +59 -2
  3. package/dist/{action-log-diTHyMbV.mjs → action-log-D49Par9P.mjs} +2 -2
  4. package/dist/{action-log-diTHyMbV.mjs.map → action-log-D49Par9P.mjs.map} +1 -1
  5. package/dist/{active-BQopLul8.mjs → active-Dkf8AB1R.mjs} +2 -2
  6. package/dist/{active-BQopLul8.mjs.map → active-Dkf8AB1R.mjs.map} +1 -1
  7. package/dist/apps/claude-view.html +117 -0
  8. package/dist/{capabilities-C8DQSfyW.mjs → capabilities-BOOUnAeV.mjs} +3 -3
  9. package/dist/{capabilities-C8DQSfyW.mjs.map → capabilities-BOOUnAeV.mjs.map} +1 -1
  10. package/dist/cli.cjs +26 -24
  11. package/dist/cli.mjs +49 -47
  12. package/dist/cli.mjs.map +1 -1
  13. package/dist/{client-CHYskPnG.mjs → client-gsLi528K.mjs} +4 -4
  14. package/dist/{client-CHYskPnG.mjs.map → client-gsLi528K.mjs.map} +1 -1
  15. package/dist/{config-DbbPiGk0.mjs → config-Br6VEK0O.mjs} +3 -3
  16. package/dist/{config-DbbPiGk0.mjs.map → config-Br6VEK0O.mjs.map} +1 -1
  17. package/dist/{config-B542AM4w.cjs → config-CPUhkz0Z.cjs} +1 -1
  18. package/dist/{create-C0buxEfU.mjs → create-CpfZq2fx.mjs} +2 -2
  19. package/dist/{create-C0buxEfU.mjs.map → create-CpfZq2fx.mjs.map} +1 -1
  20. package/dist/index.cjs +5 -4
  21. package/dist/index.d.cts.map +1 -1
  22. package/dist/index.d.mts.map +1 -1
  23. package/dist/index.mjs +7 -6
  24. package/dist/mcp-proxy.cjs +459 -34
  25. package/dist/mcp-proxy.d.cts +7 -0
  26. package/dist/mcp-proxy.d.cts.map +1 -1
  27. package/dist/mcp-proxy.d.mts +7 -0
  28. package/dist/mcp-proxy.d.mts.map +1 -1
  29. package/dist/mcp-proxy.mjs +466 -44
  30. package/dist/mcp-proxy.mjs.map +1 -1
  31. package/dist/{public-tools-DWONw7kZ.cjs → public-tools-3yTC17cA.cjs} +1 -6
  32. package/dist/{public-tools-CDpFHbZ8.mjs → public-tools-CZyeptJQ.mjs} +3 -8
  33. package/dist/public-tools-CZyeptJQ.mjs.map +1 -0
  34. package/dist/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
  35. package/dist/{schema-B0OuHW_l.mjs → schema-KjZqCHbu.mjs} +3 -3
  36. package/dist/schema-KjZqCHbu.mjs.map +1 -0
  37. package/dist/schema-cache-DJdU4MIP.mjs.map +1 -1
  38. package/dist/{schema-CtFWYoJz.cjs → schema-tX0U0-VI.cjs} +1 -1
  39. package/dist/{subscription-status-MyeqOmbA.mjs → subscription-status-CJ-DaMW9.mjs} +2 -2
  40. package/dist/{subscription-status-MyeqOmbA.mjs.map → subscription-status-CJ-DaMW9.mjs.map} +1 -1
  41. package/dist/{tool-visibility-CyZqYnQA.cjs → tool-visibility-Boxtlbtr.cjs} +19 -1
  42. package/dist/{tool-visibility-CJV9HezW.mjs → tool-visibility-IB5nHCZ_.mjs} +16 -4
  43. package/dist/tool-visibility-IB5nHCZ_.mjs.map +1 -0
  44. package/dist/{tools-BRQAPF2R.mjs → tools-BnThuvE2.mjs} +3 -3
  45. package/dist/{tools-BRQAPF2R.mjs.map → tools-BnThuvE2.mjs.map} +1 -1
  46. package/dist/topup-server-BIbSfvX5.cjs +146 -0
  47. package/dist/{topup-server-YN3iHrHW.cjs → topup-server-Bh7MlzRt.cjs} +485 -239
  48. package/dist/{topup-server-BLdF1SFQ.mjs → topup-server-BrkPhqJG.mjs} +488 -242
  49. package/dist/topup-server-BrkPhqJG.mjs.map +1 -0
  50. package/dist/topup-server-DzeM_YAt.mjs +131 -0
  51. package/dist/topup-server-DzeM_YAt.mjs.map +1 -0
  52. package/dist/{usage-status-CHiOPA-2.mjs → usage-status-CXOnrq-s.mjs} +2 -2
  53. package/dist/{usage-status-CHiOPA-2.mjs.map → usage-status-CXOnrq-s.mjs.map} +1 -1
  54. package/dist/{wallet-COcm4oIb.mjs → wallet-GNDl3FkR.mjs} +2 -2
  55. package/dist/{wallet-COcm4oIb.mjs.map → wallet-GNDl3FkR.mjs.map} +1 -1
  56. package/docs/graph-query-compatibility.md +27 -10
  57. package/docs/graph-tools.md +40 -16
  58. package/docs/mcp-proxy.md +39 -8
  59. package/docs/stability.md +2 -1
  60. package/package.json +5 -6
  61. package/skills/chain-insights-cypher/SKILL.md +56 -23
  62. package/skills/chain-insights-schema-evm/SKILL.md +38 -27
  63. package/dist/html-generator-BCDtYcGs.mjs +0 -16
  64. package/dist/html-generator-BCDtYcGs.mjs.map +0 -1
  65. package/dist/html-generator-DFwMRWN3.cjs +0 -16
  66. package/dist/public-tools-CDpFHbZ8.mjs.map +0 -1
  67. package/dist/schema-B0OuHW_l.mjs.map +0 -1
  68. package/dist/tool-visibility-CJV9HezW.mjs.map +0 -1
  69. package/dist/topup-server-BLdF1SFQ.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { a as resolveGraphMcpEndpoint, n as applyMcpAuthHeaders } from "./client-CHYskPnG.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
+ import { a as resolveGraphMcpEndpoint, n as applyMcpAuthHeaders } from "./client-gsLi528K.mjs";
3
3
  //#region src/mcp/capabilities.ts
4
4
  var capabilities_exports = /* @__PURE__ */ __exportAll({
5
5
  fetchNetworkCapabilities: () => fetchNetworkCapabilities,
@@ -196,4 +196,4 @@ function formatNetworkCapability(network) {
196
196
  //#endregion
197
197
  export { mirrorGraphNetworkCapabilities as n, capabilities_exports as t };
198
198
 
199
- //# sourceMappingURL=capabilities-C8DQSfyW.mjs.map
199
+ //# sourceMappingURL=capabilities-BOOUnAeV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"capabilities-C8DQSfyW.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkTopologyLayer {\n enabled: boolean\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 /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\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 /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: 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 lane_progress?: NetworkLaneProgress[]\n graph_progress?: NetworkGraphProgress\n}\n\n/** One writer lane's committed height. null: the lane has not started. */\nexport interface NetworkLaneProgress {\n lane: string\n height: number | null\n}\n\n/** How far each block layer of the topology graph reaches, and their lowest. */\nexport interface NetworkGraphProgress {\n complete_through_block: number\n layers: { layer: string; position: number }[]\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nconst AVAILABLE_TOOLS_PER_LINE = 3\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction advertisedTools(raw: unknown): Record<string, string> {\n if (!isRecord(raw)) return {}\n const tools: Record<string, string> = {}\n for (const [name, status] of Object.entries(raw)) {\n if (name.trim() !== '' && typeof status === 'string') tools[name] = status\n }\n return tools\n}\n\nfunction advertisedLaneProgress(raw: unknown): NetworkLaneProgress[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const lanes: NetworkLaneProgress[] = []\n for (const entry of raw) {\n if (!isRecord(entry) || typeof entry.lane !== 'string' || entry.lane.trim() === '') continue\n if (typeof entry.height === 'number') lanes.push({ lane: entry.lane, height: entry.height })\n else if (entry.height === null) lanes.push({ lane: entry.lane, height: null })\n }\n return lanes\n}\n\nfunction advertisedGraphProgress(raw: unknown): NetworkGraphProgress | undefined {\n if (!isRecord(raw) || typeof raw.complete_through_block !== 'number') return undefined\n if (!Array.isArray(raw.layers)) return undefined\n const layers: NetworkGraphProgress['layers'] = []\n for (const entry of raw.layers) {\n if (!isRecord(entry) || typeof entry.layer !== 'string' || typeof entry.position !== 'number')\n continue\n layers.push({ layer: entry.layer, position: entry.position })\n }\n return { complete_through_block: raw.complete_through_block, layers }\n}\n\nfunction advertisedNetwork(raw: unknown): NetworkCapability | null {\n if (!isRecord(raw) || typeof raw.network !== 'string' || raw.network.trim() === '') {\n return null\n }\n const network = raw.network.trim()\n const capability: NetworkCapability = {\n network,\n display_name:\n typeof raw.display_name === 'string' && raw.display_name.trim() !== ''\n ? raw.display_name\n : network,\n status: typeof raw.status === 'string' && raw.status.trim() !== '' ? raw.status : 'live',\n layers: {},\n tools: advertisedTools(raw.tools),\n }\n if (raw.default === true) capability.default = true\n if (raw.default === false) capability.default = false\n if (isRecord(raw.coverage)) capability.coverage = raw.coverage as NetworkCapability['coverage']\n if (isRecord(raw.freshness))\n capability.freshness = raw.freshness as NetworkCapability['freshness']\n const laneProgress = advertisedLaneProgress(raw.lane_progress)\n if (laneProgress) capability.lane_progress = laneProgress\n const graphProgress = advertisedGraphProgress(raw.graph_progress)\n if (graphProgress) capability.graph_progress = graphProgress\n return capability\n}\n\n/** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */\nexport function mirrorGraphNetworkCapabilities(document: {\n networks: unknown[]\n}): NetworkCapabilitiesDocument {\n return {\n schema: 'chain-insights.network-capabilities.v1',\n networks: document.networks\n .map((network) => advertisedNetwork(network))\n .filter((network): network is NetworkCapability => network !== null),\n }\n}\n\nfunction publicNetworkCapabilities(\n document: NetworkCapabilitiesDocument\n): NetworkCapabilitiesDocument {\n return mirrorGraphNetworkCapabilities(document)\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, 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint'>\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.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 (\n parsed.schema !== 'chain-insights.network-capabilities.v1' ||\n !Array.isArray(parsed.networks)\n ) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return publicNetworkCapabilities(parsed)\n}\n\nfunction availableTools(network: NetworkCapability): string[] {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.sort()\n}\n\nfunction availableToolLines(network: NetworkCapability): string[] {\n const tools = availableTools(network)\n if (tools.length === 0) return ['none']\n const lines: string[] = []\n for (let index = 0; index < tools.length; index += AVAILABLE_TOOLS_PER_LINE) {\n lines.push(tools.slice(index, index + AVAILABLE_TOOLS_PER_LINE).join(', '))\n }\n return lines\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 =\n coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange =\n coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : ''\n if (blockRange === 'blocks unknown' && dateRange === '') return 'unknown'\n if (blockRange === 'blocks unknown') return dateRange\n if (dateRange === '') return blockRange\n return `${blockRange} / ${dateRange}`\n}\n\nfunction displayName(network: NetworkCapability): string {\n return network.display_name || network.network\n}\n\nfunction statusLabel(network: NetworkCapability): string {\n return network.default ? `${network.status} (default)` : network.status\n}\n\nfunction formatTable(headers: string[], rows: string[][], minimumWidths: number[]): string {\n const widths = headers.map((header, index) =>\n Math.max(\n minimumWidths[index] ?? 0,\n header.length,\n ...rows.map((row) => row[index]?.length ?? 0)\n )\n )\n const row = (values: string[]) =>\n values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [row(headers), widths.map((width) => '-'.repeat(width)).join(' '), ...rows.map(row)].join(\n '\\n'\n )\n}\n\nexport function formatNetworkOverview(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const rows = document.networks.map((network) => [\n displayName(network),\n statusLabel(network),\n datasetLabel(network),\n ])\n return formatTable(['Network', 'Status', 'Dataset'], rows, [14, 10, 38])\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const networkRows = document.networks.flatMap((network) => {\n const toolLines = availableToolLines(network)\n return toolLines.map((toolLine, index) => [\n index === 0 ? displayName(network) : '',\n index === 0 ? datasetLabel(network) : '',\n toolLine,\n ])\n })\n return formatTable(['Network', 'Dataset', 'Chain Insights tools'], networkRows, [14, 38, 64])\n}\n\nexport function findNetworkCapability(\n document: NetworkCapabilitiesDocument,\n name: string\n): NetworkCapability | undefined {\n const normalizedName = name.trim().toLowerCase()\n if (!normalizedName) return undefined\n return document.networks.find((network) =>\n [network.network, network.display_name].some(\n (candidate) => candidate?.trim().toLowerCase() === normalizedName\n )\n )\n}\n\nexport function formatNetworkCapability(network: NetworkCapability): string {\n const rows = [\n ['Network', network.display_name || network.network],\n ['Identifier', network.network],\n ['Status', network.default ? `${network.status} (default)` : network.status],\n ['Dataset', datasetLabel(network)],\n ['Available tools', availableTools(network).join(', ') || 'none'],\n ]\n const labelWidth = Math.max(...rows.map(([label]) => label.length))\n return rows.map(([label, value]) => `${label.padEnd(labelWidth)} ${value}`).join('\\n')\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"capabilities-BOOUnAeV.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { applyMcpAuthHeaders, resolveGraphMcpEndpoint } from './client.js'\n\nexport interface NetworkTopologyLayer {\n enabled: boolean\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 /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: number\n }\n}\n\nexport interface NetworkLayerCapability {\n enabled: boolean\n live?: NetworkTopologyLayer\n archive?: NetworkTopologyLayer\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 /** Lowest height among the raw-data lanes that have started. Above it an empty answer may mean \"not indexed yet\". */\n complete_through_block?: 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 lane_progress?: NetworkLaneProgress[]\n graph_progress?: NetworkGraphProgress\n}\n\n/** One writer lane's committed height. null: the lane has not started. */\nexport interface NetworkLaneProgress {\n lane: string\n height: number | null\n}\n\n/** How far each block layer of the topology graph reaches, and their lowest. */\nexport interface NetworkGraphProgress {\n complete_through_block: number\n layers: { layer: string; position: number }[]\n}\n\nexport interface NetworkCapabilitiesDocument {\n schema: 'chain-insights.network-capabilities.v1'\n networks: NetworkCapability[]\n}\n\nconst AVAILABLE_TOOLS_PER_LINE = 3\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction advertisedTools(raw: unknown): Record<string, string> {\n if (!isRecord(raw)) return {}\n const tools: Record<string, string> = {}\n for (const [name, status] of Object.entries(raw)) {\n if (name.trim() !== '' && typeof status === 'string') tools[name] = status\n }\n return tools\n}\n\nfunction advertisedLaneProgress(raw: unknown): NetworkLaneProgress[] | undefined {\n if (!Array.isArray(raw)) return undefined\n const lanes: NetworkLaneProgress[] = []\n for (const entry of raw) {\n if (!isRecord(entry) || typeof entry.lane !== 'string' || entry.lane.trim() === '') continue\n if (typeof entry.height === 'number') lanes.push({ lane: entry.lane, height: entry.height })\n else if (entry.height === null) lanes.push({ lane: entry.lane, height: null })\n }\n return lanes\n}\n\nfunction advertisedGraphProgress(raw: unknown): NetworkGraphProgress | undefined {\n if (!isRecord(raw) || typeof raw.complete_through_block !== 'number') return undefined\n if (!Array.isArray(raw.layers)) return undefined\n const layers: NetworkGraphProgress['layers'] = []\n for (const entry of raw.layers) {\n if (!isRecord(entry) || typeof entry.layer !== 'string' || typeof entry.position !== 'number')\n continue\n layers.push({ layer: entry.layer, position: entry.position })\n }\n return { complete_through_block: raw.complete_through_block, layers }\n}\n\nfunction advertisedNetwork(raw: unknown): NetworkCapability | null {\n if (!isRecord(raw) || typeof raw.network !== 'string' || raw.network.trim() === '') {\n return null\n }\n const network = raw.network.trim()\n const capability: NetworkCapability = {\n network,\n display_name:\n typeof raw.display_name === 'string' && raw.display_name.trim() !== ''\n ? raw.display_name\n : network,\n status: typeof raw.status === 'string' && raw.status.trim() !== '' ? raw.status : 'live',\n layers: {},\n tools: advertisedTools(raw.tools),\n }\n if (raw.default === true) capability.default = true\n if (raw.default === false) capability.default = false\n if (isRecord(raw.coverage)) capability.coverage = raw.coverage as NetworkCapability['coverage']\n if (isRecord(raw.freshness))\n capability.freshness = raw.freshness as NetworkCapability['freshness']\n const laneProgress = advertisedLaneProgress(raw.lane_progress)\n if (laneProgress) capability.lane_progress = laneProgress\n const graphProgress = advertisedGraphProgress(raw.graph_progress)\n if (graphProgress) capability.graph_progress = graphProgress\n return capability\n}\n\n/** Repeat GraphRAG's network list. CIA does not add, drop, or invent names. */\nexport function mirrorGraphNetworkCapabilities(document: {\n networks: unknown[]\n}): NetworkCapabilitiesDocument {\n return {\n schema: 'chain-insights.network-capabilities.v1',\n networks: document.networks\n .map((network) => advertisedNetwork(network))\n .filter((network): network is NetworkCapability => network !== null),\n }\n}\n\nfunction publicNetworkCapabilities(\n document: NetworkCapabilitiesDocument\n): NetworkCapabilitiesDocument {\n return mirrorGraphNetworkCapabilities(document)\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, 'graphMcpAuthToken' | 'graphMcpMode' | 'graphMcpEndpoint'>\n): Promise<NetworkCapabilitiesDocument> {\n const endpoint = resolveGraphMcpEndpoint(config)\n const request = metadataNetworksUrl(endpoint)\n const headers = new Headers()\n const token = config.graphMcpAuthToken?.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 (\n parsed.schema !== 'chain-insights.network-capabilities.v1' ||\n !Array.isArray(parsed.networks)\n ) {\n throw new Error('network capabilities response has unsupported schema')\n }\n return publicNetworkCapabilities(parsed)\n}\n\nfunction availableTools(network: NetworkCapability): string[] {\n const tools = Object.entries(network.tools ?? {})\n .filter(([, status]) => status === 'available')\n .map(([name]) => name)\n return tools.sort()\n}\n\nfunction availableToolLines(network: NetworkCapability): string[] {\n const tools = availableTools(network)\n if (tools.length === 0) return ['none']\n const lines: string[] = []\n for (let index = 0; index < tools.length; index += AVAILABLE_TOOLS_PER_LINE) {\n lines.push(tools.slice(index, index + AVAILABLE_TOOLS_PER_LINE).join(', '))\n }\n return lines\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 =\n coverage.from_block !== undefined && coverage.to_block !== undefined\n ? `${coverage.from_block}..${coverage.to_block}`\n : 'blocks unknown'\n const dateRange =\n coverage.from_timestamp && coverage.to_timestamp\n ? `${shortDate(coverage.from_timestamp)}..${shortDate(coverage.to_timestamp)}`\n : ''\n if (blockRange === 'blocks unknown' && dateRange === '') return 'unknown'\n if (blockRange === 'blocks unknown') return dateRange\n if (dateRange === '') return blockRange\n return `${blockRange} / ${dateRange}`\n}\n\nfunction displayName(network: NetworkCapability): string {\n return network.display_name || network.network\n}\n\nfunction statusLabel(network: NetworkCapability): string {\n return network.default ? `${network.status} (default)` : network.status\n}\n\nfunction formatTable(headers: string[], rows: string[][], minimumWidths: number[]): string {\n const widths = headers.map((header, index) =>\n Math.max(\n minimumWidths[index] ?? 0,\n header.length,\n ...rows.map((row) => row[index]?.length ?? 0)\n )\n )\n const row = (values: string[]) =>\n values.map((value, index) => value.padEnd(widths[index]!)).join(' ')\n return [row(headers), widths.map((width) => '-'.repeat(width)).join(' '), ...rows.map(row)].join(\n '\\n'\n )\n}\n\nexport function formatNetworkOverview(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const rows = document.networks.map((network) => [\n displayName(network),\n statusLabel(network),\n datasetLabel(network),\n ])\n return formatTable(['Network', 'Status', 'Dataset'], rows, [14, 10, 38])\n}\n\nexport function formatNetworkCapabilities(document: NetworkCapabilitiesDocument): string {\n if (document.networks.length === 0) return 'No supported networks advertised.'\n const networkRows = document.networks.flatMap((network) => {\n const toolLines = availableToolLines(network)\n return toolLines.map((toolLine, index) => [\n index === 0 ? displayName(network) : '',\n index === 0 ? datasetLabel(network) : '',\n toolLine,\n ])\n })\n return formatTable(['Network', 'Dataset', 'Chain Insights tools'], networkRows, [14, 38, 64])\n}\n\nexport function findNetworkCapability(\n document: NetworkCapabilitiesDocument,\n name: string\n): NetworkCapability | undefined {\n const normalizedName = name.trim().toLowerCase()\n if (!normalizedName) return undefined\n return document.networks.find((network) =>\n [network.network, network.display_name].some(\n (candidate) => candidate?.trim().toLowerCase() === normalizedName\n )\n )\n}\n\nexport function formatNetworkCapability(network: NetworkCapability): string {\n const rows = [\n ['Network', network.display_name || network.network],\n ['Identifier', network.network],\n ['Status', network.default ? `${network.status} (default)` : network.status],\n ['Dataset', datasetLabel(network)],\n ['Available tools', availableTools(network).join(', ') || 'none'],\n ]\n const labelWidth = Math.max(...rows.map(([label]) => label.length))\n return rows.map(([label, value]) => `${label.padEnd(labelWidth)} ${value}`).join('\\n')\n}\n"],"mappings":"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"}
package/dist/cli.cjs CHANGED
@@ -147,9 +147,9 @@ const program = new commander.Command();
147
147
  function createCliCommand(name) {
148
148
  return new commander.Command(name).showHelpAfterError();
149
149
  }
150
- program.name("cia").description("AML investigation toolkit for blockchain analysis").version(require_version.PACKAGE_INFO.version).showHelpAfterError().option("--claude", "Install Claude Code skills globally to ~/.claude/skills/").option("--codex", "Install Codex skills globally to ~/.codex/skills/ and register MCP").option("--hermes", "Install Hermes skills globally to ~/.hermes/skills/chain-insights/ and register MCP");
150
+ program.name("cia").description("AML investigation toolkit for blockchain analysis").version(require_version.PACKAGE_INFO.version).showHelpAfterError().option("--claude", "Install Claude Code skills globally to ~/.claude/skills/").option("--claude-desktop", "Register the MCP proxy in Claude Desktop").option("--codex", "Install Codex skills globally to ~/.codex/skills/ and register MCP").option("--hermes", "Install Hermes skills globally to ~/.hermes/skills/chain-insights/ and register MCP");
151
151
  const rawArgs = process.argv.slice(2);
152
- const installerFlags = rawArgs.filter((a) => a === "--claude" || a === "--codex" || a === "--hermes");
152
+ const installerFlags = rawArgs.filter((a) => a === "--claude" || a === "--claude-desktop" || a === "--codex" || a === "--hermes");
153
153
  function normalizeAmlToolVersionArgv(argv) {
154
154
  const commandIndex = rawArgs.findIndex((arg, index) => arg === "aml-address-risk" && index === 1 && rawArgs[0] === "workflow");
155
155
  if (commandIndex === -1) return argv;
@@ -184,7 +184,7 @@ function runInstaller(flag) {
184
184
  }
185
185
  }
186
186
  async function withGraphMcpClient(name, fn) {
187
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
187
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
188
188
  const config = await loadConfig();
189
189
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
190
190
  const { toGraphMcpEndpointError } = await Promise.resolve().then(() => require("./transport-error-DmC9WLTW.cjs"));
@@ -212,21 +212,21 @@ async function withGraphMcpClient(name, fn) {
212
212
  }
213
213
  }
214
214
  async function printNetworkCapabilities(opts) {
215
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
215
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
216
216
  const { fetchNetworkCapabilities, formatNetworkCapabilities } = await Promise.resolve().then(() => require("./capabilities-BbAQ4Tfa.cjs")).then((n) => n.capabilities_exports);
217
217
  const document = await fetchNetworkCapabilities(await loadConfig());
218
218
  if (opts.json) console.log(JSON.stringify(document, null, 2));
219
219
  else console.log(formatNetworkCapabilities(document));
220
220
  }
221
221
  async function printNetworkOverview(opts) {
222
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
222
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
223
223
  const { fetchNetworkCapabilities, formatNetworkOverview } = await Promise.resolve().then(() => require("./capabilities-BbAQ4Tfa.cjs")).then((n) => n.capabilities_exports);
224
224
  const document = await fetchNetworkCapabilities(await loadConfig());
225
225
  if (opts.json) console.log(JSON.stringify(document, null, 2));
226
226
  else console.log(formatNetworkOverview(document));
227
227
  }
228
228
  async function printNetworkCapability(name, opts) {
229
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
229
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
230
230
  const { fetchNetworkCapabilities, findNetworkCapability, formatNetworkCapability } = await Promise.resolve().then(() => require("./capabilities-BbAQ4Tfa.cjs")).then((n) => n.capabilities_exports);
231
231
  const document = await fetchNetworkCapabilities(await loadConfig());
232
232
  const network = findNetworkCapability(document, name);
@@ -301,11 +301,11 @@ async function printSubscriptionPassGuidance(pass) {
301
301
  function addAmlAddressRiskCommand(parent, networksCommand) {
302
302
  parent.addCommand(createCliCommand("aml-address-risk").description("CIA workflow: screen an address for AML risk, exchange behavior, and optional comparison with another address").requiredOption("--address <address>", "Full blockchain address to screen").requiredOption("--network <network>", `Network to query. Run \`${networksCommand}\` for supported networks.`).option("--compare-address <address>", "Optional second address to compare against the screened address").option("--json", "Print machine-readable JSON output").option("--version <version>", "AML tool contract version. Omit to use the latest version (currently v1)").addOption(new commander.Option("--tool-version <version>", "Internal alias for the AML tool version").hideHelp()).action(async (opts) => {
303
303
  try {
304
- const { resolveAmlAddressRiskVersion } = await Promise.resolve().then(() => require("./public-tools-DWONw7kZ.cjs"));
304
+ const { resolveAmlAddressRiskVersion } = await Promise.resolve().then(() => require("./public-tools-3yTC17cA.cjs"));
305
305
  const requestedVersion = opts.toolVersion ?? opts.version;
306
306
  resolveAmlAddressRiskVersion(requestedVersion);
307
307
  await withGraphMcpClient("chain-insights-cli-aml-address-risk", async (client) => {
308
- const { runAmlAddressRisk } = await Promise.resolve().then(() => require("./public-tools-DWONw7kZ.cjs"));
308
+ const { runAmlAddressRisk } = await Promise.resolve().then(() => require("./public-tools-3yTC17cA.cjs"));
309
309
  const result = await runAmlAddressRisk(client, {
310
310
  address: opts.address,
311
311
  network: opts.network,
@@ -344,7 +344,7 @@ program.command("workflows").description("List CIA workflow tools").option("--js
344
344
  });
345
345
  addAmlAddressRiskCommand(program.command("workflow").description("Run a high-level CIA workflow"), "cia networks");
346
346
  program.command("status").description("Show toolkit status and configuration").action(async () => {
347
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
347
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
348
348
  const config = await loadConfig();
349
349
  const graphMcpStatus = config.graphMcpMode === "debug" && config.graphMcpAuthToken?.trim() ? "bearer access mode" : `${config.graphMcpMode} mode`;
350
350
  console.log("Config: ", config.dataDir);
@@ -378,7 +378,7 @@ program.command("update").description("Check npmjs for a newer Chain Insights re
378
378
  });
379
379
  program.command("debug").description("Configure Chain Insights Graph debug mode").addCommand(createCliCommand("on").description("Enable Chain Insights Graph debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Chain Insights Graph endpoint").action(async (opts) => {
380
380
  try {
381
- const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
381
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
382
382
  await saveConfig({
383
383
  graphMcpMode: "debug",
384
384
  graphMcpAuthToken: opts.token,
@@ -393,7 +393,7 @@ program.command("debug").description("Configure Chain Insights Graph debug mode"
393
393
  }
394
394
  })).addCommand(createCliCommand("off").description("Disable Chain Insights Graph debug mode and use paid x402 calls").action(async () => {
395
395
  try {
396
- const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
396
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
397
397
  await saveConfig({
398
398
  graphMcpMode: "paid",
399
399
  graphMcpAuthToken: ""
@@ -406,7 +406,7 @@ program.command("debug").description("Configure Chain Insights Graph debug mode"
406
406
  }
407
407
  })).addCommand(createCliCommand("status").description("Show Chain Insights Graph payment/debug mode").action(async () => {
408
408
  try {
409
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
409
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
410
410
  const config = await loadConfig();
411
411
  console.log(`Chain Insights Graph mode: ${config.graphMcpMode}`);
412
412
  console.log(`Graph endpoint: ${config.graphMcpEndpoint}`);
@@ -421,7 +421,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
421
421
  try {
422
422
  const normalizedKey = key.trim();
423
423
  if (!normalizedKey) throw new Error("Test access key is required");
424
- const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
424
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
425
425
  await saveConfig({
426
426
  graphMcpMode: "debug",
427
427
  graphMcpAuthToken: normalizedKey,
@@ -436,7 +436,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
436
436
  }
437
437
  })).addCommand(createCliCommand("clear").description("Remove the Chain Insights Graph test access key and use paid x402 calls").action(async () => {
438
438
  try {
439
- const { saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
439
+ const { saveConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
440
440
  await saveConfig({
441
441
  graphMcpMode: "paid",
442
442
  graphMcpAuthToken: ""
@@ -449,7 +449,7 @@ program.command("access-key").description("Configure Chain Insights Graph test a
449
449
  }
450
450
  })).addCommand(createCliCommand("status").description("Show Chain Insights Graph test access key status").action(async () => {
451
451
  try {
452
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
452
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
453
453
  const config = await loadConfig();
454
454
  console.log(`Graph endpoint: ${config.graphMcpEndpoint}`);
455
455
  console.log(`Access key: ${config.graphMcpAuthToken?.trim() ? "configured" : "not configured"}`);
@@ -461,14 +461,16 @@ program.command("access-key").description("Configure Chain Insights Graph test a
461
461
  }));
462
462
  program.command("setup").description("Configure external MCP clients").addCommand(createCliCommand("claude-code").alias("claude").description("Install Claude Code skills and register the MCP proxy").action(() => {
463
463
  runInstaller("--claude");
464
+ })).addCommand(createCliCommand("claude-desktop").description("Register the MCP proxy in Claude Desktop, which draws the money-flow views").action(() => {
465
+ runInstaller("--claude-desktop");
464
466
  })).addCommand(createCliCommand("codex").description("Install Codex skills and register the MCP proxy").action(() => {
465
467
  runInstaller("--codex");
466
468
  })).addCommand(createCliCommand("hermes").description("Install Hermes skills and register the MCP proxy").action(() => {
467
469
  runInstaller("--hermes");
468
470
  }));
469
471
  program.command("config").description("Read or write configuration values").addCommand(createCliCommand("get").description("Read one Chain Insights configuration value").argument("<key>", "Config key to read").action(async (key) => {
470
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
471
- const { CONFIG_KEYS } = await Promise.resolve().then(() => require("./schema-CtFWYoJz.cjs")).then((n) => n.schema_exports);
472
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
473
+ const { CONFIG_KEYS } = await Promise.resolve().then(() => require("./schema-tX0U0-VI.cjs")).then((n) => n.schema_exports);
472
474
  if (!CONFIG_KEYS.includes(key)) {
473
475
  console.error(`Unknown config key: ${key}`);
474
476
  process.exit(1);
@@ -488,8 +490,8 @@ program.command("config").description("Read or write configuration values").addC
488
490
  }
489
491
  return;
490
492
  }
491
- const { loadConfig, saveConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
492
- const { CONFIG_KEYS, DEFAULT_CONFIG } = await Promise.resolve().then(() => require("./schema-CtFWYoJz.cjs")).then((n) => n.schema_exports);
493
+ const { loadConfig, saveConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
494
+ const { CONFIG_KEYS, DEFAULT_CONFIG } = await Promise.resolve().then(() => require("./schema-tX0U0-VI.cjs")).then((n) => n.schema_exports);
493
495
  const current = await loadConfig();
494
496
  if (!CONFIG_KEYS.includes(key)) {
495
497
  console.error(`Unknown config key: ${key}`);
@@ -581,7 +583,7 @@ program.command("wallet").description("Manage the local Base USDC payment wallet
581
583
  })).addCommand(createCliCommand("topup").description("Open a local browser page to top up the payment wallet").option("--no-open", "Print the top-up URL without opening a browser").option("--json", "Print machine-readable top-up metadata").action(async (opts) => {
582
584
  try {
583
585
  const { buildTopupInfo, getWalletAccount } = await Promise.resolve().then(() => require("./tools-BHfphgy9.cjs")).then((n) => n.tools_exports);
584
- const { startTopupServer } = await Promise.resolve().then(() => require("./topup-server-YN3iHrHW.cjs")).then((n) => n.topup_server_exports);
586
+ const { startTopupServer } = await Promise.resolve().then(() => require("./topup-server-BIbSfvX5.cjs")).then((n) => n.topup_server_exports);
585
587
  const account = await getWalletAccount();
586
588
  const url = await startTopupServer(account);
587
589
  const info = buildTopupInfo(account.address, url);
@@ -628,8 +630,8 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
628
630
  try {
629
631
  const { loadSchema, saveSchema } = await Promise.resolve().then(() => require("./schema-cache-n7Gbhvsj.cjs"));
630
632
  const { formatToolsTable } = await Promise.resolve().then(() => require("./format-BjZuYDr8.cjs"));
631
- const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
632
- const { loadConfig } = await Promise.resolve().then(() => require("./config-B542AM4w.cjs")).then((n) => n.config_exports);
633
+ const { visibleRemoteTools } = await Promise.resolve().then(() => require("./tool-visibility-Boxtlbtr.cjs")).then((n) => n.tool_visibility_exports);
634
+ const { loadConfig } = await Promise.resolve().then(() => require("./config-CPUhkz0Z.cjs")).then((n) => n.config_exports);
633
635
  const { createConfiguredGraphMcpFetch, resolveGraphMcpEndpoint } = await Promise.resolve().then(() => require("./client-Ypw9BNbn.cjs")).then((n) => n.client_exports);
634
636
  const config = await loadConfig();
635
637
  const graphMcpEndpoint = resolveGraphMcpEndpoint(config);
@@ -658,7 +660,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
658
660
  })).addCommand(createCliCommand("call").description("Call a low-level MCP tool directly (advanced)").option("--json", "Print machine-readable JSON output").argument("<tool>", "Tool name to call").argument("[args...]", "Key=value arguments (e.g. address=0x1234... network=robinhood)").action(async (tool, rawArgs, opts) => {
659
661
  try {
660
662
  const { parseMcpCallArgs } = await Promise.resolve().then(() => require("./call-args-DAiQSDmD.cjs"));
661
- const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
663
+ const { assertPublicMcpToolName, validatePublicMcpToolArguments } = await Promise.resolve().then(() => require("./tool-visibility-Boxtlbtr.cjs")).then((n) => n.tool_visibility_exports);
662
664
  const args = parseMcpCallArgs(rawArgs);
663
665
  assertPublicMcpToolName(tool);
664
666
  if (tool === "aml_address_risk") throw new Error("aml_address_risk is a CIA workflow. Run `cia workflow aml-address-risk` instead.");
@@ -727,7 +729,7 @@ program.command("mcp").description("Low-level access to the Chain Insights MCP e
727
729
  });
728
730
  });
729
731
  } catch (err) {
730
- const { formatMcpCallError } = await Promise.resolve().then(() => require("./tool-visibility-CyZqYnQA.cjs")).then((n) => n.tool_visibility_exports);
732
+ const { formatMcpCallError } = await Promise.resolve().then(() => require("./tool-visibility-Boxtlbtr.cjs")).then((n) => n.tool_visibility_exports);
731
733
  console.error(formatMcpCallError(tool, err));
732
734
  process.exit(1);
733
735
  }