@bitkyc08/opencodex 2.38.0 → 2.39.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/bin/ocx.mjs +58 -6
- package/gui/dist/assets/index-D-lchsPw.js +112 -0
- package/gui/dist/assets/index-uvENYLin.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/baseten.svg +13 -0
- package/gui/dist/provider-icons/bizrouter.svg +41 -0
- package/gui/dist/provider-icons/cerebras.svg +26 -0
- package/gui/dist/provider-icons/deepinfra.svg +75 -0
- package/gui/dist/provider-icons/digitalocean.svg +10 -0
- package/gui/dist/provider-icons/featherless.svg +4 -0
- package/gui/dist/provider-icons/gajae-code.svg +410 -0
- package/gui/dist/provider-icons/hermes-agent.svg +207 -0
- package/gui/dist/provider-icons/hyperbolic.svg +18 -0
- package/gui/dist/provider-icons/kilo.svg +13 -0
- package/gui/dist/provider-icons/litellm.svg +1 -0
- package/gui/dist/provider-icons/minimax.svg +1 -0
- package/gui/dist/provider-icons/nanogpt.svg +74 -0
- package/gui/dist/provider-icons/nebius.svg +1 -0
- package/gui/dist/provider-icons/neuralwatt.svg +27 -0
- package/gui/dist/provider-icons/nous.svg +149 -0
- package/gui/dist/provider-icons/novita.svg +32 -0
- package/gui/dist/provider-icons/orcarouter.svg +175 -0
- package/gui/dist/provider-icons/parallel.svg +13 -0
- package/gui/dist/provider-icons/sambanova.svg +276 -0
- package/gui/dist/provider-icons/scaleway.svg +11 -0
- package/gui/dist/provider-icons/siliconflow.svg +18 -0
- package/gui/dist/provider-icons/synthetic.svg +12 -0
- package/gui/dist/provider-icons/together.svg +18 -0
- package/gui/dist/provider-icons/umans.svg +30 -0
- package/gui/dist/provider-icons/venice.svg +165 -0
- package/gui/dist/provider-icons/vultr.svg +15 -0
- package/gui/dist/provider-icons/zai.svg +218 -0
- package/gui/dist/provider-icons/zenmux.svg +1 -0
- package/package.json +1 -1
- package/src/adapters/cursor/live-models.ts +1 -0
- package/src/adapters/openai-responses.ts +72 -10
- package/src/bridge.ts +15 -15
- package/src/cli/dispatch.ts +54 -18
- package/src/cli/index.ts +420 -30
- package/src/cli/integrations.ts +24 -2
- package/src/cli/uninstall-plan.ts +86 -0
- package/src/codex/account-store.ts +121 -8
- package/src/codex/auth-api.ts +202 -33
- package/src/codex/catalog/provider-fetch.ts +76 -9
- package/src/codex/history-job.ts +10 -0
- package/src/codex/history-manifest.ts +35 -2
- package/src/codex/history-provider.ts +196 -19
- package/src/codex/history-worker.ts +3 -0
- package/src/codex/quota-401-recovery.ts +190 -0
- package/src/codex/quota-recovery-timing.ts +28 -0
- package/src/codex/quota.ts +6 -0
- package/src/codex/routing.ts +68 -16
- package/src/codex/subagent-model-fallback.ts +4 -1
- package/src/config/pending-teardown-names.d.mts +8 -0
- package/src/config/pending-teardown-names.mjs +69 -0
- package/src/config/pending-teardown.ts +286 -0
- package/src/generated/compatibility-version.json +84 -32
- package/src/integrations/journal.ts +12 -1
- package/src/integrations/writer.ts +82 -7
- package/src/lib/process-control.ts +30 -5
- package/src/lib/state-store-registrations.ts +8 -0
- package/src/oauth/index.ts +220 -13
- package/src/oauth/store.ts +220 -18
- package/src/responses/spill-store.ts +20 -0
- package/src/responses/state.ts +288 -2
- package/src/server/management/integration-routes.ts +36 -5
- package/src/server/management-api.ts +66 -12
- package/src/server/responses/encrypted-payload.ts +18 -1
- package/src/server/stop-teardown.ts +84 -0
- package/src/service.ts +155 -20
- package/src/update/index.ts +36 -4
- package/src/update/proxy-liveness-probe.d.mts +6 -0
- package/src/update/proxy-liveness-probe.mjs +84 -0
- package/src/update/stop-contract.d.mts +2 -0
- package/src/update/stop-contract.mjs +15 -0
- package/src/update/stop-decision.d.mts +10 -0
- package/src/update/stop-decision.mjs +34 -0
- package/src/vision/eligibility.ts +19 -1
- package/src/vision/index.ts +4 -18
- package/gui/dist/assets/index-C14iCj_Q.js +0 -112
- package/gui/dist/assets/index-D7PIz7_g.css +0 -1
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
2
|
+
import { existsSync, readdirSync, readFileSync, renameSync, unlinkSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { assertNotRealHomeUnderTest } from "../lib/test-home-guard";
|
|
5
|
+
import { atomicWriteFile } from "./atomic-write";
|
|
6
|
+
import { getConfigDir } from "./paths";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Ownership receipt for a deferred shared teardown (#3008).
|
|
10
|
+
*
|
|
11
|
+
* `ocx stop` asks the proxy NOT to restore native Codex and the Grok fence, because a
|
|
12
|
+
* stopped Task Scheduler can respawn the proxy and a survivor must keep its client
|
|
13
|
+
* config. That hands one obligation to the parent — and a bare query flag cannot express
|
|
14
|
+
* an obligation: if the parent dies between the child's exit and its own restore, the
|
|
15
|
+
* shared config keeps pointing at a proxy that is gone, with nothing on disk saying so.
|
|
16
|
+
*
|
|
17
|
+
* The receipt is that missing state. The parent writes it BEFORE asking for a deferred
|
|
18
|
+
* stop and removes it only after its own restore, so a later `ocx stop`/`ocx update` can
|
|
19
|
+
* see the abandoned obligation and finish it once that proxy is proven down.
|
|
20
|
+
*
|
|
21
|
+
* ## Why the nonce is the FILENAME
|
|
22
|
+
*
|
|
23
|
+
* One shared file cannot be cleared safely. Read-compare-unlink is three syscalls, and a
|
|
24
|
+
* concurrent stop replacing the file between the compare and the unlink means this run
|
|
25
|
+
* deletes an obligation it never owned — the check passed against bytes that are already
|
|
26
|
+
* gone. Giving each claim its own path removes the race rather than serializing it:
|
|
27
|
+
* `unlink` names one specific obligation, so it can only ever delete that one. Two
|
|
28
|
+
* concurrent stops hold two receipts, which is the truth of the situation.
|
|
29
|
+
*/
|
|
30
|
+
export type PendingTeardownReceipt = {
|
|
31
|
+
/** Process that accepted the obligation, so a live owner is distinguishable from a dead one. */
|
|
32
|
+
ownerPid: number;
|
|
33
|
+
/** Identity of this claim; also its filename, which is what makes a clear a single-syscall delete. */
|
|
34
|
+
nonce: string;
|
|
35
|
+
/** ISO timestamp, for diagnostics only; recovery is decided by liveness, not by age. */
|
|
36
|
+
createdAt: string;
|
|
37
|
+
/**
|
|
38
|
+
* Endpoint the owner was stopping.
|
|
39
|
+
*
|
|
40
|
+
* Recovery has to prove THAT proxy is down, and after a crash the runtime-port record
|
|
41
|
+
* is usually gone. Falling back to the configured port asks the wrong question for a
|
|
42
|
+
* proxy started with an explicit `--port`: the configured port refuses while the live
|
|
43
|
+
* one keeps serving, and its client config gets torn out from under it.
|
|
44
|
+
*/
|
|
45
|
+
endpoint: { hostname: string; port: number };
|
|
46
|
+
/**
|
|
47
|
+
* How the endpoint was obtained.
|
|
48
|
+
*
|
|
49
|
+
* `exact` came from the runtime record or a successful liveness probe — the address the
|
|
50
|
+
* stop actually contacted. `guessed` is the configured listen address, recorded because
|
|
51
|
+
* an obligation with a weak address beats no obligation at all, but it is NOT evidence:
|
|
52
|
+
* a proxy on an explicit `--port` can be respawned there while the configured port
|
|
53
|
+
* refuses, and treating that refusal as proof would restore under a live proxy. A
|
|
54
|
+
* guessed receipt therefore fails closed into manual recovery.
|
|
55
|
+
*/
|
|
56
|
+
endpointSource: "exact" | "guessed";
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* What is on disk, kept distinct from what it means.
|
|
61
|
+
*
|
|
62
|
+
* Collapsing a malformed file into "no receipt" loses the one fact recovery needs: an
|
|
63
|
+
* obligation may still be outstanding, and its owner can no longer be identified. That
|
|
64
|
+
* state must not silently authorize a deferral, and it must not wedge every later stop
|
|
65
|
+
* either — see {@link quarantinePendingTeardown}.
|
|
66
|
+
*/
|
|
67
|
+
export type PendingTeardownRead =
|
|
68
|
+
| { state: "missing" }
|
|
69
|
+
| { state: "valid"; receipt: PendingTeardownReceipt }
|
|
70
|
+
| { state: "invalid"; nonce: string; detail: string };
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The home itself could not be listed.
|
|
74
|
+
*
|
|
75
|
+
* Distinct from an invalid receipt: there is no file to quarantine and no nonce to name,
|
|
76
|
+
* so it must never be fed to the receipt machinery. It blocks like any obligation, but the
|
|
77
|
+
* remedy is to fix the directory and retry, not to remove something.
|
|
78
|
+
*/
|
|
79
|
+
export type TeardownScanFailure = { state: "unscannable"; detail: string };
|
|
80
|
+
|
|
81
|
+
import {
|
|
82
|
+
isPendingTeardownFileName,
|
|
83
|
+
isAnyTeardownObligationFileName,
|
|
84
|
+
PENDING_TEARDOWN_PREFIX as PREFIX,
|
|
85
|
+
PENDING_TEARDOWN_SUFFIX as SUFFIX,
|
|
86
|
+
PENDING_TEARDOWN_UNREADABLE_SUFFIX as UNREADABLE_SUFFIX,
|
|
87
|
+
pendingTeardownNonceFromFileName,
|
|
88
|
+
} from "./pending-teardown-names.mjs";
|
|
89
|
+
|
|
90
|
+
const NONCE_RE = /^[0-9a-f]{32}$/;
|
|
91
|
+
|
|
92
|
+
export function pendingTeardownPathFor(nonce: string): string {
|
|
93
|
+
return join(getConfigDir(), `${PREFIX}${nonce}${SUFFIX}`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isReceipt(value: unknown, nonce: string): value is PendingTeardownReceipt {
|
|
97
|
+
if (!value || typeof value !== "object") return false;
|
|
98
|
+
const receipt = value as Record<string, unknown>;
|
|
99
|
+
const endpoint = receipt.endpoint as Record<string, unknown> | undefined;
|
|
100
|
+
const endpointOk = !!endpoint
|
|
101
|
+
&& typeof endpoint === "object"
|
|
102
|
+
&& typeof endpoint.hostname === "string"
|
|
103
|
+
&& endpoint.hostname.trim() !== ""
|
|
104
|
+
&& Number.isInteger(endpoint.port)
|
|
105
|
+
&& Number(endpoint.port) > 0
|
|
106
|
+
&& Number(endpoint.port) <= 65535;
|
|
107
|
+
return Number.isSafeInteger(receipt.ownerPid)
|
|
108
|
+
&& Number(receipt.ownerPid) > 0
|
|
109
|
+
// The body must agree with the name: a receipt whose nonce was edited to name a
|
|
110
|
+
// different claim would let a request authorize a deferral it does not own.
|
|
111
|
+
&& receipt.nonce === nonce
|
|
112
|
+
&& typeof receipt.createdAt === "string"
|
|
113
|
+
&& (receipt.endpointSource === "exact" || receipt.endpointSource === "guessed")
|
|
114
|
+
&& endpointOk;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Claim a deferred teardown for this process. Returns the receipt that was written. */
|
|
118
|
+
export function claimPendingTeardown(
|
|
119
|
+
endpoint: { hostname: string; port: number },
|
|
120
|
+
endpointSource: "exact" | "guessed",
|
|
121
|
+
ownerPid: number = process.pid,
|
|
122
|
+
): PendingTeardownReceipt {
|
|
123
|
+
const dir = getConfigDir();
|
|
124
|
+
assertNotRealHomeUnderTest(dir);
|
|
125
|
+
const nonce = randomBytes(16).toString("hex");
|
|
126
|
+
const receipt: PendingTeardownReceipt = { ownerPid, nonce, createdAt: new Date().toISOString(), endpoint, endpointSource };
|
|
127
|
+
atomicWriteFile(pendingTeardownPathFor(nonce), JSON.stringify(receipt, null, 2) + "\n");
|
|
128
|
+
return receipt;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function readPendingTeardown(nonce: string): PendingTeardownRead {
|
|
132
|
+
if (!NONCE_RE.test(nonce)) return { state: "missing" };
|
|
133
|
+
let raw: string;
|
|
134
|
+
try {
|
|
135
|
+
raw = readFileSync(pendingTeardownPathFor(nonce), "utf-8");
|
|
136
|
+
} catch (error) {
|
|
137
|
+
// Only "there is no file" is absence. A permission error, or a directory sitting where
|
|
138
|
+
// the receipt belongs, means something IS there and cannot be read; calling that
|
|
139
|
+
// missing hides an obligation that may still be outstanding.
|
|
140
|
+
const code = (error as NodeJS.ErrnoException).code;
|
|
141
|
+
if (code === "ENOENT") return { state: "missing" };
|
|
142
|
+
return { state: "invalid", nonce, detail: `unreadable (${code ?? "unknown"})` };
|
|
143
|
+
}
|
|
144
|
+
try {
|
|
145
|
+
const parsed: unknown = JSON.parse(raw);
|
|
146
|
+
if (isReceipt(parsed, nonce)) return { state: "valid", receipt: parsed };
|
|
147
|
+
const digest = createHash("sha256").update(raw).digest("hex").slice(0, 12);
|
|
148
|
+
return { state: "invalid", nonce, detail: `malformed receipt (sha256 ${digest})` };
|
|
149
|
+
} catch {
|
|
150
|
+
return { state: "invalid", nonce, detail: "unparseable JSON" };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** An obligation that exists on disk — the "missing" case cannot occur in a listing. */
|
|
155
|
+
export type OutstandingTeardown = Exclude<PendingTeardownRead, { state: "missing" }> | TeardownScanFailure;
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Every obligation currently on disk, attributable or not.
|
|
159
|
+
*
|
|
160
|
+
* A scan that FAILS is not an empty scan. Swallowing a permission or I/O error into `[]`
|
|
161
|
+
* would let `handleStop` restore client config with an unread obligation sitting right
|
|
162
|
+
* there, so anything but a missing home surfaces as one unreadable obligation the caller
|
|
163
|
+
* must treat like any other: blocking, and needing a human.
|
|
164
|
+
*/
|
|
165
|
+
export function listPendingTeardowns(): OutstandingTeardown[] {
|
|
166
|
+
let names: string[];
|
|
167
|
+
try {
|
|
168
|
+
names = readdirSync(getConfigDir());
|
|
169
|
+
} catch (error) {
|
|
170
|
+
if ((error as NodeJS.ErrnoException).code === "ENOENT") return [];
|
|
171
|
+
// Not an invalid RECEIPT: there is no file here and no nonce to name. Synthesizing one
|
|
172
|
+
// would hand a fabricated identity to the quarantine and clear paths, which could then
|
|
173
|
+
// rename or delete a real receipt that happened to carry it.
|
|
174
|
+
return [{ state: "unscannable", detail: `the opencodex home could not be listed (${(error as NodeJS.ErrnoException).code ?? "unknown"})` }];
|
|
175
|
+
}
|
|
176
|
+
const out: OutstandingTeardown[] = [];
|
|
177
|
+
for (const name of names) {
|
|
178
|
+
// One naming rule, shared with the npm launcher: the two lanes drifting apart is
|
|
179
|
+
// exactly how the Node updater stopped seeing receipts at all.
|
|
180
|
+
if (!isPendingTeardownFileName(name)) continue;
|
|
181
|
+
const nonce = pendingTeardownNonceFromFileName(name)!;
|
|
182
|
+
const read = readPendingTeardown(nonce);
|
|
183
|
+
if (read.state !== "missing") out.push(read);
|
|
184
|
+
}
|
|
185
|
+
return out;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Is any obligation outstanding, whether or not it can still be attributed?
|
|
190
|
+
*
|
|
191
|
+
* Quarantined receipts count. Filing an unreadable one away must not let the next update
|
|
192
|
+
* install over a teardown that never ran — that would turn "we could not tell" into "it
|
|
193
|
+
* is fine", which is the failure this whole mechanism exists to prevent.
|
|
194
|
+
*/
|
|
195
|
+
export function pendingTeardownOutstanding(): boolean {
|
|
196
|
+
try {
|
|
197
|
+
return readdirSync(getConfigDir()).some(isAnyTeardownObligationFileName);
|
|
198
|
+
} catch (error) {
|
|
199
|
+
// Only a missing home is empty. Any other scan failure may be hiding an obligation,
|
|
200
|
+
// and reporting "none" would unblock an update over a teardown that never ran.
|
|
201
|
+
return (error as NodeJS.ErrnoException).code !== "ENOENT";
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/** Paths of quarantined obligations awaiting a human. */
|
|
206
|
+
export function listQuarantinedTeardowns(): string[] {
|
|
207
|
+
try {
|
|
208
|
+
return readdirSync(getConfigDir())
|
|
209
|
+
.filter(name => name.startsWith(PREFIX) && name.endsWith(UNREADABLE_SUFFIX))
|
|
210
|
+
.map(name => join(getConfigDir(), name));
|
|
211
|
+
} catch {
|
|
212
|
+
return [];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Remove exactly one obligation.
|
|
218
|
+
*
|
|
219
|
+
* The nonce is the filename, so this is a compare-and-delete in one syscall: it can never
|
|
220
|
+
* remove a receipt another process wrote, because that receipt lives at a different path.
|
|
221
|
+
* Returns whether the obligation is gone — a failed unlink is reported rather than
|
|
222
|
+
* swallowed, since a receipt that survives its discharge re-triggers recovery forever.
|
|
223
|
+
*/
|
|
224
|
+
export function clearPendingTeardown(nonce: string): boolean {
|
|
225
|
+
try {
|
|
226
|
+
unlinkSync(pendingTeardownPathFor(nonce));
|
|
227
|
+
return true;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
return (error as NodeJS.ErrnoException).code === "ENOENT";
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Move an unattributable obligation aside.
|
|
235
|
+
*
|
|
236
|
+
* An invalid receipt names no endpoint, so nothing can prove its proxy is down, so it can
|
|
237
|
+
* never be discharged the normal way. Left in place it is not merely useless: both
|
|
238
|
+
* updater gates treat an outstanding receipt as a reason to run the stop, and that stop
|
|
239
|
+
* would fail on the same receipt every time — an update that can never proceed.
|
|
240
|
+
*
|
|
241
|
+
* Renaming stops the recovery loop from re-reading garbage on every stop, but it
|
|
242
|
+
* deliberately does NOT stop the obligation from counting: `pendingTeardownOutstanding`
|
|
243
|
+
* still sees it, so both updaters keep refusing to install over a teardown that never
|
|
244
|
+
* ran. Only a human removing the file ends the enforcement.
|
|
245
|
+
*
|
|
246
|
+
* Returns the path it was moved to, or null when it could not be moved.
|
|
247
|
+
*/
|
|
248
|
+
export function quarantinePendingTeardown(nonce: string): string | null {
|
|
249
|
+
const from = pendingTeardownPathFor(nonce);
|
|
250
|
+
if (!existsSync(from)) return null;
|
|
251
|
+
const to = join(getConfigDir(), `${PREFIX}${nonce}${UNREADABLE_SUFFIX}`);
|
|
252
|
+
try {
|
|
253
|
+
renameSync(from, to);
|
|
254
|
+
return to;
|
|
255
|
+
} catch {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* True when a previous deferred stop left its obligation unfinished.
|
|
262
|
+
*
|
|
263
|
+
* A receipt whose owner is still alive belongs to a stop that is still running: leave it
|
|
264
|
+
* alone. Only an abandoned obligation is a candidate, and a VALID one still has to prove
|
|
265
|
+
* its endpoint is down before anything is restored — an invalid one never can, which is
|
|
266
|
+
* what {@link quarantinePendingTeardown} exists for.
|
|
267
|
+
*/
|
|
268
|
+
export function isPendingTeardownAbandoned(
|
|
269
|
+
read: PendingTeardownRead | TeardownScanFailure,
|
|
270
|
+
isAlive: (pid: number) => boolean,
|
|
271
|
+
selfPid: number = process.pid,
|
|
272
|
+
): boolean {
|
|
273
|
+
if (read.state === "missing") return false;
|
|
274
|
+
// A home that cannot be listed may be hiding an obligation. It is not recoverable and
|
|
275
|
+
// not removable; the caller blocks on it and asks for the directory to be fixed.
|
|
276
|
+
if (read.state === "unscannable") return true;
|
|
277
|
+
if (read.state === "invalid") return true;
|
|
278
|
+
if (read.receipt.ownerPid === selfPid) return false;
|
|
279
|
+
return !isAlive(read.receipt.ownerPid);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/** Does this request name an obligation that exists and is readable? */
|
|
283
|
+
export function deferralMatchesReceipt(nonce: string | null): boolean {
|
|
284
|
+
if (!nonce || !NONCE_RE.test(nonce)) return false;
|
|
285
|
+
return readPendingTeardown(nonce).state === "valid";
|
|
286
|
+
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": "package.json",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "d90634511c7c4700a847a147914f913ffc8e68f604c9fab2c5fbcc94a33c8f3d"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "scripts/model-metadata.source.json",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
},
|
|
131
131
|
{
|
|
132
132
|
"path": "src/adapters/cursor/live-models.ts",
|
|
133
|
-
"sha256": "
|
|
133
|
+
"sha256": "14952cb90aff21691c8690dd227ca9c011e8eac945ada84886aca6c663cba827"
|
|
134
134
|
},
|
|
135
135
|
{
|
|
136
136
|
"path": "src/adapters/cursor/live-smoke-gate.ts",
|
|
@@ -338,7 +338,7 @@
|
|
|
338
338
|
},
|
|
339
339
|
{
|
|
340
340
|
"path": "src/adapters/openai-responses.ts",
|
|
341
|
-
"sha256": "
|
|
341
|
+
"sha256": "70c58ec5f2a0f6e67ace885973373b976d053068be9c19a7f4355dfb4ecbde5b"
|
|
342
342
|
},
|
|
343
343
|
{
|
|
344
344
|
"path": "src/adapters/registry.ts",
|
|
@@ -374,7 +374,7 @@
|
|
|
374
374
|
},
|
|
375
375
|
{
|
|
376
376
|
"path": "src/bridge.ts",
|
|
377
|
-
"sha256": "
|
|
377
|
+
"sha256": "949af46c2a1eba9c25283a442326c2e6acfd07e9653abec5488ec3bade1faa23"
|
|
378
378
|
},
|
|
379
379
|
{
|
|
380
380
|
"path": "src/chat/inbound.ts",
|
|
@@ -550,7 +550,7 @@
|
|
|
550
550
|
},
|
|
551
551
|
{
|
|
552
552
|
"path": "src/cli/dispatch.ts",
|
|
553
|
-
"sha256": "
|
|
553
|
+
"sha256": "7a755e1a26b2fe769d5d3cb68022ec7ae32df8f423ef5698590a4276933baed7"
|
|
554
554
|
},
|
|
555
555
|
{
|
|
556
556
|
"path": "src/cli/doctor.ts",
|
|
@@ -570,7 +570,7 @@
|
|
|
570
570
|
},
|
|
571
571
|
{
|
|
572
572
|
"path": "src/cli/index.ts",
|
|
573
|
-
"sha256": "
|
|
573
|
+
"sha256": "447dd3d1b3ca743f9041ee6644b4d106ce5baf10ddee324fa559be06ef1534c3"
|
|
574
574
|
},
|
|
575
575
|
{
|
|
576
576
|
"path": "src/cli/init.ts",
|
|
@@ -582,7 +582,7 @@
|
|
|
582
582
|
},
|
|
583
583
|
{
|
|
584
584
|
"path": "src/cli/integrations.ts",
|
|
585
|
-
"sha256": "
|
|
585
|
+
"sha256": "ead7fa2e3db71765e3a63ff275265599878de180ca653bf03d06427eec3e235e"
|
|
586
586
|
},
|
|
587
587
|
{
|
|
588
588
|
"path": "src/cli/interactive-confirm.ts",
|
|
@@ -672,6 +672,10 @@
|
|
|
672
672
|
"path": "src/cli/tray-proxy.ts",
|
|
673
673
|
"sha256": "35878717b3b9c9e9d7793fc88a72ddf21d7b2c9b41c3a6dd12f5bb5d5343a6d5"
|
|
674
674
|
},
|
|
675
|
+
{
|
|
676
|
+
"path": "src/cli/uninstall-plan.ts",
|
|
677
|
+
"sha256": "786c9f754b76a8a7fbf11a1893f8eb9a228138e822eee50c21513ea248ece34e"
|
|
678
|
+
},
|
|
675
679
|
{
|
|
676
680
|
"path": "src/cli/usage-report.ts",
|
|
677
681
|
"sha256": "0c590155ff4c4dbb39ea0a91160abf54a1b70e24060eb792df27a36fba98637a"
|
|
@@ -722,7 +726,7 @@
|
|
|
722
726
|
},
|
|
723
727
|
{
|
|
724
728
|
"path": "src/codex/account-store.ts",
|
|
725
|
-
"sha256": "
|
|
729
|
+
"sha256": "27786f63ee9887225ffeb4b6dd9a9e3592e89add7a3dbf4b190dbf5b4ceb1faa"
|
|
726
730
|
},
|
|
727
731
|
{
|
|
728
732
|
"path": "src/codex/account-usability.ts",
|
|
@@ -746,7 +750,7 @@
|
|
|
746
750
|
},
|
|
747
751
|
{
|
|
748
752
|
"path": "src/codex/auth-api.ts",
|
|
749
|
-
"sha256": "
|
|
753
|
+
"sha256": "60aa8e4d07fd5881c79fc3b7f9decbe8c669d14be2f71d48b01ab4da6e094790"
|
|
750
754
|
},
|
|
751
755
|
{
|
|
752
756
|
"path": "src/codex/auth-collision.ts",
|
|
@@ -814,7 +818,7 @@
|
|
|
814
818
|
},
|
|
815
819
|
{
|
|
816
820
|
"path": "src/codex/catalog/provider-fetch.ts",
|
|
817
|
-
"sha256": "
|
|
821
|
+
"sha256": "d8d3de67bdef52c26518948024a6a4dcfe7bbda6a9139b2eb4de26327eaed4a7"
|
|
818
822
|
},
|
|
819
823
|
{
|
|
820
824
|
"path": "src/codex/catalog/sync.ts",
|
|
@@ -874,7 +878,7 @@
|
|
|
874
878
|
},
|
|
875
879
|
{
|
|
876
880
|
"path": "src/codex/history-job.ts",
|
|
877
|
-
"sha256": "
|
|
881
|
+
"sha256": "de26dbf66f1829fa414f787507256e1cb2c9e0977c8de389445b27546d1ab462"
|
|
878
882
|
},
|
|
879
883
|
{
|
|
880
884
|
"path": "src/codex/history-lock.ts",
|
|
@@ -882,7 +886,7 @@
|
|
|
882
886
|
},
|
|
883
887
|
{
|
|
884
888
|
"path": "src/codex/history-manifest.ts",
|
|
885
|
-
"sha256": "
|
|
889
|
+
"sha256": "92431ddf0d11bab671c89a4b99e86049b1794b7ac9f07e7ba2709508d349cab8"
|
|
886
890
|
},
|
|
887
891
|
{
|
|
888
892
|
"path": "src/codex/history-migration-guardian.ts",
|
|
@@ -890,7 +894,7 @@
|
|
|
890
894
|
},
|
|
891
895
|
{
|
|
892
896
|
"path": "src/codex/history-provider.ts",
|
|
893
|
-
"sha256": "
|
|
897
|
+
"sha256": "1dd6c56defc42647592d5858147655fbd618368db0cccffc8234dd76135a0a86"
|
|
894
898
|
},
|
|
895
899
|
{
|
|
896
900
|
"path": "src/codex/history-transition.ts",
|
|
@@ -898,7 +902,7 @@
|
|
|
898
902
|
},
|
|
899
903
|
{
|
|
900
904
|
"path": "src/codex/history-worker.ts",
|
|
901
|
-
"sha256": "
|
|
905
|
+
"sha256": "f3dc8ad9a64af62423eac8d106e76a87d5f8be1aa098cc204fd7c8d7bbc9daae"
|
|
902
906
|
},
|
|
903
907
|
{
|
|
904
908
|
"path": "src/codex/home.ts",
|
|
@@ -1080,13 +1084,21 @@
|
|
|
1080
1084
|
"path": "src/codex/prompt-text-probe.ts",
|
|
1081
1085
|
"sha256": "6ab1a59afb4f0a5a7239490d5c3ec6d07f52f8cc323a60462a1776eff065e028"
|
|
1082
1086
|
},
|
|
1087
|
+
{
|
|
1088
|
+
"path": "src/codex/quota-401-recovery.ts",
|
|
1089
|
+
"sha256": "a7098de48a250f10212da8f26a098e3f139649adf295f7f9df789ad6e3e8ff52"
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
"path": "src/codex/quota-recovery-timing.ts",
|
|
1093
|
+
"sha256": "b8c0c6911b8ef908bfc81919005942f73672e7e0d51a593200736d3557bfce43"
|
|
1094
|
+
},
|
|
1083
1095
|
{
|
|
1084
1096
|
"path": "src/codex/quota-rejection.ts",
|
|
1085
1097
|
"sha256": "610c38395e08eaeb318cfed5c8472d9c0c8f1b818dd79dc6f45c5b6fbdbce226"
|
|
1086
1098
|
},
|
|
1087
1099
|
{
|
|
1088
1100
|
"path": "src/codex/quota.ts",
|
|
1089
|
-
"sha256": "
|
|
1101
|
+
"sha256": "f30fe0a4a652a28ee9200a352d9fad31a979e2dd6bf0324002dc72b25404286d"
|
|
1090
1102
|
},
|
|
1091
1103
|
{
|
|
1092
1104
|
"path": "src/codex/refresh.ts",
|
|
@@ -1102,7 +1114,7 @@
|
|
|
1102
1114
|
},
|
|
1103
1115
|
{
|
|
1104
1116
|
"path": "src/codex/routing.ts",
|
|
1105
|
-
"sha256": "
|
|
1117
|
+
"sha256": "4515c98f6b2e7dbd8ba3f5bf961329a3a0006bffc9e587bba957f05e7789bb6c"
|
|
1106
1118
|
},
|
|
1107
1119
|
{
|
|
1108
1120
|
"path": "src/codex/runtime.ts",
|
|
@@ -1118,7 +1130,7 @@
|
|
|
1118
1130
|
},
|
|
1119
1131
|
{
|
|
1120
1132
|
"path": "src/codex/subagent-model-fallback.ts",
|
|
1121
|
-
"sha256": "
|
|
1133
|
+
"sha256": "ab942407bcdd7d8d6b25e5be7c14e17a0d1d7262a48bb3f2364e75f014c6bedb"
|
|
1122
1134
|
},
|
|
1123
1135
|
{
|
|
1124
1136
|
"path": "src/codex/sync.ts",
|
|
@@ -1196,6 +1208,18 @@
|
|
|
1196
1208
|
"path": "src/config/paths.ts",
|
|
1197
1209
|
"sha256": "61f45ac80e0b176b870dd660867f6f5799e61b55ae2fdfce5691bbb9e66e6049"
|
|
1198
1210
|
},
|
|
1211
|
+
{
|
|
1212
|
+
"path": "src/config/pending-teardown-names.d.mts",
|
|
1213
|
+
"sha256": "8e56b8414ad9b3eacd2ca9711c766edc1b6254b92839245b473fee55f6f122a9"
|
|
1214
|
+
},
|
|
1215
|
+
{
|
|
1216
|
+
"path": "src/config/pending-teardown-names.mjs",
|
|
1217
|
+
"sha256": "3fe7314b6dabda15bd2ecb673145ab56a19fc4dabd3d097a2899137a962566f1"
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
"path": "src/config/pending-teardown.ts",
|
|
1221
|
+
"sha256": "6ac830654afcdb183c27b4af5b75af978e82ea325d07f39597786e655c3006a8"
|
|
1222
|
+
},
|
|
1199
1223
|
{
|
|
1200
1224
|
"path": "src/config/process-state.ts",
|
|
1201
1225
|
"sha256": "248fed86efbbb2f5c653ce3e08af7a3471ea28a3c04dff094c33916d8a3a9f01"
|
|
@@ -1298,7 +1322,7 @@
|
|
|
1298
1322
|
},
|
|
1299
1323
|
{
|
|
1300
1324
|
"path": "src/integrations/journal.ts",
|
|
1301
|
-
"sha256": "
|
|
1325
|
+
"sha256": "961d68c7b35e151e030cd2853223b0c1575fad77af444e768ff321f6e8a6b330"
|
|
1302
1326
|
},
|
|
1303
1327
|
{
|
|
1304
1328
|
"path": "src/integrations/merge.ts",
|
|
@@ -1350,7 +1374,7 @@
|
|
|
1350
1374
|
},
|
|
1351
1375
|
{
|
|
1352
1376
|
"path": "src/integrations/writer.ts",
|
|
1353
|
-
"sha256": "
|
|
1377
|
+
"sha256": "3945b3b4c408c613f76672c8cb213d84433ec4474966d9e9f00923f6a3707ed9"
|
|
1354
1378
|
},
|
|
1355
1379
|
{
|
|
1356
1380
|
"path": "src/lab/artifacts/sanitize.ts",
|
|
@@ -1982,7 +2006,7 @@
|
|
|
1982
2006
|
},
|
|
1983
2007
|
{
|
|
1984
2008
|
"path": "src/lib/process-control.ts",
|
|
1985
|
-
"sha256": "
|
|
2009
|
+
"sha256": "04d59915906bcd833d0e89a38dddc83f33f1632ca9b6014d93d030c3372914b8"
|
|
1986
2010
|
},
|
|
1987
2011
|
{
|
|
1988
2012
|
"path": "src/lib/provider-outbound.ts",
|
|
@@ -2030,7 +2054,7 @@
|
|
|
2030
2054
|
},
|
|
2031
2055
|
{
|
|
2032
2056
|
"path": "src/lib/state-store-registrations.ts",
|
|
2033
|
-
"sha256": "
|
|
2057
|
+
"sha256": "f108d262fb54d753458631b9bb16c22474ea398181331b9a2cb87d9b487864c7"
|
|
2034
2058
|
},
|
|
2035
2059
|
{
|
|
2036
2060
|
"path": "src/lib/state-store-sweeper.ts",
|
|
@@ -2182,7 +2206,7 @@
|
|
|
2182
2206
|
},
|
|
2183
2207
|
{
|
|
2184
2208
|
"path": "src/oauth/index.ts",
|
|
2185
|
-
"sha256": "
|
|
2209
|
+
"sha256": "0ac7f18a0ef2d45ae400a1f408e39ecf64b30c02ce4afca1abc7e21b34a6a913"
|
|
2186
2210
|
},
|
|
2187
2211
|
{
|
|
2188
2212
|
"path": "src/oauth/key-providers.ts",
|
|
@@ -2226,7 +2250,7 @@
|
|
|
2226
2250
|
},
|
|
2227
2251
|
{
|
|
2228
2252
|
"path": "src/oauth/store.ts",
|
|
2229
|
-
"sha256": "
|
|
2253
|
+
"sha256": "209b0e02f69cd60b09d832a770382c5a88f3b94bb8663d9c1c22b87e05596b2e"
|
|
2230
2254
|
},
|
|
2231
2255
|
{
|
|
2232
2256
|
"path": "src/oauth/token-guardian.ts",
|
|
@@ -2486,11 +2510,11 @@
|
|
|
2486
2510
|
},
|
|
2487
2511
|
{
|
|
2488
2512
|
"path": "src/responses/spill-store.ts",
|
|
2489
|
-
"sha256": "
|
|
2513
|
+
"sha256": "a28d0896063ff0828a4de660ff43a942278425fac765db6f057f162666f5e758"
|
|
2490
2514
|
},
|
|
2491
2515
|
{
|
|
2492
2516
|
"path": "src/responses/state.ts",
|
|
2493
|
-
"sha256": "
|
|
2517
|
+
"sha256": "9982437898211d879156666d375cc0c1fcc90b04297332ff74b320ca389d1c14"
|
|
2494
2518
|
},
|
|
2495
2519
|
{
|
|
2496
2520
|
"path": "src/responses/thought-signature-replay.ts",
|
|
@@ -2690,7 +2714,7 @@
|
|
|
2690
2714
|
},
|
|
2691
2715
|
{
|
|
2692
2716
|
"path": "src/server/management-api.ts",
|
|
2693
|
-
"sha256": "
|
|
2717
|
+
"sha256": "b448917c5d5fe7dcb6d9988e8bf98ba4b377f960d74269c767cbb626045101f4"
|
|
2694
2718
|
},
|
|
2695
2719
|
{
|
|
2696
2720
|
"path": "src/server/management-auth.ts",
|
|
@@ -2730,7 +2754,7 @@
|
|
|
2730
2754
|
},
|
|
2731
2755
|
{
|
|
2732
2756
|
"path": "src/server/management/integration-routes.ts",
|
|
2733
|
-
"sha256": "
|
|
2757
|
+
"sha256": "3f27c3eda18b24766f9215f962f5ffa5f146d5c34043fbbc4688ea5ee9aa3374"
|
|
2734
2758
|
},
|
|
2735
2759
|
{
|
|
2736
2760
|
"path": "src/server/management/lab-automation-routes.ts",
|
|
@@ -2946,7 +2970,7 @@
|
|
|
2946
2970
|
},
|
|
2947
2971
|
{
|
|
2948
2972
|
"path": "src/server/responses/encrypted-payload.ts",
|
|
2949
|
-
"sha256": "
|
|
2973
|
+
"sha256": "e9a5edf2ed2c9bda8e5244e50687b3ef9526841a0846fa325ce9cce6209188a7"
|
|
2950
2974
|
},
|
|
2951
2975
|
{
|
|
2952
2976
|
"path": "src/server/responses/fetch-helpers.ts",
|
|
@@ -3004,6 +3028,10 @@
|
|
|
3004
3028
|
"path": "src/server/startup-health-cache.ts",
|
|
3005
3029
|
"sha256": "c4e1972bc3029389ce3f6a40477ca242b250b36c6dd5382b61124ad4f64aa920"
|
|
3006
3030
|
},
|
|
3031
|
+
{
|
|
3032
|
+
"path": "src/server/stop-teardown.ts",
|
|
3033
|
+
"sha256": "8e0dcffcc7e2acc0f8751830a623fd1a4f9b81e7e09eaa6e67abd1ef319f01ce"
|
|
3034
|
+
},
|
|
3007
3035
|
{
|
|
3008
3036
|
"path": "src/server/system-env.ts",
|
|
3009
3037
|
"sha256": "e83b17223b42325c562be8925bfe573d4c342c68b0c9195b39657cfb64d3f0ea"
|
|
@@ -3026,7 +3054,7 @@
|
|
|
3026
3054
|
},
|
|
3027
3055
|
{
|
|
3028
3056
|
"path": "src/service.ts",
|
|
3029
|
-
"sha256": "
|
|
3057
|
+
"sha256": "182b27c731968f27140c0b2a509bb00036ef9433841ff7eef36541df5810b7d7"
|
|
3030
3058
|
},
|
|
3031
3059
|
{
|
|
3032
3060
|
"path": "src/sidecar/auth.ts",
|
|
@@ -3150,7 +3178,7 @@
|
|
|
3150
3178
|
},
|
|
3151
3179
|
{
|
|
3152
3180
|
"path": "src/update/index.ts",
|
|
3153
|
-
"sha256": "
|
|
3181
|
+
"sha256": "fd3aed5d8eb3c02b1391f736b5971e20405475c931134860eddd733ca5e0e0be"
|
|
3154
3182
|
},
|
|
3155
3183
|
{
|
|
3156
3184
|
"path": "src/update/job.ts",
|
|
@@ -3176,6 +3204,30 @@
|
|
|
3176
3204
|
"path": "src/update/npm-invocation.mjs",
|
|
3177
3205
|
"sha256": "25292222b9fa1ed00fc01164e9e9f25e82ca1820c73c20643171380467b4628b"
|
|
3178
3206
|
},
|
|
3207
|
+
{
|
|
3208
|
+
"path": "src/update/proxy-liveness-probe.d.mts",
|
|
3209
|
+
"sha256": "14b2051f2e14542720190a02ee950f1cbd79eefd044380a735c8e6a53edc5864"
|
|
3210
|
+
},
|
|
3211
|
+
{
|
|
3212
|
+
"path": "src/update/proxy-liveness-probe.mjs",
|
|
3213
|
+
"sha256": "5edce8e566742a174f4262a124b62d8b69120117ff622398f09105fde2361349"
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
"path": "src/update/stop-contract.d.mts",
|
|
3217
|
+
"sha256": "e284b5830ee058aed46f09eee2cdcab7ddca54cdc4564df07102fd080551461d"
|
|
3218
|
+
},
|
|
3219
|
+
{
|
|
3220
|
+
"path": "src/update/stop-contract.mjs",
|
|
3221
|
+
"sha256": "006056e10a136927c5bc5e2afc047064e7f7516827ce3646a6e7717ffd9d548f"
|
|
3222
|
+
},
|
|
3223
|
+
{
|
|
3224
|
+
"path": "src/update/stop-decision.d.mts",
|
|
3225
|
+
"sha256": "23cbb6e3ecd1051b0258f7fe4cea8ce54fc6e39c997bd73e3fe17df538f332e9"
|
|
3226
|
+
},
|
|
3227
|
+
{
|
|
3228
|
+
"path": "src/update/stop-decision.mjs",
|
|
3229
|
+
"sha256": "3e9a210b820171d03f862a094077da6623c047e113b116d72d73b830cd0adf2c"
|
|
3230
|
+
},
|
|
3179
3231
|
{
|
|
3180
3232
|
"path": "src/update/transactional-install.d.mts",
|
|
3181
3233
|
"sha256": "8409a8514e798b45a2e3132bdf0f3fa64590e44827cb09367ae7d33dd85c57d7"
|
|
@@ -3238,11 +3290,11 @@
|
|
|
3238
3290
|
},
|
|
3239
3291
|
{
|
|
3240
3292
|
"path": "src/vision/eligibility.ts",
|
|
3241
|
-
"sha256": "
|
|
3293
|
+
"sha256": "232243b48dd985eb57f6cd3ec2bfa39f943965d878828b5164b594614247df5e"
|
|
3242
3294
|
},
|
|
3243
3295
|
{
|
|
3244
3296
|
"path": "src/vision/index.ts",
|
|
3245
|
-
"sha256": "
|
|
3297
|
+
"sha256": "bc519374596668b8e28ddb4e12ff625d30a62f5f13d5c4679580831d2cc6d343"
|
|
3246
3298
|
},
|
|
3247
3299
|
{
|
|
3248
3300
|
"path": "src/vision/reasoning.ts",
|
|
@@ -19,7 +19,18 @@ import { atomicWriteFile } from "../config";
|
|
|
19
19
|
import { ensureDir, fingerprint, integrationsDir, type OwnershipRecord } from "./ownership";
|
|
20
20
|
import { isIntegrationClientId, type IntegrationClientId } from "./registry";
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* `overwrite` is deliberately distinct from `apply`. Both write our block, but
|
|
24
|
+
* only one of them replaced something the user or another tool had put there,
|
|
25
|
+
* and the rollback list is exactly where that distinction matters.
|
|
26
|
+
*
|
|
27
|
+
* This union is re-declared, not imported, in two other places -- the management
|
|
28
|
+
* route envelope and the GUI adapter -- because neither imports across that
|
|
29
|
+
* boundary. `tests/integrations-journal.test.ts` asserts the three agree, since
|
|
30
|
+
* nothing else can: a kind persisted here and missing there renders as a raw
|
|
31
|
+
* key with no type error anywhere.
|
|
32
|
+
*/
|
|
33
|
+
export type OperationKind = "apply" | "disable" | "refresh" | "restore" | "overwrite";
|
|
23
34
|
|
|
24
35
|
/**
|
|
25
36
|
* Tagged so "the file did not exist" and "the snapshot was collected" stay
|