@bman654/clodex 2.1.1 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -10
- package/dist/{chunk-QLGIKUKC.js → chunk-OVO6OUZG.js} +409 -280
- package/dist/chunk-OVO6OUZG.js.map +1 -0
- package/dist/claude-wrapper.js +18 -20
- package/dist/claude-wrapper.js.map +1 -1
- package/dist/cli.js +1838 -398
- package/dist/cli.js.map +1 -1
- package/docs/background-agents.md +7 -2
- package/docs/credential-helpers.md +76 -0
- package/package.json +1 -1
- package/dist/chunk-QLGIKUKC.js.map +0 -1
|
@@ -6,7 +6,7 @@ This page explains how to bridge **every** Claude Code process on your machine
|
|
|
6
6
|
|
|
7
7
|
- One global **`clodex server --proxy`** runs in the background (proxy mode is the recommended mode for this setup: your existing Anthropic login keeps working, and only `clodex:` models / aliases are rerouted to OpenAI).
|
|
8
8
|
- On startup the server adds its own record to `~/.clodex/server-runtime.json` (`mode`, `port`, `pid`, and in proxy mode the CA certificate path). The file holds one record per running server — several `clodex server` instances (say a proxy server for Claude Code plus a separate endpoint server for another tool) can be advertised at once — and each server removes only its own record on shutdown. Start a server with `--no-discovery` (or `CLODEX_NO_DISCOVERY=1`) to keep it out of the file entirely so `clodex-claude` never bridges to it.
|
|
9
|
-
- The **`clodex-claude`** bin (installed alongside `clodex`) reads that file,
|
|
9
|
+
- The **`clodex-claude`** bin (installed alongside `clodex`) reads that file, filters for live pids, and runs one fast TCP probe across all ordered candidates. It picks the highest-priority candidate that answers — proxy-mode servers are preferred over endpoint-mode (bridging keeps Claude Code's own auth), newest first within a mode. When none answers, only timed-out probes retry under one shared 500 ms deadline; definitive connection errors fail immediately. It then launches the real `claude` binary with the right env injected:
|
|
10
10
|
- proxy-mode server: `HTTPS_PROXY`/`HTTP_PROXY` + `NODE_EXTRA_CA_CERTS`, with `ANTHROPIC_BASE_URL` removed;
|
|
11
11
|
- endpoint-mode server: `ANTHROPIC_BASE_URL` pointing at the gateway;
|
|
12
12
|
- **no live server: env untouched** — `claude` always launches normally, a stopped server never breaks anything.
|
|
@@ -66,6 +66,8 @@ This page explains how to bridge **every** Claude Code process on your machine
|
|
|
66
66
|
> exec "$NODE" "$(npm root -g)/@bman654/clodex/dist/claude-wrapper.js" "$@"
|
|
67
67
|
> ```
|
|
68
68
|
>
|
|
69
|
+
> **Keep the `exec`.** Without it the shell survives as claude's parent and keeps the process group Claude Code created for it. Claude Code addresses that group when it tells a background session its terminal was resized, so agent sessions would render at a fixed size and corrupt on resize. The wrapper execs into claude for the same reason.
|
|
70
|
+
>
|
|
69
71
|
> Replace the `NODE=` line with your manager's stable path — nvm: `"$NVM_DIR/alias/default"` names the version, so use `"$NVM_DIR/versions/node/$(cat "$NVM_DIR/alias/default")/bin/node"`; volta: `"$HOME/.volta/bin/node"`; asdf: `"$(asdf which node)"` captured once. Hardcode the resolved `npm root -g` path if you prefer not to shell out. Verify the result works even with no PATH:
|
|
70
72
|
>
|
|
71
73
|
> ```bash
|
|
@@ -85,7 +87,10 @@ Port and CA discovery are automatic via `~/.clodex/server-runtime.json` — do n
|
|
|
85
87
|
|
|
86
88
|
For service-manager readiness checks, `clodex-claude --check` exits `0` when an
|
|
87
89
|
advertised server passes the process and TCP checks, and exits `1` otherwise.
|
|
88
|
-
|
|
90
|
+
Servers advertise themselves only after their listener has passed readiness.
|
|
91
|
+
The wrapper retry protects against a timed-out loopback probe, not a
|
|
92
|
+
registration-before-listen delay.
|
|
93
|
+
The check does not launch Claude.
|
|
89
94
|
|
|
90
95
|
## Troubleshooting
|
|
91
96
|
|
|
@@ -59,6 +59,82 @@ credential instances. It rejects symbolic links, foreign ownership, broad
|
|
|
59
59
|
permissions on POSIX, files over 1 MiB, and more than 1,024 queued entries
|
|
60
60
|
before attempting any credential-store deletion.
|
|
61
61
|
|
|
62
|
+
## OS keyring layout and compatibility
|
|
63
|
+
|
|
64
|
+
The default OS credential-store backend uses five service namespaces:
|
|
65
|
+
|
|
66
|
+
- `clodex` stores a short credential directly or publishes the marker for a
|
|
67
|
+
long credential;
|
|
68
|
+
- `clodex-chunks` stores the chunks for current long credentials;
|
|
69
|
+
- `clodex-journal` records crash recovery, the active chunk generation, and a
|
|
70
|
+
deletion marker;
|
|
71
|
+
- `clodex-deleted` stores a redundant non-secret deletion guard;
|
|
72
|
+
- `clodex-state-key` stores a random per-account key that protects the
|
|
73
|
+
filesystem recovery marker.
|
|
74
|
+
|
|
75
|
+
Clodex also keeps an authenticated encrypted per-account managed-state marker
|
|
76
|
+
under the native OS account home at `~/.clodex/keyring-state`. Before each
|
|
77
|
+
cleanup-journal write, the marker records the exact journal intent. A retry
|
|
78
|
+
decrypts, republishes, and verifies that intent before continuing, then marks
|
|
79
|
+
it managed. The encryption key remains only in the OS credential store, so a
|
|
80
|
+
copied filesystem marker does not expose credentials or an offline credential
|
|
81
|
+
confirmation value. If the OS keyring temporarily reports a managed journal as
|
|
82
|
+
absent, the marker makes reads, writes, and deletes fail closed instead of
|
|
83
|
+
replacing unknown chunk inventory. Malformed or unauthenticated local intent
|
|
84
|
+
also remains fail-closed.
|
|
85
|
+
|
|
86
|
+
If the filesystem marker outlives a complete OS credential-store reset,
|
|
87
|
+
Clodex allows direct reauthorization only after sentinel-backed service
|
|
88
|
+
enumeration proves that the main credential and chunk namespaces are empty.
|
|
89
|
+
The recovery first records durable deleted state, then follows the normal
|
|
90
|
+
journal-before-publication path for the replacement. A hidden, locked,
|
|
91
|
+
incomplete, or partially restored namespace cannot take this path and remains
|
|
92
|
+
fail-closed.
|
|
93
|
+
|
|
94
|
+
Credential mutation locks live beside that state under
|
|
95
|
+
`~/.clodex/credential-locks`. Neither path depends on `CLODEX_HOME`,
|
|
96
|
+
`XDG_RUNTIME_DIR`, or temporary-directory environment variables because the OS
|
|
97
|
+
keyring service and account namespaces are shared across those process-local
|
|
98
|
+
settings. The native account-home filesystem must support hard links so lock
|
|
99
|
+
publication remains atomic.
|
|
100
|
+
|
|
101
|
+
New provider credentials use a stable, versioned account instance owned by the
|
|
102
|
+
provider slot and selected credential backend. A retry derives the same
|
|
103
|
+
candidate, so an ambiguous result cannot make its reference unreachable.
|
|
104
|
+
Provisioning resumes well-formed candidate state, while unavailable or
|
|
105
|
+
malformed recovery metadata remains fail-closed. Refresh paths replace the
|
|
106
|
+
registry's current account only when its prior keyring state can be confirmed.
|
|
107
|
+
Reauthorization provisions the selected backend first, then updates the
|
|
108
|
+
registry after read-back verification. If the keyring hides both the main value
|
|
109
|
+
and its metadata, replacement and deletion stop without publishing new state
|
|
110
|
+
or reporting success.
|
|
111
|
+
|
|
112
|
+
The active-generation journal is live metadata, not stale debris. Clodex keeps
|
|
113
|
+
one generation after a successful long-credential write so a later release can
|
|
114
|
+
retire the chunks through a current provider-removal operation if an older
|
|
115
|
+
release removes or replaces only the main marker. Use the Clodex
|
|
116
|
+
provider-removal path instead of deleting one of these entries manually.
|
|
117
|
+
|
|
118
|
+
Long chunked credentials are not readable by older releases that do not
|
|
119
|
+
understand their marker format. If a downgrade removes the main marker while
|
|
120
|
+
leaving chunks behind, passive resolution preserves the recorded inventory
|
|
121
|
+
because a missing keyring value cannot be distinguished from a collapsed read
|
|
122
|
+
error on every platform. Remove the provider with a current Clodex release
|
|
123
|
+
before reauthorizing to retire the orphaned generation. A published marker that
|
|
124
|
+
does not match its recovery journal fails closed and leaves every recorded
|
|
125
|
+
generation intact.
|
|
126
|
+
|
|
127
|
+
Clodex does not implicitly import credentials from the legacy `relay-ai`
|
|
128
|
+
service. Existing legacy entries remain untouched. Reauthorize or explicitly
|
|
129
|
+
save the provider credential to publish it under the `clodex` service, verify
|
|
130
|
+
the new credential, and remove the old entry separately if it is no longer
|
|
131
|
+
needed. Provider removal deletes only the Clodex credential. Redundant
|
|
132
|
+
non-secret deletion guards keep ambiguous deleted state from becoming readable;
|
|
133
|
+
an explicit later credential save clears those guards. Unknown JSON-shaped
|
|
134
|
+
values in non-OAuth keyring and helper accounts remain opaque. Historical
|
|
135
|
+
`wellknown` token and OAuth access envelopes retain their existing decoding
|
|
136
|
+
behavior, while structured OAuth validation applies only to OAuth accounts.
|
|
137
|
+
|
|
62
138
|
## Protocol
|
|
63
139
|
|
|
64
140
|
The helper receives one of these invocations:
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server-runtime.ts","../src/paths.ts","../src/wrapper-env.ts","../src/config.ts","../src/registry/io.ts","../src/registry/types.ts","../src/registry/lock.ts","../src/registry/migrate.ts","../src/registry/validate.ts","../src/launch.ts","../src/binary-lookup.ts"],"sourcesContent":["// src/server-runtime.ts\n//\n// Runtime-state advertisement for the standalone `clodex server` command.\n// Each registering server ADDS its own record (keyed by pid) to\n// ~/.clodex/server-runtime.json on startup and removes ONLY its own record on\n// graceful shutdown, so other processes (notably the `clodex-claude` wrapper\n// bin) can discover every running server's mode, port, and CA path without any\n// hardcoding. The file holds an ARRAY of records; the legacy single-object\n// shape (pre multi-server) is tolerated on read as a one-element list. Stale\n// detection is the READER's job: a crashed server leaves its record behind, so\n// readers must validate pid liveness before trusting it. Writers additionally\n// prune dead-pid records while they hold the write lock.\n//\n// Concurrency: read-modify-write cycles are serialized by a short-lived pid\n// lock (~/.clodex/server-runtime.lock — same pattern as the patcher's\n// patch.lock: O_EXCL create, pid + staleness, ESRCH liveness) and the file is\n// replaced via write-temp-then-rename so a reader never sees a torn write. A\n// crashed lock holder cannot deadlock registration: the lock goes stale after\n// 10 seconds or when its pid dies, and after a brief bounded wait a writer\n// proceeds lockless (best-effort — same exposure as the old single-slot write).\n//\n// NOTE: only the standalone `clodex server` command writes this file. The\n// per-session MITM proxy spawned by `clodex claude --proxy` is private to that\n// session and must NOT advertise itself here. `clodex server --no-discovery`\n// (or CLODEX_NO_DISCOVERY=1) also opts a server out of registration entirely.\n\nimport {\n closeSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n rmSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppHome } from './paths.js';\n\nexport interface ServerRuntimeState {\n mode: 'endpoint' | 'proxy';\n port: number;\n pid: number;\n /** Proxy mode only: absolute path to the CA bundle a client must trust. */\n caPath?: string;\n startedAt: string;\n}\n\ninterface HomeEnv {\n HOME?: string;\n CLODEX_HOME?: string;\n USERPROFILE?: string;\n}\n\nexport function getServerRuntimePath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'server-runtime.json');\n}\n\nexport function getServerRuntimeLockPath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'server-runtime.lock');\n}\n\n/** `--no-discovery` flag, with CLODEX_NO_DISCOVERY=1 as the env fallback. */\nexport function isDiscoveryDisabled(\n flag: boolean | undefined,\n env: { CLODEX_NO_DISCOVERY?: string } = process.env,\n): boolean {\n if (flag !== undefined) return flag;\n const raw = env.CLODEX_NO_DISCOVERY?.trim().toLowerCase();\n return raw === '1' || raw === 'true';\n}\n\nfunction isPort(value: unknown): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= 65535;\n}\n\n/** Validate one runtime record. Returns null for anything malformed. */\nexport function parseServerRuntimeRecord(value: unknown): ServerRuntimeState | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return null;\n const record = value as Record<string, unknown>;\n\n const mode = record['mode'];\n if (mode !== 'endpoint' && mode !== 'proxy') return null;\n if (!isPort(record['port'])) return null;\n const pid = record['pid'];\n if (typeof pid !== 'number' || !Number.isInteger(pid) || pid <= 0) return null;\n const startedAt = typeof record['startedAt'] === 'string' ? record['startedAt'] : '';\n\n const caPath = record['caPath'];\n if (mode === 'proxy') {\n // A proxy-mode server without a CA path is unusable to clients — treat as invalid.\n if (typeof caPath !== 'string' || !caPath.trim()) return null;\n return { mode, port: record['port'], pid, caPath, startedAt };\n }\n return { mode, port: record['port'], pid, startedAt };\n}\n\n/**\n * Parse a raw server-runtime.json payload into a list of records. Tolerates\n * BOTH shapes: the current array of records and the legacy single object\n * (wrapped as a one-element list). Malformed input or records are skipped —\n * never throws.\n */\nexport function parseServerRuntimeStates(raw: string): ServerRuntimeState[] {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return [];\n }\n const items = Array.isArray(parsed) ? parsed : [parsed];\n const states: ServerRuntimeState[] = [];\n for (const item of items) {\n const state = parseServerRuntimeRecord(item);\n if (state) states.push(state);\n }\n return states;\n}\n\n/** kill(pid, 0) liveness probe: EPERM still means the process exists. */\nexport function isPidAlive(\n pid: number,\n kill: (pid: number, signal: number) => unknown = process.kill.bind(process),\n): boolean {\n try {\n kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException)?.code === 'EPERM';\n }\n}\n\n// ── Write lock (pid + staleness, patcher pattern) ───────────────────────────\n\nconst RUNTIME_LOCK_STALE_MS = 10_000;\nconst RUNTIME_LOCK_WAIT_MS = 500;\nconst RUNTIME_LOCK_RETRY_MS = 25;\n\ninterface RuntimeLockContent {\n pid: number;\n startedAt: number;\n}\n\nfunction tryAcquireRuntimeLock(\n lockPath: string,\n opts: { now?: number; isAlive?: (pid: number) => boolean } = {},\n): (() => void) | null {\n const now = opts.now ?? Date.now();\n const alive = opts.isAlive ?? isPidAlive;\n mkdirSync(dirname(lockPath), { recursive: true, mode: 0o700 });\n\n for (let attempt = 0; attempt < 2; attempt++) {\n try {\n const fd = openSync(lockPath, 'wx');\n const content: RuntimeLockContent = { pid: process.pid, startedAt: now };\n writeFileSync(fd, JSON.stringify(content));\n closeSync(fd);\n return () => {\n try {\n unlinkSync(lockPath);\n } catch {\n // already gone\n }\n };\n } catch {\n // Lock exists — check staleness.\n let stale = false;\n try {\n const existing = JSON.parse(readFileSync(lockPath, 'utf8')) as RuntimeLockContent;\n stale = !existing.pid\n || !alive(existing.pid)\n || (typeof existing.startedAt === 'number' && now - existing.startedAt > RUNTIME_LOCK_STALE_MS);\n } catch {\n stale = true; // unreadable lock file → stale\n }\n if (!stale) return null;\n try {\n unlinkSync(lockPath);\n } catch {\n // raced with the owner's cleanup — retry loop handles it\n }\n }\n }\n return null;\n}\n\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n\n/**\n * Run a read-modify-write mutation under the runtime lock. The lock is only\n * ever held for a few milliseconds, so after a short bounded wait the mutation\n * proceeds WITHOUT the lock rather than dropping a registration — the atomic\n * rename still prevents torn files; the worst case is a lost concurrent\n * update, which is no worse than the old single-slot behavior.\n */\nfunction withRuntimeWriteLock(env: HomeEnv, mutate: () => void): void {\n const lockPath = getServerRuntimeLockPath(env);\n let release: (() => void) | null = null;\n const deadline = Date.now() + RUNTIME_LOCK_WAIT_MS;\n for (;;) {\n release = tryAcquireRuntimeLock(lockPath);\n if (release || Date.now() >= deadline) break;\n sleepSync(RUNTIME_LOCK_RETRY_MS);\n }\n try {\n mutate();\n } finally {\n release?.();\n }\n}\n\nfunction readAllRecords(env: HomeEnv): ServerRuntimeState[] {\n let raw: string;\n try {\n raw = readFileSync(getServerRuntimePath(env), 'utf8');\n } catch {\n return [];\n }\n return parseServerRuntimeStates(raw);\n}\n\n/** Atomic replace: write a temp file in the same directory, then rename over. */\nfunction atomicWriteRecords(path: string, records: ServerRuntimeState[]): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 });\n const tmpPath = `${path}.${process.pid}.tmp`;\n writeFileSync(tmpPath, `${JSON.stringify(records, null, 2)}\\n`, { encoding: 'utf8', mode: 0o600 });\n renameSync(tmpPath, path);\n}\n\nexport interface RuntimeMutateOptions {\n isAlive?: (pid: number) => boolean;\n}\n\n/**\n * Add or update this server's own record (keyed by pid), pruning records whose\n * pids are dead. Best-effort — a state-file failure must never take the server\n * down.\n */\nexport function registerServerRuntimeState(\n state: ServerRuntimeState,\n env: HomeEnv = process.env,\n options: RuntimeMutateOptions = {},\n): void {\n const alive = options.isAlive ?? isPidAlive;\n try {\n withRuntimeWriteLock(env, () => {\n const records = readAllRecords(env).filter(\n record => record.pid !== state.pid && alive(record.pid),\n );\n records.push(state);\n atomicWriteRecords(getServerRuntimePath(env), records);\n });\n } catch {\n // Discovery is optional; the server itself keeps running.\n }\n}\n\n/**\n * Remove ONLY this server's own record (by pid) on graceful shutdown, pruning\n * dead-pid records along the way. Missing file/record is fine. When no live\n * records remain the file is removed entirely.\n */\nexport function unregisterServerRuntimeState(\n pid: number = process.pid,\n env: HomeEnv = process.env,\n options: RuntimeMutateOptions = {},\n): void {\n const alive = options.isAlive ?? isPidAlive;\n try {\n withRuntimeWriteLock(env, () => {\n const records = readAllRecords(env).filter(\n record => record.pid !== pid && alive(record.pid),\n );\n if (records.length === 0) {\n rmSync(getServerRuntimePath(env), { force: true });\n } else {\n atomicWriteRecords(getServerRuntimePath(env), records);\n }\n });\n } catch {\n // Stale records are handled by readers via pid liveness.\n }\n}\n\nexport interface ReadServerRuntimeOptions {\n isAlive?: (pid: number) => boolean;\n}\n\n/**\n * Read every advertised server record whose process is still alive. Missing or\n * malformed files yield an empty list. Read-only: stale records are ignored\n * here and physically pruned on the next registration/unregistration.\n */\nexport function readLiveServerRuntimeStates(\n env: HomeEnv = process.env,\n options: ReadServerRuntimeOptions = {},\n): ServerRuntimeState[] {\n const alive = options.isAlive ?? isPidAlive;\n return readAllRecords(env).filter(state => alive(state.pid));\n}\n\n/**\n * Wrapper selection policy: order candidate servers by preference —\n * 1. proxy mode before endpoint mode (bridging through the MITM proxy keeps\n * Claude Code's own Anthropic auth, the recommended setup);\n * 2. within a mode, newest startedAt first.\n * If only an endpoint server is live it is used; with no live server the\n * wrapper launches claude untouched (both handled by the caller).\n */\nexport function orderWrapperServerCandidates(records: ServerRuntimeState[]): ServerRuntimeState[] {\n return [...records].sort((a, b) => {\n if (a.mode !== b.mode) return a.mode === 'proxy' ? -1 : 1;\n return (Date.parse(b.startedAt) || 0) - (Date.parse(a.startedAt) || 0);\n });\n}\n\n/**\n * Read the single preferred live server (selection policy above), or null when\n * none is advertised/alive.\n */\nexport function readLiveServerRuntimeState(\n env: HomeEnv = process.env,\n options: ReadServerRuntimeOptions = {},\n): ServerRuntimeState | null {\n return orderWrapperServerCandidates(readLiveServerRuntimeStates(env, options))[0] ?? null;\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nexport const APP_DIR_NAME = 'clodex';\n\ninterface HomeEnv {\n HOME?: string;\n CLODEX_HOME?: string;\n USERPROFILE?: string;\n}\n\nfunction userHome(env: HomeEnv = process.env): string {\n return env.HOME ?? env.USERPROFILE ?? homedir();\n}\n\nexport function resolveAppHomeOverride(env: HomeEnv = process.env): string | undefined {\n const override = env.CLODEX_HOME;\n return override?.trim() || undefined;\n}\n\nexport function getAppHome(env: HomeEnv = process.env): string {\n const override = resolveAppHomeOverride(env);\n if (override) return override;\n return join(userHome(env), `.${APP_DIR_NAME}`);\n}\n\nexport function getConfigPath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'config.json');\n}\n\nexport function getProvidersPath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'providers.json');\n}\n\nexport function getCredentialCleanupPath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'credential-cleanup.json');\n}\n\nexport function getLogsPath(env: HomeEnv = process.env): string {\n return join(getAppHome(env), 'logs');\n}\n","// src/wrapper-env.ts\n//\n// Pure env computation for the `clodex-claude` wrapper bin. Given the process\n// env and a live `clodex server` runtime state (or null), returns the env to\n// launch the Claude Code binary with. Kept dependency-free so the wrapper\n// stays tiny and fast — it runs for every Claude-Code-spawned agent process.\n\nimport type { ServerRuntimeState } from './server-runtime.js';\n\nconst PROXY_ENV_VARS = ['HTTPS_PROXY', 'HTTP_PROXY', 'https_proxy', 'http_proxy'] as const;\nexport const REQUIRE_SERVER_ENV = 'CLODEX_REQUIRE_SERVER';\n\nexport function removeAnthropicProxyBypass(env: NodeJS.ProcessEnv): void {\n const noProxyValues = [env['NO_PROXY'], env['no_proxy']]\n .filter((value): value is string => value !== undefined);\n if (noProxyValues.length === 0) return;\n\n const filtered = [...new Set(noProxyValues\n .flatMap(value => value.split(','))\n .map(value => value.trim())\n .filter(Boolean)\n .filter(value => {\n const entry = value.toLowerCase().replace(/^https?:\\/\\//, '');\n const host = entry.replace(/:\\d+$/, '');\n if (host === '*') return false;\n const suffix = host.startsWith('*.') ? host.slice(1) : host;\n const bypassesAnthropic = suffix.startsWith('.')\n ? 'api.anthropic.com'.endsWith(suffix)\n : 'api.anthropic.com' === suffix || 'api.anthropic.com'.endsWith(`.${suffix}`);\n return !bypassesAnthropic;\n }))]\n .join(',');\n if (filtered) {\n env['NO_PROXY'] = filtered;\n env['no_proxy'] = filtered;\n } else {\n delete env['NO_PROXY'];\n delete env['no_proxy'];\n }\n}\n\n/**\n * Any non-empty key satisfies the local endpoint gateway (`isAuthorized`\n * accepts everything when no server password is set, i.e. local listen mode).\n */\nexport const LOCAL_GATEWAY_API_KEY = 'clodex-local';\n\nexport function wrapperRequiresServer(env: NodeJS.ProcessEnv): boolean {\n return env[REQUIRE_SERVER_ENV] === '1';\n}\n\nexport function computeWrapperEnv(\n baseEnv: NodeJS.ProcessEnv,\n state: ServerRuntimeState | null,\n): NodeJS.ProcessEnv {\n const env: NodeJS.ProcessEnv = { ...baseEnv };\n // No live server: launch claude completely untouched — a down server must\n // never break launching claude.\n if (!state) return env;\n\n if (state.mode === 'proxy') {\n // Selective MITM: claude keeps its own Anthropic credentials; the proxy\n // routes clodex:/alias models to OpenAI and passes everything else through.\n const proxyUrl = `http://127.0.0.1:${state.port}`;\n delete env['ANTHROPIC_BASE_URL'];\n for (const name of PROXY_ENV_VARS) env[name] = proxyUrl;\n if (state.caPath) env['NODE_EXTRA_CA_CERTS'] = state.caPath;\n removeAnthropicProxyBypass(env);\n return env;\n }\n\n // Endpoint gateway: all traffic goes to the local Anthropic-format gateway.\n for (const name of PROXY_ENV_VARS) delete env[name];\n env['ANTHROPIC_BASE_URL'] = `http://127.0.0.1:${state.port}/anthropic`;\n env['ANTHROPIC_API_KEY'] = LOCAL_GATEWAY_API_KEY;\n return env;\n}\n","import type { UserPreferences } from './types.js';\nimport { randomUUID } from 'node:crypto';\nimport { readFileSync, renameSync, unlinkSync } from 'node:fs';\nimport { getConfigPath } from './paths.js';\nimport { syncParentDirectory, writeSecureFile } from './registry/io.js';\nimport {\n assertRegistryWriteOwnership,\n withRegistryWriteLock,\n withRegistryWriteLockSync,\n} from './registry/lock.js';\n\nfunction readJsonFile(path: string): UserPreferences | null {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8'));\n return parsed && typeof parsed === 'object' ? parsed as UserPreferences : null;\n } catch {\n return null;\n }\n}\n\nfunction readConfig(): UserPreferences {\n return readJsonFile(getConfigPath()) ?? {};\n}\n\nfunction writeConfig(config: UserPreferences): void {\n const configPath = getConfigPath();\n assertRegistryWriteOwnership(configPath);\n const payload = `${JSON.stringify(config, null, 2)}\\n`;\n const tmp = `${configPath}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeSecureFile(tmp, payload);\n assertRegistryWriteOwnership(configPath);\n renameSync(tmp, configPath);\n syncParentDirectory(configPath);\n } finally {\n try {\n unlinkSync(tmp);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n }\n }\n}\n\nfunction updateConfig<T>(mutate: (config: UserPreferences) => T): T {\n const configPath = getConfigPath();\n return withRegistryWriteLockSync(() => {\n const config = readJsonFile(configPath) ?? {};\n const result = mutate(config);\n writeConfig(config);\n return result;\n }, { lockPath: `${configPath}.lock` });\n}\n\ninterface AsyncConfigUpdate<T> {\n result: T;\n write: boolean;\n}\n\nasync function updateConfigAsync<T>(\n mutate: (\n config: UserPreferences,\n ) => Promise<AsyncConfigUpdate<T>> | AsyncConfigUpdate<T>,\n): Promise<T> {\n const configPath = getConfigPath();\n return withRegistryWriteLock(async () => {\n const config = readJsonFile(configPath) ?? {};\n const update = await mutate(config);\n if (update.write) writeConfig(config);\n return update.result;\n }, { lockPath: `${configPath}.lock` });\n}\n\nexport function loadPreferences(): UserPreferences {\n const config = readConfig();\n return {\n lastModel: config.lastModel,\n lastProvider: config.lastProvider,\n recentModelsByProvider: config.recentModelsByProvider,\n favoriteModels: config.favoriteModels,\n modelAliases: config.modelAliases,\n claudeBridgeMode: config.claudeBridgeMode,\n serverBridgeMode: config.serverBridgeMode,\n appPathOverrides: config.appPathOverrides,\n recentLaunchFolders: config.recentLaunchFolders,\n server: config.server,\n };\n}\n\nexport function savePreferences(prefs: Partial<Pick<UserPreferences, 'lastModel' | 'lastProvider' | 'recentModelsByProvider' | 'favoriteModels' | 'modelAliases' | 'claudeBridgeMode' | 'serverBridgeMode' | 'appPathOverrides' | 'recentLaunchFolders'>>): void {\n updateConfig(config => {\n if (prefs.lastModel !== undefined) config.lastModel = prefs.lastModel;\n if (prefs.lastProvider !== undefined) config.lastProvider = prefs.lastProvider;\n if (prefs.recentModelsByProvider !== undefined) config.recentModelsByProvider = prefs.recentModelsByProvider;\n if (prefs.favoriteModels !== undefined) config.favoriteModels = prefs.favoriteModels;\n if (prefs.modelAliases !== undefined) config.modelAliases = prefs.modelAliases;\n if (prefs.claudeBridgeMode !== undefined) config.claudeBridgeMode = prefs.claudeBridgeMode;\n if (prefs.serverBridgeMode !== undefined) config.serverBridgeMode = prefs.serverBridgeMode;\n if (prefs.appPathOverrides !== undefined) config.appPathOverrides = prefs.appPathOverrides;\n if (prefs.recentLaunchFolders !== undefined) config.recentLaunchFolders = prefs.recentLaunchFolders;\n });\n}\n\nexport function getAppPathOverride(appId: string): string | undefined {\n const value = loadPreferences().appPathOverrides?.[appId];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nexport function setAppPathOverride(appId: string, path: string | null): Record<string, string> {\n return updateConfig(config => {\n const next = { ...(config.appPathOverrides ?? {}) };\n const trimmed = path?.trim() ?? '';\n if (trimmed) next[appId] = trimmed;\n else delete next[appId];\n config.appPathOverrides = next;\n if (Object.keys(next).length === 0) delete config.appPathOverrides;\n return next;\n });\n}\n\n/**\n * Resolve the bridge mode for a command. An explicit flag applies to that run only —\n * it is persisted as the command's default ONLY when the caller opts in (--save-mode).\n * With no flag, the saved per-command default applies; with no saved default, proxy.\n */\nexport function resolveBridgeMode(\n command: 'claude' | 'server',\n explicit: import('./types.js').BridgeMode | undefined,\n opts: { persist?: boolean } = {},\n): import('./types.js').BridgeMode {\n const key = command === 'claude' ? 'claudeBridgeMode' : 'serverBridgeMode';\n if (explicit) {\n if (opts.persist === true) savePreferences({ [key]: explicit });\n return explicit;\n }\n return loadPreferences()[key] ?? 'proxy';\n}\n\nconst MAX_RECENT_MODELS = 3;\nconst MAX_RECENT_LAUNCH_FOLDERS = 6;\n\nexport function recordLaunchFolder(folder: string): string[] {\n const trimmed = folder.trim();\n if (!trimmed) return loadPreferences().recentLaunchFolders ?? [];\n return updateConfig(config => {\n const prev = config.recentLaunchFolders ?? [];\n const next = [trimmed, ...prev.filter(path => path !== trimmed)].slice(0, MAX_RECENT_LAUNCH_FOLDERS);\n config.recentLaunchFolders = next;\n return next;\n });\n}\n\nexport function recordLaunchSelection(\n _agent: 'claude',\n providerId: string,\n modelId: string,\n prefs: UserPreferences,\n): void {\n const prevRecent = prefs.recentModelsByProvider?.[providerId] ?? [];\n const updatedRecent = [modelId, ...prevRecent.filter(id => id !== modelId)].slice(0, MAX_RECENT_MODELS);\n savePreferences({\n lastProvider: providerId,\n lastModel: modelId,\n recentModelsByProvider: { ...prefs.recentModelsByProvider, [providerId]: updatedRecent },\n });\n}\n\nconst SERVER_PASSWORD_SERVICE = 'clodex-server-password';\nconst SERVER_PASSWORD_ACCOUNT = 'server-password';\n\nasync function getServerPasswordKeyring(): Promise<any | null> {\n try {\n const { Entry } = await import('@napi-rs/keyring');\n return new Entry(SERVER_PASSWORD_SERVICE, SERVER_PASSWORD_ACCOUNT);\n } catch {\n return null;\n }\n}\n\nexport async function getSavedServerPassword(): Promise<string | null> {\n const keyring = await getServerPasswordKeyring();\n if (!keyring) return readConfig().server?.savedPassword ?? null;\n\n const savedPassword = await updateConfigAsync(async config => {\n const server = config.server;\n const password = server?.savedPassword;\n if (!password) return { result: null, write: false };\n try {\n await keyring.setPassword(password);\n delete server.savedPassword;\n if (Object.keys(server).length === 0) delete config.server;\n return { result: password, write: true };\n } catch {\n // Fallback: keep in config.json if keyring fails\n return { result: password, write: false };\n }\n });\n if (savedPassword) return savedPassword;\n\n try {\n return await keyring.getPassword();\n } catch {\n return null;\n }\n}\n\nexport async function setSavedServerPassword(password: string): Promise<void> {\n const keyring = await getServerPasswordKeyring();\n if (keyring) {\n try {\n await keyring.setPassword(password);\n return;\n } catch {\n // Fallback\n }\n }\n await updateConfigAsync(config => {\n config.server = {\n ...(config.server ?? {}),\n savedPassword: password,\n };\n return { result: undefined, write: true };\n });\n}\n\nexport async function clearSavedServerPassword(): Promise<void> {\n const keyring = await getServerPasswordKeyring();\n if (keyring) {\n try {\n await keyring.deletePassword();\n } catch {\n // Ignore\n }\n }\n await updateConfigAsync(config => {\n if (!config.server) return { result: undefined, write: false };\n delete config.server.savedPassword;\n if (Object.keys(config.server).length === 0) delete config.server;\n return { result: undefined, write: true };\n });\n}\n\nexport function getServerExposedProviders(): string[] | null {\n const list = readConfig().server?.exposedProviders;\n return list && list.length > 0 ? list : null;\n}\n\nexport function setServerExposedProviders(providerIds: string[]): void {\n updateConfig(config => {\n config.server = {\n ...(config.server ?? {}),\n exposedProviders: providerIds,\n };\n });\n}\n\nexport function getServerMaskGatewayIds(): boolean {\n return readConfig().server?.maskGatewayIds ?? true;\n}\n\nexport function setServerMaskGatewayIds(mask: boolean): void {\n updateConfig(config => {\n config.server = {\n ...(config.server ?? {}),\n maskGatewayIds: mask,\n };\n });\n}\n\nexport function getServerFavoritesOnly(): boolean {\n return readConfig().server?.favoritesOnly ?? false;\n}\n\nexport function setServerFavoritesOnly(favoritesOnly: boolean): void {\n updateConfig(config => {\n config.server = {\n ...(config.server ?? {}),\n favoritesOnly,\n };\n });\n}\n\nexport function getServerListenMode(): 'local' | 'network' {\n return readConfig().server?.listenMode === 'network' ? 'network' : 'local';\n}\n\nexport function setServerListenMode(listenMode: 'local' | 'network'): void {\n updateConfig(config => {\n config.server = {\n ...(config.server ?? {}),\n listenMode,\n };\n });\n}\n","// src/registry/io.ts — load/save providers.json with secure permissions\n\nimport { randomUUID } from 'node:crypto';\nimport {\n chmodSync,\n closeSync,\n copyFileSync,\n existsSync,\n fsyncSync,\n mkdirSync,\n openSync,\n readFileSync,\n renameSync,\n unlinkSync,\n writeSync,\n} from 'node:fs';\nimport { dirname } from 'node:path';\nimport { getAppHome, getProvidersPath } from '../paths.js';\nimport type { ProviderRegistry, RegistryProvider } from './types.js';\nimport { REGISTRY_SCHEMA_VERSION } from './types.js';\nimport {\n assertRegistryWriteOwnership,\n withRegistryWriteLockSync,\n} from './lock.js';\nimport { migrateOAuthOpenAiProvider } from './migrate.js';\nimport { isValidProviderId } from './validate.js';\n\nconst DIR_MODE = 0o700;\nconst FILE_MODE = 0o600;\n\nexport function ensureSecureAppHome(): void {\n const home = getAppHome();\n mkdirSync(home, { recursive: true, mode: DIR_MODE });\n try {\n chmodSync(home, DIR_MODE);\n } catch {\n // best-effort on platforms that restrict chmod\n }\n}\n\nexport function writeSecureFile(path: string, content: string): void {\n ensureSecureAppHome();\n mkdirSync(dirname(path), { recursive: true, mode: DIR_MODE });\n const fd = openSync(path, 'wx', FILE_MODE);\n try {\n const payload = Buffer.from(content);\n let offset = 0;\n while (offset < payload.length) {\n const written = writeSync(fd, payload, offset, payload.length - offset);\n if (written <= 0) {\n throw new Error(`Could not complete secure file write: ${path}`);\n }\n offset += written;\n }\n fsyncSync(fd);\n } finally {\n closeSync(fd);\n }\n try {\n chmodSync(path, FILE_MODE);\n } catch {\n // best-effort\n }\n}\n\nexport function syncParentDirectory(path: string): void {\n let fd: number | undefined;\n try {\n fd = openSync(dirname(path), 'r');\n fsyncSync(fd);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== 'EINVAL' && code !== 'ENOTSUP' && code !== 'EPERM') throw error;\n } finally {\n if (fd !== undefined) closeSync(fd);\n }\n}\n\nfunction parseProvider(raw: unknown): RegistryProvider | null {\n if (!raw || typeof raw !== 'object') return null;\n const p = raw as Record<string, unknown>;\n if (typeof p.id !== 'string' || !isValidProviderId(p.id)) return null;\n if (typeof p.templateId !== 'string' || !p.templateId) return null;\n if (typeof p.name !== 'string' || !p.name) return null;\n if (typeof p.enabled !== 'boolean') return null;\n if (typeof p.authRef !== 'string' || !p.authRef) return null;\n if (typeof p.addedAt !== 'string' || !p.addedAt) return null;\n const api = p.api;\n if (!api || typeof api !== 'object') return null;\n\n const provider: RegistryProvider = {\n id: p.id,\n templateId: p.templateId,\n name: p.name,\n enabled: p.enabled,\n authRef: p.authRef,\n api: api as RegistryProvider['api'],\n addedAt: p.addedAt,\n };\n\n if (p.subscriptionFilter === 'free') {\n provider.subscriptionFilter = p.subscriptionFilter;\n }\n if (p.authType === 'api' || p.authType === 'oauth' || p.authType === 'none') {\n provider.authType = p.authType;\n }\n if (typeof p.refreshedAt === 'string') provider.refreshedAt = p.refreshedAt;\n if (p.modelsCache && typeof p.modelsCache === 'object') {\n const cache = p.modelsCache as { fetchedAt?: string; models?: unknown[] };\n if (typeof cache.fetchedAt === 'string' && Array.isArray(cache.models)) {\n provider.modelsCache = {\n fetchedAt: cache.fetchedAt,\n models: cache.models.filter(m => m && typeof m === 'object') as RegistryProvider['modelsCache'] extends infer C\n ? C extends { models: infer M } ? M : never\n : never,\n };\n }\n }\n return provider;\n}\n\nfunction hasOwn(record: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nfunction hasValidStrictProviderFields(raw: unknown): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return false;\n const provider = raw as Record<string, unknown>;\n if (hasOwn(provider, 'subscriptionFilter') && provider.subscriptionFilter !== 'free') {\n return false;\n }\n if (\n hasOwn(provider, 'authType')\n && provider.authType !== 'api'\n && provider.authType !== 'oauth'\n && provider.authType !== 'none'\n ) {\n return false;\n }\n if (hasOwn(provider, 'refreshedAt') && typeof provider.refreshedAt !== 'string') {\n return false;\n }\n if (hasOwn(provider, 'modelsCache')) {\n const cache = provider.modelsCache;\n if (!cache || typeof cache !== 'object' || Array.isArray(cache)) return false;\n const fields = cache as Record<string, unknown>;\n if (typeof fields.fetchedAt !== 'string' || !Array.isArray(fields.models)) {\n return false;\n }\n if (fields.models.some(model => !model || typeof model !== 'object' || Array.isArray(model))) {\n return false;\n }\n }\n return true;\n}\n\nfunction parseRegistry(raw: unknown): ProviderRegistry {\n const empty: ProviderRegistry = { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };\n if (!raw || typeof raw !== 'object') return empty;\n const data = raw as Record<string, unknown>;\n const providers: RegistryProvider[] = [];\n if (Array.isArray(data.providers)) {\n for (const entry of data.providers) {\n const parsed = parseProvider(entry);\n if (parsed) providers.push(parsed);\n }\n }\n const registry: ProviderRegistry = {\n schemaVersion:\n typeof data.schemaVersion === 'number' ? data.schemaVersion : REGISTRY_SCHEMA_VERSION,\n providers,\n };\n if (typeof data.importedAt === 'string') registry.importedAt = data.importedAt;\n if (typeof data.pricingCacheAt === 'string') registry.pricingCacheAt = data.pricingCacheAt;\n return registry;\n}\n\nfunction parseRegistryStrict(raw: unknown): ProviderRegistry {\n if (!raw || typeof raw !== 'object') {\n throw new Error('Provider registry must be a JSON object.');\n }\n const data = raw as Record<string, unknown>;\n if (data.schemaVersion !== REGISTRY_SCHEMA_VERSION) {\n throw new Error('Provider registry has an unsupported schema version.');\n }\n if (!Array.isArray(data.providers)) {\n throw new Error('Provider registry is missing its providers list.');\n }\n for (const entry of data.providers) {\n if (!parseProvider(entry) || !hasValidStrictProviderFields(entry)) {\n throw new Error('Provider registry contains an invalid provider entry.');\n }\n }\n return parseRegistry(raw);\n}\n\nfunction readRegistryStrict(path: string): ProviderRegistry {\n return parseRegistryStrict(JSON.parse(readFileSync(path, 'utf8')));\n}\n\nexport function loadRegistry(path = getProvidersPath()): ProviderRegistry {\n if (!existsSync(path)) {\n return { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };\n }\n try {\n const raw = JSON.parse(readFileSync(path, 'utf8'));\n const registry = parseRegistry(raw);\n const migrated = migrateOAuthOpenAiProvider(registry);\n if (migrated) {\n try {\n withRegistryWriteLockSync(() => {\n if (!existsSync(path)) return;\n const current = readRegistryStrict(path);\n if (migrateOAuthOpenAiProvider(current)) saveRegistry(current, path);\n }, { lockPath: `${path}.lock` });\n } catch {\n // Parsed data remains usable even when migration persistence fails.\n }\n }\n return registry;\n } catch {\n return { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };\n }\n}\n\n/**\n * Load a registry for destructive decisions. Unlike `loadRegistry`, read,\n * parse, and provider-shape errors propagate so callers cannot confuse an\n * unreadable registry with an empty one.\n */\nexport function loadRegistryStrict(path = getProvidersPath()): ProviderRegistry {\n if (!existsSync(path)) {\n return { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };\n }\n const registry = readRegistryStrict(path);\n migrateOAuthOpenAiProvider(registry);\n return registry;\n}\n\nexport function saveRegistry(registry: ProviderRegistry, path = getProvidersPath()): void {\n assertRegistryWriteOwnership(path);\n const payload = `${JSON.stringify(registry, null, 2)}\\n`;\n const backup = `${path}.bak`;\n if (existsSync(path)) {\n try {\n copyFileSync(path, backup);\n } catch {\n // backup is best-effort\n }\n }\n const tmp = `${path}.${process.pid}.${randomUUID()}.tmp`;\n try {\n writeSecureFile(tmp, payload);\n assertRegistryWriteOwnership(path);\n renameSync(tmp, path);\n syncParentDirectory(path);\n } finally {\n try {\n unlinkSync(tmp);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n}\n\nexport function emptyRegistry(): ProviderRegistry {\n return { schemaVersion: REGISTRY_SCHEMA_VERSION, providers: [] };\n}\n","// src/registry/types.ts — native provider registry schema (no secrets)\n\nimport type { FreeStatus } from '../free-models.js';\n\nexport const REGISTRY_SCHEMA_VERSION = 1;\n\nexport type RegistrySubscriptionFilter = 'free';\n\nexport interface CachedModel {\n id: string;\n name: string;\n upstreamModelId: string;\n family?: string;\n brand?: string;\n contextWindow?: number;\n cost?: { input: number; output: number; cache_read?: number; cache_write?: number };\n isFree?: boolean;\n freeStatus?: FreeStatus;\n modelFormat: 'anthropic' | 'openai' | 'cloud-code';\n /** Per-model override — wins over provider-level api.npm */\n npm?: string;\n /** Per-model override — wins over provider-level api.url */\n apiUrl?: string;\n sourceBackend?: string;\n /** Provider-reported request parameters, e.g. OpenRouter supported_parameters. */\n supportedParameters?: string[];\n /** Broad model metadata: model can produce reasoning/thinking output. */\n reasoning?: boolean;\n /** Streaming/interleaved reasoning field name from metadata, e.g. reasoning_content. */\n interleavedReasoningField?: string;\n /** Backend capability: model requires the Responses-Lite request shape (x-openai-internal-codex-responses-lite). */\n useResponsesLite?: boolean;\n /** Backend capability: model must use the WebSocket Responses transport instead of HTTP. */\n preferWebSockets?: boolean;\n}\n\nexport interface RegistryProvider {\n id: string;\n templateId: string;\n name: string;\n enabled: boolean;\n authRef: string;\n authType?: 'api' | 'oauth' | 'none';\n subscriptionFilter?: RegistrySubscriptionFilter;\n api: {\n npm?: string;\n url?: string;\n id?: string;\n /** Static headers sent on every upstream request (e.g. a plan/auth-tracking header a custom endpoint requires). */\n headers?: Record<string, string>;\n };\n modelsCache?: {\n fetchedAt: string;\n models: CachedModel[];\n };\n addedAt: string;\n refreshedAt?: string;\n}\n\nexport interface ProviderRegistry {\n schemaVersion: number;\n providers: RegistryProvider[];\n importedAt?: string;\n pricingCacheAt?: string;\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { createHash, randomUUID } from 'node:crypto';\nimport {\n closeSync,\n fstatSync,\n fsyncSync,\n linkSync,\n mkdirSync,\n openSync,\n readFileSync,\n statSync,\n unlinkSync,\n writeFileSync,\n} from 'node:fs';\nimport { dirname } from 'node:path';\nimport { getProvidersPath } from '../paths.js';\n\nconst DEFAULT_WAIT_MS = 30_000;\nconst DEFAULT_CREDENTIAL_MUTATION_WAIT_MS = 150_000;\nconst DEFAULT_RETRY_MS = 25;\n\ninterface RegistryLockOwner {\n pid: number;\n startedAt: number;\n token: string;\n}\n\ninterface RegistryLockSnapshot {\n raw: string;\n device: number;\n inode: number;\n modifiedAt: number;\n}\n\ninterface RegistryLockOptions {\n lockPath?: string;\n waitMs?: number;\n retryMs?: number;\n now?: () => number;\n isAlive?: (pid: number) => boolean;\n}\n\ninterface RegistryLockContext {\n leases: ReadonlyMap<string, RegistryLockLease>;\n}\n\nexport interface RegistryLockLease {\n active: boolean;\n readonly lockPath: string;\n readonly token: string;\n readonly device: number;\n readonly inode: number;\n assertOwned: () => void;\n release: () => void;\n}\n\nconst registryLockContext = new AsyncLocalStorage<RegistryLockContext>();\n\nexport class RegistryLockLostError extends Error {\n constructor(lockPath: string) {\n super(`Provider registry lock ownership was lost before write: ${lockPath}`);\n this.name = 'RegistryLockLostError';\n }\n}\n\nexport function getRegistryLockPath(): string {\n return `${getProvidersPath()}.lock`;\n}\n\nfunction isPidAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nfunction parseLockOwner(raw: string): RegistryLockOwner | null {\n try {\n const parsed = JSON.parse(raw) as Partial<RegistryLockOwner>;\n if (!Number.isInteger(parsed.pid) || (parsed.pid ?? 0) <= 0) return null;\n if (\n typeof parsed.startedAt !== 'number' ||\n !Number.isFinite(parsed.startedAt)\n )\n return null;\n if (typeof parsed.token !== 'string' || parsed.token.length === 0)\n return null;\n return parsed as RegistryLockOwner;\n } catch {\n return null;\n }\n}\n\nfunction createLockRecord(\n lockPath: string,\n owner: RegistryLockOwner,\n): RegistryLockSnapshot | null {\n const raw = JSON.stringify(owner);\n const tempPath = `${lockPath}.${process.pid}.${owner.token}.tmp`;\n let fd: number | undefined;\n try {\n fd = openSync(tempPath, 'wx', 0o600);\n writeFileSync(fd, raw);\n fsyncSync(fd);\n const stats = fstatSync(fd);\n try {\n linkSync(tempPath, lockPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST') return null;\n throw err;\n }\n return {\n raw,\n device: stats.dev,\n inode: stats.ino,\n modifiedAt: stats.mtimeMs,\n };\n } finally {\n if (fd !== undefined) closeSync(fd);\n try {\n unlinkSync(tempPath);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n }\n}\n\nfunction lockFileMatchesLease(lease: RegistryLockLease): boolean {\n let fd: number | undefined;\n try {\n fd = openSync(lease.lockPath, 'r');\n const openedStats = fstatSync(fd);\n const owner = parseLockOwner(readFileSync(fd, 'utf8'));\n const pathStats = statSync(lease.lockPath);\n return (\n owner?.token === lease.token &&\n openedStats.dev === lease.device &&\n openedStats.ino === lease.inode &&\n pathStats.dev === lease.device &&\n pathStats.ino === lease.inode\n );\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return false;\n throw err;\n } finally {\n if (fd !== undefined) closeSync(fd);\n }\n}\n\nfunction createLease(\n lockPath: string,\n owner: RegistryLockOwner,\n snapshot: RegistryLockSnapshot,\n): RegistryLockLease {\n const lease: RegistryLockLease = {\n active: true,\n lockPath,\n token: owner.token,\n device: snapshot.device,\n inode: snapshot.inode,\n assertOwned: () => {\n if (!lease.active || !lockFileMatchesLease(lease)) {\n lease.active = false;\n throw new RegistryLockLostError(lockPath);\n }\n },\n release: () => {\n if (!lease.active) return;\n lease.active = false;\n if (lockFileMatchesLease(lease)) unlinkSync(lockPath);\n },\n };\n return lease;\n}\n\nexport function assertRegistryWriteOwnership(\n registryPath = getProvidersPath(),\n): void {\n const lockPath = `${registryPath}.lock`;\n const lease = registryLockContext.getStore()?.leases.get(lockPath);\n if (!lease) throw new RegistryLockLostError(lockPath);\n lease.assertOwned();\n}\n\nfunction getStaleLockSnapshot(\n lockPath: string,\n alive: (pid: number) => boolean,\n): RegistryLockSnapshot | null {\n const raw = readFileSync(lockPath, 'utf8');\n const stats = statSync(lockPath);\n const snapshot: RegistryLockSnapshot = {\n raw,\n device: stats.dev,\n inode: stats.ino,\n modifiedAt: stats.mtimeMs,\n };\n const owner = parseLockOwner(raw);\n if (owner) return alive(owner.pid) ? null : snapshot;\n return snapshot;\n}\n\nfunction removeStaleLock(\n lockPath: string,\n expected?: RegistryLockSnapshot,\n): boolean {\n try {\n if (expected) {\n const raw = readFileSync(lockPath, 'utf8');\n const stats = statSync(lockPath);\n if (\n raw !== expected.raw ||\n stats.dev !== expected.device ||\n stats.ino !== expected.inode ||\n stats.mtimeMs !== expected.modifiedAt\n )\n return false;\n }\n unlinkSync(lockPath);\n return true;\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n return false;\n }\n}\n\nfunction tryAcquireReaperGuard(\n lockPath: string,\n now: number,\n alive: (pid: number) => boolean,\n): RegistryLockLease | null {\n const guardPath = `${lockPath}.reap`;\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const owner: RegistryLockOwner = {\n pid: process.pid,\n startedAt: now,\n token: randomUUID(),\n };\n try {\n const snapshot = createLockRecord(guardPath, owner);\n if (snapshot) return createLease(guardPath, owner, snapshot);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw err;\n }\n\n let stale: RegistryLockSnapshot | null = null;\n try {\n stale = getStaleLockSnapshot(guardPath, alive);\n } catch (readErr) {\n if ((readErr as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw readErr;\n }\n if (!stale) return null;\n if (!removeStaleLock(guardPath, stale)) continue;\n }\n return null;\n}\n\nexport function tryAcquireRegistryLock(\n lockPath = getRegistryLockPath(),\n options: Pick<RegistryLockOptions, 'now' | 'isAlive'> = {},\n): RegistryLockLease | null {\n const now = options.now?.() ?? Date.now();\n const alive = options.isAlive ?? isPidAlive;\n mkdirSync(dirname(lockPath), { recursive: true, mode: 0o700 });\n\n for (let attempt = 0; attempt < 3; attempt += 1) {\n const owner: RegistryLockOwner = {\n pid: process.pid,\n startedAt: now,\n token: randomUUID(),\n };\n try {\n const snapshot = createLockRecord(lockPath, owner);\n if (snapshot) return createLease(lockPath, owner, snapshot);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw err;\n }\n\n let stale: RegistryLockSnapshot | null = null;\n try {\n stale = getStaleLockSnapshot(lockPath, alive);\n } catch (readErr) {\n if ((readErr as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw readErr;\n }\n if (!stale) return null;\n const reaperLease = tryAcquireReaperGuard(lockPath, now, alive);\n if (!reaperLease) return null;\n try {\n let currentStale: RegistryLockSnapshot | null = null;\n try {\n currentStale = getStaleLockSnapshot(lockPath, alive);\n } catch (readErr) {\n if ((readErr as NodeJS.ErrnoException).code === 'ENOENT') continue;\n throw readErr;\n }\n if (!currentStale) return null;\n if (!removeStaleLock(lockPath, currentStale)) continue;\n } finally {\n reaperLease.release();\n }\n }\n return null;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction sleepSync(ms: number): void {\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);\n}\n\nfunction lockTimeoutError(\n lockPath: string,\n waitMs: number,\n alive: (pid: number) => boolean,\n): Error {\n let owner: RegistryLockOwner | null = null;\n try {\n owner = parseLockOwner(readFileSync(lockPath, 'utf8'));\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n if (owner && alive(owner.pid)) {\n return new Error(\n `Timed out after ${waitMs}ms waiting for lock held by clodex process ` +\n `(pid ${owner.pid}): ${lockPath}`,\n );\n }\n return new Error(\n `Timed out after ${waitMs}ms waiting for lock: ${lockPath}`,\n );\n}\n\nexport async function withRegistryWriteLock<T>(\n operation: () => Promise<T> | T,\n options: RegistryLockOptions = {},\n): Promise<T> {\n const lockPath = options.lockPath ?? getRegistryLockPath();\n const inheritedLeases = registryLockContext.getStore()?.leases;\n if (inheritedLeases?.get(lockPath)?.active) return operation();\n\n const waitMs = options.waitMs ?? DEFAULT_WAIT_MS;\n const retryMs = options.retryMs ?? DEFAULT_RETRY_MS;\n const now = options.now ?? Date.now;\n const deadline = now() + waitMs;\n let lease: RegistryLockLease | null = null;\n\n while (!lease) {\n lease = tryAcquireRegistryLock(lockPath, {\n now,\n isAlive: options.isAlive,\n });\n if (lease) break;\n if (now() >= deadline)\n throw lockTimeoutError(lockPath, waitMs, options.isAlive ?? isPidAlive);\n await sleep(retryMs);\n }\n\n const leases = new Map(inheritedLeases);\n leases.set(lockPath, lease);\n const context: RegistryLockContext = { leases };\n return registryLockContext.run(context, async () => {\n try {\n return await operation();\n } finally {\n lease.release();\n }\n });\n}\n\nexport function withRegistryWriteLockSync<T>(\n operation: () => T,\n options: RegistryLockOptions = {},\n): T {\n const lockPath = options.lockPath ?? getRegistryLockPath();\n const inheritedLeases = registryLockContext.getStore()?.leases;\n if (inheritedLeases?.get(lockPath)?.active) return operation();\n\n const waitMs = options.waitMs ?? DEFAULT_WAIT_MS;\n const retryMs = options.retryMs ?? DEFAULT_RETRY_MS;\n const now = options.now ?? Date.now;\n const deadline = now() + waitMs;\n let lease: RegistryLockLease | null = null;\n\n while (!lease) {\n lease = tryAcquireRegistryLock(lockPath, {\n now,\n isAlive: options.isAlive,\n });\n if (lease) break;\n if (now() >= deadline)\n throw lockTimeoutError(lockPath, waitMs, options.isAlive ?? isPidAlive);\n sleepSync(retryMs);\n }\n\n const leases = new Map(inheritedLeases);\n leases.set(lockPath, lease);\n const context: RegistryLockContext = { leases };\n return registryLockContext.run(context, () => {\n try {\n return operation();\n } finally {\n lease.release();\n }\n });\n}\n\nexport function getCredentialMutationLockPath(authRef: string): string {\n const digest = createHash('sha256')\n .update('clodex-credential-mutation\\0')\n .update(authRef)\n .digest('hex');\n return `${getProvidersPath()}.credential-${digest}.lock`;\n}\n\nexport function withCredentialMutationLock<T>(\n authRef: string,\n operation: () => Promise<T> | T,\n options: Pick<RegistryLockOptions, 'waitMs' | 'retryMs'> = {},\n): Promise<T> {\n return withRegistryWriteLock(operation, {\n ...options,\n lockPath: getCredentialMutationLockPath(authRef),\n waitMs: options.waitMs ?? DEFAULT_CREDENTIAL_MUTATION_WAIT_MS,\n });\n}\n","import type { ProviderRegistry } from './types.js';\n\n// Rename {id:'openai', authType:'oauth'} → {id:'openai-oauth'} so it can coexist\n// with the API-key 'openai' provider. Preserves the original authRef so the\n// keyring credential isn't orphaned.\nexport function migrateOAuthOpenAiProvider(registry: ProviderRegistry): boolean {\n if (registry.providers.some(p => p.id === 'openai-oauth')) return false;\n\n const idx = registry.providers.findIndex(\n p => p.id === 'openai' && p.authType === 'oauth',\n );\n if (idx < 0) return false;\n\n const existing = registry.providers[idx]!;\n registry.providers[idx] = {\n ...existing,\n id: 'openai-oauth',\n templateId: existing.templateId || 'openai',\n name: existing.name === 'OpenAI' ? 'OpenAI (ChatGPT)' : existing.name,\n };\n return true;\n}\n","// src/registry/validate.ts\n\n/** Stable provider slug: lowercase alphanumeric + internal hyphens. */\nexport const PROVIDER_ID_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\n\nexport function isValidProviderId(id: string): boolean {\n return PROVIDER_ID_PATTERN.test(id);\n}\n\nexport function slugifyProviderId(displayName: string): string {\n const base = displayName\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!base) return 'custom-provider';\n if (isValidProviderId(base)) return base;\n const trimmed = base.replace(/^-+|-+$/g, '');\n return isValidProviderId(trimmed) ? trimmed : `custom-${trimmed.slice(0, 40)}`;\n}\n\nexport function customProviderId(displayName: string): string {\n const slug = slugifyProviderId(displayName);\n return slug.startsWith('custom-') ? slug : `custom-${slug}`;\n}\n","// src/launch.ts\nimport { execSync, spawn } from 'node:child_process';\nimport { existsSync, appendFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { getAppPathOverride } from './config.js';\nimport { findBinaryOnPath } from './binary-lookup.js';\n\nconst isWindows = process.platform === 'win32';\n\nconst FALLBACK_PATHS = isWindows\n ? [\n join(process.env['APPDATA'] ?? homedir(), 'npm', 'claude.cmd'),\n join(process.env['APPDATA'] ?? homedir(), 'npm', 'claude'),\n join(homedir(), 'AppData', 'Roaming', 'npm', 'claude.cmd'),\n ]\n : [\n join(homedir(), '.local', 'bin', 'claude'),\n join(homedir(), '.npm', 'bin', 'claude'),\n '/usr/local/bin/claude',\n '/opt/homebrew/bin/claude',\n ];\n\nexport function findClaudeBinary(): string | null {\n const environmentOverride = process.env['CLODEX_CLAUDE_PATH'];\n if (environmentOverride?.trim()) {\n return existsSync(environmentOverride) ? environmentOverride : null;\n }\n\n const override = getAppPathOverride('claude');\n if (override) return existsSync(override) ? override : null;\n\n return findBinaryOnPath('claude', FALLBACK_PATHS);\n}\n\nexport function getInstalledClaudeVersion(): string {\n try {\n const claudePath = findClaudeBinary();\n if (!claudePath) return '2.1.183';\n const result = execSync(`${isWindows ? `\"${claudePath}\"` : claudePath} --version`, {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n const match = result.match(/(\\d+\\.\\d+\\.\\d+)/);\n if (match) return match[1];\n } catch {\n // fallback\n }\n return '2.1.183'; // default fallback version known to work\n}\n\nexport function buildClaudeArgs(model: string | undefined, extraArgs: string[]): string[] {\n return model ? ['--model', model, ...extraArgs] : [...extraArgs];\n}\n\nexport function launchClaude(\n env: NodeJS.ProcessEnv,\n model: string | undefined,\n extraArgs: string[],\n): Promise<number> {\n return new Promise((resolve) => {\n const claudePath = findClaudeBinary()!;\n const args = buildClaudeArgs(model, extraArgs);\n\n const debugFileIdx = extraArgs.indexOf('--debug-file');\n const debugLogPath = debugFileIdx !== -1 && extraArgs[debugFileIdx + 1] ? extraArgs[debugFileIdx + 1] : undefined;\n\n const originalStdoutWrite = process.stdout.write;\n const originalStderrWrite = process.stderr.write;\n\n const muteWrite = (chunk: string | Uint8Array, encoding?: any, callback?: any) => {\n if (typeof encoding === 'function') {\n callback = encoding;\n }\n if (debugLogPath) {\n try {\n const str = typeof chunk === 'string' ? chunk : new TextDecoder().decode(chunk);\n appendFileSync(debugLogPath, `[parent] ${str}`);\n } catch {\n // ignore\n }\n }\n if (callback) callback();\n return true;\n };\n\n process.stdout.write = muteWrite as any;\n process.stderr.write = muteWrite as any;\n\n const restore = () => {\n process.stdout.write = originalStdoutWrite;\n process.stderr.write = originalStderrWrite;\n };\n\n const child = spawn(claudePath, args, {\n stdio: 'inherit',\n env,\n shell: isWindows,\n });\n\n const forward = (signal: NodeJS.Signals): void => {\n child.kill(signal);\n };\n\n process.once('SIGINT', () => forward('SIGINT'));\n process.once('SIGTERM', () => forward('SIGTERM'));\n\n child.on('exit', (code) => {\n restore();\n resolve(code ?? 0);\n });\n\n child.on('error', (err) => {\n restore();\n resolve(1);\n });\n });\n}\n","import { execFileSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\n\nexport interface FindBinaryOnPathOptions {\n verifyWhichResult?: boolean;\n isWindows?: boolean;\n exists?: (path: string) => boolean;\n runWhich?: (name: string, isWindows: boolean) => string;\n}\n\nexport function findBinaryOnPath(\n name: string,\n fallbackPaths: string[],\n options: FindBinaryOnPathOptions = {},\n): string | null {\n const isWindows = options.isWindows ?? process.platform === 'win32';\n const exists = options.exists ?? existsSync;\n // argv form, never a shell string — the binary name must not be shell-interpretable\n // (defense-in-depth originally added in d887984, must survive refactors).\n const runWhich = options.runWhich ?? ((binary, win) =>\n execFileSync(win ? 'where.exe' : 'which', [binary], {\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }));\n\n try {\n const lines = runWhich(name, isWindows)\n .trim()\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n const path = (isWindows ? lines.find(line => line.toLowerCase().endsWith('.cmd')) : null)\n ?? lines[0];\n if (path && (!options.verifyWhichResult || exists(path))) return path;\n } catch {\n // Fall through to fallback paths.\n }\n\n for (const path of fallbackPaths) {\n if (exists(path)) return path;\n }\n return null;\n}\n"],"mappings":"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","names":["join","join","randomUUID","readFileSync","renameSync","unlinkSync","randomUUID","closeSync","fsyncSync","mkdirSync","openSync","readFileSync","renameSync","unlinkSync","dirname","closeSync","mkdirSync","openSync","readFileSync","unlinkSync","writeFileSync","dirname","isPidAlive","openSync","writeFileSync","closeSync","unlinkSync","readFileSync","mkdirSync","dirname","sleepSync","mkdirSync","dirname","openSync","fsyncSync","closeSync","readFileSync","randomUUID","renameSync","unlinkSync","readFileSync","randomUUID","renameSync","unlinkSync","existsSync","homedir","join","existsSync","isWindows","join","homedir","existsSync"]}
|