@cliangdev/flux-plugin 0.0.0-dev.b40f7c2 → 0.0.0-dev.cf5e864

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 (3) hide show
  1. package/README.md +54 -21
  2. package/bin/install.cjs +243 -0
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -4,30 +4,29 @@ Agent-orchestrated, spec-driven workflow for Claude Code.
4
4
 
5
5
  ## Installation
6
6
 
7
- ### Quick Install (Recommended)
8
-
9
7
  ```bash
10
- claude mcp add flux -- npx -y @cliangdev/flux-plugin
8
+ npx @cliangdev/flux-plugin
11
9
  ```
12
10
 
13
- ### Manual Configuration
14
-
15
- Add to your `.mcp.json`:
16
-
17
- ```json
18
- {
19
- "mcpServers": {
20
- "flux": {
21
- "command": "npx",
22
- "args": ["-y", "@cliangdev/flux-plugin"],
23
- "env": {
24
- "FLUX_PROJECT_ROOT": "${CLAUDE_PROJECT_DIR}"
25
- }
26
- }
27
- }
28
- }
11
+ This installs:
12
+ - Commands (`/flux`, `/flux:prd`, `/flux:breakdown`, `/flux:implement`)
13
+ - Skills for AI orchestration
14
+ - MCP server for project data
15
+
16
+ ### Options
17
+
18
+ ```bash
19
+ npx @cliangdev/flux-plugin --global # Install to ~/.claude (all projects)
20
+ npx @cliangdev/flux-plugin --local # Install to ./.claude (current project)
29
21
  ```
30
22
 
23
+ ### What Gets Configured
24
+
25
+ The installer automatically:
26
+ 1. Copies commands to `.claude/commands/`
27
+ 2. Copies skills to `.claude/skills/`
28
+ 3. Adds MCP server config to `.claude.json`
29
+
31
30
  ## Commands
32
31
 
33
32
  | Command | Purpose |
@@ -119,13 +118,47 @@ your-project/
119
118
 
120
119
  ## Updating
121
120
 
122
- The plugin auto-updates via npx. Restart Claude Code to get the latest version.
121
+ To update to the latest version, simply re-run the installer:
123
122
 
124
- Check your version:
123
+ ```bash
124
+ npx @cliangdev/flux-plugin@latest --global
125
+ ```
126
+
127
+ This will:
128
+ - Update commands and skills to the latest version
129
+ - Update the MCP server configuration
130
+
131
+ Check your current version:
125
132
  ```
126
133
  /flux version
127
134
  ```
128
135
 
136
+ ## Uninstall
137
+
138
+ ### Global Installation
139
+
140
+ ```bash
141
+ # Remove commands and skills
142
+ rm -rf ~/.claude/commands/flux ~/.claude/commands/prd ~/.claude/commands/breakdown ~/.claude/commands/implement
143
+ rm -rf ~/.claude/skills/agent-creator ~/.claude/skills/epic-template ~/.claude/skills/flux-orchestrator ~/.claude/skills/prd-template
144
+ rm -f ~/.claude/flux-version
145
+
146
+ # Remove MCP server config (edit ~/.claude.json and remove the "flux" entry from "mcpServers")
147
+ ```
148
+
149
+ ### Local Installation
150
+
151
+ ```bash
152
+ # Remove commands and skills
153
+ rm -rf .claude/commands/flux .claude/commands/prd .claude/commands/breakdown .claude/commands/implement
154
+ rm -rf .claude/skills/agent-creator .claude/skills/epic-template .claude/skills/flux-orchestrator .claude/skills/prd-template
155
+ rm -f .claude/flux-version
156
+
157
+ # Remove MCP server config (edit .claude.json and remove the "flux" entry from "mcpServers")
158
+ ```
159
+
160
+ Note: Your project data in `.flux/` is preserved. Delete it manually if you want to remove all Flux data.
161
+
129
162
  ## Support
130
163
 
131
164
  GitHub: [github.com/cliangdev/flux-plugin](https://github.com/cliangdev/flux-plugin)
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const os = require("os");
6
+ const readline = require("readline");
7
+
8
+ // Parse args first to check for serve command
9
+ const args = process.argv.slice(2);
10
+
11
+ // Check for "serve" subcommand - starts MCP server
12
+ if (args[0] === "serve") {
13
+ // Dynamic import to load ESM server
14
+ import("../dist/server/index.js").catch((err) => {
15
+ console.error("Failed to start Flux MCP server:", err.message);
16
+ process.exit(1);
17
+ });
18
+ } else {
19
+ // Run installer
20
+ runInstaller();
21
+ }
22
+
23
+ function runInstaller() {
24
+ // Colors
25
+ const cyan = "\x1b[36m";
26
+ const green = "\x1b[32m";
27
+ const yellow = "\x1b[33m";
28
+ const dim = "\x1b[2m";
29
+ const reset = "\x1b[0m";
30
+
31
+ // Get version from package.json
32
+ const pkg = require("../package.json");
33
+
34
+ const banner = `
35
+ ${cyan} ███████╗██╗ ██╗ ██╗██╗ ██╗
36
+ ██╔════╝██║ ██║ ██║╚██╗██╔╝
37
+ █████╗ ██║ ██║ ██║ ╚███╔╝
38
+ ██╔══╝ ██║ ██║ ██║ ██╔██╗
39
+ ██║ ███████╗╚██████╔╝██╔╝ ██╗
40
+ ╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝${reset}
41
+
42
+ Flux Plugin ${dim}v${pkg.version}${reset}
43
+ AI-first workflow orchestration for Claude Code
44
+ `;
45
+
46
+ const hasGlobal = args.includes("--global") || args.includes("-g");
47
+ const hasLocal = args.includes("--local") || args.includes("-l");
48
+ const hasHelp = args.includes("--help") || args.includes("-h");
49
+
50
+ console.log(banner);
51
+
52
+ // Show help
53
+ if (hasHelp) {
54
+ console.log(` ${yellow}Usage:${reset} npx @cliangdev/flux-plugin [options]
55
+
56
+ ${yellow}Options:${reset}
57
+ ${cyan}-g, --global${reset} Install globally (to ~/.claude)
58
+ ${cyan}-l, --local${reset} Install locally (to ./.claude in current directory)
59
+ ${cyan}-h, --help${reset} Show this help message
60
+
61
+ ${yellow}Examples:${reset}
62
+ ${dim}# Interactive installation${reset}
63
+ npx @cliangdev/flux-plugin
64
+
65
+ ${dim}# Install globally (all projects)${reset}
66
+ npx @cliangdev/flux-plugin --global
67
+
68
+ ${dim}# Install locally (current project only)${reset}
69
+ npx @cliangdev/flux-plugin --local
70
+ `);
71
+ process.exit(0);
72
+ }
73
+
74
+ /**
75
+ * Recursively copy directory
76
+ */
77
+ function copyDir(src, dest) {
78
+ fs.mkdirSync(dest, { recursive: true });
79
+ const entries = fs.readdirSync(src, { withFileTypes: true });
80
+
81
+ for (const entry of entries) {
82
+ const srcPath = path.join(src, entry.name);
83
+ const destPath = path.join(dest, entry.name);
84
+
85
+ if (entry.isDirectory()) {
86
+ copyDir(srcPath, destPath);
87
+ } else {
88
+ fs.copyFileSync(srcPath, destPath);
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Read JSON file, return empty object if doesn't exist
95
+ */
96
+ function readJson(filePath) {
97
+ if (fs.existsSync(filePath)) {
98
+ try {
99
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
100
+ } catch {
101
+ return {};
102
+ }
103
+ }
104
+ return {};
105
+ }
106
+
107
+ /**
108
+ * Write JSON file with formatting
109
+ */
110
+ function writeJson(filePath, data) {
111
+ fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n");
112
+ }
113
+
114
+ /**
115
+ * Install to specified directory
116
+ */
117
+ function install(isGlobal) {
118
+ const src = path.join(__dirname, "..");
119
+ const claudeDir = isGlobal
120
+ ? path.join(os.homedir(), ".claude")
121
+ : path.join(process.cwd(), ".claude");
122
+
123
+ const locationLabel = isGlobal ? "~/.claude" : "./.claude";
124
+
125
+ console.log(` Installing to ${cyan}${locationLabel}${reset}\n`);
126
+
127
+ // Create directories
128
+ fs.mkdirSync(claudeDir, { recursive: true });
129
+
130
+ // Copy commands
131
+ const commandsSrc = path.join(src, "commands");
132
+ if (fs.existsSync(commandsSrc)) {
133
+ const commandsDest = path.join(claudeDir, "commands");
134
+ fs.mkdirSync(commandsDest, { recursive: true });
135
+
136
+ // Copy each command as a directory (flux.md -> commands/flux/COMMAND.md)
137
+ const commandFiles = fs.readdirSync(commandsSrc);
138
+ for (const file of commandFiles) {
139
+ if (file.endsWith(".md")) {
140
+ const name = file.replace(".md", "");
141
+ const destDir = path.join(commandsDest, name);
142
+ fs.mkdirSync(destDir, { recursive: true });
143
+ fs.copyFileSync(
144
+ path.join(commandsSrc, file),
145
+ path.join(destDir, "COMMAND.md")
146
+ );
147
+ console.log(` ${green}✓${reset} Installed command: /${name}`);
148
+ }
149
+ }
150
+ }
151
+
152
+ // Copy skills
153
+ const skillsSrc = path.join(src, "skills");
154
+ if (fs.existsSync(skillsSrc)) {
155
+ const skillsDest = path.join(claudeDir, "skills");
156
+ fs.mkdirSync(skillsDest, { recursive: true });
157
+
158
+ // Copy each skill directory
159
+ const skillDirs = fs.readdirSync(skillsSrc, { withFileTypes: true });
160
+ for (const dir of skillDirs) {
161
+ if (dir.isDirectory()) {
162
+ copyDir(
163
+ path.join(skillsSrc, dir.name),
164
+ path.join(skillsDest, dir.name)
165
+ );
166
+ console.log(` ${green}✓${reset} Installed skill: ${dir.name}`);
167
+ }
168
+ }
169
+ }
170
+
171
+ // Configure MCP server
172
+ const claudeJsonPath = isGlobal
173
+ ? path.join(os.homedir(), ".claude.json")
174
+ : path.join(process.cwd(), ".claude.json");
175
+
176
+ const claudeJson = readJson(claudeJsonPath);
177
+
178
+ if (!claudeJson.mcpServers) {
179
+ claudeJson.mcpServers = {};
180
+ }
181
+
182
+ // Add or update flux MCP server
183
+ claudeJson.mcpServers.flux = {
184
+ command: "npx",
185
+ args: ["-y", "@cliangdev/flux-plugin", "serve"],
186
+ };
187
+
188
+ writeJson(claudeJsonPath, claudeJson);
189
+ console.log(
190
+ ` ${green}✓${reset} Configured MCP server in ${isGlobal ? "~/.claude.json" : "./.claude.json"}`
191
+ );
192
+
193
+ // Write version file for update checking
194
+ const versionFile = path.join(claudeDir, "flux-version");
195
+ fs.writeFileSync(versionFile, pkg.version);
196
+
197
+ console.log(`
198
+ ${green}Done!${reset} Restart Claude Code and run ${cyan}/flux${reset} to get started.
199
+
200
+ ${dim}Commands available:${reset}
201
+ /flux - Project status and guidance
202
+ /flux:prd - Create or refine PRDs
203
+ /flux:breakdown - Break PRDs into epics and tasks
204
+ /flux:implement - Implement tasks with TDD
205
+
206
+ ${dim}Learn more:${reset} https://github.com/cliangdev/flux-plugin
207
+ `);
208
+ }
209
+
210
+ /**
211
+ * Prompt for install location
212
+ */
213
+ function promptLocation() {
214
+ const rl = readline.createInterface({
215
+ input: process.stdin,
216
+ output: process.stdout,
217
+ });
218
+
219
+ console.log(` ${yellow}Where would you like to install?${reset}
220
+
221
+ ${cyan}1${reset}) Global ${dim}(~/.claude)${reset} - available in all projects
222
+ ${cyan}2${reset}) Local ${dim}(./.claude)${reset} - this project only
223
+ `);
224
+
225
+ rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
226
+ rl.close();
227
+ const choice = answer.trim() || "1";
228
+ install(choice !== "2");
229
+ });
230
+ }
231
+
232
+ // Main
233
+ if (hasGlobal && hasLocal) {
234
+ console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
235
+ process.exit(1);
236
+ } else if (hasGlobal) {
237
+ install(true);
238
+ } else if (hasLocal) {
239
+ install(false);
240
+ } else {
241
+ promptLocation();
242
+ }
243
+ }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@cliangdev/flux-plugin",
3
- "version": "0.0.0-dev.b40f7c2",
3
+ "version": "0.0.0-dev.cf5e864",
4
4
  "description": "Claude Code plugin for AI-first workflow orchestration with MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/server/index.js",
7
7
  "bin": {
8
- "flux-plugin": "./dist/server/index.js"
8
+ "flux-plugin": "./bin/install.cjs"
9
9
  },
10
10
  "files": [
11
+ "bin/",
11
12
  "dist/",
12
13
  "skills/",
13
14
  "commands/"