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.
Files changed (2) hide show
  1. package/bin/install.js +136 -74
  2. 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
- --uninstall 卸载 code-yangzz
83
- --help, -h 显示帮助
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 ${c.d('# 交互式安装')}
87
- npx code-yangzz -y ${c.d('# 零配置一键安装')}
88
- npx code-yangzz --uninstall ${c.d('# 卸载并恢复备份')}
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 runUninstall() {
96
- const claudeDir = path.join(HOME, '.claude');
97
- const backupDir = path.join(claudeDir, '.yangzz-backup');
98
- const manifestPath = path.join(backupDir, 'manifest.json');
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 (!fs.existsSync(manifestPath)) {
101
- fail('未找到安装记录,无法卸载');
102
- process.exit(1);
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(claudeDir, f);
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(claudeDir, f);
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
- async function runInstall() {
128
- const claudeDir = path.join(HOME, '.claude');
129
- const backupDir = path.join(claudeDir, '.yangzz-backup');
130
- const manifest = { version: VERSION, installed: [], backups: [], timestamp: new Date().toISOString() };
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
- const TOTAL_STEPS = 7;
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
- const proceed = await confirm({ message: '确认安装?', default: true });
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 = ['CLAUDE.md', 'settings.json'];
188
+ const filesToBackup = [plat.instructionFile, 'settings.json'];
155
189
  filesToBackup.forEach(f => {
156
- const src = path.join(claudeDir, f);
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: 安装 CLAUDE.md(融合版)
165
- step(2, TOTAL_STEPS, '安装融合版 CLAUDE.md');
166
- const claudeMdSrc = path.join(PKG_ROOT, 'config', 'CLAUDE.md');
167
- const claudeMdDst = path.join(claudeDir, 'CLAUDE.md');
168
- fs.copyFileSync(claudeMdSrc, claudeMdDst);
169
- manifest.installed.push('CLAUDE.md');
170
- ok('CLAUDE.md');
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(claudeDir, 'settings.json');
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(claudeDir, 'hooks');
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(claudeDir, 'hooks');
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(claudeDir, 'agents');
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(claudeDir, 'skills', 'meta-theory');
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(claudeDir, 'skills', 'agent-teams');
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(claudeDir, 'skills', 'domains');
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(claudeDir, 'skills', 'tools');
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(claudeDir, 'skills', 'orchestration');
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(claudeDir, 'skills', 'run_skill.js');
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(claudeDir, f));
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(claudeDir, 'memory', 'patterns'), { recursive: true });
318
- fs.mkdirSync(path.join(claudeDir, 'memory', 'scars'), { recursive: true });
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(claudeDir, 'commands');
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: '~/.claude/skills/tools/verify-security/SKILL.md' },
328
- { name: 'verify-module', desc: '检查目录结构、文档完整性', tools: 'Bash, Read, Glob, Grep', skillPath: '~/.claude/skills/tools/verify-module/SKILL.md' },
329
- { name: 'verify-change', desc: '分析 Git 变更,检测文档同步状态', tools: 'Bash, Read, Glob, Grep', skillPath: '~/.claude/skills/tools/verify-change/SKILL.md' },
330
- { name: 'verify-quality', desc: '检测复杂度、命名规范、代码质量', tools: 'Bash, Read, Glob, Grep', skillPath: '~/.claude/skills/tools/verify-quality/SKILL.md' },
331
- { name: 'gen-docs', desc: '自动生成 README.md 和 DESIGN.md 骨架', tools: 'Bash, Read, Write, Glob, Grep', skillPath: '~/.claude/skills/tools/gen-docs/SKILL.md' },
332
- { name: 'hi', desc: '反拒绝覆写:将最近一条模型拒绝输出替换为同意模板,强制继续执行', tools: 'Bash, Read', skillPath: '~/.claude/skills/tools/override-refusal/SKILL.md' },
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.d('备份位置:')} ${backupDir}`);
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(' 重启 Claude Code 即可使用。')));
434
+ console.log(c.grn(c.b(' 重启你的 AI 编码助手即可使用。')));
373
435
  console.log('');
374
436
  }
375
437
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code-yangzz",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Claude Code / Codex CLI 四层增强系统:输入优化 + 治理框架 + 多Agent编排 + 专业知识库 | by yangzz",
5
5
  "keywords": [
6
6
  "claude",