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.
- package/README.md +28 -11
- package/dist/canvas-Cn-maEIh.mjs +203 -0
- package/dist/canvas-Cn-maEIh.mjs.map +1 -0
- package/dist/canvas-p-oKCMjc.cjs +251 -0
- package/dist/cases-Bz_9XKEw.cjs +19 -0
- package/dist/cases-TVcAifxu.mjs +16 -0
- package/dist/cases-TVcAifxu.mjs.map +1 -0
- package/dist/cli.cjs +74 -28
- package/dist/cli.mjs +74 -28
- package/dist/cli.mjs.map +1 -1
- package/dist/{data-extractor-DZUJu1Bz.mjs → data-extractor-B4nHw1wZ.mjs} +2 -2
- package/dist/{data-extractor-DZUJu1Bz.mjs.map → data-extractor-B4nHw1wZ.mjs.map} +1 -1
- package/dist/{data-extractor-Cavd7wHk.cjs → data-extractor-DS4rzy3M.cjs} +1 -1
- package/dist/{export-BqTCO9lP.mjs → export-CBhcJuZ6.mjs} +8 -205
- package/dist/export-CBhcJuZ6.mjs.map +1 -0
- package/dist/{export-DsXgtCwO.cjs → export-D4v4-6F4.cjs} +16 -214
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{init-DLBL_nVG.mjs → init-CKQ6F07J.mjs} +22 -5
- package/dist/init-CKQ6F07J.mjs.map +1 -0
- package/dist/{init-zqbd7i-_.cjs → init-Dhw8F23z.cjs} +21 -4
- package/dist/mcp-proxy.cjs +20 -20
- package/dist/mcp-proxy.mjs +20 -20
- package/dist/mcp-proxy.mjs.map +1 -1
- package/dist/{public-tools-wJoAFDFa.mjs → public-tools-CyUZEz9B.mjs} +3 -3
- package/dist/{public-tools-wJoAFDFa.mjs.map → public-tools-CyUZEz9B.mjs.map} +1 -1
- package/dist/{public-tools-BvMb3H2P.cjs → public-tools-xfVNz9NE.cjs} +2 -2
- package/dist/{runner-BhZ4lnF1.cjs → runner-CVo41fjz.cjs} +2 -2
- package/dist/{runner-DIJSbkjc.mjs → runner-DWuSy1Se.mjs} +3 -3
- package/dist/{runner-DIJSbkjc.mjs.map → runner-DWuSy1Se.mjs.map} +1 -1
- package/dist/{selector-CF2o5gxN.mjs → selector-BvXM9jbe.mjs} +2 -2
- package/dist/{selector-CF2o5gxN.mjs.map → selector-BvXM9jbe.mjs.map} +1 -1
- package/dist/{selector-DfAMZEC9.cjs → selector-Dps_ZFxq.cjs} +1 -1
- package/dist/{store-CTtqQtaE.mjs → store-C2B_AssI.mjs} +2 -2
- package/dist/{store-CTtqQtaE.mjs.map → store-C2B_AssI.mjs.map} +1 -1
- package/dist/{store-CqPfs47P.cjs → store-CQhU8dz8.cjs} +0 -18
- package/dist/vault-B2y78Ypu.cjs +560 -0
- package/dist/vault-z35Dohdq.mjs +560 -0
- package/dist/vault-z35Dohdq.mjs.map +1 -0
- package/dist/{viz-Dqp3C5kb.cjs → viz-D1620cBX.cjs} +3 -3
- package/dist/{viz-5y24S5X1.mjs → viz-DB5XFG1z.mjs} +4 -4
- package/dist/{viz-5y24S5X1.mjs.map → viz-DB5XFG1z.mjs.map} +1 -1
- package/docs/graph-tools.md +24 -8
- package/docs/investigation-workspaces.md +36 -10
- package/docs/knowledge-exports.md +6 -2
- package/docs/mcp-proxy.md +29 -7
- package/docs/obsidian-vault.md +130 -0
- package/package.json +1 -1
- package/skills/chain-insights-developer-experience/SKILL.md +2 -2
- package/skills/chain-insights-investigation/SKILL.md +1 -1
- package/dist/cases-Cp9DUbEV.mjs +0 -6
- package/dist/cases-sTY5aXav.cjs +0 -9
- package/dist/export-BqTCO9lP.mjs.map +0 -1
- package/dist/init-DLBL_nVG.mjs.map +0 -1
package/dist/cli.cjs
CHANGED
|
@@ -30,7 +30,7 @@ if (rawArgs[0] === "mcp" && [
|
|
|
30
30
|
process.exit(1);
|
|
31
31
|
}
|
|
32
32
|
async function resolveCaseSelector(input) {
|
|
33
|
-
const { resolveCaseSelector } = await Promise.resolve().then(() => require("./selector-
|
|
33
|
+
const { resolveCaseSelector } = await Promise.resolve().then(() => require("./selector-Dps_ZFxq.cjs"));
|
|
34
34
|
return resolveCaseSelector(input);
|
|
35
35
|
}
|
|
36
36
|
async function scopeCasesToInvocationDir() {
|
|
@@ -39,7 +39,7 @@ async function scopeCasesToInvocationDir() {
|
|
|
39
39
|
process.env["CHAIN_INSIGHTS_CASES_ROOT"] = activeCasesRoot();
|
|
40
40
|
}
|
|
41
41
|
async function showCaseContext(caseSelector) {
|
|
42
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
42
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
43
43
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
44
44
|
const ctx = await CaseStore.loadContext(caseId);
|
|
45
45
|
console.log(`\n=== Case: ${ctx.case.id} ===`);
|
|
@@ -129,6 +129,25 @@ program.command("status").description("Show toolkit status and configuration").a
|
|
|
129
129
|
console.log("Graph MCP:", graphMcpStatus);
|
|
130
130
|
console.log("Graph endpoint:", config.graphMcpEndpoint);
|
|
131
131
|
});
|
|
132
|
+
program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new commander.Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
|
|
133
|
+
try {
|
|
134
|
+
const { findActiveWorkspace } = await Promise.resolve().then(() => require("./active-BVr55kvW.cjs")).then((n) => n.active_exports);
|
|
135
|
+
const workspace = workspacePath ? node_path.default.resolve(workspacePath) : findActiveWorkspace()?.root;
|
|
136
|
+
if (!workspace) {
|
|
137
|
+
console.error("No Chain Insights workspace found. Run: cia init .");
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
const open = (await import("open")).default;
|
|
141
|
+
await open(workspace, {
|
|
142
|
+
app: { name: "obsidian" },
|
|
143
|
+
wait: false
|
|
144
|
+
});
|
|
145
|
+
} catch (err) {
|
|
146
|
+
console.error(err.message);
|
|
147
|
+
console.error("Open Obsidian manually and choose \"Open folder as vault\" for this workspace.");
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
150
|
+
}));
|
|
132
151
|
program.command("debug").description("Configure Graph MCP debug mode").addCommand(new commander.Command("on").description("Enable Graph MCP debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Graph MCP endpoint").action(async (opts) => {
|
|
133
152
|
try {
|
|
134
153
|
const { saveConfig } = await Promise.resolve().then(() => require("./config-BwVx19Og.cjs")).then((n) => n.config_exports);
|
|
@@ -214,7 +233,7 @@ program.command("access-key").description("Configure Graph MCP test access key m
|
|
|
214
233
|
}));
|
|
215
234
|
program.command("init").description("Initialize an investigation workspace").argument("[dir]", "Workspace directory to initialize", ".").option("--force", "Overwrite existing workspace files").action(async (dir, opts) => {
|
|
216
235
|
try {
|
|
217
|
-
const { initWorkspace } = await Promise.resolve().then(() => require("./init-
|
|
236
|
+
const { initWorkspace } = await Promise.resolve().then(() => require("./init-Dhw8F23z.cjs"));
|
|
218
237
|
const result = await initWorkspace({
|
|
219
238
|
targetDir: dir,
|
|
220
239
|
force: opts.force
|
|
@@ -403,7 +422,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
403
422
|
}));
|
|
404
423
|
return;
|
|
405
424
|
}
|
|
406
|
-
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-
|
|
425
|
+
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
407
426
|
const result = await addressRisk(client, {
|
|
408
427
|
address: opts.address,
|
|
409
428
|
network: opts.network,
|
|
@@ -431,7 +450,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
431
450
|
}));
|
|
432
451
|
return;
|
|
433
452
|
}
|
|
434
|
-
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
453
|
+
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
435
454
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
436
455
|
const result = await traceVictimFunds(client, config, {
|
|
437
456
|
victimAddresses: opts.victimAddresses,
|
|
@@ -455,7 +474,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
455
474
|
const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
456
475
|
requireWorkspaceRoot();
|
|
457
476
|
await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
|
|
458
|
-
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
477
|
+
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
459
478
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
460
479
|
const result = await traceSuspectFunds(client, config, {
|
|
461
480
|
suspectAddresses: opts.suspectAddresses,
|
|
@@ -478,7 +497,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
478
497
|
const { requireWorkspaceRoot } = await Promise.resolve().then(() => require("./output-root-YIbl6PwF.cjs")).then((n) => n.output_root_exports);
|
|
479
498
|
requireWorkspaceRoot();
|
|
480
499
|
await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
|
|
481
|
-
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-
|
|
500
|
+
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
482
501
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
483
502
|
const result = await traceDepositSources(client, config, {
|
|
484
503
|
depositAddresses: opts.depositAddresses,
|
|
@@ -496,7 +515,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
496
515
|
})).addCommand(new commander.Command("stake-insights").description("Explain Bittensor staking behavior around an address, coldkey, or hotkey").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--address <address>", "Full Bittensor address to inspect as either coldkey or hotkey").option("--coldkey <address>", "Full Bittensor coldkey address to inspect").option("--hotkey <address>", "Full Bittensor hotkey address to inspect").option("--netuid <number>", "Optional subnet netuid filter").option("--start-timestamp-ms <milliseconds>", "Optional inclusive lower activity timestamp bound").option("--end-timestamp-ms <milliseconds>", "Optional inclusive upper activity timestamp bound").option("--start-block <number>", "Optional start block. Current stake graph parity may require timestamp windows instead.").option("--end-block <number>", "Optional end block. Current stake graph parity may require timestamp windows instead.").option("--depth <number>", "Optional expansion depth limit, default 1, max 3").action(async (opts) => {
|
|
497
516
|
try {
|
|
498
517
|
await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
|
|
499
|
-
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-
|
|
518
|
+
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
500
519
|
const result = await stakeInsights(client, {
|
|
501
520
|
network: opts.network,
|
|
502
521
|
address: opts.address,
|
|
@@ -524,7 +543,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
524
543
|
assertPublicMcpToolName(tool);
|
|
525
544
|
await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
|
|
526
545
|
if (tool === "address_risk") {
|
|
527
|
-
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-
|
|
546
|
+
const { addressRisk } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
528
547
|
const result = await addressRisk(client, {
|
|
529
548
|
address: String(args["address"] ?? ""),
|
|
530
549
|
network: String(args["network"] ?? ""),
|
|
@@ -534,7 +553,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
534
553
|
return;
|
|
535
554
|
}
|
|
536
555
|
if (tool === "trace_victim_funds") {
|
|
537
|
-
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
556
|
+
const { traceVictimFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
538
557
|
const result = await traceVictimFunds(client, config, {
|
|
539
558
|
victimAddresses: args["victim_addresses"] ?? "",
|
|
540
559
|
knownSuspectAddresses: args["known_suspect_addresses"],
|
|
@@ -550,7 +569,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
550
569
|
return;
|
|
551
570
|
}
|
|
552
571
|
if (tool === "trace_suspect_funds") {
|
|
553
|
-
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-
|
|
572
|
+
const { traceSuspectFunds } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
554
573
|
const result = await traceSuspectFunds(client, config, {
|
|
555
574
|
suspectAddresses: args["suspect_addresses"] ?? "",
|
|
556
575
|
network: String(args["network"] ?? ""),
|
|
@@ -565,7 +584,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
565
584
|
return;
|
|
566
585
|
}
|
|
567
586
|
if (tool === "trace_deposit_sources") {
|
|
568
|
-
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-
|
|
587
|
+
const { traceDepositSources } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
569
588
|
const result = await traceDepositSources(client, config, {
|
|
570
589
|
depositAddresses: args["deposit_addresses"] ?? "",
|
|
571
590
|
network: String(args["network"] ?? ""),
|
|
@@ -577,7 +596,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
577
596
|
return;
|
|
578
597
|
}
|
|
579
598
|
if (tool === "stake_insights") {
|
|
580
|
-
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-
|
|
599
|
+
const { stakeInsights } = await Promise.resolve().then(() => require("./public-tools-xfVNz9NE.cjs"));
|
|
581
600
|
const result = await stakeInsights(client, {
|
|
582
601
|
network: String(args["network"] ?? ""),
|
|
583
602
|
address: args["address"] === void 0 ? void 0 : String(args["address"]),
|
|
@@ -609,24 +628,36 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
609
628
|
}).addCommand(new commander.Command("open").description("Open a new investigation case").argument("<name>", "Case name (e.g. \"Tornado Mixer Investigation\")").option("--tags <tags>", "Comma-separated tags (e.g. aml,mixer,defi)", "").option("--description <desc>", "Brief description of the investigation", "").action(async (name, opts) => {
|
|
610
629
|
try {
|
|
611
630
|
if (/^[1-9]\d*$/.test(name.trim())) throw new Error("Numeric case names look like list selectors. Use a descriptive case name, e.g. `cia case open \"Tracking stolen funds from <address>\"`.");
|
|
612
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
631
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
613
632
|
const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
|
|
614
633
|
const c = await CaseStore.create({
|
|
615
634
|
name,
|
|
616
635
|
tags,
|
|
617
636
|
description: opts.description
|
|
618
637
|
});
|
|
619
|
-
const { casesRoot } = await Promise.resolve().then(() => require("./store-
|
|
638
|
+
const { casesRoot } = await Promise.resolve().then(() => require("./store-CQhU8dz8.cjs")).then((n) => n.store_exports);
|
|
620
639
|
console.log(`Case opened: ${c.id}`);
|
|
621
640
|
console.log(`Directory: ${node_path.default.join(casesRoot(), c.id)}/`);
|
|
622
641
|
console.log(`Status: ${c.status}`);
|
|
642
|
+
const { findActiveWorkspace } = await Promise.resolve().then(() => require("./active-BVr55kvW.cjs")).then((n) => n.active_exports);
|
|
643
|
+
if (findActiveWorkspace()) try {
|
|
644
|
+
const { refreshCaseVault } = await Promise.resolve().then(() => require("./vault-B2y78Ypu.cjs"));
|
|
645
|
+
const result = await refreshCaseVault({
|
|
646
|
+
caseId: c.id,
|
|
647
|
+
force: true
|
|
648
|
+
});
|
|
649
|
+
console.log(`Open first: ${result.nextFile}`);
|
|
650
|
+
} catch (refreshErr) {
|
|
651
|
+
console.error(`Warning: live vault refresh failed: ${refreshErr.message}`);
|
|
652
|
+
console.error(`Run: cia case vault refresh ${c.id} --force`);
|
|
653
|
+
}
|
|
623
654
|
} catch (err) {
|
|
624
655
|
console.error(err.message);
|
|
625
656
|
process.exit(1);
|
|
626
657
|
}
|
|
627
658
|
})).addCommand(new commander.Command("activate").description("Activate a case (set status to active)").argument("<case-id>", "Case ID to activate").action(async (caseSelector) => {
|
|
628
659
|
try {
|
|
629
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
660
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
630
661
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
631
662
|
const c = await CaseStore.setStatus(caseId, "active");
|
|
632
663
|
console.log(`Case ${c.id} is now: active`);
|
|
@@ -636,7 +667,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
636
667
|
}
|
|
637
668
|
})).addCommand(new commander.Command("suspend").description("Suspend a case (set status to suspended)").argument("<case-id>", "Case ID to suspend").action(async (caseSelector) => {
|
|
638
669
|
try {
|
|
639
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
670
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
640
671
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
641
672
|
const c = await CaseStore.setStatus(caseId, "suspended");
|
|
642
673
|
console.log(`Case ${c.id} is now: suspended`);
|
|
@@ -646,7 +677,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
646
677
|
}
|
|
647
678
|
})).addCommand(new commander.Command("close").description("Close a case permanently").argument("<case-id>", "Case ID to close").action(async (caseSelector) => {
|
|
648
679
|
try {
|
|
649
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
680
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
650
681
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
651
682
|
const c = await CaseStore.setStatus(caseId, "closed");
|
|
652
683
|
console.log(`Case ${c.id} is now: closed`);
|
|
@@ -656,7 +687,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
656
687
|
}
|
|
657
688
|
})).addCommand(new commander.Command("list").description("List all investigation cases").option("--status <status>", "Filter by status (open|active|suspended|closed)").action(async (opts) => {
|
|
658
689
|
try {
|
|
659
|
-
const { CaseStore } = await Promise.resolve().then(() => require("./cases-
|
|
690
|
+
const { CaseStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
660
691
|
const cases = await CaseStore.list();
|
|
661
692
|
const filtered = opts.status ? cases.filter((c) => c.status === opts.status) : cases;
|
|
662
693
|
if (filtered.length === 0) {
|
|
@@ -670,7 +701,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
670
701
|
}
|
|
671
702
|
})).addCommand(new commander.Command("evidence").description("Manage case evidence").addCommand(new commander.Command("add").description("Add evidence to a case from an MCP query result").argument("<case-id>", "Case ID to add evidence to").option("--source <tool>", "MCP tool name that produced this evidence", "manual").option("--content <text>", "Evidence content (MCP response or notes)", "").option("--query-params <params>", "Query parameters used (e.g. address=0x1234)", "").action(async (caseSelector, opts) => {
|
|
672
703
|
try {
|
|
673
|
-
const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-
|
|
704
|
+
const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
674
705
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
675
706
|
const result = await EvidenceStore.append(caseId, {
|
|
676
707
|
source: opts.source,
|
|
@@ -685,7 +716,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
685
716
|
}
|
|
686
717
|
})).addCommand(new commander.Command("verify").description("Verify evidence manifest integrity for a case").argument("<case-id>", "Case ID to verify").action(async (caseSelector) => {
|
|
687
718
|
try {
|
|
688
|
-
const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-
|
|
719
|
+
const { EvidenceStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
689
720
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
690
721
|
const result = await EvidenceStore.verifyManifest(caseId);
|
|
691
722
|
if (result.ok) console.log(`Manifest OK — ${result.count} evidence file(s) verified`);
|
|
@@ -699,7 +730,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
699
730
|
}
|
|
700
731
|
}))).addCommand(new commander.Command("dossier").description("Manage entity dossiers for a case").addCommand(new commander.Command("update").description("Append a finding to an entity dossier").argument("<case-id>", "Case ID").argument("<address>", "Entity address or identifier").option("--finding <text>", "Finding to append to the dossier", "").option("--type <type>", "Entity type (eoa|contract|exchange|mixer|unknown)", "unknown").action(async (caseSelector, address, opts) => {
|
|
701
732
|
try {
|
|
702
|
-
const { DossierStore } = await Promise.resolve().then(() => require("./cases-
|
|
733
|
+
const { DossierStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
703
734
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
704
735
|
const entityType = [
|
|
705
736
|
"eoa",
|
|
@@ -716,7 +747,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
716
747
|
}
|
|
717
748
|
}))).addCommand(new commander.Command("session").description("Manage investigation sessions").addCommand(new commander.Command("start").description("Start a new investigation session for a case").argument("<case-id>", "Case ID").argument("[title...]", "Optional session title").action(async (caseSelector, titleParts) => {
|
|
718
749
|
try {
|
|
719
|
-
const { SessionStore } = await Promise.resolve().then(() => require("./cases-
|
|
750
|
+
const { SessionStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
720
751
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
721
752
|
const title = titleParts.join(" ").trim();
|
|
722
753
|
const s = await SessionStore.start(caseId, title ? { title } : {});
|
|
@@ -727,7 +758,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
727
758
|
}
|
|
728
759
|
})).addCommand(new commander.Command("end").description("End the current session with findings and next steps").argument("<case-id>", "Case ID").option("--findings <text>", "Key findings from this session", "").option("--next-steps <text>", "Next steps for the investigation", "").action(async (caseSelector, opts) => {
|
|
729
760
|
try {
|
|
730
|
-
const { SessionStore } = await Promise.resolve().then(() => require("./cases-
|
|
761
|
+
const { SessionStore } = await Promise.resolve().then(() => require("./cases-Bz_9XKEw.cjs")).then((n) => n.cases_exports);
|
|
731
762
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
732
763
|
await SessionStore.end(caseId, {
|
|
733
764
|
findings: opts.findings,
|
|
@@ -739,7 +770,22 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
739
770
|
console.error(err.message);
|
|
740
771
|
process.exit(1);
|
|
741
772
|
}
|
|
742
|
-
}))).addCommand(new commander.Command("
|
|
773
|
+
}))).addCommand(new commander.Command("vault").description("Manage live Obsidian case vault notes").addCommand(new commander.Command("refresh").description("Refresh Obsidian vault notes for a case").argument("<case-id-or-selector>", "Case ID or case list number to refresh").option("--force", "Overwrite existing generated case vault files").action(async (caseSelector, opts) => {
|
|
774
|
+
try {
|
|
775
|
+
const caseId = await resolveCaseSelector(caseSelector);
|
|
776
|
+
const { refreshCaseVault } = await Promise.resolve().then(() => require("./vault-B2y78Ypu.cjs"));
|
|
777
|
+
const result = await refreshCaseVault({
|
|
778
|
+
caseId,
|
|
779
|
+
force: opts.force === true
|
|
780
|
+
});
|
|
781
|
+
console.log(`Case vault refreshed: ${caseId}`);
|
|
782
|
+
console.log(`Files: ${result.filesWritten.length}`);
|
|
783
|
+
console.log(`Open first: ${result.nextFile}`);
|
|
784
|
+
} catch (err) {
|
|
785
|
+
console.error(err.message);
|
|
786
|
+
process.exit(1);
|
|
787
|
+
}
|
|
788
|
+
}))).addCommand(new commander.Command("export").description("Export a case for Obsidian, LLM Wiki, and agents").argument("<case-id>", "Case ID or case list number to export").option("--target <target>", "Export target: obsidian-llmwiki", "obsidian-llmwiki").option("--mode <mode>", "Redaction mode: private|partner|public", "private").option("--out <directory>", "Output directory. Defaults to published/<case-slug>").action(async (caseSelector, opts) => {
|
|
743
789
|
try {
|
|
744
790
|
const target = opts.target === "obsidian-llmwiki" ? opts.target : void 0;
|
|
745
791
|
const mode = [
|
|
@@ -750,7 +796,7 @@ const caseCommand = new commander.Command("case").description("Manage investigat
|
|
|
750
796
|
if (!target) throw new Error(`Unsupported export target: ${opts.target}`);
|
|
751
797
|
if (!mode) throw new Error(`Unsupported export mode: ${opts.mode}`);
|
|
752
798
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
753
|
-
const { exportCase } = await Promise.resolve().then(() => require("./export-
|
|
799
|
+
const { exportCase } = await Promise.resolve().then(() => require("./export-D4v4-6F4.cjs"));
|
|
754
800
|
const result = await exportCase({
|
|
755
801
|
caseId,
|
|
756
802
|
target,
|
|
@@ -804,7 +850,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
|
|
|
804
850
|
console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
|
|
805
851
|
process.exit(1);
|
|
806
852
|
}
|
|
807
|
-
const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-
|
|
853
|
+
const { PlaybookRunner } = await Promise.resolve().then(() => require("./runner-CVo41fjz.cjs"));
|
|
808
854
|
await PlaybookRunner.run(definition, {
|
|
809
855
|
caseId: opts.case,
|
|
810
856
|
from: fromN,
|
|
@@ -854,7 +900,7 @@ program.command("viz").description("Generate money flow visualization").argument
|
|
|
854
900
|
console.error("Provide either a case ID or --data <file.json>");
|
|
855
901
|
process.exit(1);
|
|
856
902
|
}
|
|
857
|
-
const { generateVisualization } = await Promise.resolve().then(() => require("./viz-
|
|
903
|
+
const { generateVisualization } = await Promise.resolve().then(() => require("./viz-D1620cBX.cjs")).then((n) => n.viz_exports);
|
|
858
904
|
const result = await generateVisualization({
|
|
859
905
|
caseId,
|
|
860
906
|
dataFile: opts.data
|
package/dist/cli.mjs
CHANGED
|
@@ -28,7 +28,7 @@ if (rawArgs[0] === "mcp" && [
|
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
30
|
async function resolveCaseSelector(input) {
|
|
31
|
-
const { resolveCaseSelector } = await import("./selector-
|
|
31
|
+
const { resolveCaseSelector } = await import("./selector-BvXM9jbe.mjs");
|
|
32
32
|
return resolveCaseSelector(input);
|
|
33
33
|
}
|
|
34
34
|
async function scopeCasesToInvocationDir() {
|
|
@@ -37,7 +37,7 @@ async function scopeCasesToInvocationDir() {
|
|
|
37
37
|
process.env["CHAIN_INSIGHTS_CASES_ROOT"] = activeCasesRoot();
|
|
38
38
|
}
|
|
39
39
|
async function showCaseContext(caseSelector) {
|
|
40
|
-
const { CaseStore } = await import("./cases-
|
|
40
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
41
41
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
42
42
|
const ctx = await CaseStore.loadContext(caseId);
|
|
43
43
|
console.log(`\n=== Case: ${ctx.case.id} ===`);
|
|
@@ -127,6 +127,25 @@ program.command("status").description("Show toolkit status and configuration").a
|
|
|
127
127
|
console.log("Graph MCP:", graphMcpStatus);
|
|
128
128
|
console.log("Graph endpoint:", config.graphMcpEndpoint);
|
|
129
129
|
});
|
|
130
|
+
program.command("obsidian").description("Manage the local Obsidian investigation vault").addCommand(new Command("open").description("Open the current Chain Insights vault in Obsidian").argument("[path]", "Workspace path to open as an Obsidian vault").action(async (workspacePath) => {
|
|
131
|
+
try {
|
|
132
|
+
const { findActiveWorkspace } = await import("./active-ByNgjuAg.mjs").then((n) => n.n);
|
|
133
|
+
const workspace = workspacePath ? path.resolve(workspacePath) : findActiveWorkspace()?.root;
|
|
134
|
+
if (!workspace) {
|
|
135
|
+
console.error("No Chain Insights workspace found. Run: cia init .");
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
const open = (await import("open")).default;
|
|
139
|
+
await open(workspace, {
|
|
140
|
+
app: { name: "obsidian" },
|
|
141
|
+
wait: false
|
|
142
|
+
});
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.error(err.message);
|
|
145
|
+
console.error("Open Obsidian manually and choose \"Open folder as vault\" for this workspace.");
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
}));
|
|
130
149
|
program.command("debug").description("Configure Graph MCP debug mode").addCommand(new Command("on").description("Enable Graph MCP debug mode without x402 payments").requiredOption("--token <token>", "Debug bearer token").option("--endpoint <url>", "Graph MCP endpoint").action(async (opts) => {
|
|
131
150
|
try {
|
|
132
151
|
const { saveConfig } = await import("./config-Drgc2HuF.mjs").then((n) => n.t);
|
|
@@ -212,7 +231,7 @@ program.command("access-key").description("Configure Graph MCP test access key m
|
|
|
212
231
|
}));
|
|
213
232
|
program.command("init").description("Initialize an investigation workspace").argument("[dir]", "Workspace directory to initialize", ".").option("--force", "Overwrite existing workspace files").action(async (dir, opts) => {
|
|
214
233
|
try {
|
|
215
|
-
const { initWorkspace } = await import("./init-
|
|
234
|
+
const { initWorkspace } = await import("./init-CKQ6F07J.mjs");
|
|
216
235
|
const result = await initWorkspace({
|
|
217
236
|
targetDir: dir,
|
|
218
237
|
force: opts.force
|
|
@@ -401,7 +420,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
401
420
|
}));
|
|
402
421
|
return;
|
|
403
422
|
}
|
|
404
|
-
const { addressRisk } = await import("./public-tools-
|
|
423
|
+
const { addressRisk } = await import("./public-tools-CyUZEz9B.mjs");
|
|
405
424
|
const result = await addressRisk(client, {
|
|
406
425
|
address: opts.address,
|
|
407
426
|
network: opts.network,
|
|
@@ -429,7 +448,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
429
448
|
}));
|
|
430
449
|
return;
|
|
431
450
|
}
|
|
432
|
-
const { traceVictimFunds } = await import("./public-tools-
|
|
451
|
+
const { traceVictimFunds } = await import("./public-tools-CyUZEz9B.mjs");
|
|
433
452
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
434
453
|
const result = await traceVictimFunds(client, config, {
|
|
435
454
|
victimAddresses: opts.victimAddresses,
|
|
@@ -453,7 +472,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
453
472
|
const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
454
473
|
requireWorkspaceRoot();
|
|
455
474
|
await withGraphMcpClient("chain-insights-cli-trace-suspect-funds", async (client, config) => {
|
|
456
|
-
const { traceSuspectFunds } = await import("./public-tools-
|
|
475
|
+
const { traceSuspectFunds } = await import("./public-tools-CyUZEz9B.mjs");
|
|
457
476
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
458
477
|
const result = await traceSuspectFunds(client, config, {
|
|
459
478
|
suspectAddresses: opts.suspectAddresses,
|
|
@@ -476,7 +495,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
476
495
|
const { requireWorkspaceRoot } = await import("./output-root-BRhzhhXZ.mjs").then((n) => n.t);
|
|
477
496
|
requireWorkspaceRoot();
|
|
478
497
|
await withGraphMcpClient("chain-insights-cli-trace-deposit-sources", async (client, config) => {
|
|
479
|
-
const { traceDepositSources } = await import("./public-tools-
|
|
498
|
+
const { traceDepositSources } = await import("./public-tools-CyUZEz9B.mjs");
|
|
480
499
|
const caseId = opts.case ? await resolveCaseSelector(opts.case) : void 0;
|
|
481
500
|
const result = await traceDepositSources(client, config, {
|
|
482
501
|
depositAddresses: opts.depositAddresses,
|
|
@@ -494,7 +513,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
494
513
|
})).addCommand(new Command("stake-insights").description("Explain Bittensor staking behavior around an address, coldkey, or hotkey").requiredOption("--network <network>", "Network to query. Run `cia mcp networks` for supported networks.").option("--address <address>", "Full Bittensor address to inspect as either coldkey or hotkey").option("--coldkey <address>", "Full Bittensor coldkey address to inspect").option("--hotkey <address>", "Full Bittensor hotkey address to inspect").option("--netuid <number>", "Optional subnet netuid filter").option("--start-timestamp-ms <milliseconds>", "Optional inclusive lower activity timestamp bound").option("--end-timestamp-ms <milliseconds>", "Optional inclusive upper activity timestamp bound").option("--start-block <number>", "Optional start block. Current stake graph parity may require timestamp windows instead.").option("--end-block <number>", "Optional end block. Current stake graph parity may require timestamp windows instead.").option("--depth <number>", "Optional expansion depth limit, default 1, max 3").action(async (opts) => {
|
|
495
514
|
try {
|
|
496
515
|
await withGraphMcpClient("chain-insights-cli-stake-insights", async (client) => {
|
|
497
|
-
const { stakeInsights } = await import("./public-tools-
|
|
516
|
+
const { stakeInsights } = await import("./public-tools-CyUZEz9B.mjs");
|
|
498
517
|
const result = await stakeInsights(client, {
|
|
499
518
|
network: opts.network,
|
|
500
519
|
address: opts.address,
|
|
@@ -522,7 +541,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
522
541
|
assertPublicMcpToolName(tool);
|
|
523
542
|
await withGraphMcpClient("chain-insights-cli-call", async (client, config) => {
|
|
524
543
|
if (tool === "address_risk") {
|
|
525
|
-
const { addressRisk } = await import("./public-tools-
|
|
544
|
+
const { addressRisk } = await import("./public-tools-CyUZEz9B.mjs");
|
|
526
545
|
const result = await addressRisk(client, {
|
|
527
546
|
address: String(args["address"] ?? ""),
|
|
528
547
|
network: String(args["network"] ?? ""),
|
|
@@ -532,7 +551,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
532
551
|
return;
|
|
533
552
|
}
|
|
534
553
|
if (tool === "trace_victim_funds") {
|
|
535
|
-
const { traceVictimFunds } = await import("./public-tools-
|
|
554
|
+
const { traceVictimFunds } = await import("./public-tools-CyUZEz9B.mjs");
|
|
536
555
|
const result = await traceVictimFunds(client, config, {
|
|
537
556
|
victimAddresses: args["victim_addresses"] ?? "",
|
|
538
557
|
knownSuspectAddresses: args["known_suspect_addresses"],
|
|
@@ -548,7 +567,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
548
567
|
return;
|
|
549
568
|
}
|
|
550
569
|
if (tool === "trace_suspect_funds") {
|
|
551
|
-
const { traceSuspectFunds } = await import("./public-tools-
|
|
570
|
+
const { traceSuspectFunds } = await import("./public-tools-CyUZEz9B.mjs");
|
|
552
571
|
const result = await traceSuspectFunds(client, config, {
|
|
553
572
|
suspectAddresses: args["suspect_addresses"] ?? "",
|
|
554
573
|
network: String(args["network"] ?? ""),
|
|
@@ -563,7 +582,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
563
582
|
return;
|
|
564
583
|
}
|
|
565
584
|
if (tool === "trace_deposit_sources") {
|
|
566
|
-
const { traceDepositSources } = await import("./public-tools-
|
|
585
|
+
const { traceDepositSources } = await import("./public-tools-CyUZEz9B.mjs");
|
|
567
586
|
const result = await traceDepositSources(client, config, {
|
|
568
587
|
depositAddresses: args["deposit_addresses"] ?? "",
|
|
569
588
|
network: String(args["network"] ?? ""),
|
|
@@ -575,7 +594,7 @@ program.command("mcp").description("Interact with the Chain Insights MCP endpoin
|
|
|
575
594
|
return;
|
|
576
595
|
}
|
|
577
596
|
if (tool === "stake_insights") {
|
|
578
|
-
const { stakeInsights } = await import("./public-tools-
|
|
597
|
+
const { stakeInsights } = await import("./public-tools-CyUZEz9B.mjs");
|
|
579
598
|
const result = await stakeInsights(client, {
|
|
580
599
|
network: String(args["network"] ?? ""),
|
|
581
600
|
address: args["address"] === void 0 ? void 0 : String(args["address"]),
|
|
@@ -607,24 +626,36 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
607
626
|
}).addCommand(new Command("open").description("Open a new investigation case").argument("<name>", "Case name (e.g. \"Tornado Mixer Investigation\")").option("--tags <tags>", "Comma-separated tags (e.g. aml,mixer,defi)", "").option("--description <desc>", "Brief description of the investigation", "").action(async (name, opts) => {
|
|
608
627
|
try {
|
|
609
628
|
if (/^[1-9]\d*$/.test(name.trim())) throw new Error("Numeric case names look like list selectors. Use a descriptive case name, e.g. `cia case open \"Tracking stolen funds from <address>\"`.");
|
|
610
|
-
const { CaseStore } = await import("./cases-
|
|
629
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
611
630
|
const tags = opts.tags ? opts.tags.split(",").map((t) => t.trim()).filter(Boolean) : [];
|
|
612
631
|
const c = await CaseStore.create({
|
|
613
632
|
name,
|
|
614
633
|
tags,
|
|
615
634
|
description: opts.description
|
|
616
635
|
});
|
|
617
|
-
const { casesRoot } = await import("./store-
|
|
636
|
+
const { casesRoot } = await import("./store-C2B_AssI.mjs").then((n) => n.n);
|
|
618
637
|
console.log(`Case opened: ${c.id}`);
|
|
619
638
|
console.log(`Directory: ${path.join(casesRoot(), c.id)}/`);
|
|
620
639
|
console.log(`Status: ${c.status}`);
|
|
640
|
+
const { findActiveWorkspace } = await import("./active-ByNgjuAg.mjs").then((n) => n.n);
|
|
641
|
+
if (findActiveWorkspace()) try {
|
|
642
|
+
const { refreshCaseVault } = await import("./vault-z35Dohdq.mjs");
|
|
643
|
+
const result = await refreshCaseVault({
|
|
644
|
+
caseId: c.id,
|
|
645
|
+
force: true
|
|
646
|
+
});
|
|
647
|
+
console.log(`Open first: ${result.nextFile}`);
|
|
648
|
+
} catch (refreshErr) {
|
|
649
|
+
console.error(`Warning: live vault refresh failed: ${refreshErr.message}`);
|
|
650
|
+
console.error(`Run: cia case vault refresh ${c.id} --force`);
|
|
651
|
+
}
|
|
621
652
|
} catch (err) {
|
|
622
653
|
console.error(err.message);
|
|
623
654
|
process.exit(1);
|
|
624
655
|
}
|
|
625
656
|
})).addCommand(new Command("activate").description("Activate a case (set status to active)").argument("<case-id>", "Case ID to activate").action(async (caseSelector) => {
|
|
626
657
|
try {
|
|
627
|
-
const { CaseStore } = await import("./cases-
|
|
658
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
628
659
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
629
660
|
const c = await CaseStore.setStatus(caseId, "active");
|
|
630
661
|
console.log(`Case ${c.id} is now: active`);
|
|
@@ -634,7 +665,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
634
665
|
}
|
|
635
666
|
})).addCommand(new Command("suspend").description("Suspend a case (set status to suspended)").argument("<case-id>", "Case ID to suspend").action(async (caseSelector) => {
|
|
636
667
|
try {
|
|
637
|
-
const { CaseStore } = await import("./cases-
|
|
668
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
638
669
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
639
670
|
const c = await CaseStore.setStatus(caseId, "suspended");
|
|
640
671
|
console.log(`Case ${c.id} is now: suspended`);
|
|
@@ -644,7 +675,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
644
675
|
}
|
|
645
676
|
})).addCommand(new Command("close").description("Close a case permanently").argument("<case-id>", "Case ID to close").action(async (caseSelector) => {
|
|
646
677
|
try {
|
|
647
|
-
const { CaseStore } = await import("./cases-
|
|
678
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
648
679
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
649
680
|
const c = await CaseStore.setStatus(caseId, "closed");
|
|
650
681
|
console.log(`Case ${c.id} is now: closed`);
|
|
@@ -654,7 +685,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
654
685
|
}
|
|
655
686
|
})).addCommand(new Command("list").description("List all investigation cases").option("--status <status>", "Filter by status (open|active|suspended|closed)").action(async (opts) => {
|
|
656
687
|
try {
|
|
657
|
-
const { CaseStore } = await import("./cases-
|
|
688
|
+
const { CaseStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
658
689
|
const cases = await CaseStore.list();
|
|
659
690
|
const filtered = opts.status ? cases.filter((c) => c.status === opts.status) : cases;
|
|
660
691
|
if (filtered.length === 0) {
|
|
@@ -668,7 +699,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
668
699
|
}
|
|
669
700
|
})).addCommand(new Command("evidence").description("Manage case evidence").addCommand(new Command("add").description("Add evidence to a case from an MCP query result").argument("<case-id>", "Case ID to add evidence to").option("--source <tool>", "MCP tool name that produced this evidence", "manual").option("--content <text>", "Evidence content (MCP response or notes)", "").option("--query-params <params>", "Query parameters used (e.g. address=0x1234)", "").action(async (caseSelector, opts) => {
|
|
670
701
|
try {
|
|
671
|
-
const { EvidenceStore } = await import("./cases-
|
|
702
|
+
const { EvidenceStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
672
703
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
673
704
|
const result = await EvidenceStore.append(caseId, {
|
|
674
705
|
source: opts.source,
|
|
@@ -683,7 +714,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
683
714
|
}
|
|
684
715
|
})).addCommand(new Command("verify").description("Verify evidence manifest integrity for a case").argument("<case-id>", "Case ID to verify").action(async (caseSelector) => {
|
|
685
716
|
try {
|
|
686
|
-
const { EvidenceStore } = await import("./cases-
|
|
717
|
+
const { EvidenceStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
687
718
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
688
719
|
const result = await EvidenceStore.verifyManifest(caseId);
|
|
689
720
|
if (result.ok) console.log(`Manifest OK — ${result.count} evidence file(s) verified`);
|
|
@@ -697,7 +728,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
697
728
|
}
|
|
698
729
|
}))).addCommand(new Command("dossier").description("Manage entity dossiers for a case").addCommand(new Command("update").description("Append a finding to an entity dossier").argument("<case-id>", "Case ID").argument("<address>", "Entity address or identifier").option("--finding <text>", "Finding to append to the dossier", "").option("--type <type>", "Entity type (eoa|contract|exchange|mixer|unknown)", "unknown").action(async (caseSelector, address, opts) => {
|
|
699
730
|
try {
|
|
700
|
-
const { DossierStore } = await import("./cases-
|
|
731
|
+
const { DossierStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
701
732
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
702
733
|
const entityType = [
|
|
703
734
|
"eoa",
|
|
@@ -714,7 +745,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
714
745
|
}
|
|
715
746
|
}))).addCommand(new Command("session").description("Manage investigation sessions").addCommand(new Command("start").description("Start a new investigation session for a case").argument("<case-id>", "Case ID").argument("[title...]", "Optional session title").action(async (caseSelector, titleParts) => {
|
|
716
747
|
try {
|
|
717
|
-
const { SessionStore } = await import("./cases-
|
|
748
|
+
const { SessionStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
718
749
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
719
750
|
const title = titleParts.join(" ").trim();
|
|
720
751
|
const s = await SessionStore.start(caseId, title ? { title } : {});
|
|
@@ -725,7 +756,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
725
756
|
}
|
|
726
757
|
})).addCommand(new Command("end").description("End the current session with findings and next steps").argument("<case-id>", "Case ID").option("--findings <text>", "Key findings from this session", "").option("--next-steps <text>", "Next steps for the investigation", "").action(async (caseSelector, opts) => {
|
|
727
758
|
try {
|
|
728
|
-
const { SessionStore } = await import("./cases-
|
|
759
|
+
const { SessionStore } = await import("./cases-TVcAifxu.mjs").then((n) => n.t);
|
|
729
760
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
730
761
|
await SessionStore.end(caseId, {
|
|
731
762
|
findings: opts.findings,
|
|
@@ -737,7 +768,22 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
737
768
|
console.error(err.message);
|
|
738
769
|
process.exit(1);
|
|
739
770
|
}
|
|
740
|
-
}))).addCommand(new Command("
|
|
771
|
+
}))).addCommand(new Command("vault").description("Manage live Obsidian case vault notes").addCommand(new Command("refresh").description("Refresh Obsidian vault notes for a case").argument("<case-id-or-selector>", "Case ID or case list number to refresh").option("--force", "Overwrite existing generated case vault files").action(async (caseSelector, opts) => {
|
|
772
|
+
try {
|
|
773
|
+
const caseId = await resolveCaseSelector(caseSelector);
|
|
774
|
+
const { refreshCaseVault } = await import("./vault-z35Dohdq.mjs");
|
|
775
|
+
const result = await refreshCaseVault({
|
|
776
|
+
caseId,
|
|
777
|
+
force: opts.force === true
|
|
778
|
+
});
|
|
779
|
+
console.log(`Case vault refreshed: ${caseId}`);
|
|
780
|
+
console.log(`Files: ${result.filesWritten.length}`);
|
|
781
|
+
console.log(`Open first: ${result.nextFile}`);
|
|
782
|
+
} catch (err) {
|
|
783
|
+
console.error(err.message);
|
|
784
|
+
process.exit(1);
|
|
785
|
+
}
|
|
786
|
+
}))).addCommand(new Command("export").description("Export a case for Obsidian, LLM Wiki, and agents").argument("<case-id>", "Case ID or case list number to export").option("--target <target>", "Export target: obsidian-llmwiki", "obsidian-llmwiki").option("--mode <mode>", "Redaction mode: private|partner|public", "private").option("--out <directory>", "Output directory. Defaults to published/<case-slug>").action(async (caseSelector, opts) => {
|
|
741
787
|
try {
|
|
742
788
|
const target = opts.target === "obsidian-llmwiki" ? opts.target : void 0;
|
|
743
789
|
const mode = [
|
|
@@ -748,7 +794,7 @@ const caseCommand = new Command("case").description("Manage investigation cases"
|
|
|
748
794
|
if (!target) throw new Error(`Unsupported export target: ${opts.target}`);
|
|
749
795
|
if (!mode) throw new Error(`Unsupported export mode: ${opts.mode}`);
|
|
750
796
|
const caseId = await resolveCaseSelector(caseSelector);
|
|
751
|
-
const { exportCase } = await import("./export-
|
|
797
|
+
const { exportCase } = await import("./export-CBhcJuZ6.mjs");
|
|
752
798
|
const result = await exportCase({
|
|
753
799
|
caseId,
|
|
754
800
|
target,
|
|
@@ -802,7 +848,7 @@ program.command("playbook").description("Run and manage investigation playbooks"
|
|
|
802
848
|
console.error(`Invalid --from value: "${opts.from}". Must be a positive integer.`);
|
|
803
849
|
process.exit(1);
|
|
804
850
|
}
|
|
805
|
-
const { PlaybookRunner } = await import("./runner-
|
|
851
|
+
const { PlaybookRunner } = await import("./runner-DWuSy1Se.mjs");
|
|
806
852
|
await PlaybookRunner.run(definition, {
|
|
807
853
|
caseId: opts.case,
|
|
808
854
|
from: fromN,
|
|
@@ -852,7 +898,7 @@ program.command("viz").description("Generate money flow visualization").argument
|
|
|
852
898
|
console.error("Provide either a case ID or --data <file.json>");
|
|
853
899
|
process.exit(1);
|
|
854
900
|
}
|
|
855
|
-
const { generateVisualization } = await import("./viz-
|
|
901
|
+
const { generateVisualization } = await import("./viz-DB5XFG1z.mjs").then((n) => n.n);
|
|
856
902
|
const result = await generateVisualization({
|
|
857
903
|
caseId,
|
|
858
904
|
dataFile: opts.data
|