@mfjjs/ruflo-setup 0.2.5 β 0.2.6
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/CHANGELOG.md +7 -0
- package/README.md +19 -2
- package/package.json +1 -1
- package/src/cli.js +21 -1
- package/src/setup.js +95 -18
- package/templates/ruflo-setup.md +38 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.2.6](///compare/v0.2.5...v0.2.6) (2026-03-20)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **cli:** add cleanup command to remove Ruflo packages from npm global registry. 5151c70
|
|
11
|
+
|
|
5
12
|
### [0.2.5](///compare/v0.2.4...v0.2.5) (2026-03-17)
|
|
6
13
|
|
|
7
14
|
### [0.2.4](https://gitlab.mfj.local:8022/mario/ruflo-setup/compare/v0.2.3...v0.2.4) (2026-03-17)
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Cross-platform npm CLI to bootstrap a project with Ruflo on Windows and Linux.
|
|
|
16
16
|
<summary>Click to toggle visibility</summary>
|
|
17
17
|
|
|
18
18
|
- Node.js 20+
|
|
19
|
-
- pnpm available on PATH
|
|
19
|
+
- pnpm **10.32.1 or higher** available on PATH
|
|
20
20
|
|
|
21
21
|
Quickest pnpm install by platform:
|
|
22
22
|
|
|
@@ -42,9 +42,12 @@ corepack prepare pnpm@latest --activate
|
|
|
42
42
|
## π¦ Installation
|
|
43
43
|
|
|
44
44
|
```powershell
|
|
45
|
-
pnpm
|
|
45
|
+
pnpm add -g @mfjjs/ruflo-setup
|
|
46
|
+
ruflo-setup cleanup
|
|
46
47
|
```
|
|
47
48
|
|
|
49
|
+
> **Why run `cleanup` first?** If you previously installed any Ruflo packages via `npm install -g` (e.g. `ruflo`, `claude-flow`, `ruv-swarm`), those npm-global copies can shadow or conflict with the pnpm-managed versions. `ruflo-setup cleanup` removes them from the npm global registry before setup runs, giving you a clean slate.
|
|
50
|
+
|
|
48
51
|
## π‘ Why You Need This
|
|
49
52
|
|
|
50
53
|
If youβre working on:
|
|
@@ -60,6 +63,20 @@ You only need to do this once in each folder. Just run the command and youβre
|
|
|
60
63
|
|
|
61
64
|
## π Usage
|
|
62
65
|
|
|
66
|
+
### Cleanup
|
|
67
|
+
Remove any previous npm global installs of Ruflo packages that could conflict with the pnpm-managed versions:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
ruflo-setup cleanup
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This uninstalls `ruflo`, `@mfjjs/ruflo-setup`, `ruflo-setup`, `claude-flow`, `@claude-flow/cli`, and `ruv-swarm` from the **npm** global registry. It does not touch pnpm globals. Run this before setup if you suspect stale npm globals are shadowing the pnpm-installed binaries.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# preview what would be removed without making changes
|
|
77
|
+
ruflo-setup cleanup --dry-run
|
|
78
|
+
```
|
|
79
|
+
|
|
63
80
|
### Status
|
|
64
81
|
Check whether all Ruflo feature layers (0β8) are enabled in the current project:
|
|
65
82
|
|
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -2,7 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { createRequire } from 'node:module';
|
|
4
4
|
import { parseArgs } from './utils.js';
|
|
5
|
-
import { runSetup } from './setup.js';
|
|
5
|
+
import { runSetup, runCleanup } from './setup.js';
|
|
6
6
|
import { getGlobalHookStatus, installGlobalCheckRufloHook } from './hooks.js';
|
|
7
7
|
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
@@ -19,6 +19,7 @@ function printHelp() {
|
|
|
19
19
|
Usage:
|
|
20
20
|
ruflo-setup [options]
|
|
21
21
|
ruflo-setup status
|
|
22
|
+
ruflo-setup cleanup [--dry-run]
|
|
22
23
|
ruflo-setup hooks install [options]
|
|
23
24
|
ruflo-setup hooks status
|
|
24
25
|
|
|
@@ -31,9 +32,15 @@ Options:
|
|
|
31
32
|
--version, -v Print version and exit
|
|
32
33
|
--verbose Extra output
|
|
33
34
|
|
|
35
|
+
Commands:
|
|
36
|
+
cleanup Remove all Ruflo packages from the npm global registry
|
|
37
|
+
(ruflo, @mfjjs/ruflo-setup, claude-flow, @claude-flow/cli, ruv-swarm)
|
|
38
|
+
|
|
34
39
|
Examples:
|
|
35
40
|
ruflo-setup
|
|
36
41
|
ruflo-setup status
|
|
42
|
+
ruflo-setup cleanup
|
|
43
|
+
ruflo-setup cleanup --dry-run
|
|
37
44
|
ruflo-setup --dry-run --skip-init
|
|
38
45
|
ruflo-setup hooks status
|
|
39
46
|
ruflo-setup hooks install --dry-run
|
|
@@ -93,6 +100,19 @@ export async function runCli(argv, cwd) {
|
|
|
93
100
|
return 1;
|
|
94
101
|
}
|
|
95
102
|
|
|
103
|
+
if (flags.command === 'cleanup') {
|
|
104
|
+
if (!flags.dryRun && !flags.yes) {
|
|
105
|
+
const { confirm } = await import('./utils.js');
|
|
106
|
+
const ok = await confirm('Remove Ruflo packages from npm global registry? [y/N] ');
|
|
107
|
+
if (!ok) {
|
|
108
|
+
process.stdout.write('Aborted. No changes made.\n');
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
runCleanup({ dryRun: flags.dryRun });
|
|
113
|
+
return 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
96
116
|
await runSetup({
|
|
97
117
|
cwd,
|
|
98
118
|
packageRoot,
|
package/src/setup.js
CHANGED
|
@@ -33,30 +33,49 @@ function getPnpmInstallSuggestions(platform) {
|
|
|
33
33
|
];
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
const MIN_PNPM_VERSION = '10.32.1';
|
|
37
|
+
|
|
38
|
+
function parseSemver(str) {
|
|
39
|
+
const [major = 0, minor = 0, patch = 0] = str.trim().split('.').map(Number);
|
|
40
|
+
return { major, minor, patch };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function semverGte(a, b) {
|
|
44
|
+
if (a.major !== b.major) return a.major > b.major;
|
|
45
|
+
if (a.minor !== b.minor) return a.minor > b.minor;
|
|
46
|
+
return a.patch >= b.patch;
|
|
47
|
+
}
|
|
48
|
+
|
|
36
49
|
function ensurePnpmAvailable() {
|
|
37
50
|
const check = spawnSync('pnpm', ['--version'], {
|
|
38
|
-
stdio: 'ignore',
|
|
51
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
39
52
|
shell: process.platform === 'win32'
|
|
40
53
|
});
|
|
41
54
|
|
|
42
|
-
if (check.status
|
|
43
|
-
|
|
55
|
+
if (check.status !== 0 || check.error) {
|
|
56
|
+
const platformLabel = process.platform === 'win32'
|
|
57
|
+
? 'Windows'
|
|
58
|
+
: process.platform === 'darwin'
|
|
59
|
+
? 'macOS'
|
|
60
|
+
: 'Linux';
|
|
61
|
+
const suggestions = getPnpmInstallSuggestions(process.platform)
|
|
62
|
+
.map((command) => ` - ${command}`)
|
|
63
|
+
.join('\n');
|
|
64
|
+
|
|
65
|
+
throw new Error(
|
|
66
|
+
`pnpm is required but was not found in PATH.\n` +
|
|
67
|
+
`Install pnpm, then re-run ruflo-setup.\n` +
|
|
68
|
+
`Quick install options for ${platformLabel}:\n${suggestions}`
|
|
69
|
+
);
|
|
44
70
|
}
|
|
45
71
|
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
:
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
.join('\n');
|
|
54
|
-
|
|
55
|
-
throw new Error(
|
|
56
|
-
`pnpm is required but was not found in PATH.\n` +
|
|
57
|
-
`Install pnpm, then re-run ruflo-setup.\n` +
|
|
58
|
-
`Quick install options for ${platformLabel}:\n${suggestions}`
|
|
59
|
-
);
|
|
72
|
+
const version = (check.stdout || '').toString().trim();
|
|
73
|
+
if (!semverGte(parseSemver(version), parseSemver(MIN_PNPM_VERSION))) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`pnpm ${MIN_PNPM_VERSION} or higher is required, but found ${version}.\n` +
|
|
76
|
+
`Upgrade with: pnpm self-update`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
function runPnpmInit({ force, cwd, dryRun }) {
|
|
@@ -67,22 +86,46 @@ function runPnpmInit({ force, cwd, dryRun }) {
|
|
|
67
86
|
|
|
68
87
|
if (dryRun) {
|
|
69
88
|
logLine(` [DRY RUN] Would run: pnpm add -g ruflo@latest`);
|
|
89
|
+
logLine(` [DRY RUN] Would run: pnpm approve-builds -g --all (if changes detected)`);
|
|
70
90
|
logLine(` [DRY RUN] Would run: ruflo ${initArgs.join(' ')}`);
|
|
71
91
|
return;
|
|
72
92
|
}
|
|
73
93
|
|
|
74
94
|
ensurePnpmAvailable();
|
|
75
95
|
|
|
96
|
+
// Capture stdout to detect whether pnpm installed/updated anything.
|
|
97
|
+
// Progress spinners go to stderr (still shown to user); stdout has the summary.
|
|
76
98
|
const install = spawnSync('pnpm', ['add', '-g', 'ruflo@latest'], {
|
|
77
99
|
cwd,
|
|
78
|
-
stdio: 'inherit',
|
|
100
|
+
stdio: ['inherit', 'pipe', 'inherit'],
|
|
79
101
|
shell: process.platform === 'win32'
|
|
80
102
|
});
|
|
81
103
|
|
|
104
|
+
const installOutput = (install.stdout || '').toString();
|
|
105
|
+
if (installOutput) {
|
|
106
|
+
process.stdout.write(installOutput);
|
|
107
|
+
}
|
|
108
|
+
|
|
82
109
|
if (install.status !== 0) {
|
|
83
110
|
throw new Error(`pnpm add -g ruflo@latest failed with exit code ${install.status}`);
|
|
84
111
|
}
|
|
85
112
|
|
|
113
|
+
// pnpm prints a "Packages:" summary line and "+ pkg version" lines when
|
|
114
|
+
// something is actually installed or updated. When already up to date the
|
|
115
|
+
// stdout is empty or contains only "Already up to date".
|
|
116
|
+
const somethingChanged = /Packages:/i.test(installOutput) || /^\+\s/m.test(installOutput);
|
|
117
|
+
if (somethingChanged) {
|
|
118
|
+
logLine(' Changes detected β running pnpm approve-builds -g --all ...');
|
|
119
|
+
const approve = spawnSync('pnpm', ['approve-builds', '-g', '--all'], {
|
|
120
|
+
cwd,
|
|
121
|
+
stdio: 'inherit',
|
|
122
|
+
shell: process.platform === 'win32'
|
|
123
|
+
});
|
|
124
|
+
if (approve.status !== 0) {
|
|
125
|
+
throw new Error(`pnpm approve-builds -g --all failed with exit code ${approve.status}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
86
129
|
const run = spawnSync('ruflo', initArgs, {
|
|
87
130
|
cwd,
|
|
88
131
|
stdio: 'inherit',
|
|
@@ -233,3 +276,37 @@ export async function runSetup({
|
|
|
233
276
|
logLine(' 2. Run: claude');
|
|
234
277
|
logLine(' 3. Verify hooks: ruflo-setup hooks status');
|
|
235
278
|
}
|
|
279
|
+
|
|
280
|
+
const CLEANUP_NPM_PACKAGES = [
|
|
281
|
+
'ruflo',
|
|
282
|
+
'@mfjjs/ruflo-setup',
|
|
283
|
+
'ruflo-setup',
|
|
284
|
+
'claude-flow',
|
|
285
|
+
'@claude-flow/cli',
|
|
286
|
+
'ruv-swarm'
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
export function runCleanup({ dryRun = false } = {}) {
|
|
290
|
+
logLine('');
|
|
291
|
+
logLine('Ruflo Cleanup β removing from npm global registry');
|
|
292
|
+
logLine(`Packages: ${CLEANUP_NPM_PACKAGES.join(', ')}`);
|
|
293
|
+
logLine('');
|
|
294
|
+
|
|
295
|
+
if (dryRun) {
|
|
296
|
+
logLine(` [DRY RUN] Would run: npm uninstall -g ${CLEANUP_NPM_PACKAGES.join(' ')}`);
|
|
297
|
+
logLine('');
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
const result = spawnSync('npm', ['uninstall', '-g', ...CLEANUP_NPM_PACKAGES], {
|
|
302
|
+
stdio: 'inherit',
|
|
303
|
+
shell: process.platform === 'win32'
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
if (result.status !== 0) {
|
|
307
|
+
throw new Error(`npm uninstall -g failed with exit code ${result.status}`);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
logLine('');
|
|
311
|
+
logLine('Cleanup complete.');
|
|
312
|
+
}
|
package/templates/ruflo-setup.md
CHANGED
|
@@ -5,7 +5,7 @@ Set up Ruflo + Claude Flow V3 in the current project directory.
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- Node.js 20+
|
|
8
|
-
- pnpm installed and available on PATH
|
|
8
|
+
- pnpm 10.32.1+ installed and available on PATH
|
|
9
9
|
|
|
10
10
|
Quickest pnpm install by platform:
|
|
11
11
|
|
|
@@ -41,15 +41,50 @@ Runs `pnpm add -g @mfjjs/ruflo-setup` then `ruflo-setup` which:
|
|
|
41
41
|
3. Installs a global `SessionStart` hook in `~/.claude/settings.json` that warns when Ruflo is not configured
|
|
42
42
|
4. May refresh `~/.claude/commands/ruflo-setup.md` from the latest packaged template when differences are detected
|
|
43
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
|
+
|
|
44
52
|
## Instructions for Claude
|
|
45
53
|
|
|
46
54
|
When the user runs /ruflo-setup:
|
|
47
55
|
|
|
56
|
+
### Default (no arguments) β install
|
|
57
|
+
|
|
48
58
|
1. Confirm the current working directory with the user
|
|
49
59
|
2. Check if `.mcp.json` already exists β if so, warn and ask before overwriting
|
|
50
|
-
3.
|
|
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:
|
|
51
66
|
```bash
|
|
52
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
|
|
53
77
|
ruflo-setup
|
|
54
78
|
```
|
|
55
|
-
|
|
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)
|