@haven_ai/connect 0.0.0-dev.202609031523.fd49e1a

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/api.ts","../src/key.ts","../src/redact.ts","../src/server-names.ts","../src/storage.ts","../src/runtime-manifest.ts","../src/config-writers.ts","../src/local-mcp-consent.ts","../src/probes.ts","../src/signer-runtime.ts","../src/local-mcp-runtime.ts","../src/skill-install.ts","../src/connect-error.ts","../src/runtime-registry.ts","../src/signer-consent.ts","../src/runtime-install.ts","../src/rekey-messages.ts","../src/tombstone.ts","../src/unwire.ts","../src/rekey.ts","../src/rekey-restart.ts","../src/doctor.ts","../src/runtime.ts","../src/installed-clients.ts","../src/args.ts","../src/cli.ts"],"names":["Wallet","crypto","mkdir","join","rm","readdir","rename","writeFile","path","readFile","stat","homedir","resolve","access","chmod","MCP_VERSION","HAVEN_MINIMUM_NODE_VERSION","registeredToolNames","signerToolSchemas","parseDocument","isMap","replacement","needsTrailingNewline","stringify","unlink","merged","dirname","platform","connectorRerunCommand","ensureConsent","computeConsentHash","loadCredentials","consentInputFromClient","spawn","promisify","execFile","installedRuntimeMatches","installRuntimePackages","assertFileExists","writeWrapper","writeRuntimeSidecar","isSupportedNodeVersion","execFileAsync","readPackageJson","unsupportedNodeVersionMessage","SKILL_FOLDER_NAME","HAVEN_SKILL_MD","HAVEN_SKILL_BODY_MD","nextAction","ensureSignerConsent","writeLogChunk","computeSignerConsentHash","loadSignerCredentials","signer","createEdgeSigner","toolSchemas","signerCredentialReady","errorCode","basename","createInterface","resolveTokenFromAddress","writeAgentTombstone","unwireAgent","startRekey","finishRekey","restartGuidance","result","runDoctor","runRepair","realpathSync","fileURLToPath","pathToFileURL"],"mappings":"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","file":"cli.cjs","sourcesContent":["export interface ConnectApiClient {\n resolveSetup(input: ResolveSetupInput): Promise<ResolvedSetup>\n registerSetup(input: RegisterSetupInput): Promise<RegisterSetupResponse>\n updateInstallStatus(\n setupId: string,\n apiKey: string,\n input: UpdateInstallStatusInput,\n ): Promise<void>\n /**\n * #1377 D: the narrow status read the connector polls after registering,\n * authenticated with the agent API key it just minted (works while the\n * agent is still `setup_pending` — the endpoint exists for exactly that\n * window). Returns status plus the approved budget once approval lands;\n * never any secret material.\n */\n getConnectorStatus(setupId: string, apiKey: string): Promise<ConnectorStatusResponse>\n /**\n * #1700: the agent behind an API key. Used by the re-key flow on both sides\n * of the dashboard hand-off — see {@link AgentIdentity}.\n */\n getAgentIdentity(apiKey: string): Promise<AgentIdentity>\n}\n\nexport interface ConnectorStatusResponse {\n status: string\n approved_budget: {\n token_symbol: string\n token_address: string\n amount: string\n reset_period_min: number\n } | null\n}\n\nexport interface ResolveSetupInput {\n setupToken: string\n connectorVersion: string\n runtime?: string\n}\n\nexport interface RegisterSetupInput extends ResolveSetupInput {\n challengeId: string\n delegateAddress: string\n proofSignature: string\n apiKeyHash: string\n apiKeyPrefix: string\n /**\n * #1878: the RESOLVED hosted MCP server name this agent is being wired as —\n * `haven` for the bare pair, `haven-<slug>` for a named one. Sent so the\n * dashboard can tell two agents in one harness apart; it is a display aid\n * and Haven keys nothing off it.\n *\n * Always sent by a connector that supports it, bare pair included. Omitting\n * it for the bare pair would make \"absent\" ambiguous between *this is the\n * unnamed pair* and *an older connector said nothing*, and only the second\n * of those may render as unknown.\n */\n mcpServerName?: string\n connectorContext?: ConnectorContext\n installCapabilities?: {\n canWriteRuntimeConfig?: boolean\n restartRequired?: boolean\n }\n}\n\nexport interface UpdateInstallStatusInput {\n runtime?: string\n connectorVersion: string\n runtimeMcpMode?: string\n hostedMcpConfigured: boolean\n localSignerConfigured: boolean\n localMcpConfigured?: boolean\n credentialFilesWritten?: boolean\n signerAcknowledged?: boolean\n localMcpAcknowledged?: boolean\n activationCommandAvailable?: boolean\n skillInstalled?: boolean\n /**\n * Omitted on the #1543 early config-written report — no probe has run yet,\n * and the backend merge keeps the key absent until the final report sets it.\n */\n probeResult?: string\n restartRequired: boolean\n nextUserAction: string\n errorCode?: string | null\n environmentLabel?: string\n}\n\nexport interface ConnectorContext {\n environment_label?: string\n runtime_version?: string\n config_target?: string\n}\n\nexport interface ResolvedSetup {\n setup_id: string\n status: string\n agent: {\n name: string\n description?: string | null\n }\n haven_wallet: {\n id: string\n name: string\n address: string\n chain_id: number\n network: string\n }\n agent_budget: Array<{\n token_address: string\n token_symbol: string\n allowance_amount: string\n reset_period_min: number\n }>\n hosted_mcp_url: string\n // Address the edge signer verifies x402 expected-context signatures against.\n // null/absent when the backend has no x402 binding key configured.\n x402_binding_signer?: string | null\n challenge: {\n id: string\n message: string\n expires_at: string\n }\n}\n\nexport interface RegisterSetupResponse {\n setup_id: string\n agent_id: string\n status: string\n agent_status: string\n api_key_prefix: string\n api_key_scope: string\n delegate_address: string\n hosted_mcp_url: string\n next_action: string\n}\n\n/**\n * The agent identity behind an API key (#1700).\n *\n * Read from `GET /machine-payments/agent`, the same agent-authenticated\n * endpoint the SDK's `getAgent()` uses. Re-key needs it twice and for two\n * different questions: BEFORE, to refuse a legacy-rail account the way the\n * backend would rather than let the owner discover it five signed steps later;\n * and AFTER, to prove the API key the owner pasted really belongs to this\n * agent and really names the key this machine just generated.\n */\nexport interface AgentIdentity {\n id: string\n name: string\n status: string\n safe_address: string | null\n delegate_address: string | null\n chain_id: number | null\n execution_rail: 'legacy' | 'delegation' | string\n}\n\nexport function createConnectApiClient(baseUrl: string, fetchImpl: typeof fetch = fetch): ConnectApiClient {\n const root = baseUrl.replace(/\\/+$/, '')\n return {\n resolveSetup: (input) =>\n request(fetchImpl, `${root}/agent-connection-setups/resolve`, {\n method: 'POST',\n body: JSON.stringify({\n setup_token: input.setupToken,\n connector_version: input.connectorVersion,\n runtime: input.runtime,\n }),\n }),\n\n registerSetup: (input) =>\n request(fetchImpl, `${root}/agent-connection-setups/register`, {\n method: 'POST',\n body: JSON.stringify({\n setup_token: input.setupToken,\n challenge_id: input.challengeId,\n delegate_address: input.delegateAddress,\n proof_signature: input.proofSignature,\n api_key_hash: input.apiKeyHash,\n api_key_prefix: input.apiKeyPrefix,\n runtime: input.runtime,\n connector_version: input.connectorVersion,\n mcp_server_name: input.mcpServerName,\n connector_context: input.connectorContext,\n install_capabilities: input.installCapabilities && {\n can_write_runtime_config: input.installCapabilities.canWriteRuntimeConfig,\n restart_required: input.installCapabilities.restartRequired,\n },\n }),\n }),\n\n getAgentIdentity: (apiKey) =>\n request(fetchImpl, `${root}/machine-payments/agent`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${apiKey}` },\n }),\n\n getConnectorStatus: (setupId, apiKey) =>\n request(fetchImpl, `${root}/agent-connection-setups/${encodeURIComponent(setupId)}/connector-status`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${apiKey}` },\n }),\n\n updateInstallStatus: async (setupId, apiKey, input) => {\n await request(fetchImpl, `${root}/agent-connection-setups/${encodeURIComponent(setupId)}/install-status`, {\n method: 'POST',\n headers: { Authorization: `Bearer ${apiKey}` },\n body: JSON.stringify({\n runtime: input.runtime,\n connector_version: input.connectorVersion,\n runtime_mcp_mode: input.runtimeMcpMode,\n hosted_mcp_configured: input.hostedMcpConfigured,\n local_signer_configured: input.localSignerConfigured,\n local_mcp_configured: input.localMcpConfigured,\n credential_files_written: input.credentialFilesWritten,\n signer_acknowledged: input.signerAcknowledged,\n local_mcp_acknowledged: input.localMcpAcknowledged,\n activation_command_available: input.activationCommandAvailable,\n skill_installed: input.skillInstalled,\n probe_result: input.probeResult,\n restart_required: input.restartRequired,\n next_user_action: input.nextUserAction,\n error_code: input.errorCode ?? null,\n environment_label: input.environmentLabel,\n }),\n })\n },\n }\n}\n\n/**\n * Request failure carrying the HTTP status, so callers can tell a permanent\n * verdict (401 revoked key, 404 gone) from transient noise (5xx, network).\n * The approval poll loop (#1377 D) branches on this: retrying a 401 for the\n * full window and then saying \"still pending\" is actively wrong when the user\n * cancelled the setup and the key was revoked.\n */\nexport class ConnectRequestError extends Error {\n constructor(message: string, readonly status: number) {\n super(message)\n this.name = 'ConnectRequestError'\n }\n}\n\nasync function request<T>(\n fetchImpl: typeof fetch,\n url: string,\n init: RequestInit,\n): Promise<T> {\n const response = await fetchImpl(url, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n ...(init.headers ?? {}),\n },\n })\n const text = await response.text()\n const body = text ? JSON.parse(text) : null\n if (!response.ok) {\n const message = body?.error ?? body?.message ?? `${response.status} ${response.statusText}`\n throw new ConnectRequestError(`Haven setup request failed: ${message}`, response.status)\n }\n return body as T\n}\n","import crypto from 'node:crypto'\nimport { Wallet } from 'ethers'\n\nexport interface LocalDelegateKey {\n privateKey: string\n address: string\n signChallenge(message: string): Promise<string>\n}\n\nexport function generateDelegateKey(): LocalDelegateKey {\n return delegateKeyFromPrivateKey(Wallet.createRandom().privateKey)\n}\n\nexport function delegateKeyFromPrivateKey(privateKey: string): LocalDelegateKey {\n const wallet = new Wallet(privateKey)\n return {\n privateKey: wallet.privateKey,\n address: wallet.address,\n signChallenge: (message: string) => wallet.signMessage(message),\n }\n}\n\nexport function generateAgentApiKey(): string {\n return `sk_agent_${crypto.randomBytes(24).toString('hex')}`\n}\n\nexport function hashAgentApiKey(apiKey: string): string {\n return crypto.createHash('sha256').update(apiKey).digest('hex')\n}\n\nexport function agentApiKeyPrefix(apiKey: string): string {\n return apiKey.slice(0, 12)\n}\n","const API_KEY_RE = /sk_agent_[A-Za-z0-9]+/g\nconst PRIVATE_KEY_RE = /0x[0-9a-fA-F]{64}/g\n\nexport function redactSecrets(value: string): string {\n return value\n .replace(API_KEY_RE, 'sk_agent_[redacted]')\n .replace(PRIVATE_KEY_RE, '0x[redacted-private-key]')\n}\n\n/**\n * Sanitizer for messages that enter the machine-readable `--json` contract\n * (#2091). The failure record used to omit the message entirely because it\n * \"can contain server or filesystem detail\"; keeping that stance made every\n * refusal opaque to automation. Redact instead of omit: secrets always, plus\n * the credential-file paths the human log already masks in redact-paths mode.\n */\nexport function redactForAutomation(value: string): string {\n return redactSecrets(value)\n .replace(/(?:~|\\/)[^\\s`\"']*\\/(?:identity|signer|agent)\\.json\\b/g, '[credential-file-redacted]')\n .replace(/(?:~|\\/)[^\\s`\"']*\\/\\.env\\b/g, '[credential-env-redacted]')\n}\n\nexport function shortAddress(address: string): string {\n if (!/^0x[0-9a-fA-F]{40}$/.test(address)) return address\n return `${address.slice(0, 6)}...${address.slice(-4)}`\n}\n","/**\n * MCP server-name pairs (#1695, epic #1694).\n *\n * One runtime config can hold several Haven agents, each as its own\n * hosted+signer MCP pair keyed by server name. The names are the wiring\n * contract every host depends on (server name = tool prefix), so:\n *\n * - The UNNAMED pair keeps today's exact names — bare `haven` /\n * `haven-signer`, and Codex's historical `haven_signer` table — because a\n * rename would break every currently-wired host (#1694 owner decision).\n * - A NAMED pair suffixes the slug: `haven-<slug>` / `haven-signer-<slug>`.\n * The slug is fixed at connect time and never changes (#1694: editable\n * display name, immutable wiring slug). #1696 wires the `--name` flag.\n *\n * Hermes stores each pair's API key in its dotenv file, so a named pair also\n * needs its own env key — two agents sharing `MCP_HAVEN_API_KEY` would both\n * authenticate as whichever setup ran last.\n */\n\nexport interface ServerNames {\n /** Hosted MCP entry name in JSON/YAML configs and the Claude Code registry. */\n hosted: string\n /** Signer entry name in JSON/YAML configs and the Claude Code registry. */\n signer: string\n /** Codex TOML table name for the hosted entry (`mcp_servers.<name>`). */\n codexHosted: string\n /** Codex TOML table name for the signer entry. */\n codexSigner: string\n /** Hermes dotenv key holding this pair's hosted API key. */\n hermesEnvKey: string\n}\n\n/**\n * Slug shape: lowercase alphanumerics and single hyphens, 1–32 chars. Strict\n * on purpose — the slug becomes a server name, a TOML bare key, part of an\n * env var, and a tool prefix, and it is immutable once wired.\n */\nconst SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/\n\nexport function assertValidServerSlug(slug: string): void {\n if (slug.length === 0 || slug.length > 32 || !SLUG_RE.test(slug)) {\n throw new Error(\n `Invalid server name ${JSON.stringify(slug)}: use 1-32 lowercase letters, digits, and single hyphens (e.g. \"research\").`,\n )\n }\n // Collision-freedom (#1695 review, blocking finding): every derived name\n // must be unique across ALL valid slugs and the bare pair, or \"a writer\n // touches only its own pair\" is false. The only cross-collisions the\n // haven-<slug> / haven-signer-<slug> scheme admits are:\n // hosted(A) === bare signer ⇔ A === 'signer'\n // hosted(A) === signer(B), A≠B ⇔ A === `signer-${B}`\n // (signer(A) === signer(B) and hosted(A) === hosted(B) already force A===B.)\n // Rejecting 'signer' and the 'signer-' prefix therefore closes the whole\n // family, not just the literal case — proven by the adversarial-pair test.\n // #1696: the bare pair's own names are refused as slugs outright — not a\n // collision ('haven' would yield 'haven-haven'), but an operator typing\n // --name haven means the bare pair, and silently minting a doubled name\n // would wire an agent nobody can find again.\n if (slug === 'haven' || slug === 'haven-signer') {\n throw new Error(\n `Invalid server name ${JSON.stringify(slug)}: \"haven\" and \"haven-signer\" are the unnamed pair's own names — omit --name for the bare pair.`,\n )\n }\n if (slug === 'signer' || slug.startsWith('signer-')) {\n throw new Error(\n `Invalid server name ${JSON.stringify(slug)}: \"signer\" and \"signer-*\" are reserved — ` +\n \"they would collide with another pair's haven-signer-* entry.\",\n )\n }\n}\n\nexport function serverNamesFor(slug?: string): ServerNames {\n if (slug === undefined) {\n return {\n hosted: 'haven',\n signer: 'haven-signer',\n // Historical Codex table names — every wired Codex host has these.\n codexHosted: 'haven',\n codexSigner: 'haven_signer',\n hermesEnvKey: 'MCP_HAVEN_API_KEY',\n }\n }\n assertValidServerSlug(slug)\n return {\n hosted: `haven-${slug}`,\n signer: `haven-signer-${slug}`,\n // Hyphens are valid TOML bare keys, so named Codex tables match the\n // JSON/YAML names instead of inheriting the legacy underscore.\n codexHosted: `haven-${slug}`,\n codexSigner: `haven-signer-${slug}`,\n hermesEnvKey: `MCP_HAVEN_${slug.toUpperCase().replace(/-/g, '_')}_API_KEY`,\n }\n}\n","import { access, chmod, mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises'\nimport crypto from 'node:crypto'\nimport { homedir } from 'node:os'\nimport { join, resolve } from 'node:path'\n\nexport interface StoredCredentialPaths {\n directory: string\n identityPath: string\n signerPath: string\n /** Non-secret orientation file (identity + configured budget, no keys). */\n agentPath: string\n}\n\nexport interface WriteCredentialInput {\n baseDir?: string\n agentId: string\n /**\n * #1696: wiring slug. Named agents live at ~/.haven/agents/<slug>/ (stable\n * across a re-key by construction — the slug never rotates); unnamed keep\n * the historical ~/.haven/agents/<agent-uuid>/. Both schemes coexist.\n */\n serverName?: string\n apiKey: string\n delegateKey: string\n delegateAddress: string\n safeAddress?: string\n chainId?: number\n network?: string\n agentBudget?: Array<{\n token_symbol: string\n allowance_amount: string\n reset_period_min: number\n }>\n apiUrl: string\n hostedMcpUrl: string\n x402BindingSigner?: string\n warn?: (message: string) => void\n}\n\nexport interface PreflightCredentialStorageInput {\n baseDir?: string\n warn?: (message: string) => void\n}\n\nexport async function preflightCredentialStorage(\n input: PreflightCredentialStorageInput = {},\n): Promise<string> {\n const directory = defaultCredentialRoot(input.baseDir)\n await mkdir(directory, { recursive: true, mode: 0o700 })\n await restrictPermissions(directory, 0o700, input.warn)\n\n const probePath = join(directory, `.haven-connect-preflight-${crypto.randomBytes(8).toString('hex')}`)\n try {\n await writeOwnerOnlyJson(probePath, { ok: true }, input.warn)\n } finally {\n await rm(probePath, { force: true }).catch(() => undefined)\n }\n\n return directory\n}\n\nexport async function writeCredentialFiles(input: WriteCredentialInput): Promise<StoredCredentialPaths> {\n const directory = defaultAgentDirectory(input.serverName ?? input.agentId, input.baseDir)\n await mkdir(directory, { recursive: true, mode: 0o700 })\n await restrictPermissions(directory, 0o700, input.warn)\n\n const identityPath = join(directory, 'identity.json')\n const signerPath = join(directory, 'signer.json')\n const agentPath = join(directory, 'agent.json')\n\n await assertDoesNotExist(identityPath)\n await assertDoesNotExist(signerPath)\n await assertDoesNotExist(agentPath)\n\n await writeOwnerOnlyJson(signerPath, signerPayload(input), input.warn)\n\n try {\n await writeOwnerOnlyJson(identityPath, identityPayload(input), input.warn)\n } catch (err) {\n await rm(signerPath, { force: true }).catch(() => undefined)\n throw err\n }\n\n // Non-secret orientation file. Lets the agent answer \"who am I and what may I\n // spend\" on its first turn by reading one local file — no MCP round trip and\n // no exposure of the API key (identity.json) or delegate key (signer.json) in\n // the agent's transcript. Holds the *configured* budget; live remaining budget\n // still comes from haven_get_allowances before a payment.\n try {\n await writeOwnerOnlyJson(agentPath, agentPayload(input), input.warn)\n } catch (err) {\n // Roll back every file so a partial write (e.g. writeFile succeeds but chmod\n // fails) can't leave agent.json behind and block reconnection via\n // assertDoesNotExist on the next run.\n await rm(signerPath, { force: true }).catch(() => undefined)\n await rm(identityPath, { force: true }).catch(() => undefined)\n await rm(agentPath, { force: true }).catch(() => undefined)\n throw err\n }\n\n return { directory, identityPath, signerPath, agentPath }\n}\n\n// ── The three credential payloads, in one place ────────────────────────────\n//\n// Shared by the create path above and the re-key rewrite below (#1700). A\n// second copy of these shapes is how a re-key ends up writing a credential set\n// that setup would never have produced — a missing `x402_binding_signer`, a\n// dropped budget — which nothing downstream would flag, because each file is\n// individually well-formed.\n\nfunction signerPayload(input: WriteCredentialInput): Record<string, unknown> {\n return {\n delegate_key: input.delegateKey,\n delegate_address: input.delegateAddress,\n agent_id: input.agentId,\n safe_address: input.safeAddress,\n chain_id: input.chainId,\n network: input.network,\n x402_binding_signer: input.x402BindingSigner,\n note: 'Local signer credential. Haven backend never receives this private key.',\n }\n}\n\nfunction identityPayload(input: WriteCredentialInput): Record<string, unknown> {\n return {\n api_key: input.apiKey,\n agent_id: input.agentId,\n safe_address: input.safeAddress,\n chain_id: input.chainId,\n network: input.network,\n api_url: input.apiUrl,\n hosted_mcp_url: input.hostedMcpUrl,\n agent_budget: input.agentBudget,\n note: 'Haven API key identifies the agent only. It cannot spend without the local signer key and on-chain Haven wallet rules.',\n }\n}\n\nfunction agentPayload(input: WriteCredentialInput): Record<string, unknown> {\n return {\n agent_id: input.agentId,\n delegate_address: input.delegateAddress,\n safe_address: input.safeAddress,\n chain_id: input.chainId,\n network: input.network,\n agent_budget: input.agentBudget,\n note: 'Non-secret orientation for the agent: public delegate/Haven wallet identity + configured budget. Contains no API key or signing key. For the live remaining budget, call haven_get_allowances.',\n }\n}\n\n// ── Re-key: rewriting a credential set IN PLACE (#1700) ────────────────────\n\n/** What a re-key found on disk before it rewrote anything. */\nexport interface StoredCredentialSnapshot {\n directory: string\n agentId: string\n apiKey: string\n delegateAddress?: string\n safeAddress?: string\n chainId?: number\n network?: string\n apiUrl: string\n hostedMcpUrl: string\n x402BindingSigner?: string\n agentBudget?: WriteCredentialInput['agentBudget']\n}\n\n/**\n * Read the existing credential set a re-key is about to replace.\n *\n * Deliberately strict about the three fields a rewrite cannot invent — the\n * agent id, the current API key and the API URL. A directory missing any of\n * them is not a re-keyable agent, and guessing (say, defaulting the API URL to\n * localhost) would produce a credential set that authenticates against the\n * wrong Haven.\n */\nexport async function readStoredCredentials(\n serverName: string | undefined,\n agentIdOrSlug: string | undefined,\n baseDir?: string,\n): Promise<StoredCredentialSnapshot> {\n const key = serverName ?? agentIdOrSlug\n const directory = key ? defaultAgentDirectory(key, baseDir) : await discoverSoleAgentDirectory(baseDir)\n\n const identity = await readJsonFile(join(directory, 'identity.json'))\n if (!identity) {\n throw new Error(\n `No Haven credentials at ${directory}. Nothing to re-key — connect this agent first, ` +\n 'or pass the --name you wired it under.',\n )\n }\n const agent = (await readJsonFile(join(directory, 'agent.json'))) ?? {}\n const signer = (await readJsonFile(join(directory, 'signer.json'))) ?? {}\n\n const agentId = asString(identity.agent_id)\n const apiKey = asString(identity.api_key)\n const apiUrl = asString(identity.api_url)\n const hostedMcpUrl = asString(identity.hosted_mcp_url)\n if (!agentId || !apiKey || !apiUrl || !hostedMcpUrl) {\n throw new Error(\n `The credential set at ${directory} is incomplete (identity.json is missing agent_id, ` +\n 'api_key, api_url or hosted_mcp_url). Re-key cannot rebuild it — reconnect the agent instead.',\n )\n }\n\n return {\n directory,\n agentId,\n apiKey,\n apiUrl,\n hostedMcpUrl,\n delegateAddress: asString(agent.delegate_address) ?? asString(signer.delegate_address),\n safeAddress: asString(identity.safe_address) ?? asString(agent.safe_address),\n chainId: typeof identity.chain_id === 'number' ? identity.chain_id : undefined,\n network: asString(identity.network),\n x402BindingSigner: asString(signer.x402_binding_signer),\n agentBudget: Array.isArray(identity.agent_budget)\n ? (identity.agent_budget as WriteCredentialInput['agentBudget'])\n : undefined,\n }\n}\n\n/**\n * Find the one wired agent on this machine, when no `--name` was given.\n *\n * The unnamed agent's directory is keyed by its AGENT ID\n * (`~/.haven/agents/<agent-uuid>/`), which the person running the command does\n * not know and has no reason to — they never typed it. Requiring it was the\n * defect review caught: `--rekey` was unusable for the DEFAULT setup, the one\n * the help text describes as \"omit --name for the bare pair\", while working\n * fine for the named case the tests happened to cover.\n *\n * Discovery, not guessing. Exactly one candidate is resolved; several is an\n * ambiguity only the user can settle, so it refuses and NAMES them rather than\n * picking the newest — \"newest wins\" is the heuristic #1695 removed, and\n * silently re-keying the wrong agent is the worst outcome available here.\n * A tombstoned directory (#1681) is skipped: it is a deliberately retired\n * agent, never a re-key target.\n */\nasync function discoverSoleAgentDirectory(baseDir?: string): Promise<string> {\n const root = defaultCredentialRoot(baseDir)\n let entries: string[] = []\n try {\n entries = await readdir(root)\n } catch {\n throw new Error(`No Haven credentials found under ${root}. Connect an agent on this machine first.`)\n }\n\n const candidates: string[] = []\n for (const entry of entries) {\n const directory = join(root, entry)\n if (!(await readJsonFile(join(directory, 'identity.json')))) continue\n if (await readJsonFile(join(directory, 'TOMBSTONE.json'))) continue\n candidates.push(directory)\n }\n\n if (candidates.length === 1) return candidates[0]\n if (candidates.length === 0) {\n throw new Error(`No Haven credentials found under ${root}. Connect an agent on this machine first.`)\n }\n throw new Error(\n `Several agents are wired on this machine, so --rekey cannot tell which one you mean:\\n` +\n candidates.map((d) => ` ${d}`).join('\\n') +\n '\\nRe-run with --name <slug> to pick one.',\n )\n}\n\n/**\n * Replace an existing credential set in place, all-or-nothing.\n *\n * This is the ONLY path allowed to overwrite credential files, and the reason\n * `assertDoesNotExist` is not consulted here. That guard exists to stop a\n * re-run silently replacing a live agent's keys; a re-key is the one operation\n * whose whole purpose is to replace them, at a path that deliberately does not\n * move (#1694 owner decision — no new directory, no tombstone, so nothing\n * downstream has a dead path to chase).\n *\n * **Why the temp-then-rename dance.** The acceptance bar is that a failure\n * never leaves a MIXED set — the old signer key beside the new API key, or the\n * reverse. That pairing is worse than either generation intact: the agent\n * authenticates as itself and then signs with a key its delegation no longer\n * names, which is precisely the payer/signer mismatch #1690 exists to catch.\n * So every file is written and permission-set as a sibling temp FIRST, and only\n * once all three are safely on disk are they renamed into place. A failure\n * before the first rename touches nothing; a failure during the renames is\n * rolled back from the in-memory snapshot of the originals.\n *\n * The residual window is a hard process kill (SIGKILL, power loss) between two\n * renames — not an exception, which is handled. Closing that needs a\n * write-ahead marker and a recovery pass at startup; it is out of scope here\n * and named rather than papered over. `doctor` already reports a credential\n * set whose delegate address disagrees with the backend, which is what such a\n * kill would leave behind.\n */\nexport async function rewriteCredentialFiles(\n input: WriteCredentialInput,\n): Promise<StoredCredentialPaths> {\n const directory = defaultAgentDirectory(input.serverName ?? input.agentId, input.baseDir)\n const identityPath = join(directory, 'identity.json')\n const signerPath = join(directory, 'signer.json')\n const agentPath = join(directory, 'agent.json')\n\n const targets: Array<{ path: string; payload: Record<string, unknown> }> = [\n { path: signerPath, payload: signerPayload(input) },\n { path: identityPath, payload: identityPayload(input) },\n { path: agentPath, payload: agentPayload(input) },\n ]\n\n // The originals, so a failure mid-rename can put back exactly what was there.\n const originals = new Map<string, string | null>()\n for (const { path } of targets) {\n originals.set(path, await readRawFile(path))\n }\n\n const temps: Array<{ from: string; to: string }> = []\n try {\n for (const { path, payload } of targets) {\n const temp = `${path}.rekey-${crypto.randomBytes(6).toString('hex')}.tmp`\n await writeOwnerOnlyJson(temp, payload, input.warn)\n temps.push({ from: temp, to: path })\n }\n // Every temp is on disk and mode-restricted before ANY of them lands.\n for (const { from, to } of temps) {\n await rename(from, to)\n }\n } catch (err) {\n for (const { from } of temps) await rm(from, { force: true }).catch(() => undefined)\n for (const [path, contents] of originals) {\n if (contents === null) {\n await rm(path, { force: true }).catch(() => undefined)\n } else {\n await writeFile(path, contents, { mode: 0o600 }).catch(() => undefined)\n }\n }\n throw err\n }\n\n return { directory, identityPath, signerPath, agentPath }\n}\n\n// ── The pending key, between the two re-key phases (#1700) ─────────────────\n//\n// `--rekey` generates the new keypair and then STOPS, because the dashboard\n// needs its public address before it can run the five owner-signed steps that\n// end in a new API key. The private half has to survive that gap.\n//\n// It lives in the agent's own credential directory, at 0600, beside the live\n// signer key it is going to replace — the same directory, the same mode, the\n// same machine. That is the point: it widens no boundary that the live key has\n// not already crossed. It is a SECOND copy until `--rekey-finish` consumes it,\n// which is why it expires and why both the finish and a fresh `--rekey` delete\n// it rather than leaving it to rot.\n//\n// It is deliberately NOT a tombstone and NOT in a temp dir: a tombstone marks a\n// dead path (#1681's recreation case) and there is no dead path here, while a\n// temp dir is exactly the kind of world-traversable location a private key\n// should never sit in.\n\nexport const REKEY_PENDING_FILENAME = 'rekey-pending.json'\n\n/** How long a started re-key stays resumable. */\nexport const REKEY_PENDING_TTL_MS = 24 * 60 * 60 * 1000\n\nexport interface RekeyPending {\n agent_id: string\n new_delegate_address: string\n new_delegate_key: string\n started_at: string\n expires_at: string\n}\n\nexport async function writeRekeyPending(\n directory: string,\n pending: RekeyPending,\n warn?: (message: string) => void,\n): Promise<string> {\n const path = join(directory, REKEY_PENDING_FILENAME)\n // Overwrite deliberately: starting a re-key again replaces an earlier\n // unfinished attempt. Keeping the first would strand the owner on an address\n // the dashboard no longer shows, with no way to tell which is live.\n await rm(path, { force: true }).catch(() => undefined)\n await writeOwnerOnlyJson(path, { ...pending }, warn)\n return path\n}\n\n/**\n * Read a started re-key, or explain why there is nothing to finish.\n *\n * An EXPIRED pending file is an error rather than a silent miss: the owner\n * asked to finish a re-key, and \"no pending re-key found\" would send them\n * looking for a typo when the real answer is that it timed out and the address\n * in their dashboard is stale.\n */\nexport async function readRekeyPending(directory: string, now = Date.now()): Promise<RekeyPending> {\n const path = join(directory, REKEY_PENDING_FILENAME)\n const raw = await readJsonFile(path)\n if (!raw) {\n throw new Error(\n `No re-key in progress at ${directory}. Run the connector with --rekey first — it prints ` +\n 'the new signing address to paste into the Haven agent page.',\n )\n }\n const pending = raw as unknown as RekeyPending\n if (!pending.new_delegate_key || !pending.new_delegate_address || !pending.agent_id) {\n throw new Error(`The pending re-key at ${path} is unreadable. Delete it and start again with --rekey.`)\n }\n if (pending.expires_at && Date.parse(pending.expires_at) < now) {\n throw new Error(\n `The re-key started at ${pending.started_at} has expired. Start again with --rekey — the ` +\n 'address currently shown in your dashboard is no longer the one this machine holds.',\n )\n }\n return pending\n}\n\n/**\n * What a pending re-key IS, for anything that only needs to report it (#1911).\n *\n * Deliberately a separate return type from {@link RekeyPending}: it has no\n * `new_delegate_key` field at all, so a caller that reports this cannot leak\n * the private half by forgetting to strip it. The diagnostic surface uses this\n * accessor and never {@link readRekeyPending} — key material is unreachable\n * from that side by construction, not by discipline.\n *\n * Also a non-throwing read, where `readRekeyPending` throws: `--rekey-finish`\n * asked to consume one and deserves an error, but the doctor is enumerating\n * every directory on the machine and \"there isn't one\" is the normal answer.\n */\nexport interface RekeyPendingStatus {\n /** `pending` — still resumable; `expired` — past its TTL; `unreadable` — present but malformed. */\n state: 'pending' | 'expired' | 'unreadable'\n /** Where the file is, so the owner can act on it without hunting. */\n path: string\n agentId?: string\n /** PUBLIC address. The private half is never read into this shape. */\n newDelegateAddress?: string\n startedAt?: string\n expiresAt?: string\n}\n\nexport async function inspectRekeyPending(\n directory: string,\n now = Date.now(),\n): Promise<RekeyPendingStatus | null> {\n const path = join(directory, REKEY_PENDING_FILENAME)\n const raw = await readJsonFile(path)\n if (!raw) {\n // Distinguish \"no file\" from \"file that will not parse\". A file present\n // but unparseable still holds bytes that were a private key, so it is\n // reportable — reporting nothing would be the observability gap this\n // accessor exists to close.\n const present = (await readRawFile(path)) !== null\n return present ? { state: 'unreadable', path } : null\n }\n const agentId = asString(raw.agent_id)\n const newDelegateAddress = asString(raw.new_delegate_address)\n const startedAt = asString(raw.started_at)\n const expiresAt = asString(raw.expires_at)\n if (!agentId || !newDelegateAddress) {\n return { state: 'unreadable', path, ...(startedAt ? { startedAt } : {}) }\n }\n const expired = expiresAt !== undefined && Date.parse(expiresAt) < now\n return {\n state: expired ? 'expired' : 'pending',\n path,\n agentId,\n newDelegateAddress,\n ...(startedAt ? { startedAt } : {}),\n ...(expiresAt ? { expiresAt } : {}),\n }\n}\n\nexport async function clearRekeyPending(directory: string): Promise<void> {\n await rm(join(directory, REKEY_PENDING_FILENAME), { force: true }).catch(() => undefined)\n}\n\nasync function readJsonFile(path: string): Promise<Record<string, unknown> | null> {\n const raw = await readRawFile(path)\n if (raw === null) return null\n try {\n const parsed = JSON.parse(raw) as unknown\n return parsed && typeof parsed === 'object' && !Array.isArray(parsed)\n ? (parsed as Record<string, unknown>)\n : null\n } catch {\n return null\n }\n}\n\nasync function readRawFile(path: string): Promise<string | null> {\n try {\n return await readFile(path, 'utf8')\n } catch {\n return null\n }\n}\n\nfunction asString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\n\n/**\n * #1696: a wiring slug keys a credential directory, and connect never\n * overwrites credential files — a taken slug is refused before any side\n * effect. A leftover EMPTY slug directory (no identity.json) does not count\n * as taken. Replacing a named agent's credentials in place is #1700's\n * explicit re-key path, never a re-run.\n */\nexport async function assertServerSlugAvailable(serverName: string, baseDir?: string): Promise<void> {\n const directory = defaultAgentDirectory(serverName, baseDir)\n try {\n await stat(join(directory, 'identity.json'))\n } catch {\n return\n }\n throw new Error(\n `The name \"${serverName}\" is already wired on this machine (${directory} holds credentials). ` +\n 'Pick a different --name, or revoke and remove that agent first — connect never overwrites credentials.',\n )\n}\n\nexport function defaultAgentDirectory(agentId: string, baseDir = join(homedir(), '.haven', 'agents')): string {\n return resolve(defaultCredentialRoot(baseDir), safePathPart(agentId))\n}\n\nexport function defaultCredentialRoot(baseDir = join(homedir(), '.haven', 'agents')): string {\n return resolve(baseDir)\n}\n\nasync function writeOwnerOnlyJson(\n path: string,\n value: Record<string, unknown>,\n warn: ((message: string) => void) | undefined,\n): Promise<void> {\n const json = JSON.stringify(dropUndefined(value), null, 2)\n await writeFile(path, `${json}\\n`, { mode: 0o600, flag: 'wx' })\n await restrictPermissions(path, 0o600, warn)\n}\n\nfunction safePathPart(value: string): string {\n return value.replace(/[^A-Za-z0-9_.-]/g, '_')\n}\n\nfunction dropUndefined(value: Record<string, unknown>): Record<string, unknown> {\n return Object.fromEntries(Object.entries(value).filter(([, field]) => field !== undefined))\n}\n\nasync function assertDoesNotExist(path: string): Promise<void> {\n try {\n await access(path)\n } catch (err) {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') return\n throw err\n }\n throw new Error(`Refusing to overwrite existing Haven credential file: ${path}`)\n}\n\nasync function restrictPermissions(\n path: string,\n mode: 0o600 | 0o700,\n warn: ((message: string) => void) | undefined,\n): Promise<void> {\n try {\n await chmod(path, mode)\n } catch (err) {\n warn?.(\n `Warning: could not restrict permissions on ${path} to ${mode.toString(8)}. ` +\n `Move this credential to a private location or run chmod ${mode.toString(8)} ${path}. ` +\n `${err instanceof Error ? err.message : String(err)}`,\n )\n }\n}\n\n// ── The recovery record (#2173) ─────────────────────────────────────────────\n\n/**\n * Where the terminal `ConnectOutcome` is parked so a caller that lost the\n * stream can still read the verdict.\n *\n * The field failure this exists for (2026-08-28, connector 0.1.31-alpha.0):\n * setup SUCCEEDED, but the agent driving it stopped watching during the cold\n * signer install, so the connector's final `--json` object — the only place\n * the restart instruction and the read-only verification sequence live — was\n * emitted into a stream nobody was reading. The agent reverse-engineered\n * completion from `codex mcp list` instead.\n */\nexport const CONNECT_OUTCOME_FILENAME = 'last-connect-outcome.json'\n\n/**\n * Persist the terminal outcome next to the credentials it describes.\n *\n * Non-secret by construction: the content is exactly the object already\n * emitted on stdout, whose secret-freedom is pinned by its own tests. This\n * function never reads or embeds credential-file contents — it serializes what\n * it is handed and nothing else. Written 0o600 anyway, because it lives inside\n * a 0o700 credential directory and there is no reason to widen it.\n *\n * Overwrites, unlike every other write in this file: \"the last outcome\" is a\n * single slot, not a credential, so `assertDoesNotExist` would be wrong here —\n * a stale verdict left in place is exactly the failure the file exists to\n * prevent.\n *\n * Throws on failure. Best-effort is the CALLER's contract (`runConnect` wraps\n * both call sites), so that a test can inject a writer that fails and still\n * assert the run completes.\n */\nexport async function writeConnectOutcomeRecord(\n directory: string,\n outcome: unknown,\n warn?: (message: string) => void,\n): Promise<string> {\n const path = join(directory, CONNECT_OUTCOME_FILENAME)\n await writeFile(path, `${JSON.stringify(outcome, null, 2)}\\n`, { mode: 0o600 })\n await restrictPermissions(path, 0o600, warn)\n return path\n}\n","import { MCP_VERSION, registeredToolNames } from '@haven_ai/mcp'\nimport { toolSchemas as signerToolSchemas } from '@haven_ai/signer'\nimport { HAVEN_MINIMUM_NODE_VERSION } from '@haven_ai/sdk'\n\n// The required-tools list is derived from `@haven_ai/mcp`'s canonical\n// `registeredToolNames()` rather than maintained as a literal here. An earlier\n// hand-maintained list drifted out of sync with the MCP package (it advertised\n// tools the local MCP no longer exposed, and missed `haven_pay_x402` when it\n// landed), which broke the consent screen and the post-setup probe. Sourcing\n// from the MCP package directly is now the only way new tools can ship.\nexport const MCP_RUNTIME_MANIFEST = {\n mcpPackage: '@haven_ai/mcp',\n mcpVersion: MCP_VERSION,\n sdkPackage: '@haven_ai/sdk',\n sdkVersion: '0.0.0-dev.202609031523.fd49e1a',\n signerPackage: '@haven_ai/signer',\n signerVersion: '0.0.0-dev.202609031523.fd49e1a',\n // Sourced from the SDK, never a literal (#1161). This field read '20.0.0'\n // while every package's `engines` said `>=24` and the docs said `>=24.0.0`,\n // so the guard that was supposed to enforce the floor waved Node v23 through\n // — including on the `--local` path where it does run. A hand-maintained\n // second copy of a number is a drift waiting to happen; a guard test pins\n // this against `package.json`'s `engines.node`.\n minimumNodeVersion: HAVEN_MINIMUM_NODE_VERSION,\n supportedClients: ['codex-cli', 'codex-desktop', 'claude-code'] as const,\n requiredTools: registeredToolNames() as readonly string[],\n /**\n * The signer MCP's tool surface, DERIVED from the pinned @haven_ai/signer\n * package (#1587) — same anti-drift rule as `requiredTools` above: a\n * literal list here would rot the first time the signer gains a tool.\n * The handshake probe requires all of them.\n */\n requiredSignerTools: Object.keys(signerToolSchemas) as readonly string[],\n} as const\n\nexport function mcpPackageSpec(): string {\n return `${MCP_RUNTIME_MANIFEST.mcpPackage}@${MCP_RUNTIME_MANIFEST.mcpVersion}`\n}\n\nexport function sdkPackageSpec(): string {\n return `${MCP_RUNTIME_MANIFEST.sdkPackage}@${MCP_RUNTIME_MANIFEST.sdkVersion}`\n}\n\nexport function signerPackageSpec(): string {\n return `${MCP_RUNTIME_MANIFEST.signerPackage}@${MCP_RUNTIME_MANIFEST.signerVersion}`\n}\n","import { mkdir, readFile, writeFile, chmod, unlink } from 'node:fs/promises'\nimport { connectorRerunCommand } from '@haven_ai/sdk'\nimport { homedir, platform } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { isMap, parseDocument, stringify } from 'yaml'\nimport { signerPackageSpec } from './runtime-manifest.js'\nimport { serverNamesFor, type ServerNames } from './server-names.js'\nimport { type RuntimeId } from './runtime-registry.js'\n\nexport type RuntimeMcpMode = 'local_stdio' | 'hosted_plus_signer' | 'manual'\n\nconst HERMES_API_KEY_ENV = 'MCP_HAVEN_API_KEY'\n\n/** How to launch the local edge signer as an MCP stdio server. */\nexport interface SignerLaunchSpec {\n command: string\n args: string[]\n}\n\nexport interface RuntimeConfigInput {\n runtime: RuntimeId\n hostedMcpUrl: string\n apiKey: string\n identityPath: string\n signerPath: string\n credentialDirectory: string\n localMcpCommand?: string\n /**\n * Prepared signer launch command (absolute wrapper from prepareSignerRuntime).\n * When absent, falls back to a runtime `npx -y @haven_ai/signer@…` invocation,\n * which is fragile under the agent runtime's MCP-spawn environment — prefer\n * always passing a prepared command.\n */\n signerCommand?: SignerLaunchSpec\n homeDir?: string\n /**\n * Topology to write. 'hosted' (default) configures the keyless hosted MCP\n * server plus the local signer; 'local' restores the local-stdio MCP for\n * runtimes that support it (explicit opt-in only).\n */\n mode?: 'hosted' | 'local'\n /**\n * #1695: wiring slug for a NAMED server pair (haven-<slug> /\n * haven-signer-<slug>). Absent = the bare haven / haven-signer pair,\n * byte-identical to the pre-#1695 output. A writer only ever touches the\n * pair it owns, so named and unnamed pairs coexist in one config.\n */\n serverName?: string\n}\n\nexport interface RuntimeConfigWriteResult {\n hostedConfigured: boolean\n signerConfigured: boolean\n localMcpConfigured: boolean\n runtimeMcpMode: RuntimeMcpMode\n target: string\n changed: boolean\n restartRequired: boolean\n messages: string[]\n errorCode?: string\n activationCommand?: string\n}\n\n/** Injectable file operations for failure-safe runtime-config tests. */\nexport interface RuntimeConfigWriteDeps {\n writeOwnerOnlyText?: (path: string, value: string) => Promise<void>\n}\n\nclass HermesConfigRecoveryError extends Error {\n constructor() {\n super('Hermes configuration recovery did not complete')\n this.name = 'HermesConfigRecoveryError'\n }\n}\n\nexport class InvalidCodexTomlError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'InvalidCodexTomlError'\n }\n}\n\n/**\n * #1719: the chosen client's config file EXISTS but Haven cannot read it.\n *\n * Distinct from a write failure on purpose. A write failure is a permissions\n * or disk problem and \"try again\" is reasonable advice; an unreadable config\n * is a file the user has to fix by hand, and re-running the connector will\n * fail identically forever until they do. Collapsing the two under\n * `runtime_config_write_failed` told the user to retry a thing that cannot\n * succeed.\n */\n/**\n * Mirrors `RERUN` in doctor.ts — a moving dist-tag rather than a pinned\n * version, so the advice resolves to a connector that has `--repair`\n * regardless of what is cached locally. Which tag that is comes from the SDK's\n * build-time `HAVEN_CONNECTOR_CHANNEL` (#2423), so a build published under\n * `dev` repairs with the `dev` connector.\n */\nconst REPAIR_COMMAND_PREFIX = connectorRerunCommand('--doctor --repair --runtime')\n\nexport class UnreadableRuntimeConfigError extends Error {\n readonly configPath: string\n constructor(configPath: string, detail: string) {\n super(`${configPath} is not a config Haven can merge into (${detail})`)\n this.name = 'UnreadableRuntimeConfigError'\n this.configPath = configPath\n }\n}\n\nexport async function writeRuntimeConfig(\n input: RuntimeConfigInput,\n deps: RuntimeConfigWriteDeps = {},\n): Promise<RuntimeConfigWriteResult> {\n switch (input.runtime) {\n case 'codex-cli':\n case 'codex-desktop':\n return writeCodexConfig(input)\n case 'cursor':\n return writeJsonRuntimeConfig(input, cursorConfigPath(input.homeDir), 'mcpServers')\n case 'vscode':\n return writeJsonRuntimeConfig(input, vscodeConfigPath(input.homeDir), 'servers')\n case 'vscode-insiders':\n return writeJsonRuntimeConfig(input, vscodeInsidersConfigPath(input.homeDir), 'servers')\n case 'claude-desktop':\n return writeJsonRuntimeConfig(input, claudeDesktopConfigPath(input.homeDir), 'mcpServers')\n case 'hermes':\n return writeHermesConfig(input, deps)\n default:\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: 'manual',\n target: 'manual runtime setup',\n changed: false,\n restartRequired: true,\n messages: ['Runtime config needs to be added manually for this agent environment.'],\n errorCode: 'manual_runtime_setup_required',\n }\n }\n}\n\nexport function buildHostedServer(hostedMcpUrl: string, apiKey: string, runtime: RuntimeId): Record<string, unknown> {\n if (runtime === 'vscode' || runtime === 'vscode-insiders') {\n return {\n type: 'http',\n url: hostedMcpUrl,\n headers: { Authorization: `Bearer ${apiKey}` },\n }\n }\n return {\n url: hostedMcpUrl,\n headers: { Authorization: `Bearer ${apiKey}` },\n }\n}\n\n/**\n * Resolve how to launch the signer: the prepared absolute-path wrapper when\n * available, otherwise a runtime npx invocation (fallback only).\n */\nexport function resolveSignerLaunchSpec(input: RuntimeConfigInput): SignerLaunchSpec {\n return (\n input.signerCommand ?? {\n command: 'npx',\n args: ['-y', signerPackageSpec(), '--credentials', input.signerPath],\n }\n )\n}\n\nexport function buildSignerServer(spec: SignerLaunchSpec, runtime: RuntimeId): Record<string, unknown> {\n const server = {\n command: spec.command,\n args: spec.args,\n }\n if (runtime === 'vscode' || runtime === 'vscode-insiders') return { type: 'stdio', ...server }\n return server\n}\n\nexport function buildLocalMcpServer(command: string, runtime: RuntimeId): Record<string, unknown> {\n const server = {\n command,\n args: [],\n }\n if (runtime === 'vscode' || runtime === 'vscode-insiders') return { type: 'stdio', ...server }\n return server\n}\n\nexport function mergeJsonMcpConfig(\n existingJson: string | null,\n serverRoot: 'mcpServers' | 'servers',\n hostedServer: Record<string, unknown>,\n signerServer: Record<string, unknown>,\n names: ServerNames = serverNamesFor(),\n configPath?: string,\n): string {\n const config = existingJson?.trim() ? parseJsonObject(existingJson, configPath) : {}\n const existingRoot = config[serverRoot]\n const servers = existingRoot && typeof existingRoot === 'object' && !Array.isArray(existingRoot)\n ? existingRoot as Record<string, unknown>\n : {}\n config[serverRoot] = {\n ...servers,\n [names.hosted]: hostedServer,\n [names.signer]: signerServer,\n }\n return `${JSON.stringify(config, null, 2)}\\n`\n}\n\n/** Merge Haven's managed MCP entries into Hermes's YAML configuration. */\nexport function mergeHermesYaml(\n existingYaml: string | null,\n hostedServer: Record<string, unknown>,\n signerServer: Record<string, unknown>,\n names: ServerNames = serverNamesFor(),\n configPath?: string,\n): string {\n if (!existingYaml?.trim()) {\n return renderHermesYaml({ [names.hosted]: hostedServer, [names.signer]: signerServer })\n }\n\n const doc = parseDocument(existingYaml, { keepSourceTokens: true })\n if (doc.errors.length > 0 || !isMap(doc.contents)) {\n // #1719: the same class as an unparseable JSON config — the file has to be\n // fixed by hand, so it must not be reported as a retryable write failure.\n // The YAML parser's own message is deliberately NOT included: it quotes the\n // offending source, which is a file that may hold another server's bearer\n // token (the #1719 sibling of the redaction rule this writer already keeps).\n throw new UnreadableRuntimeConfigError(configPath ?? 'the Hermes config', 'it is not a YAML object')\n }\n\n const mcpPair = doc.contents.items.find((item) => item.key?.toString() === 'mcp_servers')\n const existingServers = mcpPair && isMap(mcpPair.value) ? mcpPair.value.toJSON() : {}\n const servers = isRecord(existingServers) ? existingServers : {}\n const mergedServers = {\n ...servers,\n [names.hosted]: hostedServer,\n [names.signer]: signerServer,\n }\n\n if (!mcpPair) {\n return appendHermesMcpServers(existingYaml, mergedServers)\n }\n if (!mcpPair.value?.range) return replaceEmptyHermesMcpServers(existingYaml, mcpPair.key?.range, mergedServers)\n return replaceHermesMcpServers(existingYaml, mcpPair.key?.range, mcpPair.value.range, mergedServers)\n}\n\n/**\n * Upsert the hosted MCP identity in Hermes's dotenv file without evaluating\n * arbitrary dotenv syntax or rewriting unrelated lines.\n */\nexport function mergeHermesEnv(\n existingEnv: string | null,\n apiKey: string,\n envKey: string = HERMES_API_KEY_ENV,\n): string {\n if (/[\\r\\n]/.test(apiKey)) throw new Error('Hermes API key must be a single line')\n\n const assignment = `${envKey}=${apiKey}`\n if (!existingEnv) return `${assignment}\\n`\n\n const lineEnding = existingEnv.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const hasTrailingNewline = /\\r?\\n$/.test(existingEnv)\n const lines = existingEnv.split(/\\r?\\n/)\n if (hasTrailingNewline) lines.pop()\n\n let found = false\n const merged = lines.flatMap((line) => {\n if (isHermesEnvAssignment(line, envKey)) {\n if (found) return []\n found = true\n return [assignment]\n }\n if (isAmbiguousHermesEnvLine(line, envKey)) {\n throw new Error('Hermes environment contains an ambiguous managed key')\n }\n return [line]\n })\n\n if (!found) {\n return `${existingEnv}${hasTrailingNewline ? '' : lineEnding}${assignment}${lineEnding}`\n }\n return `${merged.join(lineEnding)}${hasTrailingNewline ? lineEnding : ''}`\n}\n\nfunction isHermesEnvAssignment(line: string, envKey: string): boolean {\n return new RegExp(`^\\\\s*(?:export[ \\\\t]+)?${envKey}[ \\\\t]*=`).test(line)\n}\n\nfunction isAmbiguousHermesEnvLine(line: string, envKey: string): boolean {\n // The env keys are our own generated identifiers (no regex metacharacters),\n // so embedding them in a pattern is safe by construction.\n return new RegExp(`^\\\\s*(?:export[ \\\\t]+)?${envKey}\\\\b`).test(line)\n}\n\n/**\n * Remove one agent's managed pair from Hermes's YAML configuration,\n * byte-preserving every other line (#2169). The mirror of `mergeHermesYaml`.\n *\n * Returns the input unchanged when the pair is not present. Throws\n * `UnreadableRuntimeConfigError` when the file cannot be safely parsed, so a\n * caller can report it as a hand-fixable problem instead of writing over it.\n */\nexport function removeHermesYaml(\n existingYaml: string | null,\n names: ServerNames,\n configPath?: string,\n): string {\n if (!existingYaml?.trim()) return existingYaml ?? ''\n const doc = parseDocument(existingYaml, { keepSourceTokens: true })\n if (doc.errors.length > 0 || !isMap(doc.contents)) {\n throw new UnreadableRuntimeConfigError(configPath ?? 'the Hermes config', 'it is not a YAML object')\n }\n const mcpPair = doc.contents.items.find((item) => item.key?.toString() === 'mcp_servers')\n if (!mcpPair || !isMap(mcpPair.value)) return existingYaml\n\n const toRemove = mcpPair.value.items.filter((item) => {\n const name = item.key?.toString()\n return name === names.hosted || name === names.signer\n })\n if (toRemove.length === 0) return existingYaml\n if (toRemove.length !== mcpPair.value.items.length && toRemove.some((item) => !item.key?.range || !item.value?.range)) {\n // A sibling entry we would have to splice around lacks source ranges —\n // refuse rather than risk corrupting someone else's pair.\n throw new UnreadableRuntimeConfigError(configPath ?? 'the Hermes config', 'an MCP server entry cannot be safely removed')\n }\n\n let out = existingYaml\n // Splice from the bottom up so earlier offsets stay valid.\n const ranges: Array<[number, number]> = toRemove.map((item) => {\n const keyStart = item.key!.range![0]\n const valueEnd = item.value!.range![1]\n const lineStart = existingYaml.lastIndexOf('\\n', keyStart - 1) + 1\n let end = valueEnd\n if (existingYaml.slice(end).startsWith('\\r\\n')) end += 2\n else if (existingYaml[end] === '\\n') end += 1\n return [lineStart, end] as [number, number]\n })\n ranges.sort((a, b) => b[0] - a[0])\n for (const [start, end] of ranges) out = out.slice(0, start) + out.slice(end)\n\n // If mcp_servers now holds nothing, drop the key itself so the config does\n // not carry an empty managed map.\n if (toRemove.length === mcpPair.value.items.length) {\n const reparsed = parseDocument(out, { keepSourceTokens: true })\n if (!reparsed.errors.length && isMap(reparsed.contents)) {\n const pair = reparsed.contents.items.find((item) => item.key?.toString() === 'mcp_servers')\n if (pair && pair.key?.range && pair.value?.range) {\n const keyStart = pair.key.range[0]\n const valueEnd = pair.value.range[1]\n const lineStart = out.lastIndexOf('\\n', keyStart - 1) + 1\n let end = valueEnd\n if (out.slice(end).startsWith('\\r\\n')) end += 2\n else if (out[end] === '\\n') end += 1\n out = out.slice(0, lineStart) + out.slice(end)\n }\n }\n }\n return out\n}\n\n/**\n * Remove one pair's API-key assignment from Hermes's dotenv file,\n * byte-preserving every other line (#2169). The mirror of `mergeHermesEnv`.\n *\n * Returns the input unchanged when the key is absent. Refuses when the managed\n * key is ambiguous, matching `mergeHermesEnv`'s discipline — never rewrite a\n * line it cannot positively identify as ours.\n */\nexport function removeHermesEnv(existingEnv: string | null, envKey: string): string {\n if (!existingEnv) return ''\n const lineEnding = existingEnv.includes('\\r\\n') ? '\\r\\n' : '\\n'\n const hasTrailingNewline = /\\r?\\n$/.test(existingEnv)\n const lines = existingEnv.split(/\\r?\\n/)\n if (hasTrailingNewline) lines.pop()\n\n let removed = 0\n const kept = lines.filter((line) => {\n if (isHermesEnvAssignment(line, envKey)) {\n removed += 1\n return false\n }\n if (isAmbiguousHermesEnvLine(line, envKey)) {\n throw new Error('Hermes environment contains an ambiguous managed key')\n }\n return true\n })\n if (removed === 0) return existingEnv\n const joined = kept.join(lineEnding)\n return hasTrailingNewline ? `${joined}${lineEnding}` : joined\n}\n\n/**\n * Remove one agent's hosted + signer entries from a JSON MCP config (Cursor,\n * VS Code, VS Code Insiders, Claude Desktop). The mirror of\n * `mergeJsonMcpConfig`; deletes only the owned names and re-serializes with\n * the writer's own 2-space style.\n */\nexport function removeJsonMcpConfig(\n existingJson: string | null,\n serverRoot: 'mcpServers' | 'servers',\n names: ServerNames,\n configPath?: string,\n): string {\n if (!existingJson?.trim()) return existingJson ?? ''\n const config = parseJsonObject(existingJson, configPath) as Record<string, unknown>\n const root = config[serverRoot]\n if (!root || typeof root !== 'object' || Array.isArray(root)) return existingJson\n const servers = root as Record<string, unknown>\n let removed = false\n for (const name of [names.hosted, names.signer]) {\n if (name in servers) {\n delete servers[name]\n removed = true\n }\n }\n if (!removed) return existingJson\n if (Object.keys(servers).length === 0) delete config[serverRoot]\n return `${JSON.stringify(config, null, 2)}\\n`\n}\n\n/**\n * Remove one agent's Codex TOML tables. The mirror of `mergeCodexToml` /\n * `mergeCodexTomlHosted`, which already remove-then-append — this is the\n * remove half alone.\n */\nexport function removeCodexToml(existingToml: string, names: ServerNames): string {\n let next = removeTomlTableTree(\n removeTomlTableTree(existingToml, `mcp_servers.${names.codexHosted}`),\n `mcp_servers.${names.codexSigner}`,\n )\n return next\n}\n\n\nfunction appendHermesMcpServers(source: string, servers: Record<string, unknown>): string {\n const documentEnd = /(?:^|\\n)[ \\t]*\\.\\.\\.[ \\t]*(?:#[^\\n]*)?\\r?\\n?$/.exec(source)\n if (documentEnd) {\n const markerStart = documentEnd.index + (documentEnd[0].startsWith('\\n') ? 1 : 0)\n const beforeMarker = source.slice(0, markerStart)\n return `${beforeMarker}${beforeMarker.endsWith('\\n') ? '' : '\\n'}${renderHermesMcpServers(servers, '')}\\n${source.slice(markerStart)}`\n }\n const separator = source.endsWith('\\n') ? '' : '\\n'\n return `${source}${separator}${renderHermesMcpServers(servers, '')}\\n`\n}\n\nfunction replaceHermesMcpServers(\n source: string,\n keyRange: readonly number[] | undefined,\n valueRange: readonly number[],\n servers: Record<string, unknown>,\n): string {\n const valueStart = valueRange[0]\n const valueEnd = valueRange[1]\n const valueLineStart = source.lastIndexOf('\\n', valueStart - 1) + 1\n const keyStartsOnValueLine = keyRange?.[0] !== undefined && keyRange[0] >= valueLineStart\n const nestedIndent = `${source.slice(valueLineStart, keyRange?.[0] ?? valueLineStart)} `\n\n if (keyStartsOnValueLine) {\n const keyStart = keyRange![0]\n const keyEnd = keyRange![1]\n const replacement = `${source.slice(keyStart, keyEnd)}:\\n${renderHermesMcpServerEntries(servers, nestedIndent)}`\n const needsTrailingNewline = valueEnd < source.length && !source.slice(valueEnd).startsWith('\\n')\n return `${source.slice(0, keyStart)}${replacement}${needsTrailingNewline ? '\\n' : ''}${source.slice(valueEnd)}`\n }\n\n const indent = source.slice(valueLineStart, valueStart)\n const rendered = stringify(servers, { lineWidth: 120 }).trimEnd()\n const replacement = rendered.split('\\n').map((line, index) => index === 0 ? line : `${indent}${line}`).join('\\n')\n const needsTrailingNewline = valueEnd < source.length && !source.slice(valueEnd).startsWith('\\n')\n return `${source.slice(0, valueStart)}${replacement}${needsTrailingNewline ? '\\n' : ''}${source.slice(valueEnd)}`\n}\n\nfunction replaceEmptyHermesMcpServers(\n source: string,\n keyRange: readonly number[] | undefined,\n servers: Record<string, unknown>,\n): string {\n if (!keyRange) throw new Error('Hermes config mcp_servers key is invalid')\n const keyStart = keyRange[0]\n const keyEnd = keyRange[1]\n const lineStart = source.lastIndexOf('\\n', keyStart - 1) + 1\n const lineEnd = source.indexOf('\\n', keyEnd)\n const nestedIndent = `${source.slice(lineStart, keyStart)} `\n const replacement = `${source.slice(keyStart, keyEnd)}:\\n${renderHermesMcpServerEntries(servers, nestedIndent)}`\n return `${source.slice(0, keyStart)}${replacement}${lineEnd === -1 ? '\\n' : source.slice(lineEnd)}`\n}\n\nfunction renderHermesYaml(servers: Record<string, unknown>): string {\n return `${renderHermesMcpServers(servers, '')}\\n`\n}\n\nfunction renderHermesMcpServers(servers: Record<string, unknown>, indent: string): string {\n return `mcp_servers:\\n${renderHermesMcpServerEntries(servers, `${indent} `)}`\n}\n\nfunction renderHermesMcpServerEntries(servers: Record<string, unknown>, indent: string): string {\n return stringify(servers, { lineWidth: 120 })\n .trimEnd()\n .split('\\n')\n .map((line) => `${indent}${line}`)\n .join('\\n')\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nexport function mergeCodexToml(\n existingToml: string,\n localMcpCommand: string,\n names: ServerNames = serverNamesFor(),\n): string {\n let next = removeTomlTableTree(\n removeTomlTableTree(existingToml, `mcp_servers.${names.codexHosted}`),\n `mcp_servers.${names.codexSigner}`,\n )\n next = next.trimEnd()\n const block = [\n `[mcp_servers.${names.codexHosted}]`,\n `command = ${tomlString(localMcpCommand)}`,\n 'args = []',\n 'startup_timeout_sec = 120',\n ].join('\\n')\n validateCodexToml(block, 'Generated Codex Haven config')\n const merged = `${next ? `${next}\\n\\n` : ''}${block}\\n`\n return merged\n}\n\nexport function mergeCodexTomlHosted(\n existingToml: string,\n hostedMcpUrl: string,\n apiKey: string,\n signerSpec: SignerLaunchSpec,\n names: ServerNames = serverNamesFor(),\n): string {\n let next = removeTomlTableTree(\n removeTomlTableTree(existingToml, `mcp_servers.${names.codexHosted}`),\n `mcp_servers.${names.codexSigner}`,\n )\n next = next.trimEnd()\n const block = [\n `[mcp_servers.${names.codexHosted}]`,\n `url = ${tomlString(hostedMcpUrl)}`,\n `http_headers = { \"Authorization\" = ${tomlString(`Bearer ${apiKey}`)} }`,\n '',\n `[mcp_servers.${names.codexSigner}]`,\n `command = ${tomlString(signerSpec.command)}`,\n `args = [${signerSpec.args.map((arg) => tomlString(arg)).join(', ')}]`,\n 'startup_timeout_sec = 120',\n ].join('\\n')\n validateCodexToml(block, 'Generated Codex Haven config')\n const merged = `${next ? `${next}\\n\\n` : ''}${block}\\n`\n return merged\n}\n\nasync function writeJsonRuntimeConfig(\n input: RuntimeConfigInput,\n target: string,\n serverRoot: 'mcpServers' | 'servers',\n): Promise<RuntimeConfigWriteResult> {\n try {\n const existing = await readOptional(target)\n const merged = mergeJsonMcpConfig(\n existing,\n serverRoot,\n buildHostedServer(input.hostedMcpUrl, input.apiKey, input.runtime),\n buildSignerServer(resolveSignerLaunchSpec(input), input.runtime),\n serverNamesFor(input.serverName),\n target,\n )\n await writeOwnerOnlyText(target, merged)\n return {\n hostedConfigured: true,\n signerConfigured: true,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: configTargetLabel(input.runtime),\n changed: existing !== merged,\n restartRequired: input.runtime === 'claude-desktop',\n messages: [`Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`],\n }\n } catch (err) {\n // #1719: the parse runs BEFORE the write, so an unreadable config leaves\n // the file untouched — no half-merged config, nothing to roll back. The\n // separate code exists so the message can say \"fix this file\" instead of\n // \"run setup again\", which would never succeed — this fires AFTER\n // registerSetup consumed the one-shot setup token, so the pasted command\n // now 409s at /resolve. `--repair` is the recovery that actually works:\n // it rewrites this exact config from the credentials already on disk,\n // needs no token, and mints no second agent (the #1688 orphaning a fresh\n // connection would cause).\n const unreadable = err instanceof UnreadableRuntimeConfigError\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: configTargetLabel(input.runtime),\n changed: false,\n restartRequired: true,\n messages: unreadable\n ? [\n `Could not update ${configTargetLabel(input.runtime)}: ${err.message}.`,\n `Nothing was written to ${err.configPath}. Fix the JSON there (or move the file aside), then run \\`${REPAIR_COMMAND_PREFIX} ${input.runtime}\\` to write the Haven entries from the credentials already stored on this machine. Do not re-run the setup command: its token is already used.`,\n ]\n : [`Could not update ${configTargetLabel(input.runtime)}: ${err instanceof Error ? err.message : String(err)}`],\n errorCode: unreadable ? 'runtime_config_unreadable' : 'runtime_config_write_failed',\n }\n }\n}\n\nasync function writeHermesConfig(input: RuntimeConfigInput, deps: RuntimeConfigWriteDeps): Promise<RuntimeConfigWriteResult> {\n const target = hermesConfigPath(input.homeDir)\n const envTarget = hermesEnvPath(input.homeDir)\n try {\n const [existing, existingEnv] = await Promise.all([readOptional(target), readOptional(envTarget)])\n const names = serverNamesFor(input.serverName)\n const hostedServer = {\n ...buildHostedServer(input.hostedMcpUrl, `\\${${names.hermesEnvKey}}`, input.runtime),\n enabled: true,\n }\n const signerServer = {\n ...buildSignerServer(resolveSignerLaunchSpec(input), input.runtime),\n enabled: true,\n }\n const merged = mergeHermesYaml(\n existing,\n hostedServer,\n signerServer,\n names,\n target,\n )\n const mergedEnv = mergeHermesEnv(existingEnv, input.apiKey, names.hermesEnvKey)\n const writeText = deps.writeOwnerOnlyText ?? writeOwnerOnlyText\n await writeText(envTarget, mergedEnv)\n try {\n await writeText(target, merged)\n } catch (err) {\n const recovered = await restoreHermesFiles(target, existing, envTarget, existingEnv, writeText)\n if (!recovered) throw new HermesConfigRecoveryError()\n throw err\n }\n return {\n hostedConfigured: true,\n signerConfigured: true,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: 'Hermes Agent config',\n changed: existing !== merged || existingEnv !== mergedEnv,\n restartRequired: true,\n messages: [\n `Updated Haven MCP entries in ${target}; stored the hosted MCP identity in ${envTarget}.`,\n 'Restart Hermes (start a new session; gateway users: /restart), then verify with `hermes mcp list`, `hermes mcp test haven`, and `hermes mcp test haven-signer`.',\n 'If several long-lived Hermes processes are running (a gateway plus TUI workers), restart EVERY one: each loads its MCP wiring at startup, so a process started before this setup keeps using its old snapshot.',\n 'If no mcp_* tools appear after restart, ensure the MCP SDK is installed in Hermes: pip install mcp',\n ],\n }\n } catch (err) {\n const recoveryIncomplete = err instanceof HermesConfigRecoveryError\n const unreadable = err instanceof UnreadableRuntimeConfigError\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: 'Hermes Agent config',\n changed: false,\n restartRequired: true,\n messages: unreadable\n ? [\n `Could not update Hermes Agent config: ${err.message}.`,\n `Nothing was written to ${err.configPath}. Fix the YAML there (or move the file aside), then run \\`${REPAIR_COMMAND_PREFIX} hermes\\` to write the Haven entries from the credentials already stored on this machine. Do not re-run the setup command: its token is already used.`,\n ]\n : [recoveryIncomplete\n ? 'Could not update Hermes Agent config. Recovery did not complete; inspect the Hermes configuration before retrying.'\n : 'Could not update Hermes Agent config. Existing configuration was left unchanged.'],\n errorCode: unreadable ? 'runtime_config_unreadable' : 'runtime_config_write_failed',\n }\n }\n}\n\nasync function restoreHermesFiles(\n configPath: string,\n existingConfig: string | null,\n envPath: string,\n existingEnv: string | null,\n writeText: (path: string, value: string) => Promise<void>,\n): Promise<boolean> {\n const [envResult, configResult] = await Promise.allSettled([\n restoreOptionalText(envPath, existingEnv, writeText),\n restoreOptionalText(configPath, existingConfig, writeText),\n ])\n return envResult.status === 'fulfilled' && configResult.status === 'fulfilled'\n}\n\nasync function restoreOptionalText(\n path: string,\n existing: string | null,\n writeText: (path: string, value: string) => Promise<void>,\n): Promise<void> {\n if (existing !== null) {\n await writeText(path, existing)\n return\n }\n try {\n await unlink(path)\n } catch (err) {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') return\n throw err\n }\n}\n\nasync function writeCodexConfig(input: RuntimeConfigInput): Promise<RuntimeConfigWriteResult> {\n const target = codexConfigPath(input.homeDir)\n const local = input.mode === 'local'\n try {\n const existing = await readOptional(target)\n if (local) {\n if (!input.localMcpCommand) {\n throw new Error('local MCP wrapper command is required')\n }\n const merged = mergeCodexToml(existing ?? '', input.localMcpCommand, serverNamesFor(input.serverName))\n await writeOwnerOnlyText(target, merged)\n return {\n hostedConfigured: false,\n signerConfigured: true,\n localMcpConfigured: true,\n runtimeMcpMode: 'local_stdio',\n target: configTargetLabel(input.runtime),\n changed: existing !== merged,\n restartRequired: true,\n messages: [\n `Updated local Haven MCP entry in ${configTargetLabel(input.runtime)}.`,\n ],\n }\n }\n const merged = mergeCodexTomlHosted(\n existing ?? '',\n input.hostedMcpUrl,\n input.apiKey,\n resolveSignerLaunchSpec(input),\n serverNamesFor(input.serverName),\n )\n await writeOwnerOnlyText(target, merged)\n return {\n hostedConfigured: true,\n signerConfigured: true,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: configTargetLabel(input.runtime),\n changed: existing !== merged,\n restartRequired: true,\n messages: [\n `Updated Haven MCP entries in ${configTargetLabel(input.runtime)}.`,\n ],\n }\n } catch (err) {\n const invalidToml = err instanceof InvalidCodexTomlError\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: local ? 'local_stdio' : 'hosted_plus_signer',\n target: configTargetLabel(input.runtime),\n changed: false,\n restartRequired: true,\n messages: [`Could not update ${configTargetLabel(input.runtime)}: ${err instanceof Error ? err.message : String(err)}`],\n errorCode: invalidToml ? 'codex_config_invalid' : 'runtime_config_write_failed',\n }\n }\n}\n\nasync function readOptional(path: string): Promise<string | null> {\n try {\n return await readFile(path, 'utf8')\n } catch (err) {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'ENOENT') return null\n throw err\n }\n}\n\nasync function writeOwnerOnlyText(path: string, value: string): Promise<void> {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 })\n await writeFile(path, value, { mode: 0o600 })\n await chmod(path, 0o600).catch(() => undefined)\n}\n\nfunction parseJsonObject(value: string, configPath?: string): Record<string, unknown> {\n let parsed: unknown\n try {\n parsed = JSON.parse(value) as unknown\n } catch {\n // The parser's own message is deliberately dropped: V8's SyntaxError text\n // quotes the offending source, and this file may hold ANOTHER MCP server's\n // bearer token. The path plus \"not valid JSON\" is everything the user\n // needs, and nothing they must not see in a log.\n throw new UnreadableRuntimeConfigError(configPath ?? 'the runtime config', 'it is not valid JSON')\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new UnreadableRuntimeConfigError(configPath ?? 'the runtime config', 'the top level is not a JSON object')\n }\n return parsed as Record<string, unknown>\n}\n\nfunction removeTomlTableTree(toml: string, table: string): string {\n const lines = toml.split(/\\r?\\n/)\n const kept: string[] = []\n let skipping = false\n for (const line of lines) {\n const trimmed = line.trim()\n const tableName = tomlTableName(trimmed)\n if (tableName) {\n skipping = tableName === table || tableName.startsWith(`${table}.`)\n if (skipping) continue\n }\n if (!skipping) kept.push(line)\n }\n return kept.join('\\n')\n}\n\nfunction tomlTableName(line: string): string | null {\n if (line.startsWith('[[') && line.endsWith(']]')) return line.slice(2, -2).trim()\n if (line.startsWith('[') && line.endsWith(']')) return line.slice(1, -1).trim()\n return null\n}\n\nexport function validateCodexToml(toml: string, label = 'Codex config'): void {\n const lines = toml.split(/\\r?\\n/)\n let pendingValue: { value: string; line: number } | null = null\n for (let index = 0; index < lines.length; index += 1) {\n const raw = lines[index]\n const line = stripTomlComment(raw).trim()\n if (!line) continue\n\n if (pendingValue) {\n pendingValue.value = `${pendingValue.value}\\n${line}`\n if (hasBalancedTomlContainers(pendingValue.value)) {\n if (!isTomlValue(pendingValue.value)) {\n throw new InvalidCodexTomlError(`${label} has invalid TOML near line ${pendingValue.line}.`)\n }\n pendingValue = null\n }\n continue\n }\n\n if (isTomlTable(line)) continue\n\n const equalsIndex = line.indexOf('=')\n if (equalsIndex <= 0) {\n throw new InvalidCodexTomlError(`${label} has invalid TOML near line ${index + 1}.`)\n }\n\n const key = line.slice(0, equalsIndex).trim()\n const value = line.slice(equalsIndex + 1).trim()\n if (!isTomlKey(key)) {\n throw new InvalidCodexTomlError(`${label} has invalid TOML near line ${index + 1}.`)\n }\n if (startsTomlContainer(value) && !hasBalancedTomlContainers(value)) {\n pendingValue = { value, line: index + 1 }\n continue\n }\n if (!isTomlValue(value)) {\n throw new InvalidCodexTomlError(`${label} has invalid TOML near line ${index + 1}.`)\n }\n }\n if (pendingValue) {\n throw new InvalidCodexTomlError(`${label} has invalid TOML near line ${pendingValue.line}.`)\n }\n}\n\nfunction isTomlTable(line: string): boolean {\n const table = tomlTableName(line)\n return Boolean(table && splitTomlDottedKey(table).every(isTomlKeyPart))\n}\n\nfunction isTomlKey(value: string): boolean {\n return splitTomlDottedKey(value).every(isTomlKeyPart)\n}\n\nfunction splitTomlDottedKey(value: string): string[] {\n const parts: string[] = []\n let current = ''\n let quote: '\"' | \"'\" | null = null\n let escaped = false\n for (let i = 0; i < value.length; i += 1) {\n const char = value[i]\n if (quote) {\n current += char\n if (quote === '\"' && char === '\\\\' && !escaped) {\n escaped = true\n continue\n }\n if (char === quote && !escaped) quote = null\n escaped = false\n continue\n }\n if (char === '\"' || char === \"'\") {\n quote = char\n current += char\n continue\n }\n if (char === '.') {\n parts.push(current.trim())\n current = ''\n continue\n }\n current += char\n }\n parts.push(current.trim())\n return quote ? [] : parts\n}\n\nfunction isTomlKeyPart(value: string): boolean {\n return isTomlBareKey(value) || isTomlQuotedString(value)\n}\n\nfunction isTomlBareKey(value: string): boolean {\n return /^[A-Za-z0-9_-]+$/.test(value)\n}\n\nfunction isTomlValue(value: string): boolean {\n if (!value) return false\n if (isTomlQuotedString(value)) return true\n if (/^(true|false)$/i.test(value)) return true\n if (/^[+-]?(?:inf|nan)$/i.test(value)) return true\n if (/^[+-]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]+)?(?:[eE][+-]?[0-9_]+)?$/.test(value)) return true\n if (/^\\d{4}-\\d{2}-\\d{2}(?:[Tt ][0-9:.+-Zz]+)?$/.test(value)) return true\n if ((value.startsWith('[') && value.endsWith(']')) || (value.startsWith('{') && value.endsWith('}'))) {\n return hasBalancedTomlContainers(value)\n }\n return false\n}\n\nfunction startsTomlContainer(value: string): boolean {\n return value.startsWith('[') || value.startsWith('{')\n}\n\nfunction isTomlQuotedString(value: string): boolean {\n if (value.startsWith('\"\"\"') || value.startsWith(\"'''\")) {\n const marker = value.slice(0, 3)\n return value.length >= 6 && value.endsWith(marker)\n }\n if ((!value.startsWith('\"') || !value.endsWith('\"')) && (!value.startsWith(\"'\") || !value.endsWith(\"'\"))) {\n return false\n }\n return hasBalancedTomlContainers(value)\n}\n\nfunction stripTomlComment(value: string): string {\n let quote: '\"' | \"'\" | null = null\n let escaped = false\n for (let i = 0; i < value.length; i += 1) {\n const char = value[i]\n if (quote) {\n if (quote === '\"' && char === '\\\\' && !escaped) {\n escaped = true\n continue\n }\n if (char === quote && !escaped) quote = null\n escaped = false\n continue\n }\n if (char === '\"' || char === \"'\") {\n quote = char\n continue\n }\n if (char === '#') return value.slice(0, i)\n }\n return value\n}\n\nfunction hasBalancedTomlContainers(value: string): boolean {\n const stack: string[] = []\n let quote: '\"' | \"'\" | null = null\n let escaped = false\n for (let i = 0; i < value.length; i += 1) {\n const char = value[i]\n if (quote) {\n if (quote === '\"' && char === '\\\\' && !escaped) {\n escaped = true\n continue\n }\n if (char === quote && !escaped) quote = null\n escaped = false\n continue\n }\n if (char === '\"' || char === \"'\") {\n quote = char\n continue\n }\n if (char === '[' || char === '{') {\n stack.push(char)\n continue\n }\n if (char === ']') {\n if (stack.pop() !== '[') return false\n continue\n }\n if (char === '}') {\n if (stack.pop() !== '{') return false\n }\n }\n return stack.length === 0 && quote === null\n}\n\nfunction tomlString(value: string): string {\n return `\"${value.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"')}\"`\n}\n\n/**\n * #1589: the doctor needs to READ the config the writers write. One resolver,\n * next to the path functions themselves so a new runtime cannot be added\n * without the doctor seeing it (returns null for runtimes without a\n * file-based config this module owns, e.g. claude-code via the CLI).\n */\nexport function runtimeConfigPathFor(runtime: string, homeDir = homedir()): string | null {\n switch (runtime) {\n case 'cursor':\n return cursorConfigPath(homeDir)\n case 'codex-cli':\n case 'codex-desktop':\n return codexConfigPath(homeDir)\n case 'vscode':\n return vscodeConfigPath(homeDir)\n case 'vscode-insiders':\n return vscodeInsidersConfigPath(homeDir)\n case 'claude-desktop':\n return claudeDesktopConfigPath(homeDir)\n case 'hermes':\n return hermesConfigPath(homeDir)\n default:\n return null\n }\n}\n\nfunction cursorConfigPath(homeDir = homedir()): string {\n return resolve(homeDir, '.cursor', 'mcp.json')\n}\n\nfunction codexConfigPath(homeDir = homedir()): string {\n return resolve(homeDir, '.codex', 'config.toml')\n}\n\nfunction vscodeConfigPath(homeDir = homedir()): string {\n if (platform() === 'darwin') return resolve(homeDir, 'Library', 'Application Support', 'Code', 'User', 'mcp.json')\n if (platform() === 'win32') {\n return resolve(process.env.APPDATA ?? join(homeDir, 'AppData', 'Roaming'), 'Code', 'User', 'mcp.json')\n }\n return resolve(homeDir, '.config', 'Code', 'User', 'mcp.json')\n}\n\nfunction vscodeInsidersConfigPath(homeDir = homedir()): string {\n if (platform() === 'darwin') return resolve(homeDir, 'Library', 'Application Support', 'Code - Insiders', 'User', 'mcp.json')\n if (platform() === 'win32') {\n return resolve(process.env.APPDATA ?? join(homeDir, 'AppData', 'Roaming'), 'Code - Insiders', 'User', 'mcp.json')\n }\n return resolve(homeDir, '.config', 'Code - Insiders', 'User', 'mcp.json')\n}\n\nfunction claudeDesktopConfigPath(homeDir = homedir()): string {\n if (platform() === 'darwin') {\n return resolve(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json')\n }\n if (platform() === 'win32') {\n return resolve(process.env.APPDATA ?? join(homeDir, 'AppData', 'Roaming'), 'Claude', 'claude_desktop_config.json')\n }\n return resolve(homeDir, '.config', 'Claude', 'claude_desktop_config.json')\n}\n\nexport function hermesConfigPath(homeDir?: string): string {\n return join(hermesHomePath(homeDir), 'config.yaml')\n}\n\nexport function hermesEnvPath(homeDir?: string): string {\n return join(hermesHomePath(homeDir), '.env')\n}\n\nfunction hermesHomePath(homeDir?: string): string {\n return process.env.HERMES_HOME ?? join(homeDir ?? homedir(), '.hermes')\n}\n\nfunction configTargetLabel(runtime: RuntimeId): string {\n switch (runtime) {\n case 'codex-cli':\n return 'Codex CLI config'\n case 'codex-desktop':\n return 'Codex Desktop config'\n case 'cursor':\n return 'Cursor MCP config'\n case 'vscode':\n return 'VS Code MCP config'\n case 'vscode-insiders':\n return 'VS Code Insiders MCP config'\n case 'claude-desktop':\n return 'Claude Desktop config'\n default:\n return 'runtime MCP config'\n }\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport {\n computeConsentHash,\n consentInputFromClient,\n ensureConsent,\n loadCredentials,\n registeredToolNames,\n type ConsentDecision,\n} from '@haven_ai/mcp'\n\nexport interface LocalMcpConsentStatus {\n acknowledged: boolean\n hash?: string\n reason?: ConsentDecision['reason'] | 'ack_file_missing' | 'ack_file_mismatch'\n error?: string\n}\n\nexport async function acknowledgeLocalMcpConsent(\n identityPath: string,\n signerPath: string,\n log?: (message: string) => void,\n): Promise<LocalMcpConsentStatus> {\n try {\n const input = await buildLocalMcpConsentInput(identityPath, signerPath)\n const decision = await ensureConsent(input, {\n credentialsPath: identityPath,\n writeAck: true,\n out: log ? { write: (chunk) => writeLogChunk(log, chunk) } : undefined,\n })\n return {\n acknowledged: decision.ok,\n hash: decision.hash,\n reason: decision.reason,\n }\n } catch (err) {\n return {\n acknowledged: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\nexport async function getLocalMcpConsentStatus(\n identityPath: string,\n signerPath: string,\n): Promise<LocalMcpConsentStatus> {\n try {\n const input = await buildLocalMcpConsentInput(identityPath, signerPath)\n const hash = computeConsentHash(input)\n const stored = await readLocalMcpAckFile(localMcpAckPath(identityPath))\n if (stored === hash) {\n return { acknowledged: true, hash, reason: 'ack_file_match' }\n }\n return {\n acknowledged: false,\n hash,\n reason: stored ? 'ack_file_mismatch' : 'ack_file_missing',\n }\n } catch (err) {\n return {\n acknowledged: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\nexport function localMcpAckPath(identityPath: string): string {\n return resolve(`${identityPath}.ack.json`)\n}\n\nasync function buildLocalMcpConsentInput(identityPath: string, signerPath: string) {\n const credentials = await loadCredentials({ identityPath, signerPath })\n const unavailableDuringSetup = {\n getAllowances: async () => {\n throw new Error('Haven approval is not complete yet.')\n },\n }\n return consentInputFromClient(\n unavailableDuringSetup as never,\n {\n apiKey: credentials.apiKey,\n apiUrl: credentials.apiUrl,\n agentId: credentials.agentId,\n safeAddress: credentials.safeAddress,\n delegateAddress: credentials.delegateAddress,\n chainId: credentials.chainId,\n allowanceSummary: credentials.allowanceSummary,\n },\n registeredToolNames(),\n )\n}\n\nasync function readLocalMcpAckFile(path: string): Promise<string | null> {\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as { ack?: unknown }\n return typeof parsed.ack === 'string' ? parsed.ack : null\n } catch {\n return null\n }\n}\n\nfunction writeLogChunk(log: (message: string) => void, chunk: string): void {\n const message = String(chunk).trimEnd()\n if (message) log(message)\n}\n","import { spawn } from 'node:child_process'\nimport { readFile } from 'node:fs/promises'\n\nexport type HostedProbeStatus = 'ok' | 'unauthorized' | 'network_error' | 'bad_response'\n\nexport interface HostedProbeResult {\n status: HostedProbeStatus\n toolCount?: number\n}\n\n/**\n * #1697: who does this API key actually authenticate as?\n *\n * The #1681 incident was only provable by hand: cross-checking the delegate\n * address a live session reported against the `signer.json` on disk, a check\n * nothing in the product performed. This is the knowable half — the doctor\n * still cannot see inside a running host, but it CAN prove that the stored\n * API key and the stored signing key belong to the same agent. The key read\n * here is the same one the hosted MCP entry carries, which is what makes the\n * comparison meaningful rather than incidental.\n *\n * Read-only: a GET of the agent's own identity, nothing else.\n */\nexport interface HostedIdentityProbeResult {\n status: HostedProbeStatus\n agentId?: string\n delegateAddress?: string\n}\n\nexport async function probeHostedAgentIdentity(\n apiKey: string,\n apiUrl: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<HostedIdentityProbeResult> {\n let response: Response\n try {\n response = await fetchWithTimeout(fetchImpl, `${apiUrl.replace(/\\/+$/, '')}/machine-payments/agent`, {\n method: 'GET',\n headers: { Authorization: `Bearer ${apiKey}`, Accept: 'application/json' },\n })\n } catch {\n return { status: 'network_error' }\n }\n if (response.status === 401 || response.status === 403) return { status: 'unauthorized' }\n if (!response.ok) return { status: 'bad_response' }\n try {\n const payload = JSON.parse(await response.text()) as { id?: string; delegate_address?: string }\n if (typeof payload?.delegate_address !== 'string') return { status: 'bad_response' }\n return { status: 'ok', agentId: payload.id, delegateAddress: payload.delegate_address }\n } catch {\n return { status: 'bad_response' }\n }\n}\n\nexport type LocalMcpProbeStatus = 'ok' | 'timeout' | 'process_error' | 'bad_response' | 'missing_tools'\n\nexport interface LocalMcpProbeResult {\n status: LocalMcpProbeStatus\n /** #1589: the initialize response's serverInfo/capabilities, when reached —\n * the doctor reports the signer's advertised compat versions from here\n * instead of a second probe call. */\n serverInfo?: { name?: string; version?: string }\n capabilities?: Record<string, unknown>\n toolNames?: string[]\n}\n\nexport async function probeHostedMcpTools(\n apiKey: string,\n hostedMcpUrl: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<HostedProbeResult> {\n let response: Response\n try {\n response = await fetchWithTimeout(fetchImpl, hostedMcpUrl, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n Accept: 'application/json, text/event-stream',\n },\n body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'tools/list' }),\n })\n } catch {\n return { status: 'network_error' }\n }\n\n if (response.status === 401 || response.status === 403) return { status: 'unauthorized' }\n if (!response.ok) return { status: 'bad_response' }\n\n try {\n const payload = parseJsonRpcPayload(await response.text())\n if (!payload || payload.error) return { status: 'bad_response' }\n const tools = (payload.result as { tools?: unknown[] } | undefined)?.tools\n return { status: 'ok', toolCount: Array.isArray(tools) ? tools.length : undefined }\n } catch {\n return { status: 'bad_response' }\n }\n}\n\nexport async function probeLocalSignerCredential(signerPath: string): Promise<boolean> {\n try {\n const parsed = JSON.parse(await readFile(signerPath, 'utf8')) as unknown\n return Boolean(\n parsed &&\n typeof parsed === 'object' &&\n 'delegate_key' in parsed &&\n typeof (parsed as { delegate_key?: unknown }).delegate_key === 'string',\n )\n } catch {\n return false\n }\n}\n\nexport async function probeLocalMcpTools(\n command: string,\n args: string[],\n requiredTools: readonly string[],\n timeoutMs = 10_000,\n): Promise<LocalMcpProbeResult> {\n return new Promise((resolve) => {\n const child = spawn(command, args, { stdio: ['pipe', 'pipe', 'ignore'] })\n let stdout = ''\n let settled = false\n let sawInitialize = false\n let serverInfo: { name?: string; version?: string } | undefined\n let capabilities: Record<string, unknown> | undefined\n\n const finish = (result: LocalMcpProbeResult): void => {\n if (settled) return\n settled = true\n clearTimeout(timeout)\n child.kill()\n resolve(result)\n }\n\n const timeout = setTimeout(() => finish({ status: 'timeout' }), timeoutMs)\n\n child.on('error', () => finish({ status: 'process_error' }))\n child.on('exit', (code) => {\n if (!settled && code !== 0) finish({ status: 'process_error' })\n })\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n const lines = stdout.split(/\\r?\\n/)\n stdout = lines.pop() ?? ''\n for (const line of lines) {\n const trimmed = line.trim()\n if (!trimmed) continue\n let payload: JsonRpcEnvelope & { id?: number }\n try {\n payload = JSON.parse(trimmed) as JsonRpcEnvelope & { id?: number }\n } catch {\n continue\n }\n if (payload.error) {\n finish({ status: 'bad_response' })\n return\n }\n if (payload.id === 1 && !sawInitialize) {\n sawInitialize = true\n const init = payload.result as\n | { serverInfo?: { name?: string; version?: string }; capabilities?: Record<string, unknown> }\n | undefined\n serverInfo = init?.serverInfo\n capabilities = init?.capabilities\n writeJsonRpc(child, { jsonrpc: '2.0', method: 'notifications/initialized', params: {} })\n writeJsonRpc(child, { jsonrpc: '2.0', id: 2, method: 'tools/list', params: {} })\n continue\n }\n if (payload.id === 2) {\n const tools = (payload.result as { tools?: unknown[] } | undefined)?.tools\n const toolNames = Array.isArray(tools)\n ? tools\n .map((tool) => tool && typeof tool === 'object' && 'name' in tool ? (tool as { name?: unknown }).name : undefined)\n .filter((name): name is string => typeof name === 'string')\n : []\n const missing = requiredTools.filter((name) => !toolNames.includes(name))\n finish({ status: missing.length === 0 ? 'ok' : 'missing_tools', toolNames, serverInfo, capabilities })\n return\n }\n }\n })\n\n writeJsonRpc(child, {\n jsonrpc: '2.0',\n id: 1,\n method: 'initialize',\n params: {\n protocolVersion: '2025-06-18',\n capabilities: {},\n clientInfo: { name: 'haven-connect-probe', version: '0.0.0' },\n },\n })\n })\n}\n\ninterface JsonRpcEnvelope {\n result?: unknown\n error?: unknown\n}\n\nfunction writeJsonRpc(child: ReturnType<typeof spawn>, payload: Record<string, unknown>): void {\n child.stdin?.write(`${JSON.stringify(payload)}\\n`)\n}\n\nfunction parseJsonRpcPayload(raw: string): JsonRpcEnvelope | null {\n const trimmed = raw.trim()\n if (!trimmed) return null\n if (trimmed.startsWith('{')) {\n try {\n return JSON.parse(trimmed) as JsonRpcEnvelope\n } catch {\n return null\n }\n }\n const dataLines = trimmed\n .split(/\\r?\\n/)\n .filter((line) => line.startsWith('data:'))\n .map((line) => line.slice(5).trim())\n for (let i = dataLines.length - 1; i >= 0; i -= 1) {\n try {\n return JSON.parse(dataLines[i]) as JsonRpcEnvelope\n } catch {\n /* try previous SSE frame */\n }\n }\n return null\n}\n\nasync function fetchWithTimeout(fetchImpl: typeof fetch, url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 3000)\n try {\n return await fetchImpl(url, { ...init, signal: controller.signal })\n } finally {\n clearTimeout(timeout)\n }\n}\n","import { execFile } from 'node:child_process'\nimport { access, chmod, mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { promisify } from 'node:util'\nimport { MCP_RUNTIME_MANIFEST, sdkPackageSpec, signerPackageSpec } from './runtime-manifest.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface PrepareSignerRuntimeInput {\n credentialDirectory: string\n signerPath: string\n homeDir?: string\n /** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */\n serverName?: string\n}\n\nexport interface PreparedSignerRuntime {\n /** Absolute command to register as the signer MCP `command`. */\n command: string\n /** Args to register alongside `command` (credentials are baked into the wrapper). */\n args: string[]\n wrapperPath: string\n runtimeDirectory: string\n npmCacheDirectory: string\n cliPath: string\n messages: string[]\n}\n\nexport interface SignerRuntimeDeps {\n runCommand?: (command: string, args: string[]) => Promise<void>\n /** Heartbeats during the (possibly minutes-long) npm install (#1586). */\n onProgress?: (message: string) => void\n}\n\n/**\n * Honest budget for a COLD-cache install over a slow link (#1586). The old\n * 120s budget was exactly what broke the 2026-08-18 Codex Desktop setup: a\n * 6+ minute cold install was killed at 2 minutes, the failure fell back to\n * npx silently, and the resulting config structurally could not start.\n */\nexport const SIGNER_INSTALL_TIMEOUT_MS = 600_000\n\n/** How often the console hears from a long install instead of going silent. */\nexport const SIGNER_INSTALL_HEARTBEAT_MS = 15_000\n\n/**\n * Pre-install the edge signer into a version-pinned, connector-managed\n * directory and write a stable wrapper that launches it with an absolute Node\n * path. The signer MCP is then registered as `command: <wrapper>` instead of a\n * runtime `npx -y @haven_ai/signer@…` invocation.\n *\n * Why: launching the signer via bare `npx` at every MCP spawn made it depend on\n * the PATH/environment the agent runtime hands the stdio subprocess, which is\n * not the user's interactive shell — the failure mode that left `haven-signer`\n * stuck at \"Failed to connect\" while the hosted HTTP server connected fine. The\n * local MCP topology already avoids this with the same pre-install + wrapper\n * pattern (see prepareLocalMcpRuntime); this brings the default hosted+signer\n * topology to parity. Version stays pinned (no unpinned `npm i -g`), and the\n * wrapper lives under ~/.haven so the reset flow already cleans it up.\n */\nexport async function prepareSignerRuntime(\n input: PrepareSignerRuntimeInput,\n deps: SignerRuntimeDeps = {},\n): Promise<PreparedSignerRuntime> {\n const homeDir = input.homeDir ?? homedir()\n const runtimeDirectory = resolve(homeDir, '.haven', 'signer-runtime', MCP_RUNTIME_MANIFEST.signerVersion)\n const npmCacheDirectory = resolve(homeDir, '.haven', 'npm-cache')\n const cliPath = join(runtimeDirectory, 'node_modules', '@haven_ai', 'signer', 'dist', 'cli.js')\n const messages: string[] = []\n\n await mkdir(runtimeDirectory, { recursive: true, mode: 0o700 })\n await chmod(runtimeDirectory, 0o700).catch(() => undefined)\n await mkdir(npmCacheDirectory, { recursive: true, mode: 0o700 })\n await chmod(npmCacheDirectory, 0o700).catch(() => undefined)\n\n if (await installedRuntimeMatches(runtimeDirectory, cliPath)) {\n messages.push(`Using existing local Haven signer runtime ${signerPackageSpec()}.`)\n } else {\n await installRuntimePackages(runtimeDirectory, npmCacheDirectory, deps)\n messages.push(`Installed local Haven signer runtime ${signerPackageSpec()}.`)\n }\n\n await assertFileExists(cliPath, 'local Haven signer CLI')\n\n // .mjs so the wrapper is unambiguously ESM when the runtime exec's it via the\n // shebang — Node < 20.10 has no automatic module detection, and there is no\n // package.json with \"type\":\"module\" under ~/.haven to disambiguate otherwise.\n const wrapperPath = join(input.credentialDirectory, 'bin', 'haven-signer.mjs')\n await writeWrapper({ wrapperPath, cliPath, signerPath: input.signerPath })\n\n await writeRuntimeSidecar({\n path: join(input.credentialDirectory, 'signer-runtime.json'),\n wrapperPath,\n runtimeDirectory,\n npmCacheDirectory,\n cliPath,\n serverName: input.serverName,\n })\n\n messages.push(`Prepared stable local Haven signer wrapper: ${wrapperPath}`)\n\n return {\n command: wrapperPath,\n args: [],\n wrapperPath,\n runtimeDirectory,\n npmCacheDirectory,\n cliPath,\n messages,\n }\n}\n\nasync function installRuntimePackages(\n runtimeDirectory: string,\n npmCacheDirectory: string,\n deps: SignerRuntimeDeps,\n): Promise<void> {\n const { runCommand, onProgress } = deps\n // Fast path: install against the user's default npm cache with\n // `--prefer-offline`. `npx @haven_ai/connect` just downloaded the signer + sdk\n // tarballs (plus their closure) into that cache moments earlier, so this\n // resolves from disk instead of re-fetching over the network — the single\n // biggest avoidable cost in cold setup.\n const baseArgs = [\n 'install',\n '--prefix',\n runtimeDirectory,\n '--no-audit',\n '--no-fund',\n '--omit=dev',\n '--prefer-offline',\n signerPackageSpec(),\n sdkPackageSpec(),\n ]\n const run = async (args: string[]): Promise<void> => {\n // Heartbeat while npm works: a cold install can legitimately take\n // minutes, and a silent console reads as a hang (#1586).\n const startedAt = Date.now()\n const heartbeat = setInterval(() => {\n const seconds = Math.round((Date.now() - startedAt) / 1000)\n onProgress?.(`Still installing the local Haven signer runtime… (${seconds}s — a cold cache can take several minutes)`)\n }, SIGNER_INSTALL_HEARTBEAT_MS)\n heartbeat.unref?.()\n try {\n if (runCommand) await runCommand('npm', args)\n else await execFileAsync('npm', args, { timeout: SIGNER_INSTALL_TIMEOUT_MS, maxBuffer: 1024 * 1024 })\n } finally {\n clearInterval(heartbeat)\n }\n }\n\n try {\n await run(baseArgs)\n } catch {\n // Fallback: the default `~/.npm` can be corrupted or root-owned (a real,\n // documented failure mode — see docs/operations/mcp-runtime-compatibility.md).\n // Retry against the isolated Haven-owned cache so a broken global cache can't\n // break agent setup. This path may hit the network; that is the acceptable\n // cost of recovering from an unusable default cache.\n try {\n await run([...baseArgs, '--cache', npmCacheDirectory])\n } catch (err) {\n throw new Error(\n `Could not install local Haven signer runtime ${signerPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`,\n )\n }\n }\n}\n\nexport async function installedRuntimeMatches(runtimeDirectory: string, cliPath: string): Promise<boolean> {\n try {\n await assertFileExists(cliPath, 'local Haven signer CLI')\n const [signerPackage, sdkPackage] = await Promise.all([\n readPackageJson(join(runtimeDirectory, 'node_modules', '@haven_ai', 'signer', 'package.json')),\n readPackageJson(join(runtimeDirectory, 'node_modules', '@haven_ai', 'sdk', 'package.json')),\n ])\n return signerPackage.version === MCP_RUNTIME_MANIFEST.signerVersion &&\n sdkPackage.version === MCP_RUNTIME_MANIFEST.sdkVersion\n } catch {\n return false\n }\n}\n\nasync function readPackageJson(path: string): Promise<{ version?: string }> {\n return JSON.parse(await readFile(path, 'utf8')) as { version?: string }\n}\n\nasync function writeWrapper(input: {\n wrapperPath: string\n cliPath: string\n signerPath: string\n}): Promise<void> {\n await mkdir(dirname(input.wrapperPath), { recursive: true, mode: 0o700 })\n await chmod(dirname(input.wrapperPath), 0o700).catch(() => undefined)\n const source = [\n '#!/usr/bin/env node',\n \"import { spawn } from 'node:child_process'\",\n '',\n `const cliPath = ${JSON.stringify(input.cliPath)}`,\n `const signerPath = ${JSON.stringify(input.signerPath)}`,\n '',\n \"const child = spawn(process.execPath, [cliPath, '--credentials', signerPath, ...process.argv.slice(2)], {\",\n \" stdio: 'inherit',\",\n '})',\n '',\n \"child.on('exit', (code, signal) => {\",\n ' if (signal) process.kill(process.pid, signal)',\n ' else process.exit(code ?? 1)',\n '})',\n '',\n ].join('\\n')\n await writeFile(input.wrapperPath, source, { mode: 0o700 })\n await chmod(input.wrapperPath, 0o700).catch(() => undefined)\n}\n\n/** The sidecar `prepareSignerRuntime` writes next to the credentials (#1589). */\nexport interface SignerRuntimeSidecar {\n /** #1696: present when this credential dir belongs to a NAMED pair. */\n server_name?: string\n signer_package: string\n signer_version: string\n sdk_package: string\n sdk_version: string\n wrapper_path: string\n runtime_directory: string\n npm_cache_directory: string\n cli_path: string\n}\n\nexport async function readRuntimeSidecar(credentialDirectory: string): Promise<SignerRuntimeSidecar | null> {\n try {\n return JSON.parse(\n await readFile(join(credentialDirectory, 'signer-runtime.json'), 'utf8'),\n ) as SignerRuntimeSidecar\n } catch {\n return null\n }\n}\n\nasync function writeRuntimeSidecar(input: {\n path: string\n wrapperPath: string\n runtimeDirectory: string\n npmCacheDirectory: string\n cliPath: string\n serverName?: string\n}): Promise<void> {\n const value = {\n ...(input.serverName ? { server_name: input.serverName } : {}),\n signer_package: MCP_RUNTIME_MANIFEST.signerPackage,\n signer_version: MCP_RUNTIME_MANIFEST.signerVersion,\n sdk_package: MCP_RUNTIME_MANIFEST.sdkPackage,\n sdk_version: MCP_RUNTIME_MANIFEST.sdkVersion,\n wrapper_path: input.wrapperPath,\n runtime_directory: input.runtimeDirectory,\n npm_cache_directory: input.npmCacheDirectory,\n cli_path: input.cliPath,\n }\n await writeFile(input.path, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 })\n await chmod(input.path, 0o600).catch(() => undefined)\n}\n\nasync function assertFileExists(path: string, label: string): Promise<void> {\n try {\n await access(path)\n } catch {\n throw new Error(`Missing ${label}: ${path}`)\n }\n}\n","import { execFile } from 'node:child_process'\nimport { access, chmod, mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { promisify } from 'node:util'\nimport { isSupportedNodeVersion, unsupportedNodeVersionMessage } from '@haven_ai/sdk'\nimport { SIGNER_INSTALL_HEARTBEAT_MS, SIGNER_INSTALL_TIMEOUT_MS } from './signer-runtime.js'\nimport {\n MCP_RUNTIME_MANIFEST,\n mcpPackageSpec,\n sdkPackageSpec,\n} from './runtime-manifest.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface PrepareLocalMcpRuntimeInput {\n credentialDirectory: string\n identityPath: string\n signerPath: string\n homeDir?: string\n nodeVersion?: string\n /** #1696: wiring slug, recorded in the sidecar for per-agent inventory (#1697). */\n serverName?: string\n}\n\nexport interface PreparedLocalMcpRuntime {\n command: string\n args: string[]\n wrapperPath: string\n runtimeDirectory: string\n npmCacheDirectory: string\n cliPath: string\n messages: string[]\n}\n\nexport interface LocalMcpRuntimeDeps {\n runCommand?: (command: string, args: string[]) => Promise<void>\n /** Install progress heartbeat, mirrored from the signer runtime (#1586/#1593). */\n onProgress?: (message: string) => void\n}\n\n/**\n * Raised when the running Node is below the floor every Haven package declares.\n *\n * The `code` is load-bearing: `runtime-install.ts` maps it to the\n * `local_stdio_mcp_unsupported_node_version` probe result, and Haven's install\n * telemetry has been recording that string since the local path shipped. Kept\n * verbatim even though the guard is no longer local-MCP-only (#1161), because\n * renaming it would silently split one condition across two codes in the\n * historical data.\n */\nexport class UnsupportedNodeVersionError extends Error {\n readonly code = 'local_mcp_unsupported_node_version'\n readonly nodeVersion: string\n readonly minimumNodeVersion: string\n\n constructor(nodeVersion: string, minimumNodeVersion: string, subject = 'Haven setup') {\n super(unsupportedNodeVersionMessage({ subject, nodeVersion, minimumNodeVersion }))\n this.name = 'UnsupportedNodeVersionError'\n this.nodeVersion = nodeVersion\n this.minimumNodeVersion = minimumNodeVersion\n }\n}\n\nexport async function prepareLocalMcpRuntime(\n input: PrepareLocalMcpRuntimeInput,\n deps: LocalMcpRuntimeDeps = {},\n): Promise<PreparedLocalMcpRuntime> {\n assertSupportedNodeVersion(input.nodeVersion)\n\n const homeDir = input.homeDir ?? homedir()\n const runtimeDirectory = resolve(homeDir, '.haven', 'mcp-runtime', MCP_RUNTIME_MANIFEST.mcpVersion)\n const npmCacheDirectory = resolve(homeDir, '.haven', 'npm-cache')\n const cliPath = join(runtimeDirectory, 'node_modules', '@haven_ai', 'mcp', 'dist', 'cli.js')\n const messages: string[] = []\n\n await mkdir(runtimeDirectory, { recursive: true, mode: 0o700 })\n await chmod(runtimeDirectory, 0o700).catch(() => undefined)\n await mkdir(npmCacheDirectory, { recursive: true, mode: 0o700 })\n await chmod(npmCacheDirectory, 0o700).catch(() => undefined)\n\n if (await installedRuntimeMatches(runtimeDirectory, cliPath)) {\n messages.push(`Using existing local Haven MCP runtime ${mcpPackageSpec()}.`)\n } else {\n await installRuntimePackages(runtimeDirectory, npmCacheDirectory, deps)\n messages.push(`Installed local Haven MCP runtime ${mcpPackageSpec()}.`)\n }\n\n await assertFileExists(cliPath, 'local Haven MCP CLI')\n\n const wrapperPath = join(input.credentialDirectory, 'bin', 'haven-mcp')\n await writeWrapper({\n wrapperPath,\n cliPath,\n identityPath: input.identityPath,\n signerPath: input.signerPath,\n })\n\n await writeRuntimeSidecar({\n path: join(input.credentialDirectory, 'mcp-runtime.json'),\n wrapperPath,\n runtimeDirectory,\n npmCacheDirectory,\n cliPath,\n serverName: input.serverName,\n })\n\n messages.push(`Prepared stable local Haven MCP wrapper: ${wrapperPath}`)\n\n return {\n command: wrapperPath,\n args: [],\n wrapperPath,\n runtimeDirectory,\n npmCacheDirectory,\n cliPath,\n messages,\n }\n}\n\n/**\n * Refuse to proceed on an unsupported Node.\n *\n * Called from BOTH connect paths since #1161: `runConnect` runs it before any\n * side effect on the default (hosted MCP + local signer) topology, and\n * `prepareLocalMcpRuntime` keeps its own call for the `--local` path. It used to\n * exist only on the latter — the path almost nobody takes — so the documented\n * floor was enforced where it mattered least.\n */\nexport function assertSupportedNodeVersion(\n nodeVersion = process.versions.node,\n minimumNodeVersion = MCP_RUNTIME_MANIFEST.minimumNodeVersion,\n subject = 'Haven setup',\n): void {\n if (!isSupportedNodeVersion(nodeVersion, minimumNodeVersion)) {\n throw new UnsupportedNodeVersionError(nodeVersion, minimumNodeVersion, subject)\n }\n}\n\nasync function installRuntimePackages(\n runtimeDirectory: string,\n npmCacheDirectory: string,\n deps: LocalMcpRuntimeDeps,\n): Promise<void> {\n const { runCommand, onProgress } = deps\n // Mirrors prepareSignerRuntime's installRuntimePackages: fast path reuses the\n // default npm cache (warmed by npx) with --prefer-offline so the mcp + sdk\n // tarballs are not re-downloaded; fall back to the isolated Haven-owned cache\n // if the default cache is broken or root-owned (see docs/operations/\n // mcp-runtime-compatibility.md).\n const baseArgs = [\n 'install',\n '--prefix',\n runtimeDirectory,\n '--no-audit',\n '--no-fund',\n '--omit=dev',\n '--prefer-offline',\n mcpPackageSpec(),\n sdkPackageSpec(),\n ]\n const run = async (args: string[]): Promise<void> => {\n // Heartbeat while npm works, and the same honest budget as the signer\n // install: a cold-cache install can legitimately exceed the old 120s\n // timeout, and a silent console reads as a hang (#1586/#1593).\n const startedAt = Date.now()\n const heartbeat = setInterval(() => {\n const seconds = Math.round((Date.now() - startedAt) / 1000)\n onProgress?.(`Still installing the local Haven MCP runtime… (${seconds}s — a cold cache can take several minutes)`)\n }, SIGNER_INSTALL_HEARTBEAT_MS)\n heartbeat.unref?.()\n try {\n if (runCommand) await runCommand('npm', args)\n else await execFileAsync('npm', args, { timeout: SIGNER_INSTALL_TIMEOUT_MS, maxBuffer: 1024 * 1024 })\n } finally {\n clearInterval(heartbeat)\n }\n }\n\n try {\n await run(baseArgs)\n } catch {\n try {\n await run([...baseArgs, '--cache', npmCacheDirectory])\n } catch (err) {\n throw new Error(`Could not install local Haven MCP runtime ${mcpPackageSpec()}: ${err instanceof Error ? err.message : String(err)}`)\n }\n }\n}\n\nasync function installedRuntimeMatches(runtimeDirectory: string, cliPath: string): Promise<boolean> {\n try {\n await assertFileExists(cliPath, 'local Haven MCP CLI')\n const [mcpPackage, sdkPackage] = await Promise.all([\n readPackageJson(join(runtimeDirectory, 'node_modules', '@haven_ai', 'mcp', 'package.json')),\n readPackageJson(join(runtimeDirectory, 'node_modules', '@haven_ai', 'sdk', 'package.json')),\n ])\n return mcpPackage.version === MCP_RUNTIME_MANIFEST.mcpVersion &&\n sdkPackage.version === MCP_RUNTIME_MANIFEST.sdkVersion\n } catch {\n return false\n }\n}\n\nasync function readPackageJson(path: string): Promise<{ version?: string }> {\n return JSON.parse(await readFile(path, 'utf8')) as { version?: string }\n}\n\nasync function writeWrapper(input: {\n wrapperPath: string\n cliPath: string\n identityPath: string\n signerPath: string\n}): Promise<void> {\n await mkdir(dirname(input.wrapperPath), { recursive: true, mode: 0o700 })\n await chmod(dirname(input.wrapperPath), 0o700).catch(() => undefined)\n const source = [\n '#!/usr/bin/env node',\n \"import { spawn } from 'node:child_process'\",\n '',\n `const cliPath = ${JSON.stringify(input.cliPath)}`,\n `const identityPath = ${JSON.stringify(input.identityPath)}`,\n `const signerPath = ${JSON.stringify(input.signerPath)}`,\n '',\n \"const child = spawn(process.execPath, [cliPath, '--identity', identityPath, '--signer', signerPath, ...process.argv.slice(2)], {\",\n \" stdio: 'inherit',\",\n '})',\n '',\n \"child.on('exit', (code, signal) => {\",\n ' if (signal) process.kill(process.pid, signal)',\n ' else process.exit(code ?? 1)',\n '})',\n '',\n ].join('\\n')\n await writeFile(input.wrapperPath, source, { mode: 0o700 })\n await chmod(input.wrapperPath, 0o700).catch(() => undefined)\n}\n\nasync function writeRuntimeSidecar(input: {\n path: string\n wrapperPath: string\n runtimeDirectory: string\n npmCacheDirectory: string\n cliPath: string\n serverName?: string\n}): Promise<void> {\n const value = {\n ...(input.serverName ? { server_name: input.serverName } : {}),\n mcp_package: MCP_RUNTIME_MANIFEST.mcpPackage,\n mcp_version: MCP_RUNTIME_MANIFEST.mcpVersion,\n sdk_package: MCP_RUNTIME_MANIFEST.sdkPackage,\n sdk_version: MCP_RUNTIME_MANIFEST.sdkVersion,\n minimum_node_version: MCP_RUNTIME_MANIFEST.minimumNodeVersion,\n wrapper_path: input.wrapperPath,\n runtime_directory: input.runtimeDirectory,\n npm_cache_directory: input.npmCacheDirectory,\n cli_path: input.cliPath,\n }\n await writeFile(input.path, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600 })\n await chmod(input.path, 0o600).catch(() => undefined)\n}\n\nasync function assertFileExists(path: string, label: string): Promise<void> {\n try {\n await access(path)\n } catch {\n throw new Error(`Missing ${label}: ${path}`)\n }\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join, resolve } from 'node:path'\nimport { HAVEN_SKILL_MD, HAVEN_SKILL_BODY_MD, SKILL_FOLDER_NAME } from '@haven_ai/sdk'\nimport type { RuntimeId } from './runtime-registry.js'\n\n/**\n * Guidance-surface parity across runtimes (#1332).\n *\n * The generic payment skill is static and secret-free. Where a runtime has a\n * DOCUMENTED instruction mechanism, setup installs the canonical content\n * there; the substance is identical everywhere — only the wrapper differs:\n *\n * - claude-code — `~/.claude/skills/haven-pay/SKILL.md` (Claude's skills\n * folder; unchanged behavior, moved here from runtime-install.ts).\n * - hermes — `$HERMES_HOME/skills/haven-pay/SKILL.md` (default\n * `~/.hermes/skills/…`). Hermes auto-discovers SKILL.md skills from that\n * directory in the same front-matter format Claude uses, so the file is\n * byte-identical to the Claude install.\n * - codex-cli / codex-desktop — a marker-delimited managed section in the\n * global `~/.codex/AGENTS.md` (Codex's documented global-guidance file,\n * shared by CLI and Desktop). The section carries the skill BODY (front\n * matter is skills-registry metadata and meaningless in AGENTS.md). Writes\n * are idempotent — an existing managed section is replaced in place — and\n * everything outside the markers is preserved byte-for-byte. The file is\n * created when absent. `AGENTS.override.md` is never touched.\n * - every other runtime — no documented instruction file; the baseline is the\n * MCP server-level initialize instructions, so nothing is written.\n */\n\nexport const CODEX_AGENTS_BEGIN_MARKER =\n '<!-- BEGIN haven-pay (managed by @haven_ai/connect; edits inside this section are overwritten on re-setup) -->'\nexport const CODEX_AGENTS_END_MARKER = '<!-- END haven-pay -->'\n\nexport interface SkillInstallResult {\n installed: boolean\n target?: string\n messages: string[]\n}\n\nexport interface SkillInstallDeps {\n homeDir?: string\n env?: NodeJS.ProcessEnv\n}\n\nexport async function installSkillForRuntime(\n runtime: RuntimeId,\n deps: SkillInstallDeps = {},\n): Promise<SkillInstallResult | undefined> {\n switch (runtime) {\n case 'claude-code':\n return installSkillFile(\n resolve(deps.homeDir ?? homedir(), '.claude', 'skills', SKILL_FOLDER_NAME),\n '~/.claude/skills/haven-pay',\n )\n case 'hermes':\n return installSkillFile(\n join(hermesHome(deps), 'skills', SKILL_FOLDER_NAME),\n 'the Hermes skills folder',\n )\n case 'codex-cli':\n case 'codex-desktop':\n return installCodexAgentsSection(deps)\n default:\n // No documented instruction file for this runtime — the MCP server's\n // initialize instructions carry the baseline guidance.\n return undefined\n }\n}\n\nasync function installSkillFile(skillDir: string, label: string): Promise<SkillInstallResult> {\n try {\n await mkdir(skillDir, { recursive: true })\n const target = join(skillDir, 'SKILL.md')\n await writeFile(target, HAVEN_SKILL_MD, 'utf8')\n return {\n installed: true,\n target,\n messages: [`Installed the generic Haven payment skill (${label}). It contains no secrets.`],\n }\n } catch (err) {\n return {\n installed: false,\n messages: [\n `Could not install the Haven payment skill: ${err instanceof Error ? err.message : String(err)}. Download it from the Haven dashboard instead.`,\n ],\n }\n }\n}\n\nasync function installCodexAgentsSection(deps: SkillInstallDeps): Promise<SkillInstallResult> {\n try {\n const codexDir = resolve(deps.homeDir ?? homedir(), '.codex')\n const target = join(codexDir, 'AGENTS.md')\n await mkdir(codexDir, { recursive: true })\n const existing = await readFile(target, 'utf8').catch(() => null)\n const next = upsertManagedSection(existing, codexManagedSection())\n if (next !== existing) {\n await writeFile(target, next, 'utf8')\n }\n return {\n installed: true,\n target,\n messages: [\n 'Installed the generic Haven payment guidance as a managed section in ~/.codex/AGENTS.md (Codex reads it as global instructions). It contains no secrets; your own content in that file is untouched.',\n ],\n }\n } catch (err) {\n return {\n installed: false,\n messages: [\n `Could not install the Haven payment guidance into ~/.codex/AGENTS.md: ${err instanceof Error ? err.message : String(err)}. Download the skill from the Haven dashboard instead.`,\n ],\n }\n }\n}\n\nfunction codexManagedSection(): string {\n return `${CODEX_AGENTS_BEGIN_MARKER}\\n\\n${HAVEN_SKILL_BODY_MD.trimEnd()}\\n\\n${CODEX_AGENTS_END_MARKER}\\n`\n}\n\n/**\n * Replace the existing managed section in place, or append one. Everything\n * outside the markers is preserved byte-for-byte — this file belongs to the\n * user; Haven owns only the span between its own markers.\n */\nexport function upsertManagedSection(existing: string | null, section: string): string {\n if (existing === null || existing.trim() === '') return section\n // Line-anchored: a marker quoted mid-line (prose, a code fence example)\n // must not be mistaken for a live section boundary.\n const begins = markerLineIndexes(existing, CODEX_AGENTS_BEGIN_MARKER)\n const ends = markerLineIndexes(existing, CODEX_AGENTS_END_MARKER)\n if (begins.length === 1 && ends.length === 1 && ends[0] > begins[0]) {\n const afterEnd = ends[0] + CODEX_AGENTS_END_MARKER.length\n // Swallow the line break the section itself terminates with (LF or CRLF),\n // so re-runs replace in place instead of accreting blank lines.\n const tail = existing.startsWith('\\r\\n', afterEnd)\n ? existing.slice(afterEnd + 2)\n : existing.startsWith('\\n', afterEnd)\n ? existing.slice(afterEnd + 1)\n : existing.slice(afterEnd)\n return existing.slice(0, begins[0]) + section + tail\n }\n if (begins.length > 0 || ends.length > 0) {\n // Anything but exactly one well-ordered pair — an orphaned marker, or a\n // duplicated section — is damage. Appending or guessing a span here could\n // swallow user content between markers on this or a LATER run; fail\n // closed and leave the file alone.\n throw new Error(\n 'found a damaged Haven marker section (orphaned or duplicated markers); remove the leftover marker lines and re-run setup',\n )\n }\n // No markers: append at the end, separated by a blank line.\n return `${existing.replace(/\\n*$/, '\\n\\n')}${section}`\n}\n\n/** Indexes of `marker` occurrences that sit at the start of a line. */\nfunction markerLineIndexes(text: string, marker: string): number[] {\n const indexes: number[] = []\n for (let from = 0; ; ) {\n const at = text.indexOf(marker, from)\n if (at === -1) return indexes\n if (at === 0 || text[at - 1] === '\\n') indexes.push(at)\n from = at + marker.length\n }\n}\n\n// Must resolve the SAME home as config-writers' hermesHomePath (which reads\n// the real process.env) — the skill and the config.yaml/.env writes belong in\n// one Hermes home. `deps.env` exists for test isolation only; production\n// callers never pass it, so both resolvers read the same process.env.\nfunction hermesHome(deps: SkillInstallDeps): string {\n const env = deps.env ?? process.env\n return env.HERMES_HOME ?? join(deps.homeDir ?? homedir(), '.hermes')\n}\n","/**\n * The connector's machine-readable failure vocabulary (#1719).\n *\n * Before this, a refusal was a bare `throw new Error(...)` and the automation\n * contract recovered a code by regex-matching the message in\n * `failedConnectOutcome`. That works only for as long as nobody rewords a\n * sentence, and it gives the caller nothing to branch on that the wording did\n * not accidentally provide. Every refusal this module fronts carries:\n *\n * - `code` — stable, snake_case, safe to switch on;\n * - `nextAction` — the one thing to do next, in the same snake_case shape the\n * install-status contract already uses for `next_action`;\n * - `message` — human/agent prose, still the thing printed to a terminal.\n *\n * Codes are additive and never renamed: a consumer pinned to an older\n * connector must keep recognising the ones it already knows.\n */\nexport interface ConnectErrorDetails {\n /**\n * The `--runtime` values a retry may use, when the refusal is about runtime\n * selection (#2091). The values lived only in `message` prose, which the\n * `--json` contract discards entirely — while the backend's setup prompt\n * instructs an agent to retry only with \"one of the values that refusal\n * lists\". Carrying them structurally is what makes that retry reachable\n * from automation.\n */\n allowedRuntimes?: readonly string[]\n /**\n * What the #1719 installed-client scan found on this machine (#2174), when\n * the refusal is `runtime_undetermined`. `installedClients` is ordered\n * likeliest-first; `suggestedRuntime` appears only when one candidate is\n * unambiguously top.\n *\n * A HINT, never a decision. The scan populates choices and never selects —\n * carrying it here does not let the connector proceed on it, and the retry\n * stays the agent's explicit `--runtime <name>`.\n */\n installedClients?: readonly string[]\n suggestedRuntime?: string\n}\n\nexport class ConnectError extends Error {\n readonly code: string\n readonly nextAction: string\n readonly details: ConnectErrorDetails\n\n constructor(code: string, message: string, nextAction: string, details: ConnectErrorDetails = {}) {\n super(message)\n this.name = 'ConnectError'\n this.code = code\n this.nextAction = nextAction\n this.details = details\n }\n}\n\nexport function isConnectError(err: unknown): err is ConnectError {\n return err instanceof ConnectError\n}\n","import { ConnectError } from './connect-error.js'\n\nexport type RuntimeId =\n | 'claude-code'\n | 'codex-desktop'\n | 'codex-cli'\n | 'cursor'\n | 'vscode'\n | 'vscode-insiders'\n | 'claude-desktop'\n | 'hermes'\n | 'other'\n\nexport type RestartMode = 'restart-session' | 'restart-app' | 'hot-reload' | 'manual'\n\nexport interface RuntimeProfile {\n id: RuntimeId\n label: string\n restartMode: RestartMode\n canWriteRuntimeConfig: boolean\n /** Precise, runtime-owned instruction for loading a freshly written MCP entry. */\n activationInstruction: string\n}\n\nconst RUNTIME_PROFILES: Record<RuntimeId, RuntimeProfile> = {\n 'claude-code': {\n id: 'claude-code',\n label: 'Claude Code',\n restartMode: 'restart-session',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Start a new Claude Code session so it loads the Haven MCP entries.',\n },\n 'codex-cli': {\n id: 'codex-cli',\n label: 'Codex CLI',\n restartMode: 'restart-session',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Start a fresh Codex CLI session (for example, run `codex resume --last`).',\n },\n 'codex-desktop': {\n id: 'codex-desktop',\n label: 'Codex Desktop',\n restartMode: 'restart-session',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Quit and reopen Codex Desktop so it loads the Haven MCP entries.',\n },\n cursor: {\n id: 'cursor',\n label: 'Cursor',\n restartMode: 'hot-reload',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Wait for Cursor to hot-reload the Haven MCP entries; no app restart is required.',\n },\n vscode: {\n id: 'vscode',\n label: 'VS Code',\n restartMode: 'hot-reload',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Wait for VS Code to hot-reload the Haven MCP entries; no app restart is required.',\n },\n 'vscode-insiders': {\n id: 'vscode-insiders',\n label: 'VS Code Insiders',\n restartMode: 'hot-reload',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Wait for VS Code Insiders to hot-reload the Haven MCP entries; no app restart is required.',\n },\n 'claude-desktop': {\n id: 'claude-desktop',\n label: 'Claude Desktop',\n restartMode: 'restart-app',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Quit and reopen Claude Desktop so it loads the Haven MCP entries.',\n },\n hermes: {\n id: 'hermes',\n label: 'Hermes Agent',\n restartMode: 'restart-session',\n canWriteRuntimeConfig: true,\n activationInstruction: 'Start a new Hermes session; in Hermes Gateway, run `/restart` instead.',\n },\n other: {\n id: 'other',\n label: 'Other agent runtime',\n restartMode: 'manual',\n canWriteRuntimeConfig: false,\n activationInstruction: 'Finish the manual MCP setup shown above, then start a fresh session in that runtime.',\n },\n}\n\nconst RUNTIME_ALIASES: Record<string, RuntimeId> = {\n claude: 'claude-code',\n 'claude-code': 'claude-code',\n claudecode: 'claude-code',\n 'claude_code': 'claude-code',\n // #1682: Cowork runs Claude Code's config, so it resolves to the same\n // profile. The dashboard's command carries no --runtime for it (it is a\n // detected, command-path runtime), but an explicit `--runtime cowork` typed\n // by hand must not fall through to the no-runtime refusal.\n cowork: 'claude-code',\n codex: 'codex-cli',\n 'codex-cli': 'codex-cli',\n codexcli: 'codex-cli',\n 'codex_cli': 'codex-cli',\n 'codex-desktop': 'codex-desktop',\n 'codex_desktop': 'codex-desktop',\n codexdesktop: 'codex-desktop',\n 'codex-app': 'codex-desktop',\n 'codex_app': 'codex-desktop',\n codexapp: 'codex-desktop',\n cursor: 'cursor',\n vscode: 'vscode',\n 'vs-code': 'vscode',\n 'vs_code': 'vscode',\n code: 'vscode',\n 'vscode-insiders': 'vscode-insiders',\n 'vscode_insiders': 'vscode-insiders',\n vscodeinsiders: 'vscode-insiders',\n 'vs-code-insiders': 'vscode-insiders',\n 'code-insiders': 'vscode-insiders',\n insiders: 'vscode-insiders',\n 'claude-desktop': 'claude-desktop',\n 'claude_desktop': 'claude-desktop',\n claudesktop: 'claude-desktop',\n desktop: 'claude-desktop',\n hermes: 'hermes',\n 'hermes-agent': 'hermes',\n hermes_agent: 'hermes',\n hermesagent: 'hermes',\n // #1682: OpenClaw is a SNIPPET target — the user pastes an mcpServers entry\n // into ~/.openclaw/openclaw.json and restarts the gateway. That is exactly\n // the 'other' profile's behaviour (credentials written to disk, no config\n // auto-written, manual finish), so it resolves there rather than earning a\n // profile whose only distinguishing feature would be its label.\n openclaw: 'other',\n 'open-claw': 'other',\n 'open_claw': 'other',\n other: 'other',\n manual: 'other',\n}\n\nexport function runtimeProfile(runtime: string | undefined, env: NodeJS.ProcessEnv = process.env): RuntimeProfile {\n return RUNTIME_PROFILES[normalizeRuntime(runtime, env)]\n}\n\nexport function normalizeRuntime(runtime: string | undefined, env: NodeJS.ProcessEnv = process.env): RuntimeId {\n const explicit = normalizeRuntimeName(runtime)\n if (explicit) return explicit\n return detectRuntime(env) ?? 'other'\n}\n\n/**\n * The flag values a refusal should offer, as data (#2091): they ride on the\n * refusal's `ConnectError.details.allowedRuntimes` so the `--json` contract\n * can list them machine-readably, not only in prose an automation run never\n * sees. Mirrors RuntimeId.\n */\nexport const RUNTIME_FLAG_VALUE_LIST = [\n 'claude-code',\n 'codex-cli',\n 'codex-desktop',\n 'cursor',\n 'vscode',\n 'vscode-insiders',\n 'claude-desktop',\n 'hermes',\n 'other',\n] as const satisfies readonly RuntimeId[]\n\n/** The same values as refusal-message prose. */\nexport const RUNTIME_FLAG_VALUES = RUNTIME_FLAG_VALUE_LIST.join(', ')\n\nexport interface RuntimeSelection {\n runtime: RuntimeId | null\n source: 'force' | 'detected' | 'explicit' | 'prompted' | 'none'\n /** Set when a confident environment detection overrode a contradicting explicit hint (#1672). */\n overrodeHint?: RuntimeId\n /** Set when a supplied hint was not a runtime name at all and detection carried the run (#1719). */\n discardedHint?: string\n}\n\nexport interface RuntimeResolutionOptions {\n env?: NodeJS.ProcessEnv\n /**\n * Rung 3b (#1719): the harness an AGENT executing this command reported for\n * ITSELF, when detection found nothing to go on.\n *\n * It deliberately enters at the same precedence as `--runtime`, which is\n * what makes it safe: a hint can only ever fill a vacuum, and loses to a\n * confident detection exactly as #1672 made it. In practice the agent\n * supplies it BY re-running with `--runtime <name>`; this field exists so a\n * programmatic caller can pass a self-report without pretending to be a\n * command-line flag, and so the ladder names the rung it has.\n */\n selfReported?: string\n /**\n * Rung 4 (#1719): ask a human at an interactive terminal which of the\n * clients installed on this machine to configure. Injected as a thunk so\n * the ladder stays a policy function — the scan, the readline prompt, and\n * the \"nothing writable is installed\" refusal all live in\n * `installed-clients.ts`. Omitted (`--json`, no TTY, library callers) means\n * the rung is skipped entirely, not answered with a guess.\n */\n promptForRuntime?: () => Promise<RuntimeId>\n}\n\n/**\n * Runtime resolution, detection-first (#1672) and self-resolving (#1719).\n *\n * The setup command carries no `--runtime`; the connector works out the\n * runtime it is executing inside. Precedence:\n *\n * 1. `--runtime-force <name>` — always wins (unknown name refuses).\n * 2. Environment detection over a CONTRADICTING hint. Detection only fires\n * inside a real agent shell, where writing a different client's config is\n * almost surely wrong — the claude-desktop-hint-in-Claude-Code dead end\n * this exists to close.\n * 3. An explicit `--runtime`, or an agent's self-report, with no contradicting\n * detection (the legit plain-terminal \"configure Claude Desktop by hand\"\n * case — unchanged).\n * 4. Detection alone.\n * 5. An interactive pick among the clients actually installed here, when a\n * human is at a TTY. The scan populates the choices; it never selects.\n * 6. Nothing known → `runtime: null`; the caller refuses BEFORE side effects\n * rather than guessing a config location.\n *\n * A hint that is not a runtime name at all is not a hint — it is a mistake, and\n * the one thing it must never do is fall through to a config location nobody\n * asked for. With no detection to fall back on it refuses (`runtime_unrecognized`).\n * With a detection it loses to it, loudly, exactly like a contradicting hint:\n * the detected client is the right write either way, and refusing there would\n * turn every rollout window in which the dashboard learns an id before the\n * published connector does into a hard failure.\n */\nexport async function resolveRuntimeSelection(\n explicit: string | undefined,\n force: string | undefined,\n options: RuntimeResolutionOptions = {},\n): Promise<RuntimeSelection> {\n const env = options.env ?? process.env\n if (force !== undefined) {\n const forced = normalizeRuntimeName(force)\n if (!forced) {\n throw new ConnectError(\n 'runtime_force_unrecognized',\n `Unknown --runtime-force value \"${force}\". Valid values: ${RUNTIME_FLAG_VALUES}.`,\n 'rerun_connect_with_a_valid_runtime_name',\n { allowedRuntimes: RUNTIME_FLAG_VALUE_LIST },\n )\n }\n return { runtime: forced, source: 'force' }\n }\n const detected = detectRuntime(env)\n const supplied = explicit?.trim() || options.selfReported?.trim() || undefined\n const hint = normalizeRuntimeName(supplied)\n if (supplied && !hint) {\n if (!detected) {\n throw new ConnectError(\n 'runtime_unrecognized',\n `\"${supplied}\" is not an agent runtime Haven knows. Valid values: ${RUNTIME_FLAG_VALUES} ` +\n '(the aliases cowork, codex and openclaw are accepted too). ' +\n 'Re-run with one of those, or --runtime other to store credentials and finish the MCP setup by hand. ' +\n 'Nothing was written and the Haven setup token is still unused.',\n 'rerun_connect_with_a_valid_runtime_name',\n { allowedRuntimes: RUNTIME_FLAG_VALUE_LIST },\n )\n }\n return { runtime: detected, source: 'detected', discardedHint: supplied }\n }\n if (detected && hint && detected !== hint) {\n return { runtime: detected, source: 'detected', overrodeHint: hint }\n }\n if (hint) return { runtime: hint, source: 'explicit' }\n if (detected) return { runtime: detected, source: 'detected' }\n if (options.promptForRuntime) {\n return { runtime: await options.promptForRuntime(), source: 'prompted' }\n }\n return { runtime: null, source: 'none' }\n}\n\nexport function restartRequiredForRuntime(runtime: string | undefined, env: NodeJS.ProcessEnv = process.env): boolean {\n const mode = runtimeProfile(runtime, env).restartMode\n return mode === 'restart-session' || mode === 'restart-app'\n}\n\n/**\n * Desktop GUI runtimes really do require a restart for the user to see the new\n * MCP server — the MCP server lifecycle is tied to app launch, not to the\n * current conversation. The agent who reported the \"restart not needed\"\n * surprise was using Claude Code (a CLI session that picks up new MCP servers\n * in-session via the deferred-tool mechanism). Don't softpedal the restart\n * instruction on Claude Desktop / Codex Desktop just because Claude Code is\n * looser about it.\n */\nexport function runtimeRequiresHardRestart(runtime: RuntimeId): boolean {\n return runtime === 'claude-desktop' || runtime === 'codex-desktop'\n}\n\n/**\n * The one safe post-activation check for every supported topology. It only\n * reads the connected agent and its live budget; it never signs, funds, or\n * creates a payment.\n */\nexport function runtimeVerificationInstruction(runtime: RuntimeId): string {\n const label = RUNTIME_PROFILES[runtime].label\n return `In ${label}, run the read-only \\`haven_get_agent\\` and \\`haven_get_allowances\\` tools to confirm the Haven wallet and live budget. Do not sign, fund, or create a payment to verify setup.`\n}\n\nfunction normalizeRuntimeName(runtime: string | undefined): RuntimeId | null {\n const key = runtime?.trim().toLowerCase()\n if (!key) return null\n return RUNTIME_ALIASES[key.replace(/\\s+/g, '-')] ?? null\n}\n\nfunction detectRuntime(env: NodeJS.ProcessEnv): RuntimeId | null {\n if (env.CLAUDECODE || env.CLAUDE_CODE || env.CLAUDECODE_CWD) return 'claude-code'\n if (env.CODEX_SANDBOX || env.CODEX_HOME || env.CODEX_CWD) return 'codex-cli'\n if (env.VSCODE_CWD || env.VSCODE_IPC_HOOK_CLI || env.TERM_PROGRAM === 'vscode') return 'vscode'\n if (env.HERMES_HOME || env.HERMES_AGENT) return 'hermes'\n return null\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport {\n computeSignerConsentHash,\n createEdgeSigner,\n ensureSignerConsent,\n loadSignerCredentials,\n toolSchemas,\n type SignerConsentDecision,\n type SignerConsentInput,\n type SignerToolName,\n} from '@haven_ai/signer'\n\nexport interface LocalSignerConsentStatus {\n acknowledged: boolean\n hash?: string\n reason?: SignerConsentDecision['reason'] | 'ack_file_missing' | 'ack_file_mismatch'\n error?: string\n}\n\nexport async function acknowledgeLocalSignerConsent(\n signerPath: string,\n log?: (message: string) => void,\n): Promise<LocalSignerConsentStatus> {\n try {\n const input = await buildSignerConsentInput(signerPath)\n const decision = await ensureSignerConsent(input, {\n credentialsPath: signerPath,\n writeAck: true,\n out: log ? { write: (chunk) => writeLogChunk(log, chunk) } : undefined,\n })\n return {\n acknowledged: decision.ok,\n hash: decision.hash,\n reason: decision.reason,\n }\n } catch (err) {\n return {\n acknowledged: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\nexport async function getLocalSignerConsentStatus(signerPath: string): Promise<LocalSignerConsentStatus> {\n try {\n const input = await buildSignerConsentInput(signerPath)\n const hash = computeSignerConsentHash(input)\n const stored = await readSignerAckFile(signerAckPath(signerPath))\n if (stored === hash) {\n return { acknowledged: true, hash, reason: 'ack_file_match' }\n }\n return {\n acknowledged: false,\n hash,\n reason: stored ? 'ack_file_mismatch' : 'ack_file_missing',\n }\n } catch (err) {\n return {\n acknowledged: false,\n error: err instanceof Error ? err.message : String(err),\n }\n }\n}\n\nexport function signerAckPath(signerPath: string): string {\n return resolve(`${signerPath}.signer-ack.json`)\n}\n\nasync function buildSignerConsentInput(signerPath: string): Promise<SignerConsentInput> {\n const credentials = await loadSignerCredentials(signerPath)\n const signer = createEdgeSigner(credentials.delegateKey, {\n x402BindingSigner: credentials.x402BindingSigner,\n })\n return {\n delegateAddress: signer.delegateAddress,\n safeAddress: credentials.safeAddress,\n agentId: credentials.agentId,\n chainId: credentials.chainId,\n network: credentials.network,\n toolNames: Object.keys(toolSchemas) as SignerToolName[],\n }\n}\n\nasync function readSignerAckFile(path: string): Promise<string | null> {\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as { ack?: unknown }\n return typeof parsed.ack === 'string' ? parsed.ack : null\n } catch {\n return null\n }\n}\n\nfunction writeLogChunk(log: (message: string) => void, chunk: string): void {\n const message = String(chunk).trimEnd()\n if (message) log(message)\n}\n","import { execFile } from 'node:child_process'\nimport { connectorRerunCommand } from '@haven_ai/sdk'\nimport { promisify } from 'node:util'\nimport { writeRuntimeConfig, type RuntimeMcpMode, type RuntimeConfigWriteResult } from './config-writers.js'\nimport { serverNamesFor } from './server-names.js'\nimport {\n acknowledgeLocalMcpConsent,\n getLocalMcpConsentStatus,\n type LocalMcpConsentStatus,\n} from './local-mcp-consent.js'\nimport {\n probeHostedMcpTools,\n probeLocalMcpTools,\n probeLocalSignerCredential,\n type LocalMcpProbeResult,\n type LocalMcpProbeStatus,\n} from './probes.js'\nimport {\n prepareLocalMcpRuntime,\n type PreparedLocalMcpRuntime,\n type PrepareLocalMcpRuntimeInput,\n} from './local-mcp-runtime.js'\nimport {\n prepareSignerRuntime,\n type PreparedSignerRuntime,\n type PrepareSignerRuntimeInput,\n} from './signer-runtime.js'\nimport { MCP_RUNTIME_MANIFEST, mcpPackageSpec, signerPackageSpec } from './runtime-manifest.js'\nimport { installSkillForRuntime } from './skill-install.js'\nimport { normalizeRuntime, restartRequiredForRuntime, runtimeProfile, type RuntimeId } from './runtime-registry.js'\nimport {\n acknowledgeLocalSignerConsent,\n getLocalSignerConsentStatus,\n type LocalSignerConsentStatus,\n} from './signer-consent.js'\n\nconst execFileAsync = promisify(execFile)\n\nexport interface RuntimeInstallInput {\n runtime?: string\n hostedMcpUrl: string\n apiKey: string\n signerPath: string\n identityPath: string\n credentialDirectory: string\n environmentLabel?: string\n ackSigner?: boolean\n ackLocalTools?: boolean\n /**\n * Explicit opt-in to the local-stdio MCP topology (zero hosted dependency).\n * Default is hosted MCP + local signer for every runtime; local MCP is only\n * used when this is true and the runtime supports it.\n */\n localMcp?: boolean\n /**\n * #1695: wiring slug for a NAMED MCP pair (haven-<slug> /\n * haven-signer-<slug>). Absent = the bare pair, unchanged from today.\n */\n serverName?: string\n}\n\nexport interface RuntimeInstallResult {\n runtime: RuntimeId\n runtimeMcpMode: RuntimeMcpMode\n hostedMcpConfigured: boolean\n localSignerConfigured: boolean\n localMcpConfigured: boolean\n probeResult: string\n restartRequired: boolean\n nextUserAction: string\n errorCode?: string\n configTarget?: string\n runtimeVersion?: string\n signerAcknowledged?: boolean\n localMcpAcknowledged?: boolean\n activationCommand?: string\n skillInstalled?: boolean\n /**\n * Hosted topology only: true when the signer was pre-installed and registered\n * via its absolute wrapper, false when prep failed and it fell back to the\n * fragile runtime-`npx` launch. Undefined for local/manual topologies that\n * do not run the signer as a separate MCP. Lets callers/tests detect the\n * silent npx fallback instead of treating every write as fully healthy.\n */\n signerRuntimePrepared?: boolean\n messages: string[]\n}\n\n/**\n * The config-write snapshot handed to `onRuntimeConfigured` (#1543). The\n * booleans mirror the semantics of the FINAL report's unlock keys minus the\n * probe verdicts: \"configured\" here means the config write succeeded, the\n * required consent is acknowledged, and the signer credential exists on disk\n * (a local fs check) — not that a handshake has verified it. A later probe\n * failure refines the final report and sets its errorCode; the dashboard's\n * unlock condition accepts either state.\n */\nexport interface EarlyRuntimeConfigReport {\n runtime: RuntimeId\n runtimeMcpMode: RuntimeMcpMode\n hostedMcpConfigured: boolean\n localSignerConfigured: boolean\n localMcpConfigured: boolean\n signerAcknowledged?: boolean\n localMcpAcknowledged?: boolean\n restartRequired: boolean\n nextUserAction: string\n errorCode?: string\n}\n\nexport interface RuntimeInstallDeps {\n env?: NodeJS.ProcessEnv\n homeDir?: string\n fetch?: typeof fetch\n /**\n * Optional live progress callback. installRuntime's slowest steps (signer\n * pre-install, runtime config write, MCP handshake probes) otherwise emit\n * nothing until the caller flushes the collected `messages` after this\n * returns — leaving the console silent through the longest part of setup.\n * When provided, a few lightweight heartbeat lines are emitted as they run.\n */\n onProgress?: (message: string) => void\n /**\n * #1543: invoked once, the moment the runtime MCP config write has settled —\n * BEFORE the network probes and the skill install. The dashboard withholds\n * its budget-approval controls until an install-status report shows the\n * runtime configured, and the final report only lands after the entire\n * install; gating approval on that tail made the user wait on work approval\n * does not depend on. The snapshot carries the config-write facts (no probe\n * verdicts, no skill state); the caller's complete report remains\n * authoritative and overwrites these keys. Best-effort by contract: a\n * throwing callback is swallowed and never fails the install.\n */\n onRuntimeConfigured?: (report: EarlyRuntimeConfigReport) => Promise<void> | void\n runCommand?: (command: string, args: string[]) => Promise<void>\n prepareLocalMcpRuntime?: (input: PrepareLocalMcpRuntimeInput) => Promise<PreparedLocalMcpRuntime>\n prepareSignerRuntime?: (input: PrepareSignerRuntimeInput) => Promise<PreparedSignerRuntime>\n probeSignerTools?: (\n command: string,\n args: string[],\n requiredTools: readonly string[],\n ) => Promise<LocalMcpProbeResult>\n probeLocalMcpTools?: (\n command: string,\n args: string[],\n requiredTools: readonly string[],\n ) => Promise<LocalMcpProbeResult>\n}\n\nexport async function installRuntime(\n input: RuntimeInstallInput,\n deps: RuntimeInstallDeps = {},\n): Promise<RuntimeInstallResult> {\n const runtime = normalizeRuntime(input.runtime, deps.env)\n const profile = runtimeProfile(runtime, deps.env)\n const progress = deps.onProgress ?? (() => undefined)\n const localRuntime = input.localMcp === true && supportsLocalMcp(runtime)\n const consentMessages: string[] = []\n const localMcpConsent = localRuntime\n ? await resolveLocalMcpConsent(input, consentMessages)\n : undefined\n const signerConsent = localRuntime\n ? undefined\n : await resolveSignerConsent(input, consentMessages)\n\n if (runtime === 'other') {\n const signerCredentialReady = await probeLocalSignerCredential(input.signerPath)\n const signerReady = signerCredentialReady && signerConsent?.acknowledged\n return {\n runtime,\n runtimeMcpMode: 'manual',\n hostedMcpConfigured: false,\n localSignerConfigured: false,\n localMcpConfigured: false,\n probeResult: signerReady\n ? 'manual_runtime_setup_required_local_signer_ready'\n : 'manual_runtime_setup_required_local_signer_unavailable',\n restartRequired: true,\n nextUserAction: 'return_to_haven_for_wallet_approval_then_configure_runtime',\n errorCode: 'manual_runtime_setup_required',\n configTarget: 'manual runtime setup',\n signerAcknowledged: signerConsent?.acknowledged,\n localMcpAcknowledged: false,\n messages: [\n ...consentMessages,\n 'Custom runtime: Haven did not auto-configure it. Your credentials are on disk (chmod 600) — read them at runtime; never paste a key into the agent prompt, memory, or logs.',\n ` identity (hosted MCP Bearer): ${input.identityPath}`,\n ` signer (local signing key): ${input.signerPath}`,\n 'After wallet approval, wire the runtime to Haven by reference:',\n ` Hosted MCP + local signer: point your MCP client at ${input.hostedMcpUrl} with the api_key from identity.json, then run npx -y ${signerPackageSpec()} --credentials ${input.signerPath}`,\n ` Fully local MCP (no hosted dependency): npx -y ${mcpPackageSpec()} --identity ${input.identityPath} --signer ${input.signerPath}`,\n ],\n }\n }\n\n let localRuntimeInstall: PreparedLocalMcpRuntime | undefined\n let localRuntimeError: unknown\n if (localRuntime) {\n try {\n localRuntimeInstall = await prepareRuntimeForLocalMcp(input, deps)\n } catch (err) {\n localRuntimeError = err\n }\n }\n\n if (localRuntimeError) {\n const errorCode = localRuntimePrepareErrorCode(localRuntimeError)\n return {\n runtime,\n runtimeMcpMode: 'local_stdio',\n hostedMcpConfigured: false,\n localSignerConfigured: false,\n localMcpConfigured: false,\n probeResult: errorCode === 'local_mcp_unsupported_node_version'\n ? 'local_stdio_mcp_unsupported_node_version'\n : 'local_stdio_mcp_runtime_install_failed',\n restartRequired: true,\n nextUserAction: nextAction(runtime, profile.restartMode, errorCode),\n errorCode,\n configTarget: profile.label,\n signerAcknowledged: signerConsent?.acknowledged,\n localMcpAcknowledged: localMcpConsent?.acknowledged,\n activationCommand: undefined,\n messages: [\n ...consentMessages,\n `Could not prepare local Haven MCP runtime: ${localRuntimeError instanceof Error ? localRuntimeError.message : String(localRuntimeError)}`,\n ],\n }\n }\n\n // Hosted topology launches the local signer as its own MCP stdio server.\n // Pre-install it and register an absolute wrapper instead of a runtime\n // `npx -y` invocation, which is fragile in the agent runtime's MCP-spawn\n // environment.\n //\n // #1586: prep failure is FATAL for this setup run — loud and fail-closed,\n // never a silent npx fallback. The 2026-08-18 Codex Desktop test showed\n // why: with Codex's startup_timeout_sec = 120, an npx first-launch is a\n // multi-minute npm install killed at 2 minutes, leaving corrupted _npx\n // dirs and a config that LOOKS wired but structurally cannot connect —\n // strictly worse than a clear error. Fail-closed here means NO config is\n // written at all (not even the hosted `haven` entry): a half-wired setup\n // where quotes work but signing never can is the same looks-fine trap in\n // a different place. The recovery is a re-run once the cause (network,\n // npm cache) is addressed.\n let signerCommand: { command: string; args: string[] } | undefined\n if (!localRuntime) {\n progress('Getting the signer ready…')\n try {\n const signerRuntime = await prepareSignerForRuntime(input, deps)\n signerCommand = { command: signerRuntime.command, args: signerRuntime.args }\n consentMessages.push(...signerRuntime.messages)\n } catch (err) {\n return {\n runtime,\n runtimeMcpMode: 'hosted_plus_signer',\n hostedMcpConfigured: false,\n localSignerConfigured: false,\n localMcpConfigured: false,\n probeResult: 'signer_runtime_install_failed',\n restartRequired: false,\n nextUserAction:\n 'The local Haven signer runtime could not be installed, so no configuration was written. ' +\n `Check your network (a cold install downloads the signer package set) and re-run: ${connectorRerunCommand()}`,\n errorCode: 'signer_runtime_install_failed',\n configTarget: profile.label,\n signerAcknowledged: signerConsent?.acknowledged,\n localMcpAcknowledged: localMcpConsent?.acknowledged,\n activationCommand: undefined,\n signerRuntimePrepared: false,\n messages: [\n ...consentMessages,\n `Could not pre-install the local Haven signer: ${err instanceof Error ? err.message : String(err)}`,\n 'No runtime configuration was written (fail-closed): a config pointing at an uninstalled signer looks wired but cannot start.',\n `Re-run \\`${connectorRerunCommand()}\\` to retry the setup.`,\n ],\n }\n }\n }\n const signerRuntimePrepared = localRuntime ? undefined : signerCommand !== undefined\n\n progress('Setting up your Haven tools…')\n const configResult = localRuntime\n ? runtime === 'claude-code'\n ? await configureClaudeCode(deps, localRuntimeInstall?.command ?? '', input.serverName)\n : await writeRuntimeConfig({\n runtime,\n hostedMcpUrl: input.hostedMcpUrl,\n apiKey: input.apiKey,\n identityPath: input.identityPath,\n signerPath: input.signerPath,\n serverName: input.serverName,\n credentialDirectory: input.credentialDirectory,\n localMcpCommand: localRuntimeInstall?.command,\n signerCommand,\n homeDir: deps.homeDir,\n mode: 'local',\n })\n : await writeHostedRuntimeConfig(deps, { ...input, runtime }, signerCommand)\n\n // #1543: the config write has settled — everything the dashboard's approval\n // unlock reads is now known, so report it before the probes and skill\n // install run. The signer-credential check is a local fs stat, cheap enough\n // to make the early booleans carry the final report's semantics (minus the\n // network probe verdicts, which only refine — never gate — the unlock).\n if (deps.onRuntimeConfigured) {\n const signerCredentialOnDisk = await probeLocalSignerCredential(input.signerPath)\n const earlyLocalMcpOk = configResult.runtimeMcpMode === 'local_stdio' &&\n configResult.localMcpConfigured &&\n signerCredentialOnDisk &&\n Boolean(localMcpConsent?.acknowledged)\n const earlySignerOk = configResult.runtimeMcpMode === 'local_stdio'\n ? earlyLocalMcpOk\n : configResult.signerConfigured && signerCredentialOnDisk && Boolean(signerConsent?.acknowledged)\n try {\n await deps.onRuntimeConfigured({\n runtime,\n runtimeMcpMode: configResult.runtimeMcpMode,\n hostedMcpConfigured: configResult.hostedConfigured,\n localSignerConfigured: earlySignerOk,\n localMcpConfigured: earlyLocalMcpOk,\n signerAcknowledged: signerConsent?.acknowledged,\n localMcpAcknowledged: localMcpConsent?.acknowledged,\n restartRequired: configResult.restartRequired || restartRequiredForRuntime(runtime, deps.env),\n nextUserAction: nextAction(runtime, profile.restartMode, configResult.errorCode),\n errorCode: configResult.errorCode,\n })\n } catch {\n // Best-effort by contract: early reporting must never fail the install —\n // the caller's complete report follows either way.\n }\n }\n\n progress('Almost there — just confirming everything connects…')\n const localProbePromise = configResult.runtimeMcpMode === 'local_stdio' && localRuntimeInstall\n ? runLocalMcpProbe(localRuntimeInstall, deps)\n : Promise.resolve(undefined)\n // #1587: in the hosted topology the signer is its own MCP stdio server and\n // gets the same courtesy as the hosted server — a REAL handshake\n // (initialize → tools/list → required-tools check) against the registered\n // command, not a credential-file stat. The 2026-08-18 Codex test is why:\n // setup exited 0 on a signer that could not start, and the failure\n // surfaced mid-payment. Cheap and fast now that #1586 guarantees the\n // command is a prepared wrapper, never a cold npx launch.\n const signerProbePromise = configResult.runtimeMcpMode !== 'local_stdio' && signerCommand\n ? (deps.probeSignerTools ?? probeLocalMcpTools)(\n signerCommand.command,\n signerCommand.args,\n MCP_RUNTIME_MANIFEST.requiredSignerTools,\n )\n : Promise.resolve(undefined)\n const [hostedProbe, signerCredentialReady, localMcpProbe, signerProbe] = await Promise.all([\n configResult.hostedConfigured\n ? probeHostedMcpTools(input.apiKey, input.hostedMcpUrl, deps.fetch)\n : Promise.resolve({ status: 'bad_response' as const }),\n probeLocalSignerCredential(input.signerPath),\n localProbePromise,\n signerProbePromise,\n ])\n\n const hostedOk = configResult.hostedConfigured && hostedProbe.status === 'ok'\n const localMcpOk = configResult.runtimeMcpMode === 'local_stdio' &&\n configResult.localMcpConfigured &&\n signerCredentialReady &&\n Boolean(localMcpConsent?.acknowledged) &&\n localMcpProbe?.status === 'ok'\n const signerOk = configResult.runtimeMcpMode === 'local_stdio'\n ? localMcpOk\n : configResult.signerConfigured &&\n signerCredentialReady &&\n Boolean(signerConsent?.acknowledged) &&\n // #1587: no handshake, no green. A signer command that was registered\n // but not probed (manual topology) keeps the old semantics.\n (signerProbe === undefined || signerProbe.status === 'ok')\n const restartRequired = configResult.restartRequired || restartRequiredForRuntime(runtime, deps.env)\n const errorCode = configResult.errorCode ??\n (configResult.runtimeMcpMode === 'local_stdio'\n ? localMcpErrorCode(signerCredentialReady, localMcpConsent, localMcpProbe?.status)\n : hostedMcpErrorCode(configResult.hostedConfigured, hostedProbe.status) ??\n signerConsentErrorCode(signerCredentialReady, signerConsent) ??\n signerProbeErrorCode(signerProbe))\n const hostedProbeMessages = configResult.hostedConfigured && hostedProbe.status !== 'ok'\n ? [`Hosted Haven MCP probe failed: ${hostedProbe.status}.`]\n : configResult.hostedConfigured\n ? ['Verified hosted Haven MCP tools with a read-only handshake.']\n : []\n const signerProbeMessages = signerProbe\n ? signerProbe.status === 'ok'\n ? ['Verified local Haven signer with a stdio handshake.']\n : [\n `Local Haven signer handshake failed: ${signerProbe.status}.`,\n `Re-run \\`${connectorRerunCommand()}\\` to repair the signer setup.`,\n ]\n : []\n const localProbeMessages = localMcpProbe && localMcpProbe.status !== 'ok'\n ? [`Local Haven MCP handshake failed: ${localMcpProbe.status}.`]\n : localMcpProbe?.status === 'ok'\n ? ['Verified local Haven MCP tools with a stdio handshake.']\n : []\n\n // The generic payment skill is static and secret-free, so it is installed\n // like the other acknowledged local writes on every runtime with a\n // documented instruction mechanism (#1332): Claude's and Hermes's skills\n // folders, Codex's global AGENTS.md managed section. Runtimes without one\n // rely on the MCP server-level initialize instructions.\n const skillInstall = !configResult.errorCode\n ? await installSkillForRuntime(runtime, { homeDir: deps.homeDir, env: deps.env })\n : undefined\n\n return {\n runtime,\n runtimeMcpMode: configResult.runtimeMcpMode,\n hostedMcpConfigured: hostedOk,\n localSignerConfigured: signerOk,\n localMcpConfigured: localMcpOk,\n probeResult: buildProbeResult(configResult.runtimeMcpMode, configResult.hostedConfigured, hostedProbe.status, signerOk, localMcpOk, localMcpProbe?.status),\n restartRequired,\n nextUserAction: nextAction(runtime, profile.restartMode, errorCode),\n errorCode,\n configTarget: configResult.target,\n signerAcknowledged: signerConsent?.acknowledged,\n localMcpAcknowledged: localMcpConsent?.acknowledged,\n activationCommand: configResult.activationCommand,\n skillInstalled: skillInstall?.installed,\n signerRuntimePrepared,\n messages: [...consentMessages, ...(localRuntimeInstall?.messages ?? []), ...configResult.messages, ...hostedProbeMessages, ...signerProbeMessages, ...localProbeMessages, ...(skillInstall?.messages ?? [])],\n }\n}\n\nexport function runtimeInstallCapabilities(runtime: string | undefined, env: NodeJS.ProcessEnv = process.env): {\n canWriteRuntimeConfig: boolean\n restartRequired: boolean\n} {\n const profile = runtimeProfile(runtime, env)\n return {\n canWriteRuntimeConfig: profile.canWriteRuntimeConfig,\n restartRequired: restartRequiredForRuntime(runtime, env),\n }\n}\n\nasync function configureClaudeCode(\n deps: RuntimeInstallDeps,\n localMcpCommand: string,\n serverName?: string,\n): Promise<{\n hostedConfigured: boolean\n signerConfigured: boolean\n localMcpConfigured: boolean\n runtimeMcpMode: RuntimeMcpMode\n target: string\n changed: boolean\n restartRequired: boolean\n messages: string[]\n errorCode?: string\n activationCommand?: string\n}> {\n const runCommand = deps.runCommand ?? defaultRunCommand\n const serverJson = JSON.stringify({\n type: 'stdio',\n command: localMcpCommand,\n args: [],\n env: {},\n })\n try {\n if (!localMcpCommand) throw new Error('local MCP wrapper command is required')\n // Remove stale entries first so re-runs and hosted→local switches are\n // idempotent — `claude mcp add-json` fails when the name already exists.\n // #1569: without this, a second setup left the runtime wired to the\n // PREVIOUS agent's wrapper (the add collided, the old entry survived) —\n // the hosted sibling below always did it in this order. Deliberate\n // tradeoff: if the add fails AFTER a successful remove, the runtime ends\n // with NO haven entry instead of a stale wrong-agent one — fail-closed,\n // and the claude_code_config_failed recovery (rerun setup) works cleanly\n // from that state because this sequence is idempotent from any start.\n const names = serverNamesFor(serverName)\n await runCommand('claude', ['mcp', 'remove', names.hosted]).catch(() => undefined)\n await runCommand('claude', ['mcp', 'remove', names.signer]).catch(() => undefined)\n await runCommand('claude', ['mcp', 'add-json', names.hosted, serverJson, '--scope', 'user'])\n .catch(async () => {\n await runCommand('claude', ['mcp', 'add', names.hosted, '--scope', 'user', '--', localMcpCommand])\n })\n const verified = await runCommand('claude', ['mcp', 'get', names.hosted])\n .then(() => true)\n .catch(() => false)\n return {\n hostedConfigured: false,\n signerConfigured: true,\n localMcpConfigured: true,\n runtimeMcpMode: 'local_stdio',\n target: 'Claude Code MCP config',\n changed: true,\n restartRequired: true,\n messages: [\n 'Updated local Haven MCP entry with Claude Code.',\n ...(verified ? ['Verified Claude Code MCP entry.'] : []),\n ],\n }\n } catch (err) {\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: 'local_stdio',\n target: 'Claude Code MCP config',\n changed: false,\n restartRequired: true,\n messages: [\n `Could not update Claude Code MCP config: ${err instanceof Error ? err.message : String(err)}`,\n 'Install Claude Code or rerun the Haven setup command inside a Claude Code terminal.',\n ],\n errorCode: 'claude_code_config_failed',\n }\n }\n}\n\n/**\n * Write the HOSTED topology's runtime config, whichever runtime it is.\n *\n * Exported and extracted (#1700) because Claude Code is not written by\n * `writeRuntimeConfig` at all — its `switch` has no `claude-code` case, so that\n * runtime falls through to the `default:` branch and returns\n * `hostedConfigured: false` with a \"add it manually\" message. Claude Code's\n * config is written by shelling out to `claude mcp add-json` instead.\n *\n * That is easy to not know, and the cost of not knowing it is silent: a caller\n * that reaches for `writeRuntimeConfig` directly gets a plausible-looking\n * result object for the single most common runtime, having changed nothing.\n * Re-key hit exactly that — it reported success while leaving every wired\n * Claude Code host presenting an API key the backend had just retired. This\n * function is the one place that fork is decided, so a future caller inherits\n * the right answer instead of rediscovering the wrong one.\n */\nexport async function writeHostedRuntimeConfig(\n deps: RuntimeInstallDeps,\n input: RuntimeInstallInput,\n signerCommand?: { command: string; args: string[] },\n): Promise<RuntimeConfigWriteResult> {\n if (input.runtime === 'claude-code') {\n return configureClaudeCodeHosted(deps, input, signerCommand)\n }\n return writeRuntimeConfig({\n runtime: input.runtime as RuntimeId,\n hostedMcpUrl: input.hostedMcpUrl,\n apiKey: input.apiKey,\n identityPath: input.identityPath,\n signerPath: input.signerPath,\n serverName: input.serverName,\n credentialDirectory: input.credentialDirectory,\n signerCommand,\n homeDir: deps.homeDir,\n mode: 'hosted',\n })\n}\n\nasync function configureClaudeCodeHosted(\n deps: RuntimeInstallDeps,\n input: RuntimeInstallInput,\n signerCommand?: { command: string; args: string[] },\n): Promise<{\n hostedConfigured: boolean\n signerConfigured: boolean\n localMcpConfigured: boolean\n runtimeMcpMode: RuntimeMcpMode\n target: string\n changed: boolean\n restartRequired: boolean\n messages: string[]\n errorCode?: string\n activationCommand?: string\n}> {\n const runCommand = deps.runCommand ?? defaultRunCommand\n const hostedJson = JSON.stringify({\n type: 'http',\n url: input.hostedMcpUrl,\n headers: { Authorization: `Bearer ${input.apiKey}` },\n })\n const signerJson = JSON.stringify({\n type: 'stdio',\n command: signerCommand?.command ?? 'npx',\n args: signerCommand?.args ?? ['-y', signerPackageSpec(), '--credentials', input.signerPath],\n env: {},\n })\n try {\n // Remove stale entries first so re-runs and local→hosted switches are\n // idempotent — `claude mcp add-json` fails when the name already exists.\n // #1695: only the entries THIS pair owns, by name — a named setup can\n // never clobber the bare pair or a sibling named pair.\n const names = serverNamesFor(input.serverName)\n await runCommand('claude', ['mcp', 'remove', names.hosted]).catch(() => undefined)\n await runCommand('claude', ['mcp', 'remove', names.signer]).catch(() => undefined)\n await runCommand('claude', ['mcp', 'add-json', names.hosted, hostedJson, '--scope', 'user'])\n await runCommand('claude', ['mcp', 'add-json', names.signer, signerJson, '--scope', 'user'])\n const verified = await runCommand('claude', ['mcp', 'get', names.hosted])\n .then(() => true)\n .catch(() => false)\n return {\n hostedConfigured: true,\n signerConfigured: true,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: 'Claude Code MCP config',\n changed: true,\n restartRequired: true,\n messages: [\n 'Updated hosted Haven MCP and local signer entries with Claude Code.',\n ...(verified ? ['Verified Claude Code MCP entry.'] : []),\n ],\n }\n } catch (err) {\n return {\n hostedConfigured: false,\n signerConfigured: false,\n localMcpConfigured: false,\n runtimeMcpMode: 'hosted_plus_signer',\n target: 'Claude Code MCP config',\n changed: false,\n restartRequired: true,\n messages: [\n `Could not update Claude Code MCP config: ${err instanceof Error ? err.message : String(err)}`,\n 'Install Claude Code or rerun the Haven setup command inside a Claude Code terminal.',\n ],\n errorCode: 'claude_code_config_failed',\n }\n }\n}\n\nasync function defaultRunCommand(command: string, args: string[]): Promise<void> {\n await execFileAsync(command, args, { timeout: 10_000 })\n}\n\nfunction buildProbeResult(\n mode: RuntimeMcpMode,\n hostedConfigured: boolean,\n hostedStatus: string,\n signerReady: boolean,\n localMcpReady: boolean,\n localMcpProbeStatus?: LocalMcpProbeStatus,\n): string {\n if (mode === 'local_stdio') {\n if (localMcpReady) return 'local_stdio_mcp_ready'\n return localMcpProbeStatus ? `local_stdio_mcp_${localMcpProbeStatus}` : 'local_stdio_mcp_unavailable'\n }\n const hostedPart = hostedConfigured ? `hosted_${hostedStatus}` : 'hosted_not_configured'\n const signerPart = signerReady ? 'local_signer_ready' : 'local_signer_unavailable'\n return `${hostedPart}_${signerPart}`.slice(0, 120)\n}\n\nasync function resolveLocalMcpConsent(\n input: RuntimeInstallInput,\n messages: string[],\n): Promise<LocalMcpConsentStatus> {\n if (input.ackLocalTools || input.ackSigner) {\n const status = await acknowledgeLocalMcpConsent(input.identityPath, input.signerPath, (message) => messages.push(message))\n if (status.acknowledged) {\n messages.push('Prepared the local Haven tools acknowledgement.')\n } else {\n messages.push('Local Haven tools acknowledgement still needs attention.')\n }\n return status\n }\n return getLocalMcpConsentStatus(input.identityPath, input.signerPath)\n}\n\nasync function resolveSignerConsent(\n input: RuntimeInstallInput,\n messages: string[],\n): Promise<LocalSignerConsentStatus> {\n if (input.ackSigner || input.ackLocalTools) {\n const status = await acknowledgeLocalSignerConsent(input.signerPath, (message) => messages.push(message))\n if (status.acknowledged) {\n messages.push('Prepared the local Haven signer acknowledgement.')\n } else {\n messages.push('Local Haven signer acknowledgement still needs attention.')\n }\n return status\n }\n return getLocalSignerConsentStatus(input.signerPath)\n}\n\nfunction signerConsentErrorCode(\n signerCredentialReady: boolean,\n signerConsent: LocalSignerConsentStatus | undefined,\n): string | undefined {\n if (!signerCredentialReady) return 'local_signer_credential_unavailable'\n if (!signerConsent?.acknowledged) return 'local_signer_ack_required'\n return undefined\n}\n\nfunction signerProbeErrorCode(probe: LocalMcpProbeResult | undefined): string | undefined {\n if (!probe || probe.status === 'ok') return undefined\n return `local_signer_probe_${probe.status}`\n}\n\nfunction hostedMcpErrorCode(\n hostedConfigured: boolean,\n hostedProbeStatus: string,\n): string | undefined {\n if (!hostedConfigured || hostedProbeStatus === 'ok') return undefined\n return `hosted_mcp_probe_${hostedProbeStatus}`\n}\n\nfunction localMcpErrorCode(\n signerCredentialReady: boolean,\n localMcpConsent: LocalMcpConsentStatus | undefined,\n localMcpProbeStatus: LocalMcpProbeStatus | undefined,\n): string | undefined {\n if (!signerCredentialReady) return 'local_signer_credential_unavailable'\n if (!localMcpConsent?.acknowledged) return 'local_mcp_ack_required'\n if (localMcpProbeStatus && localMcpProbeStatus !== 'ok') return `local_mcp_probe_${localMcpProbeStatus}`\n return undefined\n}\n\nfunction nextAction(\n runtime: RuntimeId,\n restartMode: 'restart-session' | 'restart-app' | 'hot-reload' | 'manual',\n errorCode?: string,\n): string {\n if (errorCode) return 'return_to_haven_for_wallet_approval_then_finish_runtime_setup'\n if (restartMode === 'hot-reload') return 'return_to_haven_for_wallet_approval'\n if (runtime === 'codex-cli' || runtime === 'codex-desktop') return 'return_to_haven_for_wallet_approval_then_restart_codex'\n if (runtime === 'claude-code') return 'return_to_haven_for_wallet_approval_then_restart_claude_code'\n if (restartMode === 'restart-app') return 'return_to_haven_for_wallet_approval_then_restart_app'\n if (restartMode === 'restart-session') return 'return_to_haven_for_wallet_approval_then_restart_agent_session'\n return 'return_to_haven_for_wallet_approval_then_configure_runtime'\n}\n\n/**\n * Runtimes where the local-stdio MCP topology can be installed when the user\n * explicitly opts in. Never used by default — the default topology is hosted\n * MCP + local signer for every runtime.\n */\nexport function supportsLocalMcp(runtime: RuntimeId): boolean {\n return runtime === 'codex-cli' || runtime === 'codex-desktop' || runtime === 'claude-code'\n}\n\nasync function prepareRuntimeForLocalMcp(\n input: RuntimeInstallInput,\n deps: RuntimeInstallDeps,\n): Promise<PreparedLocalMcpRuntime> {\n // onProgress threaded through on purpose (#1593, the #1586 review lesson):\n // without it the install heartbeat is dead code in production.\n const prepare = deps.prepareLocalMcpRuntime ?? ((runtimeInput: PrepareLocalMcpRuntimeInput) =>\n prepareLocalMcpRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress }))\n return prepare({\n credentialDirectory: input.credentialDirectory,\n identityPath: input.identityPath,\n signerPath: input.signerPath,\n homeDir: deps.homeDir,\n serverName: input.serverName,\n })\n}\n\nasync function prepareSignerForRuntime(\n input: RuntimeInstallInput,\n deps: RuntimeInstallDeps,\n): Promise<PreparedSignerRuntime> {\n const prepare = deps.prepareSignerRuntime ?? ((runtimeInput: PrepareSignerRuntimeInput) =>\n // onProgress threaded through on purpose (#1586 review): without it the\n // install heartbeat was dead code in production and the console still\n // went silent for the whole cold install — the exact symptom the issue\n // set out to remove, at a longer timeout.\n prepareSignerRuntime(runtimeInput, { runCommand: deps.runCommand, onProgress: deps.onProgress }))\n return prepare({\n credentialDirectory: input.credentialDirectory,\n signerPath: input.signerPath,\n homeDir: deps.homeDir,\n serverName: input.serverName,\n })\n}\n\nasync function runLocalMcpProbe(\n runtimeInstall: PreparedLocalMcpRuntime,\n deps: RuntimeInstallDeps,\n): Promise<LocalMcpProbeResult> {\n const probe = deps.probeLocalMcpTools ?? probeLocalMcpTools\n try {\n return await probe(runtimeInstall.command, runtimeInstall.args, MCP_RUNTIME_MANIFEST.requiredTools)\n } catch {\n return { status: 'process_error' }\n }\n}\n\nfunction localRuntimePrepareErrorCode(err: unknown): string {\n if (err && typeof err === 'object' && 'code' in err && err.code === 'local_mcp_unsupported_node_version') {\n return 'local_mcp_unsupported_node_version'\n }\n return 'local_mcp_runtime_install_failed'\n}\n","/**\n * Refusal prose shared between the argument parser and the re-key\n * implementation (#2187).\n *\n * Both layers legitimately refuse a `--rekey-finish` with no new API key, and\n * neither is redundant:\n *\n * - `args.ts` refuses the bad INVOCATION at parse time, before anything is read\n * from disk — the #1161 fail-early ordering this package holds to elsewhere.\n * - `rekey.ts` refuses the bad CALL whoever made it. `startRekey` and\n * `finishRekey` share one `RekeyOptions`, so `newApiKey` is optional in the\n * type only because phase one does not take one; for `finishRekey` it is\n * required in practice, and this is what makes that contract honest at\n * runtime. `rekey.test.ts` calls the function directly, and a plain-JS caller\n * could pass `undefined` past any type we could write.\n *\n * What was NOT legitimate was two copies of the sentence, with nothing pinning\n * them together — edit one and they drift silently, and the copy a user\n * actually sees is the parser's.\n *\n * This module deliberately imports nothing: `args.ts` is loaded on every CLI\n * invocation while `rekey.ts` is dynamically imported only for `--rekey`, so a\n * shared home with any dependency of its own would pull the re-key graph into\n * the parse path and defeat that lazy load.\n */\nexport const REKEY_FINISH_NEEDS_API_KEY =\n '--rekey-finish needs --api-key <key> — the one the Haven agent page showed once.'\n","/**\n * Agent-directory tombstones (#1681) — for the RECREATION case, where an old\n * directory is abandoned. (#1700's --rekey deliberately writes no tombstone:\n * it rewrites credentials in place at a stable path, so no dead path exists —\n * owner decision on epic #1694, 2026-08-21.)\n *\n * A long-lived MCP host loads its wiring snapshot once, at process start.\n * When an agent is recreated and its old directory is later removed, every\n * such host keeps spawning the OLD wrapper path — and the spawn fails with a\n * FileNotFoundError the host masks as \"Connection closed\", parked and\n * re-probed every five minutes, indefinitely. The field report behind this\n * counted 5,356 occurrences of one dead UUID, and TWO different long-lived\n * processes each parked on a DIFFERENT dead UUID, because each holds the\n * snapshot from its own start time.\n *\n * A tombstone replaces the wrapper with a script that tells the truth: which\n * agent this was, when and why it was retired, and that THIS host must be\n * restarted. The park loop does not disappear — nothing local can reach into\n * a running host's memory — but every five-minute probe now logs the\n * diagnosis instead of a masked symptom, in exactly the stderr log where the\n * original investigation had to dig it out by hand.\n *\n * What a tombstone deliberately does NOT do:\n * - It never touches key material. identity.json / signer.json are left\n * exactly as found — connect never revokes and never deletes credentials\n * (#1688's standing rule). A retirement flow that wants the keys gone\n * deletes them itself, and the tombstone survives to keep the path honest.\n * - It does not try to speak MCP. A well-formed JSON-RPC error needs the\n * request id, which means reading stdin and racing client timeouts; a\n * fast, loud stderr exit lands in the host's MCP stderr log — the place\n * the #1681 forensics actually looked — on every probe, with no protocol\n * to get subtly wrong.\n */\n\nimport { chmod, mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises'\nimport { connectorRerunCommand } from '@haven_ai/sdk'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { redactSecrets } from './redact.js'\nimport { ConnectError } from './connect-error.js'\n\nexport const TOMBSTONE_FILENAME = 'TOMBSTONE.json'\n\nexport interface TombstoneInfo {\n agent_id: string\n retired_at: string\n reason: string\n replaced_by?: string\n}\n\nexport interface WriteTombstoneInput {\n /** The agent credential directory being retired. */\n directory: string\n agentId: string\n /** Why the directory was retired — rendered verbatim in the diagnosis. */\n reason: string\n /** The agent that superseded this one, when there is one. */\n replacedBy?: string\n /** Injectable for tests; defaults to now. */\n retiredAt?: string\n /** Root for the SURVIVING mirror record; defaults to ~/.haven/tombstones. */\n tombstonesDir?: string\n}\n\n/**\n * Where tombstone records survive OUTSIDE the retired agent directory.\n *\n * A tombstone written only inside the per-agent dir dies the moment that dir\n * is deleted — and the whole point of a tombstone is to keep speaking for an\n * OLD, possibly already-removed path. The mirror is keyed by agent id (the\n * durable identity; dirs may be uuid- or slug-named) so `--doctor` and humans\n * can always find WHO was retired and WHY even after `~/.haven/agents/<id>`\n * is long gone. Same redaction as the in-place record; no key material.\n * (#1681 review follow-up: the tombstone must live outside the per-agent tree\n * to survive a reset.)\n */\nexport function defaultTombstonesDir(baseDir?: string): string {\n return join(baseDir ?? join(homedir(), '.haven'), 'tombstones')\n}\n\nconst MIRROR_MODE = 0o600\n\n/**\n * Every tombstone record mirrored under the tombstones root — INCLUDING\n * retirees whose credential directory has since been deleted, which is the\n * case the in-place record cannot cover. Non-throwing: a missing or\n * unreadable record file is skipped, like every other enumeration path.\n */\nexport async function readTombstoneRecords(\n tombstonesDir?: string,\n): Promise<Array<TombstoneInfo & { recordPath: string }>> {\n const root = tombstonesDir ?? defaultTombstonesDir()\n let entries: string[] = []\n try {\n entries = await readdir(root)\n } catch {\n return []\n }\n const records: Array<TombstoneInfo & { recordPath: string }> = []\n for (const entry of entries) {\n if (!entry.endsWith('.json')) continue\n const recordPath = join(root, entry)\n try {\n const parsed = JSON.parse(await readFile(recordPath, 'utf8')) as TombstoneInfo\n if (typeof parsed?.agent_id === 'string') {\n records.push({ ...parsed, recordPath })\n }\n } catch {\n // unreadable record — skip; the in-place copy (if any) still speaks\n }\n }\n return records\n}\n\n/** The marker string hosts and humans can grep their MCP stderr logs for. */\nexport const TOMBSTONE_MARKER = 'HAVEN-TOMBSTONE'\n\nfunction tombstoneScript(info: TombstoneInfo): string {\n const lines = [\n `${TOMBSTONE_MARKER}: this Haven agent was retired.`,\n '',\n ` agent: ${info.agent_id}`,\n ` retired at: ${info.retired_at}`,\n ` reason: ${info.reason}`,\n ...(info.replaced_by ? [` replaced by: ${info.replaced_by}`] : []),\n '',\n 'This process is running with a wiring snapshot that predates the',\n 'retirement — it loaded its MCP config at startup and has kept it since.',\n 'Restart THIS host to pick up the current wiring. If several long-lived',\n 'hosts are running (a gateway, a TUI worker, an editor), restart EVERY',\n 'one of them: each holds the snapshot from its own start time, so after',\n 'a chain of recreations each can be parked on a DIFFERENT old agent.',\n '',\n `Then verify with: ${connectorRerunCommand('--doctor --runtime <runtime>')}`,\n ]\n // Fully self-contained: no imports, no reads — a tombstone that could\n // itself fail to start would recreate the exact masking it exists to end.\n return [\n '#!/usr/bin/env node',\n `// ${TOMBSTONE_MARKER} — written by @haven_ai/connect (#1681). Safe to delete`,\n '// once every long-lived MCP host on this machine has been restarted.',\n `process.stderr.write(${JSON.stringify(lines.join('\\n') + '\\n')})`,\n 'process.exit(1)',\n '',\n ].join('\\n')\n}\n\n/**\n * Replace the directory's signer wrapper with a tombstone, record the\n * retirement in TOMBSTONE.json, and MIRROR the record under the tombstones\n * root so it survives the directory's later deletion. Key files are not\n * touched. Idempotent — a re-run overwrites the tombstone with the same\n * content shape.\n *\n * Returns the tombstone info plus the MIRROR path (`recordPath`), so callers\n * can point at the record that outlives the directory.\n */\nexport async function writeAgentTombstone(\n input: WriteTombstoneInput,\n): Promise<TombstoneInfo & { recordPath: string }> {\n // The directory must already exist: a mistyped path would otherwise be\n // silently created and reported as a successful retirement. (#1681 review)\n const dirStat = await stat(input.directory).catch(() => null)\n if (!dirStat?.isDirectory()) {\n // A ConnectError rather than a bare Error (#2175): this is the refusal an\n // automating caller actually hits, and the overwhelmingly likely cause is\n // a path built from the AGENT ID when the directory is slug-named (#1696).\n // A stable code lets that caller tell \"wrong path\" apart from every other\n // reason a retirement did not happen.\n throw new ConnectError(\n 'tombstone_directory_not_found',\n `Not a directory: ${input.directory} — nothing to tombstone. ` +\n 'Agent directories are named by their wiring SLUG when the agent has one, and by the ' +\n 'agent id otherwise — so a path built from an agent id will not exist for a named agent. ' +\n 'List ~/.haven/agents (or read the directories from --doctor --json) and pass one of those.',\n 'retry_with_an_existing_agent_directory',\n )\n }\n const info: TombstoneInfo = {\n // reason / replaced_by are persisted to disk and re-emitted to the host's\n // MCP stderr log on EVERY stale probe, potentially for months — redact\n // like every other output path, at the write layer so any future caller\n // inherits it. (#1681 review, finding 1)\n agent_id: input.agentId,\n retired_at: input.retiredAt ?? new Date().toISOString(),\n reason: redactSecrets(input.reason),\n ...(input.replacedBy ? { replaced_by: redactSecrets(input.replacedBy) } : {}),\n }\n const binDir = join(input.directory, 'bin')\n await mkdir(binDir, { recursive: true })\n const wrapperPath = join(binDir, 'haven-signer.mjs')\n await writeFile(wrapperPath, tombstoneScript(info), 'utf8')\n await chmod(wrapperPath, 0o755)\n const record = JSON.stringify(info, null, 2) + '\\n'\n await writeFile(join(input.directory, TOMBSTONE_FILENAME), record, 'utf8')\n // Surviving mirror (#1681 follow-up): keyed by agent id, OUTSIDE the dir, so\n // a retirement flow that then deletes the agent directory cannot silence\n // the diagnosis. Same redaction; no key material. Collisions (same agent id\n // tombstoned twice) overwrite — latest retirement wins, in-place records\n // remain authoritative.\n const root = input.tombstonesDir ?? defaultTombstonesDir()\n await mkdir(root, { recursive: true, mode: 0o700 })\n const recordPath = join(root, `${info.agent_id}.json`)\n await writeFile(recordPath, record, { mode: MIRROR_MODE })\n return { ...info, recordPath }\n}\n\n/** The tombstone record for a directory, or null when it is not tombstoned. */\nexport async function readAgentTombstone(directory: string): Promise<TombstoneInfo | null> {\n try {\n const parsed = JSON.parse(await readFile(join(directory, TOMBSTONE_FILENAME), 'utf8')) as TombstoneInfo\n if (typeof parsed?.agent_id !== 'string') return null\n return parsed\n } catch {\n return null\n }\n}\n","/**\n * --unwire (#2169): remove ONE agent's runtime wiring and leave every other\n * agent and every unrelated line untouched.\n *\n * The connector has always been able to WRITE a pair into a runtime config\n * (merge* writers) and never able to ERASE one. Retiring an agent therefore\n * left its MCP pair — and on Hermes its dotenv API-key line — in place, and\n * the next setup produced the exact state --doctor's `identity_match` check\n * exists to name: the runtime quotes as one agent and signs as another. That\n * is the live-demo incident #2168/#2169 were split from.\n *\n * This module is the erase half, with the discipline of the writers inverted:\n *\n * - **Tombstone first.** The directory is retired BEFORE any config is\n * touched, so a long-lived host that still resolves the old wrapper gets\n * the `HAVEN-TOMBSTONE` diagnosis instead of a masked `ENOENT` park loop\n * (#1681), and the #2155 mirrored record keeps the retirement observable\n * even after the directory itself is deleted.\n * - **Named pairs remove by name** — `haven-<slug>` / `haven-signer-<slug>`\n * are unique, so the name is proof of ownership.\n * - **Unnamed pairs refuse to guess.** Every unnamed agent claims the same\n * bare `haven` / `haven-signer` names and the same `MCP_HAVEN_API_KEY`, and\n * only the wrapper path in the config (or the key value in the dotenv)\n * distinguishes who actually owns them (#1695, `agentIsWired`'s reasoning).\n * If the config launches THIS directory's wrapper (or the env holds THIS\n * agent's stored key) the entry is ours and is removed; otherwise the\n * command REFUSES rather than unwire a different, working agent.\n * - **No custody boundary moves.** This never revokes on the backend —\n * `connect reports, the user decides` (#1688) survives; revocation stays an\n * owner action on the Haven agent page. What it DOES do, unlike\n * `--tombstone`'s touch-nothing retirement, is fully tear down the TARGET\n * directory's local half: after the tombstone it removes the directory's own\n * key material (signer.json, any abandoned re-key) and strips the API key\n * from identity.json, so `--doctor` reports `retired` — not `superseded`\n * (still spend-capable) — per the doctor's mutation-proof rule that a\n * tombstone never excuses a live key. The tombstone record and its #2155\n * mirror survive the teardown.\n *\n * Scope mirrors the writers: Hermes YAML + dotenv, Codex TOML, and the JSON\n * MCP configs (Cursor, VS Code, VS Code Insiders, Claude Desktop).\n */\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport { readFile, rm, writeFile } from 'node:fs/promises'\nimport {\n UnreadableRuntimeConfigError,\n hermesEnvPath,\n removeCodexToml,\n removeHermesEnv,\n removeHermesYaml,\n removeJsonMcpConfig,\n runtimeConfigPathFor,\n} from './config-writers.js'\nimport { serverNamesFor, type ServerNames } from './server-names.js'\nimport { readRuntimeSidecar, type SignerRuntimeSidecar } from './signer-runtime.js'\nimport { TOMBSTONE_FILENAME, writeAgentTombstone } from './tombstone.js'\nimport { REKEY_PENDING_FILENAME } from './storage.js'\n\nexport interface UnwireRuntimeOutcome {\n runtime: string\n label: string\n path: string | null\n status: 'removed' | 'clean' | 'refused' | 'unreadable'\n detail?: string\n}\n\nexport interface UnwireOutcome {\n directory: string\n agentId: string\n slug: string | undefined\n tombstoned: boolean\n runtimes: UnwireRuntimeOutcome[]\n}\n\nexport interface UnwireInput {\n directory: string\n /** #1696 wiring slug; when absent, read from the directory's own sidecar. */\n slug?: string\n /** Reason recorded in the tombstone written first (#1681). */\n reason?: string\n replacedBy?: string\n /** Override for the surviving mirror root (#2155), like `--tombstone`'s own. */\n tombstonesDir?: string\n homeDir?: string\n}\n\ninterface IdentityFile {\n agent_id?: string\n api_key?: string\n hosted_mcp_url?: string\n}\n\ninterface RuntimeModel {\n runtime: string\n label: string\n kind: 'yaml' | 'toml' | 'json'\n serverRoot?: 'mcpServers' | 'servers'\n}\n\n/** One entry per supported runtime, mirroring `runtimeConfigPathFor`. */\nconst RUNTIMES: RuntimeModel[] = [\n { runtime: 'hermes', label: 'Hermes Agent config', kind: 'yaml' },\n { runtime: 'codex-cli', label: 'Codex config', kind: 'toml' },\n { runtime: 'cursor', label: 'Cursor MCP config', kind: 'json', serverRoot: 'mcpServers' },\n { runtime: 'vscode', label: 'VS Code MCP config', kind: 'json', serverRoot: 'servers' },\n { runtime: 'vscode-insiders', label: 'VS Code Insiders MCP config', kind: 'json', serverRoot: 'servers' },\n { runtime: 'claude-desktop', label: 'Claude Desktop config', kind: 'json', serverRoot: 'mcpServers' },\n]\n\nfunction identityAt(directory: string): Promise<IdentityFile | null> {\n return readFile(join(directory, 'identity.json'), 'utf8')\n .then((raw) => JSON.parse(raw) as IdentityFile)\n .catch(() => null)\n}\n\nfunction removeForModel(text: string, model: RuntimeModel, names: ServerNames, path: string): string {\n switch (model.kind) {\n case 'yaml':\n return removeHermesYaml(text, names, path)\n case 'toml':\n return removeCodexToml(text, names)\n case 'json':\n return removeJsonMcpConfig(text, model.serverRoot ?? 'mcpServers', names, path)\n }\n}\n\nfunction envLineValue(envText: string, envKey: string): string | undefined {\n const line = envText.split(/\\r?\\n/).find((candidate) => new RegExp(`^\\\\s*(?:export[ \\\\t]+)?${envKey}[ \\\\t]*=`).test(candidate))\n if (!line) return undefined\n let value = line.slice(line.indexOf('=') + 1)\n value = value.trim()\n if ((value.startsWith('\"') && value.endsWith('\"')) || (value.startsWith(\"'\") && value.endsWith(\"'\"))) {\n value = value.slice(1, -1)\n }\n return value\n}\n\nasync function readOptionalText(path: string): Promise<string | null> {\n try {\n return await readFile(path, 'utf8')\n } catch {\n return null\n }\n}\n\n/**\n * Unwire ONE agent: tombstone it first, then remove its pair from every\n * supported runtime config and (Hermes) dotenv file that exists. Refuses —\n * never guesses — when the bare pair is present but provably belongs to a\n * different agent.\n */\nexport async function unwireAgent(input: UnwireInput): Promise<UnwireOutcome> {\n const homeDir = input.homeDir ?? homedir()\n const [identity, sidecar] = await Promise.all([identityAt(input.directory), readRuntimeSidecar(input.directory)])\n const agentId = identity?.agent_id ?? 'unknown'\n const slug = input.slug ?? sidecar?.server_name\n const names = serverNamesFor(slug)\n const runtimes: UnwireRuntimeOutcome[] = []\n\n // ── Tombstone first (#1681 ordering): the long-lived host that still\n // references this wrapper must hear \"retired\", never \"ENOENT\". ─────────\n let tombstoned = false\n const tombstonePath = join(input.directory, TOMBSTONE_FILENAME)\n if ((await readOptionalText(tombstonePath)) === null) {\n await writeAgentTombstone({\n directory: input.directory,\n agentId,\n reason: input.reason ?? 'unwired via --unwire',\n replacedBy: input.replacedBy,\n tombstonesDir: input.tombstonesDir,\n })\n tombstoned = true\n }\n\n // ── Runtime configs. ──────────────────────────────────────────────────────\n for (const model of RUNTIMES) {\n const path = runtimeConfigPathFor(model.runtime, homeDir)\n if (path === null) continue\n const text = await readOptionalText(path)\n if (text === null) continue\n try {\n if (!slug) {\n // Unnamed pair: positive proof of ownership is the wrapper path.\n // Only the wrapper in the config distinguishes two unnamed agents\n // (#1695); without it we must not touch the bare names.\n const owned = sidecar?.wrapper_path != null && text.includes(sidecar.wrapper_path)\n if (!owned) {\n const pairPresent = removeForModel(text, model, names, path) !== text\n if (!pairPresent) continue\n runtimes.push({\n runtime: model.runtime,\n label: model.label,\n path,\n status: 'refused',\n detail:\n 'the bare haven / haven-signer pair in this config launches a different agent ' +\n '(no wrapper from this directory in the file); refusing to guess which one is yours',\n })\n continue\n }\n }\n const next = removeForModel(text, model, names, path)\n if (next === text) continue\n await writeFile(path, next, 'utf8')\n runtimes.push({ runtime: model.runtime, label: model.label, path, status: 'removed' })\n } catch (err) {\n if (err instanceof UnreadableRuntimeConfigError) {\n runtimes.push({ runtime: model.runtime, label: model.label, path, status: 'unreadable', detail: err.message })\n continue\n }\n throw err\n }\n }\n\n // ── Hermes dotenv key — the half a config-only removal misses (#2169). ────\n const envPath = hermesEnvPath(homeDir)\n const envText = await readOptionalText(envPath)\n if (envText !== null) {\n try {\n if (!slug) {\n // The bare key is shared by every unnamed agent; it is OURS only when\n // its value is this directory's stored key (#1695's own hazard note).\n const value = envLineValue(envText, names.hermesEnvKey)\n if (value === undefined) {\n // No managed key line at all — nothing of ours to remove here.\n } else if (!identity?.api_key) {\n runtimes.push({\n runtime: 'hermes',\n label: 'Hermes env',\n path: envPath,\n status: 'refused',\n detail: 'MCP_HAVEN_API_KEY is shared by unnamed agents and this directory has no stored API key to compare against; refusing to remove another agent\\'s credential',\n })\n } else if (value !== identity.api_key) {\n runtimes.push({\n runtime: 'hermes',\n label: 'Hermes env',\n path: envPath,\n status: 'refused',\n detail: 'MCP_HAVEN_API_KEY in the Hermes env holds a different agent\\'s key; refusing to remove another agent\\'s credential',\n })\n } else {\n const next = removeHermesEnv(envText, names.hermesEnvKey)\n if (next !== envText) {\n await writeFile(envPath, next, 'utf8')\n runtimes.push({ runtime: 'hermes', label: 'Hermes env', path: envPath, status: 'removed' })\n }\n }\n } else {\n const next = removeHermesEnv(envText, names.hermesEnvKey)\n if (next !== envText) {\n await writeFile(envPath, next, 'utf8')\n runtimes.push({ runtime: 'hermes', label: 'Hermes env', path: envPath, status: 'removed' })\n }\n }\n } catch (err) {\n if (err instanceof Error && err.message.includes('ambiguous managed key')) {\n runtimes.push({\n runtime: 'hermes',\n label: 'Hermes env',\n path: envPath,\n status: 'refused',\n detail: err.message,\n })\n } else {\n throw err\n }\n }\n }\n\n // ── Full local teardown of THIS directory's key material (#2169 AC). ─────\n // Unlike --tombstone's touch-nothing retirement, unwire tears the target's\n // local half down: its signer private key and any abandoned re-key are\n // deleted, and identity.json keeps its orientation fields but drops the API\n // key. That is what --doctor's mutation-proof rule requires before it will\n // say `retired` instead of `superseded` (tombstone never excuses a live\n // key), and #2155's mirrored record is what keeps the retirement observable\n // after the keys are gone. The backend is NOT revoked — that stays an owner\n // action on the Haven agent page.\n await Promise.all([\n rm(join(input.directory, 'signer.json'), { force: true }),\n rm(join(input.directory, REKEY_PENDING_FILENAME), { force: true }),\n ])\n if (identity && identity.api_key !== undefined) {\n const { api_key: _dropped, ...rest } = identity\n await writeFile(join(input.directory, 'identity.json'), `${JSON.stringify(rest, null, 2)}\\n`, { mode: 0o600 })\n }\n\n return { directory: input.directory, agentId, slug, tombstoned, runtimes }\n}\n","/**\n * `--rekey` — replace an agent's signing key on the machine that runs it\n * (#1700, epic #1694).\n *\n * ## Two phases, and why it cannot be one\n *\n * Re-key is authorised by the account OWNER through the dashboard: every\n * backend re-key route sits behind the dashboard session and explicitly\n * refuses an agent credential, because an agent rotating its own credentials\n * would be an agent editing its own authority (#1694). So this connector never\n * calls the re-key API at all. It brackets it:\n *\n * 1. `--rekey` generates a fresh keypair HERE and prints its public address.\n * The owner pastes that into the dashboard, which runs the five owner-signed\n * steps and hands back a new API key, shown once.\n * 2. `--rekey-finish --api-key <key>` writes both halves into the existing\n * credential files and rewrites this agent's MCP config pair.\n *\n * The issue text called the input \"a re-key setup token\". There is no such\n * token and no endpoint that would redeem one; the shipped dashboard asks for\n * a pasted address and returns a pasted key. This follows the shipped flow.\n *\n * ## The non-custodial invariant, restated because this is where it could slip\n *\n * The new private key is generated on this machine and never leaves it. Haven\n * receives an ADDRESS. Nothing here accepts, uploads or transports key\n * material, and a design that \"restores\" a key to a new host is refused rather\n * than built (#1694).\n *\n * ## Why the config must be rewritten, not just the credential files\n *\n * The MCP config embeds the API key directly — `Authorization: Bearer <key>`\n * for the JSON and TOML runtimes, `MCP_HAVEN[_SLUG]_API_KEY` for Hermes. A\n * re-key that rewrote only `identity.json` would leave every wired host\n * presenting the rotated-away key and 401ing forever, which is the failure the\n * whole epic exists to remove.\n *\n * The wiring SLUG does not move, so the server names do not move, so no host\n * needs reconfiguring beyond a restart — that is the point of rewriting in\n * place at a stable path.\n */\n\nimport { createConnectApiClient, type AgentIdentity, type ConnectApiClient } from './api.js'\nimport { connectorRerunCommand } from '@haven_ai/sdk'\nimport { writeHostedRuntimeConfig } from './runtime-install.js'\nimport { prepareSignerRuntime } from './signer-runtime.js'\nimport { generateDelegateKey } from './key.js'\nimport { redactSecrets } from './redact.js'\nimport { REKEY_FINISH_NEEDS_API_KEY } from './rekey-messages.js'\nimport { serverNamesFor } from './server-names.js'\nimport {\n REKEY_PENDING_TTL_MS,\n clearRekeyPending,\n readRekeyPending,\n readStoredCredentials,\n rewriteCredentialFiles,\n writeRekeyPending,\n type StoredCredentialSnapshot,\n} from './storage.js'\n\nexport interface RekeyOptions {\n /** Wiring slug (`--name`). Absent = the unnamed pair's directory. */\n serverName?: string\n /** Agent id, for an unnamed agent whose directory is keyed by it. */\n agentId?: string\n credentialsDir?: string\n /** Phase two only: the new API key the dashboard showed once. */\n newApiKey?: string\n /** Set for phase two when the config pair must be rewritten. */\n runtime?: string\n homeDir?: string\n}\n\nexport interface RekeyDeps {\n createApi?: (baseUrl: string) => ConnectApiClient\n generateKey?: typeof generateDelegateKey\n now?: () => number\n log?: (message: string) => void\n /** Injected so the config rewrite is testable without touching a real host config. */\n writeConfig?: typeof writeHostedRuntimeConfig\n prepareSigner?: typeof prepareSignerRuntime\n runCommand?: Parameters<typeof prepareSignerRuntime>[1] extends { runCommand?: infer R } ? R : never\n}\n\nexport interface RekeyStartResult {\n started: true\n agentId: string\n directory: string\n newDelegateAddress: string\n expiresAt: string\n messages: string[]\n}\n\nexport interface RekeyFinishResult {\n finished: true\n agentId: string\n directory: string\n newDelegateAddress: string\n serverNames: { hosted: string; signer: string }\n /** False when no --runtime was given, so the caller can say the config is stale. */\n configRewritten: boolean\n messages: string[]\n}\n\n/** Phase one: generate the key, park it, print the address to paste. */\nexport async function startRekey(\n options: RekeyOptions,\n deps: RekeyDeps = {},\n): Promise<RekeyStartResult> {\n const now = deps.now ?? (() => Date.now())\n const stored = await readStoredCredentials(\n options.serverName,\n options.agentId,\n options.credentialsDir,\n )\n\n const api = (deps.createApi ?? ((url: string) => createConnectApiClient(url)))(stored.apiUrl)\n const identity = await probeIdentity(api, stored.apiKey, 'current')\n assertRekeyable(identity, stored)\n\n // Generated HERE. The address is the only half that will ever be sent.\n const key = (deps.generateKey ?? generateDelegateKey)()\n const startedAt = new Date(now()).toISOString()\n const expiresAt = new Date(now() + REKEY_PENDING_TTL_MS).toISOString()\n\n await writeRekeyPending(stored.directory, {\n agent_id: stored.agentId,\n new_delegate_address: key.address,\n new_delegate_key: key.privateKey,\n started_at: startedAt,\n expires_at: expiresAt,\n })\n\n const finishCommand = [\n connectorRerunCommand('--rekey-finish'),\n options.serverName ? `--name ${options.serverName}` : undefined,\n '--api-key <the key the dashboard showed you>',\n options.runtime ? `--runtime ${options.runtime}` : '--runtime <your runtime>',\n ]\n .filter(Boolean)\n .join(' ')\n\n return {\n started: true,\n agentId: stored.agentId,\n directory: stored.directory,\n newDelegateAddress: key.address,\n expiresAt,\n messages: [\n `New signing key generated on this machine for agent ${identity.name || stored.agentId}.`,\n '',\n ` New signing address: ${key.address}`,\n '',\n 'The private half stays here — Haven never receives it, and there is no way to move it',\n 'between machines. That is what keeps the account non-custodial.',\n '',\n 'Next, on the Haven agent page: choose \"Replace signing key\" and paste that address.',\n 'When it finishes it shows a new API key ONCE. Come back here and run:',\n '',\n ` ${finishCommand}`,\n '',\n `Nothing has changed yet — the agent keeps working on its old key until you finish.`,\n `This pending re-key expires ${expiresAt}.`,\n ],\n }\n}\n\n/** Phase two: verify the pasted key, then rewrite credentials and config. */\nexport async function finishRekey(\n options: RekeyOptions,\n deps: RekeyDeps = {},\n): Promise<RekeyFinishResult> {\n const now = deps.now ?? (() => Date.now())\n if (!options.newApiKey) {\n throw new Error(REKEY_FINISH_NEEDS_API_KEY)\n }\n const stored = await readStoredCredentials(\n options.serverName,\n options.agentId,\n options.credentialsDir,\n )\n const pending = await readRekeyPending(stored.directory, now())\n\n if (pending.agent_id !== stored.agentId) {\n throw new Error(\n `The pending re-key at ${stored.directory} belongs to agent ${pending.agent_id}, but that ` +\n `directory now holds ${stored.agentId}. Refusing to write a key into the wrong agent.`,\n )\n }\n\n const api = (deps.createApi ?? ((url: string) => createConnectApiClient(url)))(stored.apiUrl)\n const identity = await probeIdentity(api, options.newApiKey, 'new')\n\n // The load-bearing check, and the reason this phase talks to Haven at all.\n // It proves three things at once with one read: the pasted key authenticates,\n // it belongs to THIS agent, and the backend re-key actually completed against\n // the address this machine generated. Any of those being false and writing\n // anyway produces a credential set that fails at the next payment instead of\n // here, with the old key already gone.\n if (identity.id !== stored.agentId) {\n throw new Error(\n `That API key belongs to agent ${identity.id}, not ${stored.agentId}. Nothing was changed.`,\n )\n }\n const onChain = (identity.delegate_address ?? '').toLowerCase()\n const expected = pending.new_delegate_address.toLowerCase()\n if (onChain !== expected) {\n throw new Error(\n `Haven says this agent's signing address is ${identity.delegate_address ?? 'unset'}, but this ` +\n `machine generated ${pending.new_delegate_address}. Nothing was changed. Either the ` +\n 're-key on the agent page used a different address, or it has not finished yet.',\n )\n }\n\n await rewriteCredentialFiles({\n baseDir: options.credentialsDir,\n agentId: stored.agentId,\n serverName: options.serverName,\n apiKey: options.newApiKey,\n delegateKey: pending.new_delegate_key,\n delegateAddress: pending.new_delegate_address,\n safeAddress: stored.safeAddress ?? identity.safe_address ?? undefined,\n chainId: stored.chainId ?? identity.chain_id ?? undefined,\n network: stored.network,\n agentBudget: stored.agentBudget,\n apiUrl: stored.apiUrl,\n hostedMcpUrl: stored.hostedMcpUrl,\n x402BindingSigner: stored.x402BindingSigner,\n warn: deps.log,\n })\n\n // Only now. A pending key deleted before the rewrite lands would make a\n // failed rewrite unrecoverable — the private half would be gone with the\n // credential files still naming the old one.\n await clearRekeyPending(stored.directory)\n\n const names = serverNamesFor(options.serverName)\n const messages = [\n `Agent ${identity.name || stored.agentId} is now on its new signing key.`,\n ` Signing address: ${pending.new_delegate_address}`,\n ` Credentials: ${stored.directory} (rewritten in place)`,\n ` MCP servers: ${names.hosted} / ${names.signer} (unchanged names)`,\n ]\n\n // ── The MCP config, which is NOT optional bookkeeping ────────────────────\n //\n // The API key is embedded in the config itself — `Authorization: Bearer\n // <key>` for the JSON and TOML runtimes, `MCP_HAVEN[_SLUG]_API_KEY` for\n // Hermes. Rewriting only the credential files would leave every wired host\n // presenting the key the backend just retired, 401ing on every call, with a\n // credential set on disk that looks perfectly correct.\n //\n // Only THIS agent's pair is touched: the writers key off `serverName`, so a\n // sibling agent's entries in the same config file are carried through\n // untouched (#1695).\n let configRewritten = false\n if (options.runtime) {\n const prepared = await (deps.prepareSigner ?? prepareSignerRuntime)(\n {\n credentialDirectory: stored.directory,\n signerPath: `${stored.directory}/signer.json`,\n homeDir: options.homeDir,\n },\n { runCommand: deps.runCommand },\n )\n // `writeHostedRuntimeConfig`, NOT `writeRuntimeConfig`. The latter has no\n // `claude-code` case — that runtime is configured by shelling out to\n // `claude mcp add-json` — so calling it directly returns a\n // `hostedConfigured: false` result for the single most common runtime while\n // reporting like a success. Review of this slice caught exactly that.\n const result = await (deps.writeConfig ?? writeHostedRuntimeConfig)(\n { runCommand: deps.runCommand, homeDir: options.homeDir },\n {\n runtime: options.runtime,\n hostedMcpUrl: stored.hostedMcpUrl,\n apiKey: options.newApiKey,\n identityPath: `${stored.directory}/identity.json`,\n signerPath: `${stored.directory}/signer.json`,\n credentialDirectory: stored.directory,\n serverName: options.serverName,\n },\n { command: prepared.command, args: prepared.args },\n )\n configRewritten = result.hostedConfigured\n messages.push(` Config: ${result.target}`)\n messages.push(...result.messages.map((line) => ` ${line}`))\n if (!configRewritten) {\n // The write reported failure — a runtime with no writer, or a `claude`\n // CLI that is not on PATH. Say what it costs, in the same words as the\n // no-runtime case: a credential set that is correct on disk while every\n // wired host presents the retired key reads as \"the re-key broke my\n // agent\", and the generic writer message does not say that.\n messages.push(\n '',\n 'WARNING: the MCP config was NOT updated, so it still carries the OLD API key and every',\n `wired host will fail with 401. Fix the cause above and re-run with --runtime ${options.runtime},`,\n 'or update the config by hand. The credential files on disk are already on the new key.',\n )\n }\n } else {\n // Said loudly rather than skipped quietly: without this the user has a\n // rotated credential file and a config still carrying the dead key, which\n // presents as \"the re-key broke my agent\".\n messages.push(\n '',\n 'NOTE: no --runtime was given, so the MCP config still carries the OLD API key and every',\n 'wired host will fail with 401. Re-run with --runtime <name> to rewrite it.',\n )\n }\n\n return {\n finished: true,\n agentId: stored.agentId,\n directory: stored.directory,\n newDelegateAddress: pending.new_delegate_address,\n serverNames: { hosted: names.hosted, signer: names.signer },\n configRewritten,\n messages,\n }\n}\n\nasync function probeIdentity(\n api: ConnectApiClient,\n apiKey: string,\n which: 'current' | 'new',\n): Promise<AgentIdentity> {\n try {\n return await api.getAgentIdentity(apiKey)\n } catch (err) {\n const status = (err as { status?: number } | null)?.status\n if (status === 401 || status === 403) {\n throw new Error(\n which === 'current'\n ? 'This machine\\'s Haven API key is no longer accepted. If a re-key already finished ' +\n 'elsewhere, run --rekey-finish with the key that re-key produced instead of starting a new one.'\n : 'Haven rejected that API key. Check you pasted the whole key from the agent page — ' +\n 'nothing was changed.',\n )\n }\n throw new Error(\n `Could not reach Haven to check this agent (${redactSecrets(\n err instanceof Error ? err.message : String(err),\n )}). Nothing was changed.`,\n )\n }\n}\n\n/**\n * Refuse what the backend would refuse, before the owner starts anything.\n *\n * The legacy AllowanceModule rail is import-only and its authority is per-token\n * allowances rather than a signed delegation, so there is no delegation to\n * revoke and re-issue — the backend answers a 409 naming re-onboarding as the\n * path (#1694). Finding that out here costs one read; finding it out from the\n * dashboard costs the owner a wallet prompt first.\n */\nfunction assertRekeyable(identity: AgentIdentity, stored: StoredCredentialSnapshot): void {\n if (identity.id !== stored.agentId) {\n throw new Error(\n `The credentials at ${stored.directory} say agent ${stored.agentId}, but Haven says that key ` +\n `belongs to ${identity.id}. Refusing to re-key an agent this directory does not own.`,\n )\n }\n if (identity.execution_rail === 'legacy') {\n throw new Error(\n `Agent ${identity.name || identity.id} is on the legacy rail, which cannot be re-keyed — its ` +\n 'authority is per-token Safe allowances, not a signed delegation there is anything to ' +\n 're-issue. Re-onboard the agent on the delegation rail instead.',\n )\n }\n if (identity.status === 'revoked') {\n throw new Error(\n `Agent ${identity.name || identity.id} is revoked. Re-keying would hand a revoked agent fresh ` +\n 'credentials — create a new agent instead.',\n )\n }\n}\n","/**\n * Restart guidance after a re-key (#1700).\n *\n * ## Why this is not `activationInstruction`\n *\n * The runtime registry already carries an activation line per runtime, and it\n * is right for what it does — a first-time setup, where the user is sitting in\n * front of the one thing they just configured. A re-key is a different\n * situation: the agent was ALREADY running, in however many places it was\n * wired, and every one of those processes is holding the old API key in memory.\n *\n * #1681 finding B is the reason this exists at all: different long-lived\n * processes park on different stale wiring, so restarting the one in front of\n * you is not enough and \"restart your session\" is not an instruction, it is a\n * shrug. #1694's review then asked for the specific fix — print the COMMAND.\n * \"Restart Hermes\" cost the reporter time that `systemctl --user restart\n * hermes-gateway` would not have.\n *\n * ## What these commands are, and are not\n *\n * They are the common case, named concretely so the ninety-percent user can\n * copy one. They are NOT a claim to know this machine's process supervision —\n * a gateway under launchd, docker, pm2 or a bare `nohup` is none of these. So\n * every runtime's guidance ends with the sweep instruction rather than\n * implying the listed command is exhaustive, and the sweep is the part that is\n * always true.\n */\n\nexport interface RestartGuidance {\n /** Copy-pasteable commands, most likely first. Possibly empty. */\n commands: string[]\n /** Rendered lines, commands included, for the human-readable path. */\n lines: string[]\n}\n\nconst SWEEP =\n 'Then restart EVERY other long-lived MCP host on this machine — gateways, TUI workers, ' +\n 'editors. Each holds the wiring snapshot from its own start time, so after a re-key each ' +\n 'one is still presenting the OLD API key and will fail with 401 until it restarts.'\n\nconst BY_RUNTIME: Record<string, { commands: string[]; how: string }> = {\n 'claude-code': {\n commands: ['claude --continue'],\n how: 'Exit this Claude Code session and start a new one:',\n },\n 'codex-cli': {\n commands: ['codex resume --last'],\n how: 'Start a fresh Codex CLI session:',\n },\n 'codex-desktop': {\n commands: [],\n how: 'Quit Codex Desktop completely (not just the window) and reopen it.',\n },\n 'claude-desktop': {\n commands: [],\n how: 'Quit Claude Desktop completely (not just the window) and reopen it.',\n },\n hermes: {\n commands: ['systemctl --user restart hermes-gateway', '/restart'],\n how:\n 'Restart the Hermes gateway, or run /restart inside a Hermes session. The first form is ' +\n 'the one that matters if you run it as a user service:',\n },\n cursor: {\n commands: [],\n how:\n 'Cursor hot-reloads MCP config, so it will pick the new key up on its own. If a tool call ' +\n 'still fails with 401, reload the window (Cmd/Ctrl+Shift+P → \"Reload Window\").',\n },\n vscode: {\n commands: [],\n how:\n 'VS Code hot-reloads MCP config. If a tool call still fails with 401, reload the window ' +\n '(Cmd/Ctrl+Shift+P → \"Reload Window\").',\n },\n 'vscode-insiders': {\n commands: [],\n how:\n 'VS Code Insiders hot-reloads MCP config. If a tool call still fails with 401, reload the ' +\n 'window (Cmd/Ctrl+Shift+P → \"Reload Window\").',\n },\n}\n\nexport function restartGuidance(runtime?: string): RestartGuidance {\n const profile = runtime ? BY_RUNTIME[runtime] : undefined\n const lines: string[] = ['The new key is only live in a process that started after now.', '']\n\n if (profile) {\n lines.push(profile.how)\n for (const command of profile.commands) lines.push(` ${command}`)\n if (profile.commands.length > 0) lines.push('')\n } else {\n // No --runtime, or one with no known command. Say so rather than printing\n // a command for the wrong host — a confidently wrong restart command is\n // worse than none, because it looks like it worked.\n lines.push(\n runtime\n ? `No standard restart command is known for \"${runtime}\" — restart it the way you start it.`\n : 'Pass --runtime <name> to get the restart command for a specific host.',\n )\n lines.push('')\n }\n\n lines.push(SWEEP)\n return { commands: profile?.commands ?? [], lines }\n}\n","/**\n * `--doctor` / `--repair` (#1589, epic #1585) — end-to-end setup diagnosis\n * without hand-building an MCP stdio client, which is what the 2026-08-18\n * external Codex Desktop tester was reduced to.\n *\n * Doctor is READ-ONLY (its one spawn is the same read-only tools/list\n * handshake setup itself uses) and secret-free: checks report names, paths,\n * versions and verdicts — never the api key or any key material. Repair\n * re-runs the pieces setup already owns — reinstall the pinned signer\n * runtime, rewrite wrapper + sidecar, re-write the runtime config from the\n * STORED identity — and never touches credentials or needs a new setup token.\n *\n * Design notes carried in from #1587's review:\n * - the signer probe reports the initialize payload, so compat versions come\n * from the SAME handshake (no second probe);\n * - a probe against an un-acknowledged consent gate exits 1 — the doctor\n * reports that as \"consent missing\" with the ack re-run as the repair,\n * never as \"signer broken\".\n *\n * #1911 extends \"secret-free\" to the newest file that holds key material: the\n * doctor reports THAT a `--rekey` is parked (#1700's `rekey-pending.json`),\n * when, where and at which public address — through an accessor that does not\n * return the private half at all, so no output path can leak it by omission.\n * Repair still never deletes it: an expired TTL is a refusal to use the key,\n * not a licence to destroy key material the owner may still be mid-flow on.\n */\n\nimport { readFile, readdir, stat } from 'node:fs/promises'\nimport { connectorRerunCommand } from '@haven_ai/sdk'\nimport { homedir } from 'node:os'\nimport { basename, dirname, join } from 'node:path'\nimport { MCP_RUNTIME_MANIFEST } from './runtime-manifest.js'\nimport {\n probeHostedAgentIdentity,\n probeHostedMcpTools,\n probeLocalMcpTools,\n type LocalMcpProbeResult,\n} from './probes.js'\nimport {\n installedRuntimeMatches,\n prepareSignerRuntime,\n readRuntimeSidecar,\n type SignerRuntimeSidecar,\n} from './signer-runtime.js'\nimport { runtimeConfigPathFor, writeRuntimeConfig } from './config-writers.js'\nimport { restartRequiredForRuntime, type RuntimeId } from './runtime-registry.js'\nimport { getLocalSignerConsentStatus } from './signer-consent.js'\nimport { TOMBSTONE_FILENAME, readAgentTombstone, readTombstoneRecords } from './tombstone.js'\nimport { serverNamesFor, type ServerNames } from './server-names.js'\nimport { REKEY_PENDING_FILENAME, inspectRekeyPending, type RekeyPendingStatus } from './storage.js'\nimport { shortAddress } from './redact.js'\n\nexport interface DoctorCheck {\n id: string\n label: string\n ok: boolean\n /** Human detail — never secret material. */\n detail: string\n /** One concrete action, present exactly when the check fails. */\n repair?: string\n}\n\nexport interface DoctorReport {\n version: 1\n ok: boolean\n runtime: string\n credentialDirectory?: string\n checks: DoctorCheck[]\n /** #1697: one entry per credential directory found on this machine. */\n agents: AgentInventoryEntry[]\n /** Signer compat surface from the live handshake, when it succeeded. */\n signerCapabilities?: Record<string, unknown>\n}\n\nexport interface DoctorDeps {\n homeDir?: string\n fetch?: typeof fetch\n probeSignerTools?: typeof probeLocalMcpTools\n probeHosted?: typeof probeHostedMcpTools\n probeHostedIdentity?: typeof probeHostedAgentIdentity\n runCommand?: (command: string, args: string[]) => Promise<void>\n env?: NodeJS.ProcessEnv\n /** Injected clock — the pending-re-key TTL is the only time-dependent check (#1911). */\n now?: () => number\n}\n\ninterface IdentityFile {\n api_key?: string\n agent_id?: string\n api_url?: string\n hosted_mcp_url?: string\n}\n\n// #2423: the channel comes from the SDK's build-time `HAVEN_CONNECTOR_CHANNEL`,\n// so a `@dev` snapshot tells its tester to re-run `@dev` instead of quietly\n// pointing them back at the production connector.\nconst RERUN = connectorRerunCommand()\n\n/**\n * Newest agent directory that holds an identity.json, plus every OTHER such\n * directory (#1688). The others used to be a cosmetic note (\"N dirs found;\n * examining the newest\") — which downgraded the exact fact that matters: a\n * re-run mints a fresh agent and retires nothing, so a directory this doctor\n * did NOT select can hold a key that still authenticates and still spends.\n * The superseded_agents check now owns that fact; the note is gone.\n *\n * ## Three tells, not two (#1915)\n *\n * A directory is an agent credential directory if it holds ANY of\n * `identity.json`, `TOMBSTONE.json` or `rekey-pending.json`. The third was\n * added because #1911 shipped a diagnostic for abandoned re-key key material\n * and this was the one directory shape that diagnostic could not look at: no\n * enumeration, no `agents[]` entry, no `inspectRekeyPending` call, and so a\n * live private key at mode 0600 invisible in both the human output and\n * `--json`.\n *\n * The shipped `--rekey` flow cannot produce that shape — `writeRekeyPending`\n * writes into an EXISTING agent's directory, `startRekey` reads stored\n * credentials first, and tombstoning does not delete the pending file — so it\n * takes an out-of-band deletion of `identity.json` while the pending file\n * survives. Narrow. It is guarded anyway because of what is in the file: this\n * is the only tell whose *presence* is itself the hazard being reported, so a\n * blind spot here is a hole in the tool's stated job rather than a missing\n * nice-to-have. Cost is one `stat`, reached only when the two prior tells\n * both miss.\n *\n * `parkedOnly` records WHY such a directory was enumerated, so the classifier\n * can say `parked` from evidence instead of inferring it from an absent\n * identity — a corrupt `identity.json` must keep reading `orphaned`.\n */\nasync function discoverCredentialDirectory(\n homeDir: string,\n explicit?: string,\n): Promise<{ directory?: string; others: string[]; parkedOnly: Set<string> }> {\n // An explicit --credentials-dir names the agent DIRECTORY itself, so its\n // siblings live in its parent — never in the default root. Scanning the\n // default root under an explicit override would live-probe real keys in a\n // location the caller explicitly pointed away from (#1688 review, B2).\n const root = explicit ? dirname(explicit) : join(homeDir, '.haven', 'agents')\n let entries: string[] = []\n try {\n entries = await readdir(root)\n } catch {\n return explicit\n ? { directory: explicit, others: [], parkedOnly: new Set() }\n : { others: [], parkedOnly: new Set() }\n }\n const candidates: Array<{ directory: string; mtimeMs: number }> = []\n // #1681: a directory whose keys were removed but that carries TOMBSTONE.json\n // is a deliberately retired agent — reportable in the superseded scan, but\n // never selectable as the active credential directory.\n const tombstonedOnly: string[] = []\n // #1915: neither identity nor tombstone, but parked re-key key material.\n // Like `tombstonedOnly` this is a REPORTABLE, never SELECTABLE directory —\n // it holds no credentials to describe, so promoting it to the primary would\n // make the flat check list describe an agent that is not there.\n const parkedOnly: string[] = []\n for (const entry of entries) {\n const directory = join(root, entry)\n try {\n const s = await stat(join(directory, 'identity.json'))\n candidates.push({ directory, mtimeMs: s.mtimeMs })\n } catch {\n try {\n await stat(join(directory, TOMBSTONE_FILENAME))\n tombstonedOnly.push(directory)\n } catch {\n try {\n await stat(join(directory, REKEY_PENDING_FILENAME))\n parkedOnly.push(directory)\n } catch {\n // not an agent credential dir\n }\n }\n }\n }\n const parkedOnlySet = new Set(parkedOnly)\n candidates.sort((a, b) => b.mtimeMs - a.mtimeMs)\n if (explicit) {\n return {\n directory: explicit,\n others: [...candidates.map((c) => c.directory), ...tombstonedOnly, ...parkedOnly]\n .filter((d) => d !== explicit),\n parkedOnly: parkedOnlySet,\n }\n }\n if (candidates.length === 0 && tombstonedOnly.length === 0 && parkedOnly.length === 0) {\n return { others: [], parkedOnly: parkedOnlySet }\n }\n return {\n directory: candidates[0]?.directory,\n others: [...candidates.slice(1).map((c) => c.directory), ...tombstonedOnly, ...parkedOnly],\n parkedOnly: parkedOnlySet,\n }\n}\n\n/**\n * #1697: one entry per credential directory on this machine.\n *\n * \"Newest wins\" was a single-agent heuristic: it named one directory the real\n * one and demoted the rest to a note. Multi-agent (#1696) makes several\n * agents legitimately live at once, so the doctor enumerates instead of\n * choosing, and says which of four things each directory IS.\n */\n/**\n * What a credential directory IS:\n *\n * - `wired` — has a usable key and the runtime config actually launches it;\n * - `superseded` — has a usable key the runtime is NOT using (still spends);\n * - `retired` — carries a `TOMBSTONE.json`, a deliberate retirement record;\n * - `orphaned` — has an `identity.json` that yields no usable API key;\n * - `parked` (#1915) — holds `rekey-pending.json` and neither of the other\n * two tells. Not a broken agent: there is no agent here at all, only the\n * private key a `--rekey` generated and nobody finished with. It is its own\n * value rather than folded into `orphaned` because the two carry different\n * instructions — `orphaned` says \"this credential set is unusable, re-run\n * setup\", while `parked` says \"this is loose key material; take the agent\n * id to the Haven agent page, then decide whether to delete\". Reporting the\n * second as the first would print a verdict a reader cannot act on, which\n * is how a report teaches people to skim.\n */\nexport type AgentClassification = 'wired' | 'superseded' | 'retired' | 'orphaned' | 'parked'\n\nexport interface AgentInventoryEntry {\n /** Wiring slug (#1696); absent for the bare haven / haven-signer pair. */\n slug?: string\n agentId?: string\n directory: string\n classification: AgentClassification\n /**\n * Per-agent checks. Empty for entries that are not wired, with one\n * exception: a directory holding a pending re-key carries that check\n * whatever its classification (#1911) — an abandoned re-key in a superseded\n * or retired directory is precisely the case nothing else looks at.\n */\n checks: DoctorCheck[]\n /**\n * #1911: a started-but-unfinished `--rekey` in this directory, when there is\n * one. Populated for EVERY classification — the whole point is that the file\n * holds live key material in a directory nothing else is looking at. Address\n * and timing only; the private half is not in this shape (see\n * `RekeyPendingStatus`).\n *\n * \"Every classification\" became literally true in #1915. As shipped, it\n * meant every classification the ENUMERATION could reach, and a directory\n * holding only `rekey-pending.json` matched no discovery tell at all — so\n * the one shape whose sole content is the hazard was the one shape this\n * field could never describe. Such a directory is now enumerated and\n * classified `parked`.\n *\n * \"Populated\", not \"gates the exit code\": `report.ok` rolls up the flat\n * `checks` array plus WIRED entries' checks only, so this field and a\n * non-wired entry's `checks` are reporting surfaces, not gates. An abandoned\n * parked key outside the primary directory reaches the exit code through the\n * flat `rekey_pending_elsewhere` check instead — see its comment in\n * `runDoctor` for why that check exists rather than a cascade rule change.\n */\n rekeyPending?: RekeyPendingStatus\n}\n\n/**\n * Is this agent's MCP pair actually present in the runtime's config?\n *\n * The answer depends on whether the pair is NAMED, because only a named pair\n * has a name of its own:\n * - NAMED (#1696): its entry name is unique, so the name in the config text\n * settles it.\n * - UNNAMED: every unnamed agent claims the same bare `haven` /\n * `haven-signer` names, so the name proves nothing — exactly one of them\n * can be wired, and the tell is which signer wrapper path the config\n * actually references.\n * - No readable config at all (Claude Code is CLI-managed, or the file is\n * missing): this module cannot tell. Guessing \"orphaned\" would accuse every\n * agent on the most common runtime, so it falls back to the pre-#1697\n * heuristic — the selected directory is wired, the rest are not — which is\n * the honest degradation rather than a fabricated verdict.\n */\nfunction agentIsWired(\n configText: string | null,\n names: ServerNames,\n slug: string | undefined,\n identity: IdentityFile | undefined,\n sidecar: SignerRuntimeSidecar | null,\n isPrimary: boolean,\n bareOwnerExists: boolean,\n): boolean {\n if (configText === null) return isPrimary\n if (slug) {\n // Match the NAME with a boundary so `haven-ops` cannot match\n // `haven-ops-2` and `haven` cannot match `haven-ops`.\n for (const name of [names.hosted, names.codexHosted, names.signer, names.codexSigner]) {\n if (new RegExp(`(^|[.\"'\\\\s\\\\[])${name}([\"'\\\\]:\\\\s]|$)`, 'm').test(configText)) return true\n }\n return false\n }\n if (sidecar?.wrapper_path && configText.includes(sidecar.wrapper_path)) return true\n // #1697 review, finding 2: a sidecar whose wrapper is NOT referenced is not\n // proof of the opposite. A config still on the retired npx launch form\n // (which the runtime_config check flags separately) names no wrapper at\n // all, and condemning that directory as superseded would tell the user to\n // revoke their only working agent. Fall through to the same ownership\n // reasoning the sidecar-less case uses.\n // No proof of ownership of the bare\n // pair. If some OTHER directory's wrapper is the one the config launches,\n // the bare pair is already owned and this one is not wired — even when it\n // is the newest. Only when nothing owns the bare pair does the pre-#1697\n // heuristic apply.\n if (bareOwnerExists) return false\n return isPrimary && Boolean(identity?.hosted_mcp_url && configText.includes(identity.hosted_mcp_url))\n}\n\n/**\n * #1911 — the one state `doctor` could not see: a `--rekey` that was started\n * and never finished.\n *\n * `rekey-pending.json` holds a freshly generated PRIVATE key between the two\n * re-key phases (#1700). It is 0600, in the same directory, at the same mode,\n * as the live signer key it is about to replace — so it is not a new exposure.\n * What it is, is invisible: the surface whose entire job is \"tell me what\n * state this machine's Haven wiring is in\" did not read the file, so an\n * abandoned re-key left key material on disk with nothing naming it, and a\n * lost terminal left the owner with no way to re-read the address they were\n * supposed to paste except by running `--rekey` again and discarding the\n * parked keypair.\n *\n * This check reports THAT one exists, when it started, when it expires, its\n * PUBLIC address and its path. Never its contents — the accessor it reads does\n * not return them.\n *\n * ## What this can and cannot tell you about #1868\n *\n * #1868 establishes that a re-key abandoned AFTER the on-chain revoke wedges\n * the agent: the old delegations are gone, no new ones were issued, nothing\n * expires the in-flight row, and the only way back is a manual owner re-grant.\n * A re-key abandoned BEFORE the revoke costs nothing at all. Those two are\n * worth very different words, so this check says only what it can actually\n * establish:\n *\n * - **Can distinguish: the backend re-key COMPLETED.** `agents.delegate_address`\n * is swapped at the `complete` stage, so a hosted identity already reporting\n * the address this machine generated proves the whole owner-signed sequence\n * ran. Nothing is wedged; only the local half is outstanding, and\n * `--rekey-finish` closes it.\n * - **Cannot distinguish: before the revoke vs. after it,** within the\n * not-completed case. `rekey-pending.json` is written before the owner opens\n * the dashboard and is never touched again, so it records nothing about how\n * far the backend got; and the identity probe this connector makes reads two\n * fields (`id`, `delegate_address`) from `GET /machine-payments/agent`, whose\n * response is `id`, `name`, `status`, `safe_address`, `delegate_address`,\n * `delegate_account_address`, `chain_id` and `execution_rail` — **none of\n * which is a re-key stage**. The absent field is what matters here, not the\n * count: there is nothing on this endpoint to read the stage from, so\n * widening the probe would not help. So \"never started on the agent page\" and \"started, revoked,\n * abandoned — the #1868 wedge\" are the same observation from here. The check\n * says so, and points at the agent page, rather than implying the reassuring\n * half.\n */\nfunction rekeyPendingCheck(\n status: RekeyPendingStatus,\n hostedDelegateAddress: string | undefined,\n runtime: string,\n slug: string | undefined,\n): DoctorCheck {\n const label = 'Pending re-key'\n const nameFlag = slug ? ` --name ${slug}` : ''\n if (status.state === 'unreadable') {\n return {\n id: 'rekey_pending',\n label,\n ok: false,\n detail:\n `A re-key was started here but ${status.path} does not parse, so neither the address it ` +\n 'generated nor when it started can be read. The file still holds what was a private key.',\n repair: `Delete ${status.path}, then start again: ${RERUN} --rekey${nameFlag}`,\n }\n }\n\n const started = status.startedAt ?? 'an unknown time'\n const address = status.newDelegateAddress ?? 'unknown'\n const completedOnHaven =\n hostedDelegateAddress !== undefined &&\n status.newDelegateAddress !== undefined &&\n hostedDelegateAddress.toLowerCase() === status.newDelegateAddress.toLowerCase()\n\n if (completedOnHaven) {\n // The one branch with a definite backend answer. Haven already signs as\n // the new address, so this machine is the only thing left behind — and\n // `identity_match` is failing for exactly this reason, which this check\n // explains rather than repeats.\n return {\n id: 'rekey_pending',\n label,\n ok: false,\n detail:\n `A re-key started ${started} has COMPLETED on Haven — the agent's signing address is already ` +\n `${address}, the one this machine generated — but the local half was never finished, so the ` +\n `credential files here still hold the old key. Parked at ${status.path}.` +\n (status.state === 'expired'\n ? ' The local file is also past its 24h TTL, which --rekey-finish refuses, so the finish ' +\n 'command below will not accept it any more.'\n : ''),\n repair:\n status.state === 'expired'\n ? `The parked key expired. Start again — ${RERUN} --rekey${nameFlag} — and re-run \"Replace ` +\n 'signing key\" on the Haven agent page with the new address it prints.'\n : `Run: ${RERUN} --rekey-finish${nameFlag} --api-key <the key the agent page showed you> --runtime ${runtime}`,\n }\n }\n\n // Not completed. What is UNKNOWN from here is how far the agent page got —\n // and the two possibilities are free and expensive respectively (#1868).\n const wedgeNote =\n 'Haven is NOT yet on this address, so the re-key did not complete. This machine cannot tell ' +\n 'whether the on-chain revoke on the agent page already ran: if it did not, closing this costs ' +\n \"nothing; if it did, the agent's old delegations are revoked, no new ones were issued, and only \" +\n 'an owner re-grant restores its spend authority (#1868). Check the agent page before assuming ' +\n 'the harmless case.'\n\n if (status.state === 'expired') {\n return {\n id: 'rekey_pending',\n label,\n ok: false,\n detail:\n `A re-key started ${started} EXPIRED ${status.expiresAt ?? ''} without being finished. Its ` +\n `address was ${address}; the private half it generated is still on disk at ${status.path}. ` +\n wedgeNote,\n repair:\n `Either delete ${status.path} to drop the parked key, or start over: ${RERUN} --rekey${nameFlag}. ` +\n 'Connect never deletes it for you — an expired TTL is a refusal to USE the key, not a licence ' +\n 'to destroy key material you may still be mid-flow on.',\n }\n }\n\n return {\n id: 'rekey_pending',\n label,\n ok: true,\n detail:\n `A re-key started ${started} is still open (expires ${status.expiresAt ?? 'unknown'}). Paste this ` +\n `address into \"Replace signing key\" on the Haven agent page: ${address}. Parked at ${status.path}. ` +\n wedgeNote,\n }\n}\n\nasync function readIdentity(directory: string): Promise<IdentityFile | undefined> {\n try {\n return JSON.parse(await readFile(join(directory, 'identity.json'), 'utf8')) as IdentityFile\n } catch {\n return undefined\n }\n}\n\n/** Every per-agent check for ONE credential directory. */\nasync function checksForAgent(\n entry: { directory: string; identity?: IdentityFile; sidecar: SignerRuntimeSidecar | null },\n input: { runtime: string },\n deps: DoctorDeps,\n): Promise<{ checks: DoctorCheck[]; signerCapabilities?: Record<string, unknown> }> {\n const { directory, identity, sidecar } = entry\n const checks: DoctorCheck[] = []\n let signerCapabilities: Record<string, unknown> | undefined\n\n // ── Credentials ───────────────────────────────────────────────────────────\n let signerFile: Record<string, unknown> | undefined\n try {\n const parsed = JSON.parse(await readFile(join(directory, 'signer.json'), 'utf8')) as Record<string, unknown>\n signerFile = typeof parsed === 'object' && parsed !== null ? parsed : undefined\n } catch {\n signerFile = undefined\n }\n const credentialsOk = Boolean(identity?.api_key) && signerFile !== undefined\n checks.push({\n id: 'credentials',\n label: 'Agent credentials',\n ok: credentialsOk,\n detail: credentialsOk\n ? `identity.json and signer.json parse (agent ${identity?.agent_id ?? 'unknown'})`\n : 'identity.json or signer.json is missing or unparseable.',\n ...(credentialsOk ? {} : { repair: `Re-run the full setup with a fresh token: ${RERUN} --setup <token>.` }),\n })\n\n // ── Signer runtime install ────────────────────────────────────────────────\n if (!sidecar) {\n checks.push({\n id: 'signer_runtime',\n label: 'Signer runtime (preinstalled wrapper)',\n ok: false,\n detail: 'No signer-runtime.json sidecar — the pinned signer runtime was never prepared (or a pre-#1586 npx config).',\n repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}`,\n })\n } else {\n const matches = await installedRuntimeMatches(sidecar.runtime_directory, sidecar.cli_path)\n const versionOk = sidecar.signer_version === MCP_RUNTIME_MANIFEST.signerVersion\n const ok = matches && versionOk\n checks.push({\n id: 'signer_runtime',\n label: 'Signer runtime (preinstalled wrapper)',\n ok,\n detail: ok\n ? `Installed ${sidecar.signer_package}@${sidecar.signer_version} at ${sidecar.runtime_directory}`\n : matches\n ? `Installed version ${sidecar.signer_version} does not match the connector's pinned ${MCP_RUNTIME_MANIFEST.signerVersion}.`\n : `Runtime directory is stale or empty (${sidecar.runtime_directory}) — the CLI or package versions are missing.`,\n ...(ok ? {} : { repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}` }),\n })\n }\n\n // ── Hosted MCP ────────────────────────────────────────────────────────────\n const hostedUrl = identity?.hosted_mcp_url ?? (identity?.api_url ? `${identity.api_url}/mcp` : undefined)\n if (identity?.api_key && hostedUrl) {\n const probe = await (deps.probeHosted ?? probeHostedMcpTools)(identity.api_key, hostedUrl, deps.fetch)\n checks.push({\n id: 'hosted_mcp',\n label: 'Hosted Haven MCP',\n ok: probe.status === 'ok',\n detail: probe.status === 'ok'\n ? `Reachable and authorized (${hostedUrl}).`\n : `Probe failed: ${probe.status} (${hostedUrl}).`,\n ...(probe.status === 'ok'\n ? {}\n : {\n repair: probe.status === 'unauthorized'\n ? `The stored API key was rejected — re-run the full setup with a fresh token: ${RERUN} --setup <token>.`\n : 'Check network access to the hosted MCP URL, then re-run --doctor.',\n }),\n })\n } else {\n checks.push({\n id: 'hosted_mcp',\n label: 'Hosted Haven MCP',\n ok: false,\n detail: 'No stored API key / hosted MCP URL to probe with.',\n repair: `Re-run the full setup: ${RERUN} --setup <token>.`,\n })\n }\n\n // ── Hosted-vs-local identity (#1697) ──────────────────────────────────────\n // The #1681 incident, made mechanical: the API key and the signing key must\n // belong to the SAME agent. A mismatch means the runtime would quote as one\n // agent and sign as another — the exact shape #1690 refuses at signing time.\n // This proves the on-disk pair is self-consistent, which is the half a local\n // tool can know; it still cannot see inside an already-running host.\n const localDelegate = typeof signerFile?.delegate_address === 'string'\n ? (signerFile.delegate_address as string)\n : undefined\n // Hoisted for the pending-re-key check below: a hosted delegate that already\n // equals the parked address is the one thing that proves a backend re-key\n // completed (#1911). `undefined` when the probe did not succeed, which keeps\n // \"could not ask\" out of the \"definitely not completed\" branch.\n let hostedDelegateAddress: string | undefined\n if (identity?.api_key && identity.api_url) {\n const probe = await (deps.probeHostedIdentity ?? probeHostedAgentIdentity)(\n identity.api_key, identity.api_url, deps.fetch,\n )\n if (probe.status === 'ok') hostedDelegateAddress = probe.delegateAddress\n if (probe.status !== 'ok') {\n // #1697 review, finding 1: an unperformable comparison is NOT a pass.\n // Saying \"skipped, not passed\" in the text while setting ok:true is the\n // same green-check-proving-nothing defect this check exists to remove —\n // and worse here, because a real key mismatch that coincides with a\n // network blip would sail through. `hosted_mcp` already fails on\n // network_error; identity_match matches it rather than contradicting it.\n checks.push({\n id: 'identity_match',\n label: 'Hosted identity matches the local signing key',\n ok: false,\n detail: probe.status === 'unauthorized'\n ? 'The stored API key was rejected, so the agent it authenticates as cannot be compared with the local signing key.'\n : `Could not read the hosted identity (${probe.status}) — the comparison did not happen, so it cannot be reported as a match.`,\n repair: probe.status === 'unauthorized'\n ? `Re-run the full setup with a fresh token: ${RERUN} --setup <token>.`\n : `Restore network access to the Haven API, then re-run: ${RERUN} --doctor --runtime ${input.runtime}`,\n })\n } else if (!localDelegate) {\n checks.push({\n id: 'identity_match',\n label: 'Hosted identity matches the local signing key',\n ok: false,\n detail: 'signer.json holds no delegate_address to compare against the hosted identity.',\n repair: `Re-run the full setup with a fresh token: ${RERUN} --setup <token>.`,\n })\n } else {\n const same = probe.delegateAddress?.toLowerCase() === localDelegate.toLowerCase()\n checks.push({\n id: 'identity_match',\n label: 'Hosted identity matches the local signing key',\n ok: same,\n detail: same\n ? `The stored API key authenticates as the agent whose signing key is in this directory (${shortAddress(localDelegate)}).`\n : `MISMATCH: the stored API key authenticates as agent ${probe.agentId ?? 'unknown'} with delegate ` +\n `${shortAddress(probe.delegateAddress ?? 'unknown')}, but signer.json here holds ${shortAddress(localDelegate)}. ` +\n 'This runtime would quote as one agent and sign as another.',\n ...(same\n ? {}\n : {\n repair: 'Re-run setup for this agent so its API key and signing key come from one run: ' +\n `${RERUN} --setup <token>. Do not hand-edit either file.`,\n }),\n })\n }\n }\n\n // ── Pending re-key (#1911) ────────────────────────────────────────────────\n const pending = await inspectRekeyPending(directory, deps.now?.() ?? Date.now())\n if (pending) {\n checks.push(rekeyPendingCheck(pending, hostedDelegateAddress, input.runtime, sidecar?.server_name))\n }\n\n // ── Signer stdio handshake ────────────────────────────────────────────────\n if (sidecar) {\n const consent = await getLocalSignerConsentStatus(join(directory, 'signer.json'))\n if (!consent.acknowledged) {\n checks.push({\n id: 'signer_process',\n label: 'Signer stdio handshake',\n ok: false,\n detail: 'The local-tools consent is not acknowledged, so the signer refuses to start (by design).',\n repair: `Run: ${RERUN} --ack-local-tools --setup <token> (or re-run your original setup command with --ack-local-tools).`,\n })\n } else {\n const probe: LocalMcpProbeResult = await (deps.probeSignerTools ?? probeLocalMcpTools)(\n sidecar.wrapper_path,\n [],\n MCP_RUNTIME_MANIFEST.requiredSignerTools,\n )\n const experimental = (probe.capabilities?.experimental ?? probe.capabilities) as\n | Record<string, unknown>\n | undefined\n const compat = experimental?.['haven/signer-compatibility'] as Record<string, unknown> | undefined\n signerCapabilities = compat ? { 'haven/signer-compatibility': compat } : undefined\n const compatDetail = compat\n ? ` Compat: x402 expected-context v${JSON.stringify((compat as { x402_expected_context_versions?: unknown }).x402_expected_context_versions ?? '?')}.`\n : ''\n checks.push({\n id: 'signer_process',\n label: 'Signer stdio handshake',\n ok: probe.status === 'ok',\n detail: probe.status === 'ok'\n ? `Signer started, listed ${probe.toolNames?.length ?? 0} tools${probe.serverInfo?.version ? ` (v${probe.serverInfo.version})` : ''}.${compatDetail}`\n : `Handshake failed: ${probe.status}.`,\n ...(probe.status === 'ok' ? {} : { repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}` }),\n })\n }\n } else {\n checks.push({\n id: 'signer_process',\n label: 'Signer stdio handshake',\n ok: false,\n detail: 'Skipped — no prepared signer runtime to probe.',\n repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}`,\n })\n }\n\n return { checks, ...(signerCapabilities ? { signerCapabilities } : {}) }\n}\n\nexport async function runDoctor(\n input: { runtime: string; credentialsDir?: string },\n deps: DoctorDeps = {},\n): Promise<DoctorReport> {\n const homeDir = deps.homeDir ?? homedir()\n const checks: DoctorCheck[] = []\n let signerCapabilities: Record<string, unknown> | undefined\n\n const { directory, others, parkedOnly } = await discoverCredentialDirectory(homeDir, input.credentialsDir)\n\n // ── Runtime config (read once; every agent's wiring is judged against it) ─\n const configPath = runtimeConfigPathFor(input.runtime, homeDir)\n let configText: string | null = null\n if (configPath !== null) {\n try {\n configText = await readFile(configPath, 'utf8')\n } catch {\n configText = null\n }\n }\n\n // ── Inventory ─────────────────────────────────────────────────────────────\n const allDirectories = directory ? [directory, ...others] : others\n // Which directory (if any) owns the BARE haven / haven-signer pair? The\n // config launches exactly one signer wrapper for it, and that path is the\n // only unambiguous tell — the bare NAMES are claimed by every unnamed\n // agent, so they identify nobody.\n let bareOwnerExists = false\n for (const dir of allDirectories) {\n const sidecar = await readRuntimeSidecar(dir)\n if (!sidecar?.server_name && sidecar?.wrapper_path && configText?.includes(sidecar.wrapper_path)) {\n bareOwnerExists = true\n break\n }\n }\n const inventory: AgentInventoryEntry[] = []\n const capabilitiesByDirectory = new Map<string, Record<string, unknown> | undefined>()\n const primaryChecksById = new Map<string, DoctorCheck>()\n for (const dir of allDirectories) {\n const identity = await readIdentity(dir)\n const sidecar = await readRuntimeSidecar(dir)\n const tombstone = await readAgentTombstone(dir)\n const slug = sidecar?.server_name\n const names = serverNamesFor(slug)\n // #1911: read on EVERY directory, before the not-wired early return. A\n // retired or orphaned directory is exactly where an abandoned re-key would\n // go unnoticed, and the file holds key material regardless of whether the\n // agent it belongs to is still wired.\n const rekeyPending = await inspectRekeyPending(dir, deps.now?.() ?? Date.now())\n if (!identity?.api_key) {\n // #1915: fall back to the agent id recorded IN the parked file. Without\n // it a `parked` directory renders as `unknown: parked` — and the agent\n // id is the one thing the owner has to carry to the Haven agent page\n // before deciding whether the key is safe to delete.\n const agentId = tombstone?.agent_id ?? rekeyPending?.agentId\n inventory.push({\n ...(slug ? { slug } : {}),\n ...(agentId ? { agentId } : {}),\n directory: dir,\n // A tombstone is a deliberate record and outranks the discovery tell:\n // a retired directory that also holds a parked key stays `retired`.\n classification: tombstone ? 'retired' : parkedOnly.has(dir) ? 'parked' : 'orphaned',\n checks: rekeyPending ? [rekeyPendingCheck(rekeyPending, undefined, input.runtime, slug)] : [],\n ...(rekeyPending ? { rekeyPending } : {}),\n })\n continue\n }\n const wired = agentIsWired(configText, names, slug, identity, sidecar, dir === directory, bareOwnerExists)\n const entry: AgentInventoryEntry = {\n ...(slug ? { slug } : {}),\n ...(identity.agent_id ? { agentId: identity.agent_id } : {}),\n directory: dir,\n classification: wired ? 'wired' : 'superseded',\n checks: [],\n ...(rekeyPending ? { rekeyPending } : {}),\n }\n if (wired) {\n const result = await checksForAgent({ directory: dir, identity, sidecar }, input, deps)\n entry.checks = result.checks\n capabilitiesByDirectory.set(dir, result.signerCapabilities)\n } else if (rekeyPending) {\n // A superseded directory runs no probes (that is the point — it is not\n // the agent in use), so the backend-completed refinement is unavailable\n // here and the check reports the file facts alone.\n entry.checks = [rekeyPendingCheck(rekeyPending, undefined, input.runtime, slug)]\n }\n inventory.push(entry)\n }\n\n // Which agent does the flat `checks` array describe? An explicitly given\n // --credentials-dir always wins. Otherwise it is the first WIRED agent —\n // not merely the newest directory, because a newly created but unwired\n // credential set would otherwise hijack the report and describe an agent\n // the runtime is not even using (#1697).\n const wiredDirectories = inventory\n .filter((entry) => entry.classification === 'wired')\n .map((entry) => entry.directory)\n const primaryDirectory = input.credentialsDir\n ? directory\n : (wiredDirectories.includes(directory ?? '') ? directory : wiredDirectories[0] ?? directory)\n if (primaryDirectory) {\n const primaryEntry = inventory.find((entry) => entry.directory === primaryDirectory)\n signerCapabilities = capabilitiesByDirectory.get(primaryDirectory)\n for (const check of primaryEntry?.checks ?? []) primaryChecksById.set(check.id, check)\n }\n\n // ── The historical single-agent check list, for the PRIMARY directory ─────\n // A single-agent install must read exactly as it did before (#1697 AC), so\n // the flat `checks` array keeps its order and ids; `agents` is the new,\n // additive per-agent shape.\n if (!primaryDirectory) {\n checks.push({\n id: 'credentials',\n label: 'Agent credentials',\n ok: false,\n detail: 'No agent credential directory with an identity.json under ~/.haven/agents.',\n repair: `Run the full setup once: ${RERUN} --setup <token from the Haven dashboard>.`,\n })\n } else {\n const primaryIdentity = await readIdentity(primaryDirectory)\n const primarySidecar = await readRuntimeSidecar(primaryDirectory)\n // Keyed on a check `checksForAgent` ALWAYS produces, not on the map being\n // empty (#1911): an unwired primary directory that happens to hold a\n // pending re-key now carries that one check from the inventory pass, and a\n // bare `size === 0` would read that as \"already done\" and silently skip\n // every real check for the directory the user pointed at.\n if (!primaryChecksById.has('credentials')) {\n // The primary directory is not wired (or has no key): run its checks\n // anyway — the user pointed the doctor at this machine, and silence\n // about the selected directory would be the old heuristic's failure.\n const result = await checksForAgent(\n { directory: primaryDirectory, identity: primaryIdentity, sidecar: primarySidecar }, input, deps,\n )\n signerCapabilities = result.signerCapabilities\n for (const check of result.checks) primaryChecksById.set(check.id, check)\n }\n for (const id of ['credentials', 'signer_runtime']) {\n const check = primaryChecksById.get(id)\n if (check) checks.push(check)\n }\n }\n\n if (configPath === null) {\n checks.push({\n id: 'runtime_config',\n label: 'Runtime MCP config',\n ok: true,\n detail: `Runtime '${input.runtime}' has no file-based config the connector owns (CLI-managed) — skipping the file check.`,\n })\n } else if (configText === null) {\n checks.push({\n id: 'runtime_config',\n label: 'Runtime MCP config',\n ok: false,\n detail: `No runtime config at ${configPath}.`,\n repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}`,\n })\n } else {\n const primaryIdentity = await readIdentity(primaryDirectory ?? '')\n const primarySidecar = primaryDirectory ? await readRuntimeSidecar(primaryDirectory) : null\n const hasHaven = primaryIdentity?.hosted_mcp_url\n ? configText.includes(primaryIdentity.hosted_mcp_url)\n : configText.includes('haven')\n // The wrapper form never writes the package spec into the config; only\n // the retired npx launch does — so the spec's presence IS the tell.\n const signerViaNpx = configText.includes('@haven_ai/signer')\n const wrapperReferenced = primarySidecar ? configText.includes(primarySidecar.wrapper_path) : false\n const ok = hasHaven && !signerViaNpx && (primarySidecar ? wrapperReferenced : true)\n checks.push({\n id: 'runtime_config',\n label: 'Runtime MCP config',\n ok,\n detail: ok\n ? `Config at ${configPath} references the hosted server and the prepared signer wrapper.`\n : signerViaNpx\n ? `Config at ${configPath} still launches the signer via npx — the pre-#1586 shape that cannot start under a 120s startup timeout.`\n : `Config at ${configPath} is missing the Haven entries${primarySidecar && !wrapperReferenced ? ' (or references a different signer wrapper)' : ''}.`,\n ...(ok ? {} : { repair: `Run: ${RERUN} --doctor --repair --runtime ${input.runtime}` }),\n })\n }\n\n for (const id of ['hosted_mcp', 'identity_match', 'rekey_pending']) {\n const check = primaryChecksById.get(id)\n if (check) checks.push(check)\n }\n\n // ── Superseded agents (#1688, now inventory-driven) ───────────────────────\n // A re-run mints a NEW agent and retires nothing: the connector never\n // deletes old directories, registration only collides on delegate address,\n // and cancel deliberately refuses to auto-revoke. Net effect: an MCP host\n // that started before the re-run keeps spending as the agent the user\n // believes they replaced — silently, because its old key still resolves.\n // The doctor reports; the user decides — connect never revokes or deletes.\n const otherEntries = inventory.filter((entry) => entry.directory !== primaryDirectory)\n if (otherEntries.length > 0) {\n // Labels carry their SOURCE ENTRY (#1697 review, finding 3): resolving a\n // label back to an entry by string prefix would attribute one agent's\n // classification to another whenever one id is a prefix of the next\n // (`agent-1` / `agent-10`), and the failure mode is telling the user to\n // revoke the live agent.\n const live: Array<{ label: string; entry: AgentInventoryEntry }> = []\n const revoked: string[] = []\n const unverifiable: string[] = []\n const retired: string[] = []\n for (const entry of otherEntries) {\n const identity = await readIdentity(entry.directory)\n const tombstone = await readAgentTombstone(entry.directory)\n // #1915 review: use the id the inventory already resolved rather than\n // re-deriving a narrower one. It is identical for a wired, superseded or\n // retired directory, and strictly better for one whose only id is in the\n // parked file — a NAMED agent's directory basename is its wiring slug,\n // so re-deriving would label the same directory by its slug here and by\n // its real agent id in the \"Other agents\" section, for the same entry.\n const otherAgent = entry.agentId ?? basename(entry.directory)\n const otherUrl = identity?.hosted_mcp_url\n ?? (identity?.api_url ? `${identity.api_url}/mcp` : undefined)\n if (!identity?.api_key || !otherUrl) {\n if (tombstone) retired.push(`${otherAgent} (retired ${tombstone.retired_at})`)\n else unverifiable.push(`${otherAgent} (no stored key/URL to probe)`)\n continue\n }\n const suffix = tombstone ? ' [tombstoned — key material still present]' : ''\n const probe = await (deps.probeHosted ?? probeHostedMcpTools)(identity.api_key, otherUrl, deps.fetch)\n if (probe.status === 'ok') live.push({ label: `${otherAgent}${suffix}`, entry })\n else if (probe.status === 'unauthorized') revoked.push(`${otherAgent}${suffix}`)\n // network_error / bad_response: neither a false \"still live\" failure\n // nor a false clean bill — a note, never a verdict.\n else unverifiable.push(`${otherAgent} (${probe.status})${suffix}`)\n }\n const parts: string[] = []\n if (live.length > 0) parts.push(`STILL SPEND-CAPABLE: ${live.map((item) => item.label).join(', ')}`)\n if (revoked.length > 0) parts.push(`already revoked: ${revoked.join(', ')}`)\n if (retired.length > 0) parts.push(`tombstoned (keys removed): ${retired.join(', ')}`)\n if (unverifiable.length > 0) parts.push(`could not verify: ${unverifiable.join(', ')}`)\n // #<new>: mirrored tombstone records whose credential directory is GONE.\n // A retirement flow (or a full ~/.haven/agents wipe) deleted the dir, but\n // the mirror keeps the retirement observable. Informational only — a\n // record with no dir holds no key and can never spend, so it never fails\n // this check. Reads the SAME home the doctor scans (deps.homeDir), never\n // the ambient process home — an explicit --credentials-dir run must not\n // consult the machine-wide default root (REGRESSION B2 discipline).\n const knownIds = new Set([...inventory].map((e) => e.agentId ?? basename(e.directory)))\n const ghostRecords = (await readTombstoneRecords(join(homeDir, '.haven', 'tombstones'))).filter(\n (rec) => !knownIds.has(rec.agent_id),\n )\n if (ghostRecords.length > 0) {\n parts.push(\n `retired records (dir removed): ${ghostRecords\n .map((rec) => `${rec.agent_id} (${rec.reason})`)\n .join(', ')}`,\n )\n }\n // #1697: a WIRED sibling is a legitimately live agent, not a superseded\n // one — several agents may share a runtime now. Only unwired credential\n // dirs make the check fail.\n const supersededLive = live\n .filter((item) => item.entry.classification !== 'wired')\n .map((item) => item.label)\n checks.push({\n id: 'superseded_agents',\n label: 'Superseded agent credentials',\n ok: supersededLive.length === 0,\n detail:\n supersededLive.length > 0\n ? `${otherEntries.length} other credential dir(s) found — ${parts.join('; ')}. A host started before ` +\n 'your latest setup keeps authenticating (and spending) as the old agent.'\n : `${otherEntries.length} other credential dir(s) found — ${parts.join('; ')}.`,\n ...(supersededLive.length > 0\n ? {\n repair:\n `Revoke ${supersededLive.join(', ')} on the Haven agent page, then remove the old ` +\n 'director(y/ies) under ~/.haven/agents. Connect never revokes or deletes for you.',\n }\n : {}),\n })\n }\n\n // ── Parked re-keys in OTHER directories (#1911) ───────────────────────────\n //\n // Why this is a FLAT check and not merely a nested one. `report.ok` rolls up\n // the flat list plus every WIRED agent's checks, so a hazard found only in a\n // non-wired entry does not reach the exit code — and `--json` + `report.ok`\n // is the obvious way a CI health-check consumes this. Leaving an abandoned\n // private key visible only in `agents[]` would reproduce, one layer up,\n // exactly the invisibility #1911 exists to remove: reported, but not\n // reported anywhere that gates anything.\n //\n // The precedent is `superseded_agents` directly above: it is a flat check\n // that FAILS on a credential hazard found in a directory that is explicitly\n // not wired. This repo already treats \"spend-capable key material in a\n // directory you are not using\" as exit-code-worthy, and a parked private key\n // is the same kind of fact — arguably more so, since a superseded agent is\n // at least an agent the owner once chose to create.\n //\n // Severity matches the per-agent check rather than inventing a second scale:\n // an OPEN pending re-key elsewhere is someone mid-flow on another agent and\n // stays informational; an EXPIRED or UNREADABLE one is the abandoned case\n // and fails. Deleting is still nobody's call but the owner's.\n //\n // #1915 widened what reaches this check without touching the check itself.\n // A `parked` directory is enumerated now, so its abandoned key cascades to\n // the exit code through this existing rule on this existing severity scale.\n // That is deliberate: the exit-code surface already moved once when #1911\n // made an expired parked key a failure, and moving it a second time — a new\n // check, or a new severity for this shape — would be a second behaviour\n // change bought for a strictly narrower case than the first. The state that\n // fails is the same state that already failed; only the set of directories\n // it can be found in got honest.\n const parkedElsewhere = inventory\n .filter((entry) => entry.directory !== primaryDirectory && entry.rekeyPending)\n .map((entry) => ({ entry, pending: entry.rekeyPending as RekeyPendingStatus }))\n if (parkedElsewhere.length > 0) {\n const abandoned = parkedElsewhere.filter((item) => item.pending.state !== 'pending')\n const describe = (item: (typeof parkedElsewhere)[number]): string =>\n `${item.entry.slug ?? item.entry.agentId ?? basename(item.entry.directory)} (${item.pending.state}, ${item.pending.path})`\n checks.push({\n id: 'rekey_pending_elsewhere',\n label: 'Parked re-keys in other credential directories',\n ok: abandoned.length === 0,\n detail:\n abandoned.length > 0\n ? `ABANDONED re-key key material outside the agent this report describes: ${abandoned.map(describe).join(', ')}. ` +\n 'Each holds a private key that was generated for a re-key nobody finished.'\n : `${parkedElsewhere.length} other director(y/ies) hold an open pending re-key: ${parkedElsewhere.map(describe).join(', ')}.`,\n ...(abandoned.length > 0\n ? {\n repair:\n 'Check the Haven agent page for each before deleting: if its on-chain revoke already ran, the agent ' +\n 'has no spend authority until you re-grant it (#1868), and that is not visible from this machine. ' +\n 'Connect never deletes key material for you.',\n }\n : {}),\n })\n }\n\n const signerProcess = primaryChecksById.get('signer_process')\n if (signerProcess) checks.push(signerProcess)\n\n // ── Restart still required? (informational, never fails the doctor) ───────\n const restart = restartRequiredForRuntime(input.runtime, deps.env)\n checks.push({\n id: 'restart',\n label: 'Runtime restart',\n ok: true,\n detail: restart\n ? 'This runtime loads MCP config at startup — restart it after any repair before expecting the tools to appear.'\n : 'No restart requirement known for this runtime.',\n })\n\n // #1697: exit non-zero if ANY wired agent fails ANY check — not just the\n // one the old heuristic happened to select.\n const wiredOk = inventory\n .filter((entry) => entry.classification === 'wired')\n .every((entry) => entry.checks.every((check) => check.ok))\n\n return {\n version: 1,\n ok: checks.every((check) => check.ok) && wiredOk,\n runtime: input.runtime,\n credentialDirectory: primaryDirectory,\n checks,\n agents: inventory,\n ...(signerCapabilities ? { signerCapabilities } : {}),\n }\n}\n\nexport interface RepairResult {\n ok: boolean\n messages: string[]\n}\n\n/** Re-run the pieces setup owns; never touches credentials or tokens. */\nexport async function runRepair(\n input: { runtime: string; credentialsDir?: string },\n deps: DoctorDeps = {},\n): Promise<RepairResult> {\n const homeDir = deps.homeDir ?? homedir()\n const messages: string[] = []\n const { directory, others } = await discoverCredentialDirectory(homeDir, input.credentialsDir)\n if (others.length > 0) {\n // Repair never touches the other directories — that is the doctor's\n // superseded_agents check's job to REPORT and the user's to act on.\n messages.push(`Note: ${others.length} other agent credential dir(s) exist — run --doctor for their status.`)\n }\n if (!directory) {\n return {\n ok: false,\n messages: [`No agent credentials found to repair — run the full setup: ${RERUN} --setup <token>.`],\n }\n }\n let identity: IdentityFile\n try {\n identity = JSON.parse(await readFile(join(directory, 'identity.json'), 'utf8')) as IdentityFile\n } catch {\n return { ok: false, messages: ['identity.json is unreadable — re-run the full setup with a fresh token.'] }\n }\n if (!identity.api_key || !(identity.hosted_mcp_url || identity.api_url)) {\n return { ok: false, messages: ['identity.json lacks the stored API key / hosted URL — re-run the full setup.'] }\n }\n\n // #1589 review (HIGH): a --local (local-stdio) setup writes a structurally\n // different config (the haven entry is the LOCAL MCP wrapper, not the\n // hosted URL). Repair only knows how to write the hosted+signer shape, so\n // clobbering a local config would convert a working topology silently —\n // the exact class of harm a repair tool must never cause. Detect and\n // refuse: the local wrapper (bin/haven-mcp) and its mcp-runtime sidecar\n // are the tell.\n const configPath = runtimeConfigPathFor(input.runtime, homeDir)\n if (configPath) {\n try {\n const existing = await readFile(configPath, 'utf8')\n if (existing.includes('bin/haven-mcp') || existing.includes('.haven/mcp-runtime')) {\n return {\n ok: false,\n messages: [\n `The config at ${configPath} is the LOCAL-stdio topology (--local). Repair currently rewrites only the hosted+signer shape and will not touch it.`,\n 'Re-run your original setup command (with --local) to repair a local-stdio install.',\n ],\n }\n }\n } catch {\n // No existing config — nothing to clobber; proceed.\n }\n }\n\n // #1910: WHICH MCP pair does this directory own? `serverNamesFor(undefined)`\n // is the BARE `haven` / `haven-signer` pair, so a repair that omits the slug\n // does not merely fail to fix the named agent it was pointed at — it\n // overwrites a *different*, working agent's entries with this one's\n // credentials and wrapper path. `--repair` is what people reach for when\n // something is already broken; breaking a second agent is the worst\n // available outcome.\n //\n // The slug is not a flag the user must remember to repeat: #1696 records it\n // in this directory's own sidecar, which is already on disk. Read it before\n // `prepareSignerRuntime` — that call REWRITES the sidecar, and passing the\n // slug back in is what stops the rewrite from erasing it (a second, quieter\n // half of the same defect: a repaired named agent would afterwards read as\n // an unnamed one to every later `--doctor`).\n const existingSidecar = await readRuntimeSidecar(directory)\n const serverName = existingSidecar?.server_name\n\n const signerPath = join(directory, 'signer.json')\n const prepared = await prepareSignerRuntime(\n { credentialDirectory: directory, signerPath, homeDir, serverName },\n { runCommand: deps.runCommand },\n )\n messages.push(...prepared.messages)\n\n const names = serverNamesFor(serverName)\n messages.push(`Rewriting MCP entries ${names.hosted} / ${names.signer}${serverName ? ` (agent \"${serverName}\")` : ' (unnamed pair)'} — no other pair is touched.`)\n\n const configResult = await writeRuntimeConfig({\n runtime: input.runtime as RuntimeId,\n hostedMcpUrl: identity.hosted_mcp_url ?? `${identity.api_url}/mcp`,\n apiKey: identity.api_key,\n identityPath: join(directory, 'identity.json'),\n signerPath,\n credentialDirectory: directory,\n signerCommand: { command: prepared.command, args: prepared.args },\n homeDir,\n mode: 'hosted',\n serverName,\n })\n messages.push(...configResult.messages)\n messages.push('Repair complete — restart the runtime, then verify with --doctor.')\n return { ok: true, messages }\n}\n","import { join } from 'node:path'\nimport { readFile, readdir, stat } from 'node:fs/promises'\nimport { createConnectApiClient, ConnectRequestError, type ConnectApiClient, type ResolvedSetup } from './api.js'\nimport { connectorRerunCommand, resolveTokenFromAddress } from '@haven_ai/sdk'\nimport {\n agentApiKeyPrefix,\n generateAgentApiKey,\n generateDelegateKey,\n hashAgentApiKey,\n type LocalDelegateKey,\n} from './key.js'\nimport { redactForAutomation, redactSecrets, shortAddress } from './redact.js'\nimport { assertValidServerSlug, serverNamesFor } from './server-names.js'\nimport {\n assertServerSlugAvailable,\n defaultCredentialRoot,\n preflightCredentialStorage,\n writeConnectOutcomeRecord,\n writeCredentialFiles,\n CONNECT_OUTCOME_FILENAME,\n type StoredCredentialPaths,\n} from './storage.js'\nimport {\n installRuntime,\n runtimeInstallCapabilities,\n supportsLocalMcp,\n type RuntimeInstallResult,\n} from './runtime-install.js'\nimport { normalizeRuntime, resolveRuntimeSelection, runtimeProfile, runtimeVerificationInstruction, RUNTIME_FLAG_VALUES, RUNTIME_FLAG_VALUE_LIST, type RuntimeId, type RuntimeProfile } from './runtime-registry.js'\nimport { ConnectError } from './connect-error.js'\nimport {\n installedClientHint,\n resolveRuntimeByInstalledClientPrompt,\n scanInstalledClients,\n type InstalledClientHint,\n} from './installed-clients.js'\nimport { assertSupportedNodeVersion } from './local-mcp-runtime.js'\nimport { MCP_RUNTIME_MANIFEST } from './runtime-manifest.js'\n\nexport const CONNECTOR_VERSION = '0.0.0-dev.202609031523.fd49e1a'\n\nexport interface ConnectOptions {\n setupToken: string\n apiBaseUrl: string\n runtime?: string\n /** #1672 escape hatch: use exactly this runtime, ignoring environment detection. */\n runtimeForce?: string\n /**\n * #1719: the harness an AGENT running this command reported for itself. Enters\n * at the same precedence as `runtime`, so it can only fill a vacuum — never\n * override a detected environment.\n */\n runtimeSelfReport?: string\n /**\n * #1719: this run may ask a human which installed client to configure. The\n * CLI sets it for a non-`--json` run; a library caller must opt in. Combined\n * with `deps.isTty`, it is what makes the prompt rung SKIPPED rather than\n * answered in CI, in `--json` automation, and in library embeddings.\n */\n interactive?: boolean\n credentialsDir?: string\n environmentLabel?: string\n /** #1696: wiring slug for a named MCP pair + slug-keyed credential dir. */\n serverName?: string\n connectorVersion?: string\n ackSigner?: boolean\n ackLocalTools?: boolean\n localMcp?: boolean\n /**\n * #1377 D: keep the process alive after registering and poll for the\n * user's budget approval (default). Set false for structured/automation\n * runs (--json) where prompt output emission matters more than narration.\n */\n waitForApproval?: boolean\n /** Test/injection overrides for the approval poll cadence and clock. */\n approvalWait?: ApprovalWaitOptions\n}\n\n/** The stable machine-readable result emitted by `haven-connect --json`. */\nexport const CONNECT_OUTCOME_SCHEMA_VERSION = 1 as const\n\nexport type ConnectOutcomeStatus = 'complete' | 'action_required' | 'failed'\n\nexport interface ConnectOutcome {\n schema_version: typeof CONNECT_OUTCOME_SCHEMA_VERSION\n outcome: ConnectOutcomeStatus\n runtime: string\n topology: string\n configuration: {\n hosted_mcp: boolean\n local_signer: boolean\n local_mcp: boolean\n }\n probe: { result: string }\n activation: {\n restart_required: boolean\n instruction: string\n }\n next_action: string\n approval: { required: boolean; expires_at: string | null }\n verification: {\n tools: readonly ['haven_get_agent', 'haven_get_allowances']\n instruction: string\n }\n delegate_address?: string\n setup_challenge_expires_at?: string\n /**\n * #2173, additive within schema_version 1. Both are present on a completed\n * run and absent on `failedConnectOutcome`, which by construction has\n * neither a registration nor a credential scan behind it.\n *\n * `hosted_mcp_url` is the endpoint Connect wired this run up to — written\n * into the runtime's MCP config, or, on a manual runtime that Connect cannot\n * configure, printed as the endpoint to enter by hand. It is deliberately\n * NOT the `--api` backend URL: the hosted MCP\n * server is a separate deployment, and an automation caller comparing the\n * two used to read that intentional topology as an environment mismatch. It\n * is non-secret — the same string already sits in the user's own config file\n * — and carries no credential; the API key travels beside it in a header.\n *\n * `superseded_agent_ids` is the #1688 heads-up made structural: previously\n * it was prose on stderr, so a `--json` caller could not see that the run it\n * just completed left older agents alive with their own keys. Empty on a\n * clean first run. An empty list is NOT proof of a clean machine — a scan\n * that cannot read the credential root also yields an empty list, and the\n * connector prefers that to failing a completed setup.\n */\n hosted_mcp_url?: string\n superseded_agent_ids?: readonly string[]\n /**\n * #2091, additive within schema_version 1: `message` is the redacted human\n * refusal (automation used to get code + next_action and nothing to act\n * on), and `allowed_runtimes` carries the valid `--runtime` retry values on\n * runtime-selection refusals — the list the backend's setup prompt requires\n * a retry to be drawn from, which `--json` previously discarded with the\n * prose.\n */\n error?: {\n code: string\n next_action: string\n message?: string\n allowed_runtimes?: readonly string[]\n /**\n * #2174, additive within schema_version 1. What the installed-client scan\n * found on THIS machine, narrowing a `runtime_undetermined` retry from the\n * nine-value `allowed_runtimes` menu to what is actually here.\n *\n * A hint an agent may echo back as `--runtime`, never a selection: the\n * outcome stays `failed` with `rerun_connect_with_explicit_runtime`, and\n * the connector never proceeds on it (#1719's populates-never-selects\n * invariant). Absent when the scan found nothing OR could not run —\n * both are honestly \"no finding\"; neither is a claim the machine is bare.\n * `suggested_runtime` appears only when one candidate is unambiguously\n * top, so it is never the winner of an arbitrary tiebreak.\n */\n installed_clients?: readonly string[]\n suggested_runtime?: string\n }\n}\n\nexport interface ConnectDeps {\n api?: ConnectApiClient\n generateKey?: () => LocalDelegateKey\n generateApiKey?: () => string\n preflightStorage?: typeof preflightCredentialStorage\n writeCredentials?: typeof writeCredentialFiles\n installRuntime?: typeof installRuntime\n log?: (message: string) => void\n /** JSON CLI mode must not expose owner-only credential file locations. */\n redactPaths?: boolean\n /** Overridable so the Node-floor refusal is testable without spawning a Node. */\n nodeVersion?: string\n /** Overridable so runtime detection (#1672) is testable without faking process.env. */\n env?: NodeJS.ProcessEnv\n /** Overridable so the #1719 TTY gate is testable without faking process.stdin. */\n isTty?: boolean\n /** Overridable so the #1719 installed-client prompt is testable without readline. */\n promptRuntime?: () => Promise<RuntimeId>\n /**\n * Overridable so the #2173 recovery-record write is testable without a real\n * credential directory — and so a FAILING writer can be injected to prove\n * that a broken record write never fails a completed setup.\n */\n writeOutcomeRecord?: typeof writeConnectOutcomeRecord\n /**\n * Overridable so the #2174 refusal hint is testable without depending on\n * which agent clients happen to be installed on the machine running the\n * suite — and so a THROWING scan can be injected to prove the refusal\n * degrades to its un-hinted shape.\n */\n scanInstalledClients?: typeof scanInstalledClients\n}\n\nexport interface ConnectResult {\n setupId: string\n agentId: string\n delegateAddress: string\n credentialPaths: StoredCredentialPaths\n /** Additive, secret-free completion contract shared by library callers and --json. */\n outcome: ConnectOutcome\n}\n\n/**\n * What a failing run has to hand back to the wrapper below (#2173).\n *\n * The failure record has to reach the same recovery file as the success\n * record, and the only place the credential directory exists is inside the\n * run. Reporting it into this box as soon as it exists keeps the whole body\n * un-indented; the wrapper writes the failure outcome there and re-throws the\n * error unchanged.\n *\n * A refusal that happens BEFORE credentials are written — `runtime_undetermined`,\n * an expired setup challenge, the Node floor — leaves the box empty by\n * construction. There is no directory to write into, and nothing was created\n * that a caller could need to recover.\n */\ninterface ConnectRunTrace {\n directory?: string\n runtime?: string\n}\n\n/**\n * The failure record a run already built, keyed on the error it threw (#2173).\n *\n * The run knows the RESOLVED runtime; a caller reconstructing the record from\n * the same error knows only the raw `--runtime` hint, and detection can\n * override that hint (#1672). Without this, one failed run could persist\n * `runtime: claude-code` to the recovery file and print `runtime: cursor` on\n * stdout — two records for one run, which is precisely the \"the file is\n * exactly what was emitted\" guarantee the recovery file rests on.\n *\n * A WeakMap rather than a property on the error: nothing is mutated, nothing\n * can be serialized into a message by accident, and the entry dies with the\n * error it describes.\n */\nconst failureOutcomesByError = new WeakMap<object, ConnectOutcome>()\n\n/**\n * The failure record for an error thrown by `runConnect` — the run's own, when\n * it built one, and a freshly derived record otherwise (a rejection that never\n * entered the run at all, such as an argument-parse refusal, or an injected\n * one in a test).\n */\nexport function failureOutcomeFor(runtimeHint: string | undefined, error: unknown): ConnectOutcome {\n if (error !== null && typeof error === 'object') {\n const recorded = failureOutcomesByError.get(error)\n if (recorded) return recorded\n }\n return failedConnectOutcome(runtimeHint, error)\n}\n\nexport async function runConnect(options: ConnectOptions, deps: ConnectDeps = {}): Promise<ConnectResult> {\n const trace: ConnectRunTrace = {}\n try {\n return await executeConnect(options, deps, trace)\n } catch (err) {\n // Built ONCE, from the resolved runtime, then both persisted and handed to\n // the caller — so the file and the stdout line can never disagree. Derived\n // even when there is no directory to write into: the caller still prints\n // it, and the resolved runtime is the true answer either way.\n const outcome = failedConnectOutcome(trace.runtime ?? options.runtime, err)\n if (err !== null && typeof err === 'object') failureOutcomesByError.set(err, outcome)\n if (trace.directory) await recordConnectOutcome(deps, trace.directory, outcome)\n throw err\n }\n}\n\n/**\n * Park the terminal outcome where a caller that lost the stream can read it.\n *\n * Best-effort, and the swallow lives HERE rather than in the writer: the setup\n * has already either succeeded or failed for its own reason by the time this\n * runs, and neither verdict may be changed by a filesystem write that exists\n * only as a convenience.\n */\nasync function recordConnectOutcome(\n deps: ConnectDeps,\n directory: string,\n outcome: ConnectOutcome,\n): Promise<string | undefined> {\n try {\n return await (deps.writeOutcomeRecord ?? writeConnectOutcomeRecord)(directory, outcome)\n } catch {\n return undefined\n }\n}\n\nasync function executeConnect(\n options: ConnectOptions,\n deps: ConnectDeps,\n trace: ConnectRunTrace,\n): Promise<ConnectResult> {\n // FIRST, before anything with a side effect (#1161).\n //\n // This runs ahead of the setup-token resolve, the storage preflight, key\n // generation, the agent registration, and every credential write — so a\n // refusal cannot strand a half-created agent or burn a one-shot setup token,\n // the same discipline the hosted-MCP-URL guard adopted in #1129.\n //\n // It is checked on EVERY topology, which is the actual fix here. The guard\n // already existed but only ran inside local-MCP installation, reached solely\n // via `--local`; the default hosted-MCP + local-signer path — what nearly\n // every user runs — never touched it. The floor was enforced on the advanced\n // path and unenforced on the common one.\n //\n // Refuse rather than warn: what gets installed is the signer, which holds the\n // delegate key and produces every payment signature. An unsupported runtime\n // under a signing component is not a state to continue from, and npm's own\n // EBADENGINE notice is advisory unless the user happens to run engine-strict.\n assertSupportedNodeVersion(deps.nodeVersion, MCP_RUNTIME_MANIFEST.minimumNodeVersion)\n\n const connectorVersion = options.connectorVersion ?? CONNECTOR_VERSION\n const api = deps.api ?? createConnectApiClient(options.apiBaseUrl)\n const log = secureLogger(\n deps.log ?? ((message) => process.stdout.write(`${message}\\n`)),\n deps.redactPaths === true,\n )\n const writeCredentials = deps.writeCredentials ?? writeCredentialFiles\n const preflightStorage = deps.preflightStorage ?? preflightCredentialStorage\n const runRuntimeInstall = deps.installRuntime ?? installRuntime\n const generateKey = deps.generateKey ?? generateDelegateKey\n const generateLocalApiKey = deps.generateApiKey ?? generateAgentApiKey\n // #1672: detection-first runtime resolution, BEFORE any side effect — the\n // setup command no longer carries --runtime, and a hint that contradicts a\n // confident detection must not write another client's config. Refusing here\n // keeps the #1161 discipline: no half-created agent, no burned setup token.\n //\n // #1719 extends the ladder past detection: an agent that knows its own\n // harness may say so (as a re-run carrying --runtime, which is why the\n // backend's setup prompt now permits exactly that one change), and a human\n // at a TTY is offered the clients actually installed here. The prompt rung\n // is OMITTED — not answered — whenever this is not an interactive terminal\n // run, so CI and --json automation still reach the refusal below instead of\n // blocking on stdin.\n const selection = await resolveRuntimeSelection(options.runtime, options.runtimeForce, {\n env: deps.env ?? process.env,\n selfReported: options.runtimeSelfReport,\n promptForRuntime: runtimeSelectionPrompt(options, deps),\n })\n if (!selection.runtime) {\n const hint = await installedClientHintFor(deps)\n throw new ConnectError(\n 'runtime_undetermined',\n 'Could not determine the agent runtime: nothing was detected in this environment and no --runtime was given. ' +\n 'If you are an AI agent running this command: re-run it once, unchanged except for adding ' +\n `--runtime <name>, naming the harness you are running in — one of: ${RUNTIME_FLAG_VALUES} ` +\n '(the aliases cowork, codex and openclaw are accepted too). Do not guess: if your harness is ' +\n 'not one of those, use --runtime other, which stores the credentials and prints the manual MCP steps. ' +\n installedClientProse(hint) +\n 'Nothing was written and the Haven setup token is still unused.',\n 'rerun_connect_with_explicit_runtime',\n // #2091: the values must ride structurally too. The backend's setup\n // prompt permits a retry only with \"one of the values that refusal\n // lists\" — and --json discards prose, so a prose-only list deadlocked\n // every automation run in an undetected runtime (Codex in the field:\n // npx needs network, Codex runs network commands unsandboxed, and the\n // unsandboxed path carries none of the CODEX_* detection vars).\n //\n // #2174: the list alone still leaves the retry a nine-value guess. The\n // scan below narrows it to what is actually on this machine — as a\n // HINT. It does not select, and this stays a refusal: see\n // `installedClientHint`.\n { allowedRuntimes: RUNTIME_FLAG_VALUE_LIST, ...hint },\n )\n }\n const runtime = selection.runtime\n trace.runtime = runtime\n const installCapabilities = runtimeInstallCapabilities(runtime)\n\n if (options.localMcp) {\n if (!supportsLocalMcp(runtime)) {\n throw new Error(\n `--local (fully-local Haven MCP) is only available for Claude Code and Codex. ` +\n `The detected runtime is ${runtimeProfile(runtime).label}. ` +\n 'Re-run without --local to use the default hosted MCP + local signer setup.',\n )\n }\n }\n\n if (selection.overrodeHint) {\n log(`runtime: ${runtime} (detected; ignoring the ${selection.overrodeHint} hint — pass --runtime-force ${selection.overrodeHint} to override)`)\n }\n if (selection.discardedHint) {\n // #1719: never silent. The caller asked for something this connector has\n // no name for; detection is what saved the run, and the user has to be\n // able to see that their value did nothing.\n log(`runtime: ${runtime} (detected; \"${selection.discardedHint}\" is not a runtime Haven knows — valid values: ${RUNTIME_FLAG_VALUES})`)\n }\n if (selection.source === 'prompted') {\n log(`runtime: ${runtime} (chosen at the prompt — nothing was detected in this environment)`)\n }\n\n log('Warming up your connection to Haven…')\n let setup: ResolvedSetup\n try {\n setup = await api.resolveSetup({\n setupToken: options.setupToken,\n connectorVersion,\n runtime,\n })\n } catch (err) {\n throw deadSetupTokenError(err) ?? err\n }\n assertSetupChallengeIsUsable(setup.challenge.expires_at)\n printSetupSummary(setup, log)\n\n await preflightStorage({ baseDir: options.credentialsDir, warn: log })\n if (options.serverName) {\n // Validated HERE too, not only in the CLI parser (#1696 review): runConnect\n // is exported, and a library caller passing a reserved or malformed slug\n // would otherwise register a live agent and write real key material to\n // disk before failing deep inside the config writer — the exact orphaned\n // -agent outcome this ordering exists to prevent.\n assertValidServerSlug(options.serverName)\n // #1696: the slug keys the credential directory, and connect never\n // overwrites credential files — so a taken slug must refuse HERE, before\n // a key is minted or an agent registered, not fail on the write and\n // leave an orphaned registration behind.\n await assertServerSlugAvailable(options.serverName, options.credentialsDir)\n }\n log('Checked local credential storage — all clear.')\n\n const localKey = generateKey()\n const localApiKey = generateLocalApiKey()\n log('Minting a fresh signing key and API key — both stay on this machine.')\n const proofSignature = await localKey.signChallenge(setup.challenge.message)\n\n log('Introducing your agent to Haven…')\n let registration: Awaited<ReturnType<ConnectApiClient['registerSetup']>>\n try {\n registration = await api.registerSetup({\n setupToken: options.setupToken,\n connectorVersion,\n runtime,\n challengeId: setup.challenge.id,\n delegateAddress: localKey.address,\n proofSignature,\n apiKeyHash: hashAgentApiKey(localApiKey),\n apiKeyPrefix: agentApiKeyPrefix(localApiKey),\n // #1878: report the pair we are ACTUALLY wiring, bare pair included, so\n // the dashboard can name it. Derived here rather than sent as the raw\n // slug — `serverNamesFor` is the one place the naming rule lives, and\n // the hosted name is what a user pastes into an MCP config.\n mcpServerName: serverNamesFor(options.serverName).hosted,\n connectorContext: {\n environment_label: options.environmentLabel ?? 'Local workspace',\n config_target: installCapabilities.canWriteRuntimeConfig\n ? 'agent runtime MCP config'\n : 'local credential files',\n },\n installCapabilities,\n })\n } catch (err) {\n // #2091 review: the token can die HERE too — register happens after\n // runtime detection, key generation, and any interactive prompt, well\n // inside the 30-minute TTL race — and the backend's 410 wording carries\n // no \"challenge\" for the legacy regex below to catch.\n const dead = deadSetupTokenError(err)\n if (dead) throw dead\n if (isExpiredSetupChallenge(err)) {\n throw new Error(\n 'The Haven setup challenge expired while connecting. Return to Haven, start a fresh connection, and run its new Connect command. Do not reuse or paste credentials.',\n )\n }\n throw err\n }\n\n log(`Registered signing address with Haven: ${shortAddress(registration.delegate_address)}.`)\n\n log('Tucking your credentials away safely on disk…')\n const credentialPaths = await writeCredentials({\n baseDir: options.credentialsDir,\n agentId: registration.agent_id,\n serverName: options.serverName,\n apiKey: localApiKey,\n delegateKey: localKey.privateKey,\n delegateAddress: localKey.address,\n safeAddress: setup.haven_wallet.address,\n chainId: setup.haven_wallet.chain_id,\n network: setup.haven_wallet.network,\n agentBudget: setup.agent_budget.map((budget) => ({\n token_symbol: budget.token_symbol,\n allowance_amount: budget.allowance_amount,\n reset_period_min: budget.reset_period_min,\n })),\n apiUrl: options.apiBaseUrl,\n hostedMcpUrl: registration.hosted_mcp_url,\n x402BindingSigner: setup.x402_binding_signer ?? undefined,\n warn: log,\n })\n // From here on a failure has somewhere to leave its verdict (#2173).\n trace.directory = credentialPaths.directory\n log(`Stored Haven identity credential locally: ${credentialPaths.identityPath}`)\n log(`Stored local signer credential locally: ${credentialPaths.signerPath}`)\n log(`Stored non-secret agent orientation locally: ${credentialPaths.agentPath}`)\n if (setup.x402_binding_signer) {\n log('Configured x402 binding signer for the local signer.')\n } else {\n // Fail loud here rather than silently at x402 sign time: without a trusted\n // binding signer the edge signer refuses to sign x402 funding hashes.\n log(\n 'Warning: Haven did not provide an x402 binding signer, so x402 payments will not sign ' +\n 'until HAVEN_X402_BINDING_SIGNER is set for the signer. Non-x402 payments are unaffected.',\n )\n }\n\n const runtimeInstall = await runRuntimeInstall({\n runtime,\n hostedMcpUrl: registration.hosted_mcp_url,\n apiKey: localApiKey,\n signerPath: credentialPaths.signerPath,\n identityPath: credentialPaths.identityPath,\n credentialDirectory: credentialPaths.directory,\n environmentLabel: options.environmentLabel ?? 'Local workspace',\n ackSigner: options.ackSigner,\n ackLocalTools: options.ackLocalTools,\n localMcp: options.localMcp,\n serverName: options.serverName,\n }, {\n onProgress: log,\n // #1543: report \"runtime configured\" the moment the config write settles,\n // so the dashboard can expose its budget-approval controls without\n // waiting on the probes and skill install — a tail that approval does not\n // depend on. Silent and best-effort: the complete report below remains\n // authoritative (it overwrites these keys, adding the probe verdicts and\n // skill state), so an early failure costs nothing but the head start.\n onRuntimeConfigured: async (early) => {\n try {\n await api.updateInstallStatus(registration.setup_id, localApiKey, {\n runtime: early.runtime,\n connectorVersion,\n runtimeMcpMode: early.runtimeMcpMode,\n hostedMcpConfigured: early.hostedMcpConfigured,\n localSignerConfigured: early.localSignerConfigured,\n localMcpConfigured: early.localMcpConfigured,\n credentialFilesWritten: true,\n signerAcknowledged: early.signerAcknowledged,\n localMcpAcknowledged: early.localMcpAcknowledged,\n restartRequired: early.restartRequired,\n nextUserAction: early.nextUserAction,\n errorCode: early.errorCode ?? null,\n environmentLabel: options.environmentLabel ?? 'Local workspace',\n })\n // #2279: THIS report landing is the exact moment the dashboard's\n // approve-budget controls unlock — so say so now, imperatively,\n // instead of running the install tail (probes, consent, skill) in\n // silence and only asking after it finishes. The field report: the\n // user watched the live button for minutes while the terminal said\n // nothing about it.\n //\n // Two distinct gates, from review. Liveness: the dashboard unlocks\n // on any DELIVERED report, clean or errored (`runtimeConfigured ||\n // installErrored`, useAgentConnectionSetup.ts) — so only a report\n // that never arrived (the catch below) may leave the button dead.\n // Coherence: the CTA also stays silent when the errorCode's own\n // completion handoff will say \"start a fresh connection\" — a fresh\n // connection mints a NEW agent (#1688), so \"approve now\" would spend\n // the approval on a setup this very run is about to disown. The one\n // errorCode whose handoff still recommends approving is\n // manual_runtime_setup_required. One name for the gate: the budget\n // (#1542).\n if (!early.errorCode || early.errorCode === 'manual_runtime_setup_required') {\n log('→ Action needed: approve this agent\\'s budget in the Haven dashboard — the approval button is live now. Setup continues here in the meantime.')\n }\n } catch {\n // ignore — the final report follows either way\n }\n },\n })\n printRuntimeInstall(runtimeInstall, log)\n\n // Tell the user they're done and what to do next BEFORE the telemetry call —\n // the install-status report is best-effort and must not sit between them and\n // the \"you're finished\" signal. The agent who reported the setup couldn't tell\n // whether the connector had finished; this affirms it explicitly. Only claim\n // completion when the runtime install actually succeeded — an errorCode means\n // manual steps remain (e.g. an unrecognized runtime), so don't overstate it.\n if (runtimeInstall.errorCode) {\n log('Haven setup needs a couple more steps on this machine — see the notes above.')\n } else {\n log('Haven setup on this machine is complete.')\n }\n\n // #1688: a re-run minted a NEW agent, and nothing retires the old one — the\n // previous directory keeps an API key and a signing key, and any host that\n // started before this run keeps spending as that agent. Name the superseded\n // agents here, at the moment the user is watching, with the one action only\n // they can take. Connect never revokes or deletes credentials itself.\n let supersededAgentIds: string[] = []\n try {\n supersededAgentIds = await listOtherAgentIds(options.credentialsDir, credentialPaths.directory)\n if (supersededAgentIds.length > 0) {\n log('')\n log(\n `Heads-up: this setup created a NEW agent. Your previous agent(s) — ${supersededAgentIds.join(', ')} — ` +\n 'still exist with their own keys, and any host that was already running keeps acting as them.',\n )\n log(\n 'If you meant to replace them: revoke them on the Haven agent page, then restart EVERY ' +\n 'long-lived host (gateways, TUI workers, editors) — each holds the MCP wiring snapshot from ' +\n 'its own start time, so after repeated setups each can be stuck on a DIFFERENT old agent. ' +\n `Then remove their directories under ~/.haven/agents (or ${RERUN_HINT} --tombstone <dir> to ` +\n `leave a diagnostic in their place). Run ${RERUN_HINT} --doctor to check whether their keys are still live.`,\n )\n }\n } catch {\n // Best-effort — never let the heads-up break a completed setup. The\n // outcome's `superseded_agent_ids` then reports the empty list, the same\n // thing a genuinely clean machine reports: a scan that could not run is\n // not evidence, and the field's doc comment says so rather than letting a\n // caller read emptiness as a guarantee.\n }\n\n // Report the completed runtime state before polling for budget approval.\n // The dashboard intentionally withholds approval controls until it knows the\n // local runtime is configured; polling first would wait on controls the\n // connector itself has not made available yet. Since #1543 the unlock\n // usually happened already, via the early config-written report above —\n // this complete report refines it with the probe verdicts and skill state,\n // and stays the fallback unlock path when the early one failed. It remains\n // best-effort readiness metadata only: a failed report cannot activate the\n // agent or change its budget authority.\n try {\n await api.updateInstallStatus(registration.setup_id, localApiKey, {\n runtime: runtimeInstall.runtime,\n connectorVersion,\n runtimeMcpMode: runtimeInstall.runtimeMcpMode,\n hostedMcpConfigured: runtimeInstall.hostedMcpConfigured,\n localSignerConfigured: runtimeInstall.localSignerConfigured,\n localMcpConfigured: runtimeInstall.localMcpConfigured,\n credentialFilesWritten: true,\n signerAcknowledged: runtimeInstall.signerAcknowledged,\n localMcpAcknowledged: runtimeInstall.localMcpAcknowledged,\n activationCommandAvailable: Boolean(runtimeInstall.activationCommand),\n skillInstalled: runtimeInstall.skillInstalled,\n probeResult: runtimeInstall.probeResult,\n restartRequired: runtimeInstall.restartRequired,\n nextUserAction: runtimeInstall.nextUserAction,\n errorCode: runtimeInstall.errorCode,\n environmentLabel: options.environmentLabel ?? 'Local workspace',\n })\n } catch (err) {\n log(`Could not report install status to Haven: ${err instanceof Error ? err.message : String(err)}`)\n }\n\n // #1377 D: stay alive through the approval instead of going dead exactly\n // while the user acts. Skipped in structured/automation mode\n // (waitForApproval: false — the --json contract emits promptly) and when\n // the install itself needs manual completion first. The observed outcome\n // shapes the printed next steps (#1542): an approval the wait just\n // celebrated must not be requested again two lines later.\n let approval: BudgetApprovalOutcome | undefined\n if (options.waitForApproval !== false && !runtimeInstall.errorCode) {\n approval = await waitForBudgetApproval(api, registration.setup_id, localApiKey, log, options.approvalWait)\n }\n\n printNextSteps(runtimeInstall, log, approval)\n\n const outcome = completionOutcome({\n runtimeInstall,\n delegateAddress: registration.delegate_address,\n hostedMcpUrl: registration.hosted_mcp_url,\n supersededAgentIds,\n setupChallengeExpiresAt: setup.challenge.expires_at,\n approvalRequired: registration.agent_status === 'pending_approval',\n })\n\n // #2173: park the verdict on disk before returning it. A harness whose watch\n // window closed during the cold signer install gets the same object here that\n // it missed on stdout — including the restart instruction and the read-only\n // verification sequence. The FILENAME only: the credential directory is\n // deliberately withheld from `--json` output, and naming it on the progress\n // stream would put back what `redactPaths` takes out.\n if (await recordConnectOutcome(deps, credentialPaths.directory, outcome)) {\n log(`Saved this run's outcome to ${CONNECT_OUTCOME_FILENAME} in the agent's credential directory.`)\n }\n\n return {\n setupId: registration.setup_id,\n agentId: registration.agent_id,\n delegateAddress: registration.delegate_address,\n credentialPaths,\n outcome,\n }\n}\n\nexport function completionOutcome(input: {\n runtimeInstall: RuntimeInstallResult\n delegateAddress: string\n hostedMcpUrl?: string\n supersededAgentIds?: readonly string[]\n setupChallengeExpiresAt?: string\n approvalRequired: boolean\n}): ConnectOutcome {\n const { runtimeInstall } = input\n const manualSetup = runtimeInstall.errorCode === 'manual_runtime_setup_required'\n const nextAction = runtimeInstall.nextUserAction\n const outcome: ConnectOutcome = {\n schema_version: CONNECT_OUTCOME_SCHEMA_VERSION,\n outcome: runtimeInstall.errorCode ? 'action_required' : 'complete',\n runtime: runtimeInstall.runtime,\n topology: runtimeInstall.runtimeMcpMode,\n configuration: {\n hosted_mcp: runtimeInstall.hostedMcpConfigured,\n local_signer: runtimeInstall.localSignerConfigured,\n local_mcp: runtimeInstall.localMcpConfigured,\n },\n probe: { result: runtimeInstall.probeResult },\n activation: {\n restart_required: runtimeInstall.restartRequired,\n instruction: manualSetup\n ? 'Finish the manual MCP setup using the secret-free references shown in normal Connect output, then start a fresh session.'\n : runtimeProfile(runtimeInstall.runtime).activationInstruction,\n },\n next_action: nextAction,\n approval: { required: input.approvalRequired, expires_at: null },\n verification: {\n tools: ['haven_get_agent', 'haven_get_allowances'] as const,\n instruction: runtimeVerificationInstruction(runtimeInstall.runtime),\n },\n // The backend contract supplies a 20-byte address. If an unexpected\n // malformed value arrives, do not echo it into an automation-facing\n // record; the human log has already been redacted separately.\n delegate_address: /^0x[0-9a-fA-F]{40}$/.test(input.delegateAddress)\n ? shortAddress(input.delegateAddress)\n : '[delegate-address-redacted]',\n // The endpoint Connect wrote into the runtime's MCP config, verbatim — the\n // same string that already sits in the user's own config file. Passed\n // through the secret filter anyway: this is the automation contract, the\n // value is server-supplied, and belts are cheap (the #1589 stance).\n ...(input.hostedMcpUrl ? { hosted_mcp_url: redactSecrets(input.hostedMcpUrl) } : {}),\n // Always emitted on a completed run, empty list included: \"no superseded\n // agents\" is a fact a caller needs, and an omitted key would be\n // indistinguishable from an older connector that never reported it.\n superseded_agent_ids: input.supersededAgentIds ?? [],\n ...(input.setupChallengeExpiresAt ? { setup_challenge_expires_at: input.setupChallengeExpiresAt } : {}),\n ...(runtimeInstall.errorCode\n ? { error: { code: runtimeInstall.errorCode, next_action: nextAction } }\n : {}),\n }\n return outcome\n}\n\n/**\n * The installed-client scan, as a hint on the `runtime_undetermined` refusal\n * (#2174).\n *\n * Best-effort and read-only: `scanInstalledClients` does filesystem existence\n * checks and nothing else, and this runs at a point where no setup token has\n * been resolved and no key or credential exists. A scan that throws degrades\n * to the un-hinted refusal rather than replacing a precise refusal with a\n * filesystem error — the caller's problem is still \"name your runtime\", and\n * an `EACCES` on someone's home directory must not bury that.\n *\n * Returns `{}` rather than an empty list when the scan found nothing, so the\n * refusal carries no `installed_clients` key at all: \"the scan found none\" and\n * \"the scan could not run\" are both honestly represented by absence, whereas\n * an empty array would assert a finding neither case made.\n */\nasync function installedClientHintFor(deps: ConnectDeps): Promise<Partial<InstalledClientHint>> {\n try {\n const candidates = await (deps.scanInstalledClients ?? scanInstalledClients)({ env: deps.env })\n const hint = installedClientHint(candidates)\n return hint.installedClients.length > 0 ? hint : {}\n } catch {\n return {}\n }\n}\n\n/**\n * The same finding in the prose channel, so the human and machine refusals\n * cannot say different things about the same machine. Phrased as evidence\n * (\"Haven can see …\"), never as an instruction to use it: the retry is still\n * the agent's explicit choice.\n */\nfunction installedClientProse(hint: Partial<InstalledClientHint>): string {\n const found = hint.installedClients ?? []\n if (found.length === 0) return ''\n const suggestion = hint.suggestedRuntime\n ? ` The likeliest is ${hint.suggestedRuntime}, but Haven will not choose for you — pass it yourself if it is right.`\n : ' Haven will not choose between them for you.'\n return `Haven can see these agent clients installed here, likeliest first: ${found.join(', ')}.${suggestion} `\n}\n\n/**\n * The prompt rung's gate (#1719), in one place so the two conditions that\n * SKIP it cannot drift apart: a run that is not interactive (`--json`, a\n * library embedding) and a run whose stdin is not a terminal (CI, a pipe).\n * Returning `undefined` omits the rung from the ladder entirely, so those runs\n * reach the `runtime_undetermined` refusal instead of blocking on stdin.\n */\nfunction runtimeSelectionPrompt(\n options: ConnectOptions,\n deps: ConnectDeps,\n): (() => Promise<RuntimeId>) | undefined {\n if (options.interactive !== true) return undefined\n // The TTY gate is checked BEFORE the injected prompt, not after: an override\n // that could skip it would make the gate untestable through the seam that\n // exists to test it.\n if (!(deps.isTty ?? Boolean(process.stdin.isTTY))) return undefined\n return deps.promptRuntime ?? (() => resolveRuntimeByInstalledClientPrompt())\n}\n\n/**\n * The failure record for the `--json` contract.\n *\n * #1719: a `ConnectError` carries its own code and next action, so it is read\n * rather than guessed. The regex ladder below survives only for the refusals\n * that are still plain `Error`s — every new failure mode joins the vocabulary\n * instead of joining that ladder.\n *\n * #2091: the record now carries the redacted message rather than omitting it.\n * The old stance — terse because \"messages can contain server or filesystem\n * detail\" — left automation with a code and nothing to act on; the field\n * failure was a Codex agent staring at `connect_failed` with, in its own\n * words, \"no additional safe error detail\". Sanitize, don't silence.\n */\nexport function failedConnectOutcome(runtimeHint: string | undefined, error: unknown): ConnectOutcome {\n const message = error instanceof Error ? error.message : ''\n const code = error instanceof ConnectError\n ? error.code\n : /Node\\.js >=/i.test(message)\n ? 'unsupported_node_version'\n : /setup challenge.*expired|expired or invalid/i.test(message)\n ? 'setup_challenge_expired_or_invalid'\n : /only available for Claude Code and Codex/i.test(message)\n ? 'local_mcp_unsupported_runtime'\n : 'connect_failed'\n const runtime = normalizeRuntime(runtimeHint)\n const nextAction = error instanceof ConnectError\n ? error.nextAction\n : code === 'setup_challenge_expired_or_invalid'\n ? 'return_to_haven_for_fresh_setup'\n : code === 'unsupported_node_version'\n ? 'install_supported_node_and_rerun_connect'\n : code === 'local_mcp_unsupported_runtime'\n ? 'rerun_without_local_mcp'\n : 'review_the_safe_error_output_and_start_a_fresh_haven_setup_if_needed'\n return {\n schema_version: CONNECT_OUTCOME_SCHEMA_VERSION,\n outcome: 'failed',\n runtime,\n topology: 'unknown',\n configuration: { hosted_mcp: false, local_signer: false, local_mcp: false },\n probe: { result: 'not_run' },\n activation: { restart_required: false, instruction: 'Resolve the reported problem before activating Haven tools.' },\n next_action: nextAction,\n approval: { required: false, expires_at: null },\n verification: {\n tools: ['haven_get_agent', 'haven_get_allowances'] as const,\n instruction: 'After a successful setup and activation, verify only with haven_get_agent and haven_get_allowances.',\n },\n error: {\n code,\n next_action: nextAction,\n // Only a ConnectError's message enters the JSON record: the vocabulary's\n // prose is connector-authored and safe to serialize, while a plain\n // Error can carry arbitrary server or filesystem detail (that stance is\n // pinned by test). Redaction stays on as belt-and-braces; plain-Error\n // runs still get their redacted message on stderr via the CLI mirror.\n ...(error instanceof ConnectError && message ? { message: redactForAutomation(message) } : {}),\n ...(error instanceof ConnectError && error.details.allowedRuntimes\n ? { allowed_runtimes: error.details.allowedRuntimes }\n : {}),\n ...(error instanceof ConnectError && error.details.installedClients?.length\n ? { installed_clients: error.details.installedClients }\n : {}),\n ...(error instanceof ConnectError && error.details.suggestedRuntime\n ? { suggested_runtime: error.details.suggestedRuntime }\n : {}),\n },\n }\n}\n\nfunction printSetupSummary(setup: ResolvedSetup, log: (message: string) => void): void {\n log(`Fetched Haven setup for ${setup.agent.name}.`)\n log(`Haven wallet: ${setup.haven_wallet.name} on ${setup.haven_wallet.network}.`)\n if (setup.agent_budget.length > 0) {\n for (const budget of setup.agent_budget) {\n log(\n `Agent budget: ${budget.allowance_amount} atomic ${budget.token_symbol} / ${budget.reset_period_min} minute reset.`,\n )\n }\n }\n log(`Setup challenge expires at ${setup.challenge.expires_at}. If it expires, return to Haven for a fresh setup and rerun Connect — do not reuse or paste credentials.`)\n}\n\nfunction assertSetupChallengeIsUsable(expiresAt: string): void {\n const expiresAtMs = Date.parse(expiresAt)\n if (!Number.isNaN(expiresAtMs) && expiresAtMs > Date.now()) return\n throw new Error(\n 'This Haven setup challenge is expired or invalid. Return to Haven, start a fresh connection, and rerun Connect. No local credentials were written.',\n )\n}\n\n/**\n * #2091: a dead setup token is a first-class verdict, not `connect_failed`.\n * The backend answers 410 \"Setup token expired\" (30-minute TTL) and 401\n * \"Invalid setup token\" (no matching setup at all — a mistyped or garbled\n * token reads the same as a purged one); neither wording matched the legacy\n * expiry regexes, so a --json run degraded to the generic code with no usable\n * next action — per #1719, the failure mode joins the ConnectError vocabulary\n * instead of that ladder. Checked at BOTH token-bearing calls (resolve and\n * register): the token can expire in the gap between them, since register\n * runs after runtime detection, key generation, and any interactive prompt.\n * Returns null for anything that is not this verdict.\n */\nfunction deadSetupTokenError(err: unknown): ConnectError | null {\n if (!(err instanceof ConnectRequestError) || (err.status !== 410 && err.status !== 401)) return null\n return new ConnectError(\n 'setup_challenge_expired_or_invalid',\n 'This Haven setup token is expired or invalid — tokens are single-use and expire 30 minutes after ' +\n 'the dashboard issues them, and a mistyped token reads the same way. Return to Haven, start a ' +\n 'fresh connection, and run its new Connect command. No local credentials were written.',\n 'return_to_haven_for_fresh_setup',\n )\n}\n\nfunction isExpiredSetupChallenge(err: unknown): boolean {\n return err instanceof Error && /(?:setup )?challenge.*expir|expir.*(?:setup )?challenge/i.test(err.message)\n}\n\nfunction secureLogger(log: (message: string) => void, redactPaths = false): (message: string) => void {\n return (message) => {\n log(redactPaths ? redactForAutomation(message) : redactSecrets(message))\n }\n}\n\nfunction printRuntimeInstall(result: RuntimeInstallResult, log: (message: string) => void): void {\n for (const message of result.messages) log(message)\n if (result.localMcpConfigured) {\n log('Configured local Haven MCP tools.')\n } else if (result.hostedMcpConfigured) {\n log('Configured hosted Haven MCP identity.')\n } else {\n log('Haven MCP tools still need runtime setup.')\n }\n if (result.localSignerConfigured) {\n log('Configured local Haven signer.')\n } else {\n log('Local Haven signer still needs runtime setup.')\n }\n}\n\n/**\n * #1377 D: after registering, the connector no longer goes dead while the\n * user approves in Haven — it polls the narrow connector-status endpoint\n * (agent-API-key auth, works during `setup_pending`) and narrates progress in\n * the flow's voice, ending in a concrete celebration naming the granted\n * authority. Bounds (stated per the issue): poll every 5 s, give up after\n * 3 minutes (36 polls; with the immediate first check below the last one\n * lands at ~175 s) — the connector ALWAYS terminates on its own; a timeout\n * is a clean exit with guidance, never a hang. Injectable clock/cadence for\n * tests.\n *\n * #1542: the first check happens BEFORE the \"waiting for you to approve\" line\n * is printed. Users routinely approve in the dashboard while the runtime\n * install is still running, and announcing a wait that is already over made\n * the very next line (\"Budget approved 🎉\") read as a contradiction — the\n * field-test agent relayed the pair verbatim as a bug.\n */\nexport interface ApprovalWaitOptions {\n intervalMs?: number\n timeoutMs?: number\n sleep?: (ms: number) => Promise<void>\n}\n\n/** Human form of an atomic amount — whole numbers stay whole (\"25\", not \"25.0\"). */\nfunction formatAtomicAmount(atomic: bigint, decimals: number): string {\n const s = atomic.toString().padStart(decimals + 1, '0')\n const intPart = s.slice(0, s.length - decimals) || '0'\n const fracPart = s.slice(s.length - decimals).replace(/0+$/, '')\n return fracPart ? `${intPart}.${fracPart}` : intPart\n}\n\n/**\n * #1426: one voice with the dashboard. The celebration line renders next to\n * the dashboard's approved screen describing the SAME grant, so every period\n * the dashboard offers (RESET_PERIODS: 0/1440/10080/43200) must phrase\n * identically to `budgetPeriodLabel`'s sentence form — \"per 10080 minutes\"\n * made the user do arithmetic on a reassurance message. `0` says \"in total\"\n * (the dashboard's sentence form), not \"with no automatic reset\" — one voice,\n * decided here rather than left as a recorded divergence.\n *\n * Deliberately NOT one source of truth with the frontend: the shared mapping\n * lives in dashboard code, and the only shared home would be\n * `@haven_ai/core` — a PRIVATE workspace package that published packages\n * (this one) must never depend on. Same structural reason the frontend keeps\n * an inline copy of the skill content; the parity tests are the coupling.\n */\nfunction describeResetPeriod(resetPeriodMin: number): string {\n if (resetPeriodMin === 1440) return 'per day'\n if (resetPeriodMin === 10080) return 'per week'\n if (resetPeriodMin === 43200) return 'per month'\n if (resetPeriodMin === 60) return 'per hour'\n if (resetPeriodMin === 0) return 'in total'\n return `every ${resetPeriodMin} minutes`\n}\n\nfunction describeApprovedBudget(budget: {\n token_symbol: string\n token_address: string\n amount: string\n reset_period_min: number\n}): string {\n const token = resolveTokenFromAddress(budget.token_address)\n const amount = token\n ? `${formatAtomicAmount(BigInt(budget.amount), token.decimals)} ${budget.token_symbol}`\n : `${budget.amount} ${budget.token_symbol} (atomic units)`\n return `${amount} ${describeResetPeriod(budget.reset_period_min)}`\n}\n\n/** \"3 minutes\" for the default bound; seconds for the sub-2-minute test cadences. */\nfunction describeWaitBound(timeoutMs: number): string {\n if (timeoutMs >= 120_000) {\n const minutes = Math.round(timeoutMs / 60_000)\n return `${minutes} minutes`\n }\n return `${Math.round(timeoutMs / 1_000)}s`\n}\n\nexport type BudgetApprovalOutcome = 'approved' | 'pending' | 'ended'\n\nexport async function waitForBudgetApproval(\n api: Pick<ConnectApiClient, 'getConnectorStatus'>,\n setupId: string,\n apiKey: string,\n log: (message: string) => void,\n options: ApprovalWaitOptions = {},\n): Promise<BudgetApprovalOutcome> {\n const intervalMs = options.intervalMs ?? 5_000\n const timeoutMs = options.timeoutMs ?? 180_000\n const sleep = options.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)))\n const maxPolls = Math.max(1, Math.floor(timeoutMs / intervalMs))\n const remindEvery = Math.max(1, Math.floor(30_000 / intervalMs))\n\n // Announced only once a check has actually observed a pending (or unknown)\n // state — never ahead of a first check that may find the wait already over.\n //\n // #2279: phrased as status, not as the first ask — the imperative CTA now\n // prints when the early install-status report unlocks the dashboard button,\n // usually minutes before this line. When that CTA did not print (early\n // report failed or errored), the complete report just before this wait is\n // what unlocked the button, so this line still carries the instruction.\n let waitingAnnounced = false\n const announceWaiting = () => {\n if (waitingAnnounced) return\n waitingAnnounced = true\n log('Now waiting for you to approve the budget in the Haven dashboard — approval is what unlocks the agent\\'s Haven tools…')\n }\n\n for (let i = 0; i < maxPolls; i++) {\n // The first check is immediate (#1542); only the retries pace themselves.\n if (i > 0) await sleep(intervalMs)\n let status: Awaited<ReturnType<ConnectApiClient['getConnectorStatus']>>\n try {\n status = await api.getConnectorStatus(setupId, apiKey)\n } catch (err) {\n // 401/404 are verdicts, not noise: the user cancelled the setup from\n // the dashboard (key revoked) or the setup is gone. Retrying for the\n // rest of the window and then saying \"still pending\" would be wrong —\n // there is nothing left to approve.\n if (err instanceof ConnectRequestError && (err.status === 401 || err.status === 404)) {\n log('This setup ended in Haven — start a fresh connection from the dashboard when ready.')\n return 'ended'\n }\n // A flaky poll is not a verdict — keep waiting inside the same bound,\n // and say so, rather than sitting silent until a check succeeds.\n announceWaiting()\n continue\n }\n if (status.status === 'active') {\n log(\n status.approved_budget\n ? `Budget approved 🎉 — I can now spend up to ${describeApprovedBudget(status.approved_budget)} from your Haven wallet.`\n : 'Budget approved 🎉 — the agent can now spend within its Haven rules.',\n )\n return 'approved'\n }\n if (status.status === 'cancelled' || status.status === 'expired' || status.status === 'failed') {\n log(`This setup ended in Haven (${status.status}) — start a fresh connection from the dashboard when ready.`)\n return 'ended'\n }\n announceWaiting()\n if (i > 0 && i % remindEvery === 0) {\n // #2279: a watcher could not tell active polling from a hang, and the\n // give-up bound (#1377 D) was invisible until it fired. Elapsed time is\n // poll-count arithmetic, not a clock read, so the injectable-clock\n // tests stay deterministic.\n const elapsedSeconds = Math.round((i * intervalMs) / 1_000)\n log(\n `Still waiting for budget approval in Haven — ${elapsedSeconds}s elapsed, checking every ` +\n `${Math.round(intervalMs / 1_000)}s. I'll stop waiting after ${describeWaitBound(timeoutMs)}; ` +\n 'you can approve later and the tools unlock then.',\n )\n }\n }\n log(\n 'Budget approval is still pending in Haven. Approve it in the dashboard whenever you are ready — ' +\n 'the agent tools unlock the moment you do. Verify later with the read-only haven_get_agent tool.',\n )\n return 'pending'\n}\n\n/**\n * The two remaining gates after the local connector finishes: approve the\n * budget in Haven, then (for most runtimes) restart so the freshly-written MCP\n * config is loaded. The approval line states the dependency explicitly — tools\n * never appear before approval, restart or not — because an agent that had\n * already approved still couldn't tell whether missing tools meant \"not\n * approved\" or \"needs restart.\"\n *\n * #1542, from the field test:\n * - The lines are shaped by what the approval wait observed. `'approved'`\n * replaces the approve instruction with a confirmation — the connector must\n * never celebrate the approval and then instruct the user to go perform it.\n * `undefined` (wait skipped: --json mode, or an install errorCode) keeps the\n * full instruction.\n * - One name for the gate throughout this file: the BUDGET — the word the wait\n * loop, the celebration, and the dashboard's grant screen already use.\n * \"Agent rules\" here made one gate read as two.\n * - The restart step says WHY it survives the connector's own verification:\n * session/app-scoped runtimes only read MCP config at start-up.\n */\nexport function completionHandoffLines(\n result: RuntimeInstallResult,\n approval?: BudgetApprovalOutcome,\n): string[] {\n if (result.errorCode === 'manual_runtime_setup_required') {\n return [\n 'Next steps:',\n '1. Return to Haven and approve the budget. Approval — not restarting — unlocks Haven tools.',\n '2. Finish the manual MCP setup using the secret-free file references printed above, then start a fresh session in your runtime.',\n `3. ${runtimeVerificationInstruction(result.runtime)}`,\n ]\n }\n if (result.errorCode) {\n return [\n 'Recovery: runtime setup is not complete. Resolve the reported problem, then return to Haven for a fresh connection and run its new Connect command. Do not manually edit runtime config or paste credentials into prompts, logs, or config.',\n ]\n }\n\n if (approval === 'ended') {\n return [\n 'Next step: this setup ended in Haven before the budget was approved, so there is nothing left to approve on it — start a fresh connection from the dashboard when ready.',\n ]\n }\n\n const profile = runtimeProfile(result.runtime)\n const activation = activationInstructionWithWhy(profile)\n if (approval === 'approved') {\n return [\n 'Next steps — the budget is already approved, so there is nothing more to do in Haven:',\n `1. ${activation}`,\n `2. ${runtimeVerificationInstruction(result.runtime)}`,\n ]\n }\n return [\n 'Next steps:',\n '1. Return to Haven and approve the budget. Approval — not restarting — unlocks Haven tools.',\n `2. ${activation}`,\n `3. ${runtimeVerificationInstruction(result.runtime)}`,\n ]\n}\n\n/**\n * The field-test agent had just watched the connector print \"Verified Claude\n * Code MCP entry\" and reasonably asked why a restart was still demanded. Say\n * the reason in the instruction itself: verification ran in the connector's\n * process, but the runtime only reads MCP config at session start (or app\n * launch). Hot-reload and manual runtimes keep their registry copy untouched —\n * their instructions already carry their own activation story.\n */\nfunction activationInstructionWithWhy(profile: RuntimeProfile): string {\n if (profile.restartMode === 'restart-session') {\n return `${profile.activationInstruction} (The entries are already written and verified — ${profile.label} only reads MCP config when a session starts, which is why this step is still needed.)`\n }\n if (profile.restartMode === 'restart-app') {\n return `${profile.activationInstruction} (The entries are already written and verified — ${profile.label} only reads MCP config at app launch, which is why this step is still needed.)`\n }\n return profile.activationInstruction\n}\n\nconst RERUN_HINT = connectorRerunCommand()\n\n/**\n * Agent ids of every OTHER credential directory (#1688) — the agents this\n * run just superseded. Reads identity.json for the id; a directory that does\n * not parse is named by its directory name, because \"I could not read it\" is\n * still a directory the user should know exists.\n */\nasync function listOtherAgentIds(baseDir: string | undefined, currentDirectory: string): Promise<string[]> {\n const root = defaultCredentialRoot(baseDir)\n let entries: string[] = []\n try {\n entries = await readdir(root)\n } catch {\n return []\n }\n const ids: string[] = []\n for (const entry of entries) {\n // Exclude by the DIRECTORY this run wrote, never by agent id (#1696\n // review): a named agent's directory is its slug, which never equals the\n // agent uuid, so an id comparison would name the agent just created as a\n // superseded one and tell the user to revoke it on a clean first run.\n if (join(root, entry) === currentDirectory) continue\n const identityPath = join(root, entry, 'identity.json')\n // Gate on the FILE EXISTING before treating the entry as an agent at all\n // (#1688 review, B1): readdir returns every filesystem entry, and a\n // .DS_Store or sync-relic that merely fails to read must be skipped —\n // naming it would tell the user to \"revoke\" a file. A directory whose\n // identity.json EXISTS but does not parse is the case worth surfacing,\n // by directory name, because a corrupt agent dir is still an agent dir.\n try {\n await stat(identityPath)\n } catch {\n continue\n }\n try {\n const identity = JSON.parse(await readFile(identityPath, 'utf8')) as { agent_id?: string }\n ids.push(identity.agent_id ?? entry)\n } catch {\n ids.push(entry)\n }\n }\n return ids\n}\n\nfunction printNextSteps(\n result: RuntimeInstallResult,\n log: (message: string) => void,\n approval?: BudgetApprovalOutcome,\n): void {\n for (const line of completionHandoffLines(result, approval)) log(line)\n}\n","import { homedir } from 'node:os'\nimport { join, resolve } from 'node:path'\nimport { access } from 'node:fs/promises'\nimport { createInterface } from 'node:readline'\nimport { ConnectError } from './connect-error.js'\nimport { runtimeConfigPathFor } from './config-writers.js'\nimport { runtimeProfile, type RuntimeId } from './runtime-registry.js'\n\n/**\n * Installed-client scan + interactive pick (#1719).\n *\n * The rung that answers \"which runtime am I configuring?\" for a HUMAN in a\n * plain terminal, where there is no agent shell to detect. Two properties hold\n * it up, and both are load-bearing:\n *\n * 1. **Only clients the connector can actually write.** A row that cannot be\n * configured is not a choice, it is a dead end wearing a choice's clothes.\n * 2. **The scan populates the choices; it never selects.** Finding exactly one\n * installed app tells you what EXISTS, not where the user wants their agent\n * to run — and the cost of being wrong is an API key and a delegate key\n * written into an app the user does not use. `scanInstalledClients` returns\n * candidates and nothing else; only an answer typed at the prompt resolves\n * a runtime.\n */\nexport interface InstalledClientCandidate {\n runtime: RuntimeId\n label: string\n /** What made this a candidate — shown at the prompt so the pick is informed. */\n detail: string\n /**\n * The config file Haven would write for this client, when it owns one.\n * `null` for Claude Code, which is configured through its own CLI. Set\n * regardless of which evidence found the client — `evidence` is what says\n * whether that file exists today.\n */\n configPath: string | null\n evidence: 'config-file' | 'client-directory'\n}\n\ninterface ScanTarget {\n runtime: RuntimeId\n label: string\n /** The config file the connector would write, when it owns a file path. */\n configPath: string | null\n /** Paths that mean \"this client is installed\" even with no MCP config yet. */\n markers: string[]\n}\n\nexport interface ScanInstalledClientsOptions {\n homeDir?: string\n /** Workspace root, for the project-local `.vscode/` marker. */\n cwd?: string\n env?: NodeJS.ProcessEnv\n /** Injectable so the scan is testable without a populated home directory. */\n exists?: (path: string) => Promise<boolean>\n}\n\n/**\n * Ranked highest-confidence first WITHIN each evidence tier. An existing MCP\n * config file outranks a bare client directory across the board — a client the\n * user has already pointed at some MCP server is likelier to be the one they\n * are pointing at Haven now.\n */\nconst SCAN_ORDER: readonly RuntimeId[] = [\n 'claude-code',\n 'codex-cli',\n 'cursor',\n 'vscode',\n 'vscode-insiders',\n 'claude-desktop',\n 'hermes',\n]\n\nexport function installedClientTargets(\n homeDir: string = homedir(),\n cwd: string = process.cwd(),\n env: NodeJS.ProcessEnv = process.env,\n): ScanTarget[] {\n const targets: ScanTarget[] = [\n {\n runtime: 'claude-code',\n label: 'Claude Code',\n // Claude Code is configured through its own CLI (`claude mcp add-json`),\n // not by writing a file this module owns — so its evidence is the\n // client directory, never a config path.\n configPath: null,\n markers: [join(homeDir, '.claude'), join(homeDir, '.claude.json')],\n },\n {\n runtime: 'codex-cli',\n // Both Codex surfaces write the same ~/.codex/config.toml, so they are\n // ONE candidate. Splitting them would ask the user to answer a question\n // whose answers are the same write.\n label: 'Codex (CLI or Desktop)',\n configPath: runtimeConfigPathFor('codex-cli', homeDir),\n markers: [join(homeDir, '.codex')],\n },\n {\n runtime: 'cursor',\n label: 'Cursor',\n configPath: runtimeConfigPathFor('cursor', homeDir),\n markers: [join(homeDir, '.cursor')],\n },\n {\n runtime: 'vscode',\n label: 'VS Code',\n configPath: runtimeConfigPathFor('vscode', homeDir),\n markers: [resolve(cwd, '.vscode')],\n },\n {\n runtime: 'vscode-insiders',\n label: 'VS Code Insiders',\n configPath: runtimeConfigPathFor('vscode-insiders', homeDir),\n markers: [],\n },\n {\n runtime: 'claude-desktop',\n label: 'Claude Desktop',\n configPath: runtimeConfigPathFor('claude-desktop', homeDir),\n markers: [],\n },\n {\n runtime: 'hermes',\n label: 'Hermes Agent',\n configPath: runtimeConfigPathFor('hermes', homeDir),\n markers: [env.HERMES_HOME ?? join(homeDir, '.hermes')],\n },\n ]\n // Belt and braces against a future profile losing its writer: an unwritable\n // runtime must never reach the prompt (property 1 above).\n return targets.filter((target) => runtimeProfile(target.runtime, {}).canWriteRuntimeConfig)\n}\n\nexport async function scanInstalledClients(\n options: ScanInstalledClientsOptions = {},\n): Promise<InstalledClientCandidate[]> {\n const exists = options.exists ?? pathExists\n const targets = installedClientTargets(options.homeDir, options.cwd, options.env ?? process.env)\n const found: InstalledClientCandidate[] = []\n for (const target of targets) {\n if (target.configPath && (await exists(target.configPath))) {\n found.push({\n runtime: target.runtime,\n label: target.label,\n detail: `MCP config found at ${target.configPath}`,\n configPath: target.configPath,\n evidence: 'config-file',\n })\n continue\n }\n for (const marker of target.markers) {\n if (!(await exists(marker))) continue\n found.push({\n runtime: target.runtime,\n label: target.label,\n detail: `installed (${marker})`,\n configPath: target.configPath,\n evidence: 'client-directory',\n })\n break\n }\n }\n return found.sort((a, b) => {\n if (a.evidence !== b.evidence) return a.evidence === 'config-file' ? -1 : 1\n return SCAN_ORDER.indexOf(a.runtime) - SCAN_ORDER.indexOf(b.runtime)\n })\n}\n\n/**\n * The scan's findings as DATA, for the `--json` refusal (#2174).\n *\n * The interactive prompt is deliberately omitted under `--json`, which threw\n * this signal away exactly where it was most useful: an agent retrying a\n * `runtime_undetermined` refusal picked from a nine-value menu on\n * self-knowledge alone, while the connector already knew which client configs\n * exist on the machine.\n *\n * Property 2 above is preserved verbatim and is the reason this returns a\n * HINT rather than a runtime: the caller still has to refuse. Finding exactly\n * one installed app tells you what exists, not where the user wants their\n * agent to run, and the cost of being wrong is an API key and a delegate key\n * written into an app they do not use.\n */\nexport interface InstalledClientHint {\n /** Runtime ids the scan found, likeliest first. */\n installedClients: readonly RuntimeId[]\n /**\n * The top hit, and only when it is unambiguously top — see\n * `installedClientHint`. A value an agent may echo back as `--runtime`;\n * never a selection the connector makes for it.\n */\n suggestedRuntime?: RuntimeId\n}\n\n/**\n * A suggestion is offered only when one candidate is CLEARLY first: a lone\n * candidate, or a single live MCP config file among bare client directories —\n * the one tier difference the scan treats as evidence. Candidates within a\n * tier are separated only by `SCAN_ORDER`, a fixed preference rather than a\n * fact about this machine, so suggesting the winner of that tiebreak would\n * dress an arbitrary choice as a finding.\n *\n * The suggestion is derived from the WHOLE array rather than from the first\n * two entries, so it does not depend on the caller having sorted anything.\n * This is exported, and an unsorted list reaching a positional rule would\n * yield a quietly wrong suggestion — never a selection, since only the caller\n * can act on it, but wrong is still wrong. `installedClients` preserves the\n * order it was given, which for `scanInstalledClients` is likeliest-first.\n */\nexport function installedClientHint(\n candidates: readonly InstalledClientCandidate[],\n): InstalledClientHint {\n const installedClients = candidates.map((candidate) => candidate.runtime)\n if (candidates.length === 1) {\n return { installedClients, suggestedRuntime: candidates[0].runtime }\n }\n const configured = candidates.filter((candidate) => candidate.evidence === 'config-file')\n return configured.length === 1\n ? { installedClients, suggestedRuntime: configured[0].runtime }\n : { installedClients }\n}\n\nexport interface PromptIo {\n write: (text: string) => void\n /** Resolves the typed line, or `null` on EOF / Ctrl-C. */\n question: (query: string) => Promise<string | null>\n}\n\n/** Bounded so a piped-but-TTY-looking stdin cannot spin forever. */\nconst MAX_PROMPT_ATTEMPTS = 3\n\nexport async function promptForInstalledClient(\n candidates: readonly InstalledClientCandidate[],\n io: PromptIo = defaultPromptIo(),\n): Promise<RuntimeId> {\n if (candidates.length === 0) throw noInstalledClientsError()\n io.write('Haven could not detect which agent runtime this is.\\n')\n io.write('These agent clients are installed on this machine:\\n')\n candidates.forEach((candidate, index) => {\n io.write(` ${index + 1}) ${candidate.label} — ${candidate.detail}\\n`)\n })\n io.write('Haven writes an API key and a signing key into the client you pick, so pick the one your agent actually runs in.\\n')\n\n for (let attempt = 0; attempt < MAX_PROMPT_ATTEMPTS; attempt += 1) {\n const answer = await io.question(`Which one? [1-${candidates.length}] (default 1 — ${candidates[0].label}): `)\n if (answer === null) throw promptAbortedError('the prompt was cancelled')\n const trimmed = answer.trim()\n // Empty ACCEPTS the pre-selected default. That is still a choice the user\n // made at the prompt — the scan itself never gets to select (property 2).\n if (trimmed === '') return candidates[0].runtime\n const picked = Number.parseInt(trimmed, 10)\n if (Number.isInteger(picked) && picked >= 1 && picked <= candidates.length) {\n return candidates[picked - 1].runtime\n }\n io.write(`\"${trimmed}\" is not one of 1-${candidates.length}.\\n`)\n }\n throw promptAbortedError(`no valid choice after ${MAX_PROMPT_ATTEMPTS} attempts`)\n}\n\n/**\n * The whole rung as one thunk: scan, refuse if nothing writable is installed,\n * otherwise prompt. This is what `resolveRuntimeSelection` calls, which is why\n * the registry needs no knowledge of the filesystem or of readline.\n */\nexport async function resolveRuntimeByInstalledClientPrompt(\n options: ScanInstalledClientsOptions & { io?: PromptIo } = {},\n): Promise<RuntimeId> {\n const candidates = await scanInstalledClients(options)\n if (candidates.length === 0) throw noInstalledClientsError()\n return promptForInstalledClient(candidates, options.io ?? defaultPromptIo())\n}\n\nfunction noInstalledClientsError(): ConnectError {\n return new ConnectError(\n 'runtime_no_installed_clients',\n 'Could not determine the agent runtime: nothing was detected in this environment, and no agent client Haven can configure is installed on this machine. ' +\n 'Re-run with --runtime <name> naming the client you want configured, or --runtime other to store credentials and finish the MCP setup by hand.',\n 'rerun_connect_with_explicit_runtime',\n )\n}\n\nfunction promptAbortedError(reason: string): ConnectError {\n return new ConnectError(\n 'runtime_prompt_aborted',\n `Runtime not chosen (${reason}). Nothing was written: no agent was created, no credentials were stored, and the Haven setup token is still unused. ` +\n 'Run the setup command again, or pass --runtime <name> to skip the prompt.',\n 'rerun_connect_and_choose_a_runtime',\n )\n}\n\nasync function pathExists(path: string): Promise<boolean> {\n try {\n await access(path)\n return true\n } catch {\n return false\n }\n}\n\nfunction defaultPromptIo(): PromptIo {\n return {\n write: (text) => process.stdout.write(text),\n question: (query) =>\n new Promise<string | null>((resolvePromise) => {\n const rl = createInterface({ input: process.stdin, output: process.stdout })\n let settled = false\n const settle = (value: string | null) => {\n if (settled) return\n settled = true\n rl.close()\n resolvePromise(value)\n }\n // Without an explicit SIGINT listener readline's Ctrl-C behaviour\n // depends on the host; with one, Ctrl-C is an abort we report as such\n // and exit non-zero from, having written nothing.\n rl.once('SIGINT', () => settle(null))\n rl.once('close', () => settle(null))\n rl.question(query, (answer) => settle(answer))\n }),\n }\n}\n","import { CONNECTOR_VERSION, type ConnectOptions } from './runtime.js'\nimport { assertValidServerSlug } from './server-names.js'\nimport { REKEY_FINISH_NEEDS_API_KEY } from './rekey-messages.js'\n\nexport interface ParsedCli {\n options: ConnectOptions\n help: boolean\n json: boolean\n /** #1589: diagnosis mode — no setup token required. */\n doctor: boolean\n repair: boolean\n /** #1681: retire an agent credential directory in place — no token required. */\n tombstone?: { directory: string; reason?: string; replacedBy?: string }\n /**\n * #2169: unwire one agent — tombstone it, then remove its MCP pair and\n * Hermes dotenv key from every runtime config. No token required; refuses\n * rather than guess when a bare pair is owned by a different agent.\n */\n unwire?: { reason?: string; replacedBy?: string }\n /** Optional positional value of --unwire <dir> (else --name / --credentials-dir resolve it). */\n unwireDir?: string\n /**\n * #1700: replace an agent's signing key on this machine. Two phases, because\n * the dashboard sits between them — `start` generates the key and prints its\n * address, `finish` writes the key the owner brings back. No setup token: the\n * re-key API is owner-authenticated and this connector never calls it.\n */\n rekey?: { phase: 'start' | 'finish'; newApiKey?: string }\n}\n\nexport function parseArgs(argv: string[], env: NodeJS.ProcessEnv = process.env): ParsedCli {\n const options: Partial<ConnectOptions> = {\n apiBaseUrl: env.HAVEN_API_URL ?? 'http://localhost:3001',\n connectorVersion: CONNECTOR_VERSION,\n }\n let help = false\n let json = false\n let doctor = false\n let repair = false\n let rekeyPhase: 'start' | 'finish' | undefined\n let newApiKey: string | undefined\n let tombstoneDir: string | undefined\n let tombstoneReason: string | undefined\n let tombstoneReplacedBy: string | undefined\n let unwire: { reason?: string; replacedBy?: string } | undefined\n let unwireDir: string | undefined\n\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i]\n if (arg === '--help' || arg === '-h') {\n help = true\n } else if (arg === '--json') {\n json = true\n } else if (arg === '--doctor') {\n doctor = true\n } else if (arg === '--repair') {\n repair = true\n } else if (arg === '--rekey') {\n rekeyPhase = 'start'\n } else if (arg === '--rekey-finish') {\n rekeyPhase = 'finish'\n } else if (arg === '--api-key') {\n newApiKey = requireValue(argv, ++i, arg)\n } else if (arg === '--tombstone') {\n tombstoneDir = requireValue(argv, ++i, arg)\n } else if (arg === '--unwire') {\n unwire = unwire ?? {}\n const next = argv[i + 1]\n // Optional positional form --unwire <dir>; a following flag (usually\n // --name or --credentials-dir) means the directory is resolved later.\n if (next !== undefined && !next.startsWith('--')) {\n unwireDir = next\n i += 1\n }\n } else if (arg === '--reason') {\n tombstoneReason = requireValue(argv, ++i, arg)\n } else if (arg === '--replaced-by') {\n tombstoneReplacedBy = requireValue(argv, ++i, arg)\n } else if (arg === '--setup' || arg === '--setup-token') {\n options.setupToken = requireValue(argv, ++i, arg)\n } else if (arg === '--api' || arg === '--api-url') {\n options.apiBaseUrl = requireValue(argv, ++i, arg)\n } else if (arg === '--runtime') {\n options.runtime = requireValue(argv, ++i, arg)\n } else if (arg === '--runtime-force') {\n options.runtimeForce = requireValue(argv, ++i, arg)\n } else if (arg === '--credentials-dir') {\n options.credentialsDir = requireValue(argv, ++i, arg)\n } else if (arg === '--name') {\n // Validated HERE, before any credential or config write can happen —\n // the slug is immutable once wired (#1694 owner decision), so a bad one\n // must die at the argument, not after files exist.\n options.serverName = requireValue(argv, ++i, arg)\n assertValidServerSlug(options.serverName)\n } else if (arg === '--environment-label') {\n options.environmentLabel = requireValue(argv, ++i, arg)\n } else if (arg === '--ack-local-tools') {\n options.ackLocalTools = true\n } else if (arg === '--ack-signer') {\n options.ackSigner = true\n options.ackLocalTools = true\n } else if (arg === '--local' || arg === '--local-mcp') {\n options.localMcp = true\n } else if (arg === '--version') {\n process.stdout.write(`${CONNECTOR_VERSION}\\n`)\n process.exit(0)\n } else {\n throw new Error(`Unknown option: ${arg}`)\n }\n }\n\n const tombstone = tombstoneDir\n ? { directory: tombstoneDir, reason: tombstoneReason, replacedBy: tombstoneReplacedBy }\n : undefined\n const rekey = rekeyPhase ? { phase: rekeyPhase, newApiKey } : undefined\n\n if (help) {\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey }\n }\n\n if (rekey) {\n // Re-key reuses STORED credentials, like --doctor: the whole point is that\n // the agent already exists here, so a setup token is exactly what it does\n // not need. It refuses the two ways a caller can mean something it cannot\n // do, rather than silently doing the other one.\n if (options.setupToken) {\n throw new Error('--rekey replaces an existing agent\\'s key; it does not take --setup. Drop one of them.')\n }\n if (rekey.phase === 'start' && newApiKey !== undefined) {\n throw new Error(\n '--api-key belongs to --rekey-finish. --rekey generates the new key here and prints the ' +\n 'address to paste into Haven; the API key does not exist yet.',\n )\n }\n if (rekey.phase === 'finish' && !newApiKey) {\n throw new Error(REKEY_FINISH_NEEDS_API_KEY)\n }\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey }\n }\n\n if (newApiKey !== undefined) {\n // Refuse rather than silently discard — the caller believed it did\n // something (the #1681 finding-2 rule, applied to the new flag).\n throw new Error('--api-key requires --rekey-finish.')\n }\n\n if (!tombstoneDir && !unwire && (tombstoneReason !== undefined || tombstoneReplacedBy !== undefined)) {\n // Refuse rather than silently discard — the caller believed these did\n // something. (#1681 review, finding 2)\n throw new Error('--reason and --replaced-by require --tombstone <dir> or --unwire.')\n }\n\n // --reason / --replaced-by ride whichever teardown mode is active.\n if (unwire && (tombstoneReason !== undefined || tombstoneReplacedBy !== undefined)) {\n unwire = {\n ...(tombstoneReason !== undefined ? { reason: tombstoneReason } : {}),\n ...(tombstoneReplacedBy !== undefined ? { replacedBy: tombstoneReplacedBy } : {}),\n ...unwire,\n }\n }\n\n if (tombstone) {\n if (unwire) {\n throw new Error('--unwire and --tombstone are separate operations; run one per invocation.')\n }\n // Retirement reuses STORED state, like --doctor — no token, no runtime.\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey, unwire, unwireDir }\n }\n\n if (unwire) {\n // Unwire reuses STORED state, like --doctor — no token, no runtime.\n if (options.setupToken) {\n throw new Error('--unwire removes existing wiring; it does not take --setup. Drop --setup.')\n }\n if (!unwireDir && !options.serverName && !options.credentialsDir) {\n throw new Error('--unwire needs a target: --unwire <dir>, --unwire --name <slug>, or --unwire --credentials-dir <path>.')\n }\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey, unwire, unwireDir }\n }\n\n if (doctor || repair) {\n // Diagnosis/repair reuse STORED credentials — a setup token is exactly\n // what they exist to avoid needing.\n if (!options.runtime) {\n throw new Error('--doctor/--repair need --runtime <runtime> (which config to examine).')\n }\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey }\n }\n\n if (!options.setupToken) {\n throw new Error('Missing --setup <hv_setup_...> setup token.')\n }\n if (!options.apiBaseUrl) {\n throw new Error('Missing --api <Haven API URL>.')\n }\n\n options.apiBaseUrl = options.apiBaseUrl.replace(/\\/+$/, '')\n return { options: options as ConnectOptions, help, json, doctor, repair, tombstone, rekey }\n}\n\nexport function helpText(): string {\n return [\n 'Haven Connect Agent 2 local connector',\n '',\n 'Generates the agent signing key locally, stores it on this machine, and',\n 'sends Haven only the public signing address plus a proof signature.',\n '',\n 'Usage:',\n ' npx -y @haven_ai/connect --setup hv_setup_... --api https://api.haven.example --ack-local-tools',\n '',\n 'Options:',\n ' --setup <token> Short-lived setup token from Haven.',\n ' --api <url> Haven backend API URL. Defaults to HAVEN_API_URL or http://localhost:3001.',\n ' --runtime <name> Agent runtime hint, such as claude-code, codex-cli, codex-desktop, cursor, vscode, claude-desktop, or hermes.',\n ' Usually unnecessary: the connector detects the runtime it runs inside, and a detection',\n ' that contradicts this hint wins (with a printed notice). When nothing is detected, an',\n ' interactive terminal is offered the agent clients installed on this machine; this flag is',\n ' how an agent, or a non-interactive run, answers instead. An unknown name is refused, never guessed.',\n ' --runtime-force <name> Escape hatch: use exactly this runtime, ignoring environment detection.',\n ' --credentials-dir <path> Credential directory fallback. Defaults to ~/.haven/agents.',\n ' --environment-label <text> Non-sensitive label shown in Haven setup review.',\n ' --name <slug> Wiring slug for a NAMED agent: writes haven-<slug> / haven-signer-<slug>',\n ' MCP entries and stores credentials at ~/.haven/agents/<slug>/, so several',\n ' agents can run side by side in one runtime. 1-32 lowercase letters, digits,',\n ' single hyphens; immutable once wired. Omit for the bare haven / haven-signer pair.',\n ' --ack-local-tools Write the one-time local Haven tools acknowledgement during setup.',\n ' --ack-signer Backward-compatible alias for --ack-local-tools.',\n ' --local Advanced: install the fully-local Haven MCP (no hosted dependency).',\n ' Only available for Claude Code and Codex. Default is hosted MCP + local signer.',\n ' --json Emit one versioned, secret-free result object on stdout; progress stays on stderr.',\n ' --doctor Diagnose an existing setup (read-only, no token): config, credentials,',\n ' signer runtime, hosted MCP, and a live signer handshake. Exits non-zero on any failure.',\n ' --repair Repair, then re-diagnose (implies --doctor): reinstall the pinned signer',\n ' runtime, rewrite the wrapper and runtime config from stored credentials.',\n ' Hosted topology only (refuses to touch a --local config). No keys, no token.',\n ' --rekey Replace this agent\\'s signing key (no token). Generates a fresh keypair HERE and',\n ' prints its public address to paste into the Haven agent page. Nothing changes',\n ' until you finish; the agent keeps working on its old key throughout.',\n ' Add --name <slug> for a named agent. Refuses a legacy-rail or revoked agent.',\n ' --rekey-finish Second half of --rekey: writes the new key and the API key the agent page',\n ' showed once, in place at the same path, and rewrites only this agent\\'s MCP',\n ' config pair. Server names do not change, so wired hosts need only a restart.',\n ' --api-key <key> The new API key, for --rekey-finish.',\n ' --tombstone <dir> Retire an agent credential directory in place (no token): replaces its signer',\n ' wrapper with a diagnostic that names the retirement in MCP stderr logs, and',\n ' writes TOMBSTONE.json. Touches NO key material and revokes nothing.',\n ' --unwire [<dir>] Remove one agent\\u2019s wiring from every runtime config it appears in (no token):',\n ' tombstone-first, then drops the hosted + signer MCP pair from Hermes YAML, Codex',\n ' TOML and the JSON configs (Cursor, VS Code, Insiders, Claude Desktop), plus the',\n ' Hermes dotenv API-key line (MCP_HAVEN_API_KEY / MCP_HAVEN_<SLUG>_API_KEY).',\n ' Target the directory directly, or add --name <slug> or --credentials-dir.',\n ' An UNNAMED pair is only removed when this directory\\u2019s wrapper is the one the',\n ' config launches (or its key is the one the Hermes env holds); otherwise the',\n ' command refuses rather than unwire a different agent — it never touches a',\n ' pair another agent owns. Tears down the target directory: its signer key and',\n ' API key are removed locally (record kept via the #2155 tombstone mirror) and',\n ' nothing is ever revoked on the backend — that stays an owner action on the',\n ' Haven agent page.',\n ' --reason <text> Reason recorded in the tombstone (with --tombstone or --unwire).',\n ' --replaced-by <agent-id> Successor agent recorded in the tombstone (with --tombstone or --unwire).',\n ' --help Show this help.',\n '',\n 'The connector never prints the private key and never sends it to Haven. JSON output never includes credential contents or full credential paths.',\n ].join('\\n')\n}\n\nfunction requireValue(argv: string[], index: number, option: string): string {\n const value = argv[index]\n if (!value || value.startsWith('--')) {\n throw new Error(`Missing value for ${option}.`)\n }\n return value\n}\n","#!/usr/bin/env node\n\nimport { realpathSync } from 'node:fs'\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { helpText, parseArgs } from './args.js'\nimport { failedConnectOutcome, failureOutcomeFor, runConnect } from './runtime.js'\nimport { redactForAutomation, redactSecrets } from './redact.js'\nimport { isConnectError } from './connect-error.js'\n\nexport interface CliIo {\n stdout: (message: string) => void\n stderr: (message: string) => void\n}\n\n/**\n * Report a subcommand failure on BOTH channels (#2184).\n *\n * Every subcommand but the main connect run used to write its failure to\n * stderr alone and leave stdout empty. To a `--json` caller parsing stdout\n * that is indistinguishable from a stream it stopped reading — which is\n * exactly how a field `haven-reset` reported \"the tombstone command did not\n * create TOMBSTONE.json\" with no error to show for it (#2175). One helper, so\n * the next subcommand inherits the behaviour instead of re-deciding it.\n *\n * `envelope` carries the branch's own success discriminant inverted\n * (`{ unwired: false }`, `{ rekey: 'failed' }`), so a failure record can never\n * be mistaken for a success payload — this matters most for `--doctor`, whose\n * success output IS a JSON report.\n *\n * `message` rides along ONLY for a connector-authored `ConnectError`, the same\n * gate `failedConnectOutcome` applies. A bare `Error` here is an unguarded\n * failure whose raw text can carry agent ids, local paths, or arbitrary OS\n * detail (`rekey.ts` throws several such); that text reaches stderr, where it\n * always did, and never the machine channel.\n */\nfunction failSubcommand(\n io: CliIo,\n json: boolean,\n err: unknown,\n envelope: Record<string, unknown>,\n fallback: { code: string; nextAction: string },\n): number {\n const message = err instanceof Error ? err.message : String(err)\n io.stderr(`${redactSecrets(message)}\\n`)\n if (json) {\n io.stdout(\n `${redactSecrets(\n JSON.stringify({\n ...envelope,\n error: {\n code: isConnectError(err) ? err.code : fallback.code,\n next_action: isConnectError(err) ? err.nextAction : fallback.nextAction,\n ...(isConnectError(err) && message ? { message } : {}),\n },\n }),\n )}\\n`,\n )\n }\n return 1\n}\n\nexport async function runCli(\n argv: string[],\n io: CliIo = {\n stdout: (message) => process.stdout.write(message),\n stderr: (message) => process.stderr.write(message),\n },\n): Promise<number> {\n const wantsJson = argv.includes('--json')\n let parsed\n try {\n parsed = parseArgs(argv)\n } catch (err) {\n if (wantsJson) {\n // #2091: same stderr mirror as the run-failure path below.\n io.stderr(`${redactForAutomation(err instanceof Error ? err.message : String(err))}\\n`)\n io.stdout(`${JSON.stringify(failedConnectOutcome(undefined, err))}\\n`)\n } else {\n io.stderr(`${redactSecrets(err instanceof Error ? err.message : String(err))}\\n`)\n }\n return 1\n }\n if (parsed.help) {\n io.stdout(`${helpText()}\\n`)\n return 0\n }\n if (parsed.tombstone) {\n // #1681: retire a credential directory in place. Reads the stored\n // identity for the agent id, replaces the wrapper with a truth-telling\n // tombstone, touches NO key material, and tells the user what the\n // tombstone cannot do for them: restart every long-lived host.\n const { writeAgentTombstone } = await import('./tombstone.js')\n const { readFile } = await import('node:fs/promises')\n const { join } = await import('node:path')\n try {\n let agentId = 'unknown'\n try {\n const identity = JSON.parse(\n await readFile(join(parsed.tombstone.directory, 'identity.json'), 'utf8'),\n ) as { agent_id?: string }\n agentId = identity.agent_id ?? 'unknown'\n } catch {\n // A directory whose identity no longer parses can still be retired —\n // the tombstone then names it as unknown, which is honest.\n }\n const info = await writeAgentTombstone({\n directory: parsed.tombstone.directory,\n agentId,\n reason: parsed.tombstone.reason ?? 'retired by operator via --tombstone',\n replacedBy: parsed.tombstone.replacedBy,\n })\n if (parsed.json) {\n io.stdout(`${redactSecrets(JSON.stringify({ tombstoned: true, ...info }))}\\n`)\n } else {\n io.stdout(redactSecrets(`Tombstoned agent ${info.agent_id} at ${parsed.tombstone.directory}.\\n`))\n io.stdout(\n 'Key files were NOT touched and nothing was revoked — revoke the agent on the Haven ' +\n 'agent page if you have not already.\\n',\n )\n io.stdout(\n `A surviving tombstone record was mirrored to ${redactSecrets(info.recordPath)}\\n`,\n )\n io.stdout(\n 'Restart EVERY long-lived MCP host (gateway, TUI workers, editors): each holds the ' +\n 'wiring snapshot from its own start time, and the tombstone only speaks when a stale ' +\n 'host next probes the old path. The mirrored record keeps this retirement observable ' +\n 'even after the agent directory itself is deleted.\\n',\n )\n }\n return 0\n } catch (err) {\n // #2175 introduced this record; #2184 moved it into `failSubcommand` so\n // the three sibling subcommands share it rather than each re-deciding.\n return failSubcommand(io, parsed.json, err, { tombstoned: false }, {\n code: 'tombstone_failed',\n nextAction: 'review_the_error_and_retry_with_a_valid_agent_directory',\n })\n }\n }\n if (parsed.unwire) {\n // #2169: tombstone-first removal of ONE agent's wiring from every runtime\n // config it appears in + the Hermes dotenv key. Refuses — never guesses —\n // when the bare pair is provably another agent's.\n const { unwireAgent } = await import('./unwire.js')\n const { homedir } = await import('node:os')\n const { join } = await import('node:path')\n const homeDir = homedir()\n const root = parsed.options.credentialsDir ?? join(homeDir, '.haven', 'agents')\n const directory =\n parsed.unwireDir ?? (parsed.options.serverName ? join(root, parsed.options.serverName) : root)\n try {\n const result = await unwireAgent({\n directory,\n slug: parsed.options.serverName,\n reason: parsed.unwire.reason,\n replacedBy: parsed.unwire.replacedBy,\n homeDir,\n })\n const failures = result.runtimes.filter((r) => r.status === 'refused' || r.status === 'unreadable')\n if (parsed.json) {\n io.stdout(\n `${redactSecrets(\n JSON.stringify({\n unwired: true,\n agent_id: result.agentId,\n slug: result.slug ?? null,\n directory: result.directory,\n tombstoned: result.tombstoned,\n runtimes: result.runtimes.map((r) => ({\n runtime: r.runtime,\n label: r.label,\n status: r.status,\n ...(r.detail ? { detail: r.detail } : {}),\n })),\n }),\n )}\\n`,\n )\n } else {\n io.stdout(redactSecrets(`Unwired agent ${result.agentId} at ${result.directory}.\\n`))\n io.stdout(\n result.tombstoned\n ? ' · Tombstoned first: any long-lived host still resolving the old wrapper gets the HAVEN-TOMBSTONE diagnosis.\\n'\n : ' · Directory was already tombstoned.\\n',\n )\n for (const r of result.runtimes) {\n const mark = r.status === 'removed' ? '✓' : r.status === 'clean' ? '–' : '✗'\n io.stdout(redactSecrets(` ${mark} ${r.label}: ${r.status}${r.detail ? ` — ${r.detail}` : ''}\\n`))\n }\n io.stdout(\n failures.length > 0\n ? ' Some entries were NOT removed (✗ above). Re-run `--unwire` after resolving each refusal —\\n' +\n ' it is idempotent.\\n'\n : ' Verify: `--doctor --runtime <runtime>` per host should report this agent as `retired` with a\\n' +\n ' clean runtime-config check.\\n',\n )\n io.stdout(\n 'Restart EVERY long-lived MCP host (gateway, TUI workers, editors): each holds the wiring snapshot\\n' +\n 'from its own start time. This directory\\u2019s local key material was removed and the tombstone\\n' +\n 'record + #2155 mirror survive — but nothing was REVOKED on the backend. If you have not\\n' +\n 'already, revoke the agent on the Haven agent page to stop it spending entirely.\\n',\n )\n }\n return failures.length > 0 ? 1 : 0\n } catch (err) {\n return failSubcommand(io, parsed.json, err, { unwired: false }, {\n code: 'unwire_failed',\n nextAction: 'review_the_error_and_rerun_unwire_which_is_idempotent',\n })\n }\n }\n if (parsed.rekey) {\n // #1700: replace an agent's signing key on this machine. Two phases with\n // the owner's dashboard between them — this connector never calls the\n // re-key API, which is owner-authenticated by design.\n const { startRekey, finishRekey } = await import('./rekey.js')\n const { restartGuidance } = await import('./rekey-restart.js')\n const common = {\n serverName: parsed.options.serverName,\n credentialsDir: parsed.options.credentialsDir,\n runtime: parsed.options.runtime,\n }\n try {\n if (parsed.rekey.phase === 'start') {\n const result = await startRekey(common)\n if (parsed.json) {\n // The address is public; the private half never appears here or\n // anywhere else this process writes to a stream.\n io.stdout(\n `${redactSecrets(\n JSON.stringify({\n rekey: 'started',\n agent_id: result.agentId,\n new_delegate_address: result.newDelegateAddress,\n expires_at: result.expiresAt,\n }),\n )}\\n`,\n )\n } else {\n for (const line of result.messages) io.stdout(redactSecrets(`${line}\\n`))\n }\n return 0\n }\n\n const result = await finishRekey({ ...common, newApiKey: parsed.rekey.newApiKey })\n const restart = restartGuidance(parsed.options.runtime)\n if (parsed.json) {\n io.stdout(\n `${redactSecrets(\n JSON.stringify({\n rekey: 'finished',\n agent_id: result.agentId,\n new_delegate_address: result.newDelegateAddress,\n mcp_servers: result.serverNames,\n restart_commands: restart.commands,\n }),\n )}\\n`,\n )\n } else {\n for (const line of result.messages) io.stdout(redactSecrets(`${line}\\n`))\n io.stdout('\\n')\n for (const line of restart.lines) io.stdout(redactSecrets(`${line}\\n`))\n }\n return 0\n } catch (err) {\n return failSubcommand(io, parsed.json, err, { rekey: 'failed' }, {\n code: 'rekey_failed',\n nextAction: 'review_the_error_and_rerun_the_rekey_phase',\n })\n }\n }\n if (parsed.doctor || parsed.repair) {\n const { runDoctor, runRepair } = await import('./doctor.js')\n const runtime = parsed.options.runtime ?? ''\n const credentialsDir = parsed.options.credentialsDir\n try {\n if (parsed.repair) {\n const repair = await runRepair({ runtime, credentialsDir })\n for (const message of repair.messages) io.stderr(`${redactSecrets(message)}\\n`)\n if (!repair.ok) return 1\n }\n const report = await runDoctor({ runtime, credentialsDir })\n // Defensively redacted like every other output path — the report is\n // secret-free by construction, but signerCapabilities is untrusted\n // process output and belts are cheap (#1589 review).\n if (parsed.json) {\n io.stdout(`${redactSecrets(JSON.stringify(report))}\\n`)\n } else {\n for (const check of report.checks) {\n io.stdout(redactSecrets(`${check.ok ? '✓' : '✗'} ${check.label}: ${check.detail}\\n`))\n if (check.repair) io.stdout(redactSecrets(` ↳ repair: ${check.repair}\\n`))\n }\n // #1697: the other agents on this machine. The flat list above\n // describes ONE agent; multi-agent means the rest still have to be\n // accounted for, by name and by verdict, never silently dropped.\n const otherAgents = report.agents.filter((agent) => agent.directory !== report.credentialDirectory)\n if (otherAgents.length > 0) {\n io.stdout('\\nOther agents on this machine:\\n')\n for (const agent of otherAgents) {\n const name = agent.slug ? `${agent.slug} (${agent.agentId ?? 'unknown'})` : agent.agentId ?? 'unknown'\n const failed = agent.checks.filter((check) => !check.ok)\n const verdict = agent.classification === 'wired'\n ? failed.length === 0 ? 'wired, all checks passed' : `wired, ${failed.length} check(s) FAILED`\n // #1915: `parked` is the one classification whose bare name says\n // nothing a reader can act on — it is not a broken agent, it is\n // a directory with no agent in it and a private key still in it.\n // Spell that out here; the path and state are on the parked\n // re-key check above.\n : agent.classification === 'parked'\n ? 'parked re-key only — no identity.json in this directory, but key material is still there'\n : agent.classification\n io.stdout(redactSecrets(` ${failed.length > 0 ? '✗' : '•'} ${name}: ${verdict}\\n`))\n for (const check of failed) {\n io.stdout(redactSecrets(` ✗ ${check.label}: ${check.detail}\\n`))\n if (check.repair) io.stdout(redactSecrets(` ↳ repair: ${check.repair}\\n`))\n }\n }\n }\n io.stdout(report.ok ? 'All checks passed.\\n' : 'One or more checks FAILED — see repairs above.\\n')\n }\n return report.ok ? 0 : 1\n } catch (err) {\n return failSubcommand(io, parsed.json, err, { doctor: 'failed' }, {\n code: 'doctor_failed',\n nextAction: 'review_the_error_and_rerun_doctor',\n })\n }\n }\n try {\n // --json is the automation contract: emit the outcome promptly instead of\n // blocking up to the approval-wait bound (#1377 D).\n const result = await runConnect(\n {\n ...parsed.options,\n waitForApproval: !parsed.json,\n // #1719: only a human-facing run may be asked which installed client to\n // configure. --json is the automation contract — it must fail with a\n // machine-readable code, never block on stdin. runConnect additionally\n // requires a real TTY before it prompts.\n interactive: !parsed.json,\n },\n {\n log: (message) => (parsed.json ? io.stderr : io.stdout)(`${message}\\n`),\n redactPaths: parsed.json,\n },\n )\n if (parsed.json) io.stdout(`${JSON.stringify(result.outcome)}\\n`)\n return 0\n } catch (err) {\n if (parsed.json) {\n // #2091: mirror the redacted message to stderr as well — stdout stays\n // pure JSON for the automation contract, but the prose channel must\n // never be silently discarded (progress lines already go to stderr in\n // --json mode; the failure that ends the run belongs there too). Same\n // redaction bar as those progress lines and the JSON message field:\n // redactForAutomation, which also masks credential-file paths.\n io.stderr(`${redactForAutomation(err instanceof Error ? err.message : String(err))}\\n`)\n // #2173: the run's OWN record when it built one, so the object printed\n // here is byte-identical to the one persisted to `last-connect-outcome.json`.\n // Re-deriving it from the raw `--runtime` hint would report the hint,\n // not the runtime detection actually resolved (#1672).\n io.stdout(`${JSON.stringify(failureOutcomeFor(parsed.options.runtime, err))}\\n`)\n } else {\n io.stderr(`${redactSecrets(err instanceof Error ? err.message : String(err))}\\n`)\n }\n return 1\n }\n}\n\nasync function main(): Promise<void> {\n const exitCode = await runCli(process.argv.slice(2))\n if (exitCode !== 0) process.exitCode = exitCode\n}\n\n/**\n * npm executes package bins through a `node_modules/.bin` symlink. Node keeps\n * that symlink in `process.argv[1]`, whereas `import.meta.url` identifies the\n * real module path. Resolve both sides before comparing so a published\n * `haven-connect` bin starts, while an ordinary `runCli` import remains inert.\n */\nexport function isCliEntrypoint(\n argvPath: string | undefined = process.argv[1],\n moduleUrl: string = import.meta.url,\n): boolean {\n if (!argvPath) return false\n try {\n return realpathSync(argvPath) === realpathSync(fileURLToPath(moduleUrl))\n } catch {\n // Keep the direct-file behavior when a loader provides an unresolvable\n // path. A missing path cannot be a safe reason to run imported CLI code.\n return pathToFileURL(argvPath).href === moduleUrl\n }\n}\n\nif (isCliEntrypoint()) void main()\n"]}