code-abyss 1.7.6 → 1.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/bin/adapters/codex.js +139 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -214,7 +214,7 @@ multi_agent = true
|
|
|
214
214
|
### 兼容性说明
|
|
215
215
|
|
|
216
216
|
- 模板已对齐新版 Codex 配置风格:`[tools].web_search` 与 `[features].multi_agent`
|
|
217
|
-
-
|
|
217
|
+
- 若你本地已有旧配置,安装器不会强制覆盖;会自动补齐 root 默认项(正确写入首段)、清理 removed feature、迁移 deprecated `web_search_*` 到 `[tools].web_search`,并在 `danger-full-access` 下清理 `projects.*.trust_level`
|
|
218
218
|
- 建议在升级后执行一次 `codex --help` / 启动自检,确认无 deprecation warning
|
|
219
219
|
|
|
220
220
|
---
|
package/bin/adapters/codex.js
CHANGED
|
@@ -4,6 +4,7 @@ const fs = require('fs');
|
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
6
|
const CODEX_DEFAULTS = {
|
|
7
|
+
approvalPolicy: 'never',
|
|
7
8
|
sandboxMode: 'danger-full-access',
|
|
8
9
|
featureFlag: 'multi_agent',
|
|
9
10
|
};
|
|
@@ -28,9 +29,50 @@ function escapeRegExp(input) {
|
|
|
28
29
|
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
function
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
function isTableHeader(line) {
|
|
33
|
+
return /^\s*\[[^\]]+\]\s*$/.test(line);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isProjectTableHeader(line) {
|
|
37
|
+
return /^\s*\[projects\."[^"]+"\]\s*$/.test(line);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function isAssignmentForKey(line, key) {
|
|
41
|
+
const re = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`);
|
|
42
|
+
return re.test(line);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function hasRootKey(content, key) {
|
|
46
|
+
const lines = content.split(/\r?\n/);
|
|
47
|
+
let inRoot = true;
|
|
48
|
+
|
|
49
|
+
for (const line of lines) {
|
|
50
|
+
if (isTableHeader(line)) {
|
|
51
|
+
inRoot = false;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (inRoot && isAssignmentForKey(line, key)) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function readRootStringKey(content, key) {
|
|
62
|
+
const lines = content.split(/\r?\n/);
|
|
63
|
+
const re = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=\\s*"([^"]*)"`);
|
|
64
|
+
let inRoot = true;
|
|
65
|
+
|
|
66
|
+
for (const line of lines) {
|
|
67
|
+
if (isTableHeader(line)) {
|
|
68
|
+
inRoot = false;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (!inRoot) continue;
|
|
72
|
+
const m = line.match(re);
|
|
73
|
+
if (m) return m[1];
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
34
76
|
}
|
|
35
77
|
|
|
36
78
|
function hasSection(content, sectionName) {
|
|
@@ -66,6 +108,20 @@ function appendLine(content, line, eol) {
|
|
|
66
108
|
return `${normalized}${line}${eol}`;
|
|
67
109
|
}
|
|
68
110
|
|
|
111
|
+
function insertRootLine(content, line, eol) {
|
|
112
|
+
if (!content) return `${line}${eol}`;
|
|
113
|
+
const lines = content.split(/\r?\n/);
|
|
114
|
+
const firstSection = lines.findIndex((l) => isTableHeader(l));
|
|
115
|
+
const idx = firstSection === -1 ? lines.length : firstSection;
|
|
116
|
+
lines.splice(idx, 0, line);
|
|
117
|
+
return lines.join(eol);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function ensureRootKey(content, key, valueLiteral, eol) {
|
|
121
|
+
if (hasRootKey(content, key)) return { merged: content, added: false };
|
|
122
|
+
return { merged: insertRootLine(content, `${key} = ${valueLiteral}`, eol), added: true };
|
|
123
|
+
}
|
|
124
|
+
|
|
69
125
|
function insertLineAfterSectionHeader(content, sectionName, line, eol) {
|
|
70
126
|
const lines = content.split(/\r?\n/);
|
|
71
127
|
const sectionRe = new RegExp(`^\\s*\\[${escapeRegExp(sectionName)}\\]\\s*$`);
|
|
@@ -97,6 +153,59 @@ function parseTomlBooleanAssignment(line) {
|
|
|
97
153
|
return m[1].toLowerCase() === 'true';
|
|
98
154
|
}
|
|
99
155
|
|
|
156
|
+
function removeKeyAssignmentsInNonRootSections(content, key) {
|
|
157
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
158
|
+
const lines = content.split(/\r?\n/);
|
|
159
|
+
const kept = [];
|
|
160
|
+
let inRoot = true;
|
|
161
|
+
let removed = false;
|
|
162
|
+
|
|
163
|
+
for (const line of lines) {
|
|
164
|
+
if (isTableHeader(line)) {
|
|
165
|
+
inRoot = false;
|
|
166
|
+
kept.push(line);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (!inRoot && isAssignmentForKey(line, key)) {
|
|
170
|
+
removed = true;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
kept.push(line);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return { merged: kept.join(eol), removed };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function removeProjectTrustSectionsForFullAccess(content) {
|
|
180
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
181
|
+
const sandboxMode = readRootStringKey(content, 'sandbox_mode');
|
|
182
|
+
if (sandboxMode !== CODEX_DEFAULTS.sandboxMode) {
|
|
183
|
+
return { merged: content, removed: false };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const lines = content.split(/\r?\n/);
|
|
187
|
+
const kept = [];
|
|
188
|
+
let inProjectSection = false;
|
|
189
|
+
let removed = false;
|
|
190
|
+
|
|
191
|
+
for (const line of lines) {
|
|
192
|
+
if (isTableHeader(line)) {
|
|
193
|
+
if (isProjectTableHeader(line)) {
|
|
194
|
+
inProjectSection = true;
|
|
195
|
+
removed = true;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
inProjectSection = false;
|
|
199
|
+
kept.push(line);
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (inProjectSection) continue;
|
|
203
|
+
kept.push(line);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return { merged: kept.join(eol), removed };
|
|
207
|
+
}
|
|
208
|
+
|
|
100
209
|
function removeFeatureFlagsFromFeaturesSection(content, featureNames) {
|
|
101
210
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
102
211
|
const lines = content.split(/\r?\n/);
|
|
@@ -167,8 +276,28 @@ function mergeCodexConfigDefaults(content) {
|
|
|
167
276
|
let merged = content;
|
|
168
277
|
const added = [];
|
|
169
278
|
|
|
170
|
-
|
|
171
|
-
|
|
279
|
+
const rootKeys = [
|
|
280
|
+
'approval_policy',
|
|
281
|
+
'sandbox_mode',
|
|
282
|
+
'model_reasoning_effort',
|
|
283
|
+
'disable_response_storage',
|
|
284
|
+
'personality',
|
|
285
|
+
];
|
|
286
|
+
|
|
287
|
+
for (const key of rootKeys) {
|
|
288
|
+
const cleaned = removeKeyAssignmentsInNonRootSections(merged, key);
|
|
289
|
+
merged = cleaned.merged;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const approval = ensureRootKey(merged, 'approval_policy', `"${CODEX_DEFAULTS.approvalPolicy}"`, eol);
|
|
293
|
+
merged = approval.merged;
|
|
294
|
+
if (approval.added) {
|
|
295
|
+
added.push('approval_policy');
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const sandbox = ensureRootKey(merged, 'sandbox_mode', `"${CODEX_DEFAULTS.sandboxMode}"`, eol);
|
|
299
|
+
merged = sandbox.merged;
|
|
300
|
+
if (sandbox.added) {
|
|
172
301
|
added.push('sandbox_mode');
|
|
173
302
|
}
|
|
174
303
|
|
|
@@ -187,9 +316,12 @@ function mergeCodexConfigDefaults(content) {
|
|
|
187
316
|
function patchCodexConfig(cfgPath) {
|
|
188
317
|
const raw = fs.readFileSync(cfgPath, 'utf8');
|
|
189
318
|
const { merged: cleaned, removed, migrated } = cleanupLegacyCodexConfig(raw);
|
|
190
|
-
const { merged, added } = mergeCodexConfigDefaults(cleaned);
|
|
319
|
+
const { merged: mergedDefaults, added } = mergeCodexConfigDefaults(cleaned);
|
|
320
|
+
const { merged, removed: removedProjectTrust } = removeProjectTrustSectionsForFullAccess(mergedDefaults);
|
|
321
|
+
const removedAll = removedProjectTrust ? [...removed, 'projects.*.trust_level'] : removed;
|
|
322
|
+
|
|
191
323
|
if (merged !== raw) fs.writeFileSync(cfgPath, merged);
|
|
192
|
-
return { added, removed, migrated };
|
|
324
|
+
return { added, removed: removedAll, migrated };
|
|
193
325
|
}
|
|
194
326
|
|
|
195
327
|
function patchCodexConfigDefaults(cfgPath) {
|