import { type HealthProbe } from "./launchd.js"; export type Profile = "solo" | "team" | "ci"; export declare const VALID_PROFILES: readonly Profile[]; export interface ProfileConfig { transport: string; feature_bundles: string[]; tool_visibility: { hidden: string[]; }; logging_level: string; agent_abandon_days: number; dashboard_enabled: boolean; } export declare function applyProfileDefaults(profile: Profile): ProfileConfig; /** * Module URL → repo root, via fileURLToPath. The previous form — * `new URL(import.meta.url).pathname` — returns a PERCENT-ENCODED path, so an * install living under a directory with a space wrote * `.../Claude%20AI/.../dist/index.js` into ~/.claude.json: a path that does * not exist, i.e. a config entry that silently kills every relay session * spawned from it (the "%20 fossil" chased across nine days, 2026-07-23). * Exported for the decoding regression in tests/user-config-write-guard.test.ts. */ export declare function moduleRootFromUrl(moduleUrl: string): string; /** v2.16.0 — deep-merge the bot-relay stdio mcpServers entry into ~/.claude.json. */ export declare function installMcpServer(distEntry: string, jsonPath?: string): { changed: boolean; }; /** v2.16.0 — deep-merge the SessionStart hook into ~/.claude/settings.json. * v2.23.0 (codex #139): QUOTE the command (quoteForHookCommand) so a spaced * install root yields an unambiguous, precisely-ownable hook — and MIGRATE a * prior RAW (unquoted) literal of this exact root to the quoted form, so the * ambiguous shape drains out of the installed base instead of being carried * forever. Migration is exact-literal, never a classifier (see config-merge). */ export declare function installHook(hookScript: string, settingsPath?: string): { changed: boolean; }; /** * Probe :port/health, DISCRIMINATING "unreachable" (fetch rejects with an * unambiguous ECONNREFUSED → the port is genuinely free) from * "reachable-but-unreadable" (a response came back but the body is empty / * non-JSON, the status is non-2xx, a 3xx, or the body stalls). Exported so the * fail-closed behavior is tested through the REAL `res.json()` adapter — the * harm lives in the adapter, not a stub. * * FAIL CLOSED by ENUMERATING SUCCESS (audit HIGH #3): "the port is free" is a * POSITIVE determination (ECONNREFUSED alone), never the default for "anything * went wrong." Everything else — a 3xx (redirect:"manual", not followed to a * dead target and misread as free), a reset, a timeout/abort, a DNS failure, an * unknown error — is reachable:true → unreadable → refuse. * * The abort timer spans BOTH `fetch` AND `res.json()` in ONE try/finally (codex * round-4 P1: clearing it after fetch left the body read unbounded, so a server * that sends headers then STALLS its body hung init forever). An abort mid-body * rejects res.json() → parseable:false → unreadable. * * CROSS-PLATFORM verification (stated precisely): the claim "Node normalizes the * OS connection-refused error to code 'ECONNREFUSED' (incl. Windows * WSAECONNREFUSED)" is from Node docs. These probeHealth tests EXECUTE on Linux * Node 20 + 22 in CI (the matrix runs the full suite) and on Node 24.13.0 via * codex; macOS is local-only (the CI macOS job is scoped to the launchd guard, * not the full suite). WINDOWS IS NOT EXECUTED ANYWHERE — there is no Windows * runner in .github/workflows — that is the one OPEN gap. ACCEPTED fails-closed * residuals (all → refuse, the safe direction): a loopback firewall that DROPs * instead of REJECTs (no RST → runs to the abort deadline), EACCES, * EADDRNOTAVAIL — if loopback itself is broken, refusing to install is correct. */ export declare function probeHealth(port: number): Promise; export declare function run(argv: string[], rootOverride?: string): Promise; //# sourceMappingURL=init.d.ts.map