@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.
Files changed (2) hide show
  1. package/bin/cli.js +142 -44
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -1,50 +1,148 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const command = process.argv[2];
4
-
5
- switch (command) {
6
- case 'init':
7
- require('../lib/init.js')();
8
- break;
9
- case 'update':
10
- require('../lib/update.js')();
11
- break;
12
- case 'version':
13
- require('../lib/version.js')();
14
- break;
15
- case 'logout': {
16
- const ui = require('../lib/ui.js');
17
- const { clearCachedToken } = require('../lib/auth.js');
18
- if (clearCachedToken()) {
19
- ui.success('Token removed from ~/.claudeflow/config.json');
20
- } else {
21
- ui.info('No cached token found.');
22
- }
23
- break;
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
- case '--version':
26
- case '-v':
27
- console.log(`claudeflow v${require('../package.json').version}`);
28
- break;
29
- case '--help':
30
- case '-h':
31
- case undefined: {
32
- const ui = require('../lib/ui.js');
33
- ui.banner();
34
- console.log(` ${ui.BOLD}Usage:${ui.RESET}`);
35
- console.log(` claudeflow ${ui.CYAN}init${ui.RESET} Install the latest template files`);
36
- console.log(` claudeflow ${ui.CYAN}update${ui.RESET} Update templates to latest version`);
37
- console.log(` claudeflow ${ui.CYAN}version${ui.RESET} Show version info`);
38
- console.log(` claudeflow ${ui.CYAN}logout${ui.RESET} Remove cached GitHub token`);
39
- console.log('');
40
- console.log(` ${ui.BOLD}Options:${ui.RESET}`);
41
- console.log(` --version, -v Show CLI version`);
42
- console.log(` --help, -h Show this help`);
43
- console.log('');
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
- default:
47
- console.error(`Unknown command: ${command}`);
48
- console.error('Run "claudeflow --help" for usage.');
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.53",
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"