dexe-mcp 0.7.2 → 0.8.1

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 (91) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/README.md +19 -1
  3. package/dist/cli/doctor.d.ts +11 -0
  4. package/dist/cli/doctor.d.ts.map +1 -0
  5. package/dist/cli/doctor.js +44 -0
  6. package/dist/cli/doctor.js.map +1 -0
  7. package/dist/cli/init.d.ts +2 -0
  8. package/dist/cli/init.d.ts.map +1 -0
  9. package/dist/cli/init.js +306 -0
  10. package/dist/cli/init.js.map +1 -0
  11. package/dist/diag/checks.d.ts +25 -0
  12. package/dist/diag/checks.d.ts.map +1 -0
  13. package/dist/diag/checks.js +387 -0
  14. package/dist/diag/checks.js.map +1 -0
  15. package/dist/env/loader.d.ts +43 -0
  16. package/dist/env/loader.d.ts.map +1 -0
  17. package/dist/env/loader.js +121 -0
  18. package/dist/env/loader.js.map +1 -0
  19. package/dist/env/parse.d.ts +23 -0
  20. package/dist/env/parse.d.ts.map +1 -0
  21. package/dist/env/parse.js +41 -0
  22. package/dist/env/parse.js.map +1 -0
  23. package/dist/env/schema.d.ts +257 -0
  24. package/dist/env/schema.d.ts.map +1 -0
  25. package/dist/env/schema.js +240 -0
  26. package/dist/env/schema.js.map +1 -0
  27. package/dist/governor/tools/extras.js +12 -3
  28. package/dist/governor/tools/extras.js.map +1 -1
  29. package/dist/governor/tools/read.js +16 -4
  30. package/dist/governor/tools/read.js.map +1 -1
  31. package/dist/governor/tools/simulate.d.ts.map +1 -1
  32. package/dist/governor/tools/simulate.js +8 -2
  33. package/dist/governor/tools/simulate.js.map +1 -1
  34. package/dist/index.js +31 -11
  35. package/dist/index.js.map +1 -1
  36. package/dist/lib/requireEnv.d.ts +30 -0
  37. package/dist/lib/requireEnv.d.ts.map +1 -0
  38. package/dist/lib/requireEnv.js +48 -0
  39. package/dist/lib/requireEnv.js.map +1 -0
  40. package/dist/lib/signer.d.ts +8 -0
  41. package/dist/lib/signer.d.ts.map +1 -1
  42. package/dist/lib/signer.js +18 -0
  43. package/dist/lib/signer.js.map +1 -1
  44. package/dist/rpc.d.ts +8 -0
  45. package/dist/rpc.d.ts.map +1 -1
  46. package/dist/rpc.js +18 -0
  47. package/dist/rpc.js.map +1 -1
  48. package/dist/tools/dao.d.ts.map +1 -1
  49. package/dist/tools/dao.js +25 -10
  50. package/dist/tools/dao.js.map +1 -1
  51. package/dist/tools/daoDeploy.js +8 -2
  52. package/dist/tools/daoDeploy.js.map +1 -1
  53. package/dist/tools/doctor.d.ts +11 -0
  54. package/dist/tools/doctor.d.ts.map +1 -0
  55. package/dist/tools/doctor.js +75 -0
  56. package/dist/tools/doctor.js.map +1 -0
  57. package/dist/tools/flow.d.ts.map +1 -1
  58. package/dist/tools/flow.js +16 -4
  59. package/dist/tools/flow.js.map +1 -1
  60. package/dist/tools/gov.js +8 -14
  61. package/dist/tools/gov.js.map +1 -1
  62. package/dist/tools/inbox.d.ts.map +1 -1
  63. package/dist/tools/inbox.js +7 -1
  64. package/dist/tools/inbox.js.map +1 -1
  65. package/dist/tools/index.d.ts.map +1 -1
  66. package/dist/tools/index.js +3 -0
  67. package/dist/tools/index.js.map +1 -1
  68. package/dist/tools/otc.d.ts.map +1 -1
  69. package/dist/tools/otc.js +15 -3
  70. package/dist/tools/otc.js.map +1 -1
  71. package/dist/tools/predict.d.ts.map +1 -1
  72. package/dist/tools/predict.js +7 -1
  73. package/dist/tools/predict.js.map +1 -1
  74. package/dist/tools/proposal.js +8 -2
  75. package/dist/tools/proposal.js.map +1 -1
  76. package/dist/tools/read.js +40 -10
  77. package/dist/tools/read.js.map +1 -1
  78. package/dist/tools/safe.d.ts.map +1 -1
  79. package/dist/tools/safe.js +12 -3
  80. package/dist/tools/safe.js.map +1 -1
  81. package/dist/tools/simulate.d.ts.map +1 -1
  82. package/dist/tools/simulate.js +16 -3
  83. package/dist/tools/simulate.js.map +1 -1
  84. package/dist/tools/subgraph.js +4 -1
  85. package/dist/tools/subgraph.js.map +1 -1
  86. package/dist/tools/txSend.d.ts.map +1 -1
  87. package/dist/tools/txSend.js +18 -1
  88. package/dist/tools/txSend.js.map +1 -1
  89. package/dist/tools/vote.js +8 -2
  90. package/dist/tools/vote.js.map +1 -1
  91. package/package.json +5 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,134 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.1 — 2026-05-30
4
+
5
+ ### Full soft-fail migration
6
+
7
+ Extends the soft-fail behavior shipped in 0.8.0 (`dexe_read_*` and
8
+ `dexe_tx_send`) to **every** remaining tool that touched the throwing
9
+ `RpcProvider.requireProvider()` / `SignerManager.requireSigner()`
10
+ variants. Missing env now surfaces uniformly across the entire MCP tool
11
+ catalog as a structured error with paste-ready remediation hints —
12
+ never a thrown stack reaching the MCP transport.
13
+
14
+ ### Changed
15
+
16
+ - 18 tool files migrated from the throwing variants to the soft
17
+ `tryProvider` / `trySigner` siblings:
18
+ - `src/tools/`: `dao.ts` (incl. the shared `requireBook` helper, now
19
+ returning `EnvGuardResult<AddressBook>`), `daoDeploy.ts`, `flow.ts`,
20
+ `gov.ts`, `inbox.ts`, `otc.ts`, `predict.ts`, `proposal.ts`,
21
+ `safe.ts`, `simulate.ts`, `subgraph.ts`, `vote.ts`
22
+ - `src/governor/tools/`: `extras.ts`, `read.ts`, `simulate.ts`
23
+ - The throwing `requireSigner` / `requireProvider` definitions stay in
24
+ `src/lib/signer.ts` and `src/rpc.ts` for backward compatibility — no
25
+ removed public API. Only the in-tree call sites moved.
26
+
27
+ ### Added
28
+
29
+ - `tests/lib/soft-fail-migration.test.ts` — regression guard that
30
+ asserts no direct `.requireProvider(` / `.requireSigner(` call exists
31
+ in `src/tools/**` or `src/governor/**`. Catches the regression at
32
+ test-run time if a future tool forgets the soft-fail pattern.
33
+
34
+ ### Notes
35
+
36
+ - No env contract change. No new vars. No caller-side change required.
37
+ - Patch-level release because the failure-mode contract is identical to
38
+ 0.8.0's; just applied uniformly across the catalog.
39
+
40
+ ## 0.8.0 — 2026-05-30
41
+
42
+ ### Env onboarding overhaul
43
+
44
+ This release exists to make first-run setup fail-safe for new users
45
+ (human or AI assistant). Previously, when an env var was missing or
46
+ typoed, tools threw raw stacks and the assistant had no way to discover
47
+ which file to edit, which key was missing, or whether `.claude.json` was
48
+ shadowing `.env`. Now there is one diagnostic, one wizard, one skill,
49
+ and one schema that drives every check.
50
+
51
+ **Upgrade:** zero env changes required, no breaking renames or removals.
52
+ See [`docs/MIGRATION.md`](docs/MIGRATION.md) for the 0.7.x → 0.8.0
53
+ guide and the documented behavior change in `dexe_read_*` /
54
+ `dexe_tx_send` error responses.
55
+
56
+ ### Added
57
+
58
+ - **`dexe_doctor` tool + CLI.** New diagnostic that walks every
59
+ recognized `DEXE_*` env var, runs reachability checks (RPC
60
+ `eth_chainId` per chain, Pinata `testAuthentication`, IPFS gateway DNS
61
+ lookup, subgraph `{__typename}` introspection, backend HEAD), and
62
+ reports pass/warn/fail per check with paste-ready remediation hints.
63
+ Network checks have a 3s hard timeout that downgrades to `warn` so
64
+ offline laptops don't see all-red. Also runnable as
65
+ `npx dexe-mcp doctor` (exit 0/1/2). See [`docs/DOCTOR.md`](docs/DOCTOR.md).
66
+ - **`npx dexe-mcp init` wizard.** Interactive onboarding via native
67
+ `node:readline/promises`. Asks four questions (network, Pinata JWT,
68
+ Graph API key, signer mode), writes `.env` at the repo root (merge or
69
+ overwrite), and prints a `~/.claude.json` snippet for copy-paste.
70
+ Validates the Pinata JWT against the live endpoint before writing.
71
+ Defaults the signer mode to readonly; warns explicitly and double-confirms
72
+ before storing a private key in plaintext. Never auto-edits
73
+ `.claude.json`. No new dependencies.
74
+ - **Schema-driven env handling.** `src/env/schema.ts` (`ENV_SPEC`,
75
+ `ENV_REGISTRY`) is now the canonical registry for every recognized
76
+ `DEXE_*` var (category, doc, zod schema, enabled flows, secret flag).
77
+ Consumed by the new parser, doctor, fail-soft guards, and the
78
+ `/dexe-setup` skill. Drift guarded by `tests/env/schema.test.ts`
79
+ against `.env.example`.
80
+ - **Startup self-diagnostic banner.** `src/env/loader.ts` reads `.env`
81
+ raw bytes before `process.loadEnvFile()` and emits stderr warnings
82
+ for: UTF-8 BOM, missing trailing newline, spaces around `=`, unknown
83
+ `DEXE_*` keys, and host-env shadowing of `.env` values. Surfaces
84
+ silent parse traps that previously made "I edited .env and nothing
85
+ changed" hard to diagnose.
86
+ - **Fail-soft guard helpers.** New `src/lib/requireEnv.ts` (`requireEnv`,
87
+ `hintFor`) generalizes the existing `requirePinata` pattern from
88
+ `src/tools/ipfs.ts`. Added `SignerManager.trySigner` and
89
+ `RpcProvider.tryProvider` siblings that return `{error, remediation}`
90
+ instead of throwing — keeps the throwing variants for backward
91
+ compatibility.
92
+ - **`/dexe-setup` skill** at `.claude/skills/dexe-setup/SKILL.md`. Calls
93
+ `dexe_doctor`, parses the report, asks the user only for missing
94
+ values, edits `.env` (never `.claude.json`), and tells the user to
95
+ restart Claude Code. Caps at 3 doctor → fix → restart iterations.
96
+ Hard rule: refuse to write `DEXE_PRIVATE_KEY` without explicit user
97
+ opt-in; suggest WalletConnect first.
98
+ - **`docs/SETUP.md` + `docs/DOCTOR.md` + `docs/MIGRATION.md`.**
99
+ Consolidated quickstart with three setup paths, the full check
100
+ reference, and the per-version migration notes.
101
+ - **"For AI assistants" block in `CLAUDE.md`.** Tells future Claude:
102
+ call `dexe_doctor` first; edit `.env` not `.claude.json`; restart is
103
+ required after env changes; the `/dexe-setup` skill exists; point
104
+ upgrading users at `docs/MIGRATION.md`.
105
+
106
+ ### Changed
107
+
108
+ - **`src/tools/read.ts` and `src/tools/txSend.ts` hot handlers** migrated
109
+ to the soft `tryProvider`/`trySigner` variants. Missing RPC or
110
+ `DEXE_PRIVATE_KEY` now surfaces as a structured MCP error with fix
111
+ instructions instead of a thrown stack. Other call sites of
112
+ `requireProvider`/`requireSigner` keep their throwing behavior — they
113
+ are migrated incrementally in 0.8.1.
114
+ - **`src/index.ts`** now dispatches `dexe-mcp doctor` and `dexe-mcp init`
115
+ to their respective CLI entry points before opening the MCP stdio
116
+ transport. No-arg invocation still starts the server as before. The
117
+ env loader runs BEFORE the subcommand dispatch so the CLI sees the
118
+ same env as the MCP server.
119
+ - **`docs/TOOLS.md`** bumped to 153 tools / 19 groups (added the
120
+ Diagnostics group containing `dexe_doctor`).
121
+ - **`README.md` Quickstart** now leads with the wizard path
122
+ (`init` + `doctor`) above the manual install instructions.
123
+
124
+ ### Notes
125
+
126
+ - No removed APIs. `requireSigner`/`requireProvider` keep throwing so
127
+ every existing call site (~17 outside read.ts and txSend.ts)
128
+ continues to work; the migration is incremental.
129
+ - No new runtime dependencies. The wizard and doctor use only
130
+ `node:readline/promises`, `node:dns/promises`, and native `fetch`.
131
+
3
132
  ## 0.7.2 — 2026-05-27
4
133
 
5
134
  ### Fixed
package/README.md CHANGED
@@ -40,7 +40,7 @@ That era is ending.
40
40
 
41
41
  LLMs can now reason about voting power, weigh proposals against a mandate, draft calldata, simulate execution, and ask your wallet to sign — **continuously, across every DAO you care about, all at once.** What was a UI is becoming a conversation. What was a treasurer's spreadsheet is becoming an always-on agent.
42
42
 
43
- **`dexe-mcp` is the substrate that makes it real for the DeXe stack — and now for external OpenZeppelin Governor DAOs as well.** One MCP server. 152 typed tools across 19 groups. Every flow the DeXe frontend exposes — plus a generic `dexe_gov_*` surface targeting Uniswap, Compound, and Optimism.
43
+ **`dexe-mcp` is the substrate that makes it real for the DeXe stack — and now for external OpenZeppelin Governor DAOs as well.** One MCP server. 153 typed tools across 19 groups. Every flow the DeXe frontend exposes — plus a generic `dexe_gov_*` surface targeting Uniswap, Compound, and Optimism.
44
44
 
45
45
  | | What you get |
46
46
  |-----|------|
@@ -87,6 +87,24 @@ The next generation of DAOs will be **operated by language, not by clicks.**
87
87
 
88
88
  ## Quickstart
89
89
 
90
+ **Fastest path — wizard + diagnostic:**
91
+
92
+ ```bash
93
+ npm install -g dexe-mcp
94
+ npx dexe-mcp init # interactive setup (network, Pinata, signer mode)
95
+ npx dexe-mcp doctor # verify (RPC + Pinata + IPFS gateway + subgraph)
96
+ ```
97
+
98
+ The wizard writes `.env` at the repo root and prints a `~/.claude.json`
99
+ snippet to paste. Then `doctor` walks every recognized `DEXE_*` var and
100
+ returns a pass/warn/fail report with paste-ready remediation hints. See
101
+ [`docs/SETUP.md`](./docs/SETUP.md) for the full runbook,
102
+ [`docs/DOCTOR.md`](./docs/DOCTOR.md) for the check reference, and
103
+ [`docs/MIGRATION.md`](./docs/MIGRATION.md) if you are upgrading from
104
+ 0.7.x.
105
+
106
+ **Manual path:**
107
+
90
108
  **1.** Install:
91
109
 
92
110
  ```bash
@@ -0,0 +1,11 @@
1
+ /**
2
+ * CLI entrypoint: `npx dexe-mcp doctor`. Runs the same check suite as the
3
+ * MCP tool, prints a flat colorless table to stdout, exits with:
4
+ * - 0 when every check passes
5
+ * - 1 when there are warnings but no failures
6
+ * - 2 when at least one check fails
7
+ *
8
+ * Designed for both human terminal use and CI pipelines.
9
+ */
10
+ export declare function run(): Promise<void>;
11
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAGA;;;;;;;;GAQG;AACH,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAiCzC"}
@@ -0,0 +1,44 @@
1
+ import { loadConfig } from "../config.js";
2
+ import { runAllChecks } from "../diag/checks.js";
3
+ /**
4
+ * CLI entrypoint: `npx dexe-mcp doctor`. Runs the same check suite as the
5
+ * MCP tool, prints a flat colorless table to stdout, exits with:
6
+ * - 0 when every check passes
7
+ * - 1 when there are warnings but no failures
8
+ * - 2 when at least one check fails
9
+ *
10
+ * Designed for both human terminal use and CI pipelines.
11
+ */
12
+ export async function run() {
13
+ const config = await loadConfig().catch(err => {
14
+ process.stderr.write(`[dexe-mcp doctor] config load failed: ${err instanceof Error ? err.message : String(err)}\n`);
15
+ process.exit(2);
16
+ });
17
+ if (!config) {
18
+ process.exit(2);
19
+ }
20
+ const checks = await runAllChecks({ config });
21
+ let pass = 0;
22
+ let warn = 0;
23
+ let fail = 0;
24
+ for (const c of checks) {
25
+ if (c.status === "pass")
26
+ pass++;
27
+ else if (c.status === "warn")
28
+ warn++;
29
+ else
30
+ fail++;
31
+ }
32
+ for (const c of checks) {
33
+ const tag = c.status === "pass" ? " OK " : c.status === "warn" ? "WARN" : "FAIL";
34
+ process.stdout.write(`[${tag}] ${c.id.padEnd(36)} ${c.message}\n`);
35
+ if (c.remediation) {
36
+ for (const line of c.remediation.split("\n")) {
37
+ process.stdout.write(` -> ${line}\n`);
38
+ }
39
+ }
40
+ }
41
+ process.stdout.write(`\nsummary: ${pass} pass / ${warn} warn / ${fail} fail\n`);
42
+ process.exit(fail > 0 ? 2 : warn > 0 ? 1 : 0);
43
+ }
44
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,GAAG;IACvB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yCAAyC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAC9F,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;YAAE,IAAI,EAAE,CAAC;aAC3B,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;YAAE,IAAI,EAAE,CAAC;;YAChC,IAAI,EAAE,CAAC;IACd,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QACjF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC;QACnE,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAClB,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,WAAW,IAAI,WAAW,IAAI,SAAS,CAAC,CAAC;IAChF,OAAO,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function run(): Promise<void>;
2
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAsBA,wBAAsB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CA8KzC"}
@@ -0,0 +1,306 @@
1
+ import { createInterface } from "node:readline/promises";
2
+ import { stdin as input, stdout as output } from "node:process";
3
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { resolve, dirname } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ /**
7
+ * `npx dexe-mcp init` — zero-config onboarding wizard.
8
+ *
9
+ * Walks the user through a minimal `.env` (network, RPCs, Pinata, subgraph
10
+ * key, signer mode), validates the Pinata JWT against the live endpoint
11
+ * before writing, and prints a paste-ready `.claude.json` snippet. Never
12
+ * auto-edits the user's MCP host config — that is too risky to do
13
+ * automatically (other servers, other env keys, comments to preserve).
14
+ *
15
+ * Uses only the Node 20 standard library (`node:readline/promises`,
16
+ * `node:fs`, native `fetch`) — no new dependency.
17
+ */
18
+ const TESTNET_DEFAULT_RPC = "https://data-seed-prebsc-1-s1.bnbchain.org:8545";
19
+ const MAINNET_DEFAULT_RPC = "https://bsc-dataseed.bnbchain.org";
20
+ export async function run() {
21
+ if (!input.isTTY) {
22
+ process.stderr.write("[dexe-mcp init] stdin is not a TTY. Pipe-driven init is not supported (too risky for secrets). " +
23
+ "Fill in .env manually instead — see .env.example.\n");
24
+ process.exit(2);
25
+ }
26
+ const rl = createInterface({ input, output });
27
+ try {
28
+ output.write(line("dexe-mcp init — onboarding wizard"));
29
+ output.write(line("─".repeat(64)));
30
+ output.write(line("Builds a minimal .env. Answers are stored in plaintext;"));
31
+ output.write(line("use WalletConnect or readonly mode if that worries you."));
32
+ output.write("\n");
33
+ // ---- Network selection ----------------------------------------------
34
+ const network = await pickOne(rl, "Which network(s)?", [
35
+ ["t", "testnet — BSC chain 97 (free faucet BNB, recommended for first run)"],
36
+ ["m", "mainnet — BSC chain 56 (real funds)"],
37
+ ["b", "both"],
38
+ ], "t");
39
+ let rpcTestnet;
40
+ let rpcMainnet;
41
+ if (network === "t" || network === "b") {
42
+ rpcTestnet = (await ask(rl, "Testnet RPC URL", TESTNET_DEFAULT_RPC)).trim();
43
+ }
44
+ if (network === "m" || network === "b") {
45
+ rpcMainnet = (await ask(rl, "Mainnet RPC URL", MAINNET_DEFAULT_RPC)).trim();
46
+ }
47
+ const defaultChainId = network === "m" ? "56" : "97";
48
+ // ---- Pinata JWT (optional) -----------------------------------------
49
+ output.write(line("Pinata JWT enables IPFS uploads (proposal metadata, DAO avatars)."));
50
+ output.write(line("Reads work without it via a public gateway. Press Enter to skip."));
51
+ const pinataJwt = (await ask(rl, "Pinata JWT", "")).trim();
52
+ if (pinataJwt) {
53
+ const ok = await validatePinataJwt(pinataJwt);
54
+ if (!ok) {
55
+ const proceed = await yn(rl, "Pinata says that JWT is invalid (or the network is unreachable). Save anyway?", false);
56
+ if (!proceed) {
57
+ output.write(line("Aborted — re-run init when you have a valid JWT."));
58
+ process.exit(2);
59
+ }
60
+ }
61
+ else {
62
+ output.write(line(" → Pinata JWT validated."));
63
+ }
64
+ }
65
+ const ipfsGateway = pinataJwt
66
+ ? (await ask(rl, "IPFS gateway URL", "https://gateway.pinata.cloud")).trim()
67
+ : "";
68
+ // ---- Subgraph (optional) -------------------------------------------
69
+ output.write(line("Subgraph reads need a Graph API key (free at thegraph.com)."));
70
+ const graphKey = (await ask(rl, "Graph API key (blank to skip subgraph reads)", "")).trim();
71
+ // ---- Signer mode ---------------------------------------------------
72
+ output.write(line(""));
73
+ output.write(line("Signer mode:"));
74
+ output.write(line(" readonly — no broadcast; tools return unsigned calldata (safest)"));
75
+ output.write(line(" walletconnect — broadcast via phone wallet; key never enters this process"));
76
+ output.write(line(" privkey — hot key in .env; convenient for CI and bots, NOT recommended"));
77
+ const signerMode = await pickOne(rl, "Pick a signer mode", [
78
+ ["r", "readonly (recommended)"],
79
+ ["w", "walletconnect"],
80
+ ["p", "privkey (warning: plaintext in .env)"],
81
+ ], "r");
82
+ let privateKey;
83
+ let wcProjectId;
84
+ if (signerMode === "p") {
85
+ output.write(line(""));
86
+ output.write(line("⚠ Plaintext private keys in .env are a security risk."));
87
+ output.write(line(" Anyone who reads the file can drain that wallet."));
88
+ output.write(line(" Prefer WalletConnect (re-run init and pick `w`) when possible."));
89
+ const confirm = await yn(rl, "Continue with privkey mode?", false);
90
+ if (!confirm) {
91
+ output.write(line("Aborted — re-run init and pick readonly or walletconnect."));
92
+ process.exit(2);
93
+ }
94
+ const pk = (await ask(rl, "Private key (0x… 64 hex)", "")).trim();
95
+ if (!/^0x[0-9a-fA-F]{64}$/.test(pk)) {
96
+ output.write(line("That does not look like a 64-hex key — aborting."));
97
+ process.exit(2);
98
+ }
99
+ const addr = await deriveAddress(pk);
100
+ output.write(line(` → Derived address: ${addr}`));
101
+ const ok = await yn(rl, "Is that the wallet you intended?", true);
102
+ if (!ok) {
103
+ output.write(line("Aborted — re-run init."));
104
+ process.exit(2);
105
+ }
106
+ privateKey = pk;
107
+ }
108
+ else if (signerMode === "w") {
109
+ wcProjectId = (await ask(rl, "WalletConnect project id (cloud.reown.com)", "")).trim();
110
+ }
111
+ // ---- Build the env block + write .env ------------------------------
112
+ const updates = {};
113
+ if (rpcTestnet)
114
+ updates.DEXE_RPC_URL_TESTNET = rpcTestnet;
115
+ if (rpcMainnet)
116
+ updates.DEXE_RPC_URL_MAINNET = rpcMainnet;
117
+ updates.DEXE_DEFAULT_CHAIN_ID = defaultChainId;
118
+ if (pinataJwt)
119
+ updates.DEXE_PINATA_JWT = pinataJwt;
120
+ if (ipfsGateway)
121
+ updates.DEXE_IPFS_GATEWAY = ipfsGateway;
122
+ if (graphKey)
123
+ updates.DEXE_GRAPH_API_KEY = graphKey;
124
+ if (privateKey)
125
+ updates.DEXE_PRIVATE_KEY = privateKey;
126
+ if (wcProjectId)
127
+ updates.DEXE_WALLETCONNECT_PROJECT_ID = wcProjectId;
128
+ const repoRoot = findRepoRoot();
129
+ const envPath = resolve(repoRoot, ".env");
130
+ // Read the file once up-front (or treat ENOENT as "no existing .env") so
131
+ // the later write isn't a check-then-act TOCTOU: every decision below
132
+ // operates on this captured snapshot, not on a re-stat of the path.
133
+ let existingEnv = null;
134
+ try {
135
+ existingEnv = readFileSync(envPath, "utf8");
136
+ }
137
+ catch (err) {
138
+ if (err.code !== "ENOENT")
139
+ throw err;
140
+ }
141
+ let action = "write";
142
+ if (existingEnv !== null) {
143
+ const choice = await pickOne(rl, `Existing .env at ${envPath}. Overwrite or merge?`, [
144
+ ["m", "merge — replace known keys, keep everything else (recommended)"],
145
+ ["o", "overwrite — wipe and start fresh"],
146
+ ["a", "abort — keep .env unchanged, exit"],
147
+ ], "m");
148
+ if (choice === "a") {
149
+ output.write(line("Aborted — .env unchanged."));
150
+ process.exit(0);
151
+ }
152
+ action = choice === "o" ? "write" : "merge";
153
+ }
154
+ const content = action === "write" || existingEnv === null
155
+ ? renderFreshEnv(updates)
156
+ : mergeEnv(existingEnv, updates);
157
+ writeFileSync(envPath, content, "utf8");
158
+ output.write(line(`✔ Wrote ${envPath} (${Object.keys(updates).length} key${Object.keys(updates).length === 1 ? "" : "s"} set).`));
159
+ output.write(line(""));
160
+ // ---- Print .claude.json snippet ------------------------------------
161
+ output.write(line("Paste this into your ~/.claude.json under `mcpServers`:"));
162
+ output.write(line(""));
163
+ output.write(jsonSnippet(repoRoot));
164
+ output.write(line(""));
165
+ output.write(line(`Next: run \`npx dexe-mcp doctor\` to verify, then restart Claude Code.`));
166
+ }
167
+ finally {
168
+ rl.close();
169
+ }
170
+ }
171
+ // ─── prompt helpers ──────────────────────────────────────────────────────
172
+ async function ask(rl, prompt, fallback) {
173
+ const suffix = fallback ? ` [${fallback}]` : "";
174
+ const a = await rl.question(`${prompt}${suffix}: `);
175
+ return a.length === 0 ? fallback : a;
176
+ }
177
+ async function yn(rl, prompt, defaultYes) {
178
+ const suffix = defaultYes ? "[Y/n]" : "[y/N]";
179
+ const a = (await rl.question(`${prompt} ${suffix}: `)).trim().toLowerCase();
180
+ if (!a)
181
+ return defaultYes;
182
+ return a === "y" || a === "yes";
183
+ }
184
+ async function pickOne(rl, prompt, options, defaultKey) {
185
+ output.write(line(prompt));
186
+ for (const [key, label] of options) {
187
+ const tag = key === defaultKey ? `[${key}*]` : `[${key} ]`;
188
+ output.write(line(` ${tag} ${label}`));
189
+ }
190
+ const valid = new Set(options.map(o => o[0]));
191
+ // eslint-disable-next-line no-constant-condition
192
+ while (true) {
193
+ const a = (await rl.question(`Choice (default ${defaultKey}): `)).trim().toLowerCase();
194
+ if (!a)
195
+ return defaultKey;
196
+ if (valid.has(a))
197
+ return a;
198
+ output.write(line(` → please answer one of ${[...valid].join(" / ")}`));
199
+ }
200
+ }
201
+ // ─── env file rendering ──────────────────────────────────────────────────
202
+ function renderFreshEnv(updates) {
203
+ const lines = [
204
+ "# dexe-mcp — generated by `npx dexe-mcp init`",
205
+ "# Loaded via process.loadEnvFile() at MCP startup.",
206
+ "# Run `npx dexe-mcp doctor` after any edit to verify.",
207
+ "",
208
+ ];
209
+ for (const [k, v] of Object.entries(updates)) {
210
+ lines.push(`${k}=${v}`);
211
+ }
212
+ return lines.join("\n") + "\n";
213
+ }
214
+ /**
215
+ * Merge new values into an existing .env in place: known keys are replaced,
216
+ * unknown keys + comments + blank lines preserved verbatim. Detects CRLF vs
217
+ * LF and matches the file's existing line endings.
218
+ */
219
+ function mergeEnv(existing, updates) {
220
+ const eol = /\r\n/.test(existing) ? "\r\n" : "\n";
221
+ const lines = existing.split(/\r?\n/);
222
+ const seen = new Set();
223
+ const out = [];
224
+ for (const line_ of lines) {
225
+ const m = /^(\s*)([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(line_);
226
+ if (m && Object.prototype.hasOwnProperty.call(updates, m[2])) {
227
+ const key = m[2];
228
+ out.push(`${m[1] ?? ""}${key}=${updates[key]}`);
229
+ seen.add(key);
230
+ continue;
231
+ }
232
+ out.push(line_);
233
+ }
234
+ // Append any keys that did not already exist.
235
+ const appended = [];
236
+ for (const [k, v] of Object.entries(updates)) {
237
+ if (seen.has(k))
238
+ continue;
239
+ appended.push(`${k}=${v}`);
240
+ }
241
+ if (appended.length > 0) {
242
+ if (out.length > 0 && out[out.length - 1] !== "")
243
+ out.push("");
244
+ out.push("# added by `npx dexe-mcp init`");
245
+ out.push(...appended);
246
+ }
247
+ // Ensure trailing newline (Node's loadEnvFile drops the last line otherwise).
248
+ if (out.length > 0 && out[out.length - 1] !== "")
249
+ out.push("");
250
+ return out.join(eol);
251
+ }
252
+ // ─── Pinata + ethers helpers ─────────────────────────────────────────────
253
+ async function validatePinataJwt(jwt) {
254
+ try {
255
+ const ctrl = new AbortController();
256
+ const timer = setTimeout(() => ctrl.abort(), 5000);
257
+ const r = await fetch("https://api.pinata.cloud/data/testAuthentication", {
258
+ method: "GET",
259
+ headers: { Authorization: `Bearer ${jwt}` },
260
+ signal: ctrl.signal,
261
+ });
262
+ clearTimeout(timer);
263
+ return r.status >= 200 && r.status < 300;
264
+ }
265
+ catch {
266
+ return false;
267
+ }
268
+ }
269
+ async function deriveAddress(pk) {
270
+ const { Wallet } = await import("ethers");
271
+ return new Wallet(pk).address;
272
+ }
273
+ // ─── path + snippet helpers ──────────────────────────────────────────────
274
+ function findRepoRoot() {
275
+ // `dist/index.js` → `..` is repo root. Walk up if running from src/cli/.
276
+ const here = dirname(fileURLToPath(import.meta.url));
277
+ // Two known layouts: dist/cli/init.js → up 2; dist/index.js's import → up 1 from dist.
278
+ // Easiest: walk up until we find package.json.
279
+ let cur = here;
280
+ for (let i = 0; i < 6; i++) {
281
+ if (existsSync(resolve(cur, "package.json")))
282
+ return cur;
283
+ cur = resolve(cur, "..");
284
+ }
285
+ return process.cwd();
286
+ }
287
+ function jsonSnippet(repoRoot) {
288
+ const distPath = resolve(repoRoot, "dist", "index.js");
289
+ // Use JSON.stringify to handle Windows backslashes cleanly.
290
+ const safe = JSON.stringify(distPath);
291
+ return [
292
+ "{",
293
+ ` "mcpServers": {`,
294
+ ` "dexe": {`,
295
+ ` "command": "node",`,
296
+ ` "args": [${safe}]`,
297
+ ` }`,
298
+ ` }`,
299
+ `}`,
300
+ "",
301
+ ].join("\n");
302
+ }
303
+ function line(s) {
304
+ return s + "\n";
305
+ }
306
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type EnvCategory } from "../env/schema.js";
2
+ import type { DexeConfig } from "../config.js";
3
+ export type CheckStatus = "pass" | "warn" | "fail";
4
+ export type CheckCategory = EnvCategory | "network" | "process";
5
+ export interface CheckResult {
6
+ id: string;
7
+ category: CheckCategory;
8
+ status: CheckStatus;
9
+ message: string;
10
+ remediation?: string;
11
+ }
12
+ export interface RunCheckOpts {
13
+ /** When omitted, checks that depend on resolved config are skipped. */
14
+ config?: DexeConfig;
15
+ /** Per-network-check timeout. Defaults to 3000ms. */
16
+ timeoutMs?: number;
17
+ }
18
+ /**
19
+ * Run every diagnostic check in parallel, gather results.
20
+ *
21
+ * Network checks have a hard timeout that downgrades to `warn`, never `fail` —
22
+ * an offline laptop or VPN flake should not make the doctor scream red.
23
+ */
24
+ export declare function runAllChecks(opts?: RunCheckOpts): Promise<CheckResult[]>;
25
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/diag/checks.ts"],"names":[],"mappings":"AACA,OAAO,EAA4C,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACnD,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;AAEhE,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,aAAa,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAqBlF"}