@curdx/flow 6.0.5 → 6.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,11 +2,19 @@
2
2
 
3
3
  All notable changes to `@curdx/flow` are documented here. Format follows [Keep a Changelog](https://keepachangelog.com/) and the project follows [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## 6.0.6 — 2026-04-29
6
+
7
+ ### Removed
8
+
9
+ - **Legacy plugin migration code path.** `LEGACY_PLUGIN_IDS`, `uninstallLegacyIfPresent`, and the entire `src/runner/legacy-cleanup.ts` file removed. Users still on v3.x slugs will need to manually `claude plugin uninstall` the old slug before upgrading — the auto-cleanup is gone.
10
+ - **Historical CHANGELOG entries for the v3.x rename releases** (3.4.0, 3.5.0, 4.0.0, 4.0.1) deleted. Keep-a-Changelog convention deliberately violated at the user's request.
11
+ - LICENSE copyright line and NOTICE.md attribution intentionally untouched (MIT licensing requires these).
12
+
5
13
  ## 6.0.5 — 2026-04-29
6
14
 
7
15
  ### Changed
8
16
 
9
- - **Drop legacy upstream-attribution chrome from user-facing surfaces.** `src/registry/plugins/curdx-flow.ts` install description no longer carries the `(originally tzachbon/smart-ralph)` suffix; `README.md`'s tools table and the v3.x → v4 / v5 migration notes block (`ralph-specum@smart-ralph`, `ralph-specum@curdx-flow` uninstall instructions) removed — those upgrades are 2+ majors back, the auto-migration in `purgeLegacyPluginArtifacts` still handles any stragglers transparently. Authorship and legal attribution preserved verbatim in `plugins/curdx-flow/LICENSE` (MIT copyright line) and `plugins/curdx-flow/NOTICE.md`; CHANGELOG history kept untouched per Keep-a-Changelog convention; `LEGACY_PLUGIN_IDS` constant kept (still drives runtime migration cleanup).
17
+ - **Drop legacy upstream-attribution chrome from user-facing surfaces.** Install description and README tools table / migration notes block scrubbed. MIT `LICENSE` copyright line and `NOTICE.md` attribution preserved verbatim (legal requirement).
10
18
 
11
19
  ## 6.0.4 — 2026-04-29
12
20
 
@@ -31,50 +39,6 @@ All notable changes to `@curdx/flow` are documented here. Format follows [Keep a
31
39
 
32
40
  - Both additions are repo-internal — neither file ships in the npm tarball (`files: ["dist", "CHANGELOG.md"]` is unchanged), so the published artifact is byte-identical to 6.0.1 modulo version metadata. This release exists to dogfood the new `bump-version` flow end-to-end.
33
41
 
34
- ## 4.0.1 — 2026-04-27
35
-
36
- ### Fixed
37
-
38
- - **Migration cleanup is now exhaustive.** v4.0.0's auto-migration for the `ralph-specum` → `curdx-flow` rename only invoked `claude plugin uninstall`, which leaves substantial residue when the marketplace's plugin id has been renamed (the CLI can't resolve the legacy id and bails). The installer now manually purges every leftover artifact for legacy slugs (`ralph-specum@curdx-flow`, `ralph-specum@smart-ralph`):
39
- - `~/.claude/settings.json` → removes `enabledPlugins[<legacyId>]`
40
- - `~/.claude/plugins/installed_plugins.json` → removes `plugins[<legacyId>]`
41
- - `~/.claude/plugins/cache/<marketplace>/<name>/` → recursive remove
42
- - `~/.claude/plugins/data/<name>-<marketplace>/` → recursive remove
43
- - Marketplace registrations (`known_marketplaces.json`, `extraKnownMarketplaces`) are deliberately left alone — those are user-managed.
44
- - Implementation lives in `src/runner/legacy-cleanup.ts::purgeLegacyPluginArtifacts`. Idempotent and safe: every step swallows ENOENT silently and reports JSON / IO errors via the install task log without failing the flow.
45
-
46
- ## 4.0.0 — 2026-04-27
47
-
48
- ### Breaking
49
-
50
- - **Plugin renamed `ralph-specum` → `curdx-flow`.** The bundled spec-driven workflow plugin now lives under the `curdx-flow` brand, slash namespace `/curdx-flow:*`, full slug `curdx-flow@curdx`. The marketplace identifier was simultaneously shortened from `curdx-flow` to `curdx` (the GitHub repo source `curdx/curdx-flow` is unchanged). All in-plugin slash references, env vars (`RALPH_SPECUM_*` → `CURDX_FLOW_*`), and labels were updated accordingly.
51
- - **Auto-migration:** the installer now detects legacy `ralph-specum@curdx-flow` and `ralph-specum@smart-ralph` installs and uninstalls them automatically before installing the new slug, so users on v3.4 / v3.5 transparently transition. Your `specs/` directory and any in-progress spec state files are not touched — the rename is purely a plugin-identity change.
52
- - **Manual fallback:** if you'd rather run the migration yourself, execute `claude plugin uninstall ralph-specum@curdx-flow` (or `@smart-ralph`) before re-running `npx @curdx/flow install`. The old marketplace `curdx-flow` may remain registered alongside the new `curdx` marketplace; this is harmless and you can `claude plugin marketplace remove curdx-flow` if you want to clean up.
53
-
54
- ### Notes
55
-
56
- - The plugin's authorship and license lineage (smart-ralph by tzachbon → ralph-specum fork → curdx-flow) is recorded in `plugins/curdx-flow/NOTICE.md`. MIT License preserved.
57
- - `.claude-plugin/marketplace.json` now declares one plugin: `curdx-flow` v4.9.1 sourced from `./plugins/curdx-flow`.
58
-
59
- ## 3.5.0 — 2026-04-27
60
-
61
- ### Changed
62
-
63
- - **`ralph-specum` is now a required bundled plugin** — it no longer appears as an optional checkbox in the install multiselect. Instead, it's listed in a dedicated "always installed" header above the prompt, alongside its current state (not installed / up-to-date / update available). When the flow runs, ralph-specum is auto-installed or auto-updated whenever it needs action; up-to-date installs are silently skipped. The other six items (pua, claude-mem, chrome-devtools-mcp, frontend-design, sequential-thinking, context7) remain optional. `--ids X` now also auto-includes required plugins that need action; users can still explicitly run `--ids ralph-specum` to force a reinstall confirmation. Uninstall flow is unchanged — users may still uninstall ralph-specum, and the next install will re-add it.
64
- - **Internal:** `Pkg` type gains a `required?: boolean` field so future bundled plugins can opt into the same "always installed" semantics without touching install-flow code.
65
-
66
- ## 3.4.0 — 2026-04-27
67
-
68
- ### Added
69
-
70
- - **`ralph-specum` is now a bundled plugin** — spec-driven development with autonomous task-by-task execution (research → requirements → design → tasks → implement, plus epic triage). Originally authored by [tzachbon](https://github.com/tzachbon/smart-ralph); ralph-specum v4.9.1 has been migrated into this repository as the canonical home and is no longer tracked against upstream. MIT license and authorship are preserved at `plugins/ralph-specum/LICENSE` and `plugins/ralph-specum/NOTICE.md`.
71
- - **curdx-flow itself is now a Claude Code marketplace** — the repo ships `.claude-plugin/marketplace.json` so Claude CLI can install bundled plugins via `claude plugin marketplace add curdx/curdx-flow` + `claude plugin install ralph-specum@curdx-flow`. The flow installer wires this up automatically; users just run `npx @curdx/flow install` and ralph-specum is pre-checked in the multiselect along with the other not-installed items.
72
-
73
- ### Notes
74
-
75
- - If you previously installed ralph-specum from the upstream `tzachbon/smart-ralph` marketplace, run `claude plugin uninstall ralph-specum@smart-ralph` before installing this version to avoid a name collision. Going forward, only the `ralph-specum@curdx-flow` build is maintained.
76
- - Plugin files are not shipped in the npm tarball (`package.json` `files` is unchanged: `["dist", "CHANGELOG.md"]`). They live in the GitHub repo and are pulled by Claude CLI when the marketplace is added — so a `git push` of this repo must precede `npm publish` for a new release to be installable.
77
-
78
42
  ## 3.3.2 — 2026-04-27
79
43
 
80
44
  ### Fixed
package/dist/index.mjs CHANGED
@@ -576,94 +576,11 @@ var frontendDesign = {
576
576
  };
577
577
  var frontend_design_default = frontendDesign;
578
578
 
579
- // src/runner/legacy-cleanup.ts
580
- import { promises as fs2 } from "fs";
581
- import path2 from "path";
582
- import os2 from "os";
583
- async function purgeLegacyPluginArtifacts(legacyId, ctx) {
584
- const at = legacyId.indexOf("@");
585
- if (at <= 0 || at === legacyId.length - 1) return;
586
- const name = legacyId.slice(0, at);
587
- const marketplace = legacyId.slice(at + 1);
588
- const home = os2.homedir();
589
- const settingsPath = path2.join(home, ".claude", "settings.json");
590
- const installedPath = path2.join(home, ".claude", "plugins", "installed_plugins.json");
591
- const cacheDir = path2.join(home, ".claude", "plugins", "cache", marketplace, name);
592
- const dataDir = path2.join(home, ".claude", "plugins", "data", `${name}-${marketplace}`);
593
- let removedAny = false;
594
- removedAny = await deleteJsonKey(settingsPath, ["enabledPlugins", legacyId], ctx) || removedAny;
595
- removedAny = await deleteJsonKey(installedPath, ["plugins", legacyId], ctx) || removedAny;
596
- removedAny = await rmDir(cacheDir, ctx) || removedAny;
597
- removedAny = await rmDir(dataDir, ctx) || removedAny;
598
- if (removedAny) {
599
- ctx.log.message(`Purged legacy artifacts for ${legacyId}.`);
600
- clearStateCache();
601
- }
602
- }
603
- async function deleteJsonKey(filePath, keyPath, ctx) {
604
- let raw;
605
- try {
606
- raw = await fs2.readFile(filePath, "utf8");
607
- } catch (err) {
608
- if (err.code === "ENOENT") return false;
609
- ctx.log.message(`Skip purge of ${filePath}: ${err.message}`);
610
- return false;
611
- }
612
- let json;
613
- try {
614
- json = JSON.parse(raw);
615
- } catch (err) {
616
- ctx.log.message(`Skip purge of ${filePath}: invalid JSON (${err.message})`);
617
- return false;
618
- }
619
- let cursor = json;
620
- for (let i = 0; i < keyPath.length - 1; i++) {
621
- const next = cursor?.[keyPath[i]];
622
- if (!next || typeof next !== "object") return false;
623
- cursor = next;
624
- }
625
- const finalKey = keyPath[keyPath.length - 1];
626
- if (!cursor || !(finalKey in cursor)) return false;
627
- delete cursor[finalKey];
628
- try {
629
- await fs2.writeFile(filePath, JSON.stringify(json, null, 2) + "\n", "utf8");
630
- return true;
631
- } catch (err) {
632
- ctx.log.message(`Failed to rewrite ${filePath}: ${err.message}`);
633
- return false;
634
- }
635
- }
636
- async function rmDir(dirPath, ctx) {
637
- try {
638
- await fs2.access(dirPath);
639
- } catch {
640
- return false;
641
- }
642
- try {
643
- await fs2.rm(dirPath, { recursive: true, force: true });
644
- return true;
645
- } catch (err) {
646
- ctx.log.message(`Failed to remove ${dirPath}: ${err.message}`);
647
- return false;
648
- }
649
- }
650
-
651
579
  // src/registry/plugins/curdx-flow.ts
652
580
  var PLUGIN_ID5 = "curdx-flow@curdx";
653
581
  var PLUGIN_NAME3 = "curdx-flow";
654
582
  var MARKETPLACE_NAME4 = "curdx";
655
583
  var MARKETPLACE_SOURCE4 = "curdx/curdx-flow";
656
- var LEGACY_PLUGIN_IDS = ["ralph-specum@curdx-flow", "ralph-specum@smart-ralph"];
657
- async function uninstallLegacyIfPresent(ctx) {
658
- for (const legacyId of LEGACY_PLUGIN_IDS) {
659
- const installed = await isPluginInstalled(legacyId);
660
- if (installed) {
661
- ctx.log.message(`Removing legacy plugin ${legacyId} (renamed to ${PLUGIN_ID5})\u2026`);
662
- await uninstallPluginById(legacyId, ctx);
663
- }
664
- await purgeLegacyPluginArtifacts(legacyId, ctx);
665
- }
666
- }
667
584
  var curdxFlow = {
668
585
  id: "curdx-flow",
669
586
  name: "curdx-flow",
@@ -681,15 +598,11 @@ var curdxFlow = {
681
598
  },
682
599
  latestVersion: () => getMarketplacePluginVersion(MARKETPLACE_NAME4, PLUGIN_NAME3),
683
600
  install: async (ctx) => {
684
- await uninstallLegacyIfPresent(ctx);
685
601
  await ensureMarketplace(MARKETPLACE_NAME4, MARKETPLACE_SOURCE4, ctx);
686
602
  await installPluginById(PLUGIN_ID5, ctx);
687
603
  },
688
604
  uninstall: (ctx) => uninstallPluginById(PLUGIN_ID5, ctx),
689
- update: async (ctx) => {
690
- await uninstallLegacyIfPresent(ctx);
691
- await updatePluginById(PLUGIN_ID5, ctx);
692
- }
605
+ update: (ctx) => updatePluginById(PLUGIN_ID5, ctx)
693
606
  };
694
607
  var curdx_flow_default = curdxFlow;
695
608
 
@@ -799,15 +712,15 @@ function findPkg(id) {
799
712
  }
800
713
 
801
714
  // src/runner/claudeMd.ts
802
- import { promises as fs3 } from "fs";
803
- import path3 from "path";
804
- import os3 from "os";
715
+ import { promises as fs2 } from "fs";
716
+ import path2 from "path";
717
+ import os2 from "os";
805
718
  import * as p3 from "@clack/prompts";
806
719
  var BEGIN_MARKER = "<!-- BEGIN @curdx/flow v1 -->";
807
720
  var END_MARKER = "<!-- END @curdx/flow v1 -->";
808
721
  var BLOCK_RE = /<!-- BEGIN @curdx\/flow v\d+[^>]*-->[\s\S]*?<!-- END @curdx\/flow v\d+ -->/;
809
722
  function claudeMdPath() {
810
- return path3.join(os3.homedir(), ".claude", "CLAUDE.md");
723
+ return path2.join(os2.homedir(), ".claude", "CLAUDE.md");
811
724
  }
812
725
  function buildCombinationPatterns(ids) {
813
726
  const has = (k) => ids.has(k);
@@ -961,7 +874,7 @@ async function syncClaudeMd(opts) {
961
874
  let existing = "";
962
875
  let existed = true;
963
876
  try {
964
- existing = await fs3.readFile(file, "utf8");
877
+ existing = await fs2.readFile(file, "utf8");
965
878
  } catch (err) {
966
879
  if (err.code === "ENOENT") {
967
880
  existed = false;
@@ -983,10 +896,10 @@ async function syncClaudeMd(opts) {
983
896
  if (next === existing) {
984
897
  return { status: "unchanged", path: file };
985
898
  }
986
- await fs3.mkdir(path3.dirname(file), { recursive: true });
899
+ await fs2.mkdir(path2.dirname(file), { recursive: true });
987
900
  const tmp = `${file}.tmp.${process.pid}`;
988
- await fs3.writeFile(tmp, next, "utf8");
989
- await fs3.rename(tmp, file);
901
+ await fs2.writeFile(tmp, next, "utf8");
902
+ await fs2.rename(tmp, file);
990
903
  if (!existed) return { status: "created", path: file };
991
904
  if (hadBlock && items.length === 0) return { status: "removed", path: file };
992
905
  return { status: "updated", path: file };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curdx/flow",
3
- "version": "6.0.5",
3
+ "version": "6.0.6",
4
4
  "description": "Interactive installer for Claude Code plugins and MCP servers",
5
5
  "type": "module",
6
6
  "bin": "./dist/index.mjs",