@curdx/flow 2.3.11 → 3.1.0

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 (210) hide show
  1. package/CHANGELOG.md +21 -34
  2. package/LICENSE +1 -1
  3. package/README.md +28 -79
  4. package/dist/index.mjs +995 -0
  5. package/package.json +33 -42
  6. package/.claude-plugin/marketplace.json +0 -48
  7. package/.claude-plugin/plugin.json +0 -70
  8. package/agent-preamble/preamble.md +0 -314
  9. package/agents/flow-adversary.md +0 -202
  10. package/agents/flow-architect.md +0 -197
  11. package/agents/flow-brownfield-analyst.md +0 -142
  12. package/agents/flow-debugger.md +0 -321
  13. package/agents/flow-edge-hunter.md +0 -288
  14. package/agents/flow-executor.md +0 -269
  15. package/agents/flow-orchestrator.md +0 -145
  16. package/agents/flow-planner.md +0 -246
  17. package/agents/flow-product-designer.md +0 -159
  18. package/agents/flow-qa-engineer.md +0 -282
  19. package/agents/flow-researcher.md +0 -165
  20. package/agents/flow-reviewer.md +0 -303
  21. package/agents/flow-security-auditor.md +0 -401
  22. package/agents/flow-triage-analyst.md +0 -272
  23. package/agents/flow-ui-researcher.md +0 -229
  24. package/agents/flow-ux-designer.md +0 -221
  25. package/agents/flow-verifier.md +0 -349
  26. package/bin/curdx-flow +0 -5
  27. package/bin/curdx-flow.js +0 -54
  28. package/cli/README.md +0 -104
  29. package/cli/doctor-workflow.js +0 -483
  30. package/cli/doctor.js +0 -73
  31. package/cli/help.js +0 -59
  32. package/cli/install-bundled-mcps.js +0 -37
  33. package/cli/install-companions.js +0 -19
  34. package/cli/install-context7-config.js +0 -80
  35. package/cli/install-curdx-plugin.js +0 -96
  36. package/cli/install-language.js +0 -35
  37. package/cli/install-next-steps.js +0 -29
  38. package/cli/install-options.js +0 -9
  39. package/cli/install-paths.js +0 -52
  40. package/cli/install-recommended-plugins.js +0 -104
  41. package/cli/install-required-plugins.js +0 -57
  42. package/cli/install-self-update.js +0 -62
  43. package/cli/install-workflow.js +0 -209
  44. package/cli/install.js +0 -101
  45. package/cli/lib/claude-commands.js +0 -41
  46. package/cli/lib/claude-ops.js +0 -47
  47. package/cli/lib/claude.js +0 -183
  48. package/cli/lib/config.js +0 -24
  49. package/cli/lib/doctor-claude-settings.js +0 -1186
  50. package/cli/lib/doctor-report.js +0 -978
  51. package/cli/lib/doctor-runtime-environment.js +0 -196
  52. package/cli/lib/frontmatter.js +0 -44
  53. package/cli/lib/json-schema.js +0 -57
  54. package/cli/lib/logging.js +0 -25
  55. package/cli/lib/process.js +0 -60
  56. package/cli/lib/prompts.js +0 -135
  57. package/cli/lib/runtime.js +0 -107
  58. package/cli/lib/semver.js +0 -109
  59. package/cli/lib/version.js +0 -12
  60. package/cli/protocols-body.md +0 -22
  61. package/cli/protocols.js +0 -162
  62. package/cli/registry.js +0 -123
  63. package/cli/router.js +0 -49
  64. package/cli/uninstall-actions.js +0 -360
  65. package/cli/uninstall-workflow.js +0 -146
  66. package/cli/uninstall.js +0 -42
  67. package/cli/upgrade-workflow.js +0 -80
  68. package/cli/upgrade.js +0 -91
  69. package/cli/utils.js +0 -40
  70. package/gates/adversarial-review-gate.md +0 -219
  71. package/gates/coverage-audit-gate.md +0 -182
  72. package/gates/devex-gate.md +0 -254
  73. package/gates/edge-case-gate.md +0 -194
  74. package/gates/karpathy-gate.md +0 -130
  75. package/gates/security-gate.md +0 -218
  76. package/gates/tdd-gate.md +0 -182
  77. package/gates/test-quality-gate.md +0 -59
  78. package/gates/verification-gate.md +0 -179
  79. package/hooks/hooks.json +0 -58
  80. package/hooks/scripts/common.sh +0 -46
  81. package/hooks/scripts/inject-karpathy.sh +0 -53
  82. package/hooks/scripts/quick-mode-guard.sh +0 -68
  83. package/hooks/scripts/session-start.sh +0 -90
  84. package/hooks/scripts/stop-watcher.sh +0 -230
  85. package/hooks/scripts/subagent-artifact-guard.sh +0 -159
  86. package/hooks/scripts/subagent-statusline.sh +0 -105
  87. package/knowledge/artifact-output-discipline.md +0 -24
  88. package/knowledge/artifact-summary-contracts.md +0 -50
  89. package/knowledge/atomic-commits.md +0 -262
  90. package/knowledge/claude-code-runtime-contracts.md +0 -219
  91. package/knowledge/epic-decomposition.md +0 -307
  92. package/knowledge/execution-strategies.md +0 -303
  93. package/knowledge/karpathy-guidelines.md +0 -219
  94. package/knowledge/planning-reviews.md +0 -211
  95. package/knowledge/poc-first-workflow.md +0 -223
  96. package/knowledge/review-feedback-intake.md +0 -57
  97. package/knowledge/spec-driven-development.md +0 -180
  98. package/knowledge/systematic-debugging.md +0 -378
  99. package/knowledge/two-stage-review.md +0 -249
  100. package/knowledge/wave-execution.md +0 -403
  101. package/monitors/monitors.json +0 -8
  102. package/monitors/scripts/flow-state-monitor.sh +0 -99
  103. package/output-styles/curdx-evidence-first.md +0 -34
  104. package/schemas/agent-frontmatter.schema.json +0 -63
  105. package/schemas/config.schema.json +0 -134
  106. package/schemas/gate-frontmatter.schema.json +0 -30
  107. package/schemas/hooks.schema.json +0 -115
  108. package/schemas/output-style-frontmatter.schema.json +0 -22
  109. package/schemas/plugin-manifest.schema.json +0 -436
  110. package/schemas/plugin-settings.schema.json +0 -29
  111. package/schemas/skill-frontmatter.schema.json +0 -177
  112. package/schemas/spec-frontmatter.schema.json +0 -42
  113. package/schemas/spec-state.schema.json +0 -147
  114. package/settings.json +0 -7
  115. package/skills/brownfield-index/SKILL.md +0 -53
  116. package/skills/brownfield-index/references/applicability.md +0 -12
  117. package/skills/brownfield-index/references/handoff.md +0 -8
  118. package/skills/brownfield-index/references/index-contract.md +0 -10
  119. package/skills/browser-qa/SKILL.md +0 -39
  120. package/skills/browser-qa/references/handoff.md +0 -6
  121. package/skills/browser-qa/references/prerequisites.md +0 -10
  122. package/skills/browser-qa/references/qa-contract.md +0 -20
  123. package/skills/cancel/SKILL.md +0 -41
  124. package/skills/cancel/references/destructive-mode.md +0 -17
  125. package/skills/cancel/references/reporting.md +0 -18
  126. package/skills/cancel/references/state-recovery.md +0 -30
  127. package/skills/cancel/references/target-resolution.md +0 -7
  128. package/skills/debug/SKILL.md +0 -45
  129. package/skills/debug/references/context-gathering.md +0 -11
  130. package/skills/debug/references/failure-guard.md +0 -25
  131. package/skills/debug/references/intake.md +0 -12
  132. package/skills/debug/references/phase-workflow.md +0 -34
  133. package/skills/debug/references/reporting.md +0 -20
  134. package/skills/epic/SKILL.md +0 -39
  135. package/skills/epic/references/epic-artifacts.md +0 -20
  136. package/skills/epic/references/epic-intake.md +0 -9
  137. package/skills/epic/references/slice-handoff.md +0 -16
  138. package/skills/fast/SKILL.md +0 -62
  139. package/skills/fast/references/applicability.md +0 -25
  140. package/skills/fast/references/clarification.md +0 -20
  141. package/skills/fast/references/execution-contract.md +0 -56
  142. package/skills/help/SKILL.md +0 -55
  143. package/skills/help/references/dispatch.md +0 -20
  144. package/skills/help/references/overview.md +0 -39
  145. package/skills/help/references/troubleshoot.md +0 -47
  146. package/skills/help/references/workflow.md +0 -37
  147. package/skills/implement/SKILL.md +0 -96
  148. package/skills/implement/references/error-recovery.md +0 -36
  149. package/skills/implement/references/linear-execution.md +0 -32
  150. package/skills/implement/references/preflight.md +0 -43
  151. package/skills/implement/references/progress-contract.md +0 -32
  152. package/skills/implement/references/state-init.md +0 -33
  153. package/skills/implement/references/stop-hook-execution.md +0 -36
  154. package/skills/implement/references/strategy-router.md +0 -38
  155. package/skills/implement/references/subagent-execution.md +0 -43
  156. package/skills/implement/references/wave-execution.md +0 -162
  157. package/skills/init/SKILL.md +0 -49
  158. package/skills/init/references/gitignore-and-health.md +0 -26
  159. package/skills/init/references/next-steps.md +0 -22
  160. package/skills/init/references/preflight.md +0 -15
  161. package/skills/init/references/scaffold-contract.md +0 -27
  162. package/skills/review/SKILL.md +0 -82
  163. package/skills/review/references/optional-passes.md +0 -48
  164. package/skills/review/references/preflight.md +0 -38
  165. package/skills/review/references/report-contract.md +0 -49
  166. package/skills/review/references/reporting.md +0 -20
  167. package/skills/review/references/stage-execution.md +0 -32
  168. package/skills/security-audit/SKILL.md +0 -47
  169. package/skills/security-audit/references/audit-contract.md +0 -21
  170. package/skills/security-audit/references/gate-handoff.md +0 -8
  171. package/skills/security-audit/references/scope-and-depth.md +0 -9
  172. package/skills/spec/SKILL.md +0 -100
  173. package/skills/spec/references/artifact-landing.md +0 -31
  174. package/skills/spec/references/phase-execution.md +0 -50
  175. package/skills/spec/references/planning-review.md +0 -31
  176. package/skills/spec/references/preflight-and-routing.md +0 -46
  177. package/skills/spec/references/reporting.md +0 -21
  178. package/skills/start/SKILL.md +0 -84
  179. package/skills/start/references/branch-routing.md +0 -51
  180. package/skills/start/references/mode-semantics.md +0 -12
  181. package/skills/start/references/preflight.md +0 -13
  182. package/skills/start/references/reporting.md +0 -20
  183. package/skills/start/references/state-seeding.md +0 -44
  184. package/skills/start/references/workflow-handoff.md +0 -26
  185. package/skills/status/SKILL.md +0 -41
  186. package/skills/status/references/gather-contract.md +0 -27
  187. package/skills/status/references/health-rules.md +0 -27
  188. package/skills/status/references/output-contract.md +0 -24
  189. package/skills/status/references/preflight.md +0 -10
  190. package/skills/status/references/recovery-hints.md +0 -18
  191. package/skills/ui-sketch/SKILL.md +0 -39
  192. package/skills/ui-sketch/references/brief-intake.md +0 -10
  193. package/skills/ui-sketch/references/iteration-handoff.md +0 -5
  194. package/skills/ui-sketch/references/variant-contract.md +0 -15
  195. package/skills/verify/SKILL.md +0 -56
  196. package/skills/verify/references/evidence-workflow.md +0 -39
  197. package/skills/verify/references/output-contract.md +0 -23
  198. package/skills/verify/references/preflight.md +0 -11
  199. package/skills/verify/references/report-handoff.md +0 -35
  200. package/skills/verify/references/strict-mode.md +0 -12
  201. package/templates/CONTEXT.md.tmpl +0 -53
  202. package/templates/PROJECT.md.tmpl +0 -59
  203. package/templates/ROADMAP.md.tmpl +0 -50
  204. package/templates/STATE.md.tmpl +0 -49
  205. package/templates/config.json.tmpl +0 -51
  206. package/templates/design.md.tmpl +0 -83
  207. package/templates/progress.md.tmpl +0 -77
  208. package/templates/requirements.md.tmpl +0 -76
  209. package/templates/research.md.tmpl +0 -83
  210. package/templates/tasks.md.tmpl +0 -107
@@ -1,209 +0,0 @@
1
- import { spawn } from "node:child_process";
2
-
3
- import { installRecommendedPlugins } from "./install-companions.js";
4
- import { printNextSteps } from "./install-next-steps.js";
5
- import { parseInstallOptions } from "./install-options.js";
6
- import {
7
- getMarketplaceLabel,
8
- getMarketplaceSource,
9
- shouldUseOfflineInstall,
10
- } from "./install-paths.js";
11
- import { injectGlobalProtocols, GLOBAL_CLAUDE_MD } from "./protocols.js";
12
- import { checkAndUpdateSelf } from "./install-self-update.js";
13
- import {
14
- claudeVersion,
15
- color,
16
- intro,
17
- listPlugins,
18
- log,
19
- select,
20
- } from "./utils.js";
21
-
22
- export const INSTALL_STEP_COUNT = 5;
23
-
24
- export function createInstallContext(args = []) {
25
- const options = parseInstallOptions(args);
26
- const useOffline = shouldUseOfflineInstall({ forceOnline: options.forceOnline });
27
-
28
- return {
29
- ...options,
30
- args,
31
- useOffline,
32
- marketplaceSource: getMarketplaceSource(useOffline),
33
- marketplaceLabel: getMarketplaceLabel(useOffline),
34
- };
35
- }
36
-
37
- export async function maybeRestartWithUpdatedCli(
38
- context,
39
- {
40
- checkAndUpdateSelfImpl = checkAndUpdateSelf,
41
- spawnImpl = spawn,
42
- logImpl = log,
43
- exitImpl = process.exit,
44
- } = {}
45
- ) {
46
- if (context.skipSelfUpdate) {
47
- return false;
48
- }
49
-
50
- const updateResult = await checkAndUpdateSelfImpl();
51
- if (!updateResult.updated) {
52
- return false;
53
- }
54
-
55
- logImpl.info("Restarting with updated version...");
56
- const child = spawnImpl(
57
- process.execPath,
58
- [updateResult.entryPath, "install", ...context.args, "--skip-self-update"],
59
- {
60
- stdio: "inherit",
61
- shell: false,
62
- }
63
- );
64
-
65
- await new Promise((resolve) => {
66
- child.on("close", (code) => {
67
- exitImpl(code || 0);
68
- resolve();
69
- });
70
- });
71
-
72
- return true;
73
- }
74
-
75
- export async function renderInstallIntro(
76
- { yes },
77
- { introImpl = intro, logImpl = log, isTTY = process.stdout.isTTY } = {}
78
- ) {
79
- if (isTTY && !yes) {
80
- await introImpl("🚀 CurdX-Flow Installer");
81
- return;
82
- }
83
-
84
- logImpl.title("🚀 CurdX-Flow Installer");
85
- }
86
-
87
- export function ensureClaudeCliAvailable(
88
- { logImpl = log, claudeVersionImpl = claudeVersion, exitImpl = process.exit } = {}
89
- ) {
90
- logImpl.blank();
91
- logImpl.step(1, INSTALL_STEP_COUNT, "Checking claude CLI...");
92
-
93
- const version = claudeVersionImpl();
94
- if (!version) {
95
- logImpl.err(
96
- "claude CLI not found. Install Claude Code from https://code.claude.com first."
97
- );
98
- exitImpl(1);
99
- return null;
100
- }
101
-
102
- logImpl.ok(`claude CLI found (${version})`);
103
- return version;
104
- }
105
-
106
- export function snapshotCurdxFlowInstall({ listPluginsImpl = listPlugins } = {}) {
107
- return listPluginsImpl().find((plugin) => plugin.name === "curdx-flow");
108
- }
109
-
110
- export async function resolveExistingInstallationAction(
111
- { prevCurdxFlow, yes, language },
112
- { selectImpl = select, logImpl = log, exitImpl = process.exit } = {}
113
- ) {
114
- if (!prevCurdxFlow || yes) {
115
- return { action: null, continueInstall: true };
116
- }
117
-
118
- logImpl.blank();
119
- const action = await selectImpl({
120
- message: language === "zh"
121
- ? "检测到已安装的版本。如何继续?"
122
- : "Existing installation detected. How would you like to proceed?",
123
- options: [
124
- {
125
- value: "upgrade",
126
- label: language === "zh" ? "升级到最新版本" : "Upgrade to latest version",
127
- hint: language === "zh"
128
- ? `当前: v${prevCurdxFlow.version}`
129
- : `Current: v${prevCurdxFlow.version}`,
130
- },
131
- {
132
- value: "reinstall",
133
- label: language === "zh" ? "重新安装(保留配置)" : "Reinstall (preserve config)",
134
- },
135
- {
136
- value: "reconfigure",
137
- label: language === "zh" ? "重新配置插件" : "Reconfigure plugins",
138
- },
139
- {
140
- value: "cancel",
141
- label: language === "zh" ? "取消" : "Cancel",
142
- },
143
- ],
144
- initialValue: "upgrade",
145
- });
146
-
147
- if (action === "cancel") {
148
- logImpl.info(language === "zh" ? "安装已取消" : "Installation cancelled");
149
- exitImpl(0);
150
- return { action, continueInstall: false };
151
- }
152
-
153
- if (action === "reconfigure") {
154
- logImpl.info(
155
- language === "zh"
156
- ? "重新配置模式:将重新提示插件选择和 API key 配置"
157
- : "Reconfigure mode: will re-prompt for plugin selection and API key configuration"
158
- );
159
- }
160
-
161
- return { action, continueInstall: true };
162
- }
163
-
164
- export async function runRecommendedPluginsStep(
165
- { noDeps, all, yes, language },
166
- {
167
- logImpl = log,
168
- installRecommendedPluginsImpl = installRecommendedPlugins,
169
- printNextStepsImpl = printNextSteps,
170
- } = {}
171
- ) {
172
- if (noDeps) {
173
- logImpl.blank();
174
- logImpl.step(4, INSTALL_STEP_COUNT, "Recommended plugins");
175
- logImpl.info("Skipping recommended plugins (--no-deps)");
176
- printNextStepsImpl();
177
- return false;
178
- }
179
-
180
- const installedRecommended = await installRecommendedPluginsImpl({ all, yes, language });
181
- if (!installedRecommended) {
182
- printNextStepsImpl();
183
- return false;
184
- }
185
-
186
- return true;
187
- }
188
-
189
- export function injectGlobalProtocolsStep(
190
- { logImpl = log, injectGlobalProtocolsImpl = injectGlobalProtocols } = {}
191
- ) {
192
- logImpl.blank();
193
- logImpl.step(5, INSTALL_STEP_COUNT, "Injecting global protocols into ~/.claude/CLAUDE.md...");
194
-
195
- try {
196
- const result = injectGlobalProtocolsImpl();
197
- if (result.action === "created") {
198
- logImpl.ok(`Global protocols injected ${color.dim(`(${GLOBAL_CLAUDE_MD})`)}`);
199
- } else if (result.action === "appended") {
200
- logImpl.ok(`Global protocols appended ${color.dim(`(${GLOBAL_CLAUDE_MD})`)}`);
201
- } else if (result.action === "upgraded") {
202
- logImpl.ok(`Global protocols upgraded ${color.dim(`(${GLOBAL_CLAUDE_MD})`)}`);
203
- } else {
204
- logImpl.info(`Global protocols up to date ${color.dim(`(${GLOBAL_CLAUDE_MD})`)}`);
205
- }
206
- } catch (err) {
207
- logImpl.warn(`Protocol injection failed: ${err.message} ${color.dim("(non-blocking)")}`);
208
- }
209
- }
package/cli/install.js DELETED
@@ -1,101 +0,0 @@
1
- /**
2
- * install command — install curdx-flow plugin + optional recommended plugins.
3
- */
4
-
5
- import {
6
- addRequiredPluginMarketplaces,
7
- installRequiredPlugins,
8
- registerBundledMcps,
9
- } from "./install-companions.js";
10
- import {
11
- addCurdxMarketplace,
12
- installCurdxFlowPlugin,
13
- } from "./install-curdx-plugin.js";
14
- import { resolveInstallLanguage } from "./install-language.js";
15
- import { printNextSteps } from "./install-next-steps.js";
16
- import { readShippedVersion } from "./install-paths.js";
17
- import {
18
- createInstallContext,
19
- ensureClaudeCliAvailable,
20
- injectGlobalProtocolsStep,
21
- maybeRestartWithUpdatedCli,
22
- renderInstallIntro,
23
- resolveExistingInstallationAction,
24
- runRecommendedPluginsStep,
25
- snapshotCurdxFlowInstall,
26
- } from "./install-workflow.js";
27
-
28
- export async function install(args = []) {
29
- const context = createInstallContext(args);
30
-
31
- if (await maybeRestartWithUpdatedCli(context)) {
32
- return;
33
- }
34
-
35
- await renderInstallIntro(context);
36
-
37
- // ---------- Step 0: Language selection ----------
38
- const { language, config } = await resolveInstallLanguage({ yes: context.yes });
39
-
40
- // ---------- Step 1: Check claude CLI ----------
41
- ensureClaudeCliAvailable();
42
-
43
- // Snapshot curdx-flow's pre-install version BEFORE Step 2 touches the
44
- // marketplace. Step 2 does `claude plugin marketplace remove` + `add` to
45
- // rebind to the current source, and the remove side-effect also drops
46
- // any plugins installed from that marketplace. If we only call
47
- // listPlugins() in Step 3, curdx-flow is already gone from the list and
48
- // we can't tell a fresh install apart from an upgrade — the Step 3
49
- // output then incorrectly says "installed" for both cases.
50
- const prevCurdxFlow = snapshotCurdxFlowInstall();
51
-
52
- // ---------- Step 1.5: Existing installation action menu ----------
53
- const existingInstall = await resolveExistingInstallationAction({
54
- prevCurdxFlow,
55
- yes: context.yes,
56
- language,
57
- });
58
- if (!existingInstall.continueInstall) {
59
- return;
60
- }
61
-
62
- await addCurdxMarketplace(context);
63
-
64
- // Claude Code resolves plugin dependencies during install. Register
65
- // required companion marketplaces before installing curdx-flow so its
66
- // cross-marketplace dependency on Context7 can be satisfied immediately.
67
- await addRequiredPluginMarketplaces({ logWarnings: false });
68
-
69
- // ---------- Step 3: Install curdx-flow plugin ----------
70
- // Read the version the marketplace is shipping so we can decide whether an
71
- // already-installed plugin needs an update (same name but stale version
72
- // previously silently skipped the upgrade — caused the beta.1 → beta.7 drift).
73
- const shippedVersion = readShippedVersion();
74
- await installCurdxFlowPlugin({ prevCurdxFlow, shippedVersion });
75
-
76
- // ---------- Step 3.5: Install required plugins + register user-level MCPs ----------
77
- await installRequiredPlugins({
78
- yes: context.yes,
79
- language,
80
- config,
81
- skipMarketplaceAdd: true,
82
- });
83
-
84
- // Beta.12: direct MCPs migrated from plugin.json bundling. See cli/registry.js
85
- // for the rationale. Context7 now uses Upstash's official plugin instead.
86
- await registerBundledMcps();
87
-
88
- // ---------- Step 4: Recommended plugins ----------
89
- const installedRecommended = await runRecommendedPluginsStep({
90
- noDeps: context.noDeps,
91
- all: context.all,
92
- yes: context.yes,
93
- language,
94
- });
95
- if (!installedRecommended) {
96
- return;
97
- }
98
-
99
- injectGlobalProtocolsStep();
100
- printNextSteps();
101
- }
@@ -1,41 +0,0 @@
1
- export function pluginMarketplaceAddArgs({ scope, marketplaceSource }) {
2
- return ["plugin", "marketplace", "add", "--scope", scope, marketplaceSource];
3
- }
4
-
5
- export function pluginMarketplaceUpdateArgs(marketplaceId) {
6
- return ["plugin", "marketplace", "update", marketplaceId];
7
- }
8
-
9
- export function pluginMarketplaceRemoveArgs(marketplaceId) {
10
- return ["plugin", "marketplace", "remove", marketplaceId];
11
- }
12
-
13
- export function pluginInstallArgs({ scope, installSpec }) {
14
- return ["plugin", "install", "--scope", scope, installSpec];
15
- }
16
-
17
- export function pluginUpdateArgs({ scope = "user", spec }) {
18
- return ["plugin", "update", "--scope", scope, spec];
19
- }
20
-
21
- export function pluginUninstallArgs({ scope, uninstallSpec, uninstallArgs = [] }) {
22
- return ["plugin", "uninstall", "--scope", scope, ...uninstallArgs, uninstallSpec];
23
- }
24
-
25
- export function mcpAddArgs({ scope = "user", name, command, args = [], env = [] }) {
26
- return [
27
- "mcp",
28
- "add",
29
- "--scope",
30
- scope,
31
- name,
32
- ...env.flatMap((value) => ["--env", value]),
33
- "--",
34
- command,
35
- ...args,
36
- ];
37
- }
38
-
39
- export function mcpRemoveArgs({ scope = "user", name }) {
40
- return ["mcp", "remove", "--scope", scope, name];
41
- }
@@ -1,47 +0,0 @@
1
- import { run } from "./process.js";
2
- import {
3
- mcpAddArgs,
4
- mcpRemoveArgs,
5
- pluginInstallArgs,
6
- pluginMarketplaceAddArgs,
7
- pluginMarketplaceRemoveArgs,
8
- pluginMarketplaceUpdateArgs,
9
- pluginUninstallArgs,
10
- pluginUpdateArgs,
11
- } from "./claude-commands.js";
12
-
13
- async function runClaude(args, { runner = run, silent = true } = {}) {
14
- return runner("claude", args, { silent });
15
- }
16
-
17
- export async function addPluginMarketplace(entry, options) {
18
- return runClaude(pluginMarketplaceAddArgs(entry), options);
19
- }
20
-
21
- export async function updatePluginMarketplace(marketplaceId, options) {
22
- return runClaude(pluginMarketplaceUpdateArgs(marketplaceId), options);
23
- }
24
-
25
- export async function removePluginMarketplace(marketplaceId, options) {
26
- return runClaude(pluginMarketplaceRemoveArgs(marketplaceId), options);
27
- }
28
-
29
- export async function installPlugin(entry, options) {
30
- return runClaude(pluginInstallArgs(entry), options);
31
- }
32
-
33
- export async function updatePlugin(spec, options) {
34
- return runClaude(pluginUpdateArgs({ spec }), options);
35
- }
36
-
37
- export async function uninstallPlugin(entry, options) {
38
- return runClaude(pluginUninstallArgs(entry), options);
39
- }
40
-
41
- export async function addMcp(entry, options) {
42
- return runClaude(mcpAddArgs(entry), options);
43
- }
44
-
45
- export async function removeMcp(entry, options) {
46
- return runClaude(mcpRemoveArgs(entry), options);
47
- }
package/cli/lib/claude.js DELETED
@@ -1,183 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
-
5
- import { has, runSync } from "./process.js";
6
-
7
- const HOME = homedir();
8
-
9
- export function claudeVersion() {
10
- if (!has("claude")) return null;
11
- const res = runSync("claude", ["--version"]);
12
- if (res.code !== 0) return null;
13
- const m = res.stdout.match(/(\d+\.\d+\.\d+)/);
14
- return m ? m[1] : res.stdout.trim().split("\n")[0];
15
- }
16
-
17
- function normalizePluginError(error) {
18
- if (typeof error === "string") {
19
- return error;
20
- }
21
- if (error && typeof error === "object") {
22
- return error.message || error.code || JSON.stringify(error);
23
- }
24
- return String(error);
25
- }
26
-
27
- export function parsePluginListJson(output) {
28
- const trimmed = String(output || "").trim();
29
- if (!trimmed.startsWith("[")) {
30
- return null;
31
- }
32
-
33
- const arr = JSON.parse(trimmed);
34
- return arr.map((p) => {
35
- const id = String(p.id || p.name || "");
36
- const errors = Array.isArray(p.errors)
37
- ? p.errors.map(normalizePluginError).filter(Boolean)
38
- : [];
39
- const enabled = p.enabled !== false;
40
-
41
- return {
42
- id,
43
- name: id.split("@")[0],
44
- marketplaceId: id.split("@")[1] || undefined,
45
- version: p.version,
46
- status: errors.length > 0 ? "failed" : enabled ? "enabled" : "disabled",
47
- scope: p.scope,
48
- errors,
49
- raw: JSON.stringify(p),
50
- };
51
- });
52
- }
53
-
54
- export function listPlugins() {
55
- const j = runSync("claude", ["plugin", "list", "--json"]);
56
- if (j.code === 0) {
57
- try {
58
- const plugins = parsePluginListJson(j.stdout);
59
- if (plugins) {
60
- return plugins;
61
- }
62
- } catch {
63
- // JSON parse failed; fall through to legacy text parser.
64
- }
65
- }
66
-
67
- const res = runSync("claude", ["plugin", "list"]);
68
- if (res.code !== 0) return [];
69
- const plugins = [];
70
- const blocks = res.stdout.split(/\n\s*❯\s*/).slice(1);
71
- for (const block of blocks) {
72
- const lines = block.split("\n");
73
- const id = lines[0].trim();
74
- const name = id.split("@")[0];
75
- const version = (block.match(/Version:\s*(\S+)/) || [])[1];
76
- const status = block.includes("✔")
77
- ? "enabled"
78
- : block.includes("✘")
79
- ? "failed"
80
- : "unknown";
81
- plugins.push({
82
- id,
83
- name,
84
- marketplaceId: id.split("@")[1],
85
- version,
86
- status,
87
- raw: block,
88
- });
89
- }
90
- return plugins;
91
- }
92
-
93
- export function listPluginMarketplaces() {
94
- const j = runSync("claude", ["plugin", "marketplace", "list", "--json"]);
95
- if (j.code === 0 && j.stdout.trim().startsWith("[")) {
96
- try {
97
- return JSON.parse(j.stdout);
98
- } catch {
99
- return [];
100
- }
101
- }
102
- return [];
103
- }
104
-
105
- export function findPluginByRegistryEntry(plugins, registryEntry) {
106
- return plugins.find(
107
- (plugin) => plugin.id === registryEntry.id || plugin.name === registryEntry.name
108
- );
109
- }
110
-
111
- export function hasMarketplace(marketplaces, registryEntry) {
112
- if (!registryEntry.marketplaceSource) return true;
113
- return marketplaces.some((marketplace) => marketplace.name === registryEntry.marketplaceId);
114
- }
115
-
116
- export function readUserMcpConfig() {
117
- try {
118
- const path = join(HOME, ".claude.json");
119
- if (!existsSync(path)) return new Map();
120
- const cfg = JSON.parse(readFileSync(path, "utf-8"));
121
- const servers = cfg?.mcpServers || {};
122
- return new Map(Object.entries(servers));
123
- } catch {
124
- return new Map();
125
- }
126
- }
127
-
128
- export function findDuplicateMcps(mcps, userConfig) {
129
- const duplicates = [];
130
- for (const m of mcps) {
131
- if (m.plugin && userConfig.has(m.name)) {
132
- duplicates.push({
133
- name: m.name,
134
- userConfig: userConfig.get(m.name),
135
- pluginEntry: m,
136
- });
137
- }
138
- }
139
- return duplicates;
140
- }
141
-
142
- export function listMcps() {
143
- const res = runSync("claude", ["mcp", "list"]);
144
- if (res.code !== 0) return [];
145
- return parseMcpList(res.stdout);
146
- }
147
-
148
- export function parseMcpList(output) {
149
- const mcps = [];
150
- for (const raw of output.split("\n")) {
151
- const line = raw.trimEnd();
152
- if (!line) continue;
153
- if (line.startsWith("Checking") || line.startsWith("checking")) continue;
154
-
155
- const statusSplit = line.lastIndexOf(" - ");
156
- if (statusSplit === -1) continue;
157
- const statusRaw = line.slice(statusSplit + 3).trim();
158
- const beforeStatus = line.slice(0, statusSplit);
159
- const nameSplit = beforeStatus.indexOf(": ");
160
- if (nameSplit === -1) continue;
161
- const fullName = beforeStatus.slice(0, nameSplit).trim();
162
- const command = beforeStatus.slice(nameSplit + 2).trim();
163
-
164
- let plugin = null;
165
- let name = fullName;
166
- if (fullName.startsWith("plugin:")) {
167
- const parts = fullName.split(":");
168
- if (parts.length >= 3) {
169
- plugin = parts[1];
170
- name = parts.slice(2).join(":");
171
- }
172
- }
173
-
174
- const status = /Connected|✓/.test(statusRaw)
175
- ? "connected"
176
- : /Failed|✗/.test(statusRaw)
177
- ? "failed"
178
- : "unknown";
179
-
180
- mcps.push({ name, plugin, fullName, status, command });
181
- }
182
- return mcps;
183
- }
package/cli/lib/config.js DELETED
@@ -1,24 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { homedir } from "node:os";
3
- import { join } from "node:path";
4
-
5
- const CONFIG_DIR = join(homedir(), ".claude");
6
- export const CONFIG_FILE = join(CONFIG_DIR, "curdx-flow-config.json");
7
-
8
- export function readConfig() {
9
- if (!existsSync(CONFIG_FILE)) {
10
- return {};
11
- }
12
- try {
13
- return JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
14
- } catch {
15
- return {};
16
- }
17
- }
18
-
19
- export function writeConfig(config) {
20
- if (!existsSync(CONFIG_DIR)) {
21
- mkdirSync(CONFIG_DIR, { recursive: true });
22
- }
23
- writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
24
- }