@curdx/flow 7.1.18 → 7.1.19
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 +16 -0
- package/dist/index.mjs +264 -70
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
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.19 — 2026-05-11
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **Third-party capability graph for smart routing.** New `hooks/scripts/lib/tool-capabilities.mjs` maps installed companion capabilities (`claude-mem`, `context7`, `sequential-thinking`, `chrome-devtools-mcp`, `frontend-design`, and `pua`) to concrete AI-facing triggers, phases, skip rules, and invocations.
|
|
10
|
+
- **Capability recommendations in `smart-route`.** Route output now includes `recommendedCapabilities` so `/curdx-flow:start` can choose docs lookup, memory search, UI design, browser verification, structured reasoning, or retry tooling from goal/topology facts without forcing every task through every tool.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Global CLAUDE.md guidance is generated from the capability graph.** The managed block now emits concise installed-tool routing rules and a decision tree instead of hand-maintained duplicated plugin/MCP prose.
|
|
15
|
+
- **Start workflow stores tool hints with spec state.** New specs can persist compact `recommendedCapabilities` next to `projectTopology`, and the state schema/reference docs now declare both fields so later phases can reuse the original routing context without re-deriving it.
|
|
16
|
+
|
|
17
|
+
### Tests
|
|
18
|
+
|
|
19
|
+
- Added capability-router unit coverage, smart-route capability filtering checks, CLAUDE.md rendering regression coverage, and claudecc smoke assertions for empty direct-change hints and frontend/browser/docs recommendations.
|
|
20
|
+
|
|
5
21
|
## 7.1.18 — 2026-05-11
|
|
6
22
|
|
|
7
23
|
### Added
|
package/dist/index.mjs
CHANGED
|
@@ -845,6 +845,261 @@ import { promises as fs2 } from "fs";
|
|
|
845
845
|
import path4 from "path";
|
|
846
846
|
import os2 from "os";
|
|
847
847
|
import * as p4 from "@clack/prompts";
|
|
848
|
+
|
|
849
|
+
// src/hooks/lib/tool-capabilities.ts
|
|
850
|
+
import { basename } from "path";
|
|
851
|
+
import { fileURLToPath } from "url";
|
|
852
|
+
var CAPABILITIES = {
|
|
853
|
+
"context7": {
|
|
854
|
+
id: "context7",
|
|
855
|
+
name: "Context7",
|
|
856
|
+
type: "mcp",
|
|
857
|
+
invocation: "Context7 MCP",
|
|
858
|
+
summary: "current official docs for libraries, SDKs, APIs, and Claude Code",
|
|
859
|
+
useWhen: "use the Context7 MCP before implementation when external library, SDK, API, framework, or Claude Code behavior matters.",
|
|
860
|
+
skipWhen: "Skip for pure local logic, typos, and code paths fully understood from this repository."
|
|
861
|
+
},
|
|
862
|
+
"claude-mem": {
|
|
863
|
+
id: "claude-mem",
|
|
864
|
+
name: "claude-mem",
|
|
865
|
+
type: "plugin",
|
|
866
|
+
invocation: "/claude-mem:mem-search",
|
|
867
|
+
summary: "cross-session memory search and phased plan/execution commands",
|
|
868
|
+
useWhen: "Use /claude-mem:mem-search when similar work, prior decisions, or repeated failures may exist; use /claude-mem:make-plan only for genuinely phased work.",
|
|
869
|
+
skipWhen: "Skip when the task is new, obvious, and smaller than a short local edit."
|
|
870
|
+
},
|
|
871
|
+
"sequential-thinking": {
|
|
872
|
+
id: "sequential-thinking",
|
|
873
|
+
name: "sequential-thinking",
|
|
874
|
+
type: "mcp",
|
|
875
|
+
invocation: "sequential-thinking MCP",
|
|
876
|
+
summary: "structured hypothesis breakdown for hard architecture and debugging problems",
|
|
877
|
+
useWhen: "Use for architecture tradeoffs, migrations, security/data/release risk, or debugging where assumptions may change.",
|
|
878
|
+
skipWhen: "Skip for direct edits, simple lookups, and deterministic fixes."
|
|
879
|
+
},
|
|
880
|
+
"chrome-devtools-mcp": {
|
|
881
|
+
id: "chrome-devtools-mcp",
|
|
882
|
+
name: "Chrome DevTools MCP",
|
|
883
|
+
type: "plugin",
|
|
884
|
+
invocation: "Chrome DevTools MCP",
|
|
885
|
+
summary: "real browser console, network, DOM, performance, and screenshot/snapshot verification",
|
|
886
|
+
useWhen: "Use for browser runtime behavior, UI regressions, DOM/CSS issues, network failures, and frontend verification.",
|
|
887
|
+
skipWhen: "Skip for backend-only code with no browser-facing behavior."
|
|
888
|
+
},
|
|
889
|
+
"frontend-design": {
|
|
890
|
+
id: "frontend-design",
|
|
891
|
+
name: "frontend-design",
|
|
892
|
+
type: "plugin",
|
|
893
|
+
invocation: "frontend-design plugin skills",
|
|
894
|
+
summary: "frontend UX/design guidance for UI pages, components, and interaction polish",
|
|
895
|
+
useWhen: "Use when building or changing visible UI, interaction design, frontend layout, or visual quality.",
|
|
896
|
+
skipWhen: "Skip for backend-only changes, copy-only edits, and internal CLI/library work."
|
|
897
|
+
},
|
|
898
|
+
"pua": {
|
|
899
|
+
id: "pua",
|
|
900
|
+
name: "pua",
|
|
901
|
+
type: "plugin",
|
|
902
|
+
invocation: "/pua:pua-loop or /pua:p9",
|
|
903
|
+
summary: "structured retries and parallel task decomposition",
|
|
904
|
+
useWhen: "Use after multiple failed attempts or for truly independent parallel work slices.",
|
|
905
|
+
skipWhen: "Skip on first-attempt failures, known fixes, and work that is sequential by dependency."
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
var ORDER = [
|
|
909
|
+
"context7",
|
|
910
|
+
"claude-mem",
|
|
911
|
+
"frontend-design",
|
|
912
|
+
"chrome-devtools-mcp",
|
|
913
|
+
"sequential-thinking",
|
|
914
|
+
"pua"
|
|
915
|
+
];
|
|
916
|
+
var DOCS_RE = /\b(api|sdk|library|libraries|framework|docs?|documentation|version|upgrade|dependency|dependencies|claude code|plugin|mcp|hook|hooks|skill|skills|agent|agents|react|vue|spring|spring boot|spring cloud|next\.?js|vite|webpack|npm|node)\b|最新|文档|依赖|框架|插件|官方|联网|搜索/i;
|
|
917
|
+
var MEMORY_RE = /\b(previous|before|again|remember|memory|history|similar|repeated|regression|already solved|same bug|past decision)\b|之前|上次|记得|历史|做过|又|重复|老问题/i;
|
|
918
|
+
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
|
+
var BROWSER_VERIFY_RE = /\b(browser|chrome|dom|css|network|console|performance|render|screenshot|e2e|playwright|visual regression|interaction)\b|浏览器|控制台|网络|性能|渲染|截图|端到端/i;
|
|
920
|
+
var COMPLEX_RE = /\b(architecture|architect|migration|migrate|security|auth|authentication|authorization|permission|oauth|payment|billing|database|schema|release|publish|npm|tag|hook|subagent|multi[- ]?repo|monorepo|cross[- ]?system|concurrency|race|cache|rewrite|refactor)\b|架构|迁移|安全|权限|认证|数据库|发布|重写|并发|跨仓库|多仓库/i;
|
|
921
|
+
var STUCK_RE = /\b(stuck|failed|failure|fails|flaky|retry|debug|investigate|root cause|not working|broken|regression)\b|卡住|失败|报错|不行|修不好|定位|排查/i;
|
|
922
|
+
var PARALLEL_RE = /\b(parallel|multi-agent|team|decompose|split|epic|multiple subsystems|large refactor)\b|并行|多智能体|拆分|史诗|多模块/i;
|
|
923
|
+
var LOW_RISK_LOCAL_RE = /\b(typo|readme|docs?|comment|comments|copy|wording|rename label|format text)\b|错别字|注释|文案/i;
|
|
924
|
+
function normalize(input) {
|
|
925
|
+
return (input ?? "").trim().replace(/\s+/g, " ");
|
|
926
|
+
}
|
|
927
|
+
function hasAny(values, candidates) {
|
|
928
|
+
const set = new Set((values ?? []).map((v) => v.toLowerCase()));
|
|
929
|
+
return candidates.some((candidate) => set.has(candidate.toLowerCase()));
|
|
930
|
+
}
|
|
931
|
+
function capabilityAllowed(id, available) {
|
|
932
|
+
return available === null || available.has(id);
|
|
933
|
+
}
|
|
934
|
+
function pushRecommendation(out, available, id, phase, reason, instruction) {
|
|
935
|
+
if (!capabilityAllowed(id, available)) return;
|
|
936
|
+
if (out.some((rec) => rec.id === id)) return;
|
|
937
|
+
const cap = CAPABILITIES[id];
|
|
938
|
+
out.push({
|
|
939
|
+
id,
|
|
940
|
+
name: cap.name,
|
|
941
|
+
type: cap.type,
|
|
942
|
+
invocation: cap.invocation,
|
|
943
|
+
phase,
|
|
944
|
+
reason,
|
|
945
|
+
instruction
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
function sortRecommendations(recs) {
|
|
949
|
+
return [...recs].sort((a, b) => ORDER.indexOf(a.id) - ORDER.indexOf(b.id));
|
|
950
|
+
}
|
|
951
|
+
function recommendToolCapabilities(input) {
|
|
952
|
+
const goal = normalize(input.goal);
|
|
953
|
+
const route = normalize(input.route);
|
|
954
|
+
const risk = normalize(input.risk);
|
|
955
|
+
const topologyKinds = input.topologyKinds ?? [];
|
|
956
|
+
const topologyFrameworks = input.topologyFrameworks ?? [];
|
|
957
|
+
const missingRoots = input.missingRoots ?? 0;
|
|
958
|
+
const available = input.availableCapabilities === void 0 ? null : new Set(input.availableCapabilities.filter(Boolean));
|
|
959
|
+
const recs = [];
|
|
960
|
+
if (missingRoots > 0) {
|
|
961
|
+
return recs;
|
|
962
|
+
}
|
|
963
|
+
const localLowRisk = LOW_RISK_LOCAL_RE.test(goal) && route === "direct-change";
|
|
964
|
+
if (localLowRisk) {
|
|
965
|
+
return recs;
|
|
966
|
+
}
|
|
967
|
+
const hasFrontend = UI_RE.test(goal) || hasAny(topologyKinds, ["frontend-app"]) || hasAny(topologyFrameworks, ["react", "vue", "next.js", "vite"]);
|
|
968
|
+
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";
|
|
970
|
+
const stuck = STUCK_RE.test(goal);
|
|
971
|
+
const parallel = PARALLEL_RE.test(goal) || route === "epic-split";
|
|
972
|
+
if (DOCS_RE.test(goal)) {
|
|
973
|
+
pushRecommendation(
|
|
974
|
+
recs,
|
|
975
|
+
available,
|
|
976
|
+
"context7",
|
|
977
|
+
"before-coding",
|
|
978
|
+
"external documentation or current API behavior is likely relevant",
|
|
979
|
+
"Use Context7 before editing so version-specific behavior is grounded in current docs."
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
if (MEMORY_RE.test(goal) || stuck || route === "full-spec" || route === "epic-split") {
|
|
983
|
+
pushRecommendation(
|
|
984
|
+
recs,
|
|
985
|
+
available,
|
|
986
|
+
"claude-mem",
|
|
987
|
+
"planning",
|
|
988
|
+
"similar prior work or longer-running plan may exist",
|
|
989
|
+
"Search memory before planning; use make-plan only when the work is genuinely phased."
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
if (hasFrontend) {
|
|
993
|
+
pushRecommendation(
|
|
994
|
+
recs,
|
|
995
|
+
available,
|
|
996
|
+
"frontend-design",
|
|
997
|
+
"implementation",
|
|
998
|
+
"visible frontend behavior or UI quality is in scope",
|
|
999
|
+
"Use frontend-design guidance for UI structure, interaction, responsive behavior, and visual polish."
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
if (browserRuntime) {
|
|
1003
|
+
pushRecommendation(
|
|
1004
|
+
recs,
|
|
1005
|
+
available,
|
|
1006
|
+
"chrome-devtools-mcp",
|
|
1007
|
+
"verification",
|
|
1008
|
+
"browser runtime behavior should be verified in a real browser",
|
|
1009
|
+
"Use Chrome DevTools MCP for console, network, DOM, performance, or visual proof after implementation."
|
|
1010
|
+
);
|
|
1011
|
+
}
|
|
1012
|
+
if (complex || stuck) {
|
|
1013
|
+
pushRecommendation(
|
|
1014
|
+
recs,
|
|
1015
|
+
available,
|
|
1016
|
+
"sequential-thinking",
|
|
1017
|
+
"planning",
|
|
1018
|
+
"risk or uncertainty requires explicit hypothesis management",
|
|
1019
|
+
"Use sequential-thinking to break assumptions before choosing the implementation path."
|
|
1020
|
+
);
|
|
1021
|
+
}
|
|
1022
|
+
if (stuck || parallel) {
|
|
1023
|
+
pushRecommendation(
|
|
1024
|
+
recs,
|
|
1025
|
+
available,
|
|
1026
|
+
"pua",
|
|
1027
|
+
stuck ? "recovery" : "planning",
|
|
1028
|
+
stuck ? "the goal indicates repeated failure or debugging difficulty" : "large work may contain independent parallel slices",
|
|
1029
|
+
stuck ? "Use /pua:pua-loop only after local triage confirms the first fix path is not working." : "Use /pua:p9 only after dependencies prove the slices can run independently."
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
return sortRecommendations(recs);
|
|
1033
|
+
}
|
|
1034
|
+
function renderInstalledCapabilityRules(availableCapabilities) {
|
|
1035
|
+
const available = new Set(availableCapabilities);
|
|
1036
|
+
const lines = [
|
|
1037
|
+
"Use installed capabilities by trigger, not by habit. Prefer the first matching rule; skip absent capabilities."
|
|
1038
|
+
];
|
|
1039
|
+
for (const id of ORDER) {
|
|
1040
|
+
if (!available.has(id)) continue;
|
|
1041
|
+
const cap = CAPABILITIES[id];
|
|
1042
|
+
lines.push(`- ${cap.invocation}: ${cap.useWhen} ${cap.skipWhen}`);
|
|
1043
|
+
}
|
|
1044
|
+
return lines;
|
|
1045
|
+
}
|
|
1046
|
+
function renderCapabilityDecisionTree(availableCapabilities) {
|
|
1047
|
+
const available = new Set(availableCapabilities);
|
|
1048
|
+
const lines = [
|
|
1049
|
+
"1. Can the edit be finished safely from local code in 1-2 steps? -> Do it directly."
|
|
1050
|
+
];
|
|
1051
|
+
if (available.has("context7")) {
|
|
1052
|
+
lines.push("2. Does correctness depend on external docs, SDKs, APIs, or Claude Code behavior? -> use the Context7 MCP before editing.");
|
|
1053
|
+
}
|
|
1054
|
+
if (available.has("claude-mem")) {
|
|
1055
|
+
lines.push("3. Might similar work, a prior decision, or a repeated failure exist? -> Start with `/claude-mem:mem-search`.");
|
|
1056
|
+
}
|
|
1057
|
+
if (available.has("frontend-design") || available.has("chrome-devtools-mcp")) {
|
|
1058
|
+
lines.push("4. Is visible frontend behavior in scope? -> Use frontend-design for UI decisions and Chrome DevTools MCP for runtime proof when installed.");
|
|
1059
|
+
}
|
|
1060
|
+
if (available.has("sequential-thinking")) {
|
|
1061
|
+
lines.push("5. Is the work high-risk, architectural, or assumption-heavy? -> Use sequential-thinking after reading the relevant code.");
|
|
1062
|
+
}
|
|
1063
|
+
if (available.has("pua")) {
|
|
1064
|
+
lines.push("6. Are there multiple failed attempts or truly independent parallel slices? -> Use `/pua:pua-loop` for recovery or `/pua:p9` for bounded parallel planning.");
|
|
1065
|
+
}
|
|
1066
|
+
return lines;
|
|
1067
|
+
}
|
|
1068
|
+
function parseList(value) {
|
|
1069
|
+
if (!value) return [];
|
|
1070
|
+
return value.split(/[,;\n]/).map((s) => s.trim()).filter(Boolean);
|
|
1071
|
+
}
|
|
1072
|
+
function readArg(name, argv2) {
|
|
1073
|
+
const idx = argv2.indexOf(name);
|
|
1074
|
+
if (idx === -1) return void 0;
|
|
1075
|
+
return argv2[idx + 1];
|
|
1076
|
+
}
|
|
1077
|
+
function main() {
|
|
1078
|
+
const argv2 = process.argv.slice(2);
|
|
1079
|
+
const recommendations = recommendToolCapabilities({
|
|
1080
|
+
goal: readArg("--goal", argv2),
|
|
1081
|
+
route: readArg("--route", argv2),
|
|
1082
|
+
risk: readArg("--risk", argv2),
|
|
1083
|
+
topologyKinds: parseList(readArg("--topology-kinds", argv2)),
|
|
1084
|
+
topologyFrameworks: parseList(readArg("--topology-frameworks", argv2)),
|
|
1085
|
+
missingRoots: Number(readArg("--missing-roots", argv2) ?? 0),
|
|
1086
|
+
availableCapabilities: readArg("--available-capabilities", argv2) ? parseList(readArg("--available-capabilities", argv2)) : void 0
|
|
1087
|
+
});
|
|
1088
|
+
process.stdout.write(JSON.stringify(recommendations, null, 2) + "\n");
|
|
1089
|
+
}
|
|
1090
|
+
function isDirectRun() {
|
|
1091
|
+
try {
|
|
1092
|
+
const entry = fileURLToPath(import.meta.url);
|
|
1093
|
+
return process.argv[1] === entry && basename(entry).startsWith("tool-capabilities.");
|
|
1094
|
+
} catch {
|
|
1095
|
+
return false;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
if (isDirectRun()) {
|
|
1099
|
+
main();
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// src/runner/claudeMd.ts
|
|
848
1103
|
var BEGIN_MARKER = "<!-- BEGIN @curdx/flow v1 -->";
|
|
849
1104
|
var END_MARKER = "<!-- END @curdx/flow v1 -->";
|
|
850
1105
|
var BLOCK_RE = /<!-- BEGIN @curdx\/flow v\d+[^>]*-->[\s\S]*?<!-- END @curdx\/flow v\d+ -->/;
|
|
@@ -852,63 +1107,11 @@ function claudeMdPath() {
|
|
|
852
1107
|
return path4.join(os2.homedir(), ".claude", "CLAUDE.md");
|
|
853
1108
|
}
|
|
854
1109
|
function buildCombinationPatterns(ids) {
|
|
855
|
-
const
|
|
856
|
-
|
|
857
|
-
"
|
|
858
|
-
""
|
|
859
|
-
];
|
|
860
|
-
if (has("context7") || has("curdx-flow") || has("claude-mem")) {
|
|
861
|
-
out.push("- **Starting a new feature**");
|
|
862
|
-
let step = 1;
|
|
863
|
-
if (has("context7")) {
|
|
864
|
-
out.push(` ${step++}. If external libraries, SDKs, frameworks, or APIs are involved, use the Context7 MCP to pull current official docs.`);
|
|
865
|
-
}
|
|
866
|
-
const planners = [];
|
|
867
|
-
if (has("claude-mem")) planners.push("`/claude-mem:make-plan` for a phased plan");
|
|
868
|
-
if (has("curdx-flow")) planners.push("`/curdx-flow:new` or the spec flow for a full specification");
|
|
869
|
-
if (planners.length > 0) {
|
|
870
|
-
out.push(` ${step++}. Only move into ${planners.join(" or ")} when the work is multi-step, cross-cutting, or uncertain.`);
|
|
871
|
-
}
|
|
872
|
-
out.push(` ${step++}. For small, clear one-shot changes, implement directly instead of forcing the full workflow.`);
|
|
873
|
-
out.push("");
|
|
874
|
-
}
|
|
875
|
-
const stuckLines = [];
|
|
876
|
-
let s = 1;
|
|
877
|
-
if (has("chrome-devtools-mcp")) {
|
|
878
|
-
stuckLines.push(` ${s++}. For browser-side issues, use the Chrome DevTools MCP for network, console, performance, and DOM snapshots.`);
|
|
879
|
-
}
|
|
880
|
-
if (has("context7")) {
|
|
881
|
-
stuckLines.push(` ${s++}. If the issue may come from library or API behavior, use the Context7 MCP instead of relying on memory.`);
|
|
882
|
-
}
|
|
883
|
-
const stillStuck = [];
|
|
884
|
-
if (has("sequential-thinking")) stillStuck.push("switch to the sequential-thinking MCP to break down hypotheses");
|
|
885
|
-
if (has("pua")) stillStuck.push("enter `/pua:pua-loop` for structured retries");
|
|
886
|
-
if (stillStuck.length > 0) {
|
|
887
|
-
stuckLines.push(` ${s++}. If you are still stuck after multiple attempts, ${stillStuck.join(" or ")}.`);
|
|
888
|
-
}
|
|
889
|
-
if (stuckLines.length > 0) {
|
|
890
|
-
out.push("- **Debugging and repeated failures**", ...stuckLines, "");
|
|
891
|
-
}
|
|
892
|
-
if (has("frontend-design") || has("chrome-devtools-mcp")) {
|
|
893
|
-
out.push("- **UI and frontend work**");
|
|
894
|
-
if (has("frontend-design")) {
|
|
895
|
-
out.push(" - Prioritize the `frontend-design` plugin skills for UI work; if they do not trigger automatically, invoke the relevant skill explicitly.");
|
|
896
|
-
}
|
|
897
|
-
if (has("chrome-devtools-mcp")) {
|
|
898
|
-
out.push(" - For rendering issues, interaction bugs, or visual regressions, verify with the Chrome DevTools MCP instead of relying on visual guesswork alone.");
|
|
899
|
-
}
|
|
900
|
-
out.push("");
|
|
1110
|
+
const out = renderInstalledCapabilityRules([...ids]);
|
|
1111
|
+
if (ids.has("curdx-flow")) {
|
|
1112
|
+
out.push("- /curdx-flow:start: Use for ambiguous, cross-cutting, phase-based, or multi-root work; skip for small direct edits.");
|
|
1113
|
+
out.push("- /curdx-flow:triage: Use when one request is too large for a single coherent spec.");
|
|
901
1114
|
}
|
|
902
|
-
if (has("pua") || has("curdx-flow")) {
|
|
903
|
-
out.push("- **Large, cross-cutting, or multi-agent work**");
|
|
904
|
-
if (has("pua")) {
|
|
905
|
-
out.push(" - Use `/pua:p9` for parallel task decomposition and team coordination; reserve `/pua:p10` for higher-level strategy work.");
|
|
906
|
-
}
|
|
907
|
-
if (has("curdx-flow")) {
|
|
908
|
-
out.push(" - Use `/curdx-flow:triage` when one large feature needs to be split into multiple dependent specs.");
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
while (out.length > 0 && out[out.length - 1] === "") out.pop();
|
|
912
1115
|
return out;
|
|
913
1116
|
}
|
|
914
1117
|
function buildSkipRules(ids) {
|
|
@@ -928,18 +1131,9 @@ function buildSkipRules(ids) {
|
|
|
928
1131
|
return out;
|
|
929
1132
|
}
|
|
930
1133
|
function buildDecisionTree(ids) {
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
out.push("2. Is it multi-step but still clear? -> Break it into a short task list and execute without defaulting to the full spec flow.");
|
|
935
|
-
const planners = [];
|
|
936
|
-
if (has("curdx-flow")) planners.push("`/curdx-flow:new`");
|
|
937
|
-
if (has("claude-mem")) planners.push("`/claude-mem:make-plan`");
|
|
938
|
-
if (planners.length > 0) {
|
|
939
|
-
out.push(`3. Is the request ambiguous, cross-cutting, or phase-based? -> ${planners.join(" or ")}.`);
|
|
940
|
-
}
|
|
941
|
-
if (has("claude-mem")) {
|
|
942
|
-
out.push("4. Might this work have been done before? -> Start with `/claude-mem:mem-search`.");
|
|
1134
|
+
const out = renderCapabilityDecisionTree([...ids]);
|
|
1135
|
+
if (ids.has("curdx-flow")) {
|
|
1136
|
+
out.push("7. Is the request ambiguous, cross-cutting, phase-based, or multi-root? -> Run /curdx-flow:start.");
|
|
943
1137
|
}
|
|
944
1138
|
return out;
|
|
945
1139
|
}
|
|
@@ -1677,8 +1871,8 @@ var analyze_default = analyzeCmd;
|
|
|
1677
1871
|
// src/runner/buildFreshness.ts
|
|
1678
1872
|
import { readdirSync, statSync, existsSync as existsSync3 } from "fs";
|
|
1679
1873
|
import path5 from "path";
|
|
1680
|
-
import { fileURLToPath } from "url";
|
|
1681
|
-
var SELF_PATH =
|
|
1874
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1875
|
+
var SELF_PATH = fileURLToPath2(import.meta.url);
|
|
1682
1876
|
var RUNNER_DIR = path5.dirname(SELF_PATH);
|
|
1683
1877
|
var PROJECT_ROOT = path5.resolve(RUNNER_DIR, "..", "..");
|
|
1684
1878
|
var SRC_DIR = path5.join(PROJECT_ROOT, "src");
|