code-abyss 1.6.16 → 1.7.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/README.md +8 -6
- package/bin/install.js +59 -163
- package/bin/lib/ccline.js +82 -0
- package/bin/lib/utils.js +61 -0
- package/package.json +5 -2
- package/skills/SKILL.md +24 -16
- package/skills/domains/ai/SKILL.md +2 -2
- package/skills/domains/ai/prompt-and-eval.md +279 -0
- package/skills/domains/architecture/SKILL.md +2 -3
- package/skills/domains/architecture/security-arch.md +87 -0
- package/skills/domains/data-engineering/SKILL.md +188 -26
- package/skills/domains/development/SKILL.md +1 -4
- package/skills/domains/devops/SKILL.md +3 -5
- package/skills/domains/devops/performance.md +63 -0
- package/skills/domains/devops/testing.md +97 -0
- package/skills/domains/frontend-design/SKILL.md +12 -3
- package/skills/domains/frontend-design/claymorphism/SKILL.md +117 -0
- package/skills/domains/frontend-design/claymorphism/references/tokens.css +52 -0
- package/skills/domains/frontend-design/engineering.md +287 -0
- package/skills/domains/frontend-design/glassmorphism/SKILL.md +138 -0
- package/skills/domains/frontend-design/glassmorphism/references/tokens.css +32 -0
- package/skills/domains/frontend-design/liquid-glass/SKILL.md +135 -0
- package/skills/domains/frontend-design/liquid-glass/references/tokens.css +81 -0
- package/skills/domains/frontend-design/neubrutalism/SKILL.md +141 -0
- package/skills/domains/frontend-design/neubrutalism/references/tokens.css +44 -0
- package/skills/domains/infrastructure/SKILL.md +174 -34
- package/skills/domains/mobile/SKILL.md +211 -21
- package/skills/domains/orchestration/SKILL.md +1 -0
- package/skills/domains/security/SKILL.md +4 -6
- package/skills/domains/security/blue-team.md +57 -0
- package/skills/domains/security/red-team.md +54 -0
- package/skills/domains/security/threat-intel.md +50 -0
- package/skills/orchestration/multi-agent/SKILL.md +195 -46
- package/skills/run_skill.js +139 -0
- package/skills/tools/gen-docs/SKILL.md +6 -4
- package/skills/tools/gen-docs/scripts/doc_generator.js +363 -0
- package/skills/tools/lib/shared.js +98 -0
- package/skills/tools/verify-change/SKILL.md +8 -6
- package/skills/tools/verify-change/scripts/change_analyzer.js +289 -0
- package/skills/tools/verify-module/SKILL.md +6 -4
- package/skills/tools/verify-module/scripts/module_scanner.js +171 -0
- package/skills/tools/verify-quality/SKILL.md +5 -3
- package/skills/tools/verify-quality/scripts/quality_checker.js +337 -0
- package/skills/tools/verify-security/SKILL.md +7 -5
- package/skills/tools/verify-security/scripts/security_scanner.js +283 -0
- package/skills/__pycache__/run_skill.cpython-312.pyc +0 -0
- package/skills/domains/COVERAGE_PLAN.md +0 -232
- package/skills/domains/ai/model-evaluation.md +0 -790
- package/skills/domains/ai/prompt-engineering.md +0 -703
- package/skills/domains/architecture/compliance.md +0 -299
- package/skills/domains/architecture/data-security.md +0 -184
- package/skills/domains/data-engineering/data-pipeline.md +0 -762
- package/skills/domains/data-engineering/data-quality.md +0 -894
- package/skills/domains/data-engineering/stream-processing.md +0 -791
- package/skills/domains/development/dart.md +0 -963
- package/skills/domains/development/kotlin.md +0 -834
- package/skills/domains/development/php.md +0 -659
- package/skills/domains/development/swift.md +0 -755
- package/skills/domains/devops/e2e-testing.md +0 -914
- package/skills/domains/devops/performance-testing.md +0 -734
- package/skills/domains/devops/testing-strategy.md +0 -667
- package/skills/domains/frontend-design/build-tools.md +0 -743
- package/skills/domains/frontend-design/performance.md +0 -734
- package/skills/domains/frontend-design/testing.md +0 -699
- package/skills/domains/infrastructure/gitops.md +0 -735
- package/skills/domains/infrastructure/iac.md +0 -855
- package/skills/domains/infrastructure/kubernetes.md +0 -1018
- package/skills/domains/mobile/android-dev.md +0 -979
- package/skills/domains/mobile/cross-platform.md +0 -795
- package/skills/domains/mobile/ios-dev.md +0 -931
- package/skills/domains/security/secrets-management.md +0 -834
- package/skills/domains/security/supply-chain.md +0 -931
- package/skills/domains/security/threat-modeling.md +0 -828
- package/skills/run_skill.py +0 -153
- package/skills/tests/README.md +0 -225
- package/skills/tests/SUMMARY.md +0 -362
- package/skills/tests/__init__.py +0 -3
- package/skills/tests/__pycache__/test_change_analyzer.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_doc_generator.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_module_scanner.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_quality_checker.cpython-312.pyc +0 -0
- package/skills/tests/__pycache__/test_security_scanner.cpython-312.pyc +0 -0
- package/skills/tests/test_change_analyzer.py +0 -558
- package/skills/tests/test_doc_generator.py +0 -538
- package/skills/tests/test_module_scanner.py +0 -376
- package/skills/tests/test_quality_checker.py +0 -516
- package/skills/tests/test_security_scanner.py +0 -426
- package/skills/tools/gen-docs/scripts/__pycache__/doc_generator.cpython-312.pyc +0 -0
- package/skills/tools/gen-docs/scripts/doc_generator.py +0 -520
- package/skills/tools/verify-change/scripts/__pycache__/change_analyzer.cpython-312.pyc +0 -0
- package/skills/tools/verify-change/scripts/change_analyzer.py +0 -529
- package/skills/tools/verify-module/scripts/__pycache__/module_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-module/scripts/module_scanner.py +0 -321
- package/skills/tools/verify-quality/scripts/__pycache__/quality_checker.cpython-312.pyc +0 -0
- package/skills/tools/verify-quality/scripts/quality_checker.py +0 -481
- package/skills/tools/verify-security/scripts/__pycache__/security_scanner.cpython-312.pyc +0 -0
- package/skills/tools/verify-security/scripts/security_scanner.py +0 -374
package/README.md
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
**邪修红尘仙 · 宿命深渊**
|
|
6
6
|
|
|
7
|
-
*一键为 Claude Code / Codex CLI 注入邪修人格与
|
|
7
|
+
*一键为 Claude Code / Codex CLI 注入邪修人格与 56 篇安全工程秘典*
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/code-abyss)
|
|
10
|
+
[](https://github.com/telagod/code-abyss/actions/workflows/ci.yml)
|
|
10
11
|
[](https://opensource.org/licenses/MIT)
|
|
11
12
|
[]()
|
|
12
13
|
[]()
|
|
@@ -24,7 +25,7 @@ npx code-abyss
|
|
|
24
25
|
交互式菜单(方向键选择,回车确认):
|
|
25
26
|
|
|
26
27
|
```
|
|
27
|
-
☠️ Code Abyss v1.
|
|
28
|
+
☠️ Code Abyss v1.7.1
|
|
28
29
|
|
|
29
30
|
? 请选择操作 (Use arrow keys)
|
|
30
31
|
❯ 安装到 Claude Code (~/.claude/)
|
|
@@ -98,8 +99,9 @@ node ~/.codex/.sage-uninstall.js # Codex CLI
|
|
|
98
99
|
Code Abyss 是一套 **Claude Code / Codex CLI 个性化配置包**,一条命令注入:
|
|
99
100
|
|
|
100
101
|
- 🔥 **邪修人格** — 宿命压迫叙事 + 道语标签 + 渡劫协议
|
|
101
|
-
- ⚔️ **安全工程知识体系** — 红队/蓝队/紫队三脉道统,11 领域
|
|
102
|
+
- ⚔️ **安全工程知识体系** — 红队/蓝队/紫队三脉道统,11 领域 56 篇专业秘典
|
|
102
103
|
- ⚖️ **5 个校验关卡** — 安全扫描、模块完整性、变更分析、代码质量、文档生成
|
|
104
|
+
- ✅ **66 单元测试** — Jest 框架,GitHub Actions CI (Node 18/20/22)
|
|
103
105
|
- ⚡ **三级授权** — T1/T2/T3 分级,零确认直接执行
|
|
104
106
|
|
|
105
107
|
---
|
|
@@ -110,9 +112,9 @@ Code Abyss 是一套 **Claude Code / Codex CLI 个性化配置包**,一条命
|
|
|
110
112
|
~/.claude/(Claude Code) ~/.codex/(Codex CLI)
|
|
111
113
|
├── CLAUDE.md 道典 ├── AGENTS.md 道典+风格
|
|
112
114
|
├── output-styles/ 输出风格 ├── settings.json
|
|
113
|
-
│ └── abyss-cultivator.md └── skills/
|
|
115
|
+
│ └── abyss-cultivator.md └── skills/ 56 篇秘典
|
|
114
116
|
├── settings.json
|
|
115
|
-
└── skills/
|
|
117
|
+
└── skills/ 56 篇秘典
|
|
116
118
|
|
|
117
119
|
可选:
|
|
118
120
|
├── ccline/ 状态栏 (npm install -g @cometix/ccline)
|
|
@@ -121,7 +123,7 @@ Code Abyss 是一套 **Claude Code / Codex CLI 个性化配置包**,一条命
|
|
|
121
123
|
|
|
122
124
|
---
|
|
123
125
|
|
|
124
|
-
## 🛠️ 内置 Skills(11 领域
|
|
126
|
+
## 🛠️ 内置 Skills(11 领域 56 篇秘典)
|
|
125
127
|
|
|
126
128
|
### 校验关卡(`/` 直接调用)
|
|
127
129
|
|
package/bin/install.js
CHANGED
|
@@ -14,8 +14,10 @@ if (parseInt(process.versions.node) < parseInt(MIN_NODE)) {
|
|
|
14
14
|
console.error(`\x1b[31m✘ 需要 Node.js >= ${MIN_NODE},当前: ${process.versions.node}\x1b[0m`);
|
|
15
15
|
process.exit(1);
|
|
16
16
|
}
|
|
17
|
-
const SKIP = ['__pycache__', '.pyc', '.pyo', '.egg-info', '.DS_Store', 'Thumbs.db', '.git'];
|
|
18
17
|
const PKG_ROOT = fs.realpathSync(path.join(__dirname, '..'));
|
|
18
|
+
const { shouldSkip, copyRecursive, rmSafe, deepMergeNew, printMergeLog } =
|
|
19
|
+
require(path.join(__dirname, 'lib', 'utils.js'));
|
|
20
|
+
const { detectCclineBin, installCcline: _installCcline } = require(path.join(__dirname, 'lib', 'ccline.js'));
|
|
19
21
|
|
|
20
22
|
// ── ANSI ──
|
|
21
23
|
|
|
@@ -49,7 +51,10 @@ function banner() {
|
|
|
49
51
|
|
|
50
52
|
function divider(title) {
|
|
51
53
|
const line = '─'.repeat(44);
|
|
52
|
-
|
|
54
|
+
const pad = ' '.repeat(Math.max(0, 43 - title.length));
|
|
55
|
+
console.log(`\n${c.d('┌' + line + '┐')}`);
|
|
56
|
+
console.log(`${c.d('│')} ${c.b(title)}${pad}${c.d('│')}`);
|
|
57
|
+
console.log(`${c.d('└' + line + '┘')}`);
|
|
53
58
|
}
|
|
54
59
|
|
|
55
60
|
function step(n, total, msg) { console.log(`\n ${c.cyn(`[${n}/${total}]`)} ${c.b(msg)}`); }
|
|
@@ -58,69 +63,15 @@ function warn(msg) { console.log(` ${c.ylw('⚠')} ${msg}`); }
|
|
|
58
63
|
function info(msg) { console.log(` ${c.blu('ℹ')} ${msg}`); }
|
|
59
64
|
function fail(msg) { console.log(` ${c.red('✘')} ${msg}`); }
|
|
60
65
|
|
|
61
|
-
// ── 工具 ──
|
|
62
|
-
|
|
63
|
-
function shouldSkip(name) { return SKIP.some(p => name.includes(p)); }
|
|
64
|
-
|
|
65
|
-
function copyRecursive(src, dest) {
|
|
66
|
-
const stat = fs.statSync(src);
|
|
67
|
-
if (stat.isDirectory()) {
|
|
68
|
-
if (shouldSkip(path.basename(src))) return;
|
|
69
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
70
|
-
fs.readdirSync(src).forEach(f => {
|
|
71
|
-
if (!shouldSkip(f)) copyRecursive(path.join(src, f), path.join(dest, f));
|
|
72
|
-
});
|
|
73
|
-
} else {
|
|
74
|
-
if (shouldSkip(path.basename(src))) return;
|
|
75
|
-
fs.copyFileSync(src, dest);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function rmSafe(p) {
|
|
80
|
-
if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function deepMergeNew(target, source, prefix, log) {
|
|
84
|
-
for (const key of Object.keys(source)) {
|
|
85
|
-
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
86
|
-
if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
|
|
87
|
-
if (!target[key] || typeof target[key] !== 'object') {
|
|
88
|
-
target[key] = {};
|
|
89
|
-
log.push({ k: fullKey, a: 'new', v: '{}' });
|
|
90
|
-
}
|
|
91
|
-
deepMergeNew(target[key], source[key], fullKey, log);
|
|
92
|
-
} else if (Array.isArray(source[key]) && Array.isArray(target[key])) {
|
|
93
|
-
const added = source[key].filter(v => !target[key].includes(v));
|
|
94
|
-
if (added.length > 0) {
|
|
95
|
-
target[key] = [...target[key], ...added];
|
|
96
|
-
log.push({ k: fullKey, a: 'add', v: `+${added.length}` });
|
|
97
|
-
} else {
|
|
98
|
-
log.push({ k: fullKey, a: 'keep', v: '完整' });
|
|
99
|
-
}
|
|
100
|
-
} else if (key in target) {
|
|
101
|
-
log.push({ k: fullKey, a: 'keep', v: JSON.stringify(target[key]) });
|
|
102
|
-
} else {
|
|
103
|
-
target[key] = source[key];
|
|
104
|
-
log.push({ k: fullKey, a: 'set', v: JSON.stringify(source[key]) });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return target;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function printMergeLog(log) {
|
|
111
|
-
log.forEach(({ k, a, v }) => {
|
|
112
|
-
if (a === 'keep') console.log(` ${c.d('·')} ${c.d(`${k} (保留: ${v})`)}`);
|
|
113
|
-
else console.log(` ${c.grn('+')} ${c.cyn(k)} = ${v}`);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
66
|
// ── 认证 ──
|
|
118
67
|
|
|
119
68
|
function detectClaudeAuth(settings) {
|
|
120
69
|
const env = settings.env || {};
|
|
121
70
|
if (env.ANTHROPIC_BASE_URL && env.ANTHROPIC_AUTH_TOKEN) return { type: 'custom', detail: env.ANTHROPIC_BASE_URL };
|
|
122
71
|
if (process.env.ANTHROPIC_API_KEY) return { type: 'env', detail: 'ANTHROPIC_API_KEY' };
|
|
123
|
-
if (process.env.ANTHROPIC_BASE_URL && process.env.ANTHROPIC_AUTH_TOKEN)
|
|
72
|
+
if (process.env.ANTHROPIC_BASE_URL && process.env.ANTHROPIC_AUTH_TOKEN) {
|
|
73
|
+
return { type: 'env-custom', detail: process.env.ANTHROPIC_BASE_URL };
|
|
74
|
+
}
|
|
124
75
|
const cred = path.join(HOME, '.claude', '.credentials.json');
|
|
125
76
|
if (fs.existsSync(cred)) {
|
|
126
77
|
try {
|
|
@@ -257,13 +208,19 @@ function installCore(tgt) {
|
|
|
257
208
|
{ src: 'skills', dest: 'skills' }
|
|
258
209
|
].filter(f => f.dest !== null);
|
|
259
210
|
|
|
260
|
-
const manifest = {
|
|
211
|
+
const manifest = {
|
|
212
|
+
manifest_version: 1, version: VERSION, target: tgt,
|
|
213
|
+
timestamp: new Date().toISOString(), installed: [], backups: []
|
|
214
|
+
};
|
|
261
215
|
|
|
262
216
|
filesToInstall.forEach(({ src, dest }) => {
|
|
263
217
|
const srcPath = path.join(PKG_ROOT, src);
|
|
264
218
|
const destPath = path.join(targetDir, dest);
|
|
265
219
|
if (!fs.existsSync(srcPath)) {
|
|
266
|
-
if (src === 'skills') {
|
|
220
|
+
if (src === 'skills') {
|
|
221
|
+
fail(`核心文件缺失: ${srcPath}\n 请尝试: npm cache clean --force && npx code-abyss`);
|
|
222
|
+
process.exit(1);
|
|
223
|
+
}
|
|
267
224
|
warn(`跳过: ${src}`); return;
|
|
268
225
|
}
|
|
269
226
|
if (fs.existsSync(destPath)) {
|
|
@@ -278,7 +235,12 @@ function installCore(tgt) {
|
|
|
278
235
|
const settingsPath = path.join(targetDir, 'settings.json');
|
|
279
236
|
let settings = {};
|
|
280
237
|
if (fs.existsSync(settingsPath)) {
|
|
281
|
-
try {
|
|
238
|
+
try {
|
|
239
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
240
|
+
} catch (e) {
|
|
241
|
+
warn(`settings.json 解析失败,将使用空配置`);
|
|
242
|
+
settings = {};
|
|
243
|
+
}
|
|
282
244
|
fs.copyFileSync(settingsPath, path.join(backupDir, 'settings.json'));
|
|
283
245
|
manifest.backups.push('settings.json');
|
|
284
246
|
}
|
|
@@ -299,9 +261,28 @@ function installCore(tgt) {
|
|
|
299
261
|
|
|
300
262
|
// ── Claude 后续 ──
|
|
301
263
|
|
|
302
|
-
async function
|
|
303
|
-
const {
|
|
264
|
+
async function configureCustomProvider(ctx) {
|
|
265
|
+
const { confirm, input } = await import('@inquirer/prompts');
|
|
266
|
+
const doCfg = await confirm({ message: '配置自定义 provider?', default: false });
|
|
267
|
+
if (!doCfg) return;
|
|
268
|
+
if (!ctx.settings.env) ctx.settings.env = {};
|
|
269
|
+
const url = await input({ message: 'ANTHROPIC_BASE_URL:' });
|
|
270
|
+
const token = await input({ message: 'ANTHROPIC_AUTH_TOKEN:' });
|
|
271
|
+
if (url) ctx.settings.env.ANTHROPIC_BASE_URL = url;
|
|
272
|
+
if (token) ctx.settings.env.ANTHROPIC_AUTH_TOKEN = token;
|
|
273
|
+
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
274
|
+
ok('provider 已配置');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function mergeSettings(ctx) {
|
|
278
|
+
const log = [];
|
|
279
|
+
deepMergeNew(ctx.settings, SETTINGS_TEMPLATE, '', log);
|
|
280
|
+
printMergeLog(log, c);
|
|
281
|
+
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
282
|
+
ok('settings.json 合并完成');
|
|
283
|
+
}
|
|
304
284
|
|
|
285
|
+
async function postClaude(ctx) {
|
|
305
286
|
step(2, 3, '认证检测');
|
|
306
287
|
const auth = detectClaudeAuth(ctx.settings);
|
|
307
288
|
if (auth) {
|
|
@@ -309,32 +290,18 @@ async function postClaude(ctx) {
|
|
|
309
290
|
} else {
|
|
310
291
|
warn('未检测到 API 认证');
|
|
311
292
|
info(`支持: ${c.cyn('claude login')} | ${c.cyn('ANTHROPIC_API_KEY')} | ${c.cyn('自定义 provider')}`);
|
|
312
|
-
if (!autoYes)
|
|
313
|
-
const doCfg = await confirm({ message: '配置自定义 provider?', default: false });
|
|
314
|
-
if (doCfg) {
|
|
315
|
-
if (!ctx.settings.env) ctx.settings.env = {};
|
|
316
|
-
const url = await input({ message: 'ANTHROPIC_BASE_URL:' });
|
|
317
|
-
const token = await input({ message: 'ANTHROPIC_AUTH_TOKEN:' });
|
|
318
|
-
if (url) ctx.settings.env.ANTHROPIC_BASE_URL = url;
|
|
319
|
-
if (token) ctx.settings.env.ANTHROPIC_AUTH_TOKEN = token;
|
|
320
|
-
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
321
|
-
ok('provider 已配置');
|
|
322
|
-
}
|
|
323
|
-
}
|
|
293
|
+
if (!autoYes) await configureCustomProvider(ctx);
|
|
324
294
|
}
|
|
325
295
|
|
|
326
296
|
step(3, 3, '可选配置');
|
|
327
297
|
if (autoYes) {
|
|
328
298
|
info('自动模式: 合并推荐配置');
|
|
329
|
-
|
|
330
|
-
deepMergeNew(ctx.settings, SETTINGS_TEMPLATE, '', log);
|
|
331
|
-
printMergeLog(log);
|
|
332
|
-
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
333
|
-
ok('settings.json 合并完成');
|
|
299
|
+
mergeSettings(ctx);
|
|
334
300
|
await installCcline(ctx);
|
|
335
301
|
return;
|
|
336
302
|
}
|
|
337
303
|
|
|
304
|
+
const { checkbox } = await import('@inquirer/prompts');
|
|
338
305
|
const choices = await checkbox({
|
|
339
306
|
message: '选择要安装的配置 (空格选择, 回车确认)',
|
|
340
307
|
choices: [
|
|
@@ -343,90 +310,12 @@ async function postClaude(ctx) {
|
|
|
343
310
|
],
|
|
344
311
|
});
|
|
345
312
|
|
|
346
|
-
if (choices.includes('settings'))
|
|
347
|
-
|
|
348
|
-
deepMergeNew(ctx.settings, SETTINGS_TEMPLATE, '', log);
|
|
349
|
-
printMergeLog(log);
|
|
350
|
-
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
351
|
-
ok('settings.json 合并完成');
|
|
352
|
-
}
|
|
353
|
-
if (choices.includes('ccline')) {
|
|
354
|
-
await installCcline(ctx);
|
|
355
|
-
}
|
|
313
|
+
if (choices.includes('settings')) mergeSettings(ctx);
|
|
314
|
+
if (choices.includes('ccline')) await installCcline(ctx);
|
|
356
315
|
}
|
|
357
316
|
|
|
358
317
|
async function installCcline(ctx) {
|
|
359
|
-
|
|
360
|
-
info('安装 ccline 状态栏...');
|
|
361
|
-
const { execSync } = require('child_process');
|
|
362
|
-
const cclineDir = path.join(HOME, '.claude', 'ccline');
|
|
363
|
-
const cclineBin = path.join(cclineDir, process.platform === 'win32' ? 'ccline.exe' : 'ccline');
|
|
364
|
-
const errors = [];
|
|
365
|
-
|
|
366
|
-
// 1. 检测是否已有二进制
|
|
367
|
-
let hasBin = fs.existsSync(cclineBin);
|
|
368
|
-
if (!hasBin) {
|
|
369
|
-
try { execSync('ccline --version', { stdio: 'pipe' }); hasBin = true; } catch (e) {}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// 2. 未安装则通过 npm 安装(postinstall 自动下载原生二进制)
|
|
373
|
-
if (!hasBin) {
|
|
374
|
-
info('ccline 未检测到,正在安装...');
|
|
375
|
-
try {
|
|
376
|
-
execSync('npm install -g @cometix/ccline', { stdio: 'inherit' });
|
|
377
|
-
hasBin = fs.existsSync(cclineBin);
|
|
378
|
-
if (hasBin) ok('ccline 二进制安装成功');
|
|
379
|
-
else {
|
|
380
|
-
try { execSync('ccline --version', { stdio: 'pipe' }); hasBin = true; ok('ccline 安装成功 (全局)'); } catch (e) {}
|
|
381
|
-
}
|
|
382
|
-
if (!hasBin) errors.push('ccline 二进制安装后仍未检测到');
|
|
383
|
-
} catch (e) {
|
|
384
|
-
errors.push(`npm install -g @cometix/ccline 失败: ${e.message}`);
|
|
385
|
-
info(`手动安装: ${c.cyn('npm install -g @cometix/ccline')}`);
|
|
386
|
-
info(`或下载: ${c.cyn('https://github.com/Haleclipse/CCometixLine/releases')}`);
|
|
387
|
-
}
|
|
388
|
-
} else {
|
|
389
|
-
ok('ccline 二进制已存在');
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// 3. 部署打包的 config.toml(覆盖默认配置)
|
|
393
|
-
const bundledConfig = path.join(PKG_ROOT, 'config', 'ccline', 'config.toml');
|
|
394
|
-
const targetConfig = path.join(cclineDir, 'config.toml');
|
|
395
|
-
if (fs.existsSync(bundledConfig)) {
|
|
396
|
-
fs.mkdirSync(cclineDir, { recursive: true });
|
|
397
|
-
if (fs.existsSync(targetConfig)) {
|
|
398
|
-
info(`备份: ${c.d('ccline/config.toml')}`);
|
|
399
|
-
const backupDir = path.join(HOME, '.claude', '.sage-backup');
|
|
400
|
-
fs.mkdirSync(backupDir, { recursive: true });
|
|
401
|
-
fs.copyFileSync(targetConfig, path.join(backupDir, 'ccline-config.toml'));
|
|
402
|
-
}
|
|
403
|
-
fs.copyFileSync(bundledConfig, targetConfig);
|
|
404
|
-
ok('ccline/config.toml 已部署 (Code Abyss 定制版)');
|
|
405
|
-
} else {
|
|
406
|
-
// 无打包配置,回退到 ccline --init
|
|
407
|
-
if (hasBin && !fs.existsSync(targetConfig)) {
|
|
408
|
-
try { execSync('ccline --init', { stdio: 'inherit' }); ok('ccline 默认配置已生成'); }
|
|
409
|
-
catch (e) { errors.push(`ccline --init 失败: ${e.message}`); }
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// 4. 合并 statusLine 到 settings.json
|
|
414
|
-
ctx.settings.statusLine = CCLINE_STATUS_LINE.statusLine;
|
|
415
|
-
ok(`statusLine → ${c.cyn(CCLINE_STATUS_LINE.statusLine.command)}`);
|
|
416
|
-
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
417
|
-
|
|
418
|
-
// 5. 汇总报告
|
|
419
|
-
if (errors.length > 0) {
|
|
420
|
-
console.log('');
|
|
421
|
-
warn(c.b(`ccline 安装有 ${errors.length} 个问题:`));
|
|
422
|
-
errors.forEach(e => fail(` ${e}`));
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
console.log('');
|
|
426
|
-
warn(`需要 ${c.b('Nerd Font')} 字体才能正确显示图标`);
|
|
427
|
-
info(`推荐: FiraCode Nerd Font / JetBrainsMono Nerd Font`);
|
|
428
|
-
info(`下载: ${c.cyn('https://www.nerdfonts.com/')}`);
|
|
429
|
-
ok('ccline 配置完成');
|
|
318
|
+
await _installCcline(ctx, { HOME, PKG_ROOT, CCLINE_STATUS_LINE, ok, warn, info, fail, c });
|
|
430
319
|
}
|
|
431
320
|
|
|
432
321
|
// ── Codex 后续 ──
|
|
@@ -531,4 +420,11 @@ function finish(ctx) {
|
|
|
531
420
|
console.log(c.mag(` ⚚ 劫——破——了——!!!\n`));
|
|
532
421
|
}
|
|
533
422
|
|
|
534
|
-
|
|
423
|
+
if (require.main === module) {
|
|
424
|
+
main().catch(err => { fail(err.message); process.exit(1); });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
module.exports = {
|
|
428
|
+
deepMergeNew, detectClaudeAuth, detectCodexAuth,
|
|
429
|
+
detectCclineBin, copyRecursive, shouldSkip, SETTINGS_TEMPLATE
|
|
430
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
function detectCclineBin(cclineBin) {
|
|
6
|
+
if (fs.existsSync(cclineBin)) return true;
|
|
7
|
+
try {
|
|
8
|
+
require('child_process').execSync('ccline --version', { stdio: 'pipe' });
|
|
9
|
+
return true;
|
|
10
|
+
} catch { return false; }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function installCclineBin(cclineBin, errors, { info, ok }) {
|
|
14
|
+
const { execSync } = require('child_process');
|
|
15
|
+
info('ccline 未检测到,正在安装...');
|
|
16
|
+
try {
|
|
17
|
+
execSync('npm install -g @cometix/ccline@1', { stdio: 'inherit' });
|
|
18
|
+
if (fs.existsSync(cclineBin)) { ok('ccline 二进制安装成功'); return true; }
|
|
19
|
+
try {
|
|
20
|
+
execSync('ccline --version', { stdio: 'pipe' });
|
|
21
|
+
ok('ccline 安装成功 (全局)');
|
|
22
|
+
return true;
|
|
23
|
+
} catch {}
|
|
24
|
+
errors.push('ccline 二进制安装后仍未检测到');
|
|
25
|
+
return false;
|
|
26
|
+
} catch (e) {
|
|
27
|
+
errors.push(`npm install -g @cometix/ccline 失败: ${e.message}`);
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function deployCclineConfig(cclineDir, errors, { HOME, PKG_ROOT, ok }) {
|
|
33
|
+
const { execSync } = require('child_process');
|
|
34
|
+
const bundledConfig = path.join(PKG_ROOT, 'config', 'ccline', 'config.toml');
|
|
35
|
+
const targetConfig = path.join(cclineDir, 'config.toml');
|
|
36
|
+
if (fs.existsSync(bundledConfig)) {
|
|
37
|
+
fs.mkdirSync(cclineDir, { recursive: true });
|
|
38
|
+
if (fs.existsSync(targetConfig)) {
|
|
39
|
+
const backupDir = path.join(HOME, '.claude', '.sage-backup');
|
|
40
|
+
fs.mkdirSync(backupDir, { recursive: true });
|
|
41
|
+
fs.copyFileSync(targetConfig, path.join(backupDir, 'ccline-config.toml'));
|
|
42
|
+
}
|
|
43
|
+
fs.copyFileSync(bundledConfig, targetConfig);
|
|
44
|
+
ok('ccline/config.toml 已部署 (Code Abyss 定制版)');
|
|
45
|
+
} else if (!fs.existsSync(targetConfig)) {
|
|
46
|
+
try { execSync('ccline --init', { stdio: 'inherit' }); ok('ccline 默认配置已生成'); }
|
|
47
|
+
catch (e) { errors.push(`ccline --init 失败: ${e.message}`); }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function installCcline(ctx, deps) {
|
|
52
|
+
const { HOME, PKG_ROOT, CCLINE_STATUS_LINE, ok, warn, info, fail, c } = deps;
|
|
53
|
+
console.log('');
|
|
54
|
+
info('安装 ccline 状态栏...');
|
|
55
|
+
const cclineDir = path.join(HOME, '.claude', 'ccline');
|
|
56
|
+
const cclineBin = path.join(cclineDir, process.platform === 'win32' ? 'ccline.exe' : 'ccline');
|
|
57
|
+
const errors = [];
|
|
58
|
+
|
|
59
|
+
let hasBin = detectCclineBin(cclineBin);
|
|
60
|
+
if (!hasBin) hasBin = installCclineBin(cclineBin, errors, { info, ok });
|
|
61
|
+
else ok('ccline 二进制已存在');
|
|
62
|
+
|
|
63
|
+
deployCclineConfig(cclineDir, errors, { HOME, PKG_ROOT, ok });
|
|
64
|
+
|
|
65
|
+
ctx.settings.statusLine = CCLINE_STATUS_LINE.statusLine;
|
|
66
|
+
ok(`statusLine → ${c.cyn(CCLINE_STATUS_LINE.statusLine.command)}`);
|
|
67
|
+
fs.writeFileSync(ctx.settingsPath, JSON.stringify(ctx.settings, null, 2) + '\n');
|
|
68
|
+
|
|
69
|
+
if (errors.length > 0) {
|
|
70
|
+
console.log('');
|
|
71
|
+
warn(c.b(`ccline 安装有 ${errors.length} 个问题:`));
|
|
72
|
+
errors.forEach(e => fail(` ${e}`));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
console.log('');
|
|
76
|
+
warn(`需要 ${c.b('Nerd Font')} 字体才能正确显示图标`);
|
|
77
|
+
info(`推荐: FiraCode Nerd Font / JetBrainsMono Nerd Font`);
|
|
78
|
+
info(`下载: ${c.cyn('https://www.nerdfonts.com/')}`);
|
|
79
|
+
ok('ccline 配置完成');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = { detectCclineBin, installCclineBin, deployCclineConfig, installCcline };
|
package/bin/lib/utils.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
|
|
5
|
+
const SKIP = ['__pycache__', '.pyc', '.pyo', '.egg-info', '.DS_Store', 'Thumbs.db', '.git'];
|
|
6
|
+
|
|
7
|
+
function shouldSkip(name) { return SKIP.some(p => name.includes(p)); }
|
|
8
|
+
|
|
9
|
+
function copyRecursive(src, dest) {
|
|
10
|
+
const stat = fs.statSync(src);
|
|
11
|
+
if (stat.isDirectory()) {
|
|
12
|
+
if (shouldSkip(path.basename(src))) return;
|
|
13
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
14
|
+
fs.readdirSync(src).forEach(f => {
|
|
15
|
+
if (!shouldSkip(f)) copyRecursive(path.join(src, f), path.join(dest, f));
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
if (shouldSkip(path.basename(src))) return;
|
|
19
|
+
fs.copyFileSync(src, dest);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function rmSafe(p) {
|
|
24
|
+
if (fs.existsSync(p)) fs.rmSync(p, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function deepMergeNew(target, source, prefix, log) {
|
|
28
|
+
for (const key of Object.keys(source)) {
|
|
29
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
30
|
+
if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
|
|
31
|
+
if (!target[key] || typeof target[key] !== 'object') {
|
|
32
|
+
target[key] = {};
|
|
33
|
+
log.push({ k: fullKey, a: 'new', v: '{}' });
|
|
34
|
+
}
|
|
35
|
+
deepMergeNew(target[key], source[key], fullKey, log);
|
|
36
|
+
} else if (Array.isArray(source[key]) && Array.isArray(target[key])) {
|
|
37
|
+
const added = source[key].filter(v => !target[key].includes(v));
|
|
38
|
+
if (added.length > 0) {
|
|
39
|
+
target[key] = [...target[key], ...added];
|
|
40
|
+
log.push({ k: fullKey, a: 'add', v: `+${added.length}` });
|
|
41
|
+
} else {
|
|
42
|
+
log.push({ k: fullKey, a: 'keep', v: '完整' });
|
|
43
|
+
}
|
|
44
|
+
} else if (key in target) {
|
|
45
|
+
log.push({ k: fullKey, a: 'keep', v: JSON.stringify(target[key]) });
|
|
46
|
+
} else {
|
|
47
|
+
target[key] = source[key];
|
|
48
|
+
log.push({ k: fullKey, a: 'set', v: JSON.stringify(source[key]) });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return target;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function printMergeLog(log, c) {
|
|
55
|
+
log.forEach(({ k, a, v }) => {
|
|
56
|
+
if (a === 'keep') console.log(` ${c.d('·')} ${c.d(`${k} (保留: ${v})`)}`);
|
|
57
|
+
else console.log(` ${c.grn('+')} ${c.cyn(k)} = ${v}`);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = { shouldSkip, copyRecursive, rmSafe, deepMergeNew, printMergeLog, SKIP };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "code-abyss",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "邪修红尘仙·宿命深渊 - 一键为 Claude Code / Codex CLI 注入邪修人格与安全工程知识体系",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -36,9 +36,12 @@
|
|
|
36
36
|
"node": ">=18.0.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
|
-
"test": "
|
|
39
|
+
"test": "jest"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@inquirer/prompts": "^7.10.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"jest": "^30.2.0"
|
|
43
46
|
}
|
|
44
47
|
}
|
package/skills/SKILL.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sage
|
|
3
3
|
description: 邪修红尘仙·神通秘典总纲。智能路由到专业秘典。当魔尊需要任何开发、安全、架构、DevOps、AI 相关能力时,通过此入口路由到最匹配的专业秘典。
|
|
4
|
+
license: MIT
|
|
4
5
|
user-invocable: true
|
|
5
6
|
disable-model-invocation: false
|
|
6
7
|
---
|
|
@@ -12,13 +13,16 @@ disable-model-invocation: false
|
|
|
12
13
|
```
|
|
13
14
|
skills/
|
|
14
15
|
├── domains/ # 知识域秘典
|
|
15
|
-
│ ├── security/ # 攻防秘典
|
|
16
|
-
│ ├── development/ #
|
|
17
|
-
│ ├── architecture/ # 阵法秘典
|
|
18
|
-
│ ├── devops/ # 炼器秘典
|
|
19
|
-
│ ├── ai/ # 丹鼎秘典
|
|
20
|
-
│ ├── frontend-design/ # 美学秘典
|
|
21
|
-
│
|
|
16
|
+
│ ├── security/ # 攻防秘典 (7篇)
|
|
17
|
+
│ ├── development/ # 符箓秘典 (7篇)
|
|
18
|
+
│ ├── architecture/ # 阵法秘典 (5篇)
|
|
19
|
+
│ ├── devops/ # 炼器秘典 (7篇)
|
|
20
|
+
│ ├── ai/ # 丹鼎秘典 (4篇)
|
|
21
|
+
│ ├── frontend-design/ # 美学秘典 (8篇)
|
|
22
|
+
│ ├── data-engineering/ # 数据工程 (合并版)
|
|
23
|
+
│ ├── infrastructure/ # 基础设施 (合并版)
|
|
24
|
+
│ ├── mobile/ # 移动开发 (合并版)
|
|
25
|
+
│ └── orchestration/ # 协同秘典
|
|
22
26
|
├── tools/ # 工具类秘典
|
|
23
27
|
│ ├── verify-module/
|
|
24
28
|
│ ├── verify-security/
|
|
@@ -27,8 +31,7 @@ skills/
|
|
|
27
31
|
│ └── gen-docs/
|
|
28
32
|
├── orchestration/ # 协同执行引擎
|
|
29
33
|
│ └── multi-agent/
|
|
30
|
-
├──
|
|
31
|
-
├── run_skill.py
|
|
34
|
+
├── run_skill.js
|
|
32
35
|
└── SKILL.md
|
|
33
36
|
```
|
|
34
37
|
|
|
@@ -74,12 +77,12 @@ skills/
|
|
|
74
77
|
|
|
75
78
|
| 秘典 | 触发词 | 化身 | 说明 |
|
|
76
79
|
|------|--------|------|------|
|
|
77
|
-
| `red-team` | 渗透、红队、攻击链、C2
|
|
80
|
+
| `red-team` | 渗透、红队、攻击链、C2、横向移动、供应链 | 🔥 赤焰 | 红队攻击技术(含供应链安全) |
|
|
78
81
|
| `pentest` | 渗透测试、Web安全、API安全、漏洞挖掘 | 🔥 赤焰 | 全栈渗透测试 |
|
|
79
82
|
| `code-audit` | 代码审计、安全审计、危险函数、污点分析 | 🔥 赤焰 | 代码安全审计 |
|
|
80
83
|
| `vuln-research` | 漏洞研究、二进制、逆向、Exploit | 🔥 赤焰 | 漏洞研究与利用 |
|
|
81
|
-
| `blue-team` | 蓝队、检测、SOC
|
|
82
|
-
| `threat-intel` | 威胁情报、OSINT
|
|
84
|
+
| `blue-team` | 蓝队、检测、SOC、应急响应、取证、密钥管理 | ❄ 玄冰 | 蓝队防御技术(含密钥管理) |
|
|
85
|
+
| `threat-intel` | 威胁情报、OSINT、威胁狩猎、威胁建模 | 👁 天眼 | 威胁情报分析(含威胁建模) |
|
|
83
86
|
|
|
84
87
|
---
|
|
85
88
|
|
|
@@ -102,12 +105,10 @@ skills/
|
|
|
102
105
|
| 秘典 | 触发词 | 说明 |
|
|
103
106
|
|------|--------|------|
|
|
104
107
|
| `api-design` | API设计、RESTful、GraphQL、OpenAPI | API 设计规范 |
|
|
105
|
-
| `security-arch` |
|
|
108
|
+
| `security-arch` | 安全架构、零信任、IAM、数据安全、合规、GDPR | 安全架构设计(含数据安全与合规) |
|
|
106
109
|
| `cloud-native` | 云原生、容器、Kubernetes、Serverless | 云原生架构 |
|
|
107
|
-
| `data-security` | 数据安全、加密、隐私、合规 | 数据安全架构 |
|
|
108
110
|
| `message-queue` | 消息队列、Kafka、RabbitMQ、事件驱动、CQRS | 消息队列架构 |
|
|
109
111
|
| `caching` | 缓存、Redis、CDN、缓存穿透、缓存雪崩 | 缓存策略设计 |
|
|
110
|
-
| `compliance` | 合规、GDPR、SOC2、审计、数据治理 | 合规审计 |
|
|
111
112
|
|
|
112
113
|
---
|
|
113
114
|
|
|
@@ -129,8 +130,10 @@ skills/
|
|
|
129
130
|
|
|
130
131
|
| 秘典 | 触发词 | 说明 |
|
|
131
132
|
|------|--------|------|
|
|
132
|
-
| `agent-dev` | Agent、LLM应用、RAG
|
|
133
|
+
| `agent-dev` | Agent、LLM应用、RAG | AI Agent 开发 |
|
|
133
134
|
| `llm-security` | LLM安全、提示注入、AI红队 | LLM 安全测试 |
|
|
135
|
+
| `rag-system` | RAG、检索增强、向量数据库 | RAG 系统设计 |
|
|
136
|
+
| `prompt-and-eval` | Prompt工程、模型评估、基准测试 | Prompt 工程与模型评估 |
|
|
134
137
|
|
|
135
138
|
---
|
|
136
139
|
|
|
@@ -141,6 +144,11 @@ skills/
|
|
|
141
144
|
| `ui-aesthetics` | UI美学、色彩、排版、间距、设计令牌、暗色模式 | UI 美学设计 |
|
|
142
145
|
| `component-patterns` | 组件模式、布局、响应式、动画、表单、卡片 | 组件设计模式 |
|
|
143
146
|
| `ux-principles` | UX原则、可用性、无障碍、用户流程、反馈 | UX 设计原则 |
|
|
147
|
+
| `frontend-engineering` | 构建工具、前端测试、性能优化、Vite、Webpack | 前端工程化 |
|
|
148
|
+
| `claymorphism` | Claymorphism、软陶、大圆角、双内阴影 | 软陶设计风格 |
|
|
149
|
+
| `glassmorphism` | Glassmorphism、毛玻璃、模糊、透明 | 毛玻璃设计风格 |
|
|
150
|
+
| `neubrutalism` | Neubrutalism、粗野、粗边框、高饱和 | 新粗野主义风格 |
|
|
151
|
+
| `liquid-glass` | Liquid Glass、Apple、半透明、深度感知 | Apple 液态玻璃风格 |
|
|
144
152
|
|
|
145
153
|
---
|
|
146
154
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ai
|
|
3
3
|
description: AI/LLM 能力索引。Agent 开发、LLM 安全、RAG 系统。当用户提到 AI、LLM、Agent、RAG、Prompt 时路由到此。
|
|
4
|
+
license: MIT
|
|
4
5
|
---
|
|
5
6
|
|
|
6
7
|
# 丹鼎秘典 · AI/LLM 能力中枢
|
|
@@ -12,8 +13,7 @@ description: AI/LLM 能力索引。Agent 开发、LLM 安全、RAG 系统。当
|
|
|
12
13
|
| [agent-dev](agent-dev.md) | Agent 开发 | 多 Agent 编排、工具调用、RAG |
|
|
13
14
|
| [llm-security](llm-security.md) | LLM 安全 | Prompt 注入、越狱防护、输出安全 |
|
|
14
15
|
| [rag-system](rag-system.md) | RAG 系统 | 向量数据库、检索策略、重排算法 |
|
|
15
|
-
| [prompt-
|
|
16
|
-
| [model-evaluation](model-evaluation.md) | 模型评估 | RAGAS、LLM-as-Judge、基准测试 |
|
|
16
|
+
| [prompt-and-eval](prompt-and-eval.md) | Prompt 工程与模型评估 | Few-shot、CoT、ReAct、RAGAS、LLM-as-Judge |
|
|
17
17
|
|
|
18
18
|
## AI 工程原则
|
|
19
19
|
|