export interface McpSetupCliOptions { /** Refresh every detected client regardless of current registration state. */ force?: boolean; /** Emit the canonical JSON block to stdout; do not detect clients or write. */ printOnly?: boolean; /** * Auto-confirm per-client registrations (default false). In TTY * mode without `--yes`, the action prompts per detected client * before writing. In non-TTY mode (CI, piped input, no controlling * terminal) the prompt is skipped — non-interactive environments * auto-confirm so scripts don't hang. Pass `--yes` explicitly in * scripts for the safer posture. */ yes?: boolean; /** Override daemon API port (default 9200). Mirrors openclaw-setup. */ port?: string; /** Override agent name (used only on first init). Mirrors openclaw-setup. */ name?: string; /** Skip daemon start (configure only). Mirrors openclaw-setup. */ start?: boolean; /** Skip wallet funding via testnet faucet. Mirrors openclaw-setup. */ fund?: boolean; /** Skip post-setup verification probe. Mirrors openclaw-setup. */ verify?: boolean; /** Preview without writing or starting anything. Mirrors openclaw-setup. */ dryRun?: boolean; /** * Force installed-mode command form even when invoked from inside * a monorepo dev checkout. Escape hatch for contributors who want * to test the published-CLI shape from a dev cwd. Mutually * exclusive with `--monorepo`. */ installed?: boolean; /** * Force monorepo-mode command form (writes the absolute path to * the local CLI dist). Errors if no monorepo root can be located. * Mutually exclusive with `--installed`. */ monorepo?: boolean; } /** * Setup context — drives `canonicalEntry`'s output shape. `'installed'` * is the default for npm-installed CLIs (writes * `{ command: "dkg", args: ["mcp", "serve"] }`); `'monorepo'` is the * contributor-from-dev-checkout case (writes * `{ command: "node", args: ["/packages/cli/dist/cli.js", * "mcp", "serve"] }` so the contributor's local-build runs, not a * stale globally-installed version). */ export type SetupContext = 'installed' | 'monorepo'; /** * F31: per-client registration plan item. Lifted to module scope so * the `confirmPlan` helper can take and return arrays of these * without re-declaring the shape inside the action body. `Action` * mirrors the local enum the planning loop produces. */ export type PlannedAction = 'register' | 'refresh' | 'skip'; export interface PlannedItem { s: ClientState; action: PlannedAction; } /** * Dependency surface for `mcpSetupAction`. All bundled-flow primitives * are injected so the action can be unit-tested without touching the * real filesystem or spawning the daemon. The CLI wiring in `cli.ts` * dynamically imports `@origintrail-official/dkg-adapter-openclaw` and * passes its real implementations. */ export interface McpSetupActionDeps { loadNetworkConfig: typeof import('@origintrail-official/dkg-adapter-openclaw').loadNetworkConfig; /** * Codex Round-23 Fix 30: agent-agnostic config-write helper from * `dkg-core`. Pre-fix this dep was `adapter-openclaw`'s * `writeDkgConfig` wrapper, which ran 3 OpenClaw-specific * mutations (`migrateLegacyOpenClawTransport`, plus * `delete existing.openclawAdapter` / `delete existing.openclawChannel`) * before delegating to this same `ensureDkgNodeConfig`. Those * mutations are no-ops on MCP-only configs but the dependency * was architecturally wrong — MCP setup shouldn't reach into * the OpenClaw adapter for config writes. Calling the agent- * agnostic helper directly drops the dead OpenClaw baggage from * the MCP-only setup path. The OpenClaw migrations stay scoped * to `dkg openclaw setup`'s own `writeDkgConfig` call site. */ ensureDkgNodeConfig: typeof import('@origintrail-official/dkg-core').ensureDkgNodeConfig; startDaemon: typeof import('@origintrail-official/dkg-adapter-openclaw').startDaemon; readWalletsWithRetry: typeof import('@origintrail-official/dkg-adapter-openclaw').readWalletsWithRetry; logManualFundingInstructions: typeof import('@origintrail-official/dkg-adapter-openclaw').logManualFundingInstructions; /** Faucet primitive from `@origintrail-official/dkg-core`. */ requestFaucetFunding: typeof import('@origintrail-official/dkg-core').requestFaucetFunding; /** * Walks ancestors looking for a DKG monorepo root. Defaulted to the * dkg-core implementation in production; injectable so tests can * stub it without touching the real filesystem. */ findDkgMonorepoRoot: typeof import('@origintrail-official/dkg-core').findDkgMonorepoRoot; /** * Codex Round-2 Bug A: resolve the DKG home directory used by the * config / daemon / faucet steps below. Defaults to the dkg-core * implementation in production; injectable so tests can pin a * deterministic home without depending on `homedir()` or env. When * mcp-setup detects monorepo context it forwards the signal here * so the bootstrap state lands in the same `~/.dkg-dev` that the * registered local CLI dist will read at MCP-client startup time. */ resolveDkgConfigHome: typeof import('@origintrail-official/dkg-core').resolveDkgConfigHome; /** * F31: per-client interactive confirm hook. Defaulted to the * production readline-based implementation. Injectable so tests * can stub deterministic answer streams without managing a real * TTY. The helper takes the `planned` array and returns a * possibly-modified copy where declined items are downgraded to * `'skip'`. * * Optional — `mcpSetupAction` falls back to the module-level * `confirmPlan` when not supplied so existing call sites keep * working unchanged. */ confirmPlan?: (planned: readonly PlannedItem[], opts: { yes: boolean; }) => Promise; } /** * F31 production-side per-client confirm prompt. Reads each * to-be-written client name from the planned array and asks the * operator interactively before writing. Skipped entries pass * through unchanged (we don't prompt about no-ops). * * Auto-confirm conditions (skip prompts entirely): * - `opts.yes === true` (operator passed `--yes`). * - `process.stdin.isTTY === false` OR `process.stdout.isTTY === false`. * Codex Round-4 Fix 5 tightened the TTY guard: the pre-fix * stdin-only check would block on an invisible readline prompt * when stdout was redirected/captured but stdin still happened * to be a TTY (e.g. `dkg mcp setup > log.txt` from an * interactive shell). Both must be a TTY for prompting; any * non-TTY end auto-confirms. * - Zero non-skip entries in the plan (nothing to confirm). * * Default empty answer (operator just hits Enter) accepts the * registration — the prompt prefix is `[Y/n]` so the lower-case * default is "yes". Only `n` / `no` (case-insensitive) declines. * * Exported so `cli.ts` can pass it through to `mcpSetupAction`'s * deps surface in production. Tests inject their own stub. */ export declare function confirmPlan(planned: readonly PlannedItem[], opts: { yes: boolean; }): Promise; interface ClientTarget { name: string; configPath: string; /** Pretty path for display, with `~` substituted back in. */ displayPath: string; /** * Per-client config-file format. Defaults to `'json'` so the existing * Cursor + Claude Code targets stay byte-identical post-refactor. * Codex CLI uses `'toml'`. The `'yaml'` variant is reserved for * future clients (Continue was attempted in PR #443 then reverted * because its MCP config is workspace-local, not user-global — * structural mismatch with `dkg mcp setup`'s machine-wide UX); * `readConfigBody` / `writeConfigBody` keep `NotImplementedError` * stubs for the YAML branch so re-adding a YAML client is purely * additive when the time comes. */ format?: 'json' | 'toml' | 'yaml'; /** * Dotted path to the per-server entry inside the parsed config. * Defaults to `'mcpServers.dkg'` — the shape Cursor / Claude Code / * Claude Desktop / Windsurf / Cline all use. Clients diverging from * that shape (VSCode + Copilot Chat uses `servers.dkg`; Codex CLI * uses `mcp_servers.dkg` under TOML) declare the alternate path * here so a single registration helper covers all surfaces without * per-client write logic. */ entryPath?: string; } declare function expandHome(p: string): string; /** * Exported for Codex Round-13 Fix 20 tests — direct unit testing * of WSL2 client-detection branch without going through the full * `mcpSetupAction` body. Production callers go via the action. * The resolver arg is test-only so WSL Windows path discovery can * be exercised without real cmd.exe / wslpath binaries. */ export declare function detectClients(resolveWslWindowsEnvPath?: (envVarName: string) => string | null): ClientTarget[]; type RegistrationState = 'registered' | 'stale' | 'not-registered'; interface ClientState { target: ClientTarget; state: RegistrationState; current: unknown; } /** * Main entrypoint invoked by the `dkg mcp setup` commander handler in * `cli.ts`. Idempotent — re-running on a fully-set-up tree prints * step-by-step skip notices and exits cleanly without touching any * file or restarting the daemon. */ export declare function mcpSetupAction(opts: McpSetupCliOptions, deps: McpSetupActionDeps): Promise; export { expandHome }; //# sourceMappingURL=mcp-setup.d.ts.map