@ccpocket/bridge 1.69.0 → 1.69.1
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/dist/codex-process.d.ts +25 -0
- package/dist/codex-process.js +148 -23
- package/dist/codex-process.js.map +1 -1
- package/dist/sessions-index.js +4 -0
- package/dist/sessions-index.js.map +1 -1
- package/dist/websocket.d.ts +4 -0
- package/dist/websocket.js +134 -57
- package/dist/websocket.js.map +1 -1
- package/package.json +1 -1
package/dist/websocket.js
CHANGED
|
@@ -7,7 +7,7 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { WebSocketServer, WebSocket } from "ws";
|
|
8
8
|
import { SessionManager, MAX_HISTORY_PER_SESSION, } from "./session.js";
|
|
9
9
|
import { SdkProcess, listAvailableClaudeModels, } from "./sdk-process.js";
|
|
10
|
-
import { CodexProcess, } from "./codex-process.js";
|
|
10
|
+
import { codexErrorMessage, CodexRpcError, CodexProcess, } from "./codex-process.js";
|
|
11
11
|
import { stopManagedCodexAppServers } from "./codex-transport.js";
|
|
12
12
|
import { parseClientMessage, } from "./parser.js";
|
|
13
13
|
import { getAllRecentSessions, getCodexSessionHistory, getSessionHistory, codexUserTurnUuid, codexThreadToSessionHistory, findSessionsByClaudeIds, extractMessageImages, getClaudeSessionName, getCodexSessionIndexMetadata, loadCodexSessionNames, renameClaudeSession, renameCodexSession, saveCodexSessionProfile, } from "./sessions-index.js";
|
|
@@ -243,6 +243,9 @@ function normalizeCodexApprovalPolicy(value) {
|
|
|
243
243
|
return "on-request";
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
+
function isCodexAutoReviewApprovalsReviewer(value) {
|
|
247
|
+
return value === "auto_review" || value === "guardian_subagent";
|
|
248
|
+
}
|
|
246
249
|
function sanitizeCodexModel(model) {
|
|
247
250
|
if (typeof model !== "string")
|
|
248
251
|
return undefined;
|
|
@@ -457,6 +460,8 @@ export class BridgeWebSocketServer {
|
|
|
457
460
|
archiveStore;
|
|
458
461
|
codexProfiles = [];
|
|
459
462
|
defaultCodexProfile;
|
|
463
|
+
codexAutoReviewDisabled = false;
|
|
464
|
+
codexAutoReviewPolicyLoaded = false;
|
|
460
465
|
codexMetadataRequest = null;
|
|
461
466
|
lastConnectMetadataRefreshAt = null;
|
|
462
467
|
claudeModels = FALLBACK_CLAUDE_MODELS;
|
|
@@ -809,10 +814,10 @@ export class BridgeWebSocketServer {
|
|
|
809
814
|
fallback: buildCodexHistoryPrefix(session, targetOrdinal - 1),
|
|
810
815
|
});
|
|
811
816
|
this.destroySession(sessionId);
|
|
812
|
-
const newSessionId = this.sessionManager.create(projectPath, undefined, pastMessages, worktreeOpts, "codex", {
|
|
817
|
+
const newSessionId = this.sessionManager.create(projectPath, undefined, pastMessages, worktreeOpts, "codex", this.withCodexAutoReviewPolicy({
|
|
813
818
|
...(codexSettings ?? {}),
|
|
814
819
|
threadId,
|
|
815
|
-
});
|
|
820
|
+
}));
|
|
816
821
|
const newSession = this.sessionManager.get(newSessionId);
|
|
817
822
|
this.send(ws, {
|
|
818
823
|
type: "rewind_result",
|
|
@@ -824,8 +829,8 @@ export class BridgeWebSocketServer {
|
|
|
824
829
|
provider: "codex",
|
|
825
830
|
projectPath,
|
|
826
831
|
session: newSession,
|
|
827
|
-
approvalsReviewer: codexSettings?.approvalsReviewer,
|
|
828
|
-
sandboxMode: codexSettings?.sandboxMode,
|
|
832
|
+
approvalsReviewer: newSession?.codexSettings?.approvalsReviewer,
|
|
833
|
+
sandboxMode: newSession?.codexSettings?.sandboxMode,
|
|
829
834
|
sourceSessionId: sessionId,
|
|
830
835
|
}));
|
|
831
836
|
this.sendSessionList(ws);
|
|
@@ -896,18 +901,18 @@ export class BridgeWebSocketServer {
|
|
|
896
901
|
expectedUserTurns: targetOrdinal,
|
|
897
902
|
fallback: buildCodexHistoryPrefix(session, targetOrdinal),
|
|
898
903
|
});
|
|
899
|
-
const newSessionId = this.sessionManager.create(projectPath, undefined, pastMessages, worktreeOpts, "codex", {
|
|
904
|
+
const newSessionId = this.sessionManager.create(projectPath, undefined, pastMessages, worktreeOpts, "codex", this.withCodexAutoReviewPolicy({
|
|
900
905
|
...(codexSettings ?? {}),
|
|
901
906
|
threadId: forkedThreadId,
|
|
902
|
-
});
|
|
907
|
+
}));
|
|
903
908
|
const newSession = this.sessionManager.get(newSessionId);
|
|
904
909
|
this.send(ws, this.buildSessionCreatedMessage({
|
|
905
910
|
sessionId: newSessionId,
|
|
906
911
|
provider: "codex",
|
|
907
912
|
projectPath,
|
|
908
913
|
session: newSession,
|
|
909
|
-
approvalsReviewer: codexSettings?.approvalsReviewer,
|
|
910
|
-
sandboxMode: codexSettings?.sandboxMode,
|
|
914
|
+
approvalsReviewer: newSession?.codexSettings?.approvalsReviewer,
|
|
915
|
+
sandboxMode: newSession?.codexSettings?.sandboxMode,
|
|
911
916
|
sourceSessionId: sessionId,
|
|
912
917
|
}));
|
|
913
918
|
this.sendSessionList(ws);
|
|
@@ -1645,9 +1650,13 @@ export class BridgeWebSocketServer {
|
|
|
1645
1650
|
}
|
|
1646
1651
|
try {
|
|
1647
1652
|
const provider = msg.provider ?? "claude";
|
|
1648
|
-
const
|
|
1653
|
+
const normalizedCodexPermissionsMode = provider === "codex"
|
|
1649
1654
|
? normalizeCodexPermissionsMode(msg.codexPermissionsMode)
|
|
1650
1655
|
: undefined;
|
|
1656
|
+
const requestedCodexPermissionsMode = this.codexAutoReviewDisabled &&
|
|
1657
|
+
normalizedCodexPermissionsMode === "autoReview"
|
|
1658
|
+
? "default"
|
|
1659
|
+
: normalizedCodexPermissionsMode;
|
|
1651
1660
|
const codexPermissionSettings = requestedCodexPermissionsMode
|
|
1652
1661
|
? codexSettingsFromPermissionsMode(requestedCodexPermissionsMode)
|
|
1653
1662
|
: undefined;
|
|
@@ -1723,7 +1732,7 @@ export class BridgeWebSocketServer {
|
|
|
1723
1732
|
useWorktree: msg.useWorktree,
|
|
1724
1733
|
worktreeBranch: msg.worktreeBranch,
|
|
1725
1734
|
existingWorktreePath: msg.existingWorktreePath,
|
|
1726
|
-
}, provider, {
|
|
1735
|
+
}, provider, this.withCodexAutoReviewPolicy({
|
|
1727
1736
|
profile: msg.profile,
|
|
1728
1737
|
approvalPolicy: codexPermissionSettings
|
|
1729
1738
|
? codexPermissionSettings.approvalPolicy
|
|
@@ -1731,9 +1740,8 @@ export class BridgeWebSocketServer {
|
|
|
1731
1740
|
normalizeCodexApprovalPolicy(executionMode === "fullAccess"
|
|
1732
1741
|
? "never"
|
|
1733
1742
|
: "on-request")),
|
|
1734
|
-
approvalsReviewer: codexPermissionSettings
|
|
1735
|
-
|
|
1736
|
-
: msg.approvalsReviewer,
|
|
1743
|
+
approvalsReviewer: codexPermissionSettings?.approvalsReviewer ??
|
|
1744
|
+
msg.approvalsReviewer,
|
|
1737
1745
|
codexPermissionsMode: codexPermissionSettings?.codexPermissionsMode,
|
|
1738
1746
|
sandboxMode: codexPermissionSettings
|
|
1739
1747
|
? codexPermissionSettings.sandboxMode
|
|
@@ -1750,7 +1758,7 @@ export class BridgeWebSocketServer {
|
|
|
1750
1758
|
collaborationMode: planMode
|
|
1751
1759
|
? "plan"
|
|
1752
1760
|
: "default",
|
|
1753
|
-
}),
|
|
1761
|
+
})),
|
|
1754
1762
|
permissionMode: claudePermissionMode,
|
|
1755
1763
|
executionMode,
|
|
1756
1764
|
planMode,
|
|
@@ -2290,7 +2298,15 @@ export class BridgeWebSocketServer {
|
|
|
2290
2298
|
// Permission mode for Codex requires a session restart (like sandbox mode).
|
|
2291
2299
|
// approvalPolicy and collaborationMode are thread-level settings that
|
|
2292
2300
|
// only take effect reliably at thread/start or thread/resume time.
|
|
2293
|
-
const
|
|
2301
|
+
const normalizedCodexPermissionsMode = normalizeCodexPermissionsMode(msg.codexPermissionsMode);
|
|
2302
|
+
const requestedCodexPermissionsMode = this.codexAutoReviewDisabled &&
|
|
2303
|
+
normalizedCodexPermissionsMode === "autoReview"
|
|
2304
|
+
? "default"
|
|
2305
|
+
: normalizedCodexPermissionsMode;
|
|
2306
|
+
const requestedApprovalsReviewer = this.codexAutoReviewDisabled &&
|
|
2307
|
+
isCodexAutoReviewApprovalsReviewer(msg.approvalsReviewer)
|
|
2308
|
+
? "user"
|
|
2309
|
+
: msg.approvalsReviewer;
|
|
2294
2310
|
const codexPermissionSettings = requestedCodexPermissionsMode
|
|
2295
2311
|
? codexSettingsFromPermissionsMode(requestedCodexPermissionsMode)
|
|
2296
2312
|
: undefined;
|
|
@@ -2328,23 +2344,28 @@ export class BridgeWebSocketServer {
|
|
|
2328
2344
|
const newSandboxMode = codexPermissionSettings
|
|
2329
2345
|
? codexPermissionSettings.sandboxMode
|
|
2330
2346
|
: currentSandboxMode;
|
|
2331
|
-
const
|
|
2347
|
+
const configuredReviewer = requestedCodexPermissionsMode === "custom"
|
|
2348
|
+
? undefined
|
|
2349
|
+
: (codexPermissionSettings?.approvalsReviewer ??
|
|
2350
|
+
requestedApprovalsReviewer ??
|
|
2351
|
+
currentReviewer);
|
|
2352
|
+
const newReviewer = this.codexAutoReviewDisabled
|
|
2353
|
+
? "user"
|
|
2354
|
+
: configuredReviewer;
|
|
2355
|
+
const derivedPermissionsMode = codexPermissionSettings?.codexPermissionsMode ??
|
|
2332
2356
|
(collaborationOnlyChange ? currentPermissionsMode : undefined) ??
|
|
2333
2357
|
deriveCodexPermissionsMode({
|
|
2334
2358
|
approvalPolicy: newApproval,
|
|
2335
|
-
approvalsReviewer:
|
|
2336
|
-
msg.approvalsReviewer ??
|
|
2337
|
-
currentReviewer,
|
|
2359
|
+
approvalsReviewer: newReviewer,
|
|
2338
2360
|
sandboxMode: newSandboxMode,
|
|
2339
2361
|
});
|
|
2362
|
+
const newPermissionsMode = this.codexAutoReviewDisabled &&
|
|
2363
|
+
derivedPermissionsMode === "autoReview"
|
|
2364
|
+
? "default"
|
|
2365
|
+
: derivedPermissionsMode;
|
|
2340
2366
|
const newCollaboration = planMode
|
|
2341
2367
|
? "plan"
|
|
2342
2368
|
: "default";
|
|
2343
|
-
const newReviewer = requestedCodexPermissionsMode === "custom"
|
|
2344
|
-
? undefined
|
|
2345
|
-
: (codexPermissionSettings?.approvalsReviewer ??
|
|
2346
|
-
msg.approvalsReviewer ??
|
|
2347
|
-
currentReviewer);
|
|
2348
2369
|
const currentCollaboration = process.collaborationMode;
|
|
2349
2370
|
if (newApproval === currentApproval &&
|
|
2350
2371
|
newReviewer === currentReviewer &&
|
|
@@ -2355,7 +2376,9 @@ export class BridgeWebSocketServer {
|
|
|
2355
2376
|
}
|
|
2356
2377
|
const canApplyModeInPlace = session.status === "idle" &&
|
|
2357
2378
|
requestedCodexPermissionsMode !== "custom" &&
|
|
2358
|
-
newSandboxMode === currentSandboxMode
|
|
2379
|
+
newSandboxMode === currentSandboxMode &&
|
|
2380
|
+
(this.codexAutoReviewPolicyLoaded ||
|
|
2381
|
+
!isCodexAutoReviewApprovalsReviewer(newReviewer));
|
|
2359
2382
|
if (canApplyModeInPlace) {
|
|
2360
2383
|
const process = session.process;
|
|
2361
2384
|
if (newApproval && newApproval !== currentApproval) {
|
|
@@ -2411,7 +2434,7 @@ export class BridgeWebSocketServer {
|
|
|
2411
2434
|
if (!threadId || !hasUserMessages) {
|
|
2412
2435
|
const newId = this.sessionManager.create(projectPath, undefined, undefined, worktreePath
|
|
2413
2436
|
? { existingWorktreePath: worktreePath, worktreeBranch }
|
|
2414
|
-
: undefined, "codex", {
|
|
2437
|
+
: undefined, "codex", this.withCodexAutoReviewPolicy({
|
|
2415
2438
|
approvalPolicy: newApproval,
|
|
2416
2439
|
approvalsReviewer: newReviewer,
|
|
2417
2440
|
codexPermissionsMode: newPermissionsMode,
|
|
@@ -2422,7 +2445,7 @@ export class BridgeWebSocketServer {
|
|
|
2422
2445
|
networkAccessEnabled: oldSettings.networkAccessEnabled,
|
|
2423
2446
|
webSearchMode: oldSettings.webSearchMode,
|
|
2424
2447
|
collaborationMode: newCollaboration,
|
|
2425
|
-
});
|
|
2448
|
+
}));
|
|
2426
2449
|
const newSession = this.sessionManager.get(newId);
|
|
2427
2450
|
if (newSession && sessionName)
|
|
2428
2451
|
newSession.name = sessionName;
|
|
@@ -2471,7 +2494,7 @@ export class BridgeWebSocketServer {
|
|
|
2471
2494
|
}
|
|
2472
2495
|
this.getCodexThreadHistory(threadId, effectiveProjectPath)
|
|
2473
2496
|
.then((pastMessages) => {
|
|
2474
|
-
const newId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", {
|
|
2497
|
+
const newId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", this.withCodexAutoReviewPolicy({
|
|
2475
2498
|
threadId,
|
|
2476
2499
|
approvalPolicy: newApproval,
|
|
2477
2500
|
approvalsReviewer: newReviewer,
|
|
@@ -2483,7 +2506,7 @@ export class BridgeWebSocketServer {
|
|
|
2483
2506
|
networkAccessEnabled: oldSettings.networkAccessEnabled,
|
|
2484
2507
|
webSearchMode: oldSettings.webSearchMode,
|
|
2485
2508
|
collaborationMode: newCollaboration,
|
|
2486
|
-
});
|
|
2509
|
+
}));
|
|
2487
2510
|
const newSession = this.sessionManager.get(newId);
|
|
2488
2511
|
if (newSession && sessionName) {
|
|
2489
2512
|
newSession.name = sessionName;
|
|
@@ -2822,8 +2845,10 @@ export class BridgeWebSocketServer {
|
|
|
2822
2845
|
// "no rollout found for thread id".)
|
|
2823
2846
|
const newId = this.sessionManager.create(projectPath, undefined, undefined, worktreePath
|
|
2824
2847
|
? { existingWorktreePath: worktreePath, worktreeBranch }
|
|
2825
|
-
: undefined, "codex", {
|
|
2848
|
+
: undefined, "codex", this.withCodexAutoReviewPolicy({
|
|
2826
2849
|
approvalPolicy: oldSettings.approvalPolicy,
|
|
2850
|
+
approvalsReviewer: oldSettings.approvalsReviewer,
|
|
2851
|
+
codexPermissionsMode: oldSettings.codexPermissionsMode,
|
|
2827
2852
|
sandboxMode: newSandboxMode,
|
|
2828
2853
|
model: oldSettings.model,
|
|
2829
2854
|
modelReasoningEffort: oldSettings.modelReasoningEffort,
|
|
@@ -2831,7 +2856,7 @@ export class BridgeWebSocketServer {
|
|
|
2831
2856
|
networkAccessEnabled: oldSettings.networkAccessEnabled,
|
|
2832
2857
|
webSearchMode: oldSettings.webSearchMode,
|
|
2833
2858
|
collaborationMode,
|
|
2834
|
-
});
|
|
2859
|
+
}));
|
|
2835
2860
|
const newSession = this.sessionManager.get(newId);
|
|
2836
2861
|
if (newSession && sessionName)
|
|
2837
2862
|
newSession.name = sessionName;
|
|
@@ -2873,9 +2898,11 @@ export class BridgeWebSocketServer {
|
|
|
2873
2898
|
}
|
|
2874
2899
|
this.getCodexThreadHistory(threadId, effectiveProjectPath)
|
|
2875
2900
|
.then((pastMessages) => {
|
|
2876
|
-
const newId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", {
|
|
2901
|
+
const newId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", this.withCodexAutoReviewPolicy({
|
|
2877
2902
|
threadId,
|
|
2878
2903
|
approvalPolicy: oldSettings.approvalPolicy,
|
|
2904
|
+
approvalsReviewer: oldSettings.approvalsReviewer,
|
|
2905
|
+
codexPermissionsMode: oldSettings.codexPermissionsMode,
|
|
2879
2906
|
sandboxMode: newSandboxMode,
|
|
2880
2907
|
model: oldSettings.model,
|
|
2881
2908
|
modelReasoningEffort: oldSettings.modelReasoningEffort,
|
|
@@ -2883,7 +2910,7 @@ export class BridgeWebSocketServer {
|
|
|
2883
2910
|
networkAccessEnabled: oldSettings.networkAccessEnabled,
|
|
2884
2911
|
webSearchMode: oldSettings.webSearchMode,
|
|
2885
2912
|
collaborationMode,
|
|
2886
|
-
});
|
|
2913
|
+
}));
|
|
2887
2914
|
// Restore session name
|
|
2888
2915
|
const newSession = this.sessionManager.get(newId);
|
|
2889
2916
|
if (newSession && sessionName) {
|
|
@@ -3320,25 +3347,39 @@ export class BridgeWebSocketServer {
|
|
|
3320
3347
|
}
|
|
3321
3348
|
case "archive_session": {
|
|
3322
3349
|
const { sessionId, provider, projectPath } = msg;
|
|
3323
|
-
this.
|
|
3324
|
-
|
|
3325
|
-
.
|
|
3326
|
-
|
|
3327
|
-
|
|
3350
|
+
const archiveProjectPath = resolvePlatformPath(projectPath, this.platform);
|
|
3351
|
+
if (!this.isPathAllowed(archiveProjectPath)) {
|
|
3352
|
+
const pathError = this.buildPathNotAllowedError(projectPath);
|
|
3353
|
+
this.send(ws, {
|
|
3354
|
+
type: "archive_result",
|
|
3355
|
+
sessionId,
|
|
3356
|
+
success: false,
|
|
3357
|
+
error: pathError.message,
|
|
3358
|
+
});
|
|
3359
|
+
break;
|
|
3360
|
+
}
|
|
3361
|
+
void (async () => {
|
|
3328
3362
|
if (provider === "codex") {
|
|
3329
|
-
const
|
|
3330
|
-
const
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
});
|
|
3363
|
+
const activeProcess = this.getActiveCodexProcess();
|
|
3364
|
+
const codexProcess = activeProcess ??
|
|
3365
|
+
(await this.createStandaloneCodexProcess(archiveProjectPath));
|
|
3366
|
+
try {
|
|
3367
|
+
await codexProcess.archiveThread(sessionId);
|
|
3368
|
+
}
|
|
3369
|
+
catch (err) {
|
|
3370
|
+
if (!(err instanceof CodexRpcError && err.code === -32601)) {
|
|
3371
|
+
throw err;
|
|
3339
3372
|
}
|
|
3373
|
+
console.warn("[ws] thread/archive unsupported; using local archive marker");
|
|
3374
|
+
}
|
|
3375
|
+
finally {
|
|
3376
|
+
if (!activeProcess)
|
|
3377
|
+
codexProcess.stop();
|
|
3340
3378
|
}
|
|
3341
3379
|
}
|
|
3380
|
+
await this.archiveStore.archive(sessionId, provider, archiveProjectPath);
|
|
3381
|
+
})()
|
|
3382
|
+
.then(() => {
|
|
3342
3383
|
this.send(ws, {
|
|
3343
3384
|
type: "archive_result",
|
|
3344
3385
|
sessionId,
|
|
@@ -3350,7 +3391,7 @@ export class BridgeWebSocketServer {
|
|
|
3350
3391
|
type: "archive_result",
|
|
3351
3392
|
sessionId,
|
|
3352
3393
|
success: false,
|
|
3353
|
-
error:
|
|
3394
|
+
error: codexErrorMessage(err),
|
|
3354
3395
|
});
|
|
3355
3396
|
});
|
|
3356
3397
|
break;
|
|
@@ -3363,9 +3404,13 @@ export class BridgeWebSocketServer {
|
|
|
3363
3404
|
break;
|
|
3364
3405
|
}
|
|
3365
3406
|
const provider = msg.provider ?? "claude";
|
|
3366
|
-
const
|
|
3407
|
+
const normalizedCodexPermissionsMode = provider === "codex"
|
|
3367
3408
|
? normalizeCodexPermissionsMode(msg.codexPermissionsMode)
|
|
3368
3409
|
: undefined;
|
|
3410
|
+
const requestedCodexPermissionsMode = this.codexAutoReviewDisabled &&
|
|
3411
|
+
normalizedCodexPermissionsMode === "autoReview"
|
|
3412
|
+
? "default"
|
|
3413
|
+
: normalizedCodexPermissionsMode;
|
|
3369
3414
|
const codexPermissionSettings = requestedCodexPermissionsMode
|
|
3370
3415
|
? codexSettingsFromPermissionsMode(requestedCodexPermissionsMode)
|
|
3371
3416
|
: undefined;
|
|
@@ -3424,16 +3469,15 @@ export class BridgeWebSocketServer {
|
|
|
3424
3469
|
}
|
|
3425
3470
|
try {
|
|
3426
3471
|
const pastMessages = await this.getCodexThreadHistory(sessionRefId, effectiveProjectPath);
|
|
3427
|
-
const sessionId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", {
|
|
3472
|
+
const sessionId = this.sessionManager.create(effectiveProjectPath, undefined, pastMessages, worktreeOpts, "codex", this.withCodexAutoReviewPolicy({
|
|
3428
3473
|
threadId: sessionRefId,
|
|
3429
3474
|
profile: effectiveProfile,
|
|
3430
3475
|
approvalPolicy: codexPermissionSettings
|
|
3431
3476
|
? codexPermissionSettings.approvalPolicy
|
|
3432
3477
|
: (codexApprovalPolicy ??
|
|
3433
3478
|
normalizeCodexApprovalPolicy(executionMode === "fullAccess" ? "never" : "on-request")),
|
|
3434
|
-
approvalsReviewer: codexPermissionSettings
|
|
3435
|
-
|
|
3436
|
-
: msg.approvalsReviewer,
|
|
3479
|
+
approvalsReviewer: codexPermissionSettings?.approvalsReviewer ??
|
|
3480
|
+
msg.approvalsReviewer,
|
|
3437
3481
|
codexPermissionsMode: codexPermissionSettings?.codexPermissionsMode,
|
|
3438
3482
|
sandboxMode: codexPermissionSettings
|
|
3439
3483
|
? codexPermissionSettings.sandboxMode
|
|
@@ -3449,7 +3493,7 @@ export class BridgeWebSocketServer {
|
|
|
3449
3493
|
collaborationMode: planMode
|
|
3450
3494
|
? "plan"
|
|
3451
3495
|
: "default",
|
|
3452
|
-
});
|
|
3496
|
+
}));
|
|
3453
3497
|
const createdSession = this.sessionManager.get(sessionId);
|
|
3454
3498
|
const cached = this.sessionManager.getCachedCommands("codex", createdSession?.worktreePath ?? effectiveProjectPath);
|
|
3455
3499
|
await this.loadAndSetSessionName(createdSession, "codex", effectiveProjectPath, sessionRefId);
|
|
@@ -5033,6 +5077,7 @@ export class BridgeWebSocketServer {
|
|
|
5033
5077
|
codexModelServiceTiers: this.codexModelServiceTiers,
|
|
5034
5078
|
codexProfiles: this.codexProfiles,
|
|
5035
5079
|
defaultCodexProfile: this.defaultCodexProfile,
|
|
5080
|
+
codexAutoReviewDisabled: this.codexAutoReviewDisabled,
|
|
5036
5081
|
bridgeVersion: getPackageVersion(),
|
|
5037
5082
|
});
|
|
5038
5083
|
}
|
|
@@ -5064,6 +5109,7 @@ export class BridgeWebSocketServer {
|
|
|
5064
5109
|
codexModelServiceTiers: this.codexModelServiceTiers,
|
|
5065
5110
|
codexProfiles: this.codexProfiles,
|
|
5066
5111
|
defaultCodexProfile: this.defaultCodexProfile,
|
|
5112
|
+
codexAutoReviewDisabled: this.codexAutoReviewDisabled,
|
|
5067
5113
|
bridgeVersion: getPackageVersion(),
|
|
5068
5114
|
});
|
|
5069
5115
|
}
|
|
@@ -5312,6 +5358,7 @@ export class BridgeWebSocketServer {
|
|
|
5312
5358
|
console.warn(`[ws] Failed to load Codex metadata: ${err}`);
|
|
5313
5359
|
this.codexProfiles = [];
|
|
5314
5360
|
this.defaultCodexProfile = undefined;
|
|
5361
|
+
this.codexAutoReviewPolicyLoaded = false;
|
|
5315
5362
|
this.applyFallbackCodexModels();
|
|
5316
5363
|
this.broadcastSessionList();
|
|
5317
5364
|
})
|
|
@@ -5324,9 +5371,10 @@ export class BridgeWebSocketServer {
|
|
|
5324
5371
|
const activeProcess = this.getActiveCodexProcess();
|
|
5325
5372
|
const codexProcess = activeProcess ?? (await this.createStandaloneCodexProcess(projectPath));
|
|
5326
5373
|
try {
|
|
5327
|
-
const [profileResult, modelResult] = await Promise.allSettled([
|
|
5374
|
+
const [profileResult, modelResult, requirementsResult] = await Promise.allSettled([
|
|
5328
5375
|
codexProcess.readProfileConfig(projectPath),
|
|
5329
5376
|
this.readCodexModels(codexProcess),
|
|
5377
|
+
this.readCodexAutoReviewDisabled(codexProcess),
|
|
5330
5378
|
]);
|
|
5331
5379
|
if (profileResult.status === "fulfilled") {
|
|
5332
5380
|
this.codexProfiles = profileResult.value.profiles;
|
|
@@ -5346,6 +5394,14 @@ export class BridgeWebSocketServer {
|
|
|
5346
5394
|
}
|
|
5347
5395
|
this.applyFallbackCodexModels();
|
|
5348
5396
|
}
|
|
5397
|
+
if (requirementsResult.status === "fulfilled") {
|
|
5398
|
+
this.codexAutoReviewDisabled = requirementsResult.value;
|
|
5399
|
+
this.codexAutoReviewPolicyLoaded = true;
|
|
5400
|
+
}
|
|
5401
|
+
else {
|
|
5402
|
+
console.warn(`[ws] Failed to load Codex config requirements: ${requirementsResult.reason}`);
|
|
5403
|
+
this.codexAutoReviewPolicyLoaded = false;
|
|
5404
|
+
}
|
|
5349
5405
|
this.broadcastSessionList();
|
|
5350
5406
|
}
|
|
5351
5407
|
finally {
|
|
@@ -5409,6 +5465,14 @@ export class BridgeWebSocketServer {
|
|
|
5409
5465
|
supportedServiceTiers: fallbackCodexServiceTiers(model),
|
|
5410
5466
|
}));
|
|
5411
5467
|
}
|
|
5468
|
+
async readCodexAutoReviewDisabled(codexProcess) {
|
|
5469
|
+
const requirementsSource = codexProcess;
|
|
5470
|
+
if (typeof requirementsSource.readConfigRequirements !== "function") {
|
|
5471
|
+
return false;
|
|
5472
|
+
}
|
|
5473
|
+
return (await requirementsSource.readConfigRequirements())
|
|
5474
|
+
.autoReviewDisabled;
|
|
5475
|
+
}
|
|
5412
5476
|
applyCodexModels(models) {
|
|
5413
5477
|
this.codexModels = models.map((model) => model.model);
|
|
5414
5478
|
this.codexModelReasoningEfforts = Object.fromEntries(models.map((model) => [
|
|
@@ -5487,6 +5551,19 @@ export class BridgeWebSocketServer {
|
|
|
5487
5551
|
? session.process
|
|
5488
5552
|
: null;
|
|
5489
5553
|
}
|
|
5554
|
+
withCodexAutoReviewPolicy(options) {
|
|
5555
|
+
const disableAutoReview = this.codexAutoReviewDisabled;
|
|
5556
|
+
return {
|
|
5557
|
+
...options,
|
|
5558
|
+
...(disableAutoReview ? { approvalsReviewer: "user" } : {}),
|
|
5559
|
+
...(disableAutoReview && options.codexPermissionsMode === "autoReview"
|
|
5560
|
+
? { codexPermissionsMode: "default" }
|
|
5561
|
+
: {}),
|
|
5562
|
+
autoReviewDisabledByPolicy: this.codexAutoReviewPolicyLoaded
|
|
5563
|
+
? disableAutoReview
|
|
5564
|
+
: null,
|
|
5565
|
+
};
|
|
5566
|
+
}
|
|
5490
5567
|
getActiveClaudeProcess() {
|
|
5491
5568
|
const summary = this.sessionManager
|
|
5492
5569
|
.list()
|