@curdx/flow 3.0.0 → 3.2.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 (219) hide show
  1. package/CHANGELOG.md +33 -82
  2. package/LICENSE +1 -1
  3. package/README.md +28 -129
  4. package/dist/index.mjs +1165 -0
  5. package/package.json +33 -44
  6. package/.claude-plugin/marketplace.json +0 -48
  7. package/.claude-plugin/plugin.json +0 -52
  8. package/agent-preamble/preamble.md +0 -314
  9. package/agents/flow-adversary.md +0 -203
  10. package/agents/flow-architect.md +0 -198
  11. package/agents/flow-brownfield-analyst.md +0 -143
  12. package/agents/flow-debugger.md +0 -321
  13. package/agents/flow-edge-hunter.md +0 -289
  14. package/agents/flow-executor.md +0 -269
  15. package/agents/flow-orchestrator.md +0 -145
  16. package/agents/flow-planner.md +0 -247
  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 -166
  20. package/agents/flow-reviewer.md +0 -304
  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 -230
  24. package/agents/flow-ux-designer.md +0 -221
  25. package/agents/flow-verifier.md +0 -350
  26. package/bin/curdx-flow +0 -5
  27. package/bin/curdx-flow-state +0 -104
  28. package/bin/curdx-flow.js +0 -54
  29. package/cli/README.md +0 -104
  30. package/cli/doctor-workflow.js +0 -483
  31. package/cli/doctor.js +0 -73
  32. package/cli/help.js +0 -59
  33. package/cli/install-bundled-mcps.js +0 -37
  34. package/cli/install-companions.js +0 -19
  35. package/cli/install-context7-config.js +0 -80
  36. package/cli/install-curdx-plugin.js +0 -96
  37. package/cli/install-language.js +0 -35
  38. package/cli/install-next-steps.js +0 -29
  39. package/cli/install-options.js +0 -9
  40. package/cli/install-paths.js +0 -52
  41. package/cli/install-recommended-plugins.js +0 -104
  42. package/cli/install-required-plugins.js +0 -57
  43. package/cli/install-self-update.js +0 -62
  44. package/cli/install-workflow.js +0 -209
  45. package/cli/install.js +0 -101
  46. package/cli/lib/claude-commands.js +0 -41
  47. package/cli/lib/claude-ops.js +0 -47
  48. package/cli/lib/claude.js +0 -183
  49. package/cli/lib/config.js +0 -24
  50. package/cli/lib/doctor-claude-settings.js +0 -1186
  51. package/cli/lib/doctor-report.js +0 -978
  52. package/cli/lib/doctor-runtime-environment.js +0 -196
  53. package/cli/lib/frontmatter.js +0 -44
  54. package/cli/lib/json-schema.js +0 -57
  55. package/cli/lib/logging.js +0 -25
  56. package/cli/lib/process.js +0 -60
  57. package/cli/lib/prompts.js +0 -135
  58. package/cli/lib/runtime.js +0 -107
  59. package/cli/lib/semver.js +0 -109
  60. package/cli/lib/version.js +0 -12
  61. package/cli/protocols-body.md +0 -22
  62. package/cli/protocols.js +0 -162
  63. package/cli/registry.js +0 -123
  64. package/cli/router.js +0 -49
  65. package/cli/uninstall-actions.js +0 -360
  66. package/cli/uninstall-workflow.js +0 -146
  67. package/cli/uninstall.js +0 -42
  68. package/cli/upgrade-workflow.js +0 -80
  69. package/cli/upgrade.js +0 -91
  70. package/cli/utils.js +0 -40
  71. package/gates/adversarial-review-gate.md +0 -219
  72. package/gates/coverage-audit-gate.md +0 -182
  73. package/gates/devex-gate.md +0 -254
  74. package/gates/edge-case-gate.md +0 -194
  75. package/gates/karpathy-gate.md +0 -130
  76. package/gates/security-gate.md +0 -218
  77. package/gates/tdd-gate.md +0 -182
  78. package/gates/test-quality-gate.md +0 -59
  79. package/gates/verification-gate.md +0 -179
  80. package/hooks/hooks.json +0 -130
  81. package/hooks/scripts/common.sh +0 -237
  82. package/hooks/scripts/config-change-guard.sh +0 -94
  83. package/hooks/scripts/flow-context-watch.sh +0 -94
  84. package/hooks/scripts/inject-karpathy.sh +0 -53
  85. package/hooks/scripts/quick-mode-guard.sh +0 -69
  86. package/hooks/scripts/session-start.sh +0 -94
  87. package/hooks/scripts/session-title.sh +0 -87
  88. package/hooks/scripts/stop-watcher.sh +0 -231
  89. package/hooks/scripts/subagent-artifact-guard.sh +0 -92
  90. package/hooks/scripts/subagent-statusline.sh +0 -111
  91. package/hooks/scripts/task-lifecycle-guard.sh +0 -106
  92. package/hooks/scripts/teammate-idle-guard.sh +0 -83
  93. package/knowledge/artifact-output-discipline.md +0 -24
  94. package/knowledge/artifact-summary-contracts.md +0 -50
  95. package/knowledge/atomic-commits.md +0 -262
  96. package/knowledge/claude-code-runtime-contracts.md +0 -240
  97. package/knowledge/epic-decomposition.md +0 -307
  98. package/knowledge/execution-strategies.md +0 -303
  99. package/knowledge/karpathy-guidelines.md +0 -219
  100. package/knowledge/planning-reviews.md +0 -211
  101. package/knowledge/poc-first-workflow.md +0 -223
  102. package/knowledge/review-feedback-intake.md +0 -57
  103. package/knowledge/spec-driven-development.md +0 -180
  104. package/knowledge/systematic-debugging.md +0 -378
  105. package/knowledge/two-stage-review.md +0 -249
  106. package/knowledge/wave-execution.md +0 -403
  107. package/monitors/monitors.json +0 -8
  108. package/monitors/scripts/flow-state-monitor.sh +0 -102
  109. package/output-styles/curdx-evidence-first.md +0 -34
  110. package/output-styles/curdx-fast-mode.md +0 -42
  111. package/output-styles/curdx-spec-mode.md +0 -46
  112. package/schemas/agent-frontmatter.schema.json +0 -66
  113. package/schemas/config.schema.json +0 -134
  114. package/schemas/gate-frontmatter.schema.json +0 -30
  115. package/schemas/hooks.schema.json +0 -115
  116. package/schemas/output-style-frontmatter.schema.json +0 -22
  117. package/schemas/plugin-manifest.schema.json +0 -436
  118. package/schemas/plugin-settings.schema.json +0 -29
  119. package/schemas/skill-frontmatter.schema.json +0 -177
  120. package/schemas/spec-frontmatter.schema.json +0 -42
  121. package/schemas/spec-state.schema.json +0 -165
  122. package/settings.json +0 -8
  123. package/skills/brownfield-index/SKILL.md +0 -53
  124. package/skills/brownfield-index/references/applicability.md +0 -12
  125. package/skills/brownfield-index/references/handoff.md +0 -8
  126. package/skills/brownfield-index/references/index-contract.md +0 -10
  127. package/skills/browser-qa/SKILL.md +0 -39
  128. package/skills/browser-qa/references/handoff.md +0 -6
  129. package/skills/browser-qa/references/prerequisites.md +0 -10
  130. package/skills/browser-qa/references/qa-contract.md +0 -20
  131. package/skills/cancel/SKILL.md +0 -41
  132. package/skills/cancel/references/destructive-mode.md +0 -17
  133. package/skills/cancel/references/reporting.md +0 -18
  134. package/skills/cancel/references/state-recovery.md +0 -30
  135. package/skills/cancel/references/target-resolution.md +0 -7
  136. package/skills/debug/SKILL.md +0 -45
  137. package/skills/debug/references/context-gathering.md +0 -11
  138. package/skills/debug/references/failure-guard.md +0 -25
  139. package/skills/debug/references/intake.md +0 -12
  140. package/skills/debug/references/phase-workflow.md +0 -34
  141. package/skills/debug/references/reporting.md +0 -20
  142. package/skills/epic/SKILL.md +0 -39
  143. package/skills/epic/references/epic-artifacts.md +0 -20
  144. package/skills/epic/references/epic-intake.md +0 -9
  145. package/skills/epic/references/slice-handoff.md +0 -16
  146. package/skills/fast/SKILL.md +0 -62
  147. package/skills/fast/references/applicability.md +0 -25
  148. package/skills/fast/references/clarification.md +0 -20
  149. package/skills/fast/references/execution-contract.md +0 -56
  150. package/skills/help/SKILL.md +0 -55
  151. package/skills/help/references/dispatch.md +0 -20
  152. package/skills/help/references/overview.md +0 -39
  153. package/skills/help/references/troubleshoot.md +0 -47
  154. package/skills/help/references/workflow.md +0 -37
  155. package/skills/implement/SKILL.md +0 -104
  156. package/skills/implement/references/error-recovery.md +0 -36
  157. package/skills/implement/references/linear-execution.md +0 -43
  158. package/skills/implement/references/native-task-sync.md +0 -107
  159. package/skills/implement/references/preflight.md +0 -43
  160. package/skills/implement/references/progress-contract.md +0 -36
  161. package/skills/implement/references/state-init.md +0 -36
  162. package/skills/implement/references/stop-hook-execution.md +0 -50
  163. package/skills/implement/references/strategy-router.md +0 -38
  164. package/skills/implement/references/subagent-execution.md +0 -57
  165. package/skills/implement/references/wave-execution.md +0 -180
  166. package/skills/init/SKILL.md +0 -49
  167. package/skills/init/references/gitignore-and-health.md +0 -26
  168. package/skills/init/references/next-steps.md +0 -22
  169. package/skills/init/references/preflight.md +0 -15
  170. package/skills/init/references/scaffold-contract.md +0 -27
  171. package/skills/review/SKILL.md +0 -82
  172. package/skills/review/references/optional-passes.md +0 -48
  173. package/skills/review/references/preflight.md +0 -38
  174. package/skills/review/references/report-contract.md +0 -49
  175. package/skills/review/references/reporting.md +0 -20
  176. package/skills/review/references/stage-execution.md +0 -32
  177. package/skills/security-audit/SKILL.md +0 -47
  178. package/skills/security-audit/references/audit-contract.md +0 -21
  179. package/skills/security-audit/references/gate-handoff.md +0 -8
  180. package/skills/security-audit/references/scope-and-depth.md +0 -9
  181. package/skills/spec/SKILL.md +0 -100
  182. package/skills/spec/references/artifact-landing.md +0 -31
  183. package/skills/spec/references/phase-execution.md +0 -50
  184. package/skills/spec/references/planning-review.md +0 -31
  185. package/skills/spec/references/preflight-and-routing.md +0 -46
  186. package/skills/spec/references/reporting.md +0 -21
  187. package/skills/start/SKILL.md +0 -84
  188. package/skills/start/references/branch-routing.md +0 -51
  189. package/skills/start/references/mode-semantics.md +0 -12
  190. package/skills/start/references/preflight.md +0 -13
  191. package/skills/start/references/reporting.md +0 -20
  192. package/skills/start/references/state-seeding.md +0 -44
  193. package/skills/start/references/workflow-handoff.md +0 -26
  194. package/skills/status/SKILL.md +0 -41
  195. package/skills/status/references/gather-contract.md +0 -30
  196. package/skills/status/references/health-rules.md +0 -27
  197. package/skills/status/references/output-contract.md +0 -25
  198. package/skills/status/references/preflight.md +0 -10
  199. package/skills/status/references/recovery-hints.md +0 -18
  200. package/skills/ui-sketch/SKILL.md +0 -39
  201. package/skills/ui-sketch/references/brief-intake.md +0 -10
  202. package/skills/ui-sketch/references/iteration-handoff.md +0 -5
  203. package/skills/ui-sketch/references/variant-contract.md +0 -15
  204. package/skills/verify/SKILL.md +0 -56
  205. package/skills/verify/references/evidence-workflow.md +0 -39
  206. package/skills/verify/references/output-contract.md +0 -23
  207. package/skills/verify/references/preflight.md +0 -11
  208. package/skills/verify/references/report-handoff.md +0 -35
  209. package/skills/verify/references/strict-mode.md +0 -12
  210. package/templates/CONTEXT.md.tmpl +0 -53
  211. package/templates/PROJECT.md.tmpl +0 -59
  212. package/templates/ROADMAP.md.tmpl +0 -50
  213. package/templates/STATE.md.tmpl +0 -49
  214. package/templates/config.json.tmpl +0 -51
  215. package/templates/design.md.tmpl +0 -83
  216. package/templates/progress.md.tmpl +0 -77
  217. package/templates/requirements.md.tmpl +0 -76
  218. package/templates/research.md.tmpl +0 -83
  219. package/templates/tasks.md.tmpl +0 -107
package/cli/doctor.js DELETED
@@ -1,73 +0,0 @@
1
- /**
2
- * doctor command — external health check (no need to enter Claude Code).
3
- */
4
-
5
- import {
6
- color,
7
- log,
8
- } from "./utils.js";
9
- import { buildDoctorReport } from "./lib/doctor-report.js";
10
- import {
11
- applyDoctorFixes,
12
- buildDoctorJsonPayload,
13
- collectDoctorData,
14
- createDoctorContext,
15
- printDoctorSummary,
16
- printVerboseDoctorDetails,
17
- renderReportLines,
18
- } from "./doctor-workflow.js";
19
-
20
- export async function doctor(
21
- args = [],
22
- {
23
- applyDoctorFixesImpl = applyDoctorFixes,
24
- buildDoctorJsonPayloadImpl = buildDoctorJsonPayload,
25
- buildDoctorReportImpl = buildDoctorReport,
26
- collectDoctorDataImpl = collectDoctorData,
27
- createDoctorContextImpl = createDoctorContext,
28
- printDoctorSummaryImpl = printDoctorSummary,
29
- printVerboseDoctorDetailsImpl = printVerboseDoctorDetails,
30
- renderReportLinesImpl = renderReportLines,
31
- logImpl = log,
32
- colorImpl = color,
33
- consoleImpl = console,
34
- processImpl = process,
35
- } = {}
36
- ) {
37
- const context = createDoctorContextImpl(args);
38
- let fixes = [];
39
-
40
- if (!context.json) {
41
- logImpl.title("🏥 CurdX-Flow Health Check");
42
- }
43
-
44
- const doctorData = await collectDoctorDataImpl();
45
- if (context.fix) {
46
- if (!context.json) {
47
- logImpl.info("Applying safe fixes...");
48
- }
49
- fixes = await applyDoctorFixesImpl(doctorData);
50
- if (fixes.length === 0 && !context.json) {
51
- logImpl.info("No automatic fixes available for the current environment");
52
- }
53
- }
54
- const report = buildDoctorReportImpl(doctorData);
55
-
56
- if (context.json) {
57
- const payload = buildDoctorJsonPayloadImpl({ context, doctorData, fixes, report });
58
- consoleImpl.log(JSON.stringify(payload, null, 2));
59
- processImpl.exitCode = report.errors > 0 ? 1 : 0;
60
- return;
61
- }
62
-
63
- renderReportLinesImpl(report.lines, { logImpl });
64
- for (const section of report.sections) {
65
- consoleImpl.log(`\n${colorImpl.bold(section.title)}`);
66
- renderReportLinesImpl(section.lines, { logImpl });
67
- }
68
-
69
- printDoctorSummaryImpl(report, { logImpl });
70
- if (context.verbose && doctorData.claudeVersionValue) {
71
- printVerboseDoctorDetailsImpl();
72
- }
73
- }
package/cli/help.js DELETED
@@ -1,59 +0,0 @@
1
- import { VERSION, color } from "./utils.js";
2
-
3
- export function printHelp() {
4
- console.log(`
5
- ${color.bold("curdx-flow")} ${color.dim(`v${VERSION}`)}
6
- CurdX-Flow installer & helper for Claude Code
7
-
8
- ${color.bold("USAGE")}
9
- npx @curdx/flow <command> [options]
10
-
11
- ${color.bold("COMMANDS")}
12
- ${color.cyan("install")} Install curdx-flow plugin + optional recommended plugins
13
- --all Install all recommended (skip prompt)
14
- --no-deps Only install curdx-flow, skip recommendations
15
- --online Fetch plugin from GitHub instead of using the
16
- local npm package (slower; default is offline
17
- when the plugin body is bundled)
18
-
19
- ${color.cyan("doctor")} Check health (claude CLI, plugin, MCPs, recommended)
20
- --fix Apply safe runtime fixes (bun/uv PATH symlinks)
21
- --json Emit machine-readable health report JSON
22
- --verbose Show raw plugin list details
23
-
24
- ${color.cyan("upgrade")} Update curdx-flow and recommended plugins to latest
25
-
26
- ${color.cyan("uninstall")} Remove curdx-flow plugin (and optionally recommended / artifacts)
27
- -y, --yes Skip confirmation, keep recommended + .flow/
28
- --keep-recommended Don't ask about pua/claude-mem/frontend-design
29
- --purge Also remove ~/.local/bin/bun, ~/.local/bin/uv symlinks
30
-
31
- ${color.bold("OPTIONS")}
32
- -v, --version Print version
33
- -h, --help Show this CLI usage summary
34
-
35
- ${color.dim("For the full command / workflow reference (including all slash")}
36
- ${color.dim("commands like /curdx-flow:start, /curdx-flow:spec, …) run:")}
37
- ${color.cyan("/curdx-flow:help")} ${color.dim("(inside Claude Code)")}
38
-
39
- ${color.bold("EXAMPLES")}
40
- ${color.dim("# First-time install with recommended plugins")}
41
- npx @curdx/flow install --all
42
-
43
- ${color.dim("# Check what's installed")}
44
- npx @curdx/flow doctor
45
-
46
- ${color.dim("# Update everything")}
47
- npx @curdx/flow upgrade
48
-
49
- ${color.bold("INITIALIZING A PROJECT")}
50
- Once curdx-flow is installed, initialize your project inside Claude Code:
51
-
52
- ${color.cyan("claude")}
53
- ${color.cyan("/curdx-flow:init")}
54
- ${color.cyan("/curdx-flow:start my-feature \"<description>\"")}
55
-
56
- ${color.bold("LEARN MORE")}
57
- https://github.com/curdx/curdx-flow
58
- `);
59
- }
@@ -1,37 +0,0 @@
1
- /**
2
- * Register MCP servers that curdx-flow depends on at user level via
3
- * `claude mcp add`. Source-of-truth list: cli/registry.js BUNDLED_MCPS.
4
- * Preserves existing user-level entries when mcp.preserveExisting is set.
5
- */
6
-
7
- import { addMcp } from "./lib/claude-ops.js";
8
- import { BUNDLED_MCPS } from "./registry.js";
9
- import { color, log, readUserMcpConfig, resultLastLine } from "./utils.js";
10
-
11
- export async function registerBundledMcps() {
12
- log.blank();
13
- log.info("Registering required MCP servers (user-level)...");
14
- const existingUserMcps = readUserMcpConfig();
15
- for (const mcp of BUNDLED_MCPS) {
16
- if (mcp.preserveExisting && existingUserMcps.has(mcp.name)) {
17
- const existing = existingUserMcps.get(mcp.name);
18
- log.info(
19
- ` ${mcp.name.padEnd(22)} ${color.dim(`already registered (${(existing.args || []).join(" ")}) — preserving`)}`
20
- );
21
- continue;
22
- }
23
- const r = await addMcp(mcp);
24
- if (r.code === 0) {
25
- log.ok(` ${mcp.name.padEnd(22)} ${color.dim("registered")}`);
26
- } else if (r.stderr.includes("already exists")) {
27
- log.info(` ${mcp.name.padEnd(22)} ${color.dim("already exists — skipped")}`);
28
- } else {
29
- log.warn(
30
- ` ${mcp.name.padEnd(22)} registration failed: ${resultLastLine(r)}`
31
- );
32
- log.info(
33
- ` Run manually: claude mcp add --scope user ${mcp.name} -- ${mcp.command} ${mcp.args.join(" ")}`
34
- );
35
- }
36
- }
37
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * Re-export barrel preserving the stable import surface. New callers should
3
- * import directly from the concern-specific modules below instead of going
4
- * through this barrel. Kept in place so existing imports in cli/install.js
5
- * and cli/install-workflow.js keep working unchanged.
6
- *
7
- * Concern split:
8
- * install-required-plugins.js — required Claude Code companion plugins
9
- * install-bundled-mcps.js — user-level MCP registration
10
- * install-recommended-plugins.js — optional recommended plugins
11
- * install-context7-config.js — legacy Context7 state reconciliation (private to required)
12
- */
13
-
14
- export {
15
- addRequiredPluginMarketplaces,
16
- installRequiredPlugins,
17
- } from "./install-required-plugins.js";
18
- export { registerBundledMcps } from "./install-bundled-mcps.js";
19
- export { installRecommendedPlugins } from "./install-recommended-plugins.js";
@@ -1,80 +0,0 @@
1
- /**
2
- * Reconcile legacy Context7 install state after the official plugin is
3
- * installed or refreshed. Private to the required-plugins concern; not
4
- * re-exported from install-companions.js.
5
- */
6
-
7
- import { removeMcp } from "./lib/claude-ops.js";
8
- import {
9
- color,
10
- log,
11
- readUserMcpConfig,
12
- resultLastLine,
13
- writeConfig,
14
- } from "./utils.js";
15
-
16
- export async function reconcileLegacyContext7InstallState(
17
- plugin,
18
- language,
19
- config,
20
- {
21
- removeMcpImpl = removeMcp,
22
- readUserMcpConfigImpl = readUserMcpConfig,
23
- writeConfigImpl = writeConfig,
24
- logImpl = log,
25
- } = {}
26
- ) {
27
- if (plugin.name !== "context7-plugin") return;
28
-
29
- let removedStoredApiKey = false;
30
- if (config && Object.hasOwn(config, "context7ApiKey")) {
31
- delete config.context7ApiKey;
32
- writeConfigImpl(config);
33
- removedStoredApiKey = true;
34
- logImpl.info(
35
- language === "zh"
36
- ? " 已移除旧的 Context7 API key 本地配置,当前官方插件不再使用该安装方式"
37
- : " Removed legacy local Context7 API key config; the official plugin no longer uses that install path"
38
- );
39
- }
40
-
41
- const userMcps = readUserMcpConfigImpl();
42
- if (!userMcps.has("context7")) {
43
- return {
44
- removedLegacyMcp: false,
45
- removedStoredApiKey,
46
- };
47
- }
48
-
49
- const result = await removeMcpImpl({ name: "context7" });
50
- if (result.code === 0) {
51
- logImpl.ok(
52
- language === "zh"
53
- ? " 已移除遗留的用户级 context7 MCP,避免与官方 Context7 插件重复注册"
54
- : " Removed legacy user-level context7 MCP so the official Context7 plugin is the only owner"
55
- );
56
- return {
57
- removedLegacyMcp: true,
58
- removedStoredApiKey,
59
- };
60
- }
61
-
62
- logImpl.warn(
63
- language === "zh"
64
- ? ` 清理旧的 context7 MCP 失败: ${resultLastLine(result)}`
65
- : ` Failed to remove legacy context7 MCP: ${resultLastLine(result)}`
66
- );
67
- logImpl.info(
68
- color.dim(
69
- language === "zh"
70
- ? " 手动运行: claude mcp remove --scope user context7"
71
- : " Run manually: claude mcp remove --scope user context7"
72
- )
73
- );
74
- return {
75
- removedLegacyMcp: false,
76
- removedStoredApiKey,
77
- };
78
- }
79
-
80
- export const installContext7Config = reconcileLegacyContext7InstallState;
@@ -1,96 +0,0 @@
1
- import { color, log, resultOutput } from "./utils.js";
2
- import {
3
- addPluginMarketplace,
4
- installPlugin,
5
- removePluginMarketplace,
6
- } from "./lib/claude-ops.js";
7
-
8
- const CURDX_FLOW_INSTALL_ENTRY = {
9
- scope: "user",
10
- installSpec: "curdx-flow@curdx-flow-marketplace",
11
- };
12
-
13
- export function resolveCurdxFlowInstallPlan({ prevCurdxFlow, shippedVersion }) {
14
- if (prevCurdxFlow && shippedVersion && prevCurdxFlow.version === shippedVersion) {
15
- return {
16
- intro: `curdx-flow already at v${prevCurdxFlow.version}, re-registering...`,
17
- success: `curdx-flow re-registered at v${shippedVersion}`,
18
- };
19
- }
20
-
21
- if (prevCurdxFlow && shippedVersion) {
22
- return {
23
- intro: `curdx-flow v${prevCurdxFlow.version} → v${shippedVersion}, installing...`,
24
- success: `curdx-flow upgraded to v${shippedVersion}`,
25
- };
26
- }
27
-
28
- if (prevCurdxFlow) {
29
- return {
30
- intro: `curdx-flow v${prevCurdxFlow.version} detected, re-registering...`,
31
- success: "curdx-flow re-registered",
32
- };
33
- }
34
-
35
- if (shippedVersion) {
36
- return {
37
- intro: null,
38
- success: `curdx-flow v${shippedVersion} installed`,
39
- };
40
- }
41
-
42
- return {
43
- intro: null,
44
- success: "curdx-flow installed",
45
- };
46
- }
47
-
48
- export async function addCurdxMarketplace({ marketplaceSource, marketplaceLabel, useOffline }) {
49
- log.blank();
50
- log.step(2, 5, `Adding curdx-flow marketplace from ${marketplaceLabel}...`);
51
-
52
- // Remove any existing marketplace with the same name so we get a clean
53
- // rebind to the chosen source. Errors are non-fatal (marketplace may
54
- // simply not exist yet).
55
- await removePluginMarketplace("curdx-flow-marketplace");
56
-
57
- const addRes = await addPluginMarketplace({ scope: "user", marketplaceSource });
58
- if (addRes.code !== 0 && !addRes.stderr.includes("already")) {
59
- log.warn(`marketplace add output: ${resultOutput(addRes)}`);
60
- } else {
61
- log.ok(
62
- `curdx-flow-marketplace added ${color.dim(useOffline ? "(offline, no GitHub fetch)" : "(from GitHub)")}`
63
- );
64
- }
65
- }
66
-
67
- export async function installCurdxFlowPlugin(
68
- { prevCurdxFlow, shippedVersion },
69
- {
70
- installPluginImpl = installPlugin,
71
- exitImpl = process.exit,
72
- logImpl = log,
73
- } = {}
74
- ) {
75
- logImpl.blank();
76
- logImpl.step(3, 5, "Installing curdx-flow plugin...");
77
-
78
- // Use the pre-Step-2 snapshot — by this point `claude plugin marketplace
79
- // remove` has already evicted the plugin, so listPlugins() here would
80
- // always return undefined for curdx-flow and we'd mis-report "installed"
81
- // when we actually upgraded (the bug reported by @wdx's beta.14 log).
82
- const plan = resolveCurdxFlowInstallPlan({ prevCurdxFlow, shippedVersion });
83
-
84
- if (plan.intro) {
85
- logImpl.info(plan.intro);
86
- }
87
-
88
- const result = await installPluginImpl(CURDX_FLOW_INSTALL_ENTRY);
89
- if (result.code !== 0) {
90
- logImpl.err(`Install failed: ${resultOutput(result)}`);
91
- exitImpl(1);
92
- return;
93
- }
94
-
95
- logImpl.ok(plan.success);
96
- }
@@ -1,35 +0,0 @@
1
- import { log, readConfig, select, writeConfig } from "./utils.js";
2
-
3
- export async function resolveInstallLanguage({ yes }) {
4
- const config = readConfig();
5
- let language = config.language;
6
-
7
- if (!language && !yes) {
8
- log.blank();
9
- language = await select({
10
- message: "Choose your preferred language / 选择语言",
11
- options: [
12
- {
13
- value: "en",
14
- label: "English",
15
- hint: "CLI output and documentation in English",
16
- },
17
- {
18
- value: "zh",
19
- label: "简体中文",
20
- hint: "CLI 输出和文档使用简体中文",
21
- },
22
- ],
23
- initialValue: "en",
24
- });
25
- config.language = language;
26
- writeConfig(config);
27
- log.ok(`Language set to ${language === "zh" ? "简体中文" : "English"}`);
28
- } else if (!language) {
29
- language = "en";
30
- config.language = language;
31
- writeConfig(config);
32
- }
33
-
34
- return { language, config };
35
- }
@@ -1,29 +0,0 @@
1
- import { color, has } from "./utils.js";
2
-
3
- export function printNextSteps() {
4
- const cliOnPath = has("curdx-flow");
5
- const cliCmd = cliOnPath ? "curdx-flow" : "npx @curdx/flow";
6
-
7
- console.log(`\n${color.bold(`${color.green("✓")} Install complete`)}\n`);
8
- console.log(
9
- `${color.bold("Restart Claude Code")} so the plugin registers its commands, hooks, default main-thread agent, and background monitor.\n`
10
- );
11
- console.log(`${color.bold("Next steps")}:\n`);
12
- console.log(` ${color.dim("# Verify health")}`);
13
- console.log(` ${cliCmd} doctor\n`);
14
- console.log(` ${color.dim("# Review the bundled main-agent / monitor defaults")}`);
15
- console.log(` ${color.dim("# (doctor now prints CurDX-Flow runtime defaults and plugin option keys)")}\n`);
16
- console.log(` ${color.dim("# Inside any project, initialize and start a feature spec")}`);
17
- console.log(` ${color.cyan("cd ~/your-project")}`);
18
- console.log(` ${color.cyan("claude")}`);
19
- console.log(` ${color.cyan("/curdx-flow:init")}`);
20
- console.log(` ${color.cyan("/curdx-flow:start my-feature \"<one-line goal>\"")}\n`);
21
- if (!cliOnPath) {
22
- console.log(
23
- `${color.dim("Tip: install the CLI globally for shorter commands —")} ${color.cyan("npm i -g @curdx/flow")}\n`
24
- );
25
- }
26
- console.log(
27
- `${color.bold("Learn more")}: https://github.com/curdx/curdx-flow/blob/main/docs/getting-started.md\n`
28
- );
29
- }
@@ -1,9 +0,0 @@
1
- export function parseInstallOptions(args = []) {
2
- return {
3
- all: args.includes("--all"),
4
- noDeps: args.includes("--no-deps"),
5
- forceOnline: args.includes("--online") || args.includes("--from-github"),
6
- yes: args.includes("--yes") || args.includes("-y"),
7
- skipSelfUpdate: args.includes("--skip-self-update"),
8
- };
9
- }
@@ -1,52 +0,0 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { dirname, join } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
-
5
- // When installed via npm, this CLI file lives at <pkg-root>/cli/*.js.
6
- // The npm package bundles the full plugin body (.claude-plugin/, agents/,
7
- // commands/, etc.) so install can register <pkg-root> as a local marketplace
8
- // and avoid fetching anything from GitHub.
9
- const __dirname = dirname(fileURLToPath(import.meta.url));
10
- export const PKG_ROOT = dirname(__dirname);
11
- export const LOCAL_MARKETPLACE_MANIFEST = join(
12
- PKG_ROOT,
13
- ".claude-plugin",
14
- "marketplace.json"
15
- );
16
- export const LOCAL_PLUGIN_MANIFEST = join(
17
- PKG_ROOT,
18
- ".claude-plugin",
19
- "plugin.json"
20
- );
21
-
22
- export function shouldUseOfflineInstall({ forceOnline }) {
23
- return !forceOnline && existsSync(LOCAL_MARKETPLACE_MANIFEST);
24
- }
25
-
26
- export function getMarketplaceSource(useOffline) {
27
- return useOffline ? PKG_ROOT : "curdx/curdx-flow";
28
- }
29
-
30
- export function getMarketplaceLabel(useOffline) {
31
- return useOffline
32
- ? `local npm package (${PKG_ROOT})`
33
- : "GitHub curdx/curdx-flow";
34
- }
35
-
36
- export function readShippedVersion() {
37
- try {
38
- const plugin = JSON.parse(readFileSync(LOCAL_PLUGIN_MANIFEST, "utf-8"));
39
- if (plugin?.version) return plugin.version;
40
- } catch {
41
- // Fall back to the marketplace manifest below. Online installs or old
42
- // package layouts may not have a local plugin manifest available.
43
- }
44
-
45
- try {
46
- const marketplace = JSON.parse(readFileSync(LOCAL_MARKETPLACE_MANIFEST, "utf-8"));
47
- return marketplace?.metadata?.version || null;
48
- } catch {
49
- // marketplace not local (online install) or unreadable
50
- return null;
51
- }
52
- }
@@ -1,104 +0,0 @@
1
- /**
2
- * Install optional recommended companion plugins. List source-of-truth:
3
- * cli/registry.js RECOMMENDED_PLUGINS. Handles --all / --yes / interactive
4
- * multiselect and the claude-mem bun/uv PATH symlink post-install step.
5
- */
6
-
7
- import { addPluginMarketplace, installPlugin } from "./lib/claude-ops.js";
8
- import { RECOMMENDED_PLUGINS } from "./registry.js";
9
- import {
10
- color,
11
- ensureClaudeMemRuntimes,
12
- listPlugins,
13
- log,
14
- multiselectClack,
15
- resultLastLine,
16
- } from "./utils.js";
17
-
18
- const RECOMMENDED = RECOMMENDED_PLUGINS;
19
-
20
- export async function installRecommendedPlugins({ all, yes, language }) {
21
- log.blank();
22
- log.step(4, 5, "Recommended plugins");
23
-
24
- let toInstall;
25
- if (all) {
26
- toInstall = RECOMMENDED.map((r) => r.name);
27
- log.info("--all mode: installing all recommended");
28
- } else if (yes) {
29
- const currentlyInstalled = new Set(listPlugins().map((p) => p.name));
30
- toInstall = RECOMMENDED
31
- .filter((r) => !currentlyInstalled.has(r.name))
32
- .map((r) => r.name);
33
- log.info(`--yes mode: installing ${toInstall.length} recommended plugins`);
34
- } else {
35
- const currentlyInstalled = new Set(listPlugins().map((p) => p.name));
36
- const options = RECOMMENDED.map((r) => ({
37
- value: r.name,
38
- label: `${r.name}${currentlyInstalled.has(r.name) ? " (installed)" : ""}`,
39
- hint: r.hint,
40
- }));
41
- const initialValues = RECOMMENDED.map((r) => r.name);
42
-
43
- toInstall = await multiselectClack({
44
- message: language === "zh"
45
- ? "选择要安装的推荐插件(空格切换,回车确认)"
46
- : "Select recommended plugins to install (space to toggle, enter to confirm)",
47
- options,
48
- initialValues,
49
- required: false,
50
- });
51
- }
52
-
53
- if (!toInstall || toInstall.length === 0) {
54
- log.info("No recommended plugins selected, skipping");
55
- return false;
56
- }
57
-
58
- for (const pluginName of toInstall) {
59
- const rec = RECOMMENDED.find((r) => r.name === pluginName);
60
- log.blank();
61
- console.log(` ${color.cyan("▸")} Installing ${color.bold(rec.name)}...`);
62
-
63
- if (rec.marketplaceSource) {
64
- const ma = await addPluginMarketplace(rec);
65
- if (ma.code !== 0 && !ma.stderr.includes("already")) {
66
- log.warn(` marketplace add warning: ${ma.stderr.trim().split("\n")[0]}`);
67
- }
68
- }
69
-
70
- const ir = await installPlugin(rec);
71
- if (ir.code === 0) {
72
- console.log(` ${color.green("✓")} ${rec.name} installed`);
73
-
74
- if (rec.postInstall === "claude-mem-runtimes") {
75
- const r = ensureClaudeMemRuntimes();
76
- for (const [name, res] of Object.entries(r)) {
77
- if (res.status === "linked") {
78
- console.log(
79
- ` ${color.green("✓")} ${name} → PATH symlink created ${color.dim(`(${res.link} → ${res.path})`)}`
80
- );
81
- } else if (res.status === "missing") {
82
- console.log(
83
- ` ${color.yellow("⚠")} ${name} not installed ${color.dim("(claude-mem will auto-install on first run; or run: curdx-flow doctor)")}`
84
- );
85
- } else if (res.status === "path-unwritable") {
86
- console.log(
87
- ` ${color.yellow("⚠")} ${name} installed ${color.dim(`(${res.path}) but no writable PATH location — add export PATH="${res.path.split("/").slice(0,-1).join("/")}:$PATH" to your shell rc`)}`
88
- );
89
- }
90
- }
91
- }
92
- } else {
93
- console.log(
94
- ` ${color.red("✗")} ${rec.name} install failed: ${resultLastLine(ir)}`
95
- );
96
- console.log(
97
- color.dim(
98
- ` Run manually: claude plugin install --scope ${rec.scope} ${rec.installSpec}`
99
- )
100
- );
101
- }
102
- }
103
- return true;
104
- }
@@ -1,57 +0,0 @@
1
- /**
2
- * Install required Claude Code companion plugins (today: context7-plugin).
3
- * Post-install, reconcile any legacy Context7 user-level MCP/config state.
4
- */
5
-
6
- import { addPluginMarketplace, installPlugin } from "./lib/claude-ops.js";
7
- import { REQUIRED_PLUGINS } from "./registry.js";
8
- import { color, log, resultLastLine } from "./utils.js";
9
- import { reconcileLegacyContext7InstallState } from "./install-context7-config.js";
10
-
11
- export async function addRequiredPluginMarketplaces({ logWarnings = true } = {}) {
12
- for (const plugin of REQUIRED_PLUGINS) {
13
- const ma = await addPluginMarketplace(plugin);
14
- if (ma.code !== 0 && !ma.stderr.includes("already") && logWarnings) {
15
- log.warn(` marketplace add warning: ${ma.stderr.trim().split("\n")[0]}`);
16
- }
17
- }
18
- }
19
-
20
- export async function installRequiredPlugins({
21
- yes,
22
- language,
23
- config,
24
- skipMarketplaceAdd = false,
25
- }) {
26
- log.blank();
27
- log.info("Installing required Claude Code plugins...");
28
- if (!skipMarketplaceAdd) {
29
- await addRequiredPluginMarketplaces();
30
- }
31
- for (const plugin of REQUIRED_PLUGINS) {
32
- console.log(` ${color.cyan("▸")} Installing ${color.bold(plugin.name)}...`);
33
-
34
- const ir = await installPlugin(plugin);
35
- if (ir.code === 0) {
36
- console.log(` ${color.green("✓")} ${plugin.name} installed`);
37
-
38
- if (plugin.name === "context7-plugin") {
39
- await reconcileLegacyContext7InstallState(plugin, language, config);
40
- }
41
- } else {
42
- console.log(
43
- ` ${color.red("✗")} ${plugin.name} install failed: ${resultLastLine(ir)}`
44
- );
45
- console.log(
46
- color.dim(
47
- ` Run manually: claude plugin marketplace add --scope ${plugin.scope} ${plugin.marketplaceSource}`
48
- )
49
- );
50
- console.log(
51
- color.dim(
52
- ` Then: claude plugin install --scope ${plugin.scope} ${plugin.installSpec}`
53
- )
54
- );
55
- }
56
- }
57
- }