@ai21/gateway 1.3.0 → 1.4.0
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 +26 -21
- package/dist/agents/claude-code/index.d.ts +7 -0
- package/dist/agents/claude-code/index.js +112 -0
- package/dist/agents/claude-code/index.js.map +1 -0
- package/dist/agents/claude-code/revert.d.ts +11 -0
- package/dist/{revert.js → agents/claude-code/revert.js} +2 -1
- package/dist/agents/claude-code/revert.js.map +1 -0
- package/dist/agents/claude-code/settings.d.ts +33 -0
- package/dist/{config.js → agents/claude-code/settings.js} +6 -57
- package/dist/agents/claude-code/settings.js.map +1 -0
- package/dist/{snippets.d.ts → agents/claude-code/snippets.d.ts} +1 -18
- package/dist/{snippets.js → agents/claude-code/snippets.js} +0 -19
- package/dist/agents/claude-code/snippets.js.map +1 -0
- package/dist/agents/claude-code/status.d.ts +12 -0
- package/dist/agents/claude-code/status.js +42 -0
- package/dist/agents/claude-code/status.js.map +1 -0
- package/dist/agents/claude-code/verify.d.ts +39 -0
- package/dist/{verify.js → agents/claude-code/verify.js} +4 -135
- package/dist/agents/claude-code/verify.js.map +1 -0
- package/dist/agents/codex/config.d.ts +20 -0
- package/dist/agents/codex/config.js +344 -0
- package/dist/agents/codex/config.js.map +1 -0
- package/dist/agents/codex/index.d.ts +2 -0
- package/dist/agents/codex/index.js +79 -0
- package/dist/agents/codex/index.js.map +1 -0
- package/dist/agents/codex/snippets.d.ts +23 -0
- package/dist/agents/codex/snippets.js +39 -0
- package/dist/agents/codex/snippets.js.map +1 -0
- package/dist/agents/codex/status.d.ts +8 -0
- package/dist/agents/codex/status.js +36 -0
- package/dist/agents/codex/status.js.map +1 -0
- package/dist/agents/codex/toml.d.ts +57 -0
- package/dist/agents/codex/toml.js +196 -0
- package/dist/agents/codex/toml.js.map +1 -0
- package/dist/agents/codex/verify.d.ts +2 -0
- package/dist/agents/codex/verify.js +43 -0
- package/dist/agents/codex/verify.js.map +1 -0
- package/dist/agents/deps.d.ts +3 -0
- package/dist/agents/deps.js +10 -0
- package/dist/agents/deps.js.map +1 -0
- package/dist/agents/registry.d.ts +10 -0
- package/dist/agents/registry.js +14 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/agents/types.d.ts +276 -0
- package/dist/agents/types.js +3 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/args.d.ts +2 -3
- package/dist/args.js +7 -9
- package/dist/args.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +21 -14
- package/dist/cli.js.map +1 -1
- package/dist/fs/safeFile.d.ts +20 -0
- package/dist/fs/safeFile.js +50 -0
- package/dist/fs/safeFile.js.map +1 -0
- package/dist/{snapshot.d.ts → fs/snapshot.d.ts} +2 -2
- package/dist/{snapshot.js → fs/snapshot.js} +2 -2
- package/dist/fs/snapshot.js.map +1 -0
- package/dist/login/keychain/linux.d.ts +1 -1
- package/dist/login/keychain/linux.js +1 -1
- package/dist/login/keychain/linux.js.map +1 -1
- package/dist/precheck.d.ts +4 -1
- package/dist/precheck.js +12 -9
- package/dist/precheck.js.map +1 -1
- package/dist/process.d.ts +26 -0
- package/dist/process.js +94 -0
- package/dist/process.js.map +1 -0
- package/dist/report.d.ts +17 -25
- package/dist/report.js +36 -62
- package/dist/report.js.map +1 -1
- package/dist/result.d.ts +5 -5
- package/dist/result.js +5 -5
- package/dist/result.js.map +1 -1
- package/dist/router.d.ts +6 -4
- package/dist/router.js +132 -120
- package/dist/router.js.map +1 -1
- package/dist/telemetry/amplitudeHttp.js +1 -0
- package/dist/telemetry/amplitudeHttp.js.map +1 -1
- package/dist/telemetry/events.d.ts +10 -5
- package/dist/telemetry/events.js +0 -6
- package/dist/telemetry/events.js.map +1 -1
- package/dist/telemetry/telemetry.d.ts +6 -2
- package/dist/telemetry/telemetry.js +19 -8
- package/dist/telemetry/telemetry.js.map +1 -1
- package/package.json +3 -3
- package/dist/config.d.ts +0 -83
- package/dist/config.js.map +0 -1
- package/dist/revert.d.ts +0 -60
- package/dist/revert.js.map +0 -1
- package/dist/snapshot.js.map +0 -1
- package/dist/snippets.js.map +0 -1
- package/dist/verify.d.ts +0 -119
- package/dist/verify.js.map +0 -1
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
* timeout or unrecognised failure stays a warning, so a flaky network never undoes a
|
|
10
10
|
* good write.
|
|
11
11
|
*/
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { DEFAULT_URLS, isInsecureGateway } from "./args.js";
|
|
12
|
+
import { DEFAULT_URLS, isInsecureGateway } from "../../args.js";
|
|
13
|
+
import { findOnPath } from "../../process.js";
|
|
15
14
|
export const CLAUDE_COMMAND = "claude";
|
|
16
15
|
/* An instruction with a trivial answer, and it names itself so a gateway trace shows
|
|
17
16
|
* why the request happened. Both halves matter: "ai21-gateway CLI verification" alone
|
|
@@ -40,29 +39,6 @@ export const PING_BODY = {
|
|
|
40
39
|
max_tokens: 64,
|
|
41
40
|
messages: [{ role: "user", content: "Hello through the gateway" }],
|
|
42
41
|
};
|
|
43
|
-
/** npm installs the Claude Code CLI as `claude.cmd`, so this must not be empty. */
|
|
44
|
-
const DEFAULT_PATHEXT = ".COM;.EXE;.BAT;.CMD";
|
|
45
|
-
/**
|
|
46
|
-
* Hand-rolled rather than shelling out to `which`/`where`, which is slower and
|
|
47
|
-
* absent from stripped Windows images. `node:path`'s `join` and `delimiter` follow
|
|
48
|
-
* the *host* platform, so they cannot resolve a Windows PATH under test on macOS.
|
|
49
|
-
*/
|
|
50
|
-
export function findOnPath(command, lookup) {
|
|
51
|
-
const windows = lookup.platform === "win32";
|
|
52
|
-
const separator = windows ? ";" : ":";
|
|
53
|
-
const raw = lookup.processEnv.PATH ?? (windows ? lookup.processEnv.Path : undefined) ?? "";
|
|
54
|
-
const extensions = windows ? (lookup.processEnv.PATHEXT ?? DEFAULT_PATHEXT).split(";") : [""];
|
|
55
|
-
for (const dir of raw.split(separator)) {
|
|
56
|
-
if (dir === "")
|
|
57
|
-
continue;
|
|
58
|
-
for (const extension of extensions) {
|
|
59
|
-
const candidate = `${dir.replace(/[\\/]+$/, "")}${windows ? "\\" : "/"}${command}${extension}`;
|
|
60
|
-
if (lookup.isExecutableFile(candidate))
|
|
61
|
-
return candidate;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return undefined;
|
|
65
|
-
}
|
|
66
42
|
/** Blanks every credential in play, wherever it appears. */
|
|
67
43
|
function redactSecrets(text, ctx) {
|
|
68
44
|
let redacted = text;
|
|
@@ -106,7 +82,7 @@ async function viaClaude(executable, ctx, deps) {
|
|
|
106
82
|
return { kind: "passed", via: "claude-cli" };
|
|
107
83
|
// Printed before any request is made, so it cannot be a gateway or network symptom.
|
|
108
84
|
if (!result.timedOut && result.code !== null && NOT_LOGGED_IN.test(result.output)) {
|
|
109
|
-
return { kind: "no-
|
|
85
|
+
return { kind: "no-subscription", via: "claude-cli", reason: "logged-out" };
|
|
110
86
|
}
|
|
111
87
|
const failed = (reason) => ({ kind: "failed", via: "claude-cli", reason });
|
|
112
88
|
if (result.timedOut) {
|
|
@@ -243,7 +219,7 @@ async function viaDirectPing(anthropicKey, ctx, deps) {
|
|
|
243
219
|
if (response.ok)
|
|
244
220
|
return { kind: "passed", via: "direct-ping" };
|
|
245
221
|
if (response.status === 401 && isAnthropicAuthError((await response.text?.()) ?? "")) {
|
|
246
|
-
return { kind: "no-
|
|
222
|
+
return { kind: "no-subscription", via: "direct-ping", reason: "key-rejected" };
|
|
247
223
|
}
|
|
248
224
|
const hint = STATUS_HINTS[response.status];
|
|
249
225
|
const note = response.status === 401 ? environmentNote(ctx) : "";
|
|
@@ -258,41 +234,6 @@ async function viaDirectPing(anthropicKey, ctx, deps) {
|
|
|
258
234
|
return failed(`the gateway could not be reached at ${ctx.urls.gateway}`);
|
|
259
235
|
}
|
|
260
236
|
}
|
|
261
|
-
/** `claude auth status` is local and answers in about a second. */
|
|
262
|
-
export const AUTH_STATUS_TIMEOUT_MS = 5_000;
|
|
263
|
-
/**
|
|
264
|
-
* Asks `claude auth status`, which reads local state only, whether Claude Code has any
|
|
265
|
-
* credential — so a missing one is caught before anything is written. Only an explicit
|
|
266
|
-
* `"loggedIn": false` with no auth method counts as logged out, and only for Anthropic's
|
|
267
|
-
* own API: an older `claude` without the subcommand, unparseable output, or a Bedrock or
|
|
268
|
-
* Vertex setup are all inconclusive and leave the decision to verification.
|
|
269
|
-
*/
|
|
270
|
-
export async function checkClaudeLogin(cwd, deps) {
|
|
271
|
-
const executable = findOnPath(CLAUDE_COMMAND, deps.lookup);
|
|
272
|
-
if (executable === undefined)
|
|
273
|
-
return "inconclusive";
|
|
274
|
-
const result = await deps.runCommand(executable, ["auth", "status"], { cwd, timeoutMs: AUTH_STATUS_TIMEOUT_MS });
|
|
275
|
-
if (result.timedOut || result.code === null)
|
|
276
|
-
return "inconclusive";
|
|
277
|
-
const start = result.output.indexOf("{");
|
|
278
|
-
const end = result.output.lastIndexOf("}");
|
|
279
|
-
if (start === -1 || end < start)
|
|
280
|
-
return "inconclusive";
|
|
281
|
-
let status;
|
|
282
|
-
try {
|
|
283
|
-
status = JSON.parse(result.output.slice(start, end + 1));
|
|
284
|
-
}
|
|
285
|
-
catch {
|
|
286
|
-
return "inconclusive";
|
|
287
|
-
}
|
|
288
|
-
if (typeof status !== "object" || status === null)
|
|
289
|
-
return "inconclusive";
|
|
290
|
-
const { loggedIn, authMethod, apiProvider } = status;
|
|
291
|
-
if (loggedIn === true)
|
|
292
|
-
return "logged-in";
|
|
293
|
-
const firstParty = apiProvider === undefined || apiProvider === "firstParty";
|
|
294
|
-
return loggedIn === false && authMethod === "none" && firstParty ? "logged-out" : "inconclusive";
|
|
295
|
-
}
|
|
296
237
|
export async function verify(ctx, deps) {
|
|
297
238
|
const executable = findOnPath(CLAUDE_COMMAND, deps.lookup);
|
|
298
239
|
if (executable !== undefined)
|
|
@@ -302,76 +243,4 @@ export async function verify(ctx, deps) {
|
|
|
302
243
|
return viaDirectPing(anthropicKey, ctx, deps);
|
|
303
244
|
return { kind: "skipped", hint: `${manualHint(ctx.cwd)}.` };
|
|
304
245
|
}
|
|
305
|
-
/** Cap on captured subprocess output — only the first line is ever quoted. */
|
|
306
|
-
const MAX_CAPTURED_OUTPUT = 4_096;
|
|
307
|
-
function runCommand(executable, args, opts) {
|
|
308
|
-
return new Promise((resolve) => {
|
|
309
|
-
// A .cmd cannot be spawned without a shell since the CVE-2024-27980 fix. Safe
|
|
310
|
-
// here because every argument is a literal. Killing the shell may orphan the
|
|
311
|
-
// real `claude`, which exits on its own shortly after.
|
|
312
|
-
const shell = /\.(cmd|bat)$/i.test(executable);
|
|
313
|
-
const child = spawn(shell ? `"${executable}"` : executable, [...args], {
|
|
314
|
-
cwd: opts.cwd,
|
|
315
|
-
shell,
|
|
316
|
-
// stdin closed: `claude` must never sit waiting on input we will not send.
|
|
317
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
318
|
-
});
|
|
319
|
-
let output = "";
|
|
320
|
-
const capture = (chunk) => {
|
|
321
|
-
if (output.length < MAX_CAPTURED_OUTPUT)
|
|
322
|
-
output += chunk.toString("utf8");
|
|
323
|
-
};
|
|
324
|
-
child.stdout?.on("data", capture);
|
|
325
|
-
child.stderr?.on("data", capture);
|
|
326
|
-
let done = false;
|
|
327
|
-
const settle = (result) => {
|
|
328
|
-
if (done)
|
|
329
|
-
return;
|
|
330
|
-
done = true;
|
|
331
|
-
clearTimeout(timer);
|
|
332
|
-
resolve(result);
|
|
333
|
-
};
|
|
334
|
-
/**
|
|
335
|
-
* Our own timer, not spawn's `timeout`: Windows reports a killed process as an
|
|
336
|
-
* ordinary non-zero exit, so an inferred timeout would be wrong there.
|
|
337
|
-
*
|
|
338
|
-
* It resolves the promise itself rather than killing and waiting for `close`.
|
|
339
|
-
* `close` fires when the *stdio* closes, and anything `claude` spawned inherits
|
|
340
|
-
* those pipes — an MCP server or a hook outliving its parent holds them open, so
|
|
341
|
-
* the kill lands and `close` never comes. That hung the CLI indefinitely after a
|
|
342
|
-
* write it had already completed. The budget is now a guarantee, not a hope.
|
|
343
|
-
*/
|
|
344
|
-
let timedOut = false;
|
|
345
|
-
const timer = setTimeout(() => {
|
|
346
|
-
timedOut = true;
|
|
347
|
-
child.kill("SIGKILL");
|
|
348
|
-
settle({ code: null, timedOut, output: output.trim() });
|
|
349
|
-
}, opts.timeoutMs);
|
|
350
|
-
// A spawn error may never emit `close`, so both paths settle. Only the errno is
|
|
351
|
-
// kept — the message carries an absolute path.
|
|
352
|
-
child.once("error", (err) => settle({ code: null, timedOut, output: err.code ?? "" }));
|
|
353
|
-
child.once("close", (code) => settle({ code, timedOut, output: output.trim() }));
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
export function isExecutableFile(candidate) {
|
|
357
|
-
try {
|
|
358
|
-
if (!statSync(candidate).isFile())
|
|
359
|
-
return false;
|
|
360
|
-
// The execute bit is meaningless on Windows, where the extension decides.
|
|
361
|
-
if (process.platform !== "win32")
|
|
362
|
-
accessSync(candidate, constants.X_OK);
|
|
363
|
-
return true;
|
|
364
|
-
}
|
|
365
|
-
catch {
|
|
366
|
-
return false;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/** The real-world adapters, kept here so `cli.ts` stays a thin edge. */
|
|
370
|
-
export function nodeVerifyDeps(processEnv) {
|
|
371
|
-
return {
|
|
372
|
-
lookup: { platform: process.platform, processEnv, isExecutableFile },
|
|
373
|
-
runCommand,
|
|
374
|
-
fetchImpl: fetch,
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
246
|
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../../src/agents/claude-code/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ConfigPaths } from "../../fs/safeFile.js";
|
|
2
|
+
import type { ConfigOutcome, RevertOptions, RevertOutcome, SnippetInputs } from "../types.js";
|
|
3
|
+
import { type Scan } from "./toml.js";
|
|
4
|
+
/** What a conflict shows instead of an AI21 key. */
|
|
5
|
+
export declare const REDACTED = "****";
|
|
6
|
+
export declare const MARKER_BEGIN = "# >>> AI21 Gateway (managed by ai21-gateway; `ai21-gateway uninstall --client codex` removes it)";
|
|
7
|
+
export declare const MARKER_END = "# <<< AI21 Gateway";
|
|
8
|
+
/** `CODEX_HOME` wins, as it does for Codex; a relative one is resolved against the cwd, as Codex does. */
|
|
9
|
+
export declare function codexHome(env: {
|
|
10
|
+
readonly home: string;
|
|
11
|
+
readonly cwd: string;
|
|
12
|
+
readonly processEnv: Record<string, string | undefined>;
|
|
13
|
+
}): string;
|
|
14
|
+
export declare function resolveCodexPaths(dir: string): ConfigPaths;
|
|
15
|
+
/** The agent id our block names, for the uninstall guard. */
|
|
16
|
+
export declare function storedAgentId(scanned: Scan): string | undefined;
|
|
17
|
+
export declare function writeCodexConfig(paths: ConfigPaths, inputs: SnippetInputs, options: {
|
|
18
|
+
readonly force: boolean;
|
|
19
|
+
}): ConfigOutcome;
|
|
20
|
+
export declare function revertCodexConfig(paths: ConfigPaths, options: RevertOptions): RevertOutcome;
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Writing and reverting our part of `~/.codex/config.toml`.
|
|
3
|
+
*
|
|
4
|
+
* Same constraint as Claude Code's writer: this edits a file the developer owns. Every
|
|
5
|
+
* path leaves it byte-identical or replaces it atomically, with a `.bak` of the last
|
|
6
|
+
* state that was not ours, and no refusal touches it.
|
|
7
|
+
*
|
|
8
|
+
* What we own: the root `model_provider` line, and the `[model_providers.ai21]` and
|
|
9
|
+
* `[model_providers.ai21.http_headers]` tables, wrapped in marker comments when we add
|
|
10
|
+
* them. Whether a file is *ours* is judged by an `x-ai21-client` header naming this
|
|
11
|
+
* tool — a hand-pasted block from the dashboard has an `x-ai21-key` too, and must stay
|
|
12
|
+
* the developer's until they say otherwise with `--yes`.
|
|
13
|
+
*/
|
|
14
|
+
import { chmodSync, copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync, realpathSync, } from "node:fs";
|
|
15
|
+
import { dirname, join, resolve } from "node:path";
|
|
16
|
+
import { atomicWrite, backupPathFor, describeFsError } from "../../fs/safeFile.js";
|
|
17
|
+
import { ROOT_LINE, codexHeaders, codexTables } from "./snippets.js";
|
|
18
|
+
import { HEADERS_TABLE, PROVIDER_ID, PROVIDER_TABLE, entries, joinLines, newlineOf, removeRange, scan, stringValue, } from "./toml.js";
|
|
19
|
+
/** What a conflict shows instead of an AI21 key. */
|
|
20
|
+
export const REDACTED = "****";
|
|
21
|
+
export const MARKER_BEGIN = "# >>> AI21 Gateway (managed by ai21-gateway; `ai21-gateway uninstall --client codex` removes it)";
|
|
22
|
+
export const MARKER_END = "# <<< AI21 Gateway";
|
|
23
|
+
/** `CODEX_HOME` wins, as it does for Codex; a relative one is resolved against the cwd, as Codex does. */
|
|
24
|
+
export function codexHome(env) {
|
|
25
|
+
const override = env.processEnv.CODEX_HOME;
|
|
26
|
+
return override !== undefined && override !== "" ? resolve(env.cwd, override) : join(env.home, ".codex");
|
|
27
|
+
}
|
|
28
|
+
export function resolveCodexPaths(dir) {
|
|
29
|
+
const settings = join(dir, "config.toml");
|
|
30
|
+
return { settings, backup: `${settings}.bak` };
|
|
31
|
+
}
|
|
32
|
+
/** Our client tag marks a block this tool wrote; nothing else does. */
|
|
33
|
+
function isOurs(scanned) {
|
|
34
|
+
const client = entries(scanned, scanned.headers).get("x-ai21-client");
|
|
35
|
+
return client !== undefined && /^"ai21-gateway-cli\//.test(client);
|
|
36
|
+
}
|
|
37
|
+
/** The agent id our block names, for the uninstall guard. */
|
|
38
|
+
export function storedAgentId(scanned) {
|
|
39
|
+
const raw = entries(scanned, scanned.headers).get("x-agent-id");
|
|
40
|
+
return raw === undefined ? undefined : stringValue(`x = ${raw}`);
|
|
41
|
+
}
|
|
42
|
+
/** The value a root `model_provider` line assigns, or undefined without one. */
|
|
43
|
+
function rootProvider(scanned) {
|
|
44
|
+
if (scanned.rootModelProvider === undefined)
|
|
45
|
+
return undefined;
|
|
46
|
+
return stringValue(scanned.lines[scanned.rootModelProvider].text);
|
|
47
|
+
}
|
|
48
|
+
/** Resolves a symlink one level, so a write goes through the link rather than replacing it. */
|
|
49
|
+
function followLink(path) {
|
|
50
|
+
try {
|
|
51
|
+
if (lstatSync(path, { throwIfNoEntry: false })?.isSymbolicLink() === true) {
|
|
52
|
+
return resolve(dirname(path), readlinkSync(path));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return path;
|
|
57
|
+
}
|
|
58
|
+
return path;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The file with our part put in: the root line replaced in place or inserted above the
|
|
62
|
+
* first table, and our tables replaced in place or appended in a marked block. Every
|
|
63
|
+
* position comes from the scan; nothing is found again by matching text, since another
|
|
64
|
+
* provider's table can hold the same lines as ours.
|
|
65
|
+
*/
|
|
66
|
+
function withOurs(scanned, inputs) {
|
|
67
|
+
const nl = newlineOf(scanned.lines);
|
|
68
|
+
const asLines = (texts) => texts.map((text) => ({ text, eol: nl }));
|
|
69
|
+
const tables = codexTables(inputs);
|
|
70
|
+
const split = tables.indexOf(`[${HEADERS_TABLE}]`);
|
|
71
|
+
const providerLines = tables.slice(0, split);
|
|
72
|
+
const headerLines = tables.slice(split);
|
|
73
|
+
/** A region's last line that is a key, so comments and blanks after it stay put. */
|
|
74
|
+
const keysEnd = (region) => {
|
|
75
|
+
let end = region.end;
|
|
76
|
+
while (end > region.start + 1 && /^\s*(#.*)?$/.test(scanned.lines[end - 1].text))
|
|
77
|
+
end -= 1;
|
|
78
|
+
return end;
|
|
79
|
+
};
|
|
80
|
+
// Edits as [start, end, replacement], applied bottom-up so earlier indices stay valid.
|
|
81
|
+
const edits = [];
|
|
82
|
+
const { provider, headers } = scanned;
|
|
83
|
+
if (provider === undefined && headers === undefined) {
|
|
84
|
+
const lines = scanned.lines;
|
|
85
|
+
const last = lines.at(-1);
|
|
86
|
+
const fix = last !== undefined && last.eol === "" ? [{ ...last, eol: nl }] : [];
|
|
87
|
+
const gap = lines.length > 0 && lines.at(-1).text.trim() !== "" ? asLines([""]) : [];
|
|
88
|
+
const at = lines.length - fix.length;
|
|
89
|
+
edits.push([at, lines.length, [...fix, ...gap, ...asLines([MARKER_BEGIN, ...tables, MARKER_END])]]);
|
|
90
|
+
}
|
|
91
|
+
else if (provider !== undefined && headers !== undefined) {
|
|
92
|
+
edits.push([provider.start, keysEnd(provider), asLines(providerLines)]);
|
|
93
|
+
edits.push([headers.start, keysEnd(headers), asLines(headerLines)]);
|
|
94
|
+
}
|
|
95
|
+
else if (provider !== undefined) {
|
|
96
|
+
// Headers go straight after the provider table's keys.
|
|
97
|
+
edits.push([provider.start, keysEnd(provider), asLines([...providerLines, ...headerLines])]);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Provider keys go straight before the headers table.
|
|
101
|
+
edits.push([headers.start, keysEnd(headers), asLines([...providerLines, ...headerLines])]);
|
|
102
|
+
}
|
|
103
|
+
let lines = [...scanned.lines];
|
|
104
|
+
for (const [start, end, replacement] of edits.sort((x, y) => y[0] - x[0])) {
|
|
105
|
+
lines = [...lines.slice(0, start), ...replacement, ...lines.slice(end)];
|
|
106
|
+
}
|
|
107
|
+
// Root keys sit before the first table, and every edit above is at or after it.
|
|
108
|
+
if (scanned.rootModelProvider !== undefined) {
|
|
109
|
+
lines[scanned.rootModelProvider] = { text: ROOT_LINE, eol: lines[scanned.rootModelProvider].eol };
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
lines = [...asLines([ROOT_LINE]), ...lines];
|
|
113
|
+
}
|
|
114
|
+
const joined = joinLines(lines);
|
|
115
|
+
return joined.endsWith(nl) ? joined : joined + nl;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* A structural re-read of what we are about to write: exactly one of each of our tables,
|
|
119
|
+
* the root line selecting ours, and nothing the scanner would refuse. Not a TOML parser —
|
|
120
|
+
* a line-level check that our own edit did not break the shape we rely on.
|
|
121
|
+
*/
|
|
122
|
+
function checkWritten(text) {
|
|
123
|
+
const again = scan(text);
|
|
124
|
+
if (again.unsupported !== undefined)
|
|
125
|
+
return "the edited file would not keep a valid shape";
|
|
126
|
+
if (again.provider === undefined || again.headers === undefined)
|
|
127
|
+
return "the edited file lost a provider table";
|
|
128
|
+
if (rootProvider(again) !== PROVIDER_ID)
|
|
129
|
+
return "the edited file would not select the AI21 provider";
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
/** Every value we would set, compared with what the file holds now. */
|
|
133
|
+
function differences(scanned, inputs) {
|
|
134
|
+
const changed = [];
|
|
135
|
+
const conflicts = [];
|
|
136
|
+
const want = (key, current, desired, conflicting) => {
|
|
137
|
+
if (current === desired)
|
|
138
|
+
return;
|
|
139
|
+
changed.push(key);
|
|
140
|
+
// The key is masked here, where the conflict is made, so no later step can print it.
|
|
141
|
+
const secret = key === `${HEADERS_TABLE}.x-ai21-key`;
|
|
142
|
+
if (current !== undefined && conflicting) {
|
|
143
|
+
conflicts.push({ key, current: secret ? REDACTED : current, desired: secret ? REDACTED : desired });
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const provider = entries(scanned, scanned.provider);
|
|
147
|
+
const headers = entries(scanned, scanned.headers);
|
|
148
|
+
// A root model_provider naming another provider is the developer's choice; ours replaces it.
|
|
149
|
+
want("model_provider", rootProvider(scanned), PROVIDER_ID, true);
|
|
150
|
+
// Only the provider table's own lines: they end where the headers table begins.
|
|
151
|
+
const tables = codexTables(inputs);
|
|
152
|
+
const providerKeyLines = tables.slice(1, tables.indexOf(`[${HEADERS_TABLE}]`));
|
|
153
|
+
for (const line of providerKeyLines) {
|
|
154
|
+
const [key] = line.split(" = ");
|
|
155
|
+
want(`${PROVIDER_TABLE}.${key}`, provider.get(key), line.slice(line.indexOf("=") + 1).trim(), true);
|
|
156
|
+
}
|
|
157
|
+
for (const [key, value] of codexHeaders(inputs)) {
|
|
158
|
+
const current = headers.get(key);
|
|
159
|
+
want(`${HEADERS_TABLE}.${key}`, current === undefined ? undefined : stringValue(`x = ${current}`), value, true);
|
|
160
|
+
}
|
|
161
|
+
// Keys in our tables that we do not write, e.g. a stale x-ai21-user-id: they go too.
|
|
162
|
+
for (const key of [...provider.keys()].filter((k) => !providerKeyLines.some((l) => l.startsWith(`${k} =`)))) {
|
|
163
|
+
changed.push(`${PROVIDER_TABLE}.${key}`);
|
|
164
|
+
conflicts.push({ key: `${PROVIDER_TABLE}.${key}`, current: provider.get(key), desired: "(removed)" });
|
|
165
|
+
}
|
|
166
|
+
for (const key of [...headers.keys()].filter((k) => !codexHeaders(inputs).some(([h]) => h === k))) {
|
|
167
|
+
changed.push(`${HEADERS_TABLE}.${key}`);
|
|
168
|
+
conflicts.push({ key: `${HEADERS_TABLE}.${key}`, current: headers.get(key), desired: "(removed)" });
|
|
169
|
+
}
|
|
170
|
+
return { changed, conflicts };
|
|
171
|
+
}
|
|
172
|
+
function load(path) {
|
|
173
|
+
let realPath;
|
|
174
|
+
let raw;
|
|
175
|
+
try {
|
|
176
|
+
realPath = realpathSync(path);
|
|
177
|
+
raw = readFileSync(realPath, "utf8");
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
return { problem: { kind: "failed", reason: describeFsError(err) } };
|
|
181
|
+
}
|
|
182
|
+
const scanned = scan(raw);
|
|
183
|
+
if (scanned.unsupported !== undefined)
|
|
184
|
+
return { problem: { kind: "malformed", reason: scanned.unsupported } };
|
|
185
|
+
return { loaded: { realPath, raw, scanned } };
|
|
186
|
+
}
|
|
187
|
+
export function writeCodexConfig(paths, inputs, options) {
|
|
188
|
+
const { settings: path } = paths;
|
|
189
|
+
const target = followLink(path);
|
|
190
|
+
if (!existsSync(path)) {
|
|
191
|
+
try {
|
|
192
|
+
mkdirSync(dirname(target), { recursive: true, mode: 0o700 });
|
|
193
|
+
atomicWrite(target, withOurs(scan(""), inputs));
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
return { kind: "failed", path, reason: describeFsError(err) };
|
|
197
|
+
}
|
|
198
|
+
return { kind: "created", path };
|
|
199
|
+
}
|
|
200
|
+
const result = load(path);
|
|
201
|
+
if ("problem" in result)
|
|
202
|
+
return { ...result.problem, path };
|
|
203
|
+
const { realPath, scanned } = result.loaded;
|
|
204
|
+
const { changed, conflicts } = differences(scanned, inputs);
|
|
205
|
+
// Same rule as Claude Code: any value that would change needs --yes, ours or not.
|
|
206
|
+
if (conflicts.length > 0 && !options.force)
|
|
207
|
+
return { kind: "conflict", path, conflicts };
|
|
208
|
+
if (changed.length === 0)
|
|
209
|
+
return { kind: "unchanged", path };
|
|
210
|
+
const next = withOurs(scanned, inputs);
|
|
211
|
+
const broken = checkWritten(next);
|
|
212
|
+
if (broken !== undefined)
|
|
213
|
+
return { kind: "malformed", path, reason: broken };
|
|
214
|
+
const backupPath = backupPathFor(paths, realPath);
|
|
215
|
+
try {
|
|
216
|
+
// The backup holds the last state that was not ours, so a re-run never buries it.
|
|
217
|
+
if (!isOurs(scanned)) {
|
|
218
|
+
copyFileSync(realPath, backupPath);
|
|
219
|
+
chmodSync(backupPath, 0o600);
|
|
220
|
+
}
|
|
221
|
+
atomicWrite(realPath, next);
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
return { kind: "failed", path, reason: describeFsError(err) };
|
|
225
|
+
}
|
|
226
|
+
return { kind: "updated", path, backup: backupPath, changed };
|
|
227
|
+
}
|
|
228
|
+
/** The file without our part: our tables removed, and the root line put back as it was before us. */
|
|
229
|
+
function withoutOurs(scanned, before) {
|
|
230
|
+
const removed = [];
|
|
231
|
+
const restored = [];
|
|
232
|
+
let lines = [...scanned.lines];
|
|
233
|
+
/* The backup holds the last state that was not ours. A table it has — a block the
|
|
234
|
+
* developer pasted by hand before `--yes` replaced it — goes back as it was, line for
|
|
235
|
+
* line; a table it lacks is one we added, so it goes. */
|
|
236
|
+
const previousLines = (name) => {
|
|
237
|
+
const region = before?.[name];
|
|
238
|
+
if (before === undefined || region === undefined)
|
|
239
|
+
return undefined;
|
|
240
|
+
let end = region.end;
|
|
241
|
+
while (end > region.start + 1 && /^\s*(#.*)?$/.test(before.lines[end - 1].text))
|
|
242
|
+
end -= 1;
|
|
243
|
+
return before.lines.slice(region.start, end);
|
|
244
|
+
};
|
|
245
|
+
const ours = ["provider", "headers"]
|
|
246
|
+
.filter((name) => scanned[name] !== undefined)
|
|
247
|
+
.sort((a, b) => scanned[b].start - scanned[a].start);
|
|
248
|
+
for (const name of ours) {
|
|
249
|
+
const region = scanned[name];
|
|
250
|
+
const table = name === "headers" ? HEADERS_TABLE : PROVIDER_TABLE;
|
|
251
|
+
const previous = previousLines(name);
|
|
252
|
+
let { start, end } = region;
|
|
253
|
+
while (end > start + 1 && /^\s*(#.*)?$/.test(lines[end - 1].text))
|
|
254
|
+
end -= 1;
|
|
255
|
+
if (previous !== undefined) {
|
|
256
|
+
lines = [...lines.slice(0, start), ...previous, ...lines.slice(end)];
|
|
257
|
+
restored.push(table);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
// Take our marker lines with us when they sit right around the tables.
|
|
261
|
+
end = region.end;
|
|
262
|
+
while (end < lines.length && lines[end].text === MARKER_END)
|
|
263
|
+
end += 1;
|
|
264
|
+
while (start > 0 && lines[start - 1].text.startsWith(MARKER_BEGIN))
|
|
265
|
+
start -= 1;
|
|
266
|
+
lines = removeRange(lines, start, end);
|
|
267
|
+
removed.push(table);
|
|
268
|
+
}
|
|
269
|
+
// A marker left behind by a hand edit between them.
|
|
270
|
+
lines = lines.filter((l) => !l.text.startsWith(MARKER_BEGIN) && l.text !== MARKER_END);
|
|
271
|
+
if (scanned.rootModelProvider !== undefined) {
|
|
272
|
+
const previous = before === undefined ? undefined : before.rootModelProvider;
|
|
273
|
+
const index = scanned.rootModelProvider;
|
|
274
|
+
if (previous !== undefined && rootProvider(before) !== PROVIDER_ID) {
|
|
275
|
+
lines[index] = { ...before.lines[previous], eol: lines[index].eol };
|
|
276
|
+
restored.push("model_provider");
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
lines = [...lines.slice(0, index), ...lines.slice(index + 1)];
|
|
280
|
+
removed.push("model_provider");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Leading blank lines we left by removing the root line.
|
|
284
|
+
while (lines.length > 0 && lines[0].text.trim() === "" && (scanned.lines[0]?.text.trim() ?? "") !== "")
|
|
285
|
+
lines.shift();
|
|
286
|
+
return { text: joinLines(lines), removed, restored };
|
|
287
|
+
}
|
|
288
|
+
export function revertCodexConfig(paths, options) {
|
|
289
|
+
const { settings: path } = paths;
|
|
290
|
+
if (!existsSync(followLink(path)))
|
|
291
|
+
return { kind: "not-configured", path };
|
|
292
|
+
const result = load(path);
|
|
293
|
+
if ("problem" in result)
|
|
294
|
+
return { ...result.problem, path };
|
|
295
|
+
const { realPath, raw, scanned } = result.loaded;
|
|
296
|
+
if (!isOurs(scanned))
|
|
297
|
+
return { kind: "not-configured", path };
|
|
298
|
+
if (options.agentIdGuard !== undefined) {
|
|
299
|
+
const stored = storedAgentId(scanned);
|
|
300
|
+
if (stored !== options.agentIdGuard) {
|
|
301
|
+
return { kind: "agent-mismatch", path, expected: options.agentIdGuard, actual: stored ?? "none" };
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
const backup = backupPathFor(paths, realPath);
|
|
305
|
+
let backupRaw;
|
|
306
|
+
let backupUnreadable = false;
|
|
307
|
+
if (existsSync(backup)) {
|
|
308
|
+
try {
|
|
309
|
+
backupRaw = readFileSync(backup, "utf8");
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
backupUnreadable = true;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
if (options.fromBackup) {
|
|
316
|
+
if (backupRaw === undefined)
|
|
317
|
+
return backupUnreadable
|
|
318
|
+
? { kind: "failed", path, reason: "the backup could not be read" }
|
|
319
|
+
: { kind: "no-backup", path, backup };
|
|
320
|
+
if (!options.force && withoutOurs(scanned, undefined).text !== withoutOurs(scan(backupRaw), undefined).text) {
|
|
321
|
+
return { kind: "drifted", path, backup };
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
// Byte for byte: "verbatim" includes the developer's formatting and comments.
|
|
325
|
+
copyFileSync(backup, realPath);
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
return { kind: "failed", path, reason: describeFsError(err) };
|
|
329
|
+
}
|
|
330
|
+
return { kind: "restored", path, backup };
|
|
331
|
+
}
|
|
332
|
+
const before = backupRaw === undefined ? undefined : scan(backupRaw);
|
|
333
|
+
const { text, removed, restored } = withoutOurs(scanned, before);
|
|
334
|
+
if (text === raw)
|
|
335
|
+
return { kind: "not-configured", path };
|
|
336
|
+
try {
|
|
337
|
+
atomicWrite(realPath, text);
|
|
338
|
+
}
|
|
339
|
+
catch (err) {
|
|
340
|
+
return { kind: "failed", path, reason: describeFsError(err) };
|
|
341
|
+
}
|
|
342
|
+
return { kind: "reverted", path, removed, restored, backupUnreadable };
|
|
343
|
+
}
|
|
344
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/agents/codex/config.ts"],"names":[],"mappings":"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"}
|