@curdx/flow 2.0.0-beta.11 → 2.0.0-beta.13
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +2 -18
- package/CHANGELOG.md +38 -2
- package/bin/curdx-flow.js +26 -9
- package/cli/doctor.js +33 -45
- package/cli/install.js +37 -2
- package/cli/registry.js +34 -0
- package/cli/uninstall.js +33 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Claude Code Discipline Layer — spec-driven workflow + goal-backward verification + Karpathy 4 principles enforced via gates. Stops Claude from faking \"done\" on non-trivial features.",
|
|
9
|
-
"version": "2.0.0-beta.
|
|
9
|
+
"version": "2.0.0-beta.13"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "curdx-flow",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.13",
|
|
4
4
|
"description": "Claude Code Discipline Layer — spec-driven workflow + goal-backward verification + Karpathy 4 principles enforced via gates. Stops Claude from faking \"done\" on non-trivial features.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "wdx",
|
|
@@ -16,21 +16,5 @@
|
|
|
16
16
|
"orchestration",
|
|
17
17
|
"karpathy",
|
|
18
18
|
"claude-code"
|
|
19
|
-
]
|
|
20
|
-
"mcpServers": {
|
|
21
|
-
"context7": {
|
|
22
|
-
"command": "npx",
|
|
23
|
-
"args": [
|
|
24
|
-
"-y",
|
|
25
|
-
"@upstash/context7-mcp@latest"
|
|
26
|
-
]
|
|
27
|
-
},
|
|
28
|
-
"sequential-thinking": {
|
|
29
|
-
"command": "npx",
|
|
30
|
-
"args": [
|
|
31
|
-
"-y",
|
|
32
|
-
"@modelcontextprotocol/server-sequential-thinking"
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
}
|
|
19
|
+
]
|
|
36
20
|
}
|
package/CHANGELOG.md
CHANGED
|
@@ -4,10 +4,46 @@ All notable changes to CurDX-Flow will be documented here.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
### BREAKING
|
|
8
|
+
|
|
9
|
+
- **`context7` and `sequential-thinking` moved from plugin-bundled MCPs to user-level MCPs.** Previously `.claude-plugin/plugin.json` declared both in `mcpServers`, so Claude Code auto-registered them as `plugin:curdx-flow:context7` and `plugin:curdx-flow:sequential-thinking` when the plugin installed. This is no longer the case — the `mcpServers` block is gone. Instead, `curdx-flow install` now runs `claude mcp add context7 …` + `claude mcp add sequential-thinking …` against the user's `~/.claude.json`, which keeps them as standard user-level registrations named `context7` and `sequential-thinking`.
|
|
10
|
+
|
|
11
|
+
**Why**: every early adopter who ran `claude mcp add context7 -- npx -y @upstash/context7-mcp --api-key ctx7sk-…` before installing curdx-flow ended up with *both* entries side-by-side — doubling MCP processes, making API-key routing unpredictable (random between free-tier plugin copy and paid user copy), and forcing an awkward env-var migration path. User-level registration matches the way every other MCP in the ecosystem is installed, keeps tool names standard (`mcp__context7__*` instead of `mcp__plugin_curdx-flow_context7__*`), and lets users put an `--api-key` directly in their own entry without any env-var indirection. Every agent / knowledge doc / command in the repo already calls the standard tool-name form, so this is a **zero-change-for-callers** migration.
|
|
12
|
+
|
|
13
|
+
**Migration for existing users**:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Upgrade the plugin — this removes the plugin-bundled MCPs and
|
|
17
|
+
# registers them at user-level (preserving any existing user-level entry
|
|
18
|
+
# with a custom --api-key).
|
|
19
|
+
npx @curdx/flow@latest upgrade
|
|
20
|
+
|
|
21
|
+
# Restart Claude Code so the plugin manifest reloads.
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
After upgrade, `claude mcp list` will show `context7` and
|
|
25
|
+
`sequential-thinking` (user-level) but NOT `plugin:curdx-flow:context7` etc.
|
|
26
|
+
`npx @curdx/flow doctor` confirms with "user-level (standard)" in the
|
|
27
|
+
"MCP Servers" section.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- `cli/registry.js` exports a new `BUNDLED_MCPS` constant — the source-of-truth list of MCPs that `install` registers at user-level and `uninstall` optionally removes.
|
|
32
|
+
- `cli/install.js` Step 3.5 — registers the required MCPs via `claude mcp add`. Detects pre-existing user-level entries (e.g. your hand-configured context7 with an API key) and preserves them instead of overwriting.
|
|
33
|
+
- `cli/uninstall.js` Step 4.5 — asks whether to `claude mcp remove` the registered MCPs (default: no, because other tools may depend on them).
|
|
34
|
+
- `cli/doctor.js` — now reports "user-level (standard)" for each required MCP when it's registered the right way, and "(legacy)" with a migration hint when the old plugin-bundled form is still active.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- The "Duplicate MCP" warning in `doctor` (added in beta.11) is now framed as "Legacy plugin-bundled MCPs still present" with a concrete migration command, since the new architecture reserves duplication strictly for the upgrade-transition window.
|
|
39
|
+
- `docs/getting-started.md` "Optional: use your paid context7 API key" section rewritten around the user-level path (add `--api-key` to your `claude mcp add` command) since env-var indirection is no longer the only way to route a key to the plugin copy.
|
|
40
|
+
|
|
41
|
+
## [2.0.0-beta.11] - 2026-04-22
|
|
42
|
+
|
|
7
43
|
### Added
|
|
8
44
|
|
|
9
|
-
- `cli/doctor.js`
|
|
10
|
-
- `docs/getting-started.md`
|
|
45
|
+
- `cli/doctor.js` detects when a user-level MCP in `~/.claude.json` (typically `context7` added via `claude mcp add …`) duplicates a plugin-bundled MCP from `plugin.json` (`plugin:curdx-flow:context7`). Backed by `cli/utils.js:readUserMcpConfig()` + `findDuplicateMcps()` and 3 new tests in `test/utils.test.js`.
|
|
46
|
+
- `docs/getting-started.md` "Optional: use your paid context7 API key" section documenting the env-var path.
|
|
11
47
|
|
|
12
48
|
## [2.0.0-beta.10] - 2026-04-21
|
|
13
49
|
|
package/bin/curdx-flow.js
CHANGED
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
* for the full command/workflow reference)
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
-
import {
|
|
23
|
+
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { realpathSync } from "node:fs";
|
|
24
25
|
|
|
25
26
|
import { install } from "../cli/install.js";
|
|
26
27
|
import { doctor } from "../cli/doctor.js";
|
|
@@ -131,13 +132,29 @@ async function main() {
|
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
// Only execute main() when invoked directly (`node bin/curdx-flow.js ...`
|
|
134
|
-
// or via the npm bin shim). When the file is
|
|
135
|
-
// we want the module graph to load without
|
|
136
|
-
//
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
135
|
+
// or via the npm bin shim at node_modules/.bin/<name>). When the file is
|
|
136
|
+
// imported by tests or tooling, we want the module graph to load without
|
|
137
|
+
// side-effects.
|
|
138
|
+
//
|
|
139
|
+
// CRITICAL: compare RESOLVED real paths. npm installs the bin as a symlink
|
|
140
|
+
// (node_modules/.bin/curdx-flow → ../@curdx/flow/bin/curdx-flow.js), so
|
|
141
|
+
// process.argv[1] is the symlink path while import.meta.url resolves to
|
|
142
|
+
// the real file. Comparing them directly (the pre-beta.13 behavior)
|
|
143
|
+
// silently skipped main() for every single npx / global-install user,
|
|
144
|
+
// producing a completely broken CLI that exited with no output. Regression
|
|
145
|
+
// caught by user report + reproduced in CI via test/cli-entrypoints.test.js.
|
|
146
|
+
function isInvokedDirectly() {
|
|
147
|
+
if (!process.argv[1]) return false;
|
|
148
|
+
try {
|
|
149
|
+
return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
150
|
+
} catch {
|
|
151
|
+
// argv[1] is not a real filesystem path (e.g. `node -e` eval forms or
|
|
152
|
+
// a worker pipe). Treat as "not invoked directly" — the caller is
|
|
153
|
+
// doing something non-standard.
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (isInvokedDirectly()) {
|
|
142
159
|
main();
|
|
143
160
|
}
|
package/cli/doctor.js
CHANGED
|
@@ -57,27 +57,31 @@ export async function doctor(args = []) {
|
|
|
57
57
|
// chrome-devtools is NOT here anymore — it was extracted into its own
|
|
58
58
|
// recommended plugin (see below) to align with the "each MCP owned by one
|
|
59
59
|
// plugin" model and avoid double-spawning the chrome-devtools-mcp process.
|
|
60
|
-
console.log(`\n${color.bold("MCP Servers:")}`);
|
|
60
|
+
console.log(`\n${color.bold("MCP Servers (required by L2 mandatory tools):")}`);
|
|
61
61
|
const mcps = cv ? listMcps() : [];
|
|
62
62
|
const expectedMcps = ["context7", "sequential-thinking"];
|
|
63
63
|
for (const m of expectedMcps) {
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
64
|
+
// Beta.12 onward: the required MCPs are registered at user-level
|
|
65
|
+
// (via `claude mcp add`), NOT plugin-bundled. Both still show up in
|
|
66
|
+
// `claude mcp list`. Accept a standalone user-level registration
|
|
67
|
+
// as the primary form, and warn if only a plugin-bundled copy exists
|
|
68
|
+
// (because that's the legacy layout that beta.11 had).
|
|
69
|
+
const userLevel = mcps.find((x) => x.name === m && x.plugin === null);
|
|
70
|
+
const pluginLevel = mcps.find((x) => x.name === m && x.plugin !== null);
|
|
71
|
+
|
|
72
|
+
if (userLevel) {
|
|
73
|
+
log.ok(`${m.padEnd(22)} ${color.dim("user-level (standard)")}`);
|
|
74
|
+
} else if (pluginLevel) {
|
|
75
|
+
log.warn(
|
|
76
|
+
`${m.padEnd(22)} registered via plugin:${pluginLevel.plugin} (legacy). ` +
|
|
77
|
+
`Run ${color.cyan("npx @curdx/flow install --all")} to migrate to user-level.`
|
|
78
|
+
);
|
|
79
|
+
warnings++;
|
|
78
80
|
} else {
|
|
79
81
|
if (curdx) {
|
|
80
|
-
log.warn(
|
|
82
|
+
log.warn(
|
|
83
|
+
`${m.padEnd(22)} missing. Run: ${color.cyan(`claude mcp add ${m} -- npx -y @upstash/context7-mcp@latest`).replace("context7-mcp", m === "context7" ? "context7-mcp" : "server-sequential-thinking")}`
|
|
84
|
+
);
|
|
81
85
|
warnings++;
|
|
82
86
|
} else {
|
|
83
87
|
log.info(`${m.padEnd(22)} waiting for curdx-flow install`);
|
|
@@ -104,44 +108,28 @@ export async function doctor(args = []) {
|
|
|
104
108
|
}
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
// ----------
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
// differ — but it doubles MCP processes and makes API-key routing
|
|
114
|
-
// unpredictable. Surface the duplicates + concrete remediation.
|
|
111
|
+
// ---------- Legacy plugin-bundled MCP residue (beta.11 and earlier) ----------
|
|
112
|
+
// Beta.12 moved context7 + sequential-thinking to user-level registration.
|
|
113
|
+
// If both a user-level and a plugin-bundled copy are visible, the user
|
|
114
|
+
// was likely installed from an older beta.7-beta.11 that still had
|
|
115
|
+
// mcpServers in plugin.json and a `claude mcp update` hasn't refreshed
|
|
116
|
+
// the plugin cache yet. Point them at the migration command.
|
|
115
117
|
if (cv) {
|
|
116
118
|
const userCfg = readUserMcpConfig();
|
|
117
119
|
const duplicates = findDuplicateMcps(mcps, userCfg);
|
|
118
120
|
if (duplicates.length > 0) {
|
|
119
|
-
console.log(`\n${color.bold("
|
|
121
|
+
console.log(`\n${color.bold("Legacy plugin-bundled MCPs still present:")}`);
|
|
120
122
|
for (const d of duplicates) {
|
|
121
|
-
const userArgs = (d.userConfig.args || []).join(" ");
|
|
122
|
-
const hasApiKey = userArgs.includes("api-key") || userArgs.includes("ctx7sk");
|
|
123
123
|
log.warn(
|
|
124
|
-
`${d.name.padEnd(22)}
|
|
125
|
-
);
|
|
126
|
-
console.log(
|
|
127
|
-
color.dim(` user-level : ${d.userConfig.command || "?"} ${userArgs}`)
|
|
124
|
+
`${d.name.padEnd(22)} both user-level AND plugin:${d.pluginEntry.plugin} active`
|
|
128
125
|
);
|
|
129
126
|
console.log(
|
|
130
|
-
color.dim(
|
|
127
|
+
color.dim(
|
|
128
|
+
` → Migration: ${color.cyan(`claude plugin update curdx-flow@curdx-flow-marketplace`)}\n` +
|
|
129
|
+
` then restart Claude Code. Beta.12+ removes plugin-bundled\n` +
|
|
130
|
+
` versions in favor of the user-level entry you already have.`
|
|
131
|
+
)
|
|
131
132
|
);
|
|
132
|
-
if (hasApiKey && d.name === "context7") {
|
|
133
|
-
console.log(
|
|
134
|
-
color.dim(
|
|
135
|
-
` → Fix: export CONTEXT7_API_KEY=<your-key> in your shell rc,\n` +
|
|
136
|
-
` then: claude mcp remove ${d.name}\n` +
|
|
137
|
-
` (plugin MCP will inherit the env var — no key is lost)`
|
|
138
|
-
)
|
|
139
|
-
);
|
|
140
|
-
} else {
|
|
141
|
-
console.log(
|
|
142
|
-
color.dim(` → Fix: claude mcp remove ${d.name}`)
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
133
|
warnings++;
|
|
146
134
|
}
|
|
147
135
|
}
|
package/cli/install.js
CHANGED
|
@@ -17,7 +17,8 @@ import {
|
|
|
17
17
|
ensureClaudeMemRuntimes,
|
|
18
18
|
} from "./utils.js";
|
|
19
19
|
import { injectGlobalProtocols, GLOBAL_CLAUDE_MD } from "./protocols.js";
|
|
20
|
-
import { RECOMMENDED_PLUGINS } from "./registry.js";
|
|
20
|
+
import { RECOMMENDED_PLUGINS, BUNDLED_MCPS } from "./registry.js";
|
|
21
|
+
import { readUserMcpConfig } from "./utils.js";
|
|
21
22
|
|
|
22
23
|
// When installed via npm, this CLI file lives at <pkg-root>/cli/install.js.
|
|
23
24
|
// The npm package bundles the full plugin body (.claude-plugin/, agents/,
|
|
@@ -90,7 +91,7 @@ export async function install(args = []) {
|
|
|
90
91
|
|
|
91
92
|
// ---------- Step 3: Install curdx-flow plugin ----------
|
|
92
93
|
log.blank();
|
|
93
|
-
log.step(3, 5, "Installing curdx-flow plugin
|
|
94
|
+
log.step(3, 5, "Installing curdx-flow plugin...");
|
|
94
95
|
// Read the version the marketplace is shipping so we can decide whether an
|
|
95
96
|
// already-installed plugin needs an update (same name but stale version
|
|
96
97
|
// previously silently skipped the upgrade — caused the beta.1 → beta.7 drift).
|
|
@@ -136,6 +137,40 @@ export async function install(args = []) {
|
|
|
136
137
|
log.ok("curdx-flow installed");
|
|
137
138
|
}
|
|
138
139
|
|
|
140
|
+
// ---------- Step 3.5: Register user-level MCPs (context7, sequential-thinking) ----------
|
|
141
|
+
// Beta.12: migrated from plugin.json bundling. See cli/registry.js for
|
|
142
|
+
// the rationale (avoids plugin:curdx-flow:context7 vs context7 duplicate
|
|
143
|
+
// registration + keeps tool names standard for third-party agent reuse).
|
|
144
|
+
log.blank();
|
|
145
|
+
log.info("Registering required MCP servers (user-level)...");
|
|
146
|
+
const existingUserMcps = readUserMcpConfig();
|
|
147
|
+
for (const mcp of BUNDLED_MCPS) {
|
|
148
|
+
if (mcp.preserveExisting && existingUserMcps.has(mcp.name)) {
|
|
149
|
+
const existing = existingUserMcps.get(mcp.name);
|
|
150
|
+
log.info(
|
|
151
|
+
` ${mcp.name.padEnd(22)} ${color.dim(`already registered (${(existing.args || []).join(" ")}) — preserving`)}`
|
|
152
|
+
);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const r = await run(
|
|
156
|
+
"claude",
|
|
157
|
+
["mcp", "add", mcp.name, "--", mcp.command, ...mcp.args],
|
|
158
|
+
{ silent: true }
|
|
159
|
+
);
|
|
160
|
+
if (r.code === 0) {
|
|
161
|
+
log.ok(` ${mcp.name.padEnd(22)} ${color.dim("registered")}`);
|
|
162
|
+
} else if (r.stderr.includes("already exists")) {
|
|
163
|
+
log.info(` ${mcp.name.padEnd(22)} ${color.dim("already exists — skipped")}`);
|
|
164
|
+
} else {
|
|
165
|
+
log.warn(
|
|
166
|
+
` ${mcp.name.padEnd(22)} registration failed: ${r.stderr.trim().split("\n").pop()}`
|
|
167
|
+
);
|
|
168
|
+
log.info(
|
|
169
|
+
` Run manually: claude mcp add ${mcp.name} -- ${mcp.command} ${mcp.args.join(" ")}`
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
139
174
|
// ---------- Step 4: Recommended plugins ----------
|
|
140
175
|
log.blank();
|
|
141
176
|
log.step(4, 5, "Recommended plugins");
|
package/cli/registry.js
CHANGED
|
@@ -52,6 +52,40 @@ export const RECOMMENDED_PLUGINS = [
|
|
|
52
52
|
},
|
|
53
53
|
];
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Bundled MCP servers that curdx-flow depends on for its core discipline
|
|
57
|
+
* rules (context7 for library docs in L2, sequential-thinking for
|
|
58
|
+
* structured reasoning in L2). Starting beta.12 these are registered at
|
|
59
|
+
* USER-LEVEL via `claude mcp add` instead of plugin.json bundling, so:
|
|
60
|
+
*
|
|
61
|
+
* - Tool names stay standard (mcp__context7__*, mcp__sequential-thinking__*)
|
|
62
|
+
* — matching every agent's and knowledge doc's hardcoded references.
|
|
63
|
+
* - Users with a paid context7 API key can set it with --api-key in their
|
|
64
|
+
* own user-level entry; the install command will detect and respect the
|
|
65
|
+
* existing entry instead of overwriting it.
|
|
66
|
+
* - No more `plugin:curdx-flow:context7` + `context7` duplicate registration
|
|
67
|
+
* — the DX pitfall that bit every early adopter with a pre-existing
|
|
68
|
+
* `claude mcp add context7 …` history.
|
|
69
|
+
*/
|
|
70
|
+
export const BUNDLED_MCPS = [
|
|
71
|
+
{
|
|
72
|
+
name: "context7",
|
|
73
|
+
command: "npx",
|
|
74
|
+
args: ["-y", "@upstash/context7-mcp@latest"],
|
|
75
|
+
purpose: "library / framework docs lookup (L2 Mandatory Tool)",
|
|
76
|
+
// Respect any user-level entry with a custom `--api-key` or differing
|
|
77
|
+
// package spec — don't overwrite it on subsequent install runs.
|
|
78
|
+
preserveExisting: true,
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: "sequential-thinking",
|
|
82
|
+
command: "npx",
|
|
83
|
+
args: ["-y", "@modelcontextprotocol/server-sequential-thinking"],
|
|
84
|
+
purpose: "structured reasoning for design / review (L2 Mandatory Tool)",
|
|
85
|
+
preserveExisting: true,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
|
|
55
89
|
/**
|
|
56
90
|
* Marketplaces to refresh during `upgrade`. Derived from RECOMMENDED_PLUGINS
|
|
57
91
|
* plus the curdx-flow marketplace itself.
|
package/cli/uninstall.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
listPlugins,
|
|
17
17
|
} from "./utils.js";
|
|
18
18
|
import { removeGlobalProtocols, GLOBAL_CLAUDE_MD } from "./protocols.js";
|
|
19
|
-
import { RECOMMENDED_PLUGINS } from "./registry.js";
|
|
19
|
+
import { RECOMMENDED_PLUGINS, BUNDLED_MCPS } from "./registry.js";
|
|
20
20
|
|
|
21
21
|
const HOME = homedir();
|
|
22
22
|
|
|
@@ -131,6 +131,38 @@ export async function uninstall(args = []) {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
// ---------- Step 4.5: optionally remove user-level MCPs ----------
|
|
135
|
+
// Starting beta.12, the install command registers context7 +
|
|
136
|
+
// sequential-thinking at user-level (not plugin-bundled). Ask before
|
|
137
|
+
// removing because the user may have customised args (e.g. --api-key)
|
|
138
|
+
// or still be using these MCPs outside curdx-flow.
|
|
139
|
+
log.blank();
|
|
140
|
+
log.info("Required MCP servers (context7, sequential-thinking)");
|
|
141
|
+
if (keepRecommended || yes) {
|
|
142
|
+
log.info(
|
|
143
|
+
color.dim("--yes or --keep-recommended: keeping user-level MCPs (remove manually with `claude mcp remove <name>`)")
|
|
144
|
+
);
|
|
145
|
+
} else {
|
|
146
|
+
const removeMcps = await confirm(
|
|
147
|
+
`Remove user-level MCPs registered by install (${BUNDLED_MCPS.map((m) => m.name).join(", ")})? ${color.dim("(keeps them if other tools depend on them)")}`,
|
|
148
|
+
false
|
|
149
|
+
);
|
|
150
|
+
if (removeMcps) {
|
|
151
|
+
for (const mcp of BUNDLED_MCPS) {
|
|
152
|
+
const r = await run("claude", ["mcp", "remove", mcp.name], {
|
|
153
|
+
silent: true,
|
|
154
|
+
});
|
|
155
|
+
if (r.code === 0) {
|
|
156
|
+
log.ok(` ${mcp.name.padEnd(22)} removed`);
|
|
157
|
+
} else {
|
|
158
|
+
log.info(` ${mcp.name.padEnd(22)} ${color.dim("not present or already removed")}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
log.info("Keeping user-level MCPs");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
134
166
|
// ---------- Step 5: cleanup symlinks (only with --purge) ----------
|
|
135
167
|
log.blank();
|
|
136
168
|
log.step(3, 4, "Runtime symlinks");
|