mirror of
https://github.com/zhukunpenglinyutong/jetbrains-cc-gui.git
synced 2026-08-29 00:41:38 +08:00
fix(codex): stop passing retired approval_policy=untrusted to Codex CLI
Codex CLI v0.149.0 removed the 'untrusted' approval policy - its ask-before-run semantics were merged into 'on-request'. The plugin still mapped default/plan/sandbox permission modes to approval_policy=untrusted, so every message failed with: Error: approval_policy = "untrusted" is no longer supported; remove this setting and Codex became completely unusable after upgrading the CLI (v0.146.0 -> v0.149.0) (#1702). - permission-mapper.js: SANDBOX / DEFAULT now map to on-request - CodexSDKBridge.java: plan / default env override now injects on-request instead of untrusted - codex-utils.js: drop 'untrusted' from VALID_APPROVAL_POLICIES so stale env values are ignored instead of forwarded - i18n: update codexModes.default.tooltip in all 10 locales 'on-request' is supported by both old and new CLI versions, so this is safe for all users.
This commit is contained in:
@@ -30,7 +30,10 @@ export const logWarn = (tag, ...args) => debugLog(2, tag, ...args);
|
||||
export const logInfo = (tag, ...args) => debugLog(3, tag, ...args);
|
||||
export const logDebug = (tag, ...args) => debugLog(4, tag, ...args);
|
||||
export const VALID_SANDBOX_MODES = new Set(['read-only', 'workspace-write', 'danger-full-access']);
|
||||
export const VALID_APPROVAL_POLICIES = new Set(['never', 'on-request', 'on-failure', 'untrusted']);
|
||||
export const VALID_APPROVAL_POLICIES = new Set(['never', 'on-request', 'on-failure']);
|
||||
// Note: 'untrusted' was removed in Codex CLI v0.149.0 - its semantics were merged
|
||||
// into 'on-request'. Passing it makes new CLI versions exit with
|
||||
// "approval_policy = \"untrusted\" is no longer supported; remove this setting" (#1702).
|
||||
export const CODEX_CLI_ENV_BLOCKLIST = new Set([
|
||||
'CODEX_APPROVAL_POLICY',
|
||||
'CODEX_SANDBOX_MODE',
|
||||
|
||||
@@ -155,10 +155,12 @@ export class CodexPermissionMapper {
|
||||
switch (core) {
|
||||
case UnifiedPermissionMode.SANDBOX:
|
||||
// Sandbox: Read-only mode (always prompt when attempting to write)
|
||||
// 'untrusted' was removed in Codex CLI v0.149 - its ask-before-run semantics
|
||||
// were merged into 'on-request', which older CLI versions also support (#1702).
|
||||
return {
|
||||
skipGitRepoCheck: true,
|
||||
sandbox: 'read-only',
|
||||
approvalPolicy: 'untrusted'
|
||||
approvalPolicy: 'on-request'
|
||||
};
|
||||
|
||||
case UnifiedPermissionMode.YOLO:
|
||||
@@ -173,10 +175,11 @@ export class CodexPermissionMapper {
|
||||
default:
|
||||
// Default: Allow workspace writes but still prompt before executing risky actions
|
||||
// On Windows, use danger-full-access since sandbox is experimental
|
||||
// 'untrusted' was removed in Codex CLI v0.149 - see the SANDBOX case above (#1702).
|
||||
return {
|
||||
skipGitRepoCheck: true,
|
||||
sandbox: onWindows ? 'danger-full-access' : 'workspace-write',
|
||||
approvalPolicy: 'untrusted'
|
||||
approvalPolicy: 'on-request'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
import { UnifiedPermissionMode, CodexPermissionMapper } from './permission-mapper.js';
|
||||
import { VALID_APPROVAL_POLICIES } from '../services/codex/codex-utils.js';
|
||||
|
||||
// ---------- CodexPermissionMapper.toProvider (#1702: 'untrusted' retired) ----------
|
||||
|
||||
test('toProvider never maps any unified mode to the removed untrusted policy', () => {
|
||||
const modes = [
|
||||
UnifiedPermissionMode.DEFAULT,
|
||||
UnifiedPermissionMode.SANDBOX,
|
||||
UnifiedPermissionMode.YOLO,
|
||||
'bypassPermissions',
|
||||
'acceptEdits',
|
||||
'autoEdit',
|
||||
'plan',
|
||||
'unknown-mode',
|
||||
null,
|
||||
undefined,
|
||||
];
|
||||
|
||||
for (const mode of modes) {
|
||||
const config = CodexPermissionMapper.toProvider(mode);
|
||||
assert.ok(
|
||||
config.approvalPolicy !== 'untrusted',
|
||||
`mode=${mode} must not map to the removed 'untrusted' policy (got: ${config.approvalPolicy})`,
|
||||
);
|
||||
assert.ok(
|
||||
VALID_APPROVAL_POLICIES.has(config.approvalPolicy),
|
||||
`mode=${mode} approvalPolicy ${config.approvalPolicy} must be in VALID_APPROVAL_POLICIES`,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('toProvider maps default and sandbox to on-request (untrusted semantics successor)', () => {
|
||||
// Codex CLI v0.149 removed 'untrusted'; its ask-before-run semantics now live in
|
||||
// 'on-request'. Older CLI versions support 'on-request' as well, so it is safe
|
||||
// for both (#1702).
|
||||
assert.equal(CodexPermissionMapper.toProvider(UnifiedPermissionMode.DEFAULT).approvalPolicy, 'on-request');
|
||||
assert.equal(CodexPermissionMapper.toProvider(UnifiedPermissionMode.SANDBOX).approvalPolicy, 'on-request');
|
||||
assert.equal(CodexPermissionMapper.toProvider('plan').approvalPolicy, 'on-request');
|
||||
});
|
||||
|
||||
test('toProvider keeps yolo / acceptEdits mappings unchanged', () => {
|
||||
assert.equal(CodexPermissionMapper.toProvider(UnifiedPermissionMode.YOLO).approvalPolicy, 'never');
|
||||
assert.equal(CodexPermissionMapper.toProvider('bypassPermissions').approvalPolicy, 'never');
|
||||
assert.equal(CodexPermissionMapper.toProvider('acceptEdits').approvalPolicy, 'on-request');
|
||||
assert.equal(CodexPermissionMapper.toProvider('autoEdit').approvalPolicy, 'on-request');
|
||||
});
|
||||
|
||||
// ---------- VALID_APPROVAL_POLICIES whitelist ----------
|
||||
|
||||
test('VALID_APPROVAL_POLICIES no longer accepts the removed untrusted value', () => {
|
||||
assert.equal(VALID_APPROVAL_POLICIES.has('untrusted'), false);
|
||||
assert.equal(VALID_APPROVAL_POLICIES.has('on-request'), true);
|
||||
assert.equal(VALID_APPROVAL_POLICIES.has('never'), true);
|
||||
assert.equal(VALID_APPROVAL_POLICIES.has('on-failure'), true);
|
||||
});
|
||||
@@ -45,7 +45,9 @@ public class CodexSDKBridge extends BaseSDKBridge {
|
||||
private static final String SANDBOX_MODE_READ_ONLY = "read-only";
|
||||
private static final String APPROVAL_POLICY_NEVER = "never";
|
||||
private static final String APPROVAL_POLICY_ON_REQUEST = "on-request";
|
||||
private static final String APPROVAL_POLICY_UNTRUSTED = "untrusted";
|
||||
// Note: 'untrusted' was removed in Codex CLI v0.149.0 - its semantics were merged
|
||||
// into 'on-request'. Injecting it makes new CLI versions exit with
|
||||
// "approval_policy = \"untrusted\" is no longer supported" (#1702).
|
||||
private static final String ENV_CODEX_APPROVAL_POLICY = "CODEX_APPROVAL_POLICY";
|
||||
private static final String ENV_CODEX_SANDBOX_MODE = "CODEX_SANDBOX_MODE";
|
||||
private static final String ENV_CODEX_SANDBOX = "CODEX_SANDBOX";
|
||||
@@ -501,13 +503,13 @@ public class CodexSDKBridge extends BaseSDKBridge {
|
||||
case "plan":
|
||||
env.put(ENV_CODEX_SANDBOX_MODE, sandboxMode);
|
||||
env.put(ENV_CODEX_SANDBOX, sandboxMode);
|
||||
env.put(ENV_CODEX_APPROVAL_POLICY, APPROVAL_POLICY_UNTRUSTED);
|
||||
env.put(ENV_CODEX_APPROVAL_POLICY, APPROVAL_POLICY_ON_REQUEST);
|
||||
break;
|
||||
default:
|
||||
// Default mode: use configured sandbox mode with confirmation
|
||||
env.put(ENV_CODEX_SANDBOX_MODE, sandboxMode);
|
||||
env.put(ENV_CODEX_SANDBOX, sandboxMode);
|
||||
env.put(ENV_CODEX_APPROVAL_POLICY, APPROVAL_POLICY_UNTRUSTED);
|
||||
env.put(ENV_CODEX_APPROVAL_POLICY, APPROVAL_POLICY_ON_REQUEST);
|
||||
break;
|
||||
}
|
||||
LOG.info("[Codex] Permission env override: SANDBOX_MODE=" +
|
||||
|
||||
@@ -1996,7 +1996,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1620,7 +1620,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1620,7 +1620,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1619,7 +1619,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1625,7 +1625,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1715,7 +1715,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "제안 (승인 필요)",
|
||||
"tooltip": "Codex approval_policy=untrusted – 파일 편집이나 셸 명령 실행 전에 확인합니다.",
|
||||
"tooltip": "Codex approval_policy=on-request – 파일 편집이나 셸 명령 실행 전에 확인합니다.",
|
||||
"description": "가장 안전한 옵션. 모든 쓰기 또는 명령에 승인이 필요합니다."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1770,7 +1770,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Sugerir (aprovação)",
|
||||
"tooltip": "Codex approval_policy=untrusted – solicita antes de editar arquivos ou executar comandos shell.",
|
||||
"tooltip": "Codex approval_policy=on-request – solicita antes de editar arquivos ou executar comandos shell.",
|
||||
"description": "Opção mais segura. Cada escrita ou comando requer sua aprovação."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1646,7 +1646,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Предложение (одобрение)",
|
||||
"tooltip": "Codex approval_policy=untrusted — запрашивает перед редактированием файлов или выполнением команд.",
|
||||
"tooltip": "Codex approval_policy=on-request - запрашивает перед редактированием файлов или выполнением команд.",
|
||||
"description": "Самый безопасный вариант. Каждая запись или команда требует вашего одобрения."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -1625,7 +1625,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "Suggest (approval)",
|
||||
"tooltip": "Codex approval_policy=untrusted – prompts before editing files or running shell commands.",
|
||||
"tooltip": "Codex approval_policy=on-request – prompts before editing files or running shell commands.",
|
||||
"description": "Safest option. Every write or command requires your approval."
|
||||
},
|
||||
"plan": {
|
||||
|
||||
@@ -2001,7 +2001,7 @@
|
||||
"codexModes": {
|
||||
"default": {
|
||||
"label": "建议模式",
|
||||
"tooltip": "Codex approval_policy=untrusted:执行命令或写文件前都会弹窗确认。",
|
||||
"tooltip": "Codex approval_policy=on-request:执行命令或写文件前都会弹窗确认。",
|
||||
"description": "最安全的选择,每一步都需要你亲自批准。"
|
||||
},
|
||||
"plan": {
|
||||
|
||||
Reference in New Issue
Block a user