@curdx/flow 7.1.19 → 7.1.20
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 +12 -0
- package/README.md +4 -4
- package/dist/index.mjs +35 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
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
|
+
## 7.1.20 — 2026-05-11
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **Companion capabilities are now the default required bundle.** `pua`, `claude-mem`, `chrome-devtools-mcp`, `frontend-design`, `sequential-thinking`, and `context7` are marked `required` in the installer alongside `curdx-flow`, so interactive installs show them as always installed and `--ids` installs auto-include missing required companions.
|
|
10
|
+
- **Official plugin dependency metadata added.** `curdx-flow` now declares plugin dependencies for `pua`, `claude-mem`, `chrome-devtools-mcp`, and `frontend-design`, and the root marketplace explicitly allows those cross-marketplace dependencies.
|
|
11
|
+
- **Capability routing marks bundled companions as `core-required`.** Smart-route recommendations still trigger only when relevant, but recommended bundled capabilities are no longer suppressed by narrow availability filters.
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
|
|
15
|
+
- Added registry and manifest regression coverage for the required bundle, expanded capability-router expectations, rebuilt hook bundles, and tightened `claudecc` smoke checks for `core-required` recommendations.
|
|
16
|
+
|
|
5
17
|
## 7.1.19 — 2026-05-11
|
|
6
18
|
|
|
7
19
|
### Added
|
package/README.md
CHANGED
|
@@ -123,7 +123,7 @@ The same npm package delivers both products. The installer reads its descriptor
|
|
|
123
123
|
|
|
124
124
|
- **Node.js** ≥ 20.12 ([download](https://nodejs.org))
|
|
125
125
|
- **Claude Code CLI** installed and on `PATH` ([install instructions](https://docs.anthropic.com/en/docs/claude-code))
|
|
126
|
-
- *(Optional)* **Bun** ≥ 1.0 — auto-detected; the installer offers to install it
|
|
126
|
+
- *(Optional)* **Bun** ≥ 1.0 — auto-detected; the installer offers to install it for the default `claude-mem` companion
|
|
127
127
|
|
|
128
128
|
### Install
|
|
129
129
|
|
|
@@ -131,7 +131,7 @@ The same npm package delivers both products. The installer reads its descriptor
|
|
|
131
131
|
npx @curdx/flow
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
-
On first run, you pick a language (中文 / English)
|
|
134
|
+
On first run, you pick a language (中文 / English). The full curdx-flow bundle is installed by default: `curdx-flow`, `pua`, `claude-mem`, `chrome-devtools-mcp`, `frontend-design`, `sequential-thinking`, and `context7`. If a companion has a local prerequisite that is missing, the installer reports the skip reason and continues so the core workflow remains usable.
|
|
135
135
|
|
|
136
136
|
That language choice also controls the managed `~/.claude/CLAUDE.md` block that flow writes. The block is rendered in the selected language, and when you choose `zh` it additionally injects a language policy telling Claude to keep tool/model interaction in English while replying to the user in Simplified Chinese.
|
|
137
137
|
|
|
@@ -428,9 +428,9 @@ Most workflow frameworks address this by adding more agents, more orchestration,
|
|
|
428
428
|
|
|
429
429
|
No. flow runs **inside** Claude Code as a plugin. You still use the Claude Code CLI / IDE extension to chat; flow adds the `/curdx-flow:*` commands, subagents, hooks, and the bundled marketplace.
|
|
430
430
|
|
|
431
|
-
#### Can I use flow without
|
|
431
|
+
#### Can I use flow without the companion capabilities?
|
|
432
432
|
|
|
433
|
-
|
|
433
|
+
The default installer treats the companion capabilities as required because routing depends on them for memory, current docs, frontend design, browser verification, structured reasoning, and retry/parallel recovery. If a local prerequisite is missing, that item may be skipped with a visible reason, but the next `npx @curdx/flow install` run will try to restore it.
|
|
434
434
|
|
|
435
435
|
#### Do I need to commit the spec files?
|
|
436
436
|
|
package/dist/index.mjs
CHANGED
|
@@ -514,6 +514,7 @@ var pua = {
|
|
|
514
514
|
name: "pua",
|
|
515
515
|
description: "tanweai/pua \u2014 Chinese Claude Code skills bundle",
|
|
516
516
|
type: "plugin",
|
|
517
|
+
required: true,
|
|
517
518
|
slashNamespace: "/pua:*",
|
|
518
519
|
whenToUse: "auto-fires on 2+ failures or user frustration; sub-modes p7 / p9 / pro / loop. Skip on first-attempt failures or when a known fix is executing.",
|
|
519
520
|
marketplaces: () => [MARKETPLACE_NAME],
|
|
@@ -609,6 +610,7 @@ var claudeMem = {
|
|
|
609
610
|
name: "claude-mem",
|
|
610
611
|
description: "thedotmack/claude-mem \u2014 persistent cross-session memory for Claude Code",
|
|
611
612
|
type: "plugin",
|
|
613
|
+
required: true,
|
|
612
614
|
slashNamespace: "/claude-mem:*",
|
|
613
615
|
whenToUse: 'for cross-session memory search ("did we solve this before?"), phased planning (`make-plan`), or phased execution (`do`).',
|
|
614
616
|
marketplaces: () => [MARKETPLACE_NAME2],
|
|
@@ -668,6 +670,7 @@ var chromeDevtoolsMcp = {
|
|
|
668
670
|
name: "chrome-devtools-mcp",
|
|
669
671
|
description: "ChromeDevTools/chrome-devtools-mcp \u2014 drive a real Chrome from Claude Code",
|
|
670
672
|
type: "plugin",
|
|
673
|
+
required: true,
|
|
671
674
|
whenToUse: "when debugging code that runs in a browser: perf traces, network / console inspection, DOM / CSS issues. Prefer snapshot over screenshot.",
|
|
672
675
|
prereqCheck: async (t2) => {
|
|
673
676
|
const major = Number(process.versions.node.split(".")[0] ?? "0");
|
|
@@ -697,6 +700,7 @@ var frontendDesign = {
|
|
|
697
700
|
name: "frontend-design",
|
|
698
701
|
description: "Anthropic official \u2014 UI/frontend design helpers",
|
|
699
702
|
type: "plugin",
|
|
703
|
+
required: true,
|
|
700
704
|
whenToUse: "auto-fires when building UI / web components / pages. Best where visual personality matters (landing, marketing, portfolio).",
|
|
701
705
|
isInstalled: () => isPluginInstalled(PLUGIN_ID4),
|
|
702
706
|
install: (ctx) => installPluginById(PLUGIN_ID4, ctx),
|
|
@@ -742,6 +746,7 @@ var sequentialThinking = {
|
|
|
742
746
|
name: "sequential-thinking",
|
|
743
747
|
description: "modelcontextprotocol/server-sequential-thinking \u2014 structured reasoning helper",
|
|
744
748
|
type: "mcp",
|
|
749
|
+
required: true,
|
|
745
750
|
whenToUse: "for complex multi-step problems where assumptions may shift (architecture comparison, risk-assessed migrations, prod-only debugging). Skip for simple queries.",
|
|
746
751
|
isInstalled: () => isMcpInstalled(MCP_NAME),
|
|
747
752
|
install: async (ctx) => {
|
|
@@ -783,6 +788,7 @@ var context7 = {
|
|
|
783
788
|
name: "context7",
|
|
784
789
|
description: "upstash/context7 \u2014 up-to-date docs from any library (HTTP MCP, optional API key)",
|
|
785
790
|
type: "mcp",
|
|
791
|
+
required: true,
|
|
786
792
|
whenToUse: "for any library / SDK / framework / API / Claude Code docs lookup. Use instead of web search.",
|
|
787
793
|
isInstalled: () => isMcpInstalled(MCP_NAME2),
|
|
788
794
|
configPrompts: async ({ t: t2 }) => {
|
|
@@ -913,7 +919,15 @@ var ORDER = [
|
|
|
913
919
|
"sequential-thinking",
|
|
914
920
|
"pua"
|
|
915
921
|
];
|
|
916
|
-
var
|
|
922
|
+
var CORE_REQUIRED = /* @__PURE__ */ new Set([
|
|
923
|
+
"context7",
|
|
924
|
+
"claude-mem",
|
|
925
|
+
"frontend-design",
|
|
926
|
+
"chrome-devtools-mcp",
|
|
927
|
+
"sequential-thinking",
|
|
928
|
+
"pua"
|
|
929
|
+
]);
|
|
930
|
+
var EXTERNAL_DOCS_RE = /\b(api|sdk|library|libraries|framework|version|upgrade|dependency|dependencies|official docs?|latest docs?|claude code|plugin|mcp|hook|hooks|skill|skills|agent|agents|react|vue|spring|spring boot|spring cloud|next\.?js|vite|webpack|npm|node)\b|最新|依赖|框架|插件|官方|联网|搜索|文档.*(最新|官方|API|SDK|框架|插件|依赖)/i;
|
|
917
931
|
var MEMORY_RE = /\b(previous|before|again|remember|memory|history|similar|repeated|regression|already solved|same bug|past decision)\b|之前|上次|记得|历史|做过|又|重复|老问题/i;
|
|
918
932
|
var UI_RE = /\b(ui|ux|frontend|front-end|browser|chrome|dom|css|html|layout|component|page|form|modal|responsive|visual|render|react|vue|vite|next\.?js|screenshot|interaction)\b|前端|页面|浏览器|样式|交互|组件|布局|视觉|截图/i;
|
|
919
933
|
var BROWSER_VERIFY_RE = /\b(browser|chrome|dom|css|network|console|performance|render|screenshot|e2e|playwright|visual regression|interaction)\b|浏览器|控制台|网络|性能|渲染|截图|端到端/i;
|
|
@@ -928,11 +942,14 @@ function hasAny(values, candidates) {
|
|
|
928
942
|
const set = new Set((values ?? []).map((v) => v.toLowerCase()));
|
|
929
943
|
return candidates.some((candidate) => set.has(candidate.toLowerCase()));
|
|
930
944
|
}
|
|
931
|
-
function
|
|
932
|
-
|
|
945
|
+
function capabilityAvailability(id, available) {
|
|
946
|
+
if (CORE_REQUIRED.has(id)) return "core-required";
|
|
947
|
+
if (available === null) return "check-if-installed";
|
|
948
|
+
return available.has(id) ? "known-available" : null;
|
|
933
949
|
}
|
|
934
950
|
function pushRecommendation(out, available, id, phase, reason, instruction) {
|
|
935
|
-
|
|
951
|
+
const availability = capabilityAvailability(id, available);
|
|
952
|
+
if (availability === null) return;
|
|
936
953
|
if (out.some((rec) => rec.id === id)) return;
|
|
937
954
|
const cap = CAPABILITIES[id];
|
|
938
955
|
out.push({
|
|
@@ -941,6 +958,7 @@ function pushRecommendation(out, available, id, phase, reason, instruction) {
|
|
|
941
958
|
type: cap.type,
|
|
942
959
|
invocation: cap.invocation,
|
|
943
960
|
phase,
|
|
961
|
+
availability,
|
|
944
962
|
reason,
|
|
945
963
|
instruction
|
|
946
964
|
});
|
|
@@ -960,16 +978,17 @@ function recommendToolCapabilities(input) {
|
|
|
960
978
|
if (missingRoots > 0) {
|
|
961
979
|
return recs;
|
|
962
980
|
}
|
|
963
|
-
const
|
|
981
|
+
const externalDocsRelevant = EXTERNAL_DOCS_RE.test(goal);
|
|
982
|
+
const localLowRisk = LOW_RISK_LOCAL_RE.test(goal) && route === "direct-change" && !externalDocsRelevant;
|
|
964
983
|
if (localLowRisk) {
|
|
965
984
|
return recs;
|
|
966
985
|
}
|
|
967
986
|
const hasFrontend = UI_RE.test(goal) || hasAny(topologyKinds, ["frontend-app"]) || hasAny(topologyFrameworks, ["react", "vue", "next.js", "vite"]);
|
|
968
987
|
const browserRuntime = BROWSER_VERIFY_RE.test(goal) || hasFrontend;
|
|
969
|
-
const complex = COMPLEX_RE.test(goal) || risk === "high" || risk === "critical" || route === "full-spec" || route === "epic-split";
|
|
988
|
+
const complex = COMPLEX_RE.test(goal) && route !== "direct-change" || risk === "high" || risk === "critical" || route === "full-spec" || route === "epic-split";
|
|
970
989
|
const stuck = STUCK_RE.test(goal);
|
|
971
990
|
const parallel = PARALLEL_RE.test(goal) || route === "epic-split";
|
|
972
|
-
if (
|
|
991
|
+
if (externalDocsRelevant) {
|
|
973
992
|
pushRecommendation(
|
|
974
993
|
recs,
|
|
975
994
|
available,
|
|
@@ -1045,25 +1064,25 @@ function renderInstalledCapabilityRules(availableCapabilities) {
|
|
|
1045
1064
|
}
|
|
1046
1065
|
function renderCapabilityDecisionTree(availableCapabilities) {
|
|
1047
1066
|
const available = new Set(availableCapabilities);
|
|
1048
|
-
const
|
|
1049
|
-
"
|
|
1067
|
+
const rules = [
|
|
1068
|
+
"Can the edit be finished safely from local code in 1-2 steps? -> Do it directly."
|
|
1050
1069
|
];
|
|
1051
1070
|
if (available.has("context7")) {
|
|
1052
|
-
|
|
1071
|
+
rules.push("Does correctness depend on external docs, SDKs, APIs, or Claude Code behavior? -> use the Context7 MCP before editing.");
|
|
1053
1072
|
}
|
|
1054
1073
|
if (available.has("claude-mem")) {
|
|
1055
|
-
|
|
1074
|
+
rules.push("Might similar work, a prior decision, or a repeated failure exist? -> Start with `/claude-mem:mem-search`.");
|
|
1056
1075
|
}
|
|
1057
1076
|
if (available.has("frontend-design") || available.has("chrome-devtools-mcp")) {
|
|
1058
|
-
|
|
1077
|
+
rules.push("Is visible frontend behavior in scope? -> Use frontend-design for UI decisions and Chrome DevTools MCP for runtime proof when installed.");
|
|
1059
1078
|
}
|
|
1060
1079
|
if (available.has("sequential-thinking")) {
|
|
1061
|
-
|
|
1080
|
+
rules.push("Is the work high-risk, architectural, or assumption-heavy? -> Use sequential-thinking after reading the relevant code.");
|
|
1062
1081
|
}
|
|
1063
1082
|
if (available.has("pua")) {
|
|
1064
|
-
|
|
1083
|
+
rules.push("Are there multiple failed attempts or truly independent parallel slices? -> Use `/pua:pua-loop` for recovery or `/pua:p9` for bounded parallel planning.");
|
|
1065
1084
|
}
|
|
1066
|
-
return
|
|
1085
|
+
return rules.map((rule, idx) => `${idx + 1}. ${rule}`);
|
|
1067
1086
|
}
|
|
1068
1087
|
function parseList(value) {
|
|
1069
1088
|
if (!value) return [];
|
|
@@ -1133,7 +1152,7 @@ function buildSkipRules(ids) {
|
|
|
1133
1152
|
function buildDecisionTree(ids) {
|
|
1134
1153
|
const out = renderCapabilityDecisionTree([...ids]);
|
|
1135
1154
|
if (ids.has("curdx-flow")) {
|
|
1136
|
-
out.push(
|
|
1155
|
+
out.push(`${out.length + 1}. Is the request ambiguous, cross-cutting, phase-based, or multi-root? -> Run /curdx-flow:start.`);
|
|
1137
1156
|
}
|
|
1138
1157
|
return out;
|
|
1139
1158
|
}
|