@axiomatic-labs/claudeflow 2.0.53 → 2.0.55
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 +142 -44
- package/package.json +1 -1
package/bin/cli.js
CHANGED
|
@@ -1,50 +1,148 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
3
|
+
// npm shim: downloads the Go binary if needed, then delegates all commands to it.
|
|
4
|
+
|
|
5
|
+
const { execSync, execFileSync, spawn } = require('child_process');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
const https = require('https');
|
|
10
|
+
|
|
11
|
+
const OWNER = 'axiomatic-labs';
|
|
12
|
+
const REPO = 'axiomatic-cli';
|
|
13
|
+
const BIN_DIR = path.join(os.homedir(), '.claudeflow', 'bin');
|
|
14
|
+
const isWindows = os.platform() === 'win32';
|
|
15
|
+
const BIN_PATH = path.join(BIN_DIR, isWindows ? 'claudeflow.exe' : 'claudeflow');
|
|
16
|
+
const VERSION_PATH = path.join(os.homedir(), '.claudeflow', 'binary-version');
|
|
17
|
+
|
|
18
|
+
// Detect platform: darwin-arm64, darwin-amd64, linux-amd64, windows-amd64
|
|
19
|
+
function getPlatformBinary() {
|
|
20
|
+
const platform = os.platform(); // darwin, linux, win32
|
|
21
|
+
const arch = os.arch(); // arm64, x64
|
|
22
|
+
const goArch = arch === 'x64' ? 'amd64' : arch;
|
|
23
|
+
const goPlatform = platform === 'win32' ? 'windows' : platform;
|
|
24
|
+
const ext = platform === 'win32' ? '.exe' : '';
|
|
25
|
+
return `claudeflow-${goPlatform}-${goArch}${ext}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fetchUrl(url, headers = {}) {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const mod = url.startsWith('https') ? https : require('http');
|
|
31
|
+
mod.get(url, { headers: { 'User-Agent': 'claudeflow-cli', ...headers } }, (res) => {
|
|
32
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
33
|
+
return fetchUrl(res.headers.location, {}).then(resolve).catch(reject);
|
|
34
|
+
}
|
|
35
|
+
if (res.statusCode !== 200) {
|
|
36
|
+
let body = '';
|
|
37
|
+
res.on('data', (d) => body += d);
|
|
38
|
+
res.on('end', () => reject(new Error(`HTTP ${res.statusCode}: ${body.slice(0, 200)}`)));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const chunks = [];
|
|
42
|
+
res.on('data', (d) => chunks.push(d));
|
|
43
|
+
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
44
|
+
}).on('error', reject);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function getToken() {
|
|
49
|
+
// Try gh CLI
|
|
50
|
+
try {
|
|
51
|
+
const raw = execSync('gh auth token', { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
52
|
+
if (raw) return raw;
|
|
53
|
+
} catch {}
|
|
54
|
+
|
|
55
|
+
// Try env var
|
|
56
|
+
if (process.env.GITHUB_TOKEN) return process.env.GITHUB_TOKEN;
|
|
57
|
+
|
|
58
|
+
// Try cached
|
|
59
|
+
try {
|
|
60
|
+
const cfg = JSON.parse(fs.readFileSync(path.join(os.homedir(), '.claudeflow', 'config.json'), 'utf-8'));
|
|
61
|
+
if (cfg.githubToken) return cfg.githubToken;
|
|
62
|
+
} catch {}
|
|
63
|
+
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function downloadBinary(token) {
|
|
68
|
+
const ui = require('../lib/ui.js');
|
|
69
|
+
|
|
70
|
+
if (!token) {
|
|
71
|
+
ui.error('GitHub authentication required. Run with a valid GITHUB_TOKEN or gh CLI auth.');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
ui.step('Fetching latest release...');
|
|
76
|
+
|
|
77
|
+
const releaseData = await fetchUrl(
|
|
78
|
+
`https://api.github.com/repos/${OWNER}/${REPO}/releases/latest`,
|
|
79
|
+
{ Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json' }
|
|
80
|
+
);
|
|
81
|
+
const release = JSON.parse(releaseData.toString());
|
|
82
|
+
|
|
83
|
+
const binaryName = getPlatformBinary();
|
|
84
|
+
const asset = release.assets.find((a) => a.name === binaryName);
|
|
85
|
+
if (!asset) {
|
|
86
|
+
ui.error(`No binary found for your platform: ${binaryName}`);
|
|
87
|
+
ui.info(`Available: ${release.assets.map((a) => a.name).join(', ')}`);
|
|
88
|
+
process.exit(1);
|
|
24
89
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
break;
|
|
90
|
+
|
|
91
|
+
ui.step(`Downloading ${release.tag_name} (${binaryName})...`);
|
|
92
|
+
|
|
93
|
+
const binaryData = await fetchUrl(
|
|
94
|
+
`https://api.github.com/repos/${OWNER}/${REPO}/releases/assets/${asset.id}`,
|
|
95
|
+
{ Authorization: `Bearer ${token}`, Accept: 'application/octet-stream' }
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
99
|
+
fs.writeFileSync(BIN_PATH, binaryData, { mode: 0o755 });
|
|
100
|
+
fs.writeFileSync(VERSION_PATH, release.tag_name + '\n');
|
|
101
|
+
|
|
102
|
+
ui.success(`Claudeflow ${release.tag_name} installed to ~/.claudeflow/bin/`);
|
|
103
|
+
return release.tag_name;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function ensureBinary() {
|
|
107
|
+
if (fs.existsSync(BIN_PATH)) {
|
|
108
|
+
return; // Binary exists
|
|
45
109
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
110
|
+
|
|
111
|
+
const ui = require('../lib/ui.js');
|
|
112
|
+
ui.banner();
|
|
113
|
+
ui.step('First run — downloading Claudeflow binary...');
|
|
114
|
+
|
|
115
|
+
const token = getToken();
|
|
116
|
+
await downloadBinary(token);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function main() {
|
|
120
|
+
const args = process.argv.slice(2);
|
|
121
|
+
|
|
122
|
+
// These commands need the Go binary
|
|
123
|
+
await ensureBinary();
|
|
124
|
+
|
|
125
|
+
// Delegate to Go binary with transparent I/O
|
|
126
|
+
const child = spawn(BIN_PATH, args, {
|
|
127
|
+
stdio: 'inherit',
|
|
128
|
+
env: process.env,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
child.on('exit', (code) => {
|
|
132
|
+
process.exit(code || 0);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
child.on('error', (err) => {
|
|
136
|
+
if (err.code === 'ENOENT') {
|
|
137
|
+
console.error('Claudeflow binary not found. Try reinstalling: npx @axiomatic-labs/claudeflow');
|
|
138
|
+
} else {
|
|
139
|
+
console.error(`Failed to start claudeflow: ${err.message}`);
|
|
140
|
+
}
|
|
49
141
|
process.exit(1);
|
|
142
|
+
});
|
|
50
143
|
}
|
|
144
|
+
|
|
145
|
+
main().catch((err) => {
|
|
146
|
+
console.error(err.message || err);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.55",
|
|
4
4
|
"description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeflow": "./bin/cli.js"
|