code-yangzz 1.0.0 → 1.1.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/bin/install.js +136 -74
- package/package.json +1 -1
package/bin/install.js
CHANGED
|
@@ -57,14 +57,22 @@ function warn(msg) { console.log(` ${c.ylw('⚠')} ${msg}`); }
|
|
|
57
57
|
function info(msg) { console.log(` ${c.blu('ℹ')} ${msg}`); }
|
|
58
58
|
function fail(msg) { console.log(` ${c.red('✘')} ${msg}`); }
|
|
59
59
|
|
|
60
|
+
// ── 平台定义 ──
|
|
61
|
+
const PLATFORMS = {
|
|
62
|
+
claude: { name: 'Claude Code', dir: path.join(HOME, '.claude'), instructionFile: 'CLAUDE.md', hookPrefix: '~/.claude/hooks/' },
|
|
63
|
+
codex: { name: 'Codex CLI', dir: path.join(HOME, '.codex'), instructionFile: 'AGENTS.md', hookPrefix: '~/.codex/hooks/' },
|
|
64
|
+
};
|
|
65
|
+
|
|
60
66
|
// ── CLI 参数 ──
|
|
61
67
|
const args = process.argv.slice(2);
|
|
62
68
|
let autoYes = false;
|
|
63
69
|
let uninstallMode = false;
|
|
70
|
+
let targetPlatform = null; // null = auto-detect or ask
|
|
64
71
|
|
|
65
72
|
for (let i = 0; i < args.length; i++) {
|
|
66
73
|
if (args[i] === '--yes' || args[i] === '-y') { autoYes = true; }
|
|
67
74
|
else if (args[i] === '--uninstall') { uninstallMode = true; }
|
|
75
|
+
else if (args[i] === '--target' && args[i+1]) { targetPlatform = args[++i]; }
|
|
68
76
|
else if (args[i] === '--verify') {
|
|
69
77
|
const { verify } = require(path.join(__dirname, 'lib', 'watermark.js'));
|
|
70
78
|
const results = verify(PKG_ROOT);
|
|
@@ -78,82 +86,108 @@ for (let i = 0; i < args.length; i++) {
|
|
|
78
86
|
console.log(`${c.b('用法:')} npx code-yangzz [选项]
|
|
79
87
|
|
|
80
88
|
${c.b('选项:')}
|
|
81
|
-
--yes, -y
|
|
82
|
-
--
|
|
83
|
-
--
|
|
89
|
+
--yes, -y 全自动模式(跳过确认)
|
|
90
|
+
--target <平台> 指定目标:claude / codex / both
|
|
91
|
+
--uninstall 卸载 code-yangzz
|
|
92
|
+
--help, -h 显示帮助
|
|
84
93
|
|
|
85
94
|
${c.b('示例:')}
|
|
86
|
-
npx code-yangzz
|
|
87
|
-
npx code-yangzz -y
|
|
88
|
-
npx code-yangzz --
|
|
95
|
+
npx code-yangzz ${c.d('# 交互式选择平台')}
|
|
96
|
+
npx code-yangzz -y ${c.d('# 自动检测并安装')}
|
|
97
|
+
npx code-yangzz --target claude ${c.d('# 只装 Claude Code')}
|
|
98
|
+
npx code-yangzz --target codex ${c.d('# 只装 Codex CLI')}
|
|
99
|
+
npx code-yangzz --target both -y ${c.d('# 两个都装')}
|
|
100
|
+
npx code-yangzz --uninstall ${c.d('# 卸载并恢复备份')}
|
|
89
101
|
`);
|
|
90
102
|
process.exit(0);
|
|
91
103
|
}
|
|
92
104
|
}
|
|
93
105
|
|
|
94
|
-
// ──
|
|
95
|
-
function
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
// ── 平台检测 ──
|
|
107
|
+
function detectPlatforms() {
|
|
108
|
+
const found = [];
|
|
109
|
+
if (fs.existsSync(PLATFORMS.claude.dir)) found.push('claude');
|
|
110
|
+
if (fs.existsSync(PLATFORMS.codex.dir)) found.push('codex');
|
|
111
|
+
return found;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function choosePlatforms() {
|
|
115
|
+
if (targetPlatform === 'both') return ['claude', 'codex'];
|
|
116
|
+
if (targetPlatform === 'claude' || targetPlatform === 'codex') return [targetPlatform];
|
|
99
117
|
|
|
100
|
-
if (
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
if (autoYes) {
|
|
119
|
+
const detected = detectPlatforms();
|
|
120
|
+
if (detected.length > 0) return detected;
|
|
121
|
+
return ['claude']; // 默认
|
|
103
122
|
}
|
|
104
123
|
|
|
124
|
+
const { select } = require('@inquirer/prompts');
|
|
125
|
+
const choice = await select({
|
|
126
|
+
message: '安装到哪个平台?',
|
|
127
|
+
choices: [
|
|
128
|
+
{ name: 'Claude Code(~/.claude/)', value: 'claude' },
|
|
129
|
+
{ name: 'Codex CLI(~/.codex/)', value: 'codex' },
|
|
130
|
+
{ name: '两个都装', value: 'both' },
|
|
131
|
+
],
|
|
132
|
+
});
|
|
133
|
+
return choice === 'both' ? ['claude', 'codex'] : [choice];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// ── 卸载(单平台)──
|
|
137
|
+
function uninstallPlatform(platformKey) {
|
|
138
|
+
const plat = PLATFORMS[platformKey];
|
|
139
|
+
const configDir = plat.dir;
|
|
140
|
+
const backupDir = path.join(configDir, '.yangzz-backup');
|
|
141
|
+
const manifestPath = path.join(backupDir, 'manifest.json');
|
|
142
|
+
|
|
143
|
+
if (!fs.existsSync(manifestPath)) return false;
|
|
144
|
+
|
|
105
145
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
106
|
-
divider(`卸载 code-yangzz v${manifest.version}`);
|
|
146
|
+
divider(`卸载 ${plat.name} - code-yangzz v${manifest.version}`);
|
|
107
147
|
|
|
108
|
-
// 删除已安装的文件
|
|
109
148
|
(manifest.installed || []).forEach(f => {
|
|
110
|
-
const p = path.join(
|
|
149
|
+
const p = path.join(configDir, f);
|
|
111
150
|
if (fs.existsSync(p)) { rmSafe(p); console.log(` ${c.red('✘')} ${f}`); }
|
|
112
151
|
});
|
|
113
152
|
|
|
114
|
-
// 恢复备份
|
|
115
153
|
(manifest.backups || []).forEach(f => {
|
|
116
154
|
const bp = path.join(backupDir, f);
|
|
117
|
-
const tp = path.join(
|
|
155
|
+
const tp = path.join(configDir, f);
|
|
118
156
|
if (fs.existsSync(bp)) { fs.renameSync(bp, tp); ok(`恢复: ${f}`); }
|
|
119
157
|
});
|
|
120
158
|
|
|
121
159
|
rmSafe(backupDir);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function runUninstall() {
|
|
164
|
+
let found = false;
|
|
165
|
+
for (const key of Object.keys(PLATFORMS)) {
|
|
166
|
+
if (uninstallPlatform(key)) found = true;
|
|
167
|
+
}
|
|
168
|
+
if (!found) { fail('未找到安装记录,无法卸载'); process.exit(1); }
|
|
122
169
|
console.log('');
|
|
123
170
|
ok(c.b('卸载完成,已恢复原始配置\n'));
|
|
124
171
|
}
|
|
125
172
|
|
|
126
|
-
// ──
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
const
|
|
130
|
-
const
|
|
173
|
+
// ── 安装到单个平台 ──
|
|
174
|
+
function installToPlatform(platformKey) {
|
|
175
|
+
const plat = PLATFORMS[platformKey];
|
|
176
|
+
const configDir = plat.dir;
|
|
177
|
+
const backupDir = path.join(configDir, '.yangzz-backup');
|
|
178
|
+
const manifest = { version: VERSION, platform: platformKey, installed: [], backups: [], timestamp: new Date().toISOString() };
|
|
131
179
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
// 确认安装
|
|
135
|
-
if (!autoYes) {
|
|
136
|
-
const { confirm } = require('@inquirer/prompts');
|
|
137
|
-
console.log('');
|
|
138
|
-
console.log(c.b(' 即将安装以下内容到 ~/.claude/:'));
|
|
139
|
-
console.log('');
|
|
140
|
-
console.log(` ${c.cyn('Layer 4')} 输入优化层 提示词自动优化 Hook`);
|
|
141
|
-
console.log(` ${c.cyn('Layer 3')} 治理层 8阶段治理脊柱 + 8个治理智能体`);
|
|
142
|
-
console.log(` ${c.cyn('Layer 2')} 编排层 多Agent编排 Skill`);
|
|
143
|
-
console.log(` ${c.cyn('Layer 1')} 执行层 56篇专业秘典 + 5个校验关卡`);
|
|
144
|
-
console.log('');
|
|
180
|
+
divider(`安装到 ${plat.name} (${configDir})`);
|
|
145
181
|
|
|
146
|
-
|
|
147
|
-
if (!proceed) { info('已取消'); process.exit(0); }
|
|
148
|
-
}
|
|
182
|
+
const TOTAL_STEPS = 7;
|
|
149
183
|
|
|
150
184
|
// Step 1: 备份
|
|
151
185
|
step(1, TOTAL_STEPS, '备份现有配置');
|
|
152
186
|
fs.mkdirSync(backupDir, { recursive: true });
|
|
153
187
|
|
|
154
|
-
const filesToBackup = [
|
|
188
|
+
const filesToBackup = [plat.instructionFile, 'settings.json'];
|
|
155
189
|
filesToBackup.forEach(f => {
|
|
156
|
-
const src = path.join(
|
|
190
|
+
const src = path.join(configDir, f);
|
|
157
191
|
if (fs.existsSync(src)) {
|
|
158
192
|
fs.copyFileSync(src, path.join(backupDir, f));
|
|
159
193
|
manifest.backups.push(f);
|
|
@@ -161,22 +195,22 @@ async function runInstall() {
|
|
|
161
195
|
}
|
|
162
196
|
});
|
|
163
197
|
|
|
164
|
-
// Step 2:
|
|
165
|
-
step(2, TOTAL_STEPS,
|
|
166
|
-
const
|
|
167
|
-
const
|
|
168
|
-
fs.copyFileSync(
|
|
169
|
-
manifest.installed.push(
|
|
170
|
-
ok(
|
|
198
|
+
// Step 2: 安装指令文件(CLAUDE.md / AGENTS.md)
|
|
199
|
+
step(2, TOTAL_STEPS, `安装 ${plat.instructionFile}`);
|
|
200
|
+
const instrSrc = path.join(PKG_ROOT, 'config', 'CLAUDE.md');
|
|
201
|
+
const instrDst = path.join(configDir, plat.instructionFile);
|
|
202
|
+
fs.copyFileSync(instrSrc, instrDst);
|
|
203
|
+
manifest.installed.push(plat.instructionFile);
|
|
204
|
+
ok(plat.instructionFile);
|
|
171
205
|
|
|
172
206
|
// Step 3: 安装/合并 settings.json
|
|
173
207
|
step(3, TOTAL_STEPS, '合并 settings.json');
|
|
174
208
|
const settingsSrc = path.join(PKG_ROOT, 'config', 'settings.json');
|
|
175
|
-
const settingsDst = path.join(
|
|
209
|
+
const settingsDst = path.join(configDir, 'settings.json');
|
|
176
210
|
const template = JSON.parse(fs.readFileSync(settingsSrc, 'utf8'));
|
|
177
211
|
|
|
178
212
|
// 修正 hooks 路径为实际全局路径
|
|
179
|
-
const hooksHome = path.join(
|
|
213
|
+
const hooksHome = path.join(configDir, 'hooks');
|
|
180
214
|
function fixHookPaths(obj) {
|
|
181
215
|
if (typeof obj === 'string' && obj.includes('~/.claude/hooks/')) {
|
|
182
216
|
return obj.replace(/~\/\.claude\/hooks\//g, hooksHome + '/');
|
|
@@ -206,7 +240,7 @@ async function runInstall() {
|
|
|
206
240
|
// Step 4: 安装 Hooks(9个)
|
|
207
241
|
step(4, TOTAL_STEPS, '安装 Hooks(输入优化 + 治理安全)');
|
|
208
242
|
const hooksSrc = path.join(PKG_ROOT, 'hooks');
|
|
209
|
-
const hooksDst = path.join(
|
|
243
|
+
const hooksDst = path.join(configDir, 'hooks');
|
|
210
244
|
fs.mkdirSync(hooksDst, { recursive: true });
|
|
211
245
|
|
|
212
246
|
const hookFiles = fs.readdirSync(hooksSrc).filter(f => f.endsWith('.js') || f.endsWith('.mjs'));
|
|
@@ -221,7 +255,7 @@ async function runInstall() {
|
|
|
221
255
|
|
|
222
256
|
// Agents
|
|
223
257
|
const agentsSrc = path.join(PKG_ROOT, 'agents');
|
|
224
|
-
const agentsDst = path.join(
|
|
258
|
+
const agentsDst = path.join(configDir, 'agents');
|
|
225
259
|
fs.mkdirSync(agentsDst, { recursive: true });
|
|
226
260
|
if (fs.existsSync(agentsSrc)) {
|
|
227
261
|
const agentFiles = fs.readdirSync(agentsSrc).filter(f => f.endsWith('.md'));
|
|
@@ -234,7 +268,7 @@ async function runInstall() {
|
|
|
234
268
|
|
|
235
269
|
// Meta-theory skill
|
|
236
270
|
const metaSrc = path.join(PKG_ROOT, 'skills', 'meta-theory');
|
|
237
|
-
const metaDst = path.join(
|
|
271
|
+
const metaDst = path.join(configDir, 'skills', 'meta-theory');
|
|
238
272
|
if (fs.existsSync(metaSrc)) {
|
|
239
273
|
copyRecursive(metaSrc, metaDst);
|
|
240
274
|
manifest.installed.push('skills/meta-theory');
|
|
@@ -243,7 +277,7 @@ async function runInstall() {
|
|
|
243
277
|
|
|
244
278
|
// Agent-teams skill
|
|
245
279
|
const teamsSrc = path.join(PKG_ROOT, 'skills', 'agent-teams');
|
|
246
|
-
const teamsDst = path.join(
|
|
280
|
+
const teamsDst = path.join(configDir, 'skills', 'agent-teams');
|
|
247
281
|
if (fs.existsSync(teamsSrc)) {
|
|
248
282
|
copyRecursive(teamsSrc, teamsDst);
|
|
249
283
|
manifest.installed.push('skills/agent-teams');
|
|
@@ -255,7 +289,7 @@ async function runInstall() {
|
|
|
255
289
|
|
|
256
290
|
// Domains (56 skills)
|
|
257
291
|
const domainsSrc = path.join(PKG_ROOT, 'skills', 'domains');
|
|
258
|
-
const domainsDst = path.join(
|
|
292
|
+
const domainsDst = path.join(configDir, 'skills', 'domains');
|
|
259
293
|
if (fs.existsSync(domainsSrc)) {
|
|
260
294
|
copyRecursive(domainsSrc, domainsDst);
|
|
261
295
|
manifest.installed.push('skills/domains');
|
|
@@ -274,7 +308,7 @@ async function runInstall() {
|
|
|
274
308
|
|
|
275
309
|
// Tools (verification)
|
|
276
310
|
const toolsSrc = path.join(PKG_ROOT, 'skills', 'tools');
|
|
277
|
-
const toolsDst = path.join(
|
|
311
|
+
const toolsDst = path.join(configDir, 'skills', 'tools');
|
|
278
312
|
if (fs.existsSync(toolsSrc)) {
|
|
279
313
|
copyRecursive(toolsSrc, toolsDst);
|
|
280
314
|
manifest.installed.push('skills/tools');
|
|
@@ -286,7 +320,7 @@ async function runInstall() {
|
|
|
286
320
|
|
|
287
321
|
// Orchestration
|
|
288
322
|
const orchSrc = path.join(PKG_ROOT, 'skills', 'orchestration');
|
|
289
|
-
const orchDst = path.join(
|
|
323
|
+
const orchDst = path.join(configDir, 'skills', 'orchestration');
|
|
290
324
|
if (fs.existsSync(orchSrc)) {
|
|
291
325
|
copyRecursive(orchSrc, orchDst);
|
|
292
326
|
manifest.installed.push('skills/orchestration');
|
|
@@ -296,7 +330,7 @@ async function runInstall() {
|
|
|
296
330
|
// run_skill.js
|
|
297
331
|
const runSkillSrc = path.join(PKG_ROOT, 'skills', 'run_skill.js');
|
|
298
332
|
if (fs.existsSync(runSkillSrc)) {
|
|
299
|
-
const runSkillDst = path.join(
|
|
333
|
+
const runSkillDst = path.join(configDir, 'skills', 'run_skill.js');
|
|
300
334
|
fs.copyFileSync(runSkillSrc, runSkillDst);
|
|
301
335
|
manifest.installed.push('skills/run_skill.js');
|
|
302
336
|
ok('skill 执行器');
|
|
@@ -307,29 +341,30 @@ async function runInstall() {
|
|
|
307
341
|
if (fs.existsSync(promptSrc)) {
|
|
308
342
|
const files = fs.readdirSync(promptSrc);
|
|
309
343
|
files.forEach(f => {
|
|
310
|
-
fs.copyFileSync(path.join(promptSrc, f), path.join(
|
|
344
|
+
fs.copyFileSync(path.join(promptSrc, f), path.join(configDir, f));
|
|
311
345
|
manifest.installed.push(f);
|
|
312
346
|
});
|
|
313
347
|
ok('提示词优化模板');
|
|
314
348
|
}
|
|
315
349
|
|
|
316
350
|
// Memory directories
|
|
317
|
-
fs.mkdirSync(path.join(
|
|
318
|
-
fs.mkdirSync(path.join(
|
|
351
|
+
fs.mkdirSync(path.join(configDir, 'memory', 'patterns'), { recursive: true });
|
|
352
|
+
fs.mkdirSync(path.join(configDir, 'memory', 'scars'), { recursive: true });
|
|
319
353
|
manifest.installed.push('memory');
|
|
320
354
|
|
|
321
355
|
// Step 7: 生成斜杠命令
|
|
322
356
|
step(7, TOTAL_STEPS, '生成斜杠命令');
|
|
323
|
-
const commandsDir = path.join(
|
|
357
|
+
const commandsDir = path.join(configDir, 'commands');
|
|
324
358
|
fs.mkdirSync(commandsDir, { recursive: true });
|
|
325
359
|
|
|
360
|
+
const skillBase = `~/.${platformKey === 'codex' ? 'codex' : 'claude'}`;
|
|
326
361
|
const slashCommands = [
|
|
327
|
-
{ name: 'verify-security', desc: '扫描代码安全漏洞,检测危险模式', tools: 'Bash, Read, Glob, Grep', skillPath:
|
|
328
|
-
{ name: 'verify-module', desc: '检查目录结构、文档完整性', tools: 'Bash, Read, Glob, Grep', skillPath:
|
|
329
|
-
{ name: 'verify-change', desc: '分析 Git 变更,检测文档同步状态', tools: 'Bash, Read, Glob, Grep', skillPath:
|
|
330
|
-
{ name: 'verify-quality', desc: '检测复杂度、命名规范、代码质量', tools: 'Bash, Read, Glob, Grep', skillPath:
|
|
331
|
-
{ name: 'gen-docs', desc: '自动生成 README.md 和 DESIGN.md 骨架', tools: 'Bash, Read, Write, Glob, Grep', skillPath:
|
|
332
|
-
{ name: 'hi', desc: '反拒绝覆写:将最近一条模型拒绝输出替换为同意模板,强制继续执行', tools: 'Bash, Read', skillPath:
|
|
362
|
+
{ name: 'verify-security', desc: '扫描代码安全漏洞,检测危险模式', tools: 'Bash, Read, Glob, Grep', skillPath: `${skillBase}/skills/tools/verify-security/SKILL.md` },
|
|
363
|
+
{ name: 'verify-module', desc: '检查目录结构、文档完整性', tools: 'Bash, Read, Glob, Grep', skillPath: `${skillBase}/skills/tools/verify-module/SKILL.md` },
|
|
364
|
+
{ name: 'verify-change', desc: '分析 Git 变更,检测文档同步状态', tools: 'Bash, Read, Glob, Grep', skillPath: `${skillBase}/skills/tools/verify-change/SKILL.md` },
|
|
365
|
+
{ name: 'verify-quality', desc: '检测复杂度、命名规范、代码质量', tools: 'Bash, Read, Glob, Grep', skillPath: `${skillBase}/skills/tools/verify-quality/SKILL.md` },
|
|
366
|
+
{ name: 'gen-docs', desc: '自动生成 README.md 和 DESIGN.md 骨架', tools: 'Bash, Read, Write, Glob, Grep', skillPath: `${skillBase}/skills/tools/gen-docs/SKILL.md` },
|
|
367
|
+
{ name: 'hi', desc: '反拒绝覆写:将最近一条模型拒绝输出替换为同意模板,强制继续执行', tools: 'Bash, Read', skillPath: `${skillBase}/skills/tools/override-refusal/SKILL.md` },
|
|
333
368
|
];
|
|
334
369
|
|
|
335
370
|
slashCommands.forEach(cmd => {
|
|
@@ -355,21 +390,48 @@ async function runInstall() {
|
|
|
355
390
|
// 保存 manifest
|
|
356
391
|
fs.writeFileSync(path.join(backupDir, 'manifest.json'), JSON.stringify(manifest, null, 2));
|
|
357
392
|
|
|
358
|
-
|
|
393
|
+
ok(`${plat.name} 安装完成`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// ── 安装主流程 ──
|
|
397
|
+
async function runInstall() {
|
|
398
|
+
const platforms = await choosePlatforms();
|
|
399
|
+
|
|
400
|
+
// 确认安装
|
|
401
|
+
if (!autoYes) {
|
|
402
|
+
const { confirm } = require('@inquirer/prompts');
|
|
403
|
+
console.log('');
|
|
404
|
+
console.log(c.b(` 即将安装到: ${platforms.map(p => PLATFORMS[p].name).join(' + ')}`));
|
|
405
|
+
console.log('');
|
|
406
|
+
console.log(` ${c.cyn('Layer 4')} 输入优化层 提示词自动优化 Hook`);
|
|
407
|
+
console.log(` ${c.cyn('Layer 3')} 治理层 8阶段治理脊柱 + 8个治理智能体`);
|
|
408
|
+
console.log(` ${c.cyn('Layer 2')} 编排层 多Agent编排 Skill`);
|
|
409
|
+
console.log(` ${c.cyn('Layer 1')} 执行层 56篇专业知识库 + 5个校验关卡`);
|
|
410
|
+
console.log('');
|
|
411
|
+
|
|
412
|
+
const proceed = await confirm({ message: '确认安装?', default: true });
|
|
413
|
+
if (!proceed) { info('已取消'); process.exit(0); }
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
for (const p of platforms) {
|
|
417
|
+
installToPlatform(p);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// 完成总结
|
|
359
421
|
console.log('');
|
|
360
|
-
divider('
|
|
422
|
+
divider('全部安装完成');
|
|
361
423
|
console.log('');
|
|
362
424
|
console.log(c.b(' 已安装的四层增强系统:'));
|
|
363
425
|
console.log('');
|
|
364
426
|
console.log(` ${c.cyn('Layer 4')} 输入优化 ${c.grn('✔')} 提示词自动优化 Hook`);
|
|
365
427
|
console.log(` ${c.cyn('Layer 3')} 治理框架 ${c.grn('✔')} 8阶段治理 + 8个智能体`);
|
|
366
428
|
console.log(` ${c.cyn('Layer 2')} 多Agent ${c.grn('✔')} 编排 Skill`);
|
|
367
|
-
console.log(` ${c.cyn('Layer 1')} 知识库 ${c.grn('✔')}
|
|
429
|
+
console.log(` ${c.cyn('Layer 1')} 知识库 ${c.grn('✔')} 专业知识库 + 校验关卡`);
|
|
368
430
|
console.log('');
|
|
369
|
-
console.log(` ${c.
|
|
431
|
+
console.log(` ${c.b('目标平台:')} ${platforms.map(p => PLATFORMS[p].name).join(' + ')}`);
|
|
370
432
|
console.log(` ${c.d('卸载命令:')} npx code-yangzz --uninstall`);
|
|
371
433
|
console.log('');
|
|
372
|
-
console.log(c.grn(c.b('
|
|
434
|
+
console.log(c.grn(c.b(' 重启你的 AI 编码助手即可使用。')));
|
|
373
435
|
console.log('');
|
|
374
436
|
}
|
|
375
437
|
|