devflow-kit 2.4.0 → 2.5.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.
- package/CHANGELOG.md +156 -0
- package/README.md +86 -18
- package/dist/agents/git.md +824 -0
- package/dist/cli/commands/agents.js +6 -1
- package/dist/cli/commands/attribution-prompts.js +1 -1
- package/dist/cli/commands/compliance-prompts.js +1 -1
- package/dist/cli/commands/compliance.js +23 -1
- package/dist/cli/commands/init-seed.js +24 -26
- package/dist/cli/commands/init.js +502 -71
- package/dist/cli/commands/install-report.js +205 -0
- package/dist/cli/commands/knowledge/index.js +2 -2
- package/dist/cli/commands/knowledge/toggle.js +27 -37
- package/dist/cli/commands/learning.js +37 -30
- package/dist/cli/commands/memory.js +79 -69
- package/dist/cli/commands/prompt-io.js +4 -4
- package/dist/cli/commands/security.js +76 -16
- package/dist/cli/commands/skills.js +53 -7
- package/dist/cli/commands/tracker-prompts.js +145 -0
- package/dist/cli/commands/tracker.js +405 -0
- package/dist/cli/commands/uninstall.js +211 -65
- package/dist/cli.js +2 -0
- package/dist/commands/bug-analysis.md +22 -4
- package/dist/commands/code-review.md +44 -15
- package/dist/commands/debug.md +20 -6
- package/dist/commands/dynamic-build.md +289 -67
- package/dist/commands/dynamic-plan.md +60 -21
- package/dist/commands/dynamic-profile.md +1 -1
- package/dist/commands/dynamic-tickets.md +58 -8
- package/dist/commands/explore.md +2 -2
- package/dist/commands/implement.md +241 -53
- package/dist/commands/plan.md +88 -17
- package/dist/commands/release.md +64 -17
- package/dist/commands/resolve.md +138 -58
- package/dist/commands/self-review.md +2 -2
- package/dist/core/agent-models.js +55 -12
- package/dist/core/assets.js +58 -2
- package/dist/core/evidence-policy.js +147 -0
- package/dist/core/feature-config.js +130 -64
- package/dist/core/feature-switch.js +112 -0
- package/dist/core/flags.js +4 -4
- package/dist/core/manifest.js +33 -7
- package/dist/core/mds-variants.js +861 -0
- package/dist/core/model-discovery.js +12 -1
- package/dist/core/plugins.js +357 -9
- package/dist/core/project-paths.js +1 -1
- package/dist/core/proxy-log.js +8 -6
- package/dist/core/proxy-state.js +11 -8
- package/dist/core/reference-sweep.js +136 -0
- package/dist/core/tracker.js +407 -0
- package/dist/skills/git/references/decision-markers.md +19 -0
- package/dist/skills/git/references/learn-conventions.md +56 -0
- package/dist/skills/git/references/pr/check-ci-status.md +14 -0
- package/dist/skills/git/references/pr/check-merge-readiness.md +28 -0
- package/dist/skills/git/references/pr/ensure-pr-ready.md +24 -0
- package/dist/skills/git/references/pr/fetch-review-threads.md +22 -0
- package/dist/skills/git/references/pr/post-resolution-summary.md +40 -0
- package/dist/skills/git/references/pr/post-review-summary.md +42 -0
- package/dist/skills/git/references/pr/resolve-review-threads.md +35 -0
- package/dist/skills/git/references/pr/update-pr-evidence.md +14 -0
- package/dist/skills/git/references/pr/validate-branch.md +18 -0
- package/dist/skills/git/references/publication-gate.md +13 -0
- package/dist/skills/git/references/tracker/_mcp.md +153 -0
- package/dist/skills/git/references/tracker/github/associate-release.md +18 -0
- package/dist/skills/git/references/tracker/github/backlink-shipped-issues.md +40 -0
- package/dist/skills/git/references/tracker/github/create-release.md +11 -0
- package/dist/skills/git/references/tracker/github/ensure-pr-ready.md +16 -0
- package/dist/skills/git/references/tracker/github/ensure-traceable-issue.md +69 -0
- package/dist/skills/git/references/tracker/github/fetch-issue.md +32 -0
- package/dist/skills/git/references/tracker/github/fetch-issues-batch.md +17 -0
- package/dist/skills/git/references/tracker/github/gather-release-evidence.md +19 -0
- package/dist/skills/git/references/tracker/github/manage-debt.md +101 -0
- package/dist/skills/git/references/tracker/github/post-wave-report.md +28 -0
- package/dist/skills/git/references/tracker/github/setup-task.md +26 -0
- package/dist/skills/git/references/tracker/jira/associate-release.md +18 -0
- package/dist/skills/git/references/tracker/jira/backlink-shipped-issues.md +49 -0
- package/dist/skills/git/references/tracker/jira/create-release.md +17 -0
- package/dist/skills/git/references/tracker/jira/ensure-pr-ready.md +22 -0
- package/dist/skills/git/references/tracker/jira/ensure-traceable-issue.md +53 -0
- package/dist/skills/git/references/tracker/jira/fetch-issue.md +14 -0
- package/dist/skills/git/references/tracker/jira/fetch-issues-batch.md +15 -0
- package/dist/skills/git/references/tracker/jira/gather-release-evidence.md +18 -0
- package/dist/skills/git/references/tracker/jira/manage-debt.md +37 -0
- package/dist/skills/git/references/tracker/jira/post-wave-report.md +33 -0
- package/dist/skills/git/references/tracker/jira/setup-task.md +31 -0
- package/dist/skills/git/references/tracker/linear/associate-release.md +18 -0
- package/dist/skills/git/references/tracker/linear/backlink-shipped-issues.md +53 -0
- package/dist/skills/git/references/tracker/linear/create-release.md +17 -0
- package/dist/skills/git/references/tracker/linear/ensure-pr-ready.md +22 -0
- package/dist/skills/git/references/tracker/linear/ensure-traceable-issue.md +53 -0
- package/dist/skills/git/references/tracker/linear/fetch-issue.md +14 -0
- package/dist/skills/git/references/tracker/linear/fetch-issues-batch.md +15 -0
- package/dist/skills/git/references/tracker/linear/gather-release-evidence.md +18 -0
- package/dist/skills/git/references/tracker/linear/manage-debt.md +37 -0
- package/dist/skills/git/references/tracker/linear/post-wave-report.md +33 -0
- package/dist/skills/git/references/tracker/linear/setup-task.md +32 -0
- package/dist/skills/git/references/trust-rule.md +7 -0
- package/dist/targets/claude-code/installer.js +1213 -31
- package/dist/targets/claude-code/legacy.js +5 -0
- package/dist/targets/claude-code/post-install.js +196 -74
- package/dist/targets/claude-code/tracker-install.js +161 -0
- package/package.json +4 -3
- package/src/assets/agents/code.md +42 -4
- package/src/assets/agents/design.md +1 -1
- package/src/assets/agents/git.mds +827 -0
- package/src/assets/agents/knowledge.md +1 -1
- package/src/assets/agents/learning.md +11 -0
- package/src/assets/agents/synthesize.md +1 -1
- package/src/assets/agents/test.md +16 -5
- package/src/assets/agents/tracker.md +467 -0
- package/src/assets/agents/validate.md +7 -5
- package/src/assets/commands/_partials/_engine.mds +11 -9
- package/src/assets/commands/_partials/_evidence_policy.mds +30 -0
- package/src/assets/commands/_partials/_knowledge.mds +2 -2
- package/src/assets/commands/_partials/_plan_contract.mds +22 -7
- package/src/assets/commands/_partials/_preamble.mds +1 -1
- package/src/assets/commands/_partials/_publication.mds +3 -1
- package/src/assets/commands/_partials/_ticket_template.mds +3 -2
- package/src/assets/commands/_partials/_tracker.mds +18 -0
- package/src/assets/commands/_partials/_wave.mds +16 -10
- package/src/assets/commands/bug-analysis.mds +15 -5
- package/src/assets/commands/code-review.mds +34 -14
- package/src/assets/commands/debug.mds +11 -4
- package/src/assets/commands/dynamic-build.mds +227 -41
- package/src/assets/commands/dynamic-plan.mds +35 -13
- package/src/assets/commands/dynamic-tickets.mds +47 -5
- package/src/assets/commands/implement.mds +206 -52
- package/src/assets/commands/plan.mds +70 -17
- package/src/assets/commands/release.md +64 -17
- package/src/assets/commands/resolve.mds +126 -56
- package/src/assets/mds/git/_pr.mds +331 -0
- package/src/assets/mds/git/_references.mds +135 -0
- package/src/assets/mds/tracker/_common.mds +156 -0
- package/src/assets/mds/tracker/_github.mds +472 -0
- package/src/assets/mds/tracker/_jira.mds +407 -0
- package/src/assets/mds/tracker/_linear.mds +449 -0
- package/src/assets/mds/tracker/_mcp.mds +299 -0
- package/src/assets/scripts/hooks/assets/orchestrator-charter.md +5 -8
- package/src/assets/scripts/hooks/background-memory-update +14 -9
- package/src/assets/scripts/hooks/capture-prompt +6 -2
- package/src/assets/scripts/hooks/capture-question +6 -2
- package/src/assets/scripts/hooks/capture-turn +6 -2
- package/src/assets/scripts/hooks/ensure-devflow-init +1 -1
- package/src/assets/scripts/hooks/ensure-root-gitignore +161 -60
- package/src/assets/scripts/hooks/hook-log-init +3 -1
- package/src/assets/scripts/hooks/json-helper.cjs +223 -5
- package/src/assets/scripts/hooks/lib/project-paths.cjs +1 -1
- package/src/assets/scripts/hooks/memory-worker +15 -8
- package/src/assets/scripts/hooks/pre-compact-memory +12 -8
- package/src/assets/scripts/hooks/preamble +1 -4
- package/src/assets/scripts/hooks/queue-append +68 -24
- package/src/assets/scripts/hooks/session-start-context +355 -8
- package/src/assets/scripts/hooks/session-start-memory +12 -8
- package/src/assets/scripts/pr-evidence.cjs +1961 -0
- package/src/assets/scripts/redact-secrets.cjs +490 -62
- package/src/assets/scripts/release-trace.cjs +1143 -0
- package/src/assets/scripts/resolve-evidence-policy.cjs +1065 -0
- package/src/assets/scripts/verify-evidence.cjs +1822 -0
- package/src/assets/skills/compliance/SKILL.md +2 -0
- package/src/assets/skills/docs-framework/SKILL.md +5 -3
- package/src/assets/skills/git/SKILL.md +8 -78
- package/src/assets/skills/git/references/github-api.md +179 -141
- package/src/assets/skills/git/references/patterns.md +11 -6
- package/src/assets/skills/review-methodology/SKILL.md +1 -1
- package/src/assets/skills/review-methodology/references/patterns.md +6 -61
- package/src/assets/skills/review-methodology/references/violations.md +14 -22
- package/src/assets/agents/git.md +0 -938
|
@@ -552,7 +552,18 @@ async function _discoverInternal(cacheDir, logPath, deps) {
|
|
|
552
552
|
// completes during the spawn's SPAWN_TIMEOUT_MS window).
|
|
553
553
|
const staleRawP = findStaleFallback(cacheDir, currentKey);
|
|
554
554
|
// --- Live spawn ---
|
|
555
|
-
|
|
555
|
+
// @D-EFR-6 Discovery reads the runtime's built-in registry, never a user config.
|
|
556
|
+
// Since 0.5.0 every implicit config load merges the runtime's user-level file
|
|
557
|
+
// ($XDG_CONFIG_HOME/subswitch/config.json, else ~/.config/subswitch/config.json)
|
|
558
|
+
// under the cwd project file. Devflow's relay never sees that file — it is always
|
|
559
|
+
// started with an explicit SUBSWITCH_CONFIG, which bypasses the merge — so a user
|
|
560
|
+
// alias leaking into discovery would be offered in the picker yet never routed,
|
|
561
|
+
// and a malformed file would fail every live discovery. The cache key also
|
|
562
|
+
// assumes the catalog depends on the runtime version alone. Pointing
|
|
563
|
+
// XDG_CONFIG_HOME at devflow's own cache directory, which never holds a
|
|
564
|
+
// `subswitch/config.json`, makes the lookup a clean ENOENT. SUBSWITCH_CONFIG
|
|
565
|
+
// stays unset (T2): an explicit path that is missing is a hard error.
|
|
566
|
+
const env = { ...scrubChildEnv(), NO_COLOR: '1', XDG_CONFIG_HOME: cacheDir };
|
|
556
567
|
const spawnFn = deps?.spawnAndCollect ?? buildRealSpawnAndCollect(logPath);
|
|
557
568
|
let spawnResult;
|
|
558
569
|
try {
|
package/dist/core/plugins.js
CHANGED
|
@@ -29,8 +29,41 @@ export const DEVFLOW_PLUGINS = [
|
|
|
29
29
|
name: 'devflow-core-skills',
|
|
30
30
|
description: 'Auto-activating quality enforcement skills - foundation layer for all Devflow plugins',
|
|
31
31
|
commands: [],
|
|
32
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Hook-spawned agents live here, and `commands: []` above is why that works.
|
|
34
|
+
*
|
|
35
|
+
* Guard 5 reverse (registry-integrity.test.ts, "declared agents are spawned")
|
|
36
|
+
* skips a plugin whose commands spawn nothing — `if (spawned.size === 0)
|
|
37
|
+
* continue` — and this plugin ships no commands at all. So `learning` and
|
|
38
|
+
* `tracker`, which are spawned by a SessionStart directive rather than by any
|
|
39
|
+
* command, satisfy the reverse check STRUCTURALLY.
|
|
40
|
+
*
|
|
41
|
+
* Recorded because the alternative looks equivalent and is not: adding either
|
|
42
|
+
* name to an exemption list would make the guard pass by being told to ignore
|
|
43
|
+
* them, which is the vacuous-guard trap this repo polices everywhere else. If
|
|
44
|
+
* this plugin ever gains a command, the right fix is a new commands-less
|
|
45
|
+
* plugin for the hook-spawned agents — never an exemption.
|
|
46
|
+
*
|
|
47
|
+
* Neither agent may gain a `_roster.mds` row: that file is asserted
|
|
48
|
+
* set-equal, both directions, against the `agentType` values present in
|
|
49
|
+
* dist/commands/, and a hook-spawned agent appears in none of them.
|
|
50
|
+
*/
|
|
51
|
+
agents: ['learning', 'tracker'],
|
|
33
52
|
skills: ['apply-decisions', 'apply-feature-knowledge', 'software-design', 'docs-framework', 'git', 'boundary-validation', 'test-driven-development', 'testing', 'dependency-research'],
|
|
53
|
+
requires: [
|
|
54
|
+
'architecture',
|
|
55
|
+
'complexity',
|
|
56
|
+
'consistency',
|
|
57
|
+
'database',
|
|
58
|
+
'dependencies',
|
|
59
|
+
'documentation',
|
|
60
|
+
'performance',
|
|
61
|
+
'regression',
|
|
62
|
+
'reliability',
|
|
63
|
+
'review-methodology',
|
|
64
|
+
'security',
|
|
65
|
+
'worktree-support',
|
|
66
|
+
],
|
|
34
67
|
rules: ['security', 'engineering', 'quality', 'reliability'],
|
|
35
68
|
},
|
|
36
69
|
{
|
|
@@ -39,6 +72,25 @@ export const DEVFLOW_PLUGINS = [
|
|
|
39
72
|
commands: ['/plan'],
|
|
40
73
|
agents: ['git', 'skim', 'synthesize', 'design'],
|
|
41
74
|
skills: ['gap-analysis', 'design-review', 'patterns', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
|
|
75
|
+
requires: [
|
|
76
|
+
'apply-decisions',
|
|
77
|
+
'architecture',
|
|
78
|
+
'complexity',
|
|
79
|
+
'consistency',
|
|
80
|
+
'database',
|
|
81
|
+
'dependencies',
|
|
82
|
+
'docs-framework',
|
|
83
|
+
'documentation',
|
|
84
|
+
'git',
|
|
85
|
+
'performance',
|
|
86
|
+
'regression',
|
|
87
|
+
'reliability',
|
|
88
|
+
'review-methodology',
|
|
89
|
+
'security',
|
|
90
|
+
'software-design',
|
|
91
|
+
'test-driven-development',
|
|
92
|
+
'testing',
|
|
93
|
+
],
|
|
42
94
|
rules: [],
|
|
43
95
|
},
|
|
44
96
|
{
|
|
@@ -47,6 +99,26 @@ export const DEVFLOW_PLUGINS = [
|
|
|
47
99
|
commands: ['/implement'],
|
|
48
100
|
agents: ['git', 'code', 'simplify', 'scrutinize', 'evaluate', 'test', 'validate', 'knowledge'],
|
|
49
101
|
skills: ['patterns', 'qa', 'quality-gates', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
|
|
102
|
+
requires: [
|
|
103
|
+
'apply-decisions',
|
|
104
|
+
'architecture',
|
|
105
|
+
'boundary-validation',
|
|
106
|
+
'complexity',
|
|
107
|
+
'consistency',
|
|
108
|
+
'database',
|
|
109
|
+
'dependencies',
|
|
110
|
+
'dependency-research',
|
|
111
|
+
'documentation',
|
|
112
|
+
'git',
|
|
113
|
+
'performance',
|
|
114
|
+
'regression',
|
|
115
|
+
'reliability',
|
|
116
|
+
'review-methodology',
|
|
117
|
+
'security',
|
|
118
|
+
'software-design',
|
|
119
|
+
'test-driven-development',
|
|
120
|
+
'testing',
|
|
121
|
+
],
|
|
50
122
|
rules: [],
|
|
51
123
|
},
|
|
52
124
|
{
|
|
@@ -55,14 +127,34 @@ export const DEVFLOW_PLUGINS = [
|
|
|
55
127
|
commands: ['/code-review'],
|
|
56
128
|
agents: ['git', 'review', 'synthesize'],
|
|
57
129
|
skills: ['architecture', 'complexity', 'consistency', 'database', 'dependencies', 'documentation', 'performance', 'regression', 'reliability', 'review-methodology', 'security', 'testing', 'worktree-support', 'apply-feature-knowledge'],
|
|
130
|
+
requires: ['apply-decisions', 'docs-framework', 'git', 'quality-gates', 'software-design'],
|
|
58
131
|
rules: [],
|
|
59
132
|
},
|
|
60
133
|
{
|
|
61
134
|
name: 'devflow-resolve',
|
|
62
135
|
description: 'Process and fix code review issues with blast-radius triage, Code agent fixes, and Validate agent verification',
|
|
63
136
|
commands: ['/resolve'],
|
|
64
|
-
agents: ['git', 'triage', 'code', 'simplify', 'validate', 'knowledge'],
|
|
137
|
+
agents: ['git', 'triage', 'code', 'simplify', 'validate', 'test', 'knowledge'],
|
|
65
138
|
skills: ['patterns', 'security', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge', 'apply-decisions'],
|
|
139
|
+
requires: [
|
|
140
|
+
'architecture',
|
|
141
|
+
'boundary-validation',
|
|
142
|
+
'complexity',
|
|
143
|
+
'consistency',
|
|
144
|
+
'database',
|
|
145
|
+
'dependencies',
|
|
146
|
+
'dependency-research',
|
|
147
|
+
'documentation',
|
|
148
|
+
'git',
|
|
149
|
+
'performance',
|
|
150
|
+
'qa',
|
|
151
|
+
'regression',
|
|
152
|
+
'reliability',
|
|
153
|
+
'review-methodology',
|
|
154
|
+
'software-design',
|
|
155
|
+
'test-driven-development',
|
|
156
|
+
'testing',
|
|
157
|
+
],
|
|
66
158
|
rules: [],
|
|
67
159
|
},
|
|
68
160
|
{
|
|
@@ -71,6 +163,25 @@ export const DEVFLOW_PLUGINS = [
|
|
|
71
163
|
commands: ['/debug'],
|
|
72
164
|
agents: ['git', 'synthesize', 'simplify', 'knowledge'],
|
|
73
165
|
skills: ['git', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
|
|
166
|
+
requires: [
|
|
167
|
+
'apply-decisions',
|
|
168
|
+
'architecture',
|
|
169
|
+
'complexity',
|
|
170
|
+
'consistency',
|
|
171
|
+
'database',
|
|
172
|
+
'dependencies',
|
|
173
|
+
'docs-framework',
|
|
174
|
+
'documentation',
|
|
175
|
+
'patterns',
|
|
176
|
+
'performance',
|
|
177
|
+
'regression',
|
|
178
|
+
'reliability',
|
|
179
|
+
'review-methodology',
|
|
180
|
+
'security',
|
|
181
|
+
'software-design',
|
|
182
|
+
'test-driven-development',
|
|
183
|
+
'testing',
|
|
184
|
+
],
|
|
74
185
|
rules: [],
|
|
75
186
|
},
|
|
76
187
|
{
|
|
@@ -79,6 +190,22 @@ export const DEVFLOW_PLUGINS = [
|
|
|
79
190
|
commands: ['/explore'],
|
|
80
191
|
agents: ['skim', 'synthesize', 'knowledge'],
|
|
81
192
|
skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge'],
|
|
193
|
+
requires: [
|
|
194
|
+
'apply-decisions',
|
|
195
|
+
'architecture',
|
|
196
|
+
'complexity',
|
|
197
|
+
'consistency',
|
|
198
|
+
'database',
|
|
199
|
+
'dependencies',
|
|
200
|
+
'docs-framework',
|
|
201
|
+
'documentation',
|
|
202
|
+
'performance',
|
|
203
|
+
'regression',
|
|
204
|
+
'reliability',
|
|
205
|
+
'review-methodology',
|
|
206
|
+
'security',
|
|
207
|
+
'testing',
|
|
208
|
+
],
|
|
82
209
|
rules: [],
|
|
83
210
|
},
|
|
84
211
|
{
|
|
@@ -87,6 +214,22 @@ export const DEVFLOW_PLUGINS = [
|
|
|
87
214
|
commands: ['/research'],
|
|
88
215
|
agents: ['research', 'skim', 'synthesize', 'knowledge'],
|
|
89
216
|
skills: ['worktree-support', 'apply-feature-knowledge', 'feature-knowledge', 'research-codebase', 'research-external', 'research-market', 'research-competitor', 'research-technology'],
|
|
217
|
+
requires: [
|
|
218
|
+
'apply-decisions',
|
|
219
|
+
'architecture',
|
|
220
|
+
'complexity',
|
|
221
|
+
'consistency',
|
|
222
|
+
'database',
|
|
223
|
+
'dependencies',
|
|
224
|
+
'docs-framework',
|
|
225
|
+
'documentation',
|
|
226
|
+
'performance',
|
|
227
|
+
'regression',
|
|
228
|
+
'reliability',
|
|
229
|
+
'review-methodology',
|
|
230
|
+
'security',
|
|
231
|
+
'testing',
|
|
232
|
+
],
|
|
90
233
|
rules: [],
|
|
91
234
|
},
|
|
92
235
|
{
|
|
@@ -95,6 +238,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
95
238
|
commands: ['/release'],
|
|
96
239
|
agents: ['git', 'validate'],
|
|
97
240
|
skills: ['git', 'worktree-support'],
|
|
241
|
+
requires: ['testing'],
|
|
98
242
|
rules: [],
|
|
99
243
|
},
|
|
100
244
|
{
|
|
@@ -103,6 +247,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
103
247
|
commands: ['/self-review'],
|
|
104
248
|
agents: ['simplify', 'scrutinize', 'validate', 'knowledge'],
|
|
105
249
|
skills: ['quality-gates', 'software-design', 'worktree-support', 'feature-knowledge', 'apply-feature-knowledge'],
|
|
250
|
+
requires: ['apply-decisions', 'testing'],
|
|
106
251
|
rules: [],
|
|
107
252
|
},
|
|
108
253
|
{
|
|
@@ -120,6 +265,17 @@ export const DEVFLOW_PLUGINS = [
|
|
|
120
265
|
'security',
|
|
121
266
|
'worktree-support',
|
|
122
267
|
],
|
|
268
|
+
requires: [
|
|
269
|
+
'architecture',
|
|
270
|
+
'database',
|
|
271
|
+
'dependencies',
|
|
272
|
+
'docs-framework',
|
|
273
|
+
'documentation',
|
|
274
|
+
'git',
|
|
275
|
+
'performance',
|
|
276
|
+
'review-methodology',
|
|
277
|
+
'testing',
|
|
278
|
+
],
|
|
123
279
|
rules: [],
|
|
124
280
|
},
|
|
125
281
|
{
|
|
@@ -148,6 +304,21 @@ export const DEVFLOW_PLUGINS = [
|
|
|
148
304
|
'feature-knowledge',
|
|
149
305
|
'apply-feature-knowledge',
|
|
150
306
|
],
|
|
307
|
+
requires: [
|
|
308
|
+
'apply-decisions',
|
|
309
|
+
'boundary-validation',
|
|
310
|
+
'dependency-research',
|
|
311
|
+
'docs-framework',
|
|
312
|
+
'git',
|
|
313
|
+
'quality-gates',
|
|
314
|
+
'research-codebase',
|
|
315
|
+
'research-competitor',
|
|
316
|
+
'research-external',
|
|
317
|
+
'research-market',
|
|
318
|
+
'research-technology',
|
|
319
|
+
'software-design',
|
|
320
|
+
'test-driven-development',
|
|
321
|
+
],
|
|
151
322
|
rules: [],
|
|
152
323
|
},
|
|
153
324
|
{
|
|
@@ -157,6 +328,31 @@ export const DEVFLOW_PLUGINS = [
|
|
|
157
328
|
commands: ['/dynamic-tickets', '/dynamic-plan', '/dynamic-build', '/dynamic-profile'],
|
|
158
329
|
agents: ['code', 'validate', 'simplify', 'scrutinize', 'evaluate', 'test', 'review', 'git', 'synthesize', 'knowledge', 'design'],
|
|
159
330
|
skills: ['apply-decisions', 'apply-feature-knowledge', 'worktree-support', 'docs-framework'],
|
|
331
|
+
requires: [
|
|
332
|
+
'architecture',
|
|
333
|
+
'boundary-validation',
|
|
334
|
+
'complexity',
|
|
335
|
+
'consistency',
|
|
336
|
+
'database',
|
|
337
|
+
'dependencies',
|
|
338
|
+
'dependency-research',
|
|
339
|
+
'design-review',
|
|
340
|
+
'documentation',
|
|
341
|
+
'feature-knowledge',
|
|
342
|
+
'gap-analysis',
|
|
343
|
+
'git',
|
|
344
|
+
'patterns',
|
|
345
|
+
'performance',
|
|
346
|
+
'qa',
|
|
347
|
+
'quality-gates',
|
|
348
|
+
'regression',
|
|
349
|
+
'reliability',
|
|
350
|
+
'review-methodology',
|
|
351
|
+
'security',
|
|
352
|
+
'software-design',
|
|
353
|
+
'test-driven-development',
|
|
354
|
+
'testing',
|
|
355
|
+
],
|
|
160
356
|
optional: true,
|
|
161
357
|
rules: [],
|
|
162
358
|
},
|
|
@@ -166,6 +362,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
166
362
|
commands: [],
|
|
167
363
|
agents: [],
|
|
168
364
|
skills: ['typescript'],
|
|
365
|
+
requires: [],
|
|
169
366
|
optional: true,
|
|
170
367
|
rules: ['typescript'],
|
|
171
368
|
},
|
|
@@ -175,6 +372,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
175
372
|
commands: [],
|
|
176
373
|
agents: [],
|
|
177
374
|
skills: ['react'],
|
|
375
|
+
requires: [],
|
|
178
376
|
optional: true,
|
|
179
377
|
rules: ['react'],
|
|
180
378
|
},
|
|
@@ -184,6 +382,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
184
382
|
commands: [],
|
|
185
383
|
agents: [],
|
|
186
384
|
skills: ['accessibility'],
|
|
385
|
+
requires: [],
|
|
187
386
|
optional: true,
|
|
188
387
|
rules: ['accessibility'],
|
|
189
388
|
},
|
|
@@ -193,6 +392,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
193
392
|
commands: [],
|
|
194
393
|
agents: [],
|
|
195
394
|
skills: ['ui-design'],
|
|
395
|
+
requires: [],
|
|
196
396
|
optional: true,
|
|
197
397
|
rules: ['ui-design'],
|
|
198
398
|
},
|
|
@@ -202,6 +402,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
202
402
|
commands: [],
|
|
203
403
|
agents: [],
|
|
204
404
|
skills: ['go'],
|
|
405
|
+
requires: [],
|
|
205
406
|
optional: true,
|
|
206
407
|
rules: ['go'],
|
|
207
408
|
},
|
|
@@ -211,6 +412,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
211
412
|
commands: [],
|
|
212
413
|
agents: [],
|
|
213
414
|
skills: ['java'],
|
|
415
|
+
requires: [],
|
|
214
416
|
optional: true,
|
|
215
417
|
rules: ['java'],
|
|
216
418
|
},
|
|
@@ -220,6 +422,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
220
422
|
commands: [],
|
|
221
423
|
agents: [],
|
|
222
424
|
skills: ['python'],
|
|
425
|
+
requires: [],
|
|
223
426
|
optional: true,
|
|
224
427
|
rules: ['python'],
|
|
225
428
|
},
|
|
@@ -229,6 +432,7 @@ export const DEVFLOW_PLUGINS = [
|
|
|
229
432
|
commands: [],
|
|
230
433
|
agents: [],
|
|
231
434
|
skills: ['rust'],
|
|
435
|
+
requires: [],
|
|
232
436
|
optional: true,
|
|
233
437
|
rules: ['rust'],
|
|
234
438
|
},
|
|
@@ -280,6 +484,59 @@ export const FEATURE_OWNED_SKILLS = ['compliance'];
|
|
|
280
484
|
* (guarded by plugins.test.ts FEATURE_OWNED constants describe block).
|
|
281
485
|
*/
|
|
282
486
|
export const FEATURE_OWNED_RULES = ['compliance'];
|
|
487
|
+
// ── Skill-closure boundaries ──────────────────────────────────────────────────
|
|
488
|
+
/**
|
|
489
|
+
* Skills that are REFERENCED but never REQUIRED — the presence-gated set.
|
|
490
|
+
*
|
|
491
|
+
* D-PRESENCE-GATED: every language/ecosystem skill ships with an optional,
|
|
492
|
+
* command-less plugin, so a reference to one is a reference to something the
|
|
493
|
+
* user may deliberately not have. The referencing prompts are written to probe
|
|
494
|
+
* first and proceed without it — `/code-review` checks
|
|
495
|
+
* `~/.claude/skills/devflow:{focus}/SKILL.md` before spawning that focus, the
|
|
496
|
+
* Review and Code agents continue when the Skill invocation fails. Putting them
|
|
497
|
+
* in a `requires` would reinstate the universal install for exactly the eight
|
|
498
|
+
* skills the selection prompt exists to let a user decline (AC-25).
|
|
499
|
+
*
|
|
500
|
+
* DERIVED from the registry rather than hand-listed: a ninth language plugin is
|
|
501
|
+
* presence-gated by being declared, with no second roster to remember. Guarded
|
|
502
|
+
* against its own definition in tests/guards/requires-closure.test.ts.
|
|
503
|
+
*/
|
|
504
|
+
export const PRESENCE_GATED_SKILLS = [
|
|
505
|
+
...new Set(DEVFLOW_PLUGINS
|
|
506
|
+
.filter(plugin => plugin.optional === true && plugin.commands.length === 0)
|
|
507
|
+
.flatMap(plugin => plugin.skills)),
|
|
508
|
+
];
|
|
509
|
+
/**
|
|
510
|
+
* The classified exception to the closure guard — declared HERE, at the
|
|
511
|
+
* declaration site of the field it exempts, and imported by the guard.
|
|
512
|
+
*
|
|
513
|
+
* D-TEMPLATE-EXCEPTION (applies PF-067: one authority for a prohibition and its
|
|
514
|
+
* exemptions). Every other templated reference in the corpus carries a literal
|
|
515
|
+
* prefix and resolves through it — `devflow:research-{RESEARCH_TYPE}` resolves
|
|
516
|
+
* because five in-scope skills start with `research-`. The Review focus skill is
|
|
517
|
+
* the one reference with NO literal prefix: the whole skill name is substituted
|
|
518
|
+
* at spawn time, and the substitution set spans the presence-gated language
|
|
519
|
+
* skills, so there is nothing a scan or a `requires` entry could resolve it to.
|
|
520
|
+
*
|
|
521
|
+
* Two spellings, one exception: the command writes the placeholder it passes and
|
|
522
|
+
* the agent writes the placeholder it receives.
|
|
523
|
+
*
|
|
524
|
+
* An entry here is NOT permission to stop thinking about the reference — the
|
|
525
|
+
* guard asserts each literal still occurs in the corpus, so an exemption that
|
|
526
|
+
* outlives its site fails rather than rotting.
|
|
527
|
+
*/
|
|
528
|
+
export const TEMPLATE_SKILL_REFS = [
|
|
529
|
+
{
|
|
530
|
+
literal: 'devflow:{focus}',
|
|
531
|
+
site: 'dist/commands/code-review.md (Review agent spawn prompt)',
|
|
532
|
+
why: 'the whole skill name is substituted per focus; the substitution set includes presence-gated language skills',
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
literal: 'devflow:{FOCUS}',
|
|
536
|
+
site: 'src/assets/agents/review.md (the Review agent loading its own focus skill)',
|
|
537
|
+
why: 'receiving half of the same substitution — the agent is told which focus it is, not which skill exists',
|
|
538
|
+
},
|
|
539
|
+
];
|
|
283
540
|
// ── Feature redirect ──────────────────────────────────────────────────────────
|
|
284
541
|
/**
|
|
285
542
|
* Plugin names (and aliases) that have been converted to built-in features.
|
|
@@ -405,21 +662,112 @@ export function buildAssetMaps(plugins) {
|
|
|
405
662
|
return { skillsMap, agentsMap };
|
|
406
663
|
}
|
|
407
664
|
/**
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
665
|
+
* The install closure of a plugin selection: everything those plugins own plus
|
|
666
|
+
* everything they use.
|
|
667
|
+
*
|
|
668
|
+
* ONE spelling of `skills ∪ requires`, because every consumer that spells it
|
|
669
|
+
* inline is a place the two halves can be forgotten apart: the installer's
|
|
670
|
+
* install set, its removal set, the skills-list scope and the closure guard all
|
|
671
|
+
* read this. Pure, order-independent, no I/O.
|
|
411
672
|
*/
|
|
412
|
-
export function
|
|
673
|
+
export function skillsOf(plugins) {
|
|
674
|
+
const skills = new Set();
|
|
675
|
+
for (const plugin of plugins) {
|
|
676
|
+
for (const skill of plugin.skills)
|
|
677
|
+
skills.add(skill);
|
|
678
|
+
for (const skill of plugin.requires)
|
|
679
|
+
skills.add(skill);
|
|
680
|
+
}
|
|
681
|
+
return skills;
|
|
682
|
+
}
|
|
683
|
+
/**
|
|
684
|
+
* Every plugin that OWNS a skill, in registry order.
|
|
685
|
+
*
|
|
686
|
+
* D-ALL-OWNERS: returns all declarers, not the first — `devflow skills list`'s
|
|
687
|
+
* owner column becomes a lie the moment install is scoped, because the answer a
|
|
688
|
+
* user needs from it is "which plugin do I select to keep this?", and a
|
|
689
|
+
* first-wins answer names one plugin out of several that would each do. Empty
|
|
690
|
+
* for a skill no plugin owns, which for a registry-valid name cannot happen:
|
|
691
|
+
* a `requires` entry is guarded to be a known skill, and a known skill is one
|
|
692
|
+
* some plugin declares.
|
|
693
|
+
*/
|
|
694
|
+
export function skillOwners(name) {
|
|
695
|
+
return DEVFLOW_PLUGINS.filter(plugin => plugin.skills.includes(name)).map(plugin => plugin.name);
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Build the skill → source-plugin map for a SELECTION.
|
|
699
|
+
*
|
|
700
|
+
* The key set is the selection's closure ({@link skillsOf}); the value is the
|
|
701
|
+
* plugin the skill is copied on behalf of. A skill the selection only REQUIRES
|
|
702
|
+
* has no owner among the selected plugins, so its owner is resolved from the
|
|
703
|
+
* full registry ({@link skillOwners}) — the map's value is a provenance label,
|
|
704
|
+
* and labelling a required skill with the plugin that happens to need it would
|
|
705
|
+
* misattribute ownership.
|
|
706
|
+
*/
|
|
707
|
+
export function buildScopedSkillsMap(plugins) {
|
|
413
708
|
const skillsMap = new Map();
|
|
414
|
-
for (const plugin of
|
|
709
|
+
for (const plugin of plugins) {
|
|
415
710
|
for (const skill of plugin.skills) {
|
|
416
|
-
if (!skillsMap.has(skill))
|
|
711
|
+
if (!skillsMap.has(skill))
|
|
417
712
|
skillsMap.set(skill, plugin.name);
|
|
418
|
-
}
|
|
419
713
|
}
|
|
420
714
|
}
|
|
715
|
+
for (const skill of skillsOf(plugins)) {
|
|
716
|
+
if (skillsMap.has(skill))
|
|
717
|
+
continue;
|
|
718
|
+
const owner = skillOwners(skill)[0];
|
|
719
|
+
if (owner !== undefined)
|
|
720
|
+
skillsMap.set(skill, owner);
|
|
721
|
+
}
|
|
421
722
|
return skillsMap;
|
|
422
723
|
}
|
|
724
|
+
/**
|
|
725
|
+
* Build a skills map over the WHOLE registry.
|
|
726
|
+
*
|
|
727
|
+
* The scoped map applied to every plugin: `skills ∪ requires` across the full
|
|
728
|
+
* registry is `skills` across the full registry, since a `requires` entry is
|
|
729
|
+
* always some plugin's owned skill. Retained for the consumers that legitimately
|
|
730
|
+
* want every skill regardless of selection — uninstall's removal manifest and
|
|
731
|
+
* `devflow skills list`'s catalogue.
|
|
732
|
+
*/
|
|
733
|
+
export function buildFullSkillsMap() {
|
|
734
|
+
return buildScopedSkillsMap(DEVFLOW_PLUGINS);
|
|
735
|
+
}
|
|
736
|
+
/**
|
|
737
|
+
* Decide the skill install/remove/dormant sets for one run — pure, no fs.
|
|
738
|
+
*
|
|
739
|
+
* H4: extracted so the decision is unit-testable without a temp tree, and so
|
|
740
|
+
* `installViaFileCopy` consumes a decision rather than growing a fourth set of
|
|
741
|
+
* inline set-arithmetic.
|
|
742
|
+
*
|
|
743
|
+
* The removal set is GATED on a full install. A `--plugin=X` run is a request to
|
|
744
|
+
* add X, not a statement that X is the whole selection, so it may never remove
|
|
745
|
+
* what another plugin contributed (AC-22). {@link FEATURE_OWNED_SKILLS} is
|
|
746
|
+
* subtracted unconditionally: those install and uninstall with their feature,
|
|
747
|
+
* and sweeping them here would delete an artifact this code does not own
|
|
748
|
+
* (applies ADR-024).
|
|
749
|
+
*
|
|
750
|
+
* A shadow is NEVER removed, whatever the selection — `~/.devflow/skills/` is
|
|
751
|
+
* user content. One that falls outside the install set simply applies to
|
|
752
|
+
* nothing, and is reported so the user can tell "inert" from "ignored".
|
|
753
|
+
*/
|
|
754
|
+
export function resolveSkillInstallPlan(input) {
|
|
755
|
+
const install = skillsOf(input.effectivePlugins);
|
|
756
|
+
const remove = new Set();
|
|
757
|
+
if (!input.isPartialInstall) {
|
|
758
|
+
for (const skill of skillsOf(DEVFLOW_PLUGINS)) {
|
|
759
|
+
if (install.has(skill))
|
|
760
|
+
continue;
|
|
761
|
+
if (FEATURE_OWNED_SKILLS.includes(skill))
|
|
762
|
+
continue;
|
|
763
|
+
remove.add(skill);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
const dormantShadows = [...new Set(input.shadowedSkills)]
|
|
767
|
+
.filter(skill => !install.has(skill))
|
|
768
|
+
.sort();
|
|
769
|
+
return { install, remove, dormantShadows };
|
|
770
|
+
}
|
|
423
771
|
/**
|
|
424
772
|
* Derive unique rule names from all plugins.
|
|
425
773
|
*/
|
|
@@ -35,7 +35,7 @@ export function getDocsDir(projectRoot) {
|
|
|
35
35
|
// ---------------------------------------------------------------------------
|
|
36
36
|
// Feature config (neutral .devflow root — not inside learning/)
|
|
37
37
|
// ---------------------------------------------------------------------------
|
|
38
|
-
/** .devflow/config.json —
|
|
38
|
+
/** .devflow/config.json — per-repo facts {reviewPublication, tracker override} */
|
|
39
39
|
export function getFeatureConfigPath(projectRoot) {
|
|
40
40
|
return path.join(projectRoot, '.devflow', 'config.json');
|
|
41
41
|
}
|
package/dist/core/proxy-log.js
CHANGED
|
@@ -28,12 +28,14 @@ export const PROXY_LOG_TAIL_BYTES = 1_048_576;
|
|
|
28
28
|
* Call sites compose on top of this result to add process-specific vars
|
|
29
29
|
* (e.g. SUBSWITCH_CONFIG for the relay spawn and doctor spawn).
|
|
30
30
|
*
|
|
31
|
-
* applies ADR-003: the prior denylist rationale is gone — the
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
31
|
+
* applies ADR-003: the prior denylist rationale is gone — on the paths devflow
|
|
32
|
+
* invokes (serve, doctor, models) the routing runtime reads ANTHROPIC_API_KEY,
|
|
33
|
+
* FORCE_COLOR, NO_COLOR (dist/tty.js, presence semantics), SUBSWITCH_CONFIG and
|
|
34
|
+
* XDG_CONFIG_HOME (user-config lookup, reached only on an implicit config load —
|
|
35
|
+
* see D-EFR-6 in model-discovery.ts). CI is read only by `init`; CODEX_HOME and
|
|
36
|
+
* CLAUDE_CONFIG_DIR only by the Codex ingress, `init` and the Codex doctor, none of
|
|
37
|
+
* which devflow enables or invokes. Verified by whole-dist grep of the 0.5.0
|
|
38
|
+
* package. An allowlist is the correct shape: 61 inherited vars → 6.
|
|
37
39
|
*
|
|
38
40
|
* HOME is retained: the runtime's loadConfig resolves ~ paths via homedir().
|
|
39
41
|
*
|
package/dist/core/proxy-state.js
CHANGED
|
@@ -88,14 +88,17 @@ export async function writeProxyState(devflowDir, state) {
|
|
|
88
88
|
// Pure helpers
|
|
89
89
|
// ---------------------------------------------------------------------------
|
|
90
90
|
/**
|
|
91
|
-
*
|
|
92
|
-
*
|
|
91
|
+
* Top-level keys devflow carries into the routing config. Unknown top-level keys
|
|
92
|
+
* cause a hard relay startup error — never emit them.
|
|
93
93
|
*
|
|
94
|
-
* @D-EFR-4 Subswitch 0.
|
|
95
|
-
* FileConfigSchema is a z.strictObject with exactly
|
|
96
|
-
* port, logLevel, anthropic, providers, limits. Unknown keys cause a
|
|
97
|
-
* error — the relay refuses to start. anthropic and limits are
|
|
98
|
-
* strictObject + prefault({}), so they may be partially specified.
|
|
94
|
+
* @D-EFR-4 Subswitch 0.5.0 routing config contract:
|
|
95
|
+
* FileConfigSchema is a z.strictObject with exactly 6 accepted top-level keys:
|
|
96
|
+
* port, logLevel, anthropic, providers, limits, codexIngress. Unknown keys cause a
|
|
97
|
+
* hard startup error — the relay refuses to start. anthropic and limits are
|
|
98
|
+
* themselves strictObject + prefault({}), so they may be partially specified.
|
|
99
|
+
* codexIngress is accepted by the relay but deliberately NOT carried: devflow's
|
|
100
|
+
* relay serves Claude Code only, and the ingress block would make it accept native
|
|
101
|
+
* Codex traffic and hold Claude credentials on devflow's behalf.
|
|
99
102
|
*/
|
|
100
103
|
const ROUTING_CONFIG_ALLOWED_TOP_KEYS = new Set([
|
|
101
104
|
'port', 'logLevel', 'anthropic', 'providers', 'limits',
|
|
@@ -163,7 +166,7 @@ export function buildRoutingConfigJson(port, existingContent) {
|
|
|
163
166
|
const parsed = JSON.parse(existingContent);
|
|
164
167
|
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
165
168
|
for (const [k, v] of Object.entries(parsed)) {
|
|
166
|
-
// Only preserve the
|
|
169
|
+
// Only preserve the carried top-level keys; port is always ours.
|
|
167
170
|
if (ROUTING_CONFIG_ALLOWED_TOP_KEYS.has(k) && k !== 'port') {
|
|
168
171
|
preserved[k] = v;
|
|
169
172
|
}
|