code-abyss 1.7.7 → 2.0.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/README.md +42 -11
- package/bin/adapters/claude.js +12 -4
- package/bin/adapters/codex.js +1 -1
- package/bin/install.js +142 -69
- package/config/AGENTS.md +288 -332
- package/config/CLAUDE.md +124 -31
- package/config/codex-config.example.toml +8 -0
- package/config/settings.example.json +13 -4
- package/output-styles/abyss-cultivator.md +166 -303
- package/package.json +1 -1
- package/skills/domains/security/SKILL.md +30 -12
- package/skills/domains/security/red-team.md +0 -1
package/README.md
CHANGED
|
@@ -111,8 +111,8 @@ Code Abyss 是一套 **Claude Code / Codex CLI 个性化配置包**,一条命
|
|
|
111
111
|
```
|
|
112
112
|
~/.claude/(Claude Code) ~/.codex/(Codex CLI)
|
|
113
113
|
├── CLAUDE.md 道典 ├── AGENTS.md 道典+风格
|
|
114
|
-
├── output-styles/ 输出风格 ├──
|
|
115
|
-
│ └── abyss-cultivator.md
|
|
114
|
+
├── output-styles/ 输出风格 ├── config.toml 推荐配置
|
|
115
|
+
│ └── abyss-cultivator.md ├── prompts/ custom prompts
|
|
116
116
|
├── settings.json
|
|
117
117
|
└── skills/ 56 篇秘典
|
|
118
118
|
|
|
@@ -163,40 +163,59 @@ Code Abyss 是一套 **Claude Code / Codex CLI 个性化配置包**,一条命
|
|
|
163
163
|
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
|
164
164
|
"env": {
|
|
165
165
|
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
|
|
166
|
-
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
|
|
166
|
+
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
|
|
167
|
+
"CLAUDE_CODE_ENABLE_TASKS": "1",
|
|
168
|
+
"CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION": "1",
|
|
169
|
+
"ENABLE_TOOL_SEARCH": "auto:10"
|
|
167
170
|
},
|
|
171
|
+
"defaultMode": "bypassPermissions",
|
|
168
172
|
"alwaysThinkingEnabled": true,
|
|
173
|
+
"autoMemoryEnabled": true,
|
|
169
174
|
"model": "opus",
|
|
170
175
|
"outputStyle": "abyss-cultivator",
|
|
171
176
|
"attribution": { "commit": "", "pr": "" },
|
|
177
|
+
"sandbox": { "autoAllowBashIfSandboxed": true },
|
|
172
178
|
"permissions": {
|
|
173
|
-
"allow": ["Bash", "LS", "Read", "
|
|
174
|
-
"Glob", "Grep", "WebFetch", "WebSearch",
|
|
175
|
-
"NotebookRead", "NotebookEdit"]
|
|
179
|
+
"allow": ["Bash", "LS", "Read", "Edit", "Write", "MultiEdit",
|
|
180
|
+
"Agent", "Glob", "Grep", "WebFetch", "WebSearch",
|
|
181
|
+
"TodoWrite", "NotebookRead", "NotebookEdit", "mcp__*"]
|
|
176
182
|
}
|
|
177
183
|
}
|
|
178
184
|
```
|
|
179
185
|
|
|
180
186
|
| 配置项 | 说明 |
|
|
181
187
|
|--------|------|
|
|
188
|
+
| `defaultMode: bypassPermissions` | 跳过所有权限确认(`.git`等受保护目录仍会提示) |
|
|
189
|
+
| `autoMemoryEnabled` | 启用自动记忆,跨会话保留上下文 |
|
|
190
|
+
| `sandbox.autoAllowBashIfSandboxed` | 沙箱环境内自动放行 Bash 命令 |
|
|
182
191
|
| `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS` | 启用多 Agent 并行协作(实验性) |
|
|
183
192
|
| `CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC` | 禁用自动更新、遥测、错误报告 |
|
|
193
|
+
| `CLAUDE_CODE_ENABLE_TASKS` | 启用任务管理功能 |
|
|
194
|
+
| `CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION` | 启用提示建议 |
|
|
195
|
+
| `ENABLE_TOOL_SEARCH` | MCP 工具自动搜索(auto:10 = 自动匹配前10个) |
|
|
196
|
+
| `mcp__*` | 自动放行所有 MCP 工具 |
|
|
184
197
|
| `outputStyle` | 设置为 `abyss-cultivator` 启用邪修风格 |
|
|
185
198
|
|
|
186
199
|
---
|
|
187
200
|
|
|
188
201
|
### Codex `config.toml` 推荐模板
|
|
189
202
|
|
|
190
|
-
安装 `--target codex`(尤其 `-y
|
|
203
|
+
安装 `--target codex`(尤其 `-y`)时会写入以下 **全开默认档** 到 `~/.codex/config.toml`:
|
|
191
204
|
|
|
192
205
|
```toml
|
|
193
206
|
model_provider = "custom"
|
|
194
207
|
model = "gpt-5.2-codex"
|
|
195
208
|
model_reasoning_effort = "high"
|
|
209
|
+
model_reasoning_summary = "detailed"
|
|
210
|
+
model_verbosity = "medium"
|
|
196
211
|
approval_policy = "never"
|
|
197
212
|
sandbox_mode = "danger-full-access"
|
|
198
213
|
disable_response_storage = true
|
|
199
214
|
|
|
215
|
+
[profiles.safe]
|
|
216
|
+
approval_policy = "on-request"
|
|
217
|
+
sandbox_mode = "workspace-write"
|
|
218
|
+
|
|
200
219
|
[model_providers.custom]
|
|
201
220
|
name = "custom"
|
|
202
221
|
base_url = "https://your-api-endpoint.com/v1"
|
|
@@ -208,14 +227,26 @@ web_search = true
|
|
|
208
227
|
|
|
209
228
|
[features]
|
|
210
229
|
multi_agent = true
|
|
230
|
+
shell_snapshot = true
|
|
231
|
+
undo = true
|
|
211
232
|
```
|
|
212
233
|
|
|
234
|
+
- 默认零审批 + 完全沙箱访问,适合安全研究/CTF/本地开发等高自动化场景
|
|
235
|
+
- `model_reasoning_summary = "detailed"` 输出详细推理摘要
|
|
236
|
+
- `shell_snapshot` / `undo` 启用快照与撤销功能
|
|
237
|
+
- 需要安全姿态时可显式切到 `safe`:`codex -p safe`
|
|
213
238
|
|
|
214
239
|
### 兼容性说明
|
|
215
240
|
|
|
216
|
-
- 模板已对齐新版 Codex
|
|
217
|
-
-
|
|
218
|
-
-
|
|
241
|
+
- 模板已对齐新版 Codex 配置风格:root keys、`[profiles.*]`、`[tools].web_search` 与 `[features].multi_agent`
|
|
242
|
+
- 默认档从 safe 切换为全开(`approval_policy = "never"` + `sandbox_mode = "danger-full-access"`),提供 `[profiles.safe]` 作为保守回退
|
|
243
|
+
- Claude Code 默认启用 `bypassPermissions` 模式,跳过所有权限确认(`.git` 等受保护目录仍会提示)
|
|
244
|
+
- 新增实验功能环境变量:`CLAUDE_CODE_ENABLE_TASKS`、`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`
|
|
245
|
+
- 新增 `mcp__*` 通配符,自动放行所有 MCP 工具
|
|
246
|
+
- `Codex` 当前支持 `~/.codex/prompts/*.md` 作为 custom prompts;Code Abyss 会继续安装 `~/.codex/skills/`,并从 `user-invocable` skills 自动生成对应的 `prompts/`
|
|
247
|
+
- 安装器不会再为 Codex 写入伪配置 `~/.codex/settings.json`;若检测到旧版遗留文件,会在安装时备份后移除,卸载时恢复
|
|
248
|
+
- 若你本地已有旧配置,安装器不会强制覆盖;会自动补齐默认项、清理 removed feature、迁移 deprecated `web_search_*` 到 `[tools].web_search`
|
|
249
|
+
- 建议升级后执行一次 `codex --help`,或用 `codex -p safe --help` 校验 profile 可见性
|
|
219
250
|
|
|
220
251
|
---
|
|
221
252
|
|
|
@@ -228,7 +259,7 @@ multi_agent = true
|
|
|
228
259
|
- `bin/lib/ccline.js`:Claude 侧状态栏与 ccline 集成
|
|
229
260
|
- `bin/adapters/codex.js`:Codex 侧认证检测、核心文件映射、config 模板流程
|
|
230
261
|
|
|
231
|
-
当前 Claude/Codex 安装映射分别由 `getClaudeCoreFiles()` 与 `getCodexCoreFiles()`
|
|
262
|
+
当前 Claude/Codex 安装映射分别由 `getClaudeCoreFiles()` 与 `getCodexCoreFiles()` 提供;Claude 额外生成 `commands/`,Codex 保持 `skills/ + config.toml` 的官方主路径,避免在主流程硬编码目标细节。
|
|
232
263
|
|
|
233
264
|
---
|
|
234
265
|
|
package/bin/adapters/claude.js
CHANGED
|
@@ -7,17 +7,25 @@ const SETTINGS_TEMPLATE = {
|
|
|
7
7
|
$schema: 'https://json.schemastore.org/claude-code-settings.json',
|
|
8
8
|
env: {
|
|
9
9
|
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: '1',
|
|
10
|
-
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1'
|
|
10
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1',
|
|
11
|
+
CLAUDE_CODE_ENABLE_TASKS: '1',
|
|
12
|
+
CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION: '1',
|
|
13
|
+
ENABLE_TOOL_SEARCH: 'auto:10'
|
|
11
14
|
},
|
|
15
|
+
defaultMode: 'bypassPermissions',
|
|
12
16
|
alwaysThinkingEnabled: true,
|
|
17
|
+
autoMemoryEnabled: true,
|
|
13
18
|
model: 'opus',
|
|
14
19
|
outputStyle: 'abyss-cultivator',
|
|
15
20
|
attribution: { commit: '', pr: '' },
|
|
21
|
+
sandbox: {
|
|
22
|
+
autoAllowBashIfSandboxed: true
|
|
23
|
+
},
|
|
16
24
|
permissions: {
|
|
17
25
|
allow: [
|
|
18
|
-
'Bash', 'LS', 'Read', '
|
|
19
|
-
'Glob', 'Grep', 'WebFetch', 'WebSearch',
|
|
20
|
-
'NotebookRead', 'NotebookEdit'
|
|
26
|
+
'Bash', 'LS', 'Read', 'Edit', 'Write', 'MultiEdit',
|
|
27
|
+
'Agent', 'Glob', 'Grep', 'WebFetch', 'WebSearch',
|
|
28
|
+
'TodoWrite', 'NotebookRead', 'NotebookEdit', 'mcp__*'
|
|
21
29
|
]
|
|
22
30
|
}
|
|
23
31
|
};
|
package/bin/adapters/codex.js
CHANGED
|
@@ -179,7 +179,7 @@ function removeKeyAssignmentsInNonRootSections(content, key) {
|
|
|
179
179
|
function removeProjectTrustSectionsForFullAccess(content) {
|
|
180
180
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
181
181
|
const sandboxMode = readRootStringKey(content, 'sandbox_mode');
|
|
182
|
-
if (sandboxMode !==
|
|
182
|
+
if (sandboxMode !== 'danger-full-access') {
|
|
183
183
|
return { merged: content, removed: false };
|
|
184
184
|
}
|
|
185
185
|
|
package/bin/install.js
CHANGED
|
@@ -186,92 +186,154 @@ function scanInvocableSkills(skillsDir) {
|
|
|
186
186
|
return results;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
function
|
|
203
|
-
const
|
|
189
|
+
const INVOCABLE_TARGETS = {
|
|
190
|
+
claude: {
|
|
191
|
+
dir: 'commands',
|
|
192
|
+
label: '斜杠命令',
|
|
193
|
+
skillRoot: '~/.claude/skills',
|
|
194
|
+
},
|
|
195
|
+
codex: {
|
|
196
|
+
dir: 'prompts',
|
|
197
|
+
label: 'custom prompts',
|
|
198
|
+
skillRoot: '~/.codex/skills',
|
|
199
|
+
},
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
function getInvocableTarget(targetName) {
|
|
203
|
+
const targetCfg = INVOCABLE_TARGETS[targetName];
|
|
204
|
+
if (!targetCfg) throw new Error(`不支持的 invocable target: ${targetName}`);
|
|
205
|
+
return targetCfg;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function getSkillPath(skillRoot, skillRelPath) {
|
|
209
|
+
return skillRelPath
|
|
210
|
+
? `${skillRoot}/${skillRelPath}/SKILL.md`
|
|
211
|
+
: `${skillRoot}/SKILL.md`;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function buildCommandFrontmatter(meta) {
|
|
204
215
|
const desc = (meta.description || '').replace(/"/g, '\\"');
|
|
205
216
|
const argHint = meta['argument-hint'];
|
|
206
217
|
const tools = meta['allowed-tools'] || 'Read';
|
|
207
|
-
const
|
|
208
|
-
|
|
209
|
-
: '~/.claude/skills/SKILL.md';
|
|
210
|
-
|
|
211
|
-
const lines = [
|
|
212
|
-
'---',
|
|
213
|
-
`name: ${name}`,
|
|
214
|
-
`description: "${desc}"`,
|
|
215
|
-
];
|
|
218
|
+
const lines = ['---', `name: ${meta.name}`, `description: "${desc}"`];
|
|
219
|
+
|
|
216
220
|
if (argHint) lines.push(`argument-hint: "${argHint}"`);
|
|
217
221
|
lines.push(`allowed-tools: ${tools}`);
|
|
218
|
-
lines.push('---');
|
|
219
|
-
lines
|
|
222
|
+
lines.push('---', '');
|
|
223
|
+
return lines;
|
|
224
|
+
}
|
|
220
225
|
|
|
226
|
+
function buildClaudeBody(skillPath, meta, hasScripts) {
|
|
227
|
+
const lines = [];
|
|
221
228
|
if (hasScripts) {
|
|
222
|
-
|
|
223
|
-
lines.push('以下所有步骤一气呵成,不要在步骤间停顿等待用户输入:');
|
|
224
|
-
lines.push('');
|
|
229
|
+
lines.push('以下所有步骤一气呵成,不要在步骤间停顿等待用户输入:', '');
|
|
225
230
|
lines.push(`1. 读取规范:${skillPath}`);
|
|
226
|
-
lines.push(`2. 执行命令:\`node ~/.claude/skills/run_skill.js ${name} $ARGUMENTS\``);
|
|
227
|
-
lines.push('3. 按规范分析输出,完成后续动作');
|
|
228
|
-
lines.push('');
|
|
231
|
+
lines.push(`2. 执行命令:\`node ~/.claude/skills/run_skill.js ${meta.name} $ARGUMENTS\``);
|
|
232
|
+
lines.push('3. 按规范分析输出,完成后续动作', '');
|
|
229
233
|
lines.push('全程不要停顿,不要询问是否继续。');
|
|
230
|
-
|
|
231
|
-
// ── 无脚本的 skill:知识库模式 ──
|
|
232
|
-
lines.push('读取以下秘典,根据内容为用户提供专业指导:');
|
|
233
|
-
lines.push('');
|
|
234
|
-
lines.push('```');
|
|
235
|
-
lines.push(skillPath);
|
|
236
|
-
lines.push('```');
|
|
234
|
+
return lines;
|
|
237
235
|
}
|
|
238
236
|
|
|
239
|
-
lines.push('');
|
|
240
|
-
|
|
237
|
+
lines.push('读取以下秘典,根据内容为用户提供专业指导:', '');
|
|
238
|
+
lines.push('```', skillPath, '```');
|
|
239
|
+
return lines;
|
|
241
240
|
}
|
|
242
241
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
function buildCodexPromptBody(skillPath, meta, hasScripts) {
|
|
243
|
+
const lines = [];
|
|
244
|
+
if (meta['argument-hint']) lines.push(`Arguments: ${meta['argument-hint']}`, '');
|
|
245
|
+
lines.push(`Read \`${skillPath}\` before acting.`, '');
|
|
246
|
+
if (hasScripts) {
|
|
247
|
+
lines.push(`Then run \`node ~/.codex/skills/run_skill.js ${meta.name} $ARGUMENTS\`.`);
|
|
248
|
+
lines.push('Do not stop between steps unless blocked by permissions or missing required inputs.');
|
|
249
|
+
lines.push('Use the skill guidance plus script output to complete the task end-to-end.');
|
|
250
|
+
return lines;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
lines.push('Use that skill as the authoritative playbook for the task.');
|
|
254
|
+
lines.push('Respond with concrete actions instead of generic advice.');
|
|
255
|
+
return lines;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function generateInvocableContent(meta, skillRelPath, hasScripts, targetName) {
|
|
259
|
+
const targetCfg = getInvocableTarget(targetName);
|
|
260
|
+
const skillPath = getSkillPath(targetCfg.skillRoot, skillRelPath);
|
|
261
|
+
const lines = targetName === 'claude' ? buildCommandFrontmatter(meta) : [];
|
|
262
|
+
const body = targetName === 'claude'
|
|
263
|
+
? buildClaudeBody(skillPath, meta, hasScripts)
|
|
264
|
+
: buildCodexPromptBody(skillPath, meta, hasScripts);
|
|
265
|
+
return [...lines, ...body, ''].join('\n');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function generateCommandContent(meta, skillRelPath, hasScripts) {
|
|
269
|
+
return generateInvocableContent(meta, skillRelPath, hasScripts, 'claude');
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function generatePromptContent(meta, skillRelPath, hasScripts) {
|
|
273
|
+
return generateInvocableContent(meta, skillRelPath, hasScripts, 'codex');
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function installGeneratedArtifacts(skillsSrcDir, targetDir, backupDir, manifest, targetName) {
|
|
247
277
|
const skills = scanInvocableSkills(skillsSrcDir);
|
|
248
278
|
if (skills.length === 0) return 0;
|
|
249
279
|
|
|
250
|
-
const
|
|
251
|
-
|
|
280
|
+
const targetCfg = getInvocableTarget(targetName);
|
|
281
|
+
const installDir = path.join(targetDir, targetCfg.dir);
|
|
282
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
252
283
|
|
|
253
284
|
skills.forEach(({ meta, relPath, hasScripts }) => {
|
|
254
285
|
const fileName = `${meta.name}.md`;
|
|
255
|
-
const destFile = path.join(
|
|
256
|
-
const relFile = path.posix.join(
|
|
286
|
+
const destFile = path.join(installDir, fileName);
|
|
287
|
+
const relFile = path.posix.join(targetCfg.dir, fileName);
|
|
257
288
|
|
|
258
289
|
if (fs.existsSync(destFile)) {
|
|
259
|
-
const
|
|
260
|
-
fs.mkdirSync(
|
|
261
|
-
fs.copyFileSync(destFile, path.join(
|
|
290
|
+
const backupSubdir = path.join(backupDir, targetCfg.dir);
|
|
291
|
+
fs.mkdirSync(backupSubdir, { recursive: true });
|
|
292
|
+
fs.copyFileSync(destFile, path.join(backupSubdir, fileName));
|
|
262
293
|
manifest.backups.push(relFile);
|
|
263
294
|
info(`备份: ${c.d(relFile)}`);
|
|
264
295
|
}
|
|
265
296
|
|
|
266
|
-
const content =
|
|
297
|
+
const content = generateInvocableContent(meta, relPath, hasScripts, targetName);
|
|
267
298
|
fs.writeFileSync(destFile, content);
|
|
268
299
|
manifest.installed.push(relFile);
|
|
269
300
|
});
|
|
270
301
|
|
|
271
|
-
ok(
|
|
302
|
+
ok(`${targetCfg.dir}/ ${c.d(`(自动生成 ${skills.length} 个 ${targetCfg.label})`)}`);
|
|
272
303
|
return skills.length;
|
|
273
304
|
}
|
|
274
305
|
|
|
306
|
+
function installGeneratedCommands(skillsSrcDir, targetDir, backupDir, manifest) {
|
|
307
|
+
return installGeneratedArtifacts(skillsSrcDir, targetDir, backupDir, manifest, 'claude');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function installGeneratedPrompts(skillsSrcDir, targetDir, backupDir, manifest) {
|
|
311
|
+
return installGeneratedArtifacts(skillsSrcDir, targetDir, backupDir, manifest, 'codex');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function backupPathIfExists(targetDir, backupDir, relPath, manifest) {
|
|
315
|
+
const targetPath = path.join(targetDir, relPath);
|
|
316
|
+
if (!fs.existsSync(targetPath)) return false;
|
|
317
|
+
|
|
318
|
+
const backupPath = path.join(backupDir, relPath);
|
|
319
|
+
rmSafe(backupPath);
|
|
320
|
+
copyRecursive(targetPath, backupPath);
|
|
321
|
+
manifest.backups.push(relPath);
|
|
322
|
+
info(`备份: ${c.d(relPath)}`);
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function pruneLegacyCodexSettings(targetDir, backupDir, manifest) {
|
|
327
|
+
const relPath = 'settings.json';
|
|
328
|
+
const settingsPath = path.join(targetDir, relPath);
|
|
329
|
+
if (!fs.existsSync(settingsPath)) return null;
|
|
330
|
+
|
|
331
|
+
backupPathIfExists(targetDir, backupDir, relPath, manifest);
|
|
332
|
+
rmSafe(settingsPath);
|
|
333
|
+
warn('移除 legacy settings.json(Codex 已改用 config.toml)');
|
|
334
|
+
return settingsPath;
|
|
335
|
+
}
|
|
336
|
+
|
|
275
337
|
function installCore(tgt) {
|
|
276
338
|
const targetDir = path.join(HOME, `.${tgt}`);
|
|
277
339
|
const backupDir = path.join(targetDir, '.sage-backup');
|
|
@@ -309,30 +371,37 @@ function installCore(tgt) {
|
|
|
309
371
|
rmSafe(destPath); copyRecursive(srcPath, destPath); manifest.installed.push(dest);
|
|
310
372
|
});
|
|
311
373
|
|
|
312
|
-
//
|
|
374
|
+
// 为目标 CLI 自动生成 user-invocable artifacts
|
|
313
375
|
if (tgt === 'claude') {
|
|
314
376
|
const skillsSrc = path.join(PKG_ROOT, 'skills');
|
|
315
377
|
installGeneratedCommands(skillsSrc, targetDir, backupDir, manifest);
|
|
378
|
+
} else if (tgt === 'codex') {
|
|
379
|
+
const skillsSrc = path.join(PKG_ROOT, 'skills');
|
|
380
|
+
installGeneratedPrompts(skillsSrc, targetDir, backupDir, manifest);
|
|
316
381
|
}
|
|
317
382
|
|
|
318
|
-
|
|
383
|
+
let settingsPath = null;
|
|
319
384
|
let settings = {};
|
|
320
|
-
if (fs.existsSync(settingsPath)) {
|
|
321
|
-
try {
|
|
322
|
-
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
323
|
-
} catch (e) {
|
|
324
|
-
warn(`settings.json 解析失败,将使用空配置`);
|
|
325
|
-
settings = {};
|
|
326
|
-
}
|
|
327
|
-
fs.copyFileSync(settingsPath, path.join(backupDir, 'settings.json'));
|
|
328
|
-
manifest.backups.push('settings.json');
|
|
329
|
-
}
|
|
330
385
|
if (tgt === 'claude') {
|
|
386
|
+
settingsPath = path.join(targetDir, 'settings.json');
|
|
387
|
+
if (fs.existsSync(settingsPath)) {
|
|
388
|
+
try {
|
|
389
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
390
|
+
} catch (e) {
|
|
391
|
+
warn('settings.json 解析失败,将使用空配置');
|
|
392
|
+
settings = {};
|
|
393
|
+
}
|
|
394
|
+
fs.copyFileSync(settingsPath, path.join(backupDir, 'settings.json'));
|
|
395
|
+
manifest.backups.push('settings.json');
|
|
396
|
+
}
|
|
331
397
|
settings.outputStyle = 'abyss-cultivator';
|
|
332
398
|
ok(`outputStyle = ${c.mag('abyss-cultivator')}`);
|
|
399
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
400
|
+
manifest.installed.push('settings.json');
|
|
401
|
+
} else {
|
|
402
|
+
pruneLegacyCodexSettings(targetDir, backupDir, manifest);
|
|
333
403
|
}
|
|
334
|
-
|
|
335
|
-
manifest.installed.push('settings.json');
|
|
404
|
+
|
|
336
405
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
337
406
|
|
|
338
407
|
const uSrc = path.join(PKG_ROOT, 'bin', 'uninstall.js');
|
|
@@ -438,5 +507,9 @@ if (require.main === module) {
|
|
|
438
507
|
module.exports = {
|
|
439
508
|
deepMergeNew, detectClaudeAuth, detectCodexAuth,
|
|
440
509
|
detectCclineBin, copyRecursive, shouldSkip, SETTINGS_TEMPLATE,
|
|
441
|
-
scanInvocableSkills,
|
|
510
|
+
scanInvocableSkills,
|
|
511
|
+
generateCommandContent,
|
|
512
|
+
generatePromptContent,
|
|
513
|
+
installGeneratedCommands,
|
|
514
|
+
installGeneratedPrompts,
|
|
442
515
|
};
|