adspecs 0.1.19 → 0.1.21
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/.adspecs/feature.json +16 -16
- package/.adspecs/feature.yml +28 -28
- package/.adspecs/paths.json +17 -17
- package/.adspecs/templates/04-/345/211/215/347/253/257/345/212/237/350/203/275/350/256/276/350/256/241/346/250/241/346/235/277.md +1 -1
- package/.adspecs/templates/05-/345/220/216/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +613 -724
- package/.adspecs/templates/05b-/345/211/215/347/253/257/344/273/273/345/212/241/346/270/205/345/215/225/346/250/241/346/235/277.md +51 -51
- package/.claude-plugin/marketplace.json +23 -23
- package/.claude-plugin/plugin.json +18 -18
- package/.qoder-plugin/plugin.json +31 -31
- package/CLAUDE.md +1 -5
- package/INSTALL.md +3 -3
- package/README.md +395 -395
- package/bin/adspecs.js +129 -129
- package/hooks/commit-queue.js +245 -245
- package/hooks/hooks.json +63 -63
- package/hooks/session-start.js +44 -44
- package/hooks/wiki-queue.js +127 -127
- package/package.json +61 -61
- package/references/ant6-front-standard/index.md +99 -99
- package/references/antd-front-demo/public/mockServiceWorker.js +361 -361
- package/references/ecp-end-standard/index.md +63 -63
- package/references/python-end-standard/01-Python/345/220/216/347/253/257/347/274/226/347/240/201/350/247/204/350/214/203.md +372 -372
- package/references/python-end-standard/02-/346/225/260/346/215/256/345/272/223/350/256/276/350/256/241/344/270/216/344/275/277/347/224/250/350/247/204/350/214/203.md +226 -226
- package/references/python-end-standard/03-Celery/345/274/202/346/255/245/344/273/273/345/212/241/350/247/204/350/214/203.md +237 -237
- package/references/python-end-standard/04-Redis/344/275/277/347/224/250/350/247/204/350/214/203.md +231 -231
- package/scripts/postinstall.js +107 -107
- package/scripts/sync-version.js +105 -105
- package/skills/.claude/.wiki-update-queue +26 -26
- package/skills/adspecs-constitution/SKILL.md +157 -0
- package/skills/adspecs-export-word/SKILL.md +498 -498
- package/skills/adspecs-export-word/references/md-to-docx.js +862 -862
- package/skills/adspecs-export-word/references/package-lock.json +220 -220
- package/skills/adspecs-export-word/references/package.json +10 -10
- package/skills/adspecs-front-prototype/SKILL.md +405 -405
- package/skills/adspecs-front-spec/SKILL.md +4 -4
- package/skills/adspecs-front-tasks/SKILL.md +213 -173
- package/skills/adspecs-plan/SKILL.md +59 -69
- package/skills/adspecs-prd/SKILL.md +13 -5
- package/skills/adspecs-prd-to-demo/SKILL.md +532 -0
- package/skills/adspecs-tasks/SKILL.md +175 -204
- package/skills/adspecs-update-status/SKILL.md +382 -382
- package/skills/adspecs-utest/SKILL.md +107 -116
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/grill-me/agents/openai.yaml +5 -0
- package/skills/playwright-cli/SKILL.md +420 -0
- package/skills/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright-cli/references/video-recording.md +143 -0
- package/skills/playwright-trace/SKILL.md +171 -0
- package/skills/project-init/SKILL.md +93 -22
- package/skills/project-init/references/front-demo/.claude/settings.local.json +9 -0
- package/skills/wiki-update/SKILL.md +232 -232
- package/src/commands/doctor.js +197 -197
- package/src/commands/init.js +83 -83
- package/src/commands/plugin.js +165 -165
- package/src/commands/update.js +87 -87
- package/src/lib/area-scanner.js +129 -129
- package/src/lib/copier.js +104 -104
- package/src/lib/dir-utils.js +161 -133
- package/src/lib/json-merge.js +114 -114
- package/src/lib/paths-defaults.js +37 -37
- package/src/lib/prompts.js +428 -347
- package/src/lib/readme-gen.js +143 -143
- package/src/lib/report.js +338 -327
- package/src/lib/scaffolder.js +551 -518
- package/src/lib/short-name.js +36 -36
- package/src/utils.js +80 -80
- package/references/antd-front-demo/.env +0 -15
package/src/commands/plugin.js
CHANGED
|
@@ -1,165 +1,165 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { execSync } = require('child_process');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const fs = require('fs');
|
|
6
|
-
const chalk = require('chalk');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 插件根目录(即 adspecs/ 目录)
|
|
10
|
-
* bin/adspecs.js 在 bin/ 下,src/commands/ 在 src/commands/ 下
|
|
11
|
-
* 所以 __dirname/../../ 指向插件根目录
|
|
12
|
-
*/
|
|
13
|
-
const PLUGIN_DIR = path.resolve(__dirname, '../..');
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* 检查 claude CLI 是否可用
|
|
17
|
-
*/
|
|
18
|
-
function checkClaudeCli() {
|
|
19
|
-
try {
|
|
20
|
-
execSync('claude --version', { stdio: 'ignore' });
|
|
21
|
-
return true;
|
|
22
|
-
} catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 读取 plugin.json 获取插件名
|
|
29
|
-
*/
|
|
30
|
-
function getPluginName() {
|
|
31
|
-
const pluginJsonPath = path.join(PLUGIN_DIR, '.claude-plugin', 'plugin.json');
|
|
32
|
-
if (!fs.existsSync(pluginJsonPath)) {
|
|
33
|
-
throw new Error(`未找到插件清单文件: ${pluginJsonPath}`);
|
|
34
|
-
}
|
|
35
|
-
const pluginJson = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
|
|
36
|
-
return pluginJson.name || 'adspecs';
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 安装(注册)插件到 Claude Code
|
|
41
|
-
*
|
|
42
|
-
* Claude Code 的 marketplace 命令期望路径指向包含 `.claude-plugin/marketplace.json`
|
|
43
|
-
* 的目录,因此传入 PLUGIN_DIR(而非 PLUGIN_DIR/.claude-plugin)。
|
|
44
|
-
*
|
|
45
|
-
* @param {object} options
|
|
46
|
-
* @param {string} options.scope - 安装范围: user|project
|
|
47
|
-
*/
|
|
48
|
-
exports.install = async function install(options) {
|
|
49
|
-
const scope = options.scope || 'user';
|
|
50
|
-
const pluginName = getPluginName();
|
|
51
|
-
|
|
52
|
-
// marketplace.json 必须存在,否则无法注册
|
|
53
|
-
const marketplaceJson = path.join(PLUGIN_DIR, '.claude-plugin', 'marketplace.json');
|
|
54
|
-
if (!fs.existsSync(marketplaceJson)) {
|
|
55
|
-
throw new Error(`未找到 marketplace 清单: ${marketplaceJson}`);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
console.log(chalk.cyan('🔌 adspecs 插件注册'));
|
|
59
|
-
console.log('');
|
|
60
|
-
console.log(` 插件目录: ${PLUGIN_DIR}`);
|
|
61
|
-
console.log(` 插件名称: ${pluginName}`);
|
|
62
|
-
console.log(` 安装范围: ${scope}`);
|
|
63
|
-
console.log('');
|
|
64
|
-
|
|
65
|
-
// 1. 检查 claude CLI
|
|
66
|
-
if (!checkClaudeCli()) {
|
|
67
|
-
console.error(chalk.red('❌ 未检测到 claude CLI'));
|
|
68
|
-
console.error('');
|
|
69
|
-
console.error(' 请先安装 Claude Code:');
|
|
70
|
-
console.error(' npm install -g @anthropic-ai/claude-code');
|
|
71
|
-
console.error('');
|
|
72
|
-
console.error(' 或访问: https://claude.ai/code');
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// 2. 注册 marketplace
|
|
77
|
-
// 注意:传入 PLUGIN_DIR,claude 会去找 <PLUGIN_DIR>/.claude-plugin/marketplace.json
|
|
78
|
-
console.log(chalk.gray(' → 注册 marketplace...'));
|
|
79
|
-
let marketplaceRegistered = false;
|
|
80
|
-
try {
|
|
81
|
-
execSync(
|
|
82
|
-
`claude plugins marketplace add "${PLUGIN_DIR}" --scope ${scope}`,
|
|
83
|
-
{ stdio: 'pipe' }
|
|
84
|
-
);
|
|
85
|
-
console.log(chalk.green(' ✅ marketplace 注册成功'));
|
|
86
|
-
marketplaceRegistered = true;
|
|
87
|
-
} catch (err) {
|
|
88
|
-
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
89
|
-
const stdout = err.stdout ? err.stdout.toString() : '';
|
|
90
|
-
const combined = stderr + stdout;
|
|
91
|
-
if (combined.includes('already exists') || combined.includes('already registered')) {
|
|
92
|
-
console.log(chalk.yellow(' ⏭ marketplace 已存在,跳过'));
|
|
93
|
-
marketplaceRegistered = true; // 已存在也视为可用
|
|
94
|
-
} else {
|
|
95
|
-
// 把真实错误输出,方便排查,不再静默吞掉
|
|
96
|
-
console.log(chalk.red(` ❌ marketplace 注册失败: ${combined.trim() || err.message}`));
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// 3. 安装插件
|
|
101
|
-
// 只有 marketplace 注册成功(或已存在)时,才能按名称安装
|
|
102
|
-
console.log(chalk.gray(' → 安装插件...'));
|
|
103
|
-
if (!marketplaceRegistered) {
|
|
104
|
-
throw new Error('marketplace 未注册成功,无法按名称安装插件,请检查上方错误');
|
|
105
|
-
}
|
|
106
|
-
try {
|
|
107
|
-
execSync(`claude plugins install ${pluginName} --scope ${scope}`, {
|
|
108
|
-
stdio: 'pipe',
|
|
109
|
-
});
|
|
110
|
-
console.log(chalk.green(` ✅ ${pluginName} 插件安装成功`));
|
|
111
|
-
} catch (err) {
|
|
112
|
-
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
113
|
-
const stdout = err.stdout ? err.stdout.toString() : '';
|
|
114
|
-
const combined = stderr + stdout;
|
|
115
|
-
if (combined.includes('already installed')) {
|
|
116
|
-
console.log(chalk.yellow(` ⏭ ${pluginName} 已安装,跳过`));
|
|
117
|
-
} else {
|
|
118
|
-
throw new Error(`插件安装失败: ${combined.trim() || err.message}`);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
console.log('');
|
|
123
|
-
console.log(chalk.green.bold(`✅ adspecs 插件已注册到 Claude Code (scope=${scope})`));
|
|
124
|
-
console.log('');
|
|
125
|
-
console.log(' 现在可以在 Claude Code 中使用以下技能:');
|
|
126
|
-
console.log(' /adspecs-prd — 生成 PRD');
|
|
127
|
-
console.log(' /adspecs-plan — 后端系统设计');
|
|
128
|
-
console.log(' /adspecs-tasks — TDD 任务清单');
|
|
129
|
-
console.log(' /adspecs-utest — 生成单元测试');
|
|
130
|
-
console.log(' ...(共 19 个技能)');
|
|
131
|
-
console.log('');
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* 卸载插件
|
|
136
|
-
*
|
|
137
|
-
* @param {object} options
|
|
138
|
-
* @param {string} options.scope - 卸载范围: user|project
|
|
139
|
-
*/
|
|
140
|
-
exports.uninstall = async function uninstall(options) {
|
|
141
|
-
const scope = options.scope || 'user';
|
|
142
|
-
const pluginName = getPluginName();
|
|
143
|
-
|
|
144
|
-
console.log(chalk.cyan('🔌 adspecs 插件卸载'));
|
|
145
|
-
console.log('');
|
|
146
|
-
|
|
147
|
-
if (!checkClaudeCli()) {
|
|
148
|
-
console.error(chalk.red('❌ 未检测到 claude CLI'));
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
execSync(`claude plugins uninstall ${pluginName} --scope ${scope}`, {
|
|
154
|
-
stdio: 'pipe',
|
|
155
|
-
});
|
|
156
|
-
console.log(chalk.green(`✅ ${pluginName} 插件已卸载 (scope=${scope})`));
|
|
157
|
-
} catch (err) {
|
|
158
|
-
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
159
|
-
if (stderr.includes('not installed') || stderr.includes('not found')) {
|
|
160
|
-
console.log(chalk.yellow(`⏭ ${pluginName} 未安装,无需卸载`));
|
|
161
|
-
} else {
|
|
162
|
-
throw new Error(`插件卸载失败: ${stderr || err.message}`);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const chalk = require('chalk');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 插件根目录(即 adspecs/ 目录)
|
|
10
|
+
* bin/adspecs.js 在 bin/ 下,src/commands/ 在 src/commands/ 下
|
|
11
|
+
* 所以 __dirname/../../ 指向插件根目录
|
|
12
|
+
*/
|
|
13
|
+
const PLUGIN_DIR = path.resolve(__dirname, '../..');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* 检查 claude CLI 是否可用
|
|
17
|
+
*/
|
|
18
|
+
function checkClaudeCli() {
|
|
19
|
+
try {
|
|
20
|
+
execSync('claude --version', { stdio: 'ignore' });
|
|
21
|
+
return true;
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 读取 plugin.json 获取插件名
|
|
29
|
+
*/
|
|
30
|
+
function getPluginName() {
|
|
31
|
+
const pluginJsonPath = path.join(PLUGIN_DIR, '.claude-plugin', 'plugin.json');
|
|
32
|
+
if (!fs.existsSync(pluginJsonPath)) {
|
|
33
|
+
throw new Error(`未找到插件清单文件: ${pluginJsonPath}`);
|
|
34
|
+
}
|
|
35
|
+
const pluginJson = JSON.parse(fs.readFileSync(pluginJsonPath, 'utf8'));
|
|
36
|
+
return pluginJson.name || 'adspecs';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 安装(注册)插件到 Claude Code
|
|
41
|
+
*
|
|
42
|
+
* Claude Code 的 marketplace 命令期望路径指向包含 `.claude-plugin/marketplace.json`
|
|
43
|
+
* 的目录,因此传入 PLUGIN_DIR(而非 PLUGIN_DIR/.claude-plugin)。
|
|
44
|
+
*
|
|
45
|
+
* @param {object} options
|
|
46
|
+
* @param {string} options.scope - 安装范围: user|project
|
|
47
|
+
*/
|
|
48
|
+
exports.install = async function install(options) {
|
|
49
|
+
const scope = options.scope || 'user';
|
|
50
|
+
const pluginName = getPluginName();
|
|
51
|
+
|
|
52
|
+
// marketplace.json 必须存在,否则无法注册
|
|
53
|
+
const marketplaceJson = path.join(PLUGIN_DIR, '.claude-plugin', 'marketplace.json');
|
|
54
|
+
if (!fs.existsSync(marketplaceJson)) {
|
|
55
|
+
throw new Error(`未找到 marketplace 清单: ${marketplaceJson}`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
console.log(chalk.cyan('🔌 adspecs 插件注册'));
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log(` 插件目录: ${PLUGIN_DIR}`);
|
|
61
|
+
console.log(` 插件名称: ${pluginName}`);
|
|
62
|
+
console.log(` 安装范围: ${scope}`);
|
|
63
|
+
console.log('');
|
|
64
|
+
|
|
65
|
+
// 1. 检查 claude CLI
|
|
66
|
+
if (!checkClaudeCli()) {
|
|
67
|
+
console.error(chalk.red('❌ 未检测到 claude CLI'));
|
|
68
|
+
console.error('');
|
|
69
|
+
console.error(' 请先安装 Claude Code:');
|
|
70
|
+
console.error(' npm install -g @anthropic-ai/claude-code');
|
|
71
|
+
console.error('');
|
|
72
|
+
console.error(' 或访问: https://claude.ai/code');
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 2. 注册 marketplace
|
|
77
|
+
// 注意:传入 PLUGIN_DIR,claude 会去找 <PLUGIN_DIR>/.claude-plugin/marketplace.json
|
|
78
|
+
console.log(chalk.gray(' → 注册 marketplace...'));
|
|
79
|
+
let marketplaceRegistered = false;
|
|
80
|
+
try {
|
|
81
|
+
execSync(
|
|
82
|
+
`claude plugins marketplace add "${PLUGIN_DIR}" --scope ${scope}`,
|
|
83
|
+
{ stdio: 'pipe' }
|
|
84
|
+
);
|
|
85
|
+
console.log(chalk.green(' ✅ marketplace 注册成功'));
|
|
86
|
+
marketplaceRegistered = true;
|
|
87
|
+
} catch (err) {
|
|
88
|
+
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
89
|
+
const stdout = err.stdout ? err.stdout.toString() : '';
|
|
90
|
+
const combined = stderr + stdout;
|
|
91
|
+
if (combined.includes('already exists') || combined.includes('already registered')) {
|
|
92
|
+
console.log(chalk.yellow(' ⏭ marketplace 已存在,跳过'));
|
|
93
|
+
marketplaceRegistered = true; // 已存在也视为可用
|
|
94
|
+
} else {
|
|
95
|
+
// 把真实错误输出,方便排查,不再静默吞掉
|
|
96
|
+
console.log(chalk.red(` ❌ marketplace 注册失败: ${combined.trim() || err.message}`));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 3. 安装插件
|
|
101
|
+
// 只有 marketplace 注册成功(或已存在)时,才能按名称安装
|
|
102
|
+
console.log(chalk.gray(' → 安装插件...'));
|
|
103
|
+
if (!marketplaceRegistered) {
|
|
104
|
+
throw new Error('marketplace 未注册成功,无法按名称安装插件,请检查上方错误');
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
execSync(`claude plugins install ${pluginName} --scope ${scope}`, {
|
|
108
|
+
stdio: 'pipe',
|
|
109
|
+
});
|
|
110
|
+
console.log(chalk.green(` ✅ ${pluginName} 插件安装成功`));
|
|
111
|
+
} catch (err) {
|
|
112
|
+
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
113
|
+
const stdout = err.stdout ? err.stdout.toString() : '';
|
|
114
|
+
const combined = stderr + stdout;
|
|
115
|
+
if (combined.includes('already installed')) {
|
|
116
|
+
console.log(chalk.yellow(` ⏭ ${pluginName} 已安装,跳过`));
|
|
117
|
+
} else {
|
|
118
|
+
throw new Error(`插件安装失败: ${combined.trim() || err.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
console.log('');
|
|
123
|
+
console.log(chalk.green.bold(`✅ adspecs 插件已注册到 Claude Code (scope=${scope})`));
|
|
124
|
+
console.log('');
|
|
125
|
+
console.log(' 现在可以在 Claude Code 中使用以下技能:');
|
|
126
|
+
console.log(' /adspecs-prd — 生成 PRD');
|
|
127
|
+
console.log(' /adspecs-plan — 后端系统设计');
|
|
128
|
+
console.log(' /adspecs-tasks — TDD 任务清单');
|
|
129
|
+
console.log(' /adspecs-utest — 生成单元测试');
|
|
130
|
+
console.log(' ...(共 19 个技能)');
|
|
131
|
+
console.log('');
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* 卸载插件
|
|
136
|
+
*
|
|
137
|
+
* @param {object} options
|
|
138
|
+
* @param {string} options.scope - 卸载范围: user|project
|
|
139
|
+
*/
|
|
140
|
+
exports.uninstall = async function uninstall(options) {
|
|
141
|
+
const scope = options.scope || 'user';
|
|
142
|
+
const pluginName = getPluginName();
|
|
143
|
+
|
|
144
|
+
console.log(chalk.cyan('🔌 adspecs 插件卸载'));
|
|
145
|
+
console.log('');
|
|
146
|
+
|
|
147
|
+
if (!checkClaudeCli()) {
|
|
148
|
+
console.error(chalk.red('❌ 未检测到 claude CLI'));
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
execSync(`claude plugins uninstall ${pluginName} --scope ${scope}`, {
|
|
154
|
+
stdio: 'pipe',
|
|
155
|
+
});
|
|
156
|
+
console.log(chalk.green(`✅ ${pluginName} 插件已卸载 (scope=${scope})`));
|
|
157
|
+
} catch (err) {
|
|
158
|
+
const stderr = err.stderr ? err.stderr.toString() : '';
|
|
159
|
+
if (stderr.includes('not installed') || stderr.includes('not found')) {
|
|
160
|
+
console.log(chalk.yellow(`⏭ ${pluginName} 未安装,无需卸载`));
|
|
161
|
+
} else {
|
|
162
|
+
throw new Error(`插件卸载失败: ${stderr || err.message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
};
|
package/src/commands/update.js
CHANGED
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { execSync, spawn } = require('child_process');
|
|
4
|
-
const chalk = require('chalk');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
const fs = require('fs');
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* adspecs update 命令
|
|
10
|
-
*
|
|
11
|
-
* 便捷命令:一条命令完成 adspecs 升级 + Claude Code 插件刷新。
|
|
12
|
-
*
|
|
13
|
-
* 流程:
|
|
14
|
-
* 1. 检查当前版本
|
|
15
|
-
* 2. 执行 `npm install -g adspecs@latest`(或 `npm update -g adspecs`)
|
|
16
|
-
* 3. postinstall 钩子会自动刷新 Claude Code 插件注册
|
|
17
|
-
* 4. 显示升级前后版本
|
|
18
|
-
*/
|
|
19
|
-
module.exports = async function update(options) {
|
|
20
|
-
const pluginDir = path.resolve(__dirname, '../..');
|
|
21
|
-
const pkgPath = path.join(pluginDir, 'package.json');
|
|
22
|
-
|
|
23
|
-
// 读取升级前版本
|
|
24
|
-
let oldVersion = 'unknown';
|
|
25
|
-
try {
|
|
26
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
27
|
-
oldVersion = pkg.version;
|
|
28
|
-
} catch {
|
|
29
|
-
// ignore
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
console.log(chalk.cyan('🔄 adspecs 升级'));
|
|
33
|
-
console.log('');
|
|
34
|
-
console.log(` 当前版本: ${chalk.yellow(oldVersion)}`);
|
|
35
|
-
console.log(` 目标版本: ${options.version || 'latest'}`);
|
|
36
|
-
console.log('');
|
|
37
|
-
|
|
38
|
-
// 确定要安装的版本
|
|
39
|
-
const targetVersion = options.version ? `adspecs@${options.version}` : 'adspecs@latest';
|
|
40
|
-
|
|
41
|
-
// 执行 npm install -g
|
|
42
|
-
console.log(chalk.gray(` → 执行: npm install -g ${targetVersion}`));
|
|
43
|
-
console.log('');
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
// 使用 spawn 以实时显示 npm 输出
|
|
47
|
-
await new Promise((resolve, reject) => {
|
|
48
|
-
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
49
|
-
const child = spawn(npmCmd, ['install', '-g', targetVersion], {
|
|
50
|
-
stdio: 'inherit',
|
|
51
|
-
shell: true,
|
|
52
|
-
});
|
|
53
|
-
child.on('close', (code) => {
|
|
54
|
-
if (code === 0) resolve();
|
|
55
|
-
else reject(new Error(`npm install 退出码: ${code}`));
|
|
56
|
-
});
|
|
57
|
-
child.on('error', reject);
|
|
58
|
-
});
|
|
59
|
-
} catch (err) {
|
|
60
|
-
console.error('');
|
|
61
|
-
console.error(chalk.red(`❌ 升级失败: ${err.message}`));
|
|
62
|
-
console.error('');
|
|
63
|
-
console.error(' 请检查网络连接或手动执行:');
|
|
64
|
-
console.error(' npm install -g adspecs@latest');
|
|
65
|
-
process.exit(1);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// 读取升级后版本
|
|
69
|
-
let newVersion = 'unknown';
|
|
70
|
-
try {
|
|
71
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
72
|
-
newVersion = pkg.version;
|
|
73
|
-
} catch {
|
|
74
|
-
// ignore
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
console.log('');
|
|
78
|
-
if (oldVersion === newVersion) {
|
|
79
|
-
console.log(chalk.green(`✅ 已是最新版本 (${newVersion})`));
|
|
80
|
-
} else {
|
|
81
|
-
console.log(chalk.green.bold(`✅ 升级完成: ${oldVersion} → ${newVersion}`));
|
|
82
|
-
}
|
|
83
|
-
console.log('');
|
|
84
|
-
console.log(' Claude Code 插件注册已通过 postinstall 钩子自动刷新。');
|
|
85
|
-
console.log(` 验证: ${chalk.gray('adspecs --version')}`);
|
|
86
|
-
console.log('');
|
|
87
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { execSync, spawn } = require('child_process');
|
|
4
|
+
const chalk = require('chalk');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* adspecs update 命令
|
|
10
|
+
*
|
|
11
|
+
* 便捷命令:一条命令完成 adspecs 升级 + Claude Code 插件刷新。
|
|
12
|
+
*
|
|
13
|
+
* 流程:
|
|
14
|
+
* 1. 检查当前版本
|
|
15
|
+
* 2. 执行 `npm install -g adspecs@latest`(或 `npm update -g adspecs`)
|
|
16
|
+
* 3. postinstall 钩子会自动刷新 Claude Code 插件注册
|
|
17
|
+
* 4. 显示升级前后版本
|
|
18
|
+
*/
|
|
19
|
+
module.exports = async function update(options) {
|
|
20
|
+
const pluginDir = path.resolve(__dirname, '../..');
|
|
21
|
+
const pkgPath = path.join(pluginDir, 'package.json');
|
|
22
|
+
|
|
23
|
+
// 读取升级前版本
|
|
24
|
+
let oldVersion = 'unknown';
|
|
25
|
+
try {
|
|
26
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
27
|
+
oldVersion = pkg.version;
|
|
28
|
+
} catch {
|
|
29
|
+
// ignore
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(chalk.cyan('🔄 adspecs 升级'));
|
|
33
|
+
console.log('');
|
|
34
|
+
console.log(` 当前版本: ${chalk.yellow(oldVersion)}`);
|
|
35
|
+
console.log(` 目标版本: ${options.version || 'latest'}`);
|
|
36
|
+
console.log('');
|
|
37
|
+
|
|
38
|
+
// 确定要安装的版本
|
|
39
|
+
const targetVersion = options.version ? `adspecs@${options.version}` : 'adspecs@latest';
|
|
40
|
+
|
|
41
|
+
// 执行 npm install -g
|
|
42
|
+
console.log(chalk.gray(` → 执行: npm install -g ${targetVersion}`));
|
|
43
|
+
console.log('');
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
// 使用 spawn 以实时显示 npm 输出
|
|
47
|
+
await new Promise((resolve, reject) => {
|
|
48
|
+
const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
49
|
+
const child = spawn(npmCmd, ['install', '-g', targetVersion], {
|
|
50
|
+
stdio: 'inherit',
|
|
51
|
+
shell: true,
|
|
52
|
+
});
|
|
53
|
+
child.on('close', (code) => {
|
|
54
|
+
if (code === 0) resolve();
|
|
55
|
+
else reject(new Error(`npm install 退出码: ${code}`));
|
|
56
|
+
});
|
|
57
|
+
child.on('error', reject);
|
|
58
|
+
});
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error('');
|
|
61
|
+
console.error(chalk.red(`❌ 升级失败: ${err.message}`));
|
|
62
|
+
console.error('');
|
|
63
|
+
console.error(' 请检查网络连接或手动执行:');
|
|
64
|
+
console.error(' npm install -g adspecs@latest');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// 读取升级后版本
|
|
69
|
+
let newVersion = 'unknown';
|
|
70
|
+
try {
|
|
71
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
72
|
+
newVersion = pkg.version;
|
|
73
|
+
} catch {
|
|
74
|
+
// ignore
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log('');
|
|
78
|
+
if (oldVersion === newVersion) {
|
|
79
|
+
console.log(chalk.green(`✅ 已是最新版本 (${newVersion})`));
|
|
80
|
+
} else {
|
|
81
|
+
console.log(chalk.green.bold(`✅ 升级完成: ${oldVersion} → ${newVersion}`));
|
|
82
|
+
}
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log(' Claude Code 插件注册已通过 postinstall 钩子自动刷新。');
|
|
85
|
+
console.log(` 验证: ${chalk.gray('adspecs --version')}`);
|
|
86
|
+
console.log('');
|
|
87
|
+
};
|