@mfjjs/ruflo-setup 0.2.6 → 0.2.8

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/src/status.js CHANGED
@@ -40,12 +40,11 @@ function fileExists(p) {
40
40
  }
41
41
  }
42
42
 
43
- // Flatten npm/pnpm --json list result into a name->version map (1 level deep).
43
+ // Flatten pnpm --json list result into a name->version map (1 level deep).
44
44
  function buildPkgMap(jsonText) {
45
45
  const map = {};
46
46
  try {
47
47
  const parsed = JSON.parse(jsonText || '{}');
48
- // npm list -g returns an array with one element, pnpm returns an object
49
48
  const root = Array.isArray(parsed) ? parsed[0] : parsed;
50
49
  const deps = root?.dependencies ?? {};
51
50
  for (const [name, info] of Object.entries(deps)) {
@@ -60,13 +59,7 @@ function buildPkgMap(jsonText) {
60
59
  return map;
61
60
  }
62
61
 
63
- // Tries npm list -g first, falls back to pnpm list -g.
64
62
  function getGlobalPkgMap() {
65
- const npmRes = spawn('npm', ['list', '-g', '--depth=1', '--json']);
66
- if (npmRes.status === 0 && npmRes.stdout) {
67
- const m = buildPkgMap(npmRes.stdout);
68
- if (Object.keys(m).length > 0) return m;
69
- }
70
63
  const pnpmRes = spawn('pnpm', ['list', '-g', '--depth=1', '--json']);
71
64
  if (pnpmRes.status === 0 && pnpmRes.stdout) {
72
65
  return buildPkgMap(pnpmRes.stdout);
@@ -95,7 +88,7 @@ function checkLayer0() {
95
88
  const ver = (claudeRes.stdout || '').trim();
96
89
  lines.push(` ${OK} Claude Code CLI${ver ? ` ${ver}` : ''}`); ok += 1;
97
90
  } else {
98
- lines.push(` ${MISS} Claude Code CLI (install: npm install -g @anthropic-ai/claude-code)`);
91
+ lines.push(` ${MISS} Claude Code CLI (install: pnpm add -g @anthropic-ai/claude-code)`);
99
92
  }
100
93
 
101
94
  if (process.env.ANTHROPIC_API_KEY) {
@@ -113,7 +106,7 @@ function checkLayer1(pkgMap) {
113
106
  for (const name of ['ruflo', '@mfjjs/ruflo-setup']) {
114
107
  const ver = pkgMap[name];
115
108
  if (ver) { lines.push(` ${OK} ${name}${typeof ver === 'string' ? `@${ver}` : ''}`); ok += 1; }
116
- else { lines.push(` ${MISS} ${name} (install: npm install -g ${name})`); }
109
+ else { lines.push(` ${MISS} ${name} (install: pnpm add -g ${name})`); }
117
110
  }
118
111
  return { lines, ok, total: 2 };
119
112
  }
@@ -268,7 +261,7 @@ export async function runStatus({ cwd, packageRoot }) {
268
261
 
269
262
  const layers = [
270
263
  { title: 'Layer 0: Prerequisites', result: checkLayer0() },
271
- { title: 'Layer 1: Global npm Packages', result: checkLayer1(pkgMap) },
264
+ { title: 'Layer 1: Global Packages', result: checkLayer1(pkgMap) },
272
265
  { title: 'Layer 2: Optional Packages (WASM/ML) — enables AI features', result: checkLayer2(pkgMap) },
273
266
  { title: 'Layer 3: MCP Servers (.mcp.json)', result: checkLayer3(mcpJson) },
274
267
  { title: 'Layer 4: MCP Tool Groups', result: checkLayer4(mcpJson) },
package/src/utils.js CHANGED
@@ -1,120 +1,120 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- import readline from 'node:readline';
4
-
5
- export function pathExists(filePath) {
6
- return fs.existsSync(filePath);
7
- }
8
-
9
- export function readJsonSafe(filePath, fallbackValue = {}) {
10
- if (!pathExists(filePath)) {
11
- return fallbackValue;
12
- }
13
- try {
14
- return JSON.parse(fs.readFileSync(filePath, 'utf8'));
15
- } catch {
16
- return fallbackValue;
17
- }
18
- }
19
-
20
- export function writeJson(filePath, value) {
21
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
22
- fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
23
- }
24
-
25
- export function copyFileSync(src, dest) {
26
- fs.mkdirSync(path.dirname(dest), { recursive: true });
27
- fs.copyFileSync(src, dest);
28
- }
29
-
30
- export async function confirm(question) {
31
- const rl = readline.createInterface({
32
- input: process.stdin,
33
- output: process.stdout
34
- });
35
-
36
- const answer = await new Promise((resolve) => {
37
- rl.question(question, resolve);
38
- });
39
-
40
- rl.close();
41
- return /^[Yy]$/.test((answer || '').trim());
42
- }
43
-
44
- export function parseArgs(argv) {
45
- const flags = {
46
- force: false,
47
- dryRun: false,
48
- yes: false,
49
- noHooks: false,
50
- skipInit: false,
51
- verbose: false,
52
- command: 'setup'
53
- };
54
-
55
- const positional = [];
56
- for (const item of argv) {
57
- if (item === '--force' || item === '-f') flags.force = true;
58
- else if (item === '--dry-run') flags.dryRun = true;
59
- else if (item === '--yes' || item === '-y') flags.yes = true;
60
- else if (item === '--no-hooks') flags.noHooks = true;
61
- else if (item === '--skip-init') flags.skipInit = true;
62
- else if (item === '--verbose') flags.verbose = true;
63
- else positional.push(item);
64
- }
65
-
66
- if (positional.length > 0) {
67
- flags.command = positional[0];
68
- }
69
-
70
- return flags;
71
- }
72
-
73
- export function toPlatformMcpConfig(platform) {
74
- const isWindows = platform === 'win32';
75
- const command = isWindows ? 'cmd' : 'pnpm';
76
- const pnpmArgs = isWindows ? ['/c', 'pnpm', 'dlx'] : ['dlx'];
77
-
78
- const makeArgs = (pkg, extraArgs) => {
79
- return [...pnpmArgs, pkg, ...extraArgs];
80
- };
81
-
82
- return {
83
- mcpServers: {
84
- 'claude-flow': {
85
- command,
86
- args: makeArgs('@claude-flow/cli@latest', ['mcp', 'start']),
87
- env: {
88
- npm_config_update_notifier: 'false',
89
- CLAUDE_FLOW_MODE: 'v3',
90
- CLAUDE_FLOW_HOOKS_ENABLED: 'true',
91
- CLAUDE_FLOW_TOPOLOGY: 'hierarchical-mesh',
92
- CLAUDE_FLOW_MAX_AGENTS: '15',
93
- CLAUDE_FLOW_MEMORY_BACKEND: 'hybrid',
94
- MCP_GROUP_SECURITY: 'true',
95
- MCP_GROUP_BROWSER: 'true',
96
- MCP_GROUP_NEURAL: 'true',
97
- MCP_GROUP_AGENTIC_FLOW: 'true'
98
- },
99
- autoStart: false
100
- },
101
- 'ruv-swarm': {
102
- command,
103
- args: makeArgs('ruv-swarm', ['mcp', 'start']),
104
- env: {
105
- npm_config_update_notifier: 'false'
106
- },
107
- optional: true
108
- },
109
- 'flow-nexus': {
110
- command,
111
- args: makeArgs('flow-nexus@latest', ['mcp', 'start']),
112
- env: {
113
- npm_config_update_notifier: 'false'
114
- },
115
- optional: true,
116
- requiresAuth: true
117
- }
118
- }
119
- };
120
- }
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import readline from 'node:readline';
4
+
5
+ export function pathExists(filePath) {
6
+ return fs.existsSync(filePath);
7
+ }
8
+
9
+ export function readJsonSafe(filePath, fallbackValue = {}) {
10
+ if (!pathExists(filePath)) {
11
+ return fallbackValue;
12
+ }
13
+ try {
14
+ return JSON.parse(fs.readFileSync(filePath, 'utf8'));
15
+ } catch {
16
+ return fallbackValue;
17
+ }
18
+ }
19
+
20
+ export function writeJson(filePath, value) {
21
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
22
+ fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
23
+ }
24
+
25
+ export function copyFileSync(src, dest) {
26
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
27
+ fs.copyFileSync(src, dest);
28
+ }
29
+
30
+ export async function confirm(question) {
31
+ const rl = readline.createInterface({
32
+ input: process.stdin,
33
+ output: process.stdout
34
+ });
35
+
36
+ const answer = await new Promise((resolve) => {
37
+ rl.question(question, resolve);
38
+ });
39
+
40
+ rl.close();
41
+ return /^[Yy]$/.test((answer || '').trim());
42
+ }
43
+
44
+ export function parseArgs(argv) {
45
+ const flags = {
46
+ force: false,
47
+ dryRun: false,
48
+ yes: false,
49
+ noHooks: false,
50
+ skipInit: false,
51
+ verbose: false,
52
+ command: 'setup'
53
+ };
54
+
55
+ const positional = [];
56
+ for (const item of argv) {
57
+ if (item === '--force' || item === '-f') flags.force = true;
58
+ else if (item === '--dry-run') flags.dryRun = true;
59
+ else if (item === '--yes' || item === '-y') flags.yes = true;
60
+ else if (item === '--no-hooks') flags.noHooks = true;
61
+ else if (item === '--skip-init') flags.skipInit = true;
62
+ else if (item === '--verbose') flags.verbose = true;
63
+ else positional.push(item);
64
+ }
65
+
66
+ if (positional.length > 0) {
67
+ flags.command = positional[0];
68
+ }
69
+
70
+ return flags;
71
+ }
72
+
73
+ export function toPlatformMcpConfig(platform) {
74
+ const isWindows = platform === 'win32';
75
+ const command = isWindows ? 'cmd' : 'npx';
76
+ const npxArgs = isWindows ? ['/c', 'npx', '-y'] : ['-y'];
77
+
78
+ const makeArgs = (pkg, extraArgs) => {
79
+ return [...npxArgs, pkg, ...extraArgs];
80
+ };
81
+
82
+ return {
83
+ mcpServers: {
84
+ 'claude-flow': {
85
+ command,
86
+ args: makeArgs('@claude-flow/cli@latest', ['mcp', 'start']),
87
+ env: {
88
+ npm_config_update_notifier: 'false',
89
+ CLAUDE_FLOW_MODE: 'v3',
90
+ CLAUDE_FLOW_HOOKS_ENABLED: 'true',
91
+ CLAUDE_FLOW_TOPOLOGY: 'hierarchical-mesh',
92
+ CLAUDE_FLOW_MAX_AGENTS: '15',
93
+ CLAUDE_FLOW_MEMORY_BACKEND: 'hybrid',
94
+ MCP_GROUP_SECURITY: 'true',
95
+ MCP_GROUP_BROWSER: 'true',
96
+ MCP_GROUP_NEURAL: 'true',
97
+ MCP_GROUP_AGENTIC_FLOW: 'true'
98
+ },
99
+ autoStart: false
100
+ },
101
+ 'ruv-swarm': {
102
+ command,
103
+ args: makeArgs('ruv-swarm', ['mcp', 'start']),
104
+ env: {
105
+ npm_config_update_notifier: 'false'
106
+ },
107
+ optional: true
108
+ },
109
+ 'flow-nexus': {
110
+ command,
111
+ args: makeArgs('flow-nexus@latest', ['mcp', 'start']),
112
+ env: {
113
+ npm_config_update_notifier: 'false'
114
+ },
115
+ optional: true,
116
+ requiresAuth: true
117
+ }
118
+ }
119
+ };
120
+ }
@@ -1,90 +1,92 @@
1
- # /ruflo-setup
2
-
3
- Set up Ruflo + Claude Flow V3 in the current project directory.
4
-
5
- ## Requirements
6
-
7
- - Node.js 20+
8
- - pnpm 10.32.1+ installed and available on PATH
9
-
10
- Quickest pnpm install by platform:
11
-
12
- ```bash
13
- # Windows (recommended)
14
- winget install -e --id pnpm.pnpm
15
-
16
- # macOS (recommended)
17
- brew install pnpm
18
-
19
- # Linux (recommended)
20
- curl -fsSL https://get.pnpm.io/install.sh | sh -
21
- ```
22
-
23
- Alternative (all platforms with recent Node.js):
24
-
25
- ```bash
26
- corepack enable
27
- corepack prepare pnpm@latest --activate
28
- ```
29
-
30
- ## What this does
31
-
32
- Runs `pnpm add -g @mfjjs/ruflo-setup` then `ruflo-setup` which:
33
-
34
- 1. Runs `pnpm add -g ruflo@latest` then `ruflo init --full` to install:
35
- - `.claude/settings.json` with hooks, permissions, and Claude Flow config
36
- - `.claude/helpers/` — hook-handler, statusline, auto-memory scripts
37
- - `.claude/agents/` — 120+ agent definitions
38
- - `.claude/skills/` — 30+ skill definitions
39
- - `.claude/commands/` — slash commands
40
- 2. Writes a platform-aware `.mcp.json` (MCP server registration for claude-flow, ruv-swarm, flow-nexus)
41
- 3. Installs a global `SessionStart` hook in `~/.claude/settings.json` that warns when Ruflo is not configured
42
- 4. May refresh `~/.claude/commands/ruflo-setup.md` from the latest packaged template when differences are detected
43
-
44
- ## Options
45
-
46
- ### cleanup
47
-
48
- Removes all Ruflo-related packages from the **npm** global registry (does not touch pnpm globals).
49
-
50
- Packages removed: `ruflo`, `@mfjjs/ruflo-setup`, `ruflo-setup`, `claude-flow`, `@claude-flow/cli`, `ruv-swarm`
51
-
52
- ## Instructions for Claude
53
-
54
- When the user runs /ruflo-setup:
55
-
56
- ### Default (no arguments) — install
57
-
58
- 1. Confirm the current working directory with the user
59
- 2. Check if `.mcp.json` already exists if so, warn and ask before overwriting
60
- 3. Check pnpm version is at least 10.32.1:
61
- ```bash
62
- pnpm --version
63
- ```
64
- If the version is lower than 10.32.1, stop and tell the user to upgrade pnpm before continuing.
65
- 4. Run the setup CLI and capture output to detect whether pnpm modified anything:
66
- ```bash
67
- pnpm add -g @mfjjs/ruflo-setup
68
- pnpm add -g ruflo@latest 2>&1 | tee /tmp/ruflo-pnpm-add.log
69
- ```
70
- After the `pnpm add -g ruflo@latest` step, inspect the output. If pnpm installed or updated any packages (i.e. the output does NOT contain "Already up to date" or an equivalent no-change message), run:
71
- ```bash
72
- pnpm approve-builds -g --all
73
- ```
74
- Skip `approve-builds` if nothing changed.
75
- 5. Run the setup tool:
76
- ```bash
77
- ruflo-setup
78
- ```
79
- 6. Report what was installed and remind the user to restart Claude Code to load the new MCP servers
80
-
81
- ### cleanup
82
-
83
- When the user runs `/ruflo-setup cleanup`:
84
-
85
- 1. Warn the user that this will remove Ruflo packages from the **npm** global registry and ask for confirmation
86
- 2. On confirmation, run:
87
- ```bash
88
- ruflo-setup cleanup
89
- ```
90
- 3. Report which packages were removed and which were not found (not found is fine — it means they were already clean)
1
+ # /ruflo-setup
2
+
3
+ Set up Ruflo + Claude Flow V3 in the current project directory.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js 20+
8
+ - pnpm 10.32.1+ installed and available on PATH
9
+
10
+ Quickest pnpm install by platform:
11
+
12
+ ```bash
13
+ # Windows (recommended)
14
+ winget install -e --id pnpm.pnpm
15
+
16
+ # macOS (recommended)
17
+ brew install pnpm
18
+
19
+ # Linux (recommended)
20
+ curl -fsSL https://get.pnpm.io/install.sh | sh -
21
+ ```
22
+
23
+ Alternative (all platforms with recent Node.js):
24
+
25
+ ```bash
26
+ corepack enable
27
+ corepack prepare pnpm@latest --activate
28
+ ```
29
+
30
+ ## What this does
31
+
32
+ Runs `pnpm add -g @mfjjs/ruflo-setup` then `ruflo-setup` which:
33
+
34
+ 1. Runs `pnpm add -g ruflo@latest` then `ruflo init --full` to install:
35
+ - `.claude/settings.json` with hooks, permissions, and Claude Flow config
36
+ - `.claude/helpers/` — hook-handler, statusline, auto-memory scripts
37
+ - `.claude/agents/` — 120+ agent definitions
38
+ - `.claude/skills/` — 30+ skill definitions
39
+ - `.claude/commands/` — slash commands
40
+ 2. Writes a platform-aware `.mcp.json` (MCP server registration for claude-flow, ruv-swarm, flow-nexus; servers invoked via `npx` for cross-platform compatibility)
41
+ 3. Adds `.mcp.json` and `.claude/settings.json` to the project's `.gitignore`
42
+ 4. Installs a global `SessionStart` hook in `~/.claude/settings.json` that warns when Ruflo is not configured
43
+ 5. May refresh `~/.claude/commands/ruflo-setup.md` from the latest packaged template when differences are detected
44
+
45
+ ## Options
46
+
47
+ ### cleanup
48
+
49
+ Removes all Ruflo-related packages from the **npm** global registry (does not touch pnpm globals).
50
+
51
+ Packages removed: `ruflo`, `@mfjjs/ruflo-setup`, `ruflo-setup`, `claude-flow`, `@claude-flow/cli`, `ruv-swarm`
52
+
53
+ ## Instructions for Claude
54
+
55
+ When the user runs /ruflo-setup:
56
+
57
+ ### Default (no arguments) — install
58
+
59
+ 1. Confirm the current working directory with the user
60
+ 2. Check if `.mcp.json` already exists if so, warn and ask before overwriting
61
+ 3. Check pnpm version is at least 10.32.1:
62
+ ```bash
63
+ pnpm --version
64
+ ```
65
+ If the version is lower than 10.32.1, stop and tell the user to upgrade pnpm before continuing.
66
+ 4. Run the setup CLI and capture output to detect whether pnpm modified anything:
67
+ ```bash
68
+ pnpm add -g @mfjjs/ruflo-setup
69
+ pnpm add -g ruflo@latest 2>&1 | tee /tmp/ruflo-pnpm-add.log
70
+ ```
71
+ After the `pnpm add -g ruflo@latest` step, inspect the output. If pnpm installed or updated any packages (i.e. the output does NOT contain "Already up to date" or an equivalent no-change message), run:
72
+ ```bash
73
+ pnpm approve-builds -g --all
74
+ ```
75
+ Skip `approve-builds` if nothing changed.
76
+ 5. Run the setup tool:
77
+ ```bash
78
+ ruflo-setup
79
+ ```
80
+ 6. Ensure `.mcp.json` and `.claude/settings.json` are in the project's `.gitignore` (ruflo-setup does this automatically, but verify if using `--skip-init`)
81
+ 7. Report what was installed and remind the user to restart Claude Code to load the new MCP servers
82
+
83
+ ### cleanup
84
+
85
+ When the user runs `/ruflo-setup cleanup`:
86
+
87
+ 1. Warn the user that this will remove Ruflo packages from the **npm** global registry and ask for confirmation
88
+ 2. On confirmation, run:
89
+ ```bash
90
+ ruflo-setup cleanup
91
+ ```
92
+ 3. Report which packages were removed and which were not found (not found is fine — it means they were already clean)