chain-insights 0.3.4 → 0.3.6

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 (54) hide show
  1. package/README.md +28 -11
  2. package/dist/canvas-Cn-maEIh.mjs +203 -0
  3. package/dist/canvas-Cn-maEIh.mjs.map +1 -0
  4. package/dist/canvas-p-oKCMjc.cjs +251 -0
  5. package/dist/cases-Bz_9XKEw.cjs +19 -0
  6. package/dist/cases-TVcAifxu.mjs +16 -0
  7. package/dist/cases-TVcAifxu.mjs.map +1 -0
  8. package/dist/cli.cjs +74 -28
  9. package/dist/cli.mjs +74 -28
  10. package/dist/cli.mjs.map +1 -1
  11. package/dist/{data-extractor-DZUJu1Bz.mjs → data-extractor-B4nHw1wZ.mjs} +2 -2
  12. package/dist/{data-extractor-DZUJu1Bz.mjs.map → data-extractor-B4nHw1wZ.mjs.map} +1 -1
  13. package/dist/{data-extractor-Cavd7wHk.cjs → data-extractor-DS4rzy3M.cjs} +1 -1
  14. package/dist/{export-BqTCO9lP.mjs → export-CBhcJuZ6.mjs} +8 -205
  15. package/dist/export-CBhcJuZ6.mjs.map +1 -0
  16. package/dist/{export-DsXgtCwO.cjs → export-D4v4-6F4.cjs} +16 -214
  17. package/dist/index.cjs +1 -1
  18. package/dist/index.mjs +1 -1
  19. package/dist/{init-DLBL_nVG.mjs → init-CKQ6F07J.mjs} +22 -5
  20. package/dist/init-CKQ6F07J.mjs.map +1 -0
  21. package/dist/{init-zqbd7i-_.cjs → init-Dhw8F23z.cjs} +21 -4
  22. package/dist/mcp-proxy.cjs +20 -20
  23. package/dist/mcp-proxy.mjs +20 -20
  24. package/dist/mcp-proxy.mjs.map +1 -1
  25. package/dist/{public-tools-wJoAFDFa.mjs → public-tools-CyUZEz9B.mjs} +3 -3
  26. package/dist/{public-tools-wJoAFDFa.mjs.map → public-tools-CyUZEz9B.mjs.map} +1 -1
  27. package/dist/{public-tools-BvMb3H2P.cjs → public-tools-xfVNz9NE.cjs} +2 -2
  28. package/dist/{runner-BhZ4lnF1.cjs → runner-CVo41fjz.cjs} +2 -2
  29. package/dist/{runner-DIJSbkjc.mjs → runner-DWuSy1Se.mjs} +3 -3
  30. package/dist/{runner-DIJSbkjc.mjs.map → runner-DWuSy1Se.mjs.map} +1 -1
  31. package/dist/{selector-CF2o5gxN.mjs → selector-BvXM9jbe.mjs} +2 -2
  32. package/dist/{selector-CF2o5gxN.mjs.map → selector-BvXM9jbe.mjs.map} +1 -1
  33. package/dist/{selector-DfAMZEC9.cjs → selector-Dps_ZFxq.cjs} +1 -1
  34. package/dist/{store-CTtqQtaE.mjs → store-C2B_AssI.mjs} +2 -2
  35. package/dist/{store-CTtqQtaE.mjs.map → store-C2B_AssI.mjs.map} +1 -1
  36. package/dist/{store-CqPfs47P.cjs → store-CQhU8dz8.cjs} +0 -18
  37. package/dist/vault-B2y78Ypu.cjs +560 -0
  38. package/dist/vault-z35Dohdq.mjs +560 -0
  39. package/dist/vault-z35Dohdq.mjs.map +1 -0
  40. package/dist/{viz-Dqp3C5kb.cjs → viz-D1620cBX.cjs} +3 -3
  41. package/dist/{viz-5y24S5X1.mjs → viz-DB5XFG1z.mjs} +4 -4
  42. package/dist/{viz-5y24S5X1.mjs.map → viz-DB5XFG1z.mjs.map} +1 -1
  43. package/docs/graph-tools.md +24 -8
  44. package/docs/investigation-workspaces.md +36 -10
  45. package/docs/knowledge-exports.md +6 -2
  46. package/docs/mcp-proxy.md +29 -7
  47. package/docs/obsidian-vault.md +130 -0
  48. package/package.json +1 -1
  49. package/skills/chain-insights-developer-experience/SKILL.md +2 -2
  50. package/skills/chain-insights-investigation/SKILL.md +1 -1
  51. package/dist/cases-Cp9DUbEV.mjs +0 -6
  52. package/dist/cases-sTY5aXav.cjs +0 -9
  53. package/dist/export-BqTCO9lP.mjs.map +0 -1
  54. package/dist/init-DLBL_nVG.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { t as LOCAL_GRAPH_MCP_ENDPOINT } from "./mcp-endpoint-DHs1cRFH.mjs";
2
+ import { assertNoVaultFileCollisions, scaffoldVault } from "./vault-z35Dohdq.mjs";
2
3
  import path from "node:path";
3
4
  import { access, mkdir, writeFile } from "node:fs/promises";
4
5
  //#region src/workspace/init.ts
@@ -13,7 +14,8 @@ const WORKSPACE_DIRS = [
13
14
  "reports",
14
15
  "reports/graphs",
15
16
  "reports/tables",
16
- "templates"
17
+ "templates",
18
+ "published"
17
19
  ];
18
20
  function todayIso() {
19
21
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -32,9 +34,11 @@ function workspaceJson(workspaceRoot) {
32
34
  created_at: todayIso()
33
35
  }, null, 2) + "\n";
34
36
  }
35
- const README = `# Chain Insights Investigations
37
+ const README = `# Chain Insights Investigation Vault
36
38
 
37
- This is a workspace for Chain Insights AML investigations.
39
+ This is a Chain Insights AML investigation workspace and Obsidian-compatible vault.
40
+ Open this directory in Obsidian to review cases, entities, evidence, graphs, and
41
+ published investigation bundles alongside the Chain Insights runtime metadata.
38
42
 
39
43
  ## Start
40
44
 
@@ -53,9 +57,14 @@ reports/ Final or interim analyst reports
53
57
  reports/graphs/ Graph JSON for visualization
54
58
  reports/tables/ Compact tabular extracts
55
59
  templates/ Reusable case/report templates
60
+ published/ Obsidian-ready case exports and published bundles
56
61
  .chain-insights/schema/ Runtime graph schema captures
57
62
  .chain-insights/runtime/ Workspace-local runtime process state and debug logs
58
63
  .chain-insights/runtime-skill/ Workspace-specific agent schema notes
64
+ .obsidian/ Obsidian vault configuration
65
+ Canvases/ Obsidian canvases for graph review
66
+ Entities/ Entity notes and indexes
67
+ Evidence/ Evidence notes and indexes
59
68
  \`\`\`
60
69
  `;
61
70
  const AGENTS = `# Agent Instructions
@@ -230,7 +239,10 @@ async function assertNoFileCollisions(workspaceRoot) {
230
239
  }
231
240
  async function initWorkspace(options) {
232
241
  const workspaceRoot = path.resolve(options.targetDir);
233
- if (!options.force) await assertNoFileCollisions(workspaceRoot);
242
+ if (!options.force) {
243
+ await assertNoFileCollisions(workspaceRoot);
244
+ await assertNoVaultFileCollisions(workspaceRoot);
245
+ }
234
246
  for (const dir of WORKSPACE_DIRS) await mkdir(path.join(workspaceRoot, dir), { recursive: true });
235
247
  const filesWritten = [];
236
248
  const flag = options.force ? "w" : "wx";
@@ -247,6 +259,11 @@ async function initWorkspace(options) {
247
259
  throw err;
248
260
  }
249
261
  }
262
+ const vault = await scaffoldVault({
263
+ workspaceRoot,
264
+ force: options.force
265
+ });
266
+ filesWritten.push(...vault.filesWritten);
250
267
  return {
251
268
  workspaceRoot,
252
269
  filesWritten
@@ -255,4 +272,4 @@ async function initWorkspace(options) {
255
272
  //#endregion
256
273
  export { initWorkspace };
257
274
 
258
- //# sourceMappingURL=init-DLBL_nVG.mjs.map
275
+ //# sourceMappingURL=init-CKQ6F07J.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-CKQ6F07J.mjs","names":[],"sources":["../src/workspace/init.ts"],"sourcesContent":["import { access, mkdir, writeFile } from 'node:fs/promises'\nimport path from 'node:path'\nimport { LOCAL_GRAPH_MCP_ENDPOINT } from '../config/mcp-endpoint.js'\nimport { assertNoVaultFileCollisions, scaffoldVault } from '../vault/index.js'\n\nexport interface InitWorkspaceOptions {\n targetDir: string\n force?: boolean\n}\n\nexport interface InitWorkspaceResult {\n workspaceRoot: string\n filesWritten: string[]\n}\n\nconst WORKSPACE_DIRS = [\n '.chain-insights',\n '.chain-insights/schema',\n '.chain-insights/runtime',\n '.chain-insights/runtime/logs',\n '.chain-insights/runtime-skill',\n 'cases',\n 'imports',\n 'reports',\n 'reports/graphs',\n 'reports/tables',\n 'templates',\n 'published',\n]\n\nfunction todayIso(): string {\n return new Date().toISOString().slice(0, 10)\n}\n\nfunction workspaceJson(workspaceRoot: string): string {\n return JSON.stringify({\n schema: 'chain-insights.workspace.v1',\n name: 'Chain Insights Investigations',\n workspace_root: workspaceRoot,\n default_network: 'bittensor',\n graph_mcp_endpoint: LOCAL_GRAPH_MCP_ENDPOINT,\n cases_dir: 'cases',\n imports_dir: 'imports',\n reports_dir: 'reports',\n templates_dir: 'templates',\n created_at: todayIso(),\n }, null, 2) + '\\n'\n}\n\nconst README = `# Chain Insights Investigation Vault\n\nThis is a Chain Insights AML investigation workspace and Obsidian-compatible vault.\nOpen this directory in Obsidian to review cases, entities, evidence, graphs, and\npublished investigation bundles alongside the Chain Insights runtime metadata.\n\n## Start\n\n\\`\\`\\`bash\nchain-insights mcp tools --refresh\nchain-insights wallet ready --check-only\n\\`\\`\\`\n\n## Layout\n\n\\`\\`\\`text\n.chain-insights/ Workspace metadata\ncases/ Case exports and notes\nimports/ External reports, CSVs, screenshots, raw notes\nreports/ Final or interim analyst reports\nreports/graphs/ Graph JSON for visualization\nreports/tables/ Compact tabular extracts\ntemplates/ Reusable case/report templates\npublished/ Obsidian-ready case exports and published bundles\n.chain-insights/schema/ Runtime graph schema captures\n.chain-insights/runtime/ Workspace-local runtime process state and debug logs\n.chain-insights/runtime-skill/ Workspace-specific agent schema notes\n.obsidian/ Obsidian vault configuration\nCanvases/ Obsidian canvases for graph review\nEntities/ Entity notes and indexes\nEvidence/ Evidence notes and indexes\n\\`\\`\\`\n`\n\nconst AGENTS = `# Agent Instructions\n\nYou are operating inside a Chain Insights investigation workspace.\n\n- Read README.md first.\n- If this directory is not initialized, run \\`cia init .\\` before investigation-producing commands.\n- Do not rerun init in an existing workspace unless replacing scaffolding with \\`--force\\`.\n- Read .chain-insights/runtime-skill/SKILL.md before graph queries.\n- Preserve full blockchain addresses exactly.\n- Do not guess the network for graph queries.\n- Capture or refresh graph schema before the first case query.\n- Save compact evidence with original graph field names.\n- Put canonical graph JSON in reports/graphs/ and analyst tables in reports/tables/.\n- Evidence files should summarize and point to graph/table outputs; do not paste large raw JSON blobs into evidence Markdown.\n- Investigation output must stay in this initialized workspace.\n- Never write cases, evidence, reports, graph JSON, HTML, schema captures, or logs to ~/.chain-insights.\n- Keep theories lightweight until evidence supports them.\n`\n\nconst CLAUDE = AGENTS\n\nconst CASE_BRIEF = `# Case Brief\n\n## Summary\n\nStatus:\nNetwork:\nCurrent Assessment:\n\n## Known Addresses\n\n## Claims To Validate\n\n## Evidence\n\n## Next Steps\n`\n\nconst IMPORTS_README = `# External Investigation Inputs\n\nPut user-provided or third-party investigation material here before turning it\ninto case evidence.\n\nExamples:\n\n- Exchange support exports\n- CSV extracts\n- Screenshots\n- Raw notes\n- Partner reports\n\nFiles in this directory are inputs, not verified evidence. When an import\nsupports a claim, summarize it into the case evidence manifest and reference\nthe original file path.\n`\n\nconst TEMPLATES_README = `# Reusable Workspace Templates\n\nStore local report, case, prompt, and evidence templates here.\n\nTemplates are optional workspace helpers. They are not evidence and should not\nbe treated as case state until copied into a case, evidence file, dossier, or\nreport.\n`\n\nconst RUNTIME_SKILL = `---\nname: chain-insights-runtime-schema\ndescription: Workspace-local Chain Insights runtime schema notes. Refresh this after connecting to a graph MCP endpoint.\n---\n\n# Runtime Graph Schema\n\nBefore the first investigation query, capture the live graph schema into:\n\n\\`\\`\\`text\n.chain-insights/schema/<network>.graph-schema.json\n\\`\\`\\`\n\nUse \\`graph_query_batch\\` for schema capture. Prefix current topology reads\nwith \\`USE live_topology\\`, historical topology reads with\n\\`USE archive_topology\\`, and fact reads with \\`USE facts\\`, for example:\n\n\\`\\`\\`bash\ncia mcp call graph_query_batch network=<network> 'queries=[{\"id\":\"node_labels\",\"query\":\"USE live_topology MATCH (n:Address) RETURN \\\"Address\\\" AS node_label, count(n) AS sample_count LIMIT 1\"},{\"id\":\"archive_flow_sample\",\"query\":\"USE archive_topology MATCH (:Address)-[f:FLOWS_TO]->(:Address) RETURN f.period_granularity AS granularity, f.amount_sum AS amount_sum LIMIT 20\"}]'\n\\`\\`\\`\n\nThen update this file with observed labels, relationship types, and allowed\nproperty names for the active network.\n\nRules:\n\n- Prefer \\`graph_query\\` and \\`graph_query_batch\\` for graph-language reads.\n- Use \\`USE live_topology\\` for recent topology, \\`USE archive_topology\\`\n for historical topology, and \\`USE facts\\` for labels, features,\n risk scores, assets, and enrichment. Address facts can be reached through\n relationships such as \\`(:Address)-[:HAS_FEATURE]->(:AddressFeature)\\`.\n Archived money-flow topology is exposed as\n \\`(:Address)-[:FLOWS_TO]->(:Address)\\` with \\`period_granularity\\`,\n \\`period_start_date\\`, and \\`period_end_date\\` on the relationship.\n- Preserve source schema field names in evidence and generated data files.\n- Do not rename, reinterpret, or add unit labels to graph fields unless the\n schema or query result explicitly supports that interpretation.\n- Keep evidence compact: select only the fields needed to support the claim.\n Avoid storing whole node or relationship property blobs in evidence unless\n the purpose of the query is schema discovery or debugging.\n- When using BFS, fixed-depth traversal fallbacks, or any manual \\`FLOWS_TO\\`\n traversal, treat exchange hot wallets as terminal endpoints only. Do not\n expand from, through, or classify exchange nodes as deposit, suspect, or\n intermediate candidates. In Cypher, require every non-terminal traversal node\n to satisfy \\`is_exchange IS NULL\\`; only the final exchange endpoint should\n satisfy \\`is_exchange IS NOT NULL\\`.\n- Keep analysis products separate from evidence: graph JSON belongs under\n \\`reports/graphs/\\`, tabular extracts under \\`reports/tables/\\`, and analyst\n narrative under \\`reports/\\`.\n- Evidence Markdown should be a short provenance record with key facts and\n pointers. Large JSON belongs in \\`reports/tables/\\`, not inline in evidence.\n\nTrace tool chaining:\n\n1. Use \\`trace_victim_funds\\` when the user gives victim/source addresses.\n2. Pass returned \\`continuation.candidate_deposit_addresses\\` to\n \\`trace_deposit_sources\\`; do not make victim tracing run deposit traceback\n internally.\n3. Pass high-confidence \\`continuation.candidate_suspect_addresses\\` from\n deposit traceback to \\`trace_suspect_funds\\`.\n4. Use \\`trace_suspect_funds\\` when the user gives suspected scammer, mule,\n operator, or laundering-ring addresses. \\`incident_timestamp_ms\\` is\n optional.\n5. Use \\`address_risk\\` for single-address enrichment, and\n \\`graph_query_batch\\` only when the role-specific tools do not answer the\n exact question.\n\nAll trace tools return \\`chain-insights.trace.v1\\`. Preserve full addresses in\n\\`input.addresses\\`, \\`addresses[].address\\`, \\`edges[].from_address\\`,\n\\`edges[].to_address\\`, \\`paths[].addresses\\`, \\`candidate_labels[].address\\`,\nand \\`continuation\\` address lists.\n`\n\nconst SCHEMA_README = `# Runtime Schema Captures\n\nStore graph schema captures here, for example:\n\n\\`\\`\\`text\nbittensor.graph-schema.json\n\\`\\`\\`\n\nSchema captures should be generated before the first case query in a fresh\nworkspace, then referenced by evidence, reports, and runtime skill notes.\n`\n\nfunction workspaceFiles(workspaceRoot: string): Array<[string, string]> {\n return [\n ['.chain-insights/workspace.json', workspaceJson(workspaceRoot)],\n ['README.md', README],\n ['AGENTS.md', AGENTS],\n ['CLAUDE.md', CLAUDE],\n ['imports/README.md', IMPORTS_README],\n ['templates/README.md', TEMPLATES_README],\n ['templates/case-brief.md', CASE_BRIEF],\n ['.chain-insights/runtime-skill/SKILL.md', RUNTIME_SKILL],\n ['.chain-insights/schema/README.md', SCHEMA_README],\n ['.chain-insights/runtime/.keep', ''],\n ['.chain-insights/runtime/logs/.keep', ''],\n ]\n}\n\nasync function assertNoFileCollisions(workspaceRoot: string): Promise<void> {\n for (const [relativePath] of workspaceFiles(workspaceRoot)) {\n const filePath = path.join(workspaceRoot, relativePath)\n try {\n await access(filePath)\n throw new Error(`Refusing to overwrite ${filePath}. Re-run with --force to replace workspace files.`)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') {\n continue\n }\n throw err\n }\n }\n}\n\nexport async function initWorkspace(options: InitWorkspaceOptions): Promise<InitWorkspaceResult> {\n const workspaceRoot = path.resolve(options.targetDir)\n if (!options.force) {\n await assertNoFileCollisions(workspaceRoot)\n await assertNoVaultFileCollisions(workspaceRoot)\n }\n\n for (const dir of WORKSPACE_DIRS) {\n await mkdir(path.join(workspaceRoot, dir), { recursive: true })\n }\n\n const filesWritten: string[] = []\n const flag = options.force ? 'w' : 'wx'\n for (const [relativePath, content] of workspaceFiles(workspaceRoot)) {\n const filePath = path.join(workspaceRoot, relativePath)\n try {\n await writeFile(filePath, content, { mode: 0o600, flag })\n filesWritten.push(relativePath)\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST') {\n throw new Error(`Refusing to overwrite ${filePath}. Re-run with --force to replace workspace files.`)\n }\n throw err\n }\n }\n\n const vault = await scaffoldVault({ workspaceRoot, force: options.force })\n filesWritten.push(...vault.filesWritten)\n\n return { workspaceRoot, filesWritten }\n}\n"],"mappings":";;;;;AAeA,MAAM,iBAAiB;CACrB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,SAAS,WAAmB;CAC1B,wBAAO,IAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAC7C;AAEA,SAAS,cAAc,eAA+B;CACpD,OAAO,KAAK,UAAU;EACpB,QAAQ;EACR,MAAM;EACN,gBAAgB;EAChB,iBAAiB;EACjB,oBAAoB;EACpB,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,YAAY,SAAS;CACvB,GAAG,MAAM,CAAC,IAAI;AAChB;AAEA,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCf,MAAM,SAAS;;;;;;;;;;;;;;;;;;AAmBf,MAAM,SAAS;AAEf,MAAM,aAAa;;;;;;;;;;;;;;;;AAiBnB,MAAM,iBAAiB;;;;;;;;;;;;;;;;;AAkBvB,MAAM,mBAAmB;;;;;;;;AASzB,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyEtB,MAAM,gBAAgB;;;;;;;;;;;AAYtB,SAAS,eAAe,eAAgD;CACtE,OAAO;EACL,CAAC,kCAAkC,cAAc,aAAa,CAAC;EAC/D,CAAC,aAAa,MAAM;EACpB,CAAC,aAAa,MAAM;EACpB,CAAC,aAAa,MAAM;EACpB,CAAC,qBAAqB,cAAc;EACpC,CAAC,uBAAuB,gBAAgB;EACxC,CAAC,2BAA2B,UAAU;EACtC,CAAC,0CAA0C,aAAa;EACxD,CAAC,oCAAoC,aAAa;EAClD,CAAC,iCAAiC,EAAE;EACpC,CAAC,sCAAsC,EAAE;CAC3C;AACF;AAEA,eAAe,uBAAuB,eAAsC;CAC1E,KAAK,MAAM,CAAC,iBAAiB,eAAe,aAAa,GAAG;EAC1D,MAAM,WAAW,KAAK,KAAK,eAAe,YAAY;EACtD,IAAI;GACF,MAAM,OAAO,QAAQ;GACrB,MAAM,IAAI,MAAM,yBAAyB,SAAS,kDAAkD;EACtG,SAAS,KAAK;GACZ,IAAK,IAA8B,SAAS,UAC1C;GAEF,MAAM;EACR;CACF;AACF;AAEA,eAAsB,cAAc,SAA6D;CAC/F,MAAM,gBAAgB,KAAK,QAAQ,QAAQ,SAAS;CACpD,IAAI,CAAC,QAAQ,OAAO;EAClB,MAAM,uBAAuB,aAAa;EAC1C,MAAM,4BAA4B,aAAa;CACjD;CAEA,KAAK,MAAM,OAAO,gBAChB,MAAM,MAAM,KAAK,KAAK,eAAe,GAAG,GAAG,EAAE,WAAW,KAAK,CAAC;CAGhE,MAAM,eAAyB,CAAC;CAChC,MAAM,OAAO,QAAQ,QAAQ,MAAM;CACnC,KAAK,MAAM,CAAC,cAAc,YAAY,eAAe,aAAa,GAAG;EACnE,MAAM,WAAW,KAAK,KAAK,eAAe,YAAY;EACtD,IAAI;GACF,MAAM,UAAU,UAAU,SAAS;IAAE,MAAM;IAAO;GAAK,CAAC;GACxD,aAAa,KAAK,YAAY;EAChC,SAAS,KAAK;GACZ,IAAK,IAA8B,SAAS,UAC1C,MAAM,IAAI,MAAM,yBAAyB,SAAS,kDAAkD;GAEtG,MAAM;EACR;CACF;CAEA,MAAM,QAAQ,MAAM,cAAc;EAAE;EAAe,OAAO,QAAQ;CAAM,CAAC;CACzE,aAAa,KAAK,GAAG,MAAM,YAAY;CAEvC,OAAO;EAAE;EAAe;CAAa;AACvC"}
@@ -1,5 +1,6 @@
1
1
  const require_chunk = require("./chunk-DakpK96I.cjs");
2
2
  const require_mcp_endpoint = require("./mcp-endpoint-BaV8h_lq.cjs");
3
+ const require_vault = require("./vault-B2y78Ypu.cjs");
3
4
  let node_path = require("node:path");
4
5
  node_path = require_chunk.__toESM(node_path, 1);
5
6
  let node_fs_promises = require("node:fs/promises");
@@ -15,7 +16,8 @@ const WORKSPACE_DIRS = [
15
16
  "reports",
16
17
  "reports/graphs",
17
18
  "reports/tables",
18
- "templates"
19
+ "templates",
20
+ "published"
19
21
  ];
20
22
  function todayIso() {
21
23
  return (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
@@ -34,9 +36,11 @@ function workspaceJson(workspaceRoot) {
34
36
  created_at: todayIso()
35
37
  }, null, 2) + "\n";
36
38
  }
37
- const README = `# Chain Insights Investigations
39
+ const README = `# Chain Insights Investigation Vault
38
40
 
39
- This is a workspace for Chain Insights AML investigations.
41
+ This is a Chain Insights AML investigation workspace and Obsidian-compatible vault.
42
+ Open this directory in Obsidian to review cases, entities, evidence, graphs, and
43
+ published investigation bundles alongside the Chain Insights runtime metadata.
40
44
 
41
45
  ## Start
42
46
 
@@ -55,9 +59,14 @@ reports/ Final or interim analyst reports
55
59
  reports/graphs/ Graph JSON for visualization
56
60
  reports/tables/ Compact tabular extracts
57
61
  templates/ Reusable case/report templates
62
+ published/ Obsidian-ready case exports and published bundles
58
63
  .chain-insights/schema/ Runtime graph schema captures
59
64
  .chain-insights/runtime/ Workspace-local runtime process state and debug logs
60
65
  .chain-insights/runtime-skill/ Workspace-specific agent schema notes
66
+ .obsidian/ Obsidian vault configuration
67
+ Canvases/ Obsidian canvases for graph review
68
+ Entities/ Entity notes and indexes
69
+ Evidence/ Evidence notes and indexes
61
70
  \`\`\`
62
71
  `;
63
72
  const AGENTS = `# Agent Instructions
@@ -232,7 +241,10 @@ async function assertNoFileCollisions(workspaceRoot) {
232
241
  }
233
242
  async function initWorkspace(options) {
234
243
  const workspaceRoot = node_path.default.resolve(options.targetDir);
235
- if (!options.force) await assertNoFileCollisions(workspaceRoot);
244
+ if (!options.force) {
245
+ await assertNoFileCollisions(workspaceRoot);
246
+ await require_vault.assertNoVaultFileCollisions(workspaceRoot);
247
+ }
236
248
  for (const dir of WORKSPACE_DIRS) await (0, node_fs_promises.mkdir)(node_path.default.join(workspaceRoot, dir), { recursive: true });
237
249
  const filesWritten = [];
238
250
  const flag = options.force ? "w" : "wx";
@@ -249,6 +261,11 @@ async function initWorkspace(options) {
249
261
  throw err;
250
262
  }
251
263
  }
264
+ const vault = await require_vault.scaffoldVault({
265
+ workspaceRoot,
266
+ force: options.force
267
+ });
268
+ filesWritten.push(...vault.filesWritten);
252
269
  return {
253
270
  workspaceRoot,
254
271
  filesWritten
@@ -79,12 +79,12 @@ const NETWORK_DESCRIPTION = "Required network to query. Do not guess; use networ
79
79
  const REMOTE_GRAPH_TOOL_REQUEST_TIMEOUT_MS = 900 * 1e3;
80
80
  const CHAIN_INSIGHTS_WORKFLOW = [
81
81
  "Workflow:",
82
- "1. If the user is starting or continuing an investigation, use case_open or case_list/case_resume first.",
82
+ "1. Chain Insights workspaces are Obsidian-compatible vaults. If the user is starting or continuing an investigation, use case_open or case_list/case_resume first.",
83
83
  "2. Do not call investigation tools until required arguments are known. Network is required; use network_capabilities to check supported networks, data layers, retention, and freshness, or ask the user if missing.",
84
84
  "3. Use address_risk for single-address enrichment. Use trace_victim_funds for victim/source forward tracing, trace_deposit_sources for reverse traceback from suspected deposit endpoints, and trace_suspect_funds for suspect-controlled outbound laundering/cashout topology. Use stake_insights for Bittensor staking behavior. Use graph_query(_batch) only when the high-level trace tools do not answer the exact question.",
85
85
  "4. After a material result, preserve it with case_add_evidence when a case is active or ask whether to create/select a case.",
86
86
  "5. Use case_update_dossier for durable address/entity findings and case_start_session/case_end_session for session notes.",
87
- "6. When a case reaches a useful checkpoint, use case_verify_evidence and case_export to produce Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT-ready files."
87
+ "6. For local review, use live vault notes refreshed with cia case vault refresh. When a case reaches a sharing or archive checkpoint, use case_verify_evidence and case_export to produce Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT-ready handoff bundles."
88
88
  ].join("\n");
89
89
  const GRAPH_SCHEMA_HINTS = [
90
90
  "Graph query hints for network=bittensor:",
@@ -775,13 +775,13 @@ async function createProxy() {
775
775
  }
776
776
  }, async ({ name, tags, description }) => {
777
777
  try {
778
- const { CaseStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
778
+ const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
779
779
  const created = await CaseStore.create({
780
780
  name,
781
781
  tags: parseTags(tags),
782
782
  description: description ?? ""
783
783
  });
784
- const { casesRoot } = await Promise.resolve().then(() => require("./store-CqPfs47P.cjs")).then((n) => n.store_exports);
784
+ const { casesRoot } = await Promise.resolve().then(() => require("./store-CQhU8dz8.cjs")).then((n) => n.store_exports);
785
785
  return {
786
786
  content: [{
787
787
  type: "text",
@@ -815,7 +815,7 @@ async function createProxy() {
815
815
  }
816
816
  }, async ({ status }) => {
817
817
  try {
818
- const { CaseStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
818
+ const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
819
819
  const cases = await CaseStore.list();
820
820
  const filtered = status ? cases.filter((entry) => entry.status === status) : cases;
821
821
  return {
@@ -840,7 +840,7 @@ async function createProxy() {
840
840
  }
841
841
  }, async ({ case_id }) => {
842
842
  try {
843
- const { CaseStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
843
+ const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
844
844
  const context = await CaseStore.loadContext(case_id);
845
845
  return {
846
846
  content: [{
@@ -869,7 +869,7 @@ async function createProxy() {
869
869
  }
870
870
  }, async ({ case_id, source, content, query_params }) => {
871
871
  try {
872
- const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
872
+ const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
873
873
  const saved = await EvidenceStore.append(case_id, {
874
874
  source,
875
875
  content,
@@ -897,7 +897,7 @@ async function createProxy() {
897
897
  }
898
898
  }, async ({ case_id }) => {
899
899
  try {
900
- const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
900
+ const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
901
901
  const result = await EvidenceStore.verifyManifest(case_id);
902
902
  return {
903
903
  content: [{
@@ -911,7 +911,7 @@ async function createProxy() {
911
911
  }
912
912
  });
913
913
  server.registerTool("case_export", {
914
- description: "Export a Chain Insights case to an Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT-friendly local bundle.",
914
+ description: "Export a Chain Insights case to an Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT-friendly handoff bundle.",
915
915
  inputSchema: {
916
916
  case_id: zod.string().min(1).describe("Chain Insights case ID to export"),
917
917
  target: zod.enum(["obsidian-llmwiki"]).optional().describe("Export target. Default obsidian-llmwiki."),
@@ -930,7 +930,7 @@ async function createProxy() {
930
930
  }
931
931
  }, async ({ case_id, target, mode, output_dir }) => {
932
932
  try {
933
- const { exportCase } = await Promise.resolve().then(() => require("./export-DsXgtCwO.cjs"));
933
+ const { exportCase } = await Promise.resolve().then(() => require("./export-D4v4-6F4.cjs"));
934
934
  const result = await exportCase({
935
935
  caseId: case_id,
936
936
  target: target ?? "obsidian-llmwiki",
@@ -977,7 +977,7 @@ async function createProxy() {
977
977
  }
978
978
  }, async ({ case_id, address, finding, entity_type }) => {
979
979
  try {
980
- const { DossierStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
980
+ const { DossierStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
981
981
  await DossierStore.appendFinding(case_id, address, finding, entity_type ?? "unknown");
982
982
  return {
983
983
  content: [{
@@ -1005,7 +1005,7 @@ async function createProxy() {
1005
1005
  }
1006
1006
  }, async ({ case_id }) => {
1007
1007
  try {
1008
- const { SessionStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
1008
+ const { SessionStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
1009
1009
  const session = await SessionStore.start(case_id);
1010
1010
  return {
1011
1011
  content: [{
@@ -1033,7 +1033,7 @@ async function createProxy() {
1033
1033
  }
1034
1034
  }, async ({ case_id, findings, next_steps }) => {
1035
1035
  try {
1036
- const { SessionStore } = await Promise.resolve().then(() => require("./cases-sTY5aXav.cjs"));
1036
+ const { SessionStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
1037
1037
  await SessionStore.end(case_id, {
1038
1038
  findings: findings ?? "",
1039
1039
  nextSteps: next_steps ?? ""
@@ -1078,7 +1078,7 @@ async function createProxy() {
1078
1078
  }],
1079
1079
  isError: true
1080
1080
  };
1081
- const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-BvMb3H2P.cjs"));
1081
+ const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
1082
1082
  const { writeGraphReport } = await Promise.resolve().then(() => require("./graph-reports-B3mkLP8Z.cjs"));
1083
1083
  const { ensureArtifactServer } = await Promise.resolve().then(() => require("./artifact-server-XbN16DwU.cjs"));
1084
1084
  const result = await addressRisk(remoteClient, {
@@ -1150,7 +1150,7 @@ async function createProxy() {
1150
1150
  }],
1151
1151
  isError: true
1152
1152
  };
1153
- const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-BvMb3H2P.cjs"));
1153
+ const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
1154
1154
  const { writeGraphReport } = await Promise.resolve().then(() => require("./graph-reports-B3mkLP8Z.cjs"));
1155
1155
  const { ensureArtifactServer } = await Promise.resolve().then(() => require("./artifact-server-XbN16DwU.cjs"));
1156
1156
  const result = await traceVictimFunds(remoteClient, config, {
@@ -1226,7 +1226,7 @@ async function createProxy() {
1226
1226
  }],
1227
1227
  isError: true
1228
1228
  };
1229
- const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-BvMb3H2P.cjs"));
1229
+ const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
1230
1230
  const { writeGraphReport } = await Promise.resolve().then(() => require("./graph-reports-B3mkLP8Z.cjs"));
1231
1231
  const { ensureArtifactServer } = await Promise.resolve().then(() => require("./artifact-server-XbN16DwU.cjs"));
1232
1232
  const result = await traceSuspectFunds(remoteClient, config, {
@@ -1298,7 +1298,7 @@ async function createProxy() {
1298
1298
  }],
1299
1299
  isError: true
1300
1300
  };
1301
- const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-BvMb3H2P.cjs"));
1301
+ const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
1302
1302
  const { writeGraphReport } = await Promise.resolve().then(() => require("./graph-reports-B3mkLP8Z.cjs"));
1303
1303
  const { ensureArtifactServer } = await Promise.resolve().then(() => require("./artifact-server-XbN16DwU.cjs"));
1304
1304
  const result = await traceDepositSources(remoteClient, config, {
@@ -1373,7 +1373,7 @@ async function createProxy() {
1373
1373
  }],
1374
1374
  isError: true
1375
1375
  };
1376
- const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-BvMb3H2P.cjs"));
1376
+ const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
1377
1377
  const { writeGraphReport } = await Promise.resolve().then(() => require("./graph-reports-B3mkLP8Z.cjs"));
1378
1378
  const { ensureArtifactServer } = await Promise.resolve().then(() => require("./artifact-server-XbN16DwU.cjs"));
1379
1379
  const result = await stakeInsights(remoteClient, {
@@ -1430,7 +1430,7 @@ async function createProxy() {
1430
1430
  content: [{
1431
1431
  type: "text",
1432
1432
  text: [
1433
- "Chain Insights AML investigation workspace for AI agents.",
1433
+ "Chain Insights AML investigation workspace for AI agents. Workspaces are Obsidian-compatible vaults backed by plain local files.",
1434
1434
  "",
1435
1435
  CHAIN_INSIGHTS_WORKFLOW,
1436
1436
  "",
@@ -1450,7 +1450,7 @@ async function createProxy() {
1450
1450
  "- case_resume: load case context, evidence count, dossiers, and latest session.",
1451
1451
  "- case_add_evidence: append a report or note to the case evidence manifest.",
1452
1452
  "- case_verify_evidence: verify saved evidence integrity.",
1453
- "- case_export: export a case for Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT.",
1453
+ "- case_export: export a case for Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT handoff bundles.",
1454
1454
  "- case_update_dossier: add a finding to an address/entity dossier.",
1455
1455
  "- case_start_session and case_end_session: record session notes.",
1456
1456
  "",
@@ -75,12 +75,12 @@ const NETWORK_DESCRIPTION = "Required network to query. Do not guess; use networ
75
75
  const REMOTE_GRAPH_TOOL_REQUEST_TIMEOUT_MS = 900 * 1e3;
76
76
  const CHAIN_INSIGHTS_WORKFLOW = [
77
77
  "Workflow:",
78
- "1. If the user is starting or continuing an investigation, use case_open or case_list/case_resume first.",
78
+ "1. Chain Insights workspaces are Obsidian-compatible vaults. If the user is starting or continuing an investigation, use case_open or case_list/case_resume first.",
79
79
  "2. Do not call investigation tools until required arguments are known. Network is required; use network_capabilities to check supported networks, data layers, retention, and freshness, or ask the user if missing.",
80
80
  "3. Use address_risk for single-address enrichment. Use trace_victim_funds for victim/source forward tracing, trace_deposit_sources for reverse traceback from suspected deposit endpoints, and trace_suspect_funds for suspect-controlled outbound laundering/cashout topology. Use stake_insights for Bittensor staking behavior. Use graph_query(_batch) only when the high-level trace tools do not answer the exact question.",
81
81
  "4. After a material result, preserve it with case_add_evidence when a case is active or ask whether to create/select a case.",
82
82
  "5. Use case_update_dossier for durable address/entity findings and case_start_session/case_end_session for session notes.",
83
- "6. When a case reaches a useful checkpoint, use case_verify_evidence and case_export to produce Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT-ready files."
83
+ "6. For local review, use live vault notes refreshed with cia case vault refresh. When a case reaches a sharing or archive checkpoint, use case_verify_evidence and case_export to produce Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT-ready handoff bundles."
84
84
  ].join("\n");
85
85
  const GRAPH_SCHEMA_HINTS = [
86
86
  "Graph query hints for network=bittensor:",
@@ -771,13 +771,13 @@ async function createProxy() {
771
771
  }
772
772
  }, async ({ name, tags, description }) => {
773
773
  try {
774
- const { CaseStore } = await import("./cases-Cp9DUbEV.mjs");
774
+ const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
775
775
  const created = await CaseStore.create({
776
776
  name,
777
777
  tags: parseTags(tags),
778
778
  description: description ?? ""
779
779
  });
780
- const { casesRoot } = await import("./store-CTtqQtaE.mjs").then((n) => n.r);
780
+ const { casesRoot } = await import("./store-C2B_AssI.mjs").then((n) => n.n);
781
781
  return {
782
782
  content: [{
783
783
  type: "text",
@@ -811,7 +811,7 @@ async function createProxy() {
811
811
  }
812
812
  }, async ({ status }) => {
813
813
  try {
814
- const { CaseStore } = await import("./cases-Cp9DUbEV.mjs");
814
+ const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
815
815
  const cases = await CaseStore.list();
816
816
  const filtered = status ? cases.filter((entry) => entry.status === status) : cases;
817
817
  return {
@@ -836,7 +836,7 @@ async function createProxy() {
836
836
  }
837
837
  }, async ({ case_id }) => {
838
838
  try {
839
- const { CaseStore } = await import("./cases-Cp9DUbEV.mjs");
839
+ const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
840
840
  const context = await CaseStore.loadContext(case_id);
841
841
  return {
842
842
  content: [{
@@ -865,7 +865,7 @@ async function createProxy() {
865
865
  }
866
866
  }, async ({ case_id, source, content, query_params }) => {
867
867
  try {
868
- const { EvidenceStore } = await import("./cases-Cp9DUbEV.mjs");
868
+ const { EvidenceStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
869
869
  const saved = await EvidenceStore.append(case_id, {
870
870
  source,
871
871
  content,
@@ -893,7 +893,7 @@ async function createProxy() {
893
893
  }
894
894
  }, async ({ case_id }) => {
895
895
  try {
896
- const { EvidenceStore } = await import("./cases-Cp9DUbEV.mjs");
896
+ const { EvidenceStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
897
897
  const result = await EvidenceStore.verifyManifest(case_id);
898
898
  return {
899
899
  content: [{
@@ -907,7 +907,7 @@ async function createProxy() {
907
907
  }
908
908
  });
909
909
  server.registerTool("case_export", {
910
- description: "Export a Chain Insights case to an Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT-friendly local bundle.",
910
+ description: "Export a Chain Insights case to an Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT-friendly handoff bundle.",
911
911
  inputSchema: {
912
912
  case_id: z.string().min(1).describe("Chain Insights case ID to export"),
913
913
  target: z.enum(["obsidian-llmwiki"]).optional().describe("Export target. Default obsidian-llmwiki."),
@@ -926,7 +926,7 @@ async function createProxy() {
926
926
  }
927
927
  }, async ({ case_id, target, mode, output_dir }) => {
928
928
  try {
929
- const { exportCase } = await import("./export-BqTCO9lP.mjs");
929
+ const { exportCase } = await import("./export-CBhcJuZ6.mjs");
930
930
  const result = await exportCase({
931
931
  caseId: case_id,
932
932
  target: target ?? "obsidian-llmwiki",
@@ -973,7 +973,7 @@ async function createProxy() {
973
973
  }
974
974
  }, async ({ case_id, address, finding, entity_type }) => {
975
975
  try {
976
- const { DossierStore } = await import("./cases-Cp9DUbEV.mjs");
976
+ const { DossierStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
977
977
  await DossierStore.appendFinding(case_id, address, finding, entity_type ?? "unknown");
978
978
  return {
979
979
  content: [{
@@ -1001,7 +1001,7 @@ async function createProxy() {
1001
1001
  }
1002
1002
  }, async ({ case_id }) => {
1003
1003
  try {
1004
- const { SessionStore } = await import("./cases-Cp9DUbEV.mjs");
1004
+ const { SessionStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
1005
1005
  const session = await SessionStore.start(case_id);
1006
1006
  return {
1007
1007
  content: [{
@@ -1029,7 +1029,7 @@ async function createProxy() {
1029
1029
  }
1030
1030
  }, async ({ case_id, findings, next_steps }) => {
1031
1031
  try {
1032
- const { SessionStore } = await import("./cases-Cp9DUbEV.mjs");
1032
+ const { SessionStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
1033
1033
  await SessionStore.end(case_id, {
1034
1034
  findings: findings ?? "",
1035
1035
  nextSteps: next_steps ?? ""
@@ -1074,7 +1074,7 @@ async function createProxy() {
1074
1074
  }],
1075
1075
  isError: true
1076
1076
  };
1077
- const { addressRisk } = await import("./public-tools-wJoAFDFa.mjs");
1077
+ const { addressRisk } = await import("./public-tools-CyUZEz9B.mjs");
1078
1078
  const { writeGraphReport } = await import("./graph-reports-BDELxmpi.mjs");
1079
1079
  const { ensureArtifactServer } = await import("./artifact-server-CP6LXQ9d.mjs");
1080
1080
  const result = await addressRisk(remoteClient, {
@@ -1146,7 +1146,7 @@ async function createProxy() {
1146
1146
  }],
1147
1147
  isError: true
1148
1148
  };
1149
- const { traceVictimFunds } = await import("./public-tools-wJoAFDFa.mjs");
1149
+ const { traceVictimFunds } = await import("./public-tools-CyUZEz9B.mjs");
1150
1150
  const { writeGraphReport } = await import("./graph-reports-BDELxmpi.mjs");
1151
1151
  const { ensureArtifactServer } = await import("./artifact-server-CP6LXQ9d.mjs");
1152
1152
  const result = await traceVictimFunds(remoteClient, config, {
@@ -1222,7 +1222,7 @@ async function createProxy() {
1222
1222
  }],
1223
1223
  isError: true
1224
1224
  };
1225
- const { traceSuspectFunds } = await import("./public-tools-wJoAFDFa.mjs");
1225
+ const { traceSuspectFunds } = await import("./public-tools-CyUZEz9B.mjs");
1226
1226
  const { writeGraphReport } = await import("./graph-reports-BDELxmpi.mjs");
1227
1227
  const { ensureArtifactServer } = await import("./artifact-server-CP6LXQ9d.mjs");
1228
1228
  const result = await traceSuspectFunds(remoteClient, config, {
@@ -1294,7 +1294,7 @@ async function createProxy() {
1294
1294
  }],
1295
1295
  isError: true
1296
1296
  };
1297
- const { traceDepositSources } = await import("./public-tools-wJoAFDFa.mjs");
1297
+ const { traceDepositSources } = await import("./public-tools-CyUZEz9B.mjs");
1298
1298
  const { writeGraphReport } = await import("./graph-reports-BDELxmpi.mjs");
1299
1299
  const { ensureArtifactServer } = await import("./artifact-server-CP6LXQ9d.mjs");
1300
1300
  const result = await traceDepositSources(remoteClient, config, {
@@ -1369,7 +1369,7 @@ async function createProxy() {
1369
1369
  }],
1370
1370
  isError: true
1371
1371
  };
1372
- const { stakeInsights } = await import("./public-tools-wJoAFDFa.mjs");
1372
+ const { stakeInsights } = await import("./public-tools-CyUZEz9B.mjs");
1373
1373
  const { writeGraphReport } = await import("./graph-reports-BDELxmpi.mjs");
1374
1374
  const { ensureArtifactServer } = await import("./artifact-server-CP6LXQ9d.mjs");
1375
1375
  const result = await stakeInsights(remoteClient, {
@@ -1426,7 +1426,7 @@ async function createProxy() {
1426
1426
  content: [{
1427
1427
  type: "text",
1428
1428
  text: [
1429
- "Chain Insights AML investigation workspace for AI agents.",
1429
+ "Chain Insights AML investigation workspace for AI agents. Workspaces are Obsidian-compatible vaults backed by plain local files.",
1430
1430
  "",
1431
1431
  CHAIN_INSIGHTS_WORKFLOW,
1432
1432
  "",
@@ -1446,7 +1446,7 @@ async function createProxy() {
1446
1446
  "- case_resume: load case context, evidence count, dossiers, and latest session.",
1447
1447
  "- case_add_evidence: append a report or note to the case evidence manifest.",
1448
1448
  "- case_verify_evidence: verify saved evidence integrity.",
1449
- "- case_export: export a case for Obsidian, LLMWiki, Codex, Claude Code, and ChatGPT.",
1449
+ "- case_export: export a case for Obsidian, LLM Wiki, Codex, Claude Code, and ChatGPT handoff bundles.",
1450
1450
  "- case_update_dossier: add a finding to an address/entity dossier.",
1451
1451
  "- case_start_session and case_end_session: record session notes.",
1452
1452
  "",