@axiomatic-labs/claudeflow 2.12.144 → 2.12.146

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 CHANGED
@@ -1,42 +1,112 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // npx entry point: handles install/update and version commands directly.
4
- // No Go binary — downloads ZIP and extracts skill files to disk.
3
+ // Claudeflow CLI entry point.
4
+ //
5
+ // Dual role:
6
+ // 1. Package manager: `claudeflow install` / `version` (npx-friendly).
7
+ // 2. Daily driver wrapper: `claudeflow [claude-args...]` spawns
8
+ // `claude` with `--append-system-prompt-file` auto-injected when
9
+ // an `append-system-prompt.md` is present in the project tree.
10
+ //
11
+ // Dispatch rules:
12
+ // - First arg is a known subcommand → run it.
13
+ // - First arg starts with `-` (a flag) → passthrough to claude.
14
+ // - No args:
15
+ // * If cwd (or an ancestor) is inside a Claudeflow project
16
+ // (has `.claudeflow/`), passthrough to claude.
17
+ // * Otherwise, run `install` to match the npx-first-time path.
5
18
 
19
+ const fs = require('fs');
6
20
  const path = require('path');
7
21
 
8
- async function main() {
9
- const args = process.argv.slice(2);
10
- const command = args[0] || '';
22
+ const SUBCOMMANDS = new Set(['install', 'version', '--version', '-v', 'help', '--help', '-h']);
23
+
24
+ function inClaudeflowProject(startDir) {
25
+ let dir = path.resolve(startDir);
26
+ const root = path.parse(dir).root;
27
+ while (true) {
28
+ if (fs.existsSync(path.join(dir, '.claudeflow'))) return true;
29
+ if (dir === root) return false;
30
+ const parent = path.dirname(dir);
31
+ if (parent === dir) return false;
32
+ dir = parent;
33
+ }
34
+ }
11
35
 
36
+ async function runSubcommand(command) {
12
37
  switch (command) {
13
- case '':
14
38
  case 'install': {
15
39
  const install = require('../lib/install.js');
16
40
  await install();
17
- break;
41
+ return;
18
42
  }
19
43
  case 'version':
20
44
  case '--version':
21
45
  case '-v': {
22
46
  const version = require('../lib/version.js');
23
47
  await version();
24
- break;
48
+ return;
25
49
  }
50
+ case 'help':
51
+ case '--help':
52
+ case '-h':
26
53
  default: {
27
54
  const ui = require('../lib/ui.js');
28
55
  ui.banner();
29
- console.log(' Usage: npx @axiomatic-labs/claudeflow [command]');
56
+ console.log(' Usage: claudeflow [command | claude-args...]');
30
57
  console.log('');
31
- console.log(' Commands:');
32
- console.log(` ${ui.CYAN}install${ui.RESET} Install or update Claudeflow (default)`);
58
+ console.log(' Claudeflow commands:');
59
+ console.log(` ${ui.CYAN}install${ui.RESET} Install or update Claudeflow in the current project`);
33
60
  console.log(` ${ui.CYAN}version${ui.RESET} Show version info`);
61
+ console.log(` ${ui.CYAN}help${ui.RESET} Show this message`);
34
62
  console.log('');
35
- break;
63
+ console.log(' Any other arguments are passed through to `claude`, with');
64
+ console.log(' `--append-system-prompt-file ./append-system-prompt.md`');
65
+ console.log(' auto-injected when the project ships that file.');
66
+ console.log('');
67
+ console.log(' Examples:');
68
+ console.log(' claudeflow # open claude in current project');
69
+ console.log(' claudeflow --continue # continue last claude session');
70
+ console.log(' claudeflow -p "fix bug" # one-shot prompt');
71
+ console.log(' claudeflow install # install or update claudeflow');
72
+ console.log('');
73
+ console.log(' Env:');
74
+ console.log(' CLAUDEFLOW_NO_SYSTEM_PROMPT=1 skip the append-system-prompt flag');
75
+ return;
36
76
  }
37
77
  }
38
78
  }
39
79
 
80
+ async function main() {
81
+ const args = process.argv.slice(2);
82
+ const first = args[0];
83
+
84
+ if (first && SUBCOMMANDS.has(first)) {
85
+ await runSubcommand(first);
86
+ return;
87
+ }
88
+
89
+ if (first && first.startsWith('-')) {
90
+ // Flags → passthrough to claude
91
+ require('../lib/claude-passthrough.js').run(args);
92
+ return;
93
+ }
94
+
95
+ if (!first) {
96
+ // No args: passthrough inside a claudeflow project, else install
97
+ if (inClaudeflowProject(process.cwd())) {
98
+ require('../lib/claude-passthrough.js').run([]);
99
+ } else {
100
+ await runSubcommand('install');
101
+ }
102
+ return;
103
+ }
104
+
105
+ // Unknown subcommand-looking arg → passthrough (claude owns its own
106
+ // subcommands like `claude mcp`, `claude config`, etc.)
107
+ require('../lib/claude-passthrough.js').run(args);
108
+ }
109
+
40
110
  main().catch((err) => {
41
111
  console.error(err.message || err);
42
112
  process.exit(1);
@@ -0,0 +1,60 @@
1
+ // Passthrough wrapper: spawns `claude` inheriting stdio, with
2
+ // `--append-system-prompt-file <path>` auto-injected when the project
3
+ // ships an `append-system-prompt.md` at the repo root (walking upward
4
+ // from cwd).
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const { spawn } = require('child_process');
9
+
10
+ const APPEND_PROMPT_FILENAME = 'append-system-prompt.md';
11
+
12
+ function findAppendPromptFile(startDir) {
13
+ let dir = path.resolve(startDir);
14
+ const root = path.parse(dir).root;
15
+ while (true) {
16
+ const candidate = path.join(dir, APPEND_PROMPT_FILENAME);
17
+ if (fs.existsSync(candidate)) return candidate;
18
+ if (dir === root) return null;
19
+ const parent = path.dirname(dir);
20
+ if (parent === dir) return null;
21
+ dir = parent;
22
+ }
23
+ }
24
+
25
+ function userAlreadySetAppend(userArgs) {
26
+ return userArgs.some(
27
+ (a) => a === '--append-system-prompt-file' || a === '--append-system-prompt'
28
+ );
29
+ }
30
+
31
+ function run(userArgs) {
32
+ const cwd = process.cwd();
33
+ const disabled = process.env.CLAUDEFLOW_NO_SYSTEM_PROMPT === '1';
34
+ const promptPath = disabled ? null : findAppendPromptFile(cwd);
35
+
36
+ const args = [];
37
+ if (promptPath && !userAlreadySetAppend(userArgs)) {
38
+ args.push('--append-system-prompt-file', promptPath);
39
+ }
40
+ args.push(...userArgs);
41
+
42
+ const child = spawn('claude', args, { stdio: 'inherit' });
43
+ child.on('error', (err) => {
44
+ if (err.code === 'ENOENT') {
45
+ console.error(
46
+ 'claudeflow: `claude` binary not found in PATH.\n' +
47
+ 'Install Claude Code: npm i -g @anthropic-ai/claude-code'
48
+ );
49
+ process.exit(127);
50
+ }
51
+ console.error('claudeflow: failed to launch claude —', err.message);
52
+ process.exit(1);
53
+ });
54
+ child.on('exit', (code, signal) => {
55
+ if (signal) process.kill(process.pid, signal);
56
+ else process.exit(code ?? 0);
57
+ });
58
+ }
59
+
60
+ module.exports = { run, findAppendPromptFile };
package/lib/install.js CHANGED
@@ -261,12 +261,42 @@ async function run() {
261
261
 
262
262
  ui.done(`Claudeflow ${version} installed.`);
263
263
 
264
+ // Ensure the `claudeflow` shell command is available
265
+ const cliStatus = ensureGlobalCli(version);
266
+
264
267
  // Getting started guide with project detection
265
- showGettingStarted(cwd);
268
+ showGettingStarted(cwd, cliStatus);
266
269
  }
267
270
  }
268
271
 
269
- function showGettingStarted(cwd) {
272
+ function ensureGlobalCli(version) {
273
+ // Returns { available: boolean, autoInstalled: boolean, error?: string }
274
+ if (commandExists('claudeflow')) {
275
+ return { available: true, autoInstalled: false };
276
+ }
277
+
278
+ if (process.env.CLAUDEFLOW_SKIP_GLOBAL_INSTALL === '1') {
279
+ return { available: false, autoInstalled: false, error: 'skipped' };
280
+ }
281
+
282
+ console.log('');
283
+ console.log(` ${ui.DIM}Installing claudeflow CLI globally so it is available as a shell command...${ui.RESET}`);
284
+ try {
285
+ execSync(`npm install -g @axiomatic-labs/claudeflow@${version}`, {
286
+ stdio: ['ignore', 'pipe', 'pipe'],
287
+ timeout: 120000,
288
+ });
289
+ if (commandExists('claudeflow')) {
290
+ return { available: true, autoInstalled: true };
291
+ }
292
+ return { available: false, autoInstalled: false, error: 'installed but not on PATH' };
293
+ } catch (err) {
294
+ const msg = err?.stderr?.toString?.() || err?.message || String(err);
295
+ return { available: false, autoInstalled: false, error: msg.split('\n')[0] };
296
+ }
297
+ }
298
+
299
+ function showGettingStarted(cwd, cliStatus = { available: false, autoInstalled: false }) {
270
300
  const MANIFESTS = ['package.json', 'pyproject.toml', 'Gemfile', 'go.mod', 'Cargo.toml', 'composer.json'];
271
301
  const SKIP_DIRS = new Set(['node_modules', 'vendor', '__pycache__', 'dist', 'build', '.next', '.nuxt', '.output', '.claude']);
272
302
 
@@ -289,7 +319,20 @@ function showGettingStarted(cwd) {
289
319
 
290
320
  console.log(` ${ui.BOLD}Getting started:${ui.RESET}`);
291
321
  console.log('');
292
- console.log(` 1. Run ${ui.CYAN}claude${ui.RESET} to start Claude Code`);
322
+
323
+ const startCommand = cliStatus.available ? 'claudeflow' : 'claude';
324
+ if (cliStatus.autoInstalled) {
325
+ console.log(` ${ui.DIM}✓ Installed ${ui.CYAN}claudeflow${ui.RESET}${ui.DIM} globally — available as a shell command.${ui.RESET}`);
326
+ console.log('');
327
+ } else if (!cliStatus.available) {
328
+ console.log(` ${ui.DIM}To get the ${ui.CYAN}claudeflow${ui.RESET}${ui.DIM} shell command, run:${ui.RESET}`);
329
+ console.log(` ${ui.CYAN}npm i -g @axiomatic-labs/claudeflow${ui.RESET}`);
330
+ if (cliStatus.error && cliStatus.error !== 'skipped') {
331
+ console.log(` ${ui.DIM}(auto-install failed: ${cliStatus.error})${ui.RESET}`);
332
+ }
333
+ console.log('');
334
+ }
335
+ console.log(` 1. Run ${ui.CYAN}${startCommand}${ui.RESET} to start Claude Code`);
293
336
 
294
337
  if (isGreenfield) {
295
338
  console.log(` 2. Type ${ui.CYAN}/claudeflow-install${ui.RESET} to start setup`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axiomatic-labs/claudeflow",
3
- "version": "2.12.144",
3
+ "version": "2.12.146",
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"