@bitkyc08/opencodex 2.24.1 → 2.24.2
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/gui/dist/assets/{index-C3FiAveG.js → index-DW-DYWmz.js} +8 -8
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/claude/context-windows.ts +2 -2
- package/src/claude/desktop-3p.ts +6 -6
- package/src/claude/model-info.ts +2 -2
- package/src/cli/claude-desktop.ts +2 -3
- package/src/codex/catalog/metadata.ts +29 -10
- package/src/codex/catalog/provider-fetch.ts +16 -10
- package/src/codex/catalog.ts +1 -1
- package/src/codex/injected-marker.ts +9 -3
- package/src/codex/user-identity.ts +88 -6
- package/src/generated/compatibility-version.json +25 -25
- package/src/grok/sync.ts +2 -4
- package/src/lab/projection/rebuild.ts +36 -18
- package/src/lib/windows-elevation.ts +10 -1
- package/src/lib/windows-secret-acl.ts +49 -19
- package/src/routing/capability.ts +5 -6
- package/src/server/index.ts +3 -4
- package/src/server/management/agent-settings-routes.ts +5 -5
- package/src/server/management/config-routes.ts +2 -2
- package/src/server/management/context.ts +2 -0
- package/src/server/management/native-integration-routes.ts +3 -3
- package/src/server/management/shared.ts +4 -4
- package/src/server/management-api.ts +2 -2
- package/src/server/responses/core.ts +2 -1
- package/src/server/responses/input-admission.ts +13 -10
- package/src/server/system-env.ts +3 -3
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"path": "package.json",
|
|
13
|
-
"sha256": "
|
|
13
|
+
"sha256": "6eddddb2ce07468a1c26f394225a047ae265a21e7457f38ad6500a62c2f63b66"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "scripts/model-metadata.source.json",
|
|
@@ -342,7 +342,7 @@
|
|
|
342
342
|
},
|
|
343
343
|
{
|
|
344
344
|
"path": "src/claude/context-windows.ts",
|
|
345
|
-
"sha256": "
|
|
345
|
+
"sha256": "4c49d8efeec1d1060e9e61201370d4dce268b7826ca3fcff773d1d53c4c548b4"
|
|
346
346
|
},
|
|
347
347
|
{
|
|
348
348
|
"path": "src/claude/desktop-3p-guard.ts",
|
|
@@ -354,7 +354,7 @@
|
|
|
354
354
|
},
|
|
355
355
|
{
|
|
356
356
|
"path": "src/claude/desktop-3p.ts",
|
|
357
|
-
"sha256": "
|
|
357
|
+
"sha256": "2218e3b4ba35dab0bf53e6b400468daf6a59e886f06afe96dd083b755e6beed0"
|
|
358
358
|
},
|
|
359
359
|
{
|
|
360
360
|
"path": "src/claude/desktop-health.ts",
|
|
@@ -378,7 +378,7 @@
|
|
|
378
378
|
},
|
|
379
379
|
{
|
|
380
380
|
"path": "src/claude/model-info.ts",
|
|
381
|
-
"sha256": "
|
|
381
|
+
"sha256": "8b087c12684e3e43100047227f04536321be5d2af3ca6e989693d09836fbf74f"
|
|
382
382
|
},
|
|
383
383
|
{
|
|
384
384
|
"path": "src/claude/outbound.ts",
|
|
@@ -430,7 +430,7 @@
|
|
|
430
430
|
},
|
|
431
431
|
{
|
|
432
432
|
"path": "src/cli/claude-desktop.ts",
|
|
433
|
-
"sha256": "
|
|
433
|
+
"sha256": "edc5fcaf62acdeaafac905bbe84fb5527cbe38d4729d4e94cff29cb7b2b4bf2f"
|
|
434
434
|
},
|
|
435
435
|
{
|
|
436
436
|
"path": "src/cli/claude.ts",
|
|
@@ -662,7 +662,7 @@
|
|
|
662
662
|
},
|
|
663
663
|
{
|
|
664
664
|
"path": "src/codex/catalog.ts",
|
|
665
|
-
"sha256": "
|
|
665
|
+
"sha256": "879afc5613a39b758e6e8f6f63d23cef0918ffb38e6f68dff1bc3f638278bd1a"
|
|
666
666
|
},
|
|
667
667
|
{
|
|
668
668
|
"path": "src/codex/catalog/account-models.ts",
|
|
@@ -690,7 +690,7 @@
|
|
|
690
690
|
},
|
|
691
691
|
{
|
|
692
692
|
"path": "src/codex/catalog/metadata.ts",
|
|
693
|
-
"sha256": "
|
|
693
|
+
"sha256": "fc1cce8854a517f6c80ce137a02fb183c6710899f2a1d7536707c00ad56b4de6"
|
|
694
694
|
},
|
|
695
695
|
{
|
|
696
696
|
"path": "src/codex/catalog/native-models.ts",
|
|
@@ -702,7 +702,7 @@
|
|
|
702
702
|
},
|
|
703
703
|
{
|
|
704
704
|
"path": "src/codex/catalog/provider-fetch.ts",
|
|
705
|
-
"sha256": "
|
|
705
|
+
"sha256": "bfb4a4c32de3a514190c8bf4fcb660312a64a8e7d32ef9ac83106f999f8c639d"
|
|
706
706
|
},
|
|
707
707
|
{
|
|
708
708
|
"path": "src/codex/catalog/sync.ts",
|
|
@@ -782,7 +782,7 @@
|
|
|
782
782
|
},
|
|
783
783
|
{
|
|
784
784
|
"path": "src/codex/injected-marker.ts",
|
|
785
|
-
"sha256": "
|
|
785
|
+
"sha256": "b59a1864bc2a71dae6d0349386c137ad18ce402981f09f19fb881777fcc1556f"
|
|
786
786
|
},
|
|
787
787
|
{
|
|
788
788
|
"path": "src/codex/integration-record.ts",
|
|
@@ -986,7 +986,7 @@
|
|
|
986
986
|
},
|
|
987
987
|
{
|
|
988
988
|
"path": "src/codex/user-identity.ts",
|
|
989
|
-
"sha256": "
|
|
989
|
+
"sha256": "9641f00a7213ea6cb85cdc38adcbab1615815ca1eda878d5bfc3513e023243c7"
|
|
990
990
|
},
|
|
991
991
|
{
|
|
992
992
|
"path": "src/codex/warmup.ts",
|
|
@@ -1046,7 +1046,7 @@
|
|
|
1046
1046
|
},
|
|
1047
1047
|
{
|
|
1048
1048
|
"path": "src/grok/sync.ts",
|
|
1049
|
-
"sha256": "
|
|
1049
|
+
"sha256": "a2afb3599a789276726867b559273d047b7e55a64f088ca81e4af49629e14d74"
|
|
1050
1050
|
},
|
|
1051
1051
|
{
|
|
1052
1052
|
"path": "src/images/artifacts.ts",
|
|
@@ -1442,7 +1442,7 @@
|
|
|
1442
1442
|
},
|
|
1443
1443
|
{
|
|
1444
1444
|
"path": "src/lab/projection/rebuild.ts",
|
|
1445
|
-
"sha256": "
|
|
1445
|
+
"sha256": "9de9cfcd613634b5afa7ba8bbea7fc24327ff1fb103ae2c70c6f5475e70695c3"
|
|
1446
1446
|
},
|
|
1447
1447
|
{
|
|
1448
1448
|
"path": "src/lab/projection/schema.ts",
|
|
@@ -1854,11 +1854,11 @@
|
|
|
1854
1854
|
},
|
|
1855
1855
|
{
|
|
1856
1856
|
"path": "src/lib/windows-elevation.ts",
|
|
1857
|
-
"sha256": "
|
|
1857
|
+
"sha256": "b0aab4ba8c7fe82e101669545881634ed75b59ca024522ad21e8c613c7a6cf99"
|
|
1858
1858
|
},
|
|
1859
1859
|
{
|
|
1860
1860
|
"path": "src/lib/windows-secret-acl.ts",
|
|
1861
|
-
"sha256": "
|
|
1861
|
+
"sha256": "1e3d7e199fa0433ca778ba3ffae2c610bf2d1850ead39c8fa1d1a1b64881bc1c"
|
|
1862
1862
|
},
|
|
1863
1863
|
{
|
|
1864
1864
|
"path": "src/lib/windows-text.ts",
|
|
@@ -2186,7 +2186,7 @@
|
|
|
2186
2186
|
},
|
|
2187
2187
|
{
|
|
2188
2188
|
"path": "src/routing/capability.ts",
|
|
2189
|
-
"sha256": "
|
|
2189
|
+
"sha256": "e4c7da723d461ac41b18cdf5d80085887a0b0e46917bcb4e012f52fc431475d0"
|
|
2190
2190
|
},
|
|
2191
2191
|
{
|
|
2192
2192
|
"path": "src/routing/compatibility/assemble.ts",
|
|
@@ -2330,7 +2330,7 @@
|
|
|
2330
2330
|
},
|
|
2331
2331
|
{
|
|
2332
2332
|
"path": "src/server/index.ts",
|
|
2333
|
-
"sha256": "
|
|
2333
|
+
"sha256": "1ceb408f13a9700fcdd78e112fe56c35956a0e1c3207f14477ca7f18358fa3b7"
|
|
2334
2334
|
},
|
|
2335
2335
|
{
|
|
2336
2336
|
"path": "src/server/lifecycle.ts",
|
|
@@ -2350,7 +2350,7 @@
|
|
|
2350
2350
|
},
|
|
2351
2351
|
{
|
|
2352
2352
|
"path": "src/server/management-api.ts",
|
|
2353
|
-
"sha256": "
|
|
2353
|
+
"sha256": "b3e94bff1762950449552b416de10cbed72f12362dfa3c7c1f9bf043177ae1fc"
|
|
2354
2354
|
},
|
|
2355
2355
|
{
|
|
2356
2356
|
"path": "src/server/management-auth.ts",
|
|
@@ -2358,7 +2358,7 @@
|
|
|
2358
2358
|
},
|
|
2359
2359
|
{
|
|
2360
2360
|
"path": "src/server/management/agent-settings-routes.ts",
|
|
2361
|
-
"sha256": "
|
|
2361
|
+
"sha256": "97487f7dadf5abae969085b6058f430fce0d309e8882eaeeedae078ccc6cafc9"
|
|
2362
2362
|
},
|
|
2363
2363
|
{
|
|
2364
2364
|
"path": "src/server/management/api-access.ts",
|
|
@@ -2378,11 +2378,11 @@
|
|
|
2378
2378
|
},
|
|
2379
2379
|
{
|
|
2380
2380
|
"path": "src/server/management/config-routes.ts",
|
|
2381
|
-
"sha256": "
|
|
2381
|
+
"sha256": "3a56198dbd3884707cd385a9c6b62a3c910741a0d7c576d9b30de3d7a8f86ddf"
|
|
2382
2382
|
},
|
|
2383
2383
|
{
|
|
2384
2384
|
"path": "src/server/management/context.ts",
|
|
2385
|
-
"sha256": "
|
|
2385
|
+
"sha256": "1b5d01755283307260fb942f35bc23b2d22bb6108e00b3c4d75a56ec13780dff"
|
|
2386
2386
|
},
|
|
2387
2387
|
{
|
|
2388
2388
|
"path": "src/server/management/integration-routes.ts",
|
|
@@ -2410,7 +2410,7 @@
|
|
|
2410
2410
|
},
|
|
2411
2411
|
{
|
|
2412
2412
|
"path": "src/server/management/native-integration-routes.ts",
|
|
2413
|
-
"sha256": "
|
|
2413
|
+
"sha256": "6c01497f98bc583ec2d76fe90e99f61076287c7a69f9dee67477ba60853e38e7"
|
|
2414
2414
|
},
|
|
2415
2415
|
{
|
|
2416
2416
|
"path": "src/server/management/oauth-account-routes.ts",
|
|
@@ -2438,7 +2438,7 @@
|
|
|
2438
2438
|
},
|
|
2439
2439
|
{
|
|
2440
2440
|
"path": "src/server/management/shared.ts",
|
|
2441
|
-
"sha256": "
|
|
2441
|
+
"sha256": "2ec68a5b6d334898762c729b07eb3b98a350a4cf52d3f4debe25eb359162e863"
|
|
2442
2442
|
},
|
|
2443
2443
|
{
|
|
2444
2444
|
"path": "src/server/management/sidebar-routes.ts",
|
|
@@ -2566,7 +2566,7 @@
|
|
|
2566
2566
|
},
|
|
2567
2567
|
{
|
|
2568
2568
|
"path": "src/server/responses/core.ts",
|
|
2569
|
-
"sha256": "
|
|
2569
|
+
"sha256": "fbb0b59c9a67f10d97ec28ac48b7c2c168c7ec359f43c336a11913148ae1a11a"
|
|
2570
2570
|
},
|
|
2571
2571
|
{
|
|
2572
2572
|
"path": "src/server/responses/empty-completion-guard.ts",
|
|
@@ -2582,7 +2582,7 @@
|
|
|
2582
2582
|
},
|
|
2583
2583
|
{
|
|
2584
2584
|
"path": "src/server/responses/input-admission.ts",
|
|
2585
|
-
"sha256": "
|
|
2585
|
+
"sha256": "cb04a5dea34d8e997c842626bad39d02baf1c64e6bcf614227bf3d49a2270131"
|
|
2586
2586
|
},
|
|
2587
2587
|
{
|
|
2588
2588
|
"path": "src/server/responses/pacing-overload.ts",
|
|
@@ -2630,7 +2630,7 @@
|
|
|
2630
2630
|
},
|
|
2631
2631
|
{
|
|
2632
2632
|
"path": "src/server/system-env.ts",
|
|
2633
|
-
"sha256": "
|
|
2633
|
+
"sha256": "b068365c21dbc6c92de920f9ebb3c771b9f82ecff0dfa315618923d748a93025"
|
|
2634
2634
|
},
|
|
2635
2635
|
{
|
|
2636
2636
|
"path": "src/server/windows-tcp-drop.ts",
|
package/src/grok/sync.ts
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
* Deps are injectable (mirrors src/codex/sync.ts) so tests can run without a live proxy.
|
|
8
8
|
*/
|
|
9
|
-
import { visibleNativeSlugs, filterCatalogVisibleModels, nativeOpenAiContextWindow, type CatalogModel } from "../codex/catalog";
|
|
10
|
-
import { providerContextCap } from "../providers/context-cap";
|
|
11
|
-
import { OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
|
|
9
|
+
import { visibleNativeSlugs, filterCatalogVisibleModels, nativeContextLimits, nativeOpenAiContextWindow, type CatalogModel } from "../codex/catalog";
|
|
12
10
|
import type { OcxConfig } from "../types";
|
|
13
11
|
import { injectGrokConfig, type GrokInjectModel, type GrokInjectResult } from "./inject";
|
|
14
12
|
|
|
@@ -42,7 +40,7 @@ export async function syncGrokConfig(
|
|
|
42
40
|
// default (200k) and understates models like gpt-5.6-sol, which is 372k. This is the same
|
|
43
41
|
// accessor the dashboard's native rows use, so the two cannot disagree.
|
|
44
42
|
...visibleNativeSlugs(config).map(id => {
|
|
45
|
-
const contextWindow = nativeOpenAiContextWindow(id,
|
|
43
|
+
const contextWindow = nativeOpenAiContextWindow(id, nativeContextLimits(config));
|
|
46
44
|
return { id, ...(contextWindow !== undefined ? { contextWindow } : {}) };
|
|
47
45
|
}),
|
|
48
46
|
...routed.map(m => ({
|
|
@@ -122,6 +122,20 @@ export function rebuildLabProjection(configDir?: string): RebuildResult {
|
|
|
122
122
|
|
|
123
123
|
const db = new Database(paths.sqlitePath);
|
|
124
124
|
let transactionOpen = false;
|
|
125
|
+
// Every statement prepared below, so they can be finalized before the close.
|
|
126
|
+
//
|
|
127
|
+
// Bun keeps a prepared statement alive until it is finalized or garbage collected,
|
|
128
|
+
// and on Windows an unfinalized statement holds the database file open: `close()`
|
|
129
|
+
// leaves the handle, and `close(true)` throws "database is locked". A second
|
|
130
|
+
// rebuild then failed to unlink the previous projection with EBUSY, and the retry
|
|
131
|
+
// loop in `wipeSqlite` could only turn that into a slower failure. POSIX allows
|
|
132
|
+
// unlinking an open file, which is why this never surfaced there.
|
|
133
|
+
const prepared: Array<{ finalize(): void }> = [];
|
|
134
|
+
const prepare = (sql: string) => {
|
|
135
|
+
const statement = db.prepare(sql);
|
|
136
|
+
prepared.push(statement);
|
|
137
|
+
return statement;
|
|
138
|
+
};
|
|
125
139
|
try {
|
|
126
140
|
db.exec("PRAGMA journal_mode=DELETE;");
|
|
127
141
|
db.exec("PRAGMA foreign_keys=OFF;");
|
|
@@ -129,50 +143,45 @@ export function rebuildLabProjection(configDir?: string): RebuildResult {
|
|
|
129
143
|
transactionOpen = true;
|
|
130
144
|
resetProjectionSchema(db);
|
|
131
145
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
"INSERT OR REPLACE INTO schema_meta(key, value) VALUES (?, ?)",
|
|
137
|
-
).run("projection_spec_version", LAB_PROJECTION_SPEC_VERSION);
|
|
138
|
-
db.prepare(
|
|
139
|
-
"INSERT OR REPLACE INTO schema_meta(key, value) VALUES (?, ?)",
|
|
140
|
-
).run("built_at_ms", String(Date.now()));
|
|
146
|
+
const insertMeta = prepare("INSERT OR REPLACE INTO schema_meta(key, value) VALUES (?, ?)");
|
|
147
|
+
insertMeta.run("schema_version", String(LAB_SQLITE_SCHEMA_VERSION));
|
|
148
|
+
insertMeta.run("projection_spec_version", LAB_PROJECTION_SPEC_VERSION);
|
|
149
|
+
insertMeta.run("built_at_ms", String(Date.now()));
|
|
141
150
|
|
|
142
|
-
const insertCorruption =
|
|
151
|
+
const insertCorruption = prepare(
|
|
143
152
|
"INSERT INTO corruption(kind, line_number, event_id, detail) VALUES (?, ?, ?, ?)",
|
|
144
153
|
);
|
|
145
154
|
for (const c of corruptions) {
|
|
146
155
|
insertCorruption.run(c.kind, c.lineNumber ?? null, c.eventId ?? null, c.detail);
|
|
147
156
|
}
|
|
148
157
|
|
|
149
|
-
const insertEvent =
|
|
158
|
+
const insertEvent = prepare(
|
|
150
159
|
`INSERT INTO events(event_id, event_kind, recorded_at, producer, producer_version, payload_json, excluded, exclusion_reason)
|
|
151
160
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
152
161
|
);
|
|
153
|
-
const insertSubject =
|
|
162
|
+
const insertSubject = prepare(
|
|
154
163
|
`INSERT OR IGNORE INTO subjects(subject_id, subject_kind, subject_json) VALUES (?, ?, ?)`,
|
|
155
164
|
);
|
|
156
|
-
const insertObs =
|
|
165
|
+
const insertObs = prepare(
|
|
157
166
|
`INSERT INTO observations(
|
|
158
167
|
event_id, subject_id, evidence_layer, suite_id, suite_version, suite_manifest_digest,
|
|
159
168
|
scenario_id, scenario_version, scenario_manifest_digest, outcome, completed_at, execution_mode
|
|
160
169
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
161
170
|
);
|
|
162
|
-
const insertClaim =
|
|
171
|
+
const insertClaim = prepare(
|
|
163
172
|
`INSERT INTO claims(
|
|
164
173
|
event_id, subject_id, capability, polarity, source_manifest_digest,
|
|
165
174
|
effective_at, recorded_at, supersedes_json, current, usable
|
|
166
175
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
167
176
|
);
|
|
168
|
-
const insertInv =
|
|
177
|
+
const insertInv = prepare(
|
|
169
178
|
`INSERT INTO invalidations(event_id, reason, targets_json, recorded_at, applied) VALUES (?, ?, ?, ?, ?)`,
|
|
170
179
|
);
|
|
171
|
-
const insertPurge =
|
|
180
|
+
const insertPurge = prepare(
|
|
172
181
|
`INSERT INTO purges(event_id, target_event_ids_json, target_artifact_digests_json, purge_actions_json, recorded_at)
|
|
173
182
|
VALUES (?, ?, ?, ?, ?)`,
|
|
174
183
|
);
|
|
175
|
-
const insertArtifact =
|
|
184
|
+
const insertArtifact = prepare(
|
|
176
185
|
`INSERT INTO artifacts(digest, artifact_class, media_type, byte_count, status, last_error)
|
|
177
186
|
VALUES (?, ?, ?, ?, ?, ?)
|
|
178
187
|
ON CONFLICT(digest) DO UPDATE SET
|
|
@@ -319,7 +328,7 @@ export function rebuildLabProjection(configDir?: string): RebuildResult {
|
|
|
319
328
|
}
|
|
320
329
|
}
|
|
321
330
|
|
|
322
|
-
const insertVerdict =
|
|
331
|
+
const insertVerdict = prepare(
|
|
323
332
|
`INSERT INTO verdicts(
|
|
324
333
|
projection_key, subject_id, evidence_layer, suite_id, suite_version, suite_manifest_digest,
|
|
325
334
|
projection_spec_version, verdict, as_of, scenario_manifest_digests_json, claim_source_digest,
|
|
@@ -369,6 +378,15 @@ export function rebuildLabProjection(configDir?: string): RebuildResult {
|
|
|
369
378
|
} catch {
|
|
370
379
|
// Closing the disposable DB is still safe if pragma restoration fails.
|
|
371
380
|
}
|
|
381
|
+
// Finalize before closing: an outstanding statement keeps the file open on
|
|
382
|
+
// Windows, and the next rebuild cannot unlink the projection it is replacing.
|
|
383
|
+
for (const statement of prepared) {
|
|
384
|
+
try {
|
|
385
|
+
statement.finalize();
|
|
386
|
+
} catch {
|
|
387
|
+
// A statement already finalized by an error path is not a rebuild failure.
|
|
388
|
+
}
|
|
389
|
+
}
|
|
372
390
|
db.close();
|
|
373
391
|
artifactStore.close();
|
|
374
392
|
}
|
|
@@ -175,7 +175,7 @@ export function assertTrustedSystemExecutableForTests(candidate: string, label:
|
|
|
175
175
|
return assertTrustedSystemExecutable(candidate, label);
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
type ElevationExeOverrides = { powershell?: string; schtasks?: string; taskkill?: string };
|
|
178
|
+
type ElevationExeOverrides = { powershell?: string; schtasks?: string; taskkill?: string; icacls?: string };
|
|
179
179
|
let elevationExeOverridesForTests: ElevationExeOverrides | null = null;
|
|
180
180
|
|
|
181
181
|
/**
|
|
@@ -220,6 +220,15 @@ export function resolveTrustedWindowsTaskkillExe(): string {
|
|
|
220
220
|
return assertTrustedSystemExecutable(candidate, "taskkill.exe");
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
+
/** Absolute path to System32\\icacls.exe from a trusted system directory. */
|
|
224
|
+
export function resolveTrustedWindowsIcaclsExe(): string {
|
|
225
|
+
if (elevationExeOverridesForTests?.icacls) {
|
|
226
|
+
return elevationExeOverridesForTests.icacls;
|
|
227
|
+
}
|
|
228
|
+
const candidate = join(resolveTrustedWindowsSystemDirectory(), "icacls.exe");
|
|
229
|
+
return assertTrustedSystemExecutable(candidate, "icacls.exe");
|
|
230
|
+
}
|
|
231
|
+
|
|
223
232
|
/** Stable machine-readable marker for a denied `schtasks /create`. Crosses the CLI→proxy boundary. */
|
|
224
233
|
export const WINDOWS_SCHTASKS_CREATE_ACCESS_DENIED_MARKER =
|
|
225
234
|
"OCX_ERROR_CODE=WINDOWS_SCHTASKS_CREATE_ACCESS_DENIED";
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
|
|
32
32
|
import { existsSync, statSync } from "node:fs";
|
|
33
33
|
import { env, platform } from "node:process";
|
|
34
|
+
import { resolveTrustedWindowsIcaclsExe } from "./windows-elevation";
|
|
34
35
|
import {
|
|
35
36
|
resolveCurrentWindowsPrincipal,
|
|
36
37
|
resolveCurrentWindowsPrincipalAsync,
|
|
@@ -273,22 +274,55 @@ export interface IcaclsResult {
|
|
|
273
274
|
type IcaclsRunner = (args: string[], timeoutMs: number) => IcaclsResult;
|
|
274
275
|
type AsyncIcaclsRunner = (args: string[], timeoutMs: number) => Promise<IcaclsResult>;
|
|
275
276
|
|
|
277
|
+
function resolveIcaclsExecutable(): string {
|
|
278
|
+
// Same authority as schtasks/powershell: never take icacls from PATH.
|
|
279
|
+
// A bun-shim or stripped PATH makes `icacls.exe` throw ENOENT, which used to
|
|
280
|
+
// surface as "filesystem may not support per-user NTFS ACLs".
|
|
281
|
+
return resolveTrustedWindowsIcaclsExe();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function spawnFailedResult(): IcaclsResult {
|
|
285
|
+
return { success: false, exitCode: null, timedOut: false, stdout: "" };
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Spawn icacls asynchronously, or return null when the executable cannot be
|
|
290
|
+
* launched. The pipe/ignore stdio literals stay inferred here so `stdout` keeps
|
|
291
|
+
* its `ReadableStream` type instead of widening to the generic default.
|
|
292
|
+
*/
|
|
293
|
+
function trySpawnIcacls(args: string[]) {
|
|
294
|
+
try {
|
|
295
|
+
return Bun.spawn([resolveIcaclsExecutable(), ...args], {
|
|
296
|
+
stdin: "ignore",
|
|
297
|
+
stdout: "pipe",
|
|
298
|
+
stderr: "ignore",
|
|
299
|
+
windowsHide: true,
|
|
300
|
+
});
|
|
301
|
+
} catch {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
276
306
|
function defaultIcaclsRunner(args: string[], timeoutMs: number): IcaclsResult {
|
|
277
307
|
// Bun.spawnSync with windowsHide: Node execFileSync has hung under the GUI/proxy even
|
|
278
308
|
// with windowsHide, and console-subsystem tools flash a visible window otherwise.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
309
|
+
try {
|
|
310
|
+
const result = Bun.spawnSync([resolveIcaclsExecutable(), ...args], {
|
|
311
|
+
stdin: "ignore",
|
|
312
|
+
stdout: "pipe",
|
|
313
|
+
stderr: "ignore",
|
|
314
|
+
timeout: timeoutMs,
|
|
315
|
+
windowsHide: true,
|
|
316
|
+
});
|
|
317
|
+
return {
|
|
318
|
+
success: result.success,
|
|
319
|
+
exitCode: result.exitCode,
|
|
320
|
+
timedOut: result.exitedDueToTimeout ?? false,
|
|
321
|
+
stdout: result.stdout ? result.stdout.toString() : "",
|
|
322
|
+
};
|
|
323
|
+
} catch {
|
|
324
|
+
return spawnFailedResult();
|
|
325
|
+
}
|
|
292
326
|
}
|
|
293
327
|
|
|
294
328
|
/**
|
|
@@ -297,12 +331,8 @@ function defaultIcaclsRunner(args: string[], timeoutMs: number): IcaclsResult {
|
|
|
297
331
|
* we still await process exit before classifying so settlement is confirmed.
|
|
298
332
|
*/
|
|
299
333
|
async function defaultAsyncIcaclsRunner(args: string[], timeoutMs: number): Promise<IcaclsResult> {
|
|
300
|
-
const proc =
|
|
301
|
-
|
|
302
|
-
stdout: "pipe",
|
|
303
|
-
stderr: "ignore",
|
|
304
|
-
windowsHide: true,
|
|
305
|
-
});
|
|
334
|
+
const proc = trySpawnIcacls(args);
|
|
335
|
+
if (!proc) return spawnFailedResult();
|
|
306
336
|
let timedOutByUs = false;
|
|
307
337
|
const timer = setTimeout(() => {
|
|
308
338
|
timedOutByUs = true;
|
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
import type { OcxConfig } from "../types";
|
|
14
14
|
import { isCanonicalOpenAiForwardProvider, OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
|
|
15
15
|
import { serviceTierSupportForModel } from "../providers/service-tier";
|
|
16
|
-
import { applyProviderContextCap, providerContextCap } from "../providers/context-cap";
|
|
17
16
|
import { PROVIDER_REGISTRY } from "../providers/registry";
|
|
18
17
|
import {
|
|
19
18
|
nativeInputModalities,
|
|
20
|
-
nativeOpenAiContextWindow,
|
|
19
|
+
nativeContextLimits, nativeOpenAiContextWindow,
|
|
21
20
|
nativeParallelToolCalls,
|
|
22
21
|
nativeReasoningEfforts,
|
|
23
22
|
} from "../codex/catalog/metadata";
|
|
@@ -164,11 +163,11 @@ export function candidateCapabilityEvidence(
|
|
|
164
163
|
?? provider?.contextWindow
|
|
165
164
|
?? registryEntry?.modelContextWindows?.[modelId]
|
|
166
165
|
?? catalogRow?.contextWindow
|
|
167
|
-
?? (isNative ? nativeOpenAiContextWindow(modelId) : undefined);
|
|
168
|
-
//
|
|
169
|
-
//
|
|
166
|
+
?? (isNative ? nativeOpenAiContextWindow(modelId, nativeContextLimits(config)) : undefined);
|
|
167
|
+
// Native rows go through the accessor (raise-to-ceiling + opt-in). Routed rows keep
|
|
168
|
+
// the raw value; a provider cap on openai must not invent a window they do not have.
|
|
170
169
|
const contextWindow = isNative
|
|
171
|
-
?
|
|
170
|
+
? (nativeOpenAiContextWindow(modelId, nativeContextLimits(config)) ?? rawContextWindow)
|
|
172
171
|
: rawContextWindow;
|
|
173
172
|
|
|
174
173
|
const modalities = provider?.modelInputModalities?.[modelId]
|
package/src/server/index.ts
CHANGED
|
@@ -50,7 +50,6 @@ import { runOpenAiTierStartupMigration } from "../providers/openai-tier-startup"
|
|
|
50
50
|
import { runAlibabaRegionStartupMigration } from "../providers/alibaba-region-startup";
|
|
51
51
|
import { runModelRenameStartupMigration } from "../providers/model-rename-startup";
|
|
52
52
|
import { isCanonicalOpenAiForwardProvider, OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
|
|
53
|
-
import { providerContextCap } from "../providers/context-cap";
|
|
54
53
|
import { providerCodexAccountMode } from "../providers/registry";
|
|
55
54
|
import type { StorageCleanupPolicy } from "../types";
|
|
56
55
|
import { MAX_DECOMPRESSED_BODY_BYTES } from "./request-decompress";
|
|
@@ -906,7 +905,7 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server<W
|
|
|
906
905
|
}
|
|
907
906
|
throw error;
|
|
908
907
|
}
|
|
909
|
-
const { accountBoundNativeOpenAiSlugsBySelector, applyNativeVisibility, buildCatalogEntries, configuredNativeAliasSlugs, desktopAllowlistSuppressedNativeSlugs, disabledNativeSlugs, exactComboCatalogSlugs, loadCatalogTemplate, NATIVE_OPENAI_MODELS, nativeOpenAiSlugs, nativeReasoningEfforts, nativeDefaultReasoningEffort, orderForSubagents, filterCatalogVisibleModels, shouldIncludeAccountBoundNativeOpenAi, shouldIncludeNativeOpenAi, uniqueCatalogModelsForRawPublicList, visibleCodexAccountSelectors, visibleNativeSlugs, desktopVisibleNativeSlugs } = await import("../codex/catalog");
|
|
908
|
+
const { accountBoundNativeOpenAiSlugsBySelector, applyNativeVisibility, buildCatalogEntries, configuredNativeAliasSlugs, desktopAllowlistSuppressedNativeSlugs, disabledNativeSlugs, exactComboCatalogSlugs, loadCatalogTemplate, NATIVE_OPENAI_MODELS, nativeContextLimits, nativeOpenAiSlugs, nativeReasoningEfforts, nativeDefaultReasoningEffort, orderForSubagents, filterCatalogVisibleModels, shouldIncludeAccountBoundNativeOpenAi, shouldIncludeNativeOpenAi, uniqueCatalogModelsForRawPublicList, visibleCodexAccountSelectors, visibleNativeSlugs, desktopVisibleNativeSlugs } = await import("../codex/catalog");
|
|
910
909
|
const includeNativeOpenAi = shouldIncludeNativeOpenAi(config);
|
|
911
910
|
const includeAccountBoundNativeOpenAi = shouldIncludeAccountBoundNativeOpenAi(config);
|
|
912
911
|
const nativeSlugs = includeNativeOpenAi
|
|
@@ -958,7 +957,7 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server<W
|
|
|
958
957
|
: idsParam === "desktop"
|
|
959
958
|
? "desktop3p" as const
|
|
960
959
|
: (/^claude-code\//i.test(req.headers.get("user-agent") ?? "") ? "readable" as const : "desktop3p" as const);
|
|
961
|
-
const data = buildAnthropicModelInfos([...desktopVisibleNativeSlugs(config)], goOrdered, resolveAutoContext(config.claudeCode), idStyle, activeDesktop3pAlias,
|
|
960
|
+
const data = buildAnthropicModelInfos([...desktopVisibleNativeSlugs(config)], goOrdered, resolveAutoContext(config.claudeCode), idStyle, activeDesktop3pAlias, nativeContextLimits(config));
|
|
962
961
|
return jsonResponse({ data }, 200, req, policy);
|
|
963
962
|
}
|
|
964
963
|
if (url.searchParams.has("client_version")) {
|
|
@@ -985,7 +984,7 @@ export function startServer(port?: number, deps: StartServerDeps = {}): Server<W
|
|
|
985
984
|
accountSelectors,
|
|
986
985
|
suppressedBareNativeSlugs,
|
|
987
986
|
new Set(),
|
|
988
|
-
|
|
987
|
+
nativeContextLimits(config),
|
|
989
988
|
accountNativeSlugs,
|
|
990
989
|
accountNativeSlugsBySelector,
|
|
991
990
|
config.keepNativeChatGptOnV1 === true,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import type { CatalogModel } from "../../codex/catalog";
|
|
4
|
-
import { catalogModelSlug, invalidateCodexModelsCache, nativeModelRows, uniqueCatalogModelsForPublicList } from "../../codex/catalog";
|
|
4
|
+
import { catalogModelSlug, invalidateCodexModelsCache, nativeContextLimits, nativeModelRows, uniqueCatalogModelsForPublicList } from "../../codex/catalog";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_SUBAGENT_MODELS,
|
|
7
7
|
codexAutoStartEnabled,
|
|
@@ -207,7 +207,7 @@ export async function handleAgentSettingsRoutes(ctx: ManagementContext): Promise
|
|
|
207
207
|
current.apiKeys?.[0]?.key,
|
|
208
208
|
"static",
|
|
209
209
|
current.claudeCode.desktopProfile,
|
|
210
|
-
|
|
210
|
+
nativeContextLimits(current),
|
|
211
211
|
);
|
|
212
212
|
if (result.written && result.fingerprint) {
|
|
213
213
|
current.claudeCode = { ...current.claudeCode, desktopProfile: { ...current.claudeCode.desktopProfile, appliedFingerprint: result.fingerprint, appliedAt: new Date().toISOString() } };
|
|
@@ -886,7 +886,7 @@ export async function handleAgentSettingsRoutes(ctx: ManagementContext): Promise
|
|
|
886
886
|
latest.apiKeys?.[0]?.key,
|
|
887
887
|
mode,
|
|
888
888
|
state.profile,
|
|
889
|
-
|
|
889
|
+
nativeContextLimits(latest),
|
|
890
890
|
);
|
|
891
891
|
if (!result.written) return jsonResponse({ error: result.reason ?? "Claude Desktop apply failed", saved: true, path: result.path }, 500);
|
|
892
892
|
// Persist applied fingerprint + timestamp so GUI can show saved-vs-applied state.
|
|
@@ -978,7 +978,7 @@ export async function handleAgentSettingsRoutes(ctx: ManagementContext): Promise
|
|
|
978
978
|
if (isDisabled(m.provider, m.id)) continue;
|
|
979
979
|
aliases.push({ id: claudeCodeAlias(m.provider, m.id), display_name: `${m.id} (${m.provider})` });
|
|
980
980
|
}
|
|
981
|
-
const contextWindows = buildClaudeContextWindows([...visibleNativeSlugs(config)], models,
|
|
981
|
+
const contextWindows = buildClaudeContextWindows([...visibleNativeSlugs(config)], models, nativeContextLimits(config));
|
|
982
982
|
const webSearchOverride = config.claudeCode?.webSearchSidecar;
|
|
983
983
|
const visionOverride = config.claudeCode?.visionSidecar;
|
|
984
984
|
// Auto is a RESOLUTION, recomputed per request — never stored state. Detection is
|
|
@@ -1010,7 +1010,7 @@ export async function handleAgentSettingsRoutes(ctx: ManagementContext): Promise
|
|
|
1010
1010
|
classifierModel: config.claudeCode?.classifierModel ?? "",
|
|
1011
1011
|
classifierFallbacks: config.claudeCode?.classifierFallbacks ?? [],
|
|
1012
1012
|
systemEnv: config.claudeCode?.systemEnv === true,
|
|
1013
|
-
autoConnectSupported: process.platform === "darwin",
|
|
1013
|
+
autoConnectSupported: (ctx.deps.platform ?? process.platform) === "darwin",
|
|
1014
1014
|
maxContextTokens: config.claudeCode?.maxContextTokens ?? null,
|
|
1015
1015
|
alwaysEnableEffort: config.claudeCode?.alwaysEnableEffort === true,
|
|
1016
1016
|
autoContext: config.claudeCode?.autoContext !== false,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import type { CatalogModel } from "../../codex/catalog";
|
|
4
|
-
import { catalogModelSlug, invalidateCodexModelsCache, nativeModelRows, uniqueCatalogModelsForPublicList } from "../../codex/catalog";
|
|
4
|
+
import { catalogModelSlug, invalidateCodexModelsCache, nativeContextLimits, nativeModelRows, uniqueCatalogModelsForPublicList } from "../../codex/catalog";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_SUBAGENT_MODELS,
|
|
7
7
|
codexAutoStartEnabled,
|
|
@@ -173,7 +173,7 @@ async function syncEnabledClientIntegrations(
|
|
|
173
173
|
config.apiKeys?.[0]?.key,
|
|
174
174
|
"static",
|
|
175
175
|
config.claudeCode?.desktopProfile,
|
|
176
|
-
|
|
176
|
+
nativeContextLimits(config),
|
|
177
177
|
);
|
|
178
178
|
out.push(r.written
|
|
179
179
|
? { client: "claude-desktop", ok: true, changed: true }
|
|
@@ -16,6 +16,8 @@ import type {
|
|
|
16
16
|
} from "../../codex/app-server-restart-service";
|
|
17
17
|
|
|
18
18
|
export interface ManagementApiDeps {
|
|
19
|
+
/** Platform seam for capability projections; does not alter host-level startup behavior. */
|
|
20
|
+
platform?: NodeJS.Platform;
|
|
19
21
|
toggleCodexMultiAgentV2?: (enabled: boolean) => void;
|
|
20
22
|
toggleDefaultModeRequestUserInput?: (enabled: boolean) => void;
|
|
21
23
|
createManagementConvergeCodex?: (config: Readonly<OcxConfig>) => ConvergeCodex;
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* 011 (Claude Code), 012 (Grok).
|
|
19
19
|
*/
|
|
20
20
|
import { loadConfig, readRuntimePort, saveConfigPreservingClaudeCode } from "../../config";
|
|
21
|
-
import { desktopVisibleNativeSlugs, filterCatalogVisibleModels, nativeOpenAiContextWindow, visibleNativeSlugs } from "../../codex/catalog";
|
|
21
|
+
import { desktopVisibleNativeSlugs, filterCatalogVisibleModels, nativeContextLimits, nativeOpenAiContextWindow, visibleNativeSlugs } from "../../codex/catalog";
|
|
22
22
|
import { providerContextCap } from "../../providers/context-cap";
|
|
23
23
|
import { OPENAI_CODEX_PROVIDER_ID } from "../../providers/openai-tiers";
|
|
24
24
|
import { inspectDesktop3pConfigLibrary, removeDesktop3pStandardPivot, writeDesktop3pConfig } from "../../claude/desktop-3p";
|
|
@@ -508,7 +508,7 @@ async function handleGrokToggle(ctx: ManagementContext): Promise<Response> {
|
|
|
508
508
|
// Native slugs carry their context window: without it Grok falls back
|
|
509
509
|
// to its own 200k default and understates a 372k model.
|
|
510
510
|
...visibleNativeSlugs(config).map(id => {
|
|
511
|
-
const contextWindow = nativeOpenAiContextWindow(id,
|
|
511
|
+
const contextWindow = nativeOpenAiContextWindow(id, nativeContextLimits(config));
|
|
512
512
|
return { id, ...(contextWindow !== undefined ? { contextWindow } : {}) };
|
|
513
513
|
}),
|
|
514
514
|
...routed.map(m => ({
|
|
@@ -663,7 +663,7 @@ async function handleClaudeDesktopToggle(ctx: ManagementContext): Promise<Respon
|
|
|
663
663
|
latest.apiKeys?.[0]?.key,
|
|
664
664
|
"static",
|
|
665
665
|
latest.claudeCode?.desktopProfile,
|
|
666
|
-
|
|
666
|
+
nativeContextLimits(latest),
|
|
667
667
|
);
|
|
668
668
|
if (!result.written) return postCommitRefusal(500, "claude-desktop", "write_failed", "Claude Desktop apply failed.", { desiredEnabled: latestDesiredEnabled });
|
|
669
669
|
return jsonResponse({
|