@chinhae/oxyccg 1.0.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/cli.js +28 -0
- package/lib/installer.js +151 -0
- package/package.json +24 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const installer = require('../lib/installer');
|
|
5
|
+
|
|
6
|
+
program
|
|
7
|
+
.name('oxyccg')
|
|
8
|
+
.description('OxyCCG - 多模型协作开发工作流安装工具')
|
|
9
|
+
.version('1.0.0');
|
|
10
|
+
|
|
11
|
+
program
|
|
12
|
+
.command('install')
|
|
13
|
+
.description('安装所有组件')
|
|
14
|
+
.option('--only <component>', '只安装指定组件: npm|cunzhi|superpowers|skills|config')
|
|
15
|
+
.option('--skip <components>', '跳过指定组件(逗号分隔)')
|
|
16
|
+
.action((options) => installer.install(options));
|
|
17
|
+
|
|
18
|
+
program
|
|
19
|
+
.command('update')
|
|
20
|
+
.description('更新配置文件到最新版本')
|
|
21
|
+
.action(() => installer.update());
|
|
22
|
+
|
|
23
|
+
program
|
|
24
|
+
.command('uninstall')
|
|
25
|
+
.description('卸载自定义配置')
|
|
26
|
+
.action(() => installer.uninstall());
|
|
27
|
+
|
|
28
|
+
program.parse();
|
package/lib/installer.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const ora = require('ora');
|
|
7
|
+
|
|
8
|
+
const HOME = os.homedir();
|
|
9
|
+
const CLAUDE_DIR = path.join(HOME, '.claude');
|
|
10
|
+
const CONFIG_REPO = 'https://github.com/LFT-OXY/oxyccg-config.git';
|
|
11
|
+
|
|
12
|
+
const NPM_PACKAGES = [
|
|
13
|
+
'@fission-ai/openspec@latest',
|
|
14
|
+
'ccg-workflow'
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
async function install(options = {}) {
|
|
18
|
+
const only = options.only;
|
|
19
|
+
const skip = options.skip ? options.skip.split(',') : [];
|
|
20
|
+
|
|
21
|
+
console.log(chalk.cyan('\n🚀 OxyCCG 安装开始\n'));
|
|
22
|
+
|
|
23
|
+
const steps = [
|
|
24
|
+
{ name: 'npm', fn: installNpmPackages, label: 'npm 包 (OpenSpec, CCG)' },
|
|
25
|
+
{ name: 'cunzhi', fn: installCunzhi, label: '寸止' },
|
|
26
|
+
{ name: 'superpowers', fn: installSuperpowers, label: 'Superpowers 插件' },
|
|
27
|
+
{ name: 'skills', fn: installSkills, label: 'GuDaStudio Skills' },
|
|
28
|
+
{ name: 'config', fn: installConfig, label: '自定义工作流配置' }
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
for (const step of steps) {
|
|
32
|
+
if (only && step.name !== only) continue;
|
|
33
|
+
if (skip.includes(step.name)) {
|
|
34
|
+
console.log(chalk.yellow(`⏭️ 跳过 ${step.label}`));
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const spinner = ora(`安装 ${step.label}...`).start();
|
|
39
|
+
try {
|
|
40
|
+
await step.fn();
|
|
41
|
+
spinner.succeed(`${step.label} ✓`);
|
|
42
|
+
} catch (err) {
|
|
43
|
+
spinner.fail(`${step.label} 失败: ${err.message}`);
|
|
44
|
+
if (step.name === 'npm') throw err;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(chalk.green('\n✅ 安装完成!'));
|
|
49
|
+
console.log(chalk.dim('使用 /ccg:oxyccg <任务> 开始开发\n'));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function installNpmPackages() {
|
|
53
|
+
execSync(`npm install -g ${NPM_PACKAGES.join(' ')}`, { stdio: 'pipe' });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function installCunzhi() {
|
|
57
|
+
const platform = os.platform();
|
|
58
|
+
|
|
59
|
+
if (platform === 'darwin') {
|
|
60
|
+
try {
|
|
61
|
+
execSync('brew tap imhuso/cunzhi && brew install cunzhi', { stdio: 'pipe' });
|
|
62
|
+
} catch {
|
|
63
|
+
const arch = os.arch() === 'arm64' ? 'aarch64' : 'x86_64';
|
|
64
|
+
const url = `https://github.com/imhuso/cunzhi/releases/latest/download/cunzhi-cli-darwin-${arch}.tar.gz`;
|
|
65
|
+
const binDir = path.join(HOME, '.local', 'bin');
|
|
66
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
67
|
+
execSync(`curl -fsSL "${url}" | tar -xz -C "${binDir}"`, { stdio: 'pipe' });
|
|
68
|
+
console.log(chalk.dim(`\n 已安装到 ${binDir},请确保该目录在 PATH 中`));
|
|
69
|
+
}
|
|
70
|
+
} else if (platform === 'linux') {
|
|
71
|
+
const binDir = path.join(HOME, '.local', 'bin');
|
|
72
|
+
fs.mkdirSync(binDir, { recursive: true });
|
|
73
|
+
execSync(`curl -fsSL "https://github.com/imhuso/cunzhi/releases/latest/download/cunzhi-cli-linux-x86_64.tar.gz" | tar -xz -C "${binDir}"`, { stdio: 'pipe' });
|
|
74
|
+
} else {
|
|
75
|
+
throw new Error(`不支持的平台: ${platform},请手动安装寸止`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function installSuperpowers() {
|
|
80
|
+
try {
|
|
81
|
+
execSync('claude /plugin install superpowers@superpowers-marketplace', { stdio: 'pipe' });
|
|
82
|
+
} catch {
|
|
83
|
+
console.log(chalk.yellow('\n ⚠️ 自动安装失败,请手动运行:'));
|
|
84
|
+
console.log(chalk.dim(' claude /plugin install superpowers@superpowers-marketplace'));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function installSkills() {
|
|
89
|
+
const tmpDir = path.join(os.tmpdir(), 'gudaskills-' + Date.now());
|
|
90
|
+
try {
|
|
91
|
+
execSync(`git clone --depth 1 https://github.com/GuDaStudio/skills.git "${tmpDir}"`, { stdio: 'pipe' });
|
|
92
|
+
execSync(`cd "${tmpDir}" && chmod +x install.sh && ./install.sh --user --all`, { stdio: 'pipe' });
|
|
93
|
+
} finally {
|
|
94
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function installConfig() {
|
|
99
|
+
const tmpDir = path.join(os.tmpdir(), 'oxyccg-config-' + Date.now());
|
|
100
|
+
try {
|
|
101
|
+
execSync(`git clone --depth 1 ${CONFIG_REPO} "${tmpDir}"`, { stdio: 'pipe' });
|
|
102
|
+
|
|
103
|
+
const srcCommands = path.join(tmpDir, 'commands', 'ccg');
|
|
104
|
+
const destCommands = path.join(CLAUDE_DIR, 'commands', 'ccg');
|
|
105
|
+
|
|
106
|
+
if (fs.existsSync(srcCommands)) {
|
|
107
|
+
fs.mkdirSync(destCommands, { recursive: true });
|
|
108
|
+
const files = fs.readdirSync(srcCommands);
|
|
109
|
+
for (const file of files) {
|
|
110
|
+
fs.copyFileSync(
|
|
111
|
+
path.join(srcCommands, file),
|
|
112
|
+
path.join(destCommands, file)
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
} finally {
|
|
117
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function update() {
|
|
122
|
+
console.log(chalk.cyan('\n🔄 更新配置...\n'));
|
|
123
|
+
const spinner = ora('拉取最新配置...').start();
|
|
124
|
+
try {
|
|
125
|
+
installConfig();
|
|
126
|
+
spinner.succeed('配置已更新');
|
|
127
|
+
console.log(chalk.green('\n✅ 更新完成!\n'));
|
|
128
|
+
} catch (err) {
|
|
129
|
+
spinner.fail(`更新失败: ${err.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function uninstall() {
|
|
134
|
+
console.log(chalk.cyan('\n🗑️ 卸载 OxyCCG 配置...\n'));
|
|
135
|
+
|
|
136
|
+
const files = ['oxyccg.md', 'oxyccg-plan.md', 'oxyccg-dev.md', 'oxyccg-ship.md'];
|
|
137
|
+
const dir = path.join(CLAUDE_DIR, 'commands', 'ccg');
|
|
138
|
+
|
|
139
|
+
for (const file of files) {
|
|
140
|
+
const p = path.join(dir, file);
|
|
141
|
+
if (fs.existsSync(p)) {
|
|
142
|
+
fs.unlinkSync(p);
|
|
143
|
+
console.log(chalk.dim(` 删除 ${file}`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
console.log(chalk.green('\n✅ 卸载完成'));
|
|
148
|
+
console.log(chalk.dim('npm 包和插件请手动卸载\n'));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
module.exports = { install, update, uninstall };
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chinhae/oxyccg",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OxyCCG - Claude+Codex+Gemini 多模型协作开发工作流一键安装",
|
|
5
|
+
"bin": {
|
|
6
|
+
"oxyccg": "./bin/cli.js"
|
|
7
|
+
},
|
|
8
|
+
"files": ["bin", "lib"],
|
|
9
|
+
"keywords": ["claude", "codex", "gemini", "ai", "workflow", "multi-model"],
|
|
10
|
+
"author": "chinhae",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/LFT-OXY/oxyccg"
|
|
15
|
+
},
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=18.0.0"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"chalk": "^4.1.2",
|
|
21
|
+
"commander": "^11.1.0",
|
|
22
|
+
"ora": "^5.4.1"
|
|
23
|
+
}
|
|
24
|
+
}
|