chain-insights 0.2.17 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/bin/cli.js +2 -3
- package/bin/install.cjs +0 -1
- package/dist/{active-Dv7Tu-O4.cjs → active-BVr55kvW.cjs} +1 -1
- package/dist/{active-BSrxLKwn.mjs → active-ByNgjuAg.mjs} +2 -2
- package/dist/{active-BSrxLKwn.mjs.map → active-ByNgjuAg.mjs.map} +1 -1
- package/dist/{app-Dq1TdB6p.cjs → app-BxojXjtB.cjs} +4 -4
- package/dist/{app-BjjuQM0B.mjs → app-CRd39JJ8.mjs} +4 -4
- package/dist/{app-BjjuQM0B.mjs.map → app-CRd39JJ8.mjs.map} +1 -1
- package/dist/{artifact-server-Dxz5YbuQ.mjs → artifact-server-CP6LXQ9d.mjs} +2 -2
- package/dist/{artifact-server-Dxz5YbuQ.mjs.map → artifact-server-CP6LXQ9d.mjs.map} +1 -1
- package/dist/{artifact-server-DoxJ7fCx.cjs → artifact-server-XbN16DwU.cjs} +1 -2
- package/dist/{call-args-Lk_wOJxd.mjs → call-args-DPXdX3_D.mjs} +1 -1
- package/dist/{call-args-Lk_wOJxd.mjs.map → call-args-DPXdX3_D.mjs.map} +1 -1
- package/dist/{capabilities-DliMBim-.mjs → capabilities-BShqspb-.mjs} +2 -2
- package/dist/{capabilities-DliMBim-.mjs.map → capabilities-BShqspb-.mjs.map} +1 -1
- package/dist/{capabilities-CB97WMA5.cjs → capabilities-Bm0JDbV7.cjs} +1 -1
- package/dist/cases-c0iV-XLI.cjs +9 -0
- package/dist/cases-qjPtbnUd.mjs +6 -0
- package/dist/cli.cjs +105 -64
- package/dist/cli.mjs +104 -63
- package/dist/cli.mjs.map +1 -1
- package/dist/{client-D4Bq0rp9.mjs → client-D4_hd4AP.mjs} +23 -9
- package/dist/client-D4_hd4AP.mjs.map +1 -0
- package/dist/{client-D4fZgIaO.cjs → client-DPc2eyVN.cjs} +27 -7
- package/dist/config-BwVx19Og.cjs +100 -0
- package/dist/config-Drgc2HuF.mjs +77 -0
- package/dist/config-Drgc2HuF.mjs.map +1 -0
- package/dist/{dossier-BsroDgD3.mjs → dossier-Bl0NkJKC.mjs} +3 -3
- package/dist/{dossier-BsroDgD3.mjs.map → dossier-Bl0NkJKC.mjs.map} +1 -1
- package/dist/{dossier-DtxREpPm.cjs → dossier-Br62hCG7.cjs} +3 -3
- package/dist/{evidence-BGcdKxuV.cjs → evidence-CvEesemA.cjs} +3 -3
- package/dist/{evidence-BhvFW-y_.mjs → evidence-D96PTzOQ.mjs} +3 -3
- package/dist/{evidence-BhvFW-y_.mjs.map → evidence-D96PTzOQ.mjs.map} +1 -1
- package/dist/{format-Ce1RObVl.mjs → format-Bq94jSyw.mjs} +1 -1
- package/dist/{format-Ce1RObVl.mjs.map → format-Bq94jSyw.mjs.map} +1 -1
- package/dist/{frontmatter-D8wWCeOa.mjs → frontmatter-D0ccQnUM.mjs} +1 -1
- package/dist/frontmatter-D0ccQnUM.mjs.map +1 -0
- package/dist/{graph-normalizer-Cv9yK9Pg.mjs → graph-normalizer-CXP06jKh.mjs} +1 -1
- package/dist/{graph-normalizer-Cv9yK9Pg.mjs.map → graph-normalizer-CXP06jKh.mjs.map} +1 -1
- package/dist/{graph-reports-DU05YCei.cjs → graph-reports-B3mkLP8Z.cjs} +3 -3
- package/dist/{graph-reports-C4TBjCkM.mjs → graph-reports-BDELxmpi.mjs} +3 -3
- package/dist/{graph-reports-C4TBjCkM.mjs.map → graph-reports-BDELxmpi.mjs.map} +1 -1
- package/dist/{html-generator-V6Bp0uRb.mjs → html-generator-AowOmzyi.mjs} +2 -2
- package/dist/{html-generator-V6Bp0uRb.mjs.map → html-generator-AowOmzyi.mjs.map} +1 -1
- package/dist/{html-generator-CAv81IWH.cjs → html-generator-Bx3UcLTB.cjs} +1 -1
- package/dist/index.cjs +8 -8
- package/dist/index.d.cts +3 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8 -8
- package/dist/{init-BufWeNP5.mjs → init-4tn7jfhN.mjs} +3 -2
- package/dist/init-4tn7jfhN.mjs.map +1 -0
- package/dist/{init-BxDVuX6v.cjs → init-TCQY5RDJ.cjs} +3 -2
- package/dist/mcp-endpoint-BaV8h_lq.cjs +60 -0
- package/dist/mcp-endpoint-DHs1cRFH.mjs +39 -0
- package/dist/mcp-endpoint-DHs1cRFH.mjs.map +1 -0
- package/dist/mcp-proxy.cjs +166 -30
- package/dist/mcp-proxy.d.cts.map +1 -1
- package/dist/mcp-proxy.d.mts.map +1 -1
- package/dist/mcp-proxy.mjs +165 -29
- package/dist/mcp-proxy.mjs.map +1 -1
- package/dist/{output-root-CmWM7aV2.mjs → output-root-BRhzhhXZ.mjs} +3 -3
- package/dist/{output-root-CmWM7aV2.mjs.map → output-root-BRhzhhXZ.mjs.map} +1 -1
- package/dist/{output-root-CFYms3ad.cjs → output-root-YIbl6PwF.cjs} +2 -2
- package/dist/{parser-BUIWW1OH.cjs → parser-BXLAHYnZ.cjs} +1 -1
- package/dist/{parser-DO0_SssG.mjs → parser-CJfMsOl6.mjs} +1 -1
- package/dist/{parser-DO0_SssG.mjs.map → parser-CJfMsOl6.mjs.map} +1 -1
- package/dist/{public-tools-D4UI-Zb0.mjs → public-tools-B13J0MJZ.mjs} +471 -76
- package/dist/public-tools-B13J0MJZ.mjs.map +1 -0
- package/dist/{public-tools-XSpkz2ky.cjs → public-tools-BC1fi0DV.cjs} +471 -75
- package/dist/{resolver-zYbu4wDV.cjs → resolver-BUU7ZgW-.cjs} +1 -1
- package/dist/{resolver-C2ZS7oC8.mjs → resolver-D7VBb0uB.mjs} +1 -1
- package/dist/resolver-D7VBb0uB.mjs.map +1 -0
- package/dist/{runner-BhUHbiHG.mjs → runner-DIs04IhN.mjs} +7 -7
- package/dist/{runner-BhUHbiHG.mjs.map → runner-DIs04IhN.mjs.map} +1 -1
- package/dist/{runner-1Eq55OYb.cjs → runner-ZYowxCVl.cjs} +6 -7
- package/dist/schema-BFEWhzg7.mjs +60 -0
- package/dist/schema-BFEWhzg7.mjs.map +1 -0
- package/dist/{schema-4XpzDFQM.cjs → schema-Vl9yuOFO.cjs} +32 -9
- package/dist/{schema-cache-CgWRCN2N.cjs → schema-cache-CJk1EL3L.cjs} +1 -1
- package/dist/{schema-cache-9CksD7tX.mjs → schema-cache-DwDvPy4e.mjs} +1 -1
- package/dist/{schema-cache-9CksD7tX.mjs.map → schema-cache-DwDvPy4e.mjs.map} +1 -1
- package/dist/{selector-xjm6NTHI.mjs → selector-CTUiQrzI.mjs} +2 -2
- package/dist/{selector-xjm6NTHI.mjs.map → selector-CTUiQrzI.mjs.map} +1 -1
- package/dist/{selector-CkFcTXzz.cjs → selector-DBS2jYH4.cjs} +1 -1
- package/dist/{server-BkM5xrXb.mjs → server-BXLX2j_A.mjs} +3 -3
- package/dist/{server-BkM5xrXb.mjs.map → server-BXLX2j_A.mjs.map} +1 -1
- package/dist/{server-DXowbpfi.cjs → server-BqVdWath.cjs} +2 -2
- package/dist/{session-CcTgYxsj.mjs → session-Bha3zFrx.mjs} +3 -3
- package/dist/{session-CcTgYxsj.mjs.map → session-Bha3zFrx.mjs.map} +1 -1
- package/dist/{session-BpNylyuJ.cjs → session-DwyikazY.cjs} +3 -3
- package/dist/{setup-DOpKPrlx.cjs → setup-CDha4B9s.cjs} +1 -1
- package/dist/{setup-DyrWHuwQ.mjs → setup-yXK8agdn.mjs} +1 -1
- package/dist/{setup-DyrWHuwQ.mjs.map → setup-yXK8agdn.mjs.map} +1 -1
- package/dist/{store-BoWE-Gtl.mjs → store-BT2SCcQr.mjs} +5 -5
- package/dist/{store-BoWE-Gtl.mjs.map → store-BT2SCcQr.mjs.map} +1 -1
- package/dist/{store-BiUhQOIf.cjs → store-DogLawSj.cjs} +5 -5
- package/dist/{tool-visibility-3Z_KvO9Q.mjs → tool-visibility-BHRFLXuU.mjs} +2 -2
- package/dist/{tool-visibility-3Z_KvO9Q.mjs.map → tool-visibility-BHRFLXuU.mjs.map} +1 -1
- package/dist/{tool-visibility-CwgY205r.cjs → tool-visibility-iAVQV3t0.cjs} +1 -1
- package/dist/{tools-f_vJUZAF.cjs → tools-DY8h0WbE.cjs} +2 -2
- package/dist/{tools-Cp2jAAAb.mjs → tools-Py6SXg6J.mjs} +3 -3
- package/dist/{tools-Cp2jAAAb.mjs.map → tools-Py6SXg6J.mjs.map} +1 -1
- package/dist/{topup-server-DUjyFftI.mjs → topup-server-BJgVw6Jt.mjs} +104 -46
- package/dist/topup-server-BJgVw6Jt.mjs.map +1 -0
- package/dist/{topup-server-BZuQifvh.cjs → topup-server-yAaXYkJP.cjs} +102 -44
- package/dist/{version-1gP19Lhi.mjs → version-BA3J8hu4.mjs} +1 -1
- package/dist/{version-1gP19Lhi.mjs.map → version-BA3J8hu4.mjs.map} +1 -1
- package/dist/{version-BNGtdpmH.cjs → version-CO9Or_YV.cjs} +0 -1
- package/dist/{data-extractor-BNGj7ECT.cjs → viz-Da9YWN_I.cjs} +37 -8
- package/dist/{data-extractor-DFzsa5CS.mjs → viz-DkJyqlUu.mjs} +35 -6
- package/dist/viz-DkJyqlUu.mjs.map +1 -0
- package/dist/{wallet-BMelXBYP.mjs → wallet-D8IqFRKY.mjs} +2 -2
- package/dist/{wallet-BMelXBYP.mjs.map → wallet-D8IqFRKY.mjs.map} +1 -1
- package/dist/{wallet-RnvvSpV2.cjs → wallet-TAlNMvIM.cjs} +1 -1
- package/docs/contributing.md +1 -0
- package/docs/debugging.md +10 -14
- package/docs/graph-tools.md +60 -2
- package/docs/mcp-proxy.md +3 -0
- package/package.json +3 -3
- package/skills/chain-insights-developer-experience/SKILL.md +4 -2
- package/skills/chain-insights-investigation/SKILL.md +1 -1
- package/skills/test-chain-insights-graphrag-mcp/SKILL.md +4 -5
- package/skills/test-chain-insights-graphrag-mcp/scripts/run-uat.sh +5 -24
- package/dist/cases-By7INiOa.mjs +0 -6
- package/dist/cases-CDcNU91B.cjs +0 -9
- package/dist/client-D4Bq0rp9.mjs.map +0 -1
- package/dist/config-Bmdl5hdk.cjs +0 -67
- package/dist/config-BwrBYmiC.mjs +0 -44
- package/dist/config-BwrBYmiC.mjs.map +0 -1
- package/dist/data-extractor-DFzsa5CS.mjs.map +0 -1
- package/dist/frontmatter-D8wWCeOa.mjs.map +0 -1
- package/dist/init-BufWeNP5.mjs.map +0 -1
- package/dist/public-tools-D4UI-Zb0.mjs.map +0 -1
- package/dist/resolver-C2ZS7oC8.mjs.map +0 -1
- package/dist/schema-8d0rVIdZ.mjs +0 -37
- package/dist/schema-8d0rVIdZ.mjs.map +0 -1
- package/dist/topup-server-DUjyFftI.mjs.map +0 -1
- package/dist/viz-BlCJe6Tk.mjs +0 -35
- package/dist/viz-BlCJe6Tk.mjs.map +0 -1
- package/dist/viz-ClezVXrJ.cjs +0 -44
- /package/dist/{call-args-DQA2QcRA.cjs → call-args-CcUV6gFS.cjs} +0 -0
- /package/dist/{chunk-CZWwpsFl.cjs → chunk-DakpK96I.cjs} +0 -0
- /package/dist/{format-DOrPvXEr.cjs → format-9NLBykEL.cjs} +0 -0
- /package/dist/{frontmatter-DgAuai7E.cjs → frontmatter-Dvqa5HX6.cjs} +0 -0
- /package/dist/{graph-normalizer-DeIj6Ses.cjs → graph-normalizer-DbjlbMpz.cjs} +0 -0
- /package/dist/{rolldown-runtime-wcPFST8Q.mjs → rolldown-runtime-D7D4PA-g.mjs} +0 -0
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ evidence pointers, dossiers, and reports.
|
|
|
16
16
|
| Tool | Use it for |
|
|
17
17
|
| --- | --- |
|
|
18
18
|
| `address_risk` | Screen one address for risk, behavior, neighborhood context, and exchange exposure |
|
|
19
|
+
| `stake_insights` | Explain Bittensor staking relationships, net stake movement, and counterparties |
|
|
19
20
|
| `track_funds` | Trace victim/source funds through intermediaries to exchange deposit candidates |
|
|
20
21
|
| `scam_topology` | Expand a known victim incident into reviewable scam infrastructure and label candidates |
|
|
21
22
|
| `graph_query` | Run one read-only GQL/Cypher query against a GraphRAG MCP graph layer |
|
|
@@ -52,6 +53,40 @@ cd ./chain-insights-investigations
|
|
|
52
53
|
cia init .
|
|
53
54
|
```
|
|
54
55
|
|
|
56
|
+
## Configure MCP server address
|
|
57
|
+
|
|
58
|
+
`cia` uses `graphMcpEndpoint` for all GraphRAG MCP calls. Configure it explicitly per environment.
|
|
59
|
+
|
|
60
|
+
1. Local GraphRAG MCP (loopback HTTP allowed):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
cia config set graphMcpEndpoint http://127.0.0.1:8012/mcp
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
2. Hosted staging/production GraphRAG MCP (HTTPS required):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
cia config set graphMcpEndpoint https://staging-mcp.chain-insights.ai/mcp
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
3. Optional one-shot override from environment (highest precedence for that process):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
export CHAIN_INSIGHTS_GRAPH_MCP_ENDPOINT=https://prod-mcp.example.com/mcp
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Validation rules:
|
|
79
|
+
|
|
80
|
+
- `http://` is accepted only for `localhost` / loopback addresses.
|
|
81
|
+
- Remote hosts must use `https://`.
|
|
82
|
+
- Endpoint URLs with credentials, query strings, or fragments are rejected.
|
|
83
|
+
|
|
84
|
+
Configuration precedence for `graphMcpEndpoint`:
|
|
85
|
+
|
|
86
|
+
1. `CHAIN_INSIGHTS_GRAPH_MCP_ENDPOINT` env var (`GRAPH_MCP_ENDPOINT` legacy alias also supported)
|
|
87
|
+
2. `cia config set graphMcpEndpoint ...` saved value
|
|
88
|
+
3. Local default `http://127.0.0.1:8012/mcp`
|
|
89
|
+
|
|
55
90
|
Check the configured endpoint and current GraphRAG MCP capabilities:
|
|
56
91
|
|
|
57
92
|
```bash
|
|
@@ -149,6 +184,9 @@ and local case state:
|
|
|
149
184
|
|
|
150
185
|
- `address_risk` starts a single-address screen with risk, behavior,
|
|
151
186
|
neighborhood context, and exchange exposure.
|
|
187
|
+
- `stake_insights` explains Bittensor coldkey-hotkey-netuid staking
|
|
188
|
+
relationships, aggregate stake movement amounts, top counterparties, first
|
|
189
|
+
and last activity, and source backend evidence.
|
|
152
190
|
- `track_funds` traces trusted victim/source funds through intermediaries to
|
|
153
191
|
exchange deposit candidates.
|
|
154
192
|
- `scam_topology` expands from a known victim incident into reviewable
|
package/bin/cli.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
// CJS shim
|
|
5
|
-
//
|
|
6
|
-
// (see references/get-shit-done/bin/gsd-sdk.js for the GSD precedent).
|
|
4
|
+
// CJS shim: bridges the npm bin entry to the ESM dist built by tsdown.
|
|
5
|
+
// Dynamic import() is the correct bridge pattern from CommonJS to ESM.
|
|
7
6
|
import('../dist/cli.mjs').catch((err) => {
|
|
8
7
|
console.error('Failed to load chain-insights:', err.message);
|
|
9
8
|
process.exit(1);
|
package/bin/install.cjs
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// Runs before node_modules exists; zero npm imports allowed.
|
|
6
6
|
// Extension is .cjs (not .js) because package.json has "type": "module" —
|
|
7
7
|
// a .js file would be treated as ESM and require() calls would crash.
|
|
8
|
-
// Adapted from GSD reference: references/get-shit-done/bin/install.js
|
|
9
8
|
|
|
10
9
|
const fs = require('fs');
|
|
11
10
|
const path = require('path');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import os from "node:os";
|
|
@@ -47,4 +47,4 @@ function activeDataDir(fallbackDataDir) {
|
|
|
47
47
|
//#endregion
|
|
48
48
|
export { active_exports as n, findActiveWorkspace as r, activeCasesRoot as t };
|
|
49
49
|
|
|
50
|
-
//# sourceMappingURL=active-
|
|
50
|
+
//# sourceMappingURL=active-ByNgjuAg.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-
|
|
1
|
+
{"version":3,"file":"active-ByNgjuAg.mjs","names":[],"sources":["../src/workspace/active.ts"],"sourcesContent":["import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\ninterface WorkspaceConfig {\n schema?: string\n workspace_root?: string\n cases_dir?: string\n}\n\nexport interface ActiveWorkspace {\n root: string\n metadataDir: string\n casesRoot: string\n}\n\nfunction workspaceFromRoot(rootCandidate: string): ActiveWorkspace | null {\n const root = path.resolve(rootCandidate)\n const metadataDir = path.join(root, '.chain-insights')\n const markerPath = path.join(metadataDir, 'workspace.json')\n if (!fs.existsSync(markerPath)) return null\n\n const parsed = JSON.parse(fs.readFileSync(markerPath, 'utf8')) as WorkspaceConfig\n if (parsed.schema !== 'chain-insights.workspace.v1') return null\n\n const workspaceRoot = path.resolve(parsed.workspace_root ?? root)\n const casesDir = parsed.cases_dir ?? 'cases'\n return {\n root: workspaceRoot,\n metadataDir: path.join(workspaceRoot, '.chain-insights'),\n casesRoot: path.resolve(workspaceRoot, casesDir),\n }\n}\n\nexport function findActiveWorkspace(startDir = process.cwd()): ActiveWorkspace | null {\n const envWorkspace = process.env['CHAIN_INSIGHTS_WORKSPACE']?.trim()\n if (envWorkspace) {\n const active = workspaceFromRoot(envWorkspace)\n if (active) return active\n }\n\n let current = path.resolve(startDir)\n while (true) {\n const active = workspaceFromRoot(current)\n if (active) return active\n\n const parent = path.dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n\nexport function activeMetadataDir(): string {\n return findActiveWorkspace()?.metadataDir ?? path.join(os.homedir(), '.chain-insights')\n}\n\nexport function activeCasesRoot(): string {\n return findActiveWorkspace()?.casesRoot ?? path.join(os.homedir(), '.chain-insights', 'cases')\n}\n\nexport function activeDataDir(fallbackDataDir?: string): string {\n return findActiveWorkspace()?.root ?? fallbackDataDir ?? path.join(os.homedir(), '.chain-insights')\n}\n"],"mappings":";;;;;;;;;;AAgBA,SAAS,kBAAkB,eAA+C;CACxE,MAAM,OAAO,KAAK,QAAQ,aAAa;CACvC,MAAM,cAAc,KAAK,KAAK,MAAM,iBAAiB;CACrD,MAAM,aAAa,KAAK,KAAK,aAAa,gBAAgB;CAC1D,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG,OAAO;CAEvC,MAAM,SAAS,KAAK,MAAM,GAAG,aAAa,YAAY,MAAM,CAAC;CAC7D,IAAI,OAAO,WAAW,+BAA+B,OAAO;CAE5D,MAAM,gBAAgB,KAAK,QAAQ,OAAO,kBAAkB,IAAI;CAChE,MAAM,WAAW,OAAO,aAAa;CACrC,OAAO;EACL,MAAM;EACN,aAAa,KAAK,KAAK,eAAe,iBAAiB;EACvD,WAAW,KAAK,QAAQ,eAAe,QAAQ;CACjD;AACF;AAEA,SAAgB,oBAAoB,WAAW,QAAQ,IAAI,GAA2B;CACpF,MAAM,eAAe,QAAQ,IAAI,6BAA6B,KAAK;CACnE,IAAI,cAAc;EAChB,MAAM,SAAS,kBAAkB,YAAY;EAC7C,IAAI,QAAQ,OAAO;CACrB;CAEA,IAAI,UAAU,KAAK,QAAQ,QAAQ;CACnC,OAAO,MAAM;EACX,MAAM,SAAS,kBAAkB,OAAO;EACxC,IAAI,QAAQ,OAAO;EAEnB,MAAM,SAAS,KAAK,QAAQ,OAAO;EACnC,IAAI,WAAW,SAAS,OAAO;EAC/B,UAAU;CACZ;AACF;AAMA,SAAgB,kBAA0B;CACxC,OAAO,oBAAoB,GAAG,aAAa,KAAK,KAAK,GAAG,QAAQ,GAAG,mBAAmB,OAAO;AAC/F;AAEA,SAAgB,cAAc,iBAAkC;CAC9D,OAAO,oBAAoB,GAAG,QAAQ,mBAAmB,KAAK,KAAK,GAAG,QAAQ,GAAG,iBAAiB;AACpG"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_chunk = require("./chunk-
|
|
1
|
+
const require_chunk = require("./chunk-DakpK96I.cjs");
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
node_path = require_chunk.__toESM(node_path, 1);
|
|
4
4
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -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-
|
|
103
|
+
const { loadConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
|
|
104
104
|
const config = await loadConfig();
|
|
105
105
|
return c.json({
|
|
106
106
|
dataDir: config.dataDir,
|
|
@@ -118,7 +118,7 @@ function createApp() {
|
|
|
118
118
|
app.get("/graph-reports/:filename", async (c) => {
|
|
119
119
|
const filename = c.req.param("filename");
|
|
120
120
|
if (!isSafeGraphReportFilename(filename)) return c.json({ error: "Invalid graph report filename" }, 400);
|
|
121
|
-
const { workspaceOutputPaths } = await Promise.resolve().then(() => require("./output-root-
|
|
121
|
+
const { workspaceOutputPaths } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
122
122
|
const paths = workspaceOutputPaths();
|
|
123
123
|
const graphPath = node_path.default.resolve(paths.reportGraphsRoot, filename);
|
|
124
124
|
if (!withinRoot(paths.reportGraphsRoot, graphPath)) return c.json({ error: "Invalid graph report filename" }, 400);
|
|
@@ -137,7 +137,7 @@ function createApp() {
|
|
|
137
137
|
return c.json({ error: "Invalid graph report filename" }, 400);
|
|
138
138
|
});
|
|
139
139
|
app.get("/workspace/tree", async (c) => {
|
|
140
|
-
const { workspaceOutputPaths } = await Promise.resolve().then(() => require("./output-root-
|
|
140
|
+
const { workspaceOutputPaths } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
141
141
|
const paths = workspaceOutputPaths();
|
|
142
142
|
const entries = await listWorkspaceEntries(paths.root, WORKSPACE_TREE_ROOTS);
|
|
143
143
|
return c.json({
|
|
@@ -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-
|
|
100
|
+
const { loadConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
|
|
101
101
|
const config = await loadConfig();
|
|
102
102
|
return c.json({
|
|
103
103
|
dataDir: config.dataDir,
|
|
@@ -115,7 +115,7 @@ function createApp() {
|
|
|
115
115
|
app.get("/graph-reports/:filename", async (c) => {
|
|
116
116
|
const filename = c.req.param("filename");
|
|
117
117
|
if (!isSafeGraphReportFilename(filename)) return c.json({ error: "Invalid graph report filename" }, 400);
|
|
118
|
-
const { workspaceOutputPaths } = await import("./output-root-
|
|
118
|
+
const { workspaceOutputPaths } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
119
119
|
const paths = workspaceOutputPaths();
|
|
120
120
|
const graphPath = path.resolve(paths.reportGraphsRoot, filename);
|
|
121
121
|
if (!withinRoot(paths.reportGraphsRoot, graphPath)) return c.json({ error: "Invalid graph report filename" }, 400);
|
|
@@ -134,7 +134,7 @@ function createApp() {
|
|
|
134
134
|
return c.json({ error: "Invalid graph report filename" }, 400);
|
|
135
135
|
});
|
|
136
136
|
app.get("/workspace/tree", async (c) => {
|
|
137
|
-
const { workspaceOutputPaths } = await import("./output-root-
|
|
137
|
+
const { workspaceOutputPaths } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
138
138
|
const paths = workspaceOutputPaths();
|
|
139
139
|
const entries = await listWorkspaceEntries(paths.root, WORKSPACE_TREE_ROOTS);
|
|
140
140
|
return c.json({
|
|
@@ -152,4 +152,4 @@ function createApp() {
|
|
|
152
152
|
//#endregion
|
|
153
153
|
export { createApp as t };
|
|
154
154
|
|
|
155
|
-
//# sourceMappingURL=app-
|
|
155
|
+
//# sourceMappingURL=app-CRd39JJ8.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-BjjuQM0B.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-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,4 +1,4 @@
|
|
|
1
|
-
import { t as createApp } from "./app-
|
|
1
|
+
import { t as createApp } from "./app-CRd39JJ8.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-
|
|
48
|
+
//# sourceMappingURL=artifact-server-CP6LXQ9d.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-server-
|
|
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,5 +1,4 @@
|
|
|
1
|
-
require("./
|
|
2
|
-
const require_app = require("./app-Dq1TdB6p.cjs");
|
|
1
|
+
const require_app = require("./app-BxojXjtB.cjs");
|
|
3
2
|
let _hono_node_server = require("@hono/node-server");
|
|
4
3
|
let node_timers_promises = require("node:timers/promises");
|
|
5
4
|
//#region src/mcp/artifact-server.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"call-args-
|
|
1
|
+
{"version":3,"file":"call-args-DPXdX3_D.mjs","names":[],"sources":["../src/mcp/call-args.ts"],"sourcesContent":["const NUMERIC_ARG_KEYS = new Set([\n 'per_query_timeout_seconds',\n 'incident_timestamp_ms',\n 'max_hops',\n 'per_address_limit',\n 'min_amount_sum',\n])\n\nfunction parseMcpArgValue(key: string, value: string): unknown {\n const trimmed = value.trim()\n if (!trimmed) return value\n\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n return JSON.parse(trimmed) as unknown\n }\n\n if (NUMERIC_ARG_KEYS.has(key) && /^-?\\d+(?:\\.\\d+)?$/.test(trimmed)) {\n return Number(trimmed)\n }\n\n return value\n}\n\nexport function parseMcpCallArgs(rawArgs: string[]): Record<string, unknown> {\n const args: Record<string, unknown> = {}\n for (const pair of rawArgs) {\n const eqIdx = pair.indexOf('=')\n if (eqIdx === -1) {\n throw new Error(`Invalid arg format: ${pair} (expected key=value)`)\n }\n const key = pair.slice(0, eqIdx)\n args[key] = parseMcpArgValue(key, pair.slice(eqIdx + 1))\n }\n return args\n}\n"],"mappings":";AAAA,MAAM,mBAAmB,IAAI,IAAI;CAC/B;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,iBAAiB,KAAa,OAAwB;CAC7D,MAAM,UAAU,MAAM,KAAK;CAC3B,IAAI,CAAC,SAAS,OAAO;CAErB,IAAI,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,GAAG,GACnD,OAAO,KAAK,MAAM,OAAO;CAG3B,IAAI,iBAAiB,IAAI,GAAG,KAAK,oBAAoB,KAAK,OAAO,GAC/D,OAAO,OAAO,OAAO;CAGvB,OAAO;AACT;AAEA,SAAgB,iBAAiB,SAA4C;CAC3E,MAAM,OAAgC,CAAC;CACvC,KAAK,MAAM,QAAQ,SAAS;EAC1B,MAAM,QAAQ,KAAK,QAAQ,GAAG;EAC9B,IAAI,UAAU,IACZ,MAAM,IAAI,MAAM,uBAAuB,KAAK,sBAAsB;EAEpE,MAAM,MAAM,KAAK,MAAM,GAAG,KAAK;EAC/B,KAAK,OAAO,iBAAiB,KAAK,KAAK,MAAM,QAAQ,CAAC,CAAC;CACzD;CACA,OAAO;AACT"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as resolveGraphMcpEndpoint } from "./client-D4_hd4AP.mjs";
|
|
2
2
|
//#region src/mcp/capabilities.ts
|
|
3
3
|
function metadataNetworksUrl(endpoint) {
|
|
4
4
|
const url = new URL(endpoint);
|
|
@@ -81,4 +81,4 @@ function formatNetworkCapabilities(document) {
|
|
|
81
81
|
//#endregion
|
|
82
82
|
export { fetchNetworkCapabilities, formatNetworkCapabilities };
|
|
83
83
|
|
|
84
|
-
//# sourceMappingURL=capabilities-
|
|
84
|
+
//# sourceMappingURL=capabilities-BShqspb-.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities-
|
|
1
|
+
{"version":3,"file":"capabilities-BShqspb-.mjs","names":[],"sources":["../src/mcp/capabilities.ts"],"sourcesContent":["import type { InvestigatorConfig } from '../config/schema.js'\nimport { 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 headers.set('X-MCP-Debug-Token', token)\n headers.set('Authorization', `Bearer ${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,OAAO;EACT,QAAQ,IAAI,qBAAqB,KAAK;EACtC,QAAQ,IAAI,iBAAiB,UAAU,OAAO;CAChD;CACA,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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
require("./frontmatter-Dvqa5HX6.cjs");
|
|
2
|
+
const require_dossier = require("./dossier-Br62hCG7.cjs");
|
|
3
|
+
const require_store = require("./store-DogLawSj.cjs");
|
|
4
|
+
const require_evidence = require("./evidence-CvEesemA.cjs");
|
|
5
|
+
const require_session = require("./session-DwyikazY.cjs");
|
|
6
|
+
exports.CaseStore = require_store.CaseStore;
|
|
7
|
+
exports.DossierStore = require_dossier.DossierStore;
|
|
8
|
+
exports.EvidenceStore = require_evidence.EvidenceStore;
|
|
9
|
+
exports.SessionStore = require_session.SessionStore;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import "./frontmatter-D0ccQnUM.mjs";
|
|
2
|
+
import { DossierStore } from "./dossier-Bl0NkJKC.mjs";
|
|
3
|
+
import { CaseStore } from "./store-BT2SCcQr.mjs";
|
|
4
|
+
import { t as EvidenceStore } from "./evidence-D96PTzOQ.mjs";
|
|
5
|
+
import { SessionStore } from "./session-Bha3zFrx.mjs";
|
|
6
|
+
export { CaseStore, DossierStore, EvidenceStore, SessionStore };
|