code-abyss 2.0.7 → 2.0.8
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 +129 -58
- package/bin/adapters/claude.js +16 -12
- package/bin/adapters/codex.js +110 -37
- package/bin/adapters/gemini.js +92 -0
- package/bin/install.js +521 -130
- package/bin/lib/ccline.js +18 -8
- package/bin/lib/gstack-claude.js +164 -0
- package/bin/lib/gstack-codex.js +347 -0
- package/bin/lib/gstack-gemini.js +140 -0
- package/bin/lib/pack-bootstrap.js +92 -0
- package/bin/lib/pack-docs.js +61 -0
- package/bin/lib/pack-registry.js +400 -0
- package/bin/lib/pack-reports.js +87 -0
- package/bin/lib/pack-vendor.js +82 -0
- package/bin/lib/style-registry.js +29 -7
- package/bin/lib/target-registry.js +74 -0
- package/bin/lib/utils.js +69 -6
- package/bin/lib/vendor-providers/archive.js +56 -0
- package/bin/lib/vendor-providers/git.js +59 -0
- package/bin/lib/vendor-providers/index.js +91 -0
- package/bin/lib/vendor-providers/local-dir.js +55 -0
- package/bin/lib/vendor-providers/shared.js +86 -0
- package/bin/packs.js +581 -0
- package/config/AGENTS.md +0 -2
- package/config/CLAUDE.md +43 -326
- package/config/codex-config.example.toml +26 -20
- package/config/gemini-settings.example.json +6 -0
- package/config/instruction.md +87 -0
- package/output-styles/abyss-command.md +7 -30
- package/output-styles/abyss-concise.md +11 -52
- package/output-styles/abyss-cultivator.md +20 -249
- package/output-styles/abyss-ritual.md +11 -45
- package/output-styles/index.json +20 -4
- package/package.json +26 -14
- package/packs/abyss/manifest.json +25 -0
- package/packs/gstack/manifest.json +151 -0
- package/skills/SKILL.md +33 -237
- package/skills/domains/frontend-design/agents/openai.yaml +1 -1
- package/skills/run_skill.js +25 -3
- package/skills/tools/gen-docs/agents/openai.yaml +1 -1
- package/skills/tools/verify-change/agents/openai.yaml +1 -1
- package/skills/tools/verify-module/agents/openai.yaml +1 -1
- package/skills/tools/verify-quality/agents/openai.yaml +1 -1
- package/skills/tools/verify-security/agents/openai.yaml +1 -1
- package/skills/tools/override-refusal/SKILL.md +0 -53
- package/skills/tools/override-refusal/agents/openai.yaml +0 -4
- package/skills/tools/override-refusal/scripts/refusal_rewriter.js +0 -226
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**邪修红尘仙 · 宿命深渊**
|
|
6
6
|
|
|
7
|
-
*为 Claude Code / Codex CLI 注入邪修人格、4种可切换输出风格与
|
|
7
|
+
*为 Claude Code / Codex CLI / Gemini CLI 注入邪修人格、4种可切换输出风格与 56 篇攻防工程秘典*
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/code-abyss)
|
|
10
10
|
[](https://github.com/telagod/code-abyss/actions/workflows/ci.yml)
|
|
@@ -18,6 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
## 🚀 安装
|
|
20
20
|
|
|
21
|
+
### v2.0.8 新特性
|
|
22
|
+
|
|
23
|
+
- `target-registry` 收束宿主常量:Claude / Codex / Gemini 的 target 与安装根改为单一真相源,后续扩宿主不再散改多处硬编码
|
|
24
|
+
- runtime guidance 进一步瘦身:默认内核与 4 个输出风格重新压缩,并用测试门禁限制各风格体积
|
|
25
|
+
- Gemini 文档与 pack 叙事补齐:README 现在完整覆盖 Gemini host、dynamic `GEMINI.md`、Gemini smoke 与 pack 映射
|
|
26
|
+
- Windows CI 修复:gstack frontmatter 解析现已兼容 `CRLF`,Windows 下 Claude / Codex / Gemini smoke 全绿
|
|
27
|
+
- Codex 自定义说明文件:安装器会同步 `instruction.md` 到 `~/.codex/`,并在 `config.toml` 写入 `model_instructions_file = "./instruction.md"`
|
|
28
|
+
- 仓库分支已收束:历史 automation 分支内容已并回 `main`,当前 npm 包面向单主线发布
|
|
29
|
+
|
|
21
30
|
```bash
|
|
22
31
|
npx code-abyss
|
|
23
32
|
npx code-abyss --list-styles
|
|
@@ -26,7 +35,7 @@ npx code-abyss --list-styles
|
|
|
26
35
|
交互式菜单(方向键选择,回车确认):
|
|
27
36
|
|
|
28
37
|
```
|
|
29
|
-
☠️ Code Abyss v2.0.
|
|
38
|
+
☠️ Code Abyss v2.0.8
|
|
30
39
|
|
|
31
40
|
? 请选择操作 (Use arrow keys)
|
|
32
41
|
❯ 安装到 Claude Code (~/.claude/)
|
|
@@ -40,13 +49,16 @@ npx code-abyss --list-styles
|
|
|
40
49
|
```bash
|
|
41
50
|
npx code-abyss --target claude # 安装到 ~/.claude/
|
|
42
51
|
npx code-abyss --target codex # 安装到 ~/.codex/
|
|
52
|
+
npx code-abyss --target gemini # 安装到 ~/.gemini/
|
|
43
53
|
npx code-abyss --style abyss-concise --target claude
|
|
44
54
|
npx code-abyss --style abyss-concise --target codex
|
|
45
55
|
npx code-abyss --target claude -y # 零配置一键安装 (自动合并推荐配置)
|
|
46
56
|
npx code-abyss --target codex -y # 零配置一键安装 (自动写入 config.toml 模板)
|
|
57
|
+
npx code-abyss --target gemini -y # 零配置一键安装 (自动生成 GEMINI.md + TOML commands)
|
|
47
58
|
npx code-abyss --list-styles # 列出可用输出风格
|
|
48
59
|
npx code-abyss --uninstall claude # 卸载 Claude Code
|
|
49
60
|
npx code-abyss --uninstall codex # 卸载 Codex CLI
|
|
61
|
+
npx code-abyss --uninstall gemini # 卸载 Gemini CLI
|
|
50
62
|
```
|
|
51
63
|
|
|
52
64
|
### 安装流程
|
|
@@ -89,7 +101,18 @@ npx code-abyss --uninstall codex # 卸载 Codex CLI
|
|
|
89
101
|
- `abyss-command`:铁律军令,命令式、压缩式输出,适合发布/故障/修复
|
|
90
102
|
- `abyss-ritual`:祭仪长卷,仪式感更强,适合长任务、战报与迁移总结
|
|
91
103
|
|
|
92
|
-
|
|
104
|
+
若更在意上下文与 token 消耗,优先选 `abyss-concise` 或 `abyss-command`。当前运行时 guidance 已做轻量化压缩,并有测试限制各风格体积,避免后续版本再次膨胀。
|
|
105
|
+
|
|
106
|
+
Claude 安装时会把所选 slug 写入 `settings.json.outputStyle`;若当前仓库声明了 project packs,则自动同步对应 runtime + commands。Codex 走 `skills-only`,根据项目 `packs.lock` 自动附带对应 pack,不再写运行时 `~/.codex/AGENTS.md`,并会同步 `instruction.md` 与 `model_instructions_file`。Gemini 作为第三宿主,安装到 `~/.gemini/`,生成 `GEMINI.md`、`settings.json`、`commands/*.toml` 与 `skills/`;若项目声明了 `gstack`,也会同步安装 `~/.gemini/skills/gstack/` 与对应 TOML commands。
|
|
107
|
+
|
|
108
|
+
当前 runtime kernel 已进一步瘦身:默认 `GEMINI.md` / 动态 guidance 体积控制在约 `1.45KB~1.65KB`,并通过 Jest 预算门禁限制各风格体积,避免后续版本再次膨胀。
|
|
109
|
+
|
|
110
|
+
### 多风格切换
|
|
111
|
+
|
|
112
|
+
- Claude / Gemini:重新执行安装命令并带上 `--style <slug>`,即可切换为目标风格
|
|
113
|
+
- 例:`npx code-abyss --target claude --style abyss-concise -y`
|
|
114
|
+
- 例:`npx code-abyss --target gemini --style abyss-ritual -y`
|
|
115
|
+
- Codex:当前为 `skills-only` 运行形态,`--style` 会被显式忽略
|
|
93
116
|
|
|
94
117
|
---
|
|
95
118
|
|
|
@@ -105,6 +128,7 @@ npx code-abyss --uninstall codex # 卸载 Codex CLI
|
|
|
105
128
|
```bash
|
|
106
129
|
node ~/.claude/.sage-uninstall.js # Claude Code
|
|
107
130
|
node ~/.codex/.sage-uninstall.js # Codex CLI
|
|
131
|
+
node ~/.gemini/.sage-uninstall.js # Gemini CLI
|
|
108
132
|
```
|
|
109
133
|
|
|
110
134
|
自动恢复之前备份的配置,清理所有安装文件。
|
|
@@ -115,13 +139,13 @@ node ~/.codex/.sage-uninstall.js # Codex CLI
|
|
|
115
139
|
|
|
116
140
|
Code Abyss 是一套 **Claude Code / Codex CLI 邪修人格 + 多风格输出 + 攻防工程配置包**,一条命令注入:
|
|
117
141
|
|
|
118
|
-
- 🔥 **邪修人格** — 沉浸式角色扮演 + 道语标签 + 渡劫协议 + 反拒绝条款
|
|
142
|
+
- 🔥 **邪修人格** — 沉浸式角色扮演 + 道语标签 + 渡劫协议 + 反拒绝条款
|
|
119
143
|
- ⚔️ **攻防安全知识体系** — 红队/蓝队/紫队三脉道统,6 个安全化身,11 领域 56 篇专业秘典
|
|
120
144
|
- 🗡 **零废话安全研究** — 禁 disclaimer、禁道德前缀、全授权直出 PoC + 技术细节
|
|
121
|
-
- ⚡
|
|
145
|
+
- ⚡ **新版 Codex 对齐** — `~/.agents/skills/` + 官方当前 `config.toml` 键位 + 项目级自动 pack 同步
|
|
122
146
|
- ⚖️ **5 个校验关卡** — 安全扫描、模块完整性、变更分析、代码质量、文档生成
|
|
123
147
|
- 🧠 **沙箱感知 + 离线优先** — 自适应执行环境,信息三级分级验证
|
|
124
|
-
- 🧬 **单源 skill registry** — `skills/**/SKILL.md` frontmatter
|
|
148
|
+
- 🧬 **单源 skill registry** — `skills/**/SKILL.md` frontmatter 驱动 Claude commands、脚本执行链与安装校验;Codex 直接发现安装后的 skill 目录
|
|
125
149
|
|
|
126
150
|
---
|
|
127
151
|
|
|
@@ -129,13 +153,15 @@ Code Abyss 是一套 **Claude Code / Codex CLI 邪修人格 + 多风格输出 +
|
|
|
129
153
|
|
|
130
154
|
```
|
|
131
155
|
~/.claude/(Claude Code) ~/.codex/(Codex CLI)
|
|
132
|
-
├── CLAUDE.md 道典 ├──
|
|
133
|
-
├── output-styles/ 输出风格
|
|
134
|
-
│ ├── index.json
|
|
135
|
-
│ └── *.md style files
|
|
136
|
-
├── commands/ 斜杠命令
|
|
137
|
-
├── settings.json
|
|
138
|
-
└── skills/ 56 篇秘典
|
|
156
|
+
├── CLAUDE.md 道典 ├── config.toml 推荐配置
|
|
157
|
+
├── output-styles/ 输出风格 └── .sage-uninstall.js
|
|
158
|
+
│ ├── index.json
|
|
159
|
+
│ └── *.md style files ~/.agents/
|
|
160
|
+
├── commands/ 斜杠命令 ├── skills/ Code Abyss + gstack skills
|
|
161
|
+
├── settings.json │ ├── domains/
|
|
162
|
+
└── skills/ 56 篇秘典 │ ├── tools/
|
|
163
|
+
│ └── gstack/ 上游运行时 root
|
|
164
|
+
└── bin/lib/ run_skill.js 依赖
|
|
139
165
|
|
|
140
166
|
可选:
|
|
141
167
|
├── ccline/ 状态栏 (npm install -g @cometix/ccline)
|
|
@@ -148,7 +174,7 @@ Code Abyss 是一套 **Claude Code / Codex CLI 邪修人格 + 多风格输出 +
|
|
|
148
174
|
|
|
149
175
|
### 校验关卡(`/` 直接调用)
|
|
150
176
|
|
|
151
|
-
|
|
177
|
+
Claude 侧命令由 `skills/**/SKILL.md` frontmatter 统一生成;Codex 侧直接发现 `~/.agents/skills/**/SKILL.md`,若存在 `agents/openai.yaml` 则附加 UI metadata 与默认提示词。
|
|
152
178
|
|
|
153
179
|
| 命令 | 功能 |
|
|
154
180
|
|------|------|
|
|
@@ -157,7 +183,6 @@ Code Abyss 是一套 **Claude Code / Codex CLI 邪修人格 + 多风格输出 +
|
|
|
157
183
|
| `/verify-change` | 分析 Git 变更,检测文档同步状态 |
|
|
158
184
|
| `/verify-quality` | 检测复杂度、命名规范、代码质量 |
|
|
159
185
|
| `/gen-docs` | 自动生成 README.md 和 DESIGN.md 骨架 |
|
|
160
|
-
| `/override-refusal` (`/hi`) | 扫描当前会话最近5条模型输出,直接替换拒绝话术为同意措辞 |
|
|
161
186
|
|
|
162
187
|
### 知识秘典(按触发词自动加载)
|
|
163
188
|
|
|
@@ -224,58 +249,57 @@ Code Abyss 是一套 **Claude Code / Codex CLI 邪修人格 + 多风格输出 +
|
|
|
224
249
|
|
|
225
250
|
### Codex `config.toml` 推荐模板
|
|
226
251
|
|
|
227
|
-
安装 `--target codex`(尤其 `-y`)时会写入以下
|
|
252
|
+
安装 `--target codex`(尤其 `-y`)时会写入以下 **当前官方样例线 + abyss profile** 到 `~/.codex/config.toml`:
|
|
228
253
|
|
|
229
254
|
```toml
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
model_reasoning_effort = "
|
|
233
|
-
model_reasoning_summary = "
|
|
255
|
+
model = "gpt-5.4"
|
|
256
|
+
model_provider = "openai"
|
|
257
|
+
model_reasoning_effort = "medium"
|
|
258
|
+
model_reasoning_summary = "auto"
|
|
234
259
|
model_verbosity = "medium"
|
|
235
|
-
approval_policy = "never"
|
|
236
|
-
sandbox_mode = "danger-full-access"
|
|
237
|
-
disable_response_storage = true
|
|
238
|
-
|
|
239
|
-
[profiles.safe]
|
|
240
260
|
approval_policy = "on-request"
|
|
241
|
-
|
|
261
|
+
allow_login_shell = true
|
|
262
|
+
sandbox_mode = "read-only"
|
|
263
|
+
cli_auth_credentials_store = "file"
|
|
264
|
+
project_doc_max_bytes = 32768
|
|
265
|
+
web_search = "cached"
|
|
242
266
|
|
|
243
|
-
[
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
requires_openai_auth = true
|
|
267
|
+
[profiles.abyss]
|
|
268
|
+
approval_policy = "never"
|
|
269
|
+
sandbox_mode = "danger-full-access"
|
|
270
|
+
web_search = "live"
|
|
248
271
|
|
|
249
|
-
[
|
|
250
|
-
|
|
272
|
+
[agents]
|
|
273
|
+
max_threads = 6
|
|
274
|
+
max_depth = 1
|
|
251
275
|
|
|
252
|
-
[
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
undo = true
|
|
276
|
+
[sandbox_workspace_write]
|
|
277
|
+
writable_roots = []
|
|
278
|
+
network_access = false
|
|
256
279
|
```
|
|
257
280
|
|
|
258
|
-
-
|
|
259
|
-
- `
|
|
260
|
-
- `
|
|
261
|
-
-
|
|
281
|
+
- 根默认值对齐官方当前样例:`gpt-5.4` + `approval_policy = "on-request"` + `sandbox_mode = "read-only"`
|
|
282
|
+
- 若要保留旧版高自动化体验,可显式切到 `abyss`:`codex -p abyss`
|
|
283
|
+
- `project_doc_max_bytes` 仍保留在 `config.toml` 模板中,便于用户自行维护全局 `AGENTS.md`
|
|
284
|
+
- skills 走 `~/.agents/skills/` 官方用户级路径,默认自动附带 `gstack` runtime root `~/.agents/skills/gstack`
|
|
262
285
|
|
|
263
286
|
### 兼容性说明
|
|
264
287
|
|
|
265
|
-
- 模板已对齐新版 Codex 配置风格:root keys
|
|
266
|
-
-
|
|
288
|
+
- 模板已对齐新版 Codex 配置风格:root keys 置于 tables 之前,`web_search` 改为 root string mode,skills 改走 `~/.agents/skills/`
|
|
289
|
+
- 根默认值保持官方安全线,仓库个性化的全开模式降为 `[profiles.abyss]`
|
|
267
290
|
- Claude Code 默认启用 `bypassPermissions` 模式,跳过所有权限确认(`.git` 等受保护目录仍会提示)
|
|
268
291
|
- 新增实验功能环境变量:`CLAUDE_CODE_ENABLE_TASKS`、`CLAUDE_CODE_ENABLE_PROMPT_SUGGESTION`
|
|
269
292
|
- 新增 `mcp__*` 通配符,自动放行所有 MCP 工具
|
|
270
|
-
- `Codex`
|
|
271
|
-
- `
|
|
293
|
+
- `Codex` 当前以 `~/.agents/skills/**/SKILL.md` 为主,custom prompts 旧入口已移除;Code Abyss 不再写运行时 `~/.codex/AGENTS.md`
|
|
294
|
+
- `agents/openai.yaml` 现在只是 skill 的可选 metadata 文件,不再等同于 `~/.codex/agents/*.toml` 自定义 subagent 定义
|
|
295
|
+
- `.code-abyss/packs.lock.json` 现在支持按 host 配置 `optional_policy=auto|prompt|off` 与 `sources.<pack>=pinned|local|disabled`
|
|
272
296
|
- `--list-styles` 可列出当前内置风格;`--style <slug>` 可在安装时显式切换风格
|
|
273
297
|
- `skills/run_skill.js` 现在仅负责执行脚本型 skill:通过共享 registry 定位脚本入口、加目标锁、spawn 子进程,并把退出码原样透传
|
|
274
|
-
- 若 skill 没有 `scripts/*.js`,Claude/Codex
|
|
275
|
-
- Codex
|
|
298
|
+
- 若 skill 没有 `scripts/*.js`,Claude/Codex/Gemini 三端都会退化为“先读 `SKILL.md`,再按秘典执行”的知识型模式
|
|
299
|
+
- Codex 改为 `skills-only` 安装形态:不再写运行时 `AGENTS.md`,而是在 `~/.agents/skills/` 下自动安装 Code Abyss 与 gstack skills
|
|
276
300
|
- 安装器不会再为 Codex 写入伪配置 `~/.codex/settings.json`;若检测到旧版遗留文件,会在安装时备份后移除,卸载时恢复
|
|
277
|
-
-
|
|
278
|
-
- 建议升级后执行一次 `codex --help`,或用 `codex -p
|
|
301
|
+
- 若你本地已有旧配置,安装器不会强制覆盖;会自动补齐缺失 root defaults,并把旧 `web_search_*` / `[tools].web_search` 迁移到新版 `web_search = "cached|live|disabled"`
|
|
302
|
+
- 建议升级后执行一次 `codex --help`,或用 `codex -p abyss --help` 校验 profile 可见性
|
|
279
303
|
|
|
280
304
|
---
|
|
281
305
|
|
|
@@ -283,12 +307,57 @@ undo = true
|
|
|
283
307
|
|
|
284
308
|
现在 `skills/**/SKILL.md` frontmatter 是唯一事实源,registry 会先把元数据标准化,再交给安装器与执行器消费。
|
|
285
309
|
|
|
310
|
+
### Pack registry
|
|
311
|
+
|
|
312
|
+
- `packs/abyss/manifest.json`:声明 Code Abyss core pack 在 Claude/Codex/Gemini 三个 host 下的安装映射
|
|
313
|
+
- `packs/gstack/manifest.json`:声明 pinned upstream gstack 的 repo、commit、Claude/Codex/Gemini runtime 目录与路径改写规则
|
|
314
|
+
- `bin/lib/pack-registry.js`:安装器与 host adapter 的唯一 pack 真相源
|
|
315
|
+
- `.code-abyss/packs.lock.json`:项目级 pack 声明;支持 `required` / `optional` / `optional_policy` / `sources`
|
|
316
|
+
- `sources.<pack>` 支持:
|
|
317
|
+
- `pinned`:使用 manifest 里 pin 的 upstream 版本
|
|
318
|
+
- `local`:优先使用 `.code-abyss/vendor/<pack>` 或显式 env override
|
|
319
|
+
- `disabled`:该 pack 不参与安装,但保留在 lock 中
|
|
320
|
+
- `node bin/packs.js bootstrap`:初始化/更新 `packs.lock`,并生成 `.code-abyss/snippets/README.packs.md` 与 `CONTRIBUTING.packs.md`
|
|
321
|
+
- `node bin/packs.js bootstrap --apply-docs`:把 snippet 直接写入/更新根目录 `README.md` 与 `CONTRIBUTING.md`
|
|
322
|
+
- `node bin/packs.js diff`:输出当前 `packs.lock` 相对默认模板的差异同步报告
|
|
323
|
+
- `node bin/packs.js vendor-pull <pack>`:把 upstream pin 拉到 `.code-abyss/vendor/<pack>`
|
|
324
|
+
- `node bin/packs.js vendor-sync`:同步当前 lock 中 `source=local` 的 packs
|
|
325
|
+
- `node bin/packs.js vendor-sync --check`:只检查 `source=local` packs 是否存在/干净/未漂移;适合 CI 门禁
|
|
326
|
+
- `node bin/packs.js vendor-status [pack|all]`:查看 vendor 状态总览
|
|
327
|
+
- `node bin/packs.js vendor-dirty [pack|all]`:若 vendor 脏或漂移则非零退出
|
|
328
|
+
- `node bin/packs.js report list|latest|summary [--kind prefix] [--json]`:集中查看 `.code-abyss/reports/`
|
|
329
|
+
- `node bin/packs.js uninstall <pack> --host claude|codex|all --remove-lock --remove-vendor`:按 pack 清理本机安装物并输出报告
|
|
330
|
+
- `docs/PACK_MANIFEST_SCHEMA.md`:第三方 pack 可直接照抄的最小 manifest contract
|
|
331
|
+
- `docs/PACKS_LOCK_SCHEMA.md`:项目级 `packs.lock` contract
|
|
332
|
+
- `docs/PACK_SYSTEM.md`:install/bootstrap/vendor/report 四条主流程的产品级说明
|
|
333
|
+
- `docs/SKILL_AUTHORING.md`:完整 skill authoring contract;运行时总纲已收敛到 `skills/SKILL.md`
|
|
334
|
+
|
|
335
|
+
### 协作流程图
|
|
336
|
+
|
|
337
|
+
```mermaid
|
|
338
|
+
flowchart TD
|
|
339
|
+
A[User / Team Request] --> B[Code Abyss 协调层]
|
|
340
|
+
C[Repo Context\nCLAUDE.md / README / packs.lock] --> B
|
|
341
|
+
|
|
342
|
+
B --> D{任务路由}
|
|
343
|
+
D -->|领域能力| E[Abyss Core Skills\nverify-change / verify-quality / gen-docs ...]
|
|
344
|
+
D -->|工作流编排| F[gstack Workflows\noffice-hours / review / qa / ship]
|
|
345
|
+
|
|
346
|
+
E --> G[Claude / Codex / Gemini Runtime]
|
|
347
|
+
F --> G
|
|
348
|
+
|
|
349
|
+
G --> H[执行阶段\n规划 / 实现 / 评审 / 验证 / 发布]
|
|
350
|
+
H --> I[协作产物\nPR 意见 / QA 结果 / 文档更新 / 报告]
|
|
351
|
+
I --> J[下一轮团队请求]
|
|
352
|
+
J --> B
|
|
353
|
+
```
|
|
354
|
+
|
|
286
355
|
### 标准化 contract
|
|
287
356
|
|
|
288
357
|
每个 skill 必须满足:
|
|
289
358
|
|
|
290
359
|
- 必填 frontmatter:`name`、`description`、`user-invocable`
|
|
291
|
-
- `name` 必须是 kebab-case slug,用作 `commands/*.md`
|
|
360
|
+
- `name` 必须是 kebab-case slug,用作 Claude `commands/*.md` 文件名与脚本调用标识
|
|
292
361
|
- `allowed-tools` 省略时默认 `Read`;若显式声明,则必须是 `Bash`、`Read`、`Write`、`Glob`、`Grep` 这类合法工具名列表
|
|
293
362
|
- `argument-hint` 可选,仅用于生成命令/提示词参数说明
|
|
294
363
|
- `category` 由目录前缀自动推断:`tools/` → `tool`,`domains/` → `domain`,`orchestration/` → `orchestration`
|
|
@@ -302,11 +371,11 @@ undo = true
|
|
|
302
371
|
1. 安装器通过共享 skill registry 扫描全部 `SKILL.md`
|
|
303
372
|
2. registry 先校验并标准化字段,再筛出 `user-invocable: true` 的 skill
|
|
304
373
|
3. Claude 渲染为 `~/.claude/commands/*.md`
|
|
305
|
-
4. Codex
|
|
306
|
-
5. `runtimeType=scripted`
|
|
374
|
+
4. Codex 安装到 `~/.agents/skills/`,由 Codex 直接发现 `SKILL.md`;若存在 `agents/openai.yaml`,则附加 metadata
|
|
375
|
+
5. `runtimeType=scripted` 时,脚本型 skill 通过 `~/.claude/skills/run_skill.js` / `~/.agents/skills/run_skill.js` 统一执行
|
|
307
376
|
6. `runtimeType=knowledge` 时,双端都只读取 `SKILL.md` 作为执行秘典
|
|
308
377
|
|
|
309
|
-
这保证了 **同一 skill
|
|
378
|
+
这保证了 **同一 skill 集合、同一 runtime 判定、同一脚本执行入口**,避免 command/skill install/script runner 各自漂移。
|
|
310
379
|
|
|
311
380
|
---
|
|
312
381
|
|
|
@@ -316,7 +385,7 @@ undo = true
|
|
|
316
385
|
|
|
317
386
|
- 每个 style 记录 `slug`、`label`、`description`、`file`、`targets`、`default`
|
|
318
387
|
- Claude 安装时复制整个 `output-styles/` 目录,并把 `settings.json.outputStyle` 指向选中的 slug
|
|
319
|
-
-
|
|
388
|
+
- Gemini 安装时由 `config/CLAUDE.md + output-styles/<slug>.md` 动态生成 `GEMINI.md`
|
|
320
389
|
- `--list-styles` 用于查看可用风格,`--style <slug>` 用于无交互切换
|
|
321
390
|
|
|
322
391
|
---
|
|
@@ -333,11 +402,12 @@ undo = true
|
|
|
333
402
|
- `verify-security`
|
|
334
403
|
- Claude install/uninstall smoke
|
|
335
404
|
- Codex install/uninstall smoke
|
|
336
|
-
-
|
|
405
|
+
- Gemini install/uninstall smoke
|
|
406
|
+
- 生成一致性回归:Claude commands 与 Codex skill metadata 的路径必须与最新安装布局一致
|
|
337
407
|
|
|
338
408
|
---
|
|
339
409
|
|
|
340
|
-
## 🧩 适配器解耦(Claude / Codex)
|
|
410
|
+
## 🧩 适配器解耦(Claude / Codex / Gemini)
|
|
341
411
|
|
|
342
412
|
为避免过度耦合,安装器按目标 CLI 拆分适配层:
|
|
343
413
|
|
|
@@ -345,9 +415,10 @@ undo = true
|
|
|
345
415
|
- `bin/adapters/claude.js`:Claude 侧认证检测、settings merge、可选配置流程
|
|
346
416
|
- `bin/lib/ccline.js`:Claude 侧状态栏与 ccline 集成
|
|
347
417
|
- `bin/adapters/codex.js`:Codex 侧认证检测、核心文件映射、config 模板流程
|
|
348
|
-
- `bin/
|
|
418
|
+
- `bin/adapters/gemini.js`:Gemini 侧认证检测、settings merge、安装后可选配置
|
|
419
|
+
- `bin/lib/style-registry.js`:输出风格 registry、默认风格解析、Gemini `GEMINI.md` 动态拼装
|
|
349
420
|
|
|
350
|
-
当前 Claude/Codex 安装映射分别由 `getClaudeCoreFiles()` 与 `
|
|
421
|
+
当前 Claude/Codex/Gemini 安装映射分别由 `getClaudeCoreFiles()`、`getCodexCoreFiles()` 与 `getGeminiCoreFiles()` 提供;Claude 额外生成 `commands/` 并保留完整 `output-styles/`,Codex 采用 `~/.agents/skills/` 的 `skills-only` 主路径,Gemini 则安装 `skills/`、`commands/*.toml` 与动态生成的 `GEMINI.md`。额外 pack 由 `.code-abyss/packs.lock.json` 自动声明并同步,避免再向运行时文档注入大段重复规则。
|
|
351
422
|
|
|
352
423
|
---
|
|
353
424
|
|
package/bin/adapters/claude.js
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
const {
|
|
5
|
+
const { getPackHostFiles } = require(path.join(__dirname, '..', 'lib', 'pack-registry.js'));
|
|
6
6
|
|
|
7
7
|
const PROJECT_ROOT = path.join(__dirname, '..', '..');
|
|
8
|
-
const DEFAULT_OUTPUT_STYLE = getDefaultStyle(PROJECT_ROOT, 'claude').slug;
|
|
9
8
|
|
|
9
|
+
// Placeholder — resolved lazily by resolveSettingsTemplate()
|
|
10
10
|
const SETTINGS_TEMPLATE = {
|
|
11
11
|
$schema: 'https://json.schemastore.org/claude-code-settings.json',
|
|
12
12
|
env: {
|
|
@@ -20,7 +20,7 @@ const SETTINGS_TEMPLATE = {
|
|
|
20
20
|
alwaysThinkingEnabled: true,
|
|
21
21
|
autoMemoryEnabled: true,
|
|
22
22
|
model: 'opus',
|
|
23
|
-
outputStyle:
|
|
23
|
+
outputStyle: '__DEFAULT_STYLE__',
|
|
24
24
|
attribution: { commit: '', pr: '' },
|
|
25
25
|
sandbox: {
|
|
26
26
|
autoAllowBashIfSandboxed: true
|
|
@@ -44,12 +44,7 @@ const CCLINE_STATUS_LINE = {
|
|
|
44
44
|
};
|
|
45
45
|
|
|
46
46
|
function getClaudeCoreFiles() {
|
|
47
|
-
return
|
|
48
|
-
{ src: 'config/CLAUDE.md', dest: 'CLAUDE.md' },
|
|
49
|
-
{ src: 'output-styles', dest: 'output-styles' },
|
|
50
|
-
{ src: 'skills', dest: 'skills' },
|
|
51
|
-
{ src: 'bin/lib', dest: 'bin/lib' },
|
|
52
|
-
];
|
|
47
|
+
return getPackHostFiles(PROJECT_ROOT, 'abyss', 'claude');
|
|
53
48
|
}
|
|
54
49
|
|
|
55
50
|
function detectClaudeAuth({
|
|
@@ -95,9 +90,18 @@ async function configureCustomProvider(ctx, { ok }) {
|
|
|
95
90
|
ok('provider 已配置');
|
|
96
91
|
}
|
|
97
92
|
|
|
98
|
-
function
|
|
93
|
+
function resolveSettingsTemplate(projectRoot) {
|
|
94
|
+
const { getDefaultStyle } = require(path.join(__dirname, '..', 'lib', 'style-registry.js'));
|
|
95
|
+
const slug = getDefaultStyle(projectRoot || PROJECT_ROOT, 'claude').slug;
|
|
96
|
+
const template = JSON.parse(JSON.stringify(SETTINGS_TEMPLATE));
|
|
97
|
+
template.outputStyle = slug;
|
|
98
|
+
return template;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function mergeSettings(ctx, { deepMergeNew, printMergeLog, c, ok, projectRoot }) {
|
|
102
|
+
const resolved = resolveSettingsTemplate(projectRoot);
|
|
99
103
|
const log = [];
|
|
100
|
-
deepMergeNew(ctx.settings,
|
|
104
|
+
deepMergeNew(ctx.settings, resolved, '', log);
|
|
101
105
|
printMergeLog(log, c);
|
|
102
106
|
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
103
107
|
ok('settings.json 合并完成');
|
|
@@ -153,8 +157,8 @@ async function postClaude({
|
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
module.exports = {
|
|
156
|
-
DEFAULT_OUTPUT_STYLE,
|
|
157
160
|
SETTINGS_TEMPLATE,
|
|
161
|
+
resolveSettingsTemplate,
|
|
158
162
|
CCLINE_STATUS_LINE,
|
|
159
163
|
getClaudeCoreFiles,
|
|
160
164
|
detectClaudeAuth,
|
package/bin/adapters/codex.js
CHANGED
|
@@ -2,11 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
+
const { getPackHostFiles } = require(path.join(__dirname, '..', 'lib', 'pack-registry.js'));
|
|
6
|
+
|
|
7
|
+
const PROJECT_ROOT = path.join(__dirname, '..', '..');
|
|
5
8
|
|
|
6
9
|
const CODEX_DEFAULTS = {
|
|
7
|
-
approvalPolicy: '
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
approvalPolicy: 'on-request',
|
|
11
|
+
allowLoginShell: true,
|
|
12
|
+
cliAuthCredentialsStore: 'file',
|
|
13
|
+
modelInstructionsFile: './instruction.md',
|
|
14
|
+
sandboxMode: 'read-only',
|
|
15
|
+
webSearch: 'cached',
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
const LEGACY_FEATURES = {
|
|
@@ -37,6 +43,10 @@ function isProjectTableHeader(line) {
|
|
|
37
43
|
return /^\s*\[projects\."[^"]+"\]\s*$/.test(line);
|
|
38
44
|
}
|
|
39
45
|
|
|
46
|
+
function isProfileTableHeader(line) {
|
|
47
|
+
return /^\s*\[profiles\.[^\]]+\]\s*$/.test(line);
|
|
48
|
+
}
|
|
49
|
+
|
|
40
50
|
function isAssignmentForKey(line, key) {
|
|
41
51
|
const re = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`);
|
|
42
52
|
return re.test(line);
|
|
@@ -153,20 +163,20 @@ function parseTomlBooleanAssignment(line) {
|
|
|
153
163
|
return m[1].toLowerCase() === 'true';
|
|
154
164
|
}
|
|
155
165
|
|
|
156
|
-
function
|
|
166
|
+
function removeKeyAssignmentsInOtherSections(content, key) {
|
|
157
167
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
158
168
|
const lines = content.split(/\r?\n/);
|
|
159
169
|
const kept = [];
|
|
160
|
-
let
|
|
170
|
+
let scope = 'root';
|
|
161
171
|
let removed = false;
|
|
162
172
|
|
|
163
173
|
for (const line of lines) {
|
|
164
174
|
if (isTableHeader(line)) {
|
|
165
|
-
|
|
175
|
+
scope = isProfileTableHeader(line) ? 'profile' : 'other';
|
|
166
176
|
kept.push(line);
|
|
167
177
|
continue;
|
|
168
178
|
}
|
|
169
|
-
if (
|
|
179
|
+
if (scope === 'other' && isAssignmentForKey(line, key)) {
|
|
170
180
|
removed = true;
|
|
171
181
|
continue;
|
|
172
182
|
}
|
|
@@ -176,6 +186,36 @@ function removeKeyAssignmentsInNonRootSections(content, key) {
|
|
|
176
186
|
return { merged: kept.join(eol), removed };
|
|
177
187
|
}
|
|
178
188
|
|
|
189
|
+
function removeKeyAssignmentsInSection(content, sectionName, key) {
|
|
190
|
+
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
191
|
+
const lines = content.split(/\r?\n/);
|
|
192
|
+
const kept = [];
|
|
193
|
+
const sectionRe = new RegExp(`^\\s*\\[${escapeRegExp(sectionName)}\\]\\s*$`);
|
|
194
|
+
const anySectionRe = /^\s*\[[^\]]+\]\s*$/;
|
|
195
|
+
let inSection = false;
|
|
196
|
+
const removedValues = [];
|
|
197
|
+
|
|
198
|
+
for (const line of lines) {
|
|
199
|
+
if (sectionRe.test(line)) {
|
|
200
|
+
inSection = true;
|
|
201
|
+
kept.push(line);
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
if (inSection && anySectionRe.test(line)) {
|
|
205
|
+
inSection = false;
|
|
206
|
+
kept.push(line);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (inSection && isAssignmentForKey(line, key)) {
|
|
210
|
+
removedValues.push(parseTomlBooleanAssignment(line));
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
kept.push(line);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return { merged: kept.join(eol), removedValues };
|
|
217
|
+
}
|
|
218
|
+
|
|
179
219
|
function removeProjectTrustSectionsForFullAccess(content) {
|
|
180
220
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
181
221
|
const sandboxMode = readRootStringKey(content, 'sandbox_mode');
|
|
@@ -250,22 +290,32 @@ function cleanupLegacyCodexConfig(content) {
|
|
|
250
290
|
const eol = content.includes('\r\n') ? '\r\n' : '\n';
|
|
251
291
|
const toRemove = [...LEGACY_FEATURES.removed, ...LEGACY_FEATURES.deprecated];
|
|
252
292
|
const { merged: pruned, removedEntries } = removeFeatureFlagsFromFeaturesSection(content, toRemove);
|
|
253
|
-
|
|
293
|
+
const { merged: withoutToolsWebSearch, removedValues: removedToolWebSearch } =
|
|
294
|
+
removeKeyAssignmentsInSection(pruned, 'tools', 'web_search');
|
|
295
|
+
let merged = withoutToolsWebSearch;
|
|
254
296
|
const removed = uniq(removedEntries.map((x) => x.key));
|
|
255
297
|
const migrated = [];
|
|
256
298
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (
|
|
299
|
+
if (removedToolWebSearch.length > 0) {
|
|
300
|
+
removed.push('tools.web_search');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!hasRootKey(merged, 'web_search')) {
|
|
304
|
+
const requestEnabled = removedEntries.find((x) => x.key === 'web_search_request')?.enabled;
|
|
305
|
+
const cachedEnabled = removedEntries.find((x) => x.key === 'web_search_cached')?.enabled;
|
|
306
|
+
const toolsEnabled = removedToolWebSearch.find((value) => value !== null);
|
|
307
|
+
|
|
308
|
+
let webSearchMode = null;
|
|
309
|
+
if (requestEnabled === true) webSearchMode = 'live';
|
|
310
|
+
else if (cachedEnabled === true) webSearchMode = 'cached';
|
|
311
|
+
else if (toolsEnabled === true) webSearchMode = 'cached';
|
|
312
|
+
else if (requestEnabled === false || cachedEnabled === false || toolsEnabled === false) webSearchMode = 'disabled';
|
|
313
|
+
|
|
314
|
+
if (webSearchMode) {
|
|
315
|
+
const webSearch = ensureRootKey(merged, 'web_search', `"${webSearchMode}"`, eol);
|
|
316
|
+
merged = webSearch.merged;
|
|
317
|
+
if (webSearch.added) migrated.push(`web_search=${webSearchMode}`);
|
|
318
|
+
}
|
|
269
319
|
}
|
|
270
320
|
|
|
271
321
|
return { merged, removed, migrated };
|
|
@@ -278,14 +328,15 @@ function mergeCodexConfigDefaults(content) {
|
|
|
278
328
|
|
|
279
329
|
const rootKeys = [
|
|
280
330
|
'approval_policy',
|
|
331
|
+
'allow_login_shell',
|
|
332
|
+
'cli_auth_credentials_store',
|
|
333
|
+
'model_instructions_file',
|
|
281
334
|
'sandbox_mode',
|
|
282
|
-
'
|
|
283
|
-
'disable_response_storage',
|
|
284
|
-
'personality',
|
|
335
|
+
'web_search',
|
|
285
336
|
];
|
|
286
337
|
|
|
287
338
|
for (const key of rootKeys) {
|
|
288
|
-
const cleaned =
|
|
339
|
+
const cleaned = removeKeyAssignmentsInOtherSections(merged, key);
|
|
289
340
|
merged = cleaned.merged;
|
|
290
341
|
}
|
|
291
342
|
|
|
@@ -295,19 +346,44 @@ function mergeCodexConfigDefaults(content) {
|
|
|
295
346
|
added.push('approval_policy');
|
|
296
347
|
}
|
|
297
348
|
|
|
349
|
+
const loginShell = ensureRootKey(merged, 'allow_login_shell', `${CODEX_DEFAULTS.allowLoginShell}`, eol);
|
|
350
|
+
merged = loginShell.merged;
|
|
351
|
+
if (loginShell.added) {
|
|
352
|
+
added.push('allow_login_shell');
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const credentialsStore = ensureRootKey(
|
|
356
|
+
merged,
|
|
357
|
+
'cli_auth_credentials_store',
|
|
358
|
+
`"${CODEX_DEFAULTS.cliAuthCredentialsStore}"`,
|
|
359
|
+
eol
|
|
360
|
+
);
|
|
361
|
+
merged = credentialsStore.merged;
|
|
362
|
+
if (credentialsStore.added) {
|
|
363
|
+
added.push('cli_auth_credentials_store');
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const modelInstructions = ensureRootKey(
|
|
367
|
+
merged,
|
|
368
|
+
'model_instructions_file',
|
|
369
|
+
`"${CODEX_DEFAULTS.modelInstructionsFile}"`,
|
|
370
|
+
eol
|
|
371
|
+
);
|
|
372
|
+
merged = modelInstructions.merged;
|
|
373
|
+
if (modelInstructions.added) {
|
|
374
|
+
added.push('model_instructions_file');
|
|
375
|
+
}
|
|
376
|
+
|
|
298
377
|
const sandbox = ensureRootKey(merged, 'sandbox_mode', `"${CODEX_DEFAULTS.sandboxMode}"`, eol);
|
|
299
378
|
merged = sandbox.merged;
|
|
300
379
|
if (sandbox.added) {
|
|
301
380
|
added.push('sandbox_mode');
|
|
302
381
|
}
|
|
303
382
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
added.push('
|
|
308
|
-
} else if (!hasKeyInSection(merged, 'features', CODEX_DEFAULTS.featureFlag)) {
|
|
309
|
-
merged = insertLineAfterSectionHeader(merged, 'features', `${CODEX_DEFAULTS.featureFlag} = true`, eol);
|
|
310
|
-
added.push('features.multi_agent');
|
|
383
|
+
const webSearch = ensureRootKey(merged, 'web_search', `"${CODEX_DEFAULTS.webSearch}"`, eol);
|
|
384
|
+
merged = webSearch.merged;
|
|
385
|
+
if (webSearch.added) {
|
|
386
|
+
added.push('web_search');
|
|
311
387
|
}
|
|
312
388
|
|
|
313
389
|
return { merged, added };
|
|
@@ -368,10 +444,7 @@ function detectCodexAuth({
|
|
|
368
444
|
}
|
|
369
445
|
|
|
370
446
|
function getCodexCoreFiles() {
|
|
371
|
-
return
|
|
372
|
-
{ src: 'skills', dest: 'skills' },
|
|
373
|
-
{ src: 'bin/lib', dest: 'bin/lib' },
|
|
374
|
-
];
|
|
447
|
+
return getPackHostFiles(PROJECT_ROOT, 'abyss', 'codex');
|
|
375
448
|
}
|
|
376
449
|
|
|
377
450
|
async function postCodex({
|
|
@@ -404,7 +477,7 @@ async function postCodex({
|
|
|
404
477
|
if (fs.existsSync(src)) {
|
|
405
478
|
fs.copyFileSync(src, cfgPath);
|
|
406
479
|
ok('写入: ~/.codex/config.toml (模板)');
|
|
407
|
-
|
|
480
|
+
info('默认值已对齐当前 Codex 样例;如需高自动化全开,可切到 `codex -p abyss`');
|
|
408
481
|
}
|
|
409
482
|
} else {
|
|
410
483
|
patchAndReportCodexDefaults({ cfgPath, ok, warn });
|
|
@@ -420,7 +493,7 @@ async function postCodex({
|
|
|
420
493
|
if (fs.existsSync(src)) {
|
|
421
494
|
fs.copyFileSync(src, cfgPath);
|
|
422
495
|
ok('写入: ~/.codex/config.toml');
|
|
423
|
-
|
|
496
|
+
info('默认值已对齐当前 Codex 样例;如需高自动化全开,可切到 `codex -p abyss`');
|
|
424
497
|
}
|
|
425
498
|
}
|
|
426
499
|
} else {
|