dflow-sdd-ddd 0.12.0 → 0.13.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 (38) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.en.md +83 -17
  3. package/README.md +39 -9
  4. package/TEMPLATE-COVERAGE.md +1 -0
  5. package/bin/dflow.js +58 -2
  6. package/docs/evaluating-dflow.en.md +21 -2
  7. package/docs/evaluating-dflow.md +17 -3
  8. package/docs/using-with-claude-code.en.md +23 -16
  9. package/docs/using-with-claude-code.md +20 -14
  10. package/docs/using-with-codex.en.md +15 -8
  11. package/docs/using-with-codex.md +10 -7
  12. package/docs/using-with-github-copilot.en.md +8 -3
  13. package/docs/using-with-github-copilot.md +6 -3
  14. package/lib/init.js +93 -8
  15. package/lib/render.js +1263 -0
  16. package/package.json +5 -2
  17. package/templates/brownfield/references/init-project-flow.md +43 -1
  18. package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +5 -0
  19. package/templates/brownfield/templates/_index.md +2 -0
  20. package/templates/brownfield/templates/context-definition.md +2 -0
  21. package/templates/brownfield/templates/context-map.md +1 -0
  22. package/templates/brownfield/templates/glossary.md +1 -0
  23. package/templates/brownfield/templates/models.md +1 -0
  24. package/templates/brownfield/templates/phase-spec.md +2 -0
  25. package/templates/brownfield/templates/rules.md +1 -0
  26. package/templates/brownfield/templates/tech-debt.md +1 -0
  27. package/templates/greenfield/references/init-project-flow.md +43 -1
  28. package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +5 -0
  29. package/templates/greenfield/templates/_index.md +2 -0
  30. package/templates/greenfield/templates/aggregate-design.md +2 -0
  31. package/templates/greenfield/templates/context-definition.md +2 -0
  32. package/templates/greenfield/templates/context-map.md +1 -0
  33. package/templates/greenfield/templates/events.md +1 -0
  34. package/templates/greenfield/templates/glossary.md +1 -0
  35. package/templates/greenfield/templates/models.md +1 -0
  36. package/templates/greenfield/templates/phase-spec.md +2 -0
  37. package/templates/greenfield/templates/rules.md +1 -0
  38. package/templates/greenfield/templates/tech-debt.md +1 -0
@@ -213,18 +213,23 @@ re-projects adapters from the **new registry**, but an existing
213
213
  adapters" is not the same as "migrating the canonical guide." Re-project with
214
214
  the **same dflow CLI version** to avoid a registry / guide version mismatch.
215
215
 
216
- ### Optional Skill Adapter (Restore Natural-Language Auto-Trigger)
216
+ ### Skill Adapter (Natural-Language Auto-Trigger, Installed by Default)
217
217
 
218
218
  Command adapters give you a `/` menu entry, but they **do not auto-trigger** —
219
- you have to invoke the command yourself. If you want to restore the "say 'I want
220
- to add a feature' and it shows up automatically" experience, run this in an
221
- initialized project:
219
+ you have to invoke the command yourself. Auto-trigger comes from the
220
+ project-level skill, and it now installs **by default**: `dflow init` installs
221
+ it when AI tools were selected (interactive runs ask one question — press Enter
222
+ to install; non-interactive runs never read an extra answer and install by
223
+ default), and `dflow configure-agents` asks the same question for newly
224
+ selected tools that have no skill yet. If you answered `n` back then, or want
225
+ to force-regenerate (for example to refresh after upgrading Dflow), run:
222
226
 
223
227
  ```bash
224
228
  dflow configure-agents --skills
225
229
  ```
226
230
 
227
- After you select Claude Code, Dflow generates a thin skill:
231
+ After you select Claude Code (in init or configure-agents), Dflow generates a
232
+ thin skill:
228
233
 
229
234
  - `.claude/skills/dflow/SKILL.md`
230
235
 
@@ -233,8 +238,8 @@ This skill does not copy workflow steps; its body points to the canonical
233
238
  `dflow/specs/shared/dflow-workflows/` (vendored bundle with executable step
234
239
  definitions).
235
240
 
236
- The same edition-neutral skill source is now also projected by `--skills` as a
237
- project-level skill for Codex (`.agents/skills/dflow/SKILL.md`) and GitHub Copilot
241
+ The same edition-neutral skill source is also projected as a project-level
242
+ skill for Codex (`.agents/skills/dflow/SKILL.md`) and GitHub Copilot
238
243
  (`.github/skills/dflow/SKILL.md`); all three follow the same cross-tool
239
244
  agentskills.io standard.
240
245
 
@@ -249,14 +254,14 @@ Its behavior:
249
254
  judges the intent, **suggests the matching `/dflow:` command, and waits for
250
255
  your confirmation** before proceeding.
251
256
 
252
- **The four combinations** (command adapters and the skill are each independently
253
- opt-in):
257
+ **The four combinations** (command adapters stay opt-in; the skill installs by
258
+ default — answer `n` at init to skip it, or delete it later):
254
259
 
255
260
  | Installed | Entry behavior |
256
261
  |---|---|
257
- | Neither | Root shim only (CLAUDE.md points to the guide); no `/` menu, no auto-trigger |
262
+ | Neither (skill skipped with `n`, no adapters) | Root shim only (CLAUDE.md points to the guide); no `/` menu, no auto-trigger |
258
263
  | Command adapters only | `/dflow:*` appears in the `/` menu; no natural-language auto-trigger |
259
- | Skill only | Natural-language auto-trigger (suggest-and-wait); no `/` menu |
264
+ | Skill only (init's default outcome) | Natural-language auto-trigger (suggest-and-wait); no `/` menu |
260
265
  | Both | `/` menu + natural-language safety net **may coexist** |
261
266
 
262
267
  **Both may coexist with no mutex needed** (validated in a real Claude Code
@@ -307,11 +312,13 @@ spec locations, or SDD constraints to `CLAUDE.md`, those belong in
307
312
  `dflow/specs/shared/AI-AGENT-GUIDE.md` instead. The shim stays small so
308
313
  that other tools' shims don't drift away from it.
309
314
 
310
- **`/dflow:*` is not a Claude Code Skill installation.** `init` does not
311
- install anything into Claude Code's skill system. Without command adapters,
312
- Dflow names are text triggers the AI recognizes from the workflow table. After
313
- you run `dflow configure-agents --command-adapters`, the added files are thin
314
- command wrappers, not a second workflow definition.
315
+ **The `/dflow:*` command names are not the skill.** `init` does install the
316
+ auto-trigger skill into Claude Code's skill system by default
317
+ (`.claude/skills/dflow/SKILL.md`; answer `n` at the skill question to skip),
318
+ but the `/dflow:*` **command names** themselves are not a skill. Without
319
+ command adapters, those names are text triggers the AI recognizes from the
320
+ workflow table. After you run `dflow configure-agents --command-adapters`, the
321
+ added files are thin command wrappers, not a second workflow definition.
315
322
 
316
323
  **Choose either legacy Claude skills or the installed adapter.** If the
317
324
  project still has legacy `.claude/skills/sdd-ddd-*` skills, choose either
@@ -187,16 +187,19 @@ git rm --cached -r .claude/commands/dflow/
187
187
  重投影;但既有 `dflow/specs/shared/AI-AGENT-GUIDE.md` **不會**被覆寫——「重投影 adapter」不等於
188
188
  「升級 canonical guide」。請以**相同的 dflow CLI 版本**重投影,避免 registry 與 guide 版本錯位。
189
189
 
190
- ### 選配 Skill Adapter(找回自然語言自動觸發)
190
+ ### Skill Adapter(自然語言自動觸發,init 預設安裝)
191
191
 
192
- Command adapter 提供 `/` 選單入口,但**不會自動觸發**——你得主動打命令。若想找回
193
- 「講『我要加一個功能』就自動現身」的體驗,可在已初始化的專案中執行:
192
+ Command adapter 提供 `/` 選單入口,但**不會自動觸發**——你得主動打命令。自動觸發
193
+ 來自 project-level skill,而它現在是**預設安裝**:`dflow init` 有選 AI 工具時就會裝
194
+ (互動模式問一題、直接按 Enter = 裝;非互動不多讀答案、直接預設裝),
195
+ `dflow configure-agents` 對「新選且尚無 skill」的工具也補問同一題。若當時答 `n`
196
+ 略過、或想強制重生成(例如升級 Dflow 後刷新),執行:
194
197
 
195
198
  ```bash
196
199
  dflow configure-agents --skills
197
200
  ```
198
201
 
199
- 選擇 Claude Code 後,Dflow 會產生一份薄 skill:
202
+ 選擇 Claude Code 後(init 或 configure-agents 皆同),Dflow 會產生一份薄 skill:
200
203
 
201
204
  - `.claude/skills/dflow/SKILL.md`
202
205
 
@@ -204,7 +207,7 @@ dflow configure-agents --skills
204
207
  `dflow/specs/shared/AI-AGENT-GUIDE.md`(命令登錄表與路由規則)以及
205
208
  `dflow/specs/shared/dflow-workflows/`(含可執行步驟定義的 vendored bundle)。
206
209
 
207
- 同一份 edition-neutral skill source,現在也會由 `--skills` 為 Codex
210
+ 同一份 edition-neutral skill source,也會為 Codex
208
211
  (`.agents/skills/dflow/SKILL.md`)與 GitHub Copilot(`.github/skills/dflow/SKILL.md`)
209
212
  投影 project-level skill,三家沿用相同的跨工具 agentskills.io 標準。
210
213
 
@@ -216,14 +219,15 @@ dflow configure-agents --skills
216
219
  - 由自然語言觸發時,**不會直接進 workflow**:它會判斷意圖、**建議對應的 `/dflow:`
217
220
  命令並等待你確認**,再進入流程。
218
221
 
219
- **四種組合**(command adapter 與 skill 各自獨立 opt-in):
222
+ **四種組合**(command adapter 維持 opt-in;skill 預設安裝,可在 init 答 `n`
223
+ 略過或事後刪除):
220
224
 
221
225
  | 安裝組合 | 入口行為 |
222
226
  |---|---|
223
- | 都不裝 | 只有根目錄 shim(CLAUDE.md 指向 guide);無 `/` 選單、無自動觸發 |
224
- | 只裝 command adapters | `/dflow:*` 出現在 `/` 選單;無自然語言自動觸發 |
225
- | 只裝 skill | 自然語言自動觸發(suggest-and-wait);無 `/` 選單 |
226
- | 兩者都裝 | `/` 選單 + 自然語言 safety net **可共存** |
227
+ | 都沒有(skill 題答 `n`、未裝 adapters) | 只有根目錄 shim(CLAUDE.md 指向 guide);無 `/` 選單、無自動觸發 |
228
+ | 只有 command adapters | `/dflow:*` 出現在 `/` 選單;無自然語言自動觸發 |
229
+ | 只有 skill(init 預設結果) | 自然語言自動觸發(suggest-and-wait);無 `/` 選單 |
230
+ | 兩者都有 | `/` 選單 + 自然語言 safety net **可共存** |
227
231
 
228
232
  **兩者可共存、無需互斥**(已在真實 Claude Code 環境驗證):skill 名稱 `dflow` 與
229
233
  command adapter 的 `dflow:<id>` 不撞名,明確命令各自精準載入、不會雙觸發;skill 當
@@ -266,10 +270,12 @@ SDD 約束加入 `CLAUDE.md`,這些內容應該放到
266
270
  `dflow/specs/shared/AI-AGENT-GUIDE.md`。shim 保持精簡,其他工具的 shim 才不會
267
271
  與它產生漂移(drift)。
268
272
 
269
- **`/dflow:*` 不是安裝 Claude Code Skill。** `init` 不會在 Claude Code 的
270
- skill 系統中安裝任何東西。未安裝 command adapters 時,Dflow 名稱只是 AI 從
271
- workflow 表識別的文字 trigger;安裝 `dflow configure-agents --command-adapters`
272
- 後,新增的是薄 command wrapper,不是 workflow 的第二份定義。
273
+ **`/dflow:*` 命令名不等於 skill。** init 預設會在 Claude Code 的 skill 系統
274
+ 裝一份自動觸發 skill(`.claude/skills/dflow/SKILL.md`,skill 題答 `n` 可略過),
275
+ 但 `/dflow:*` 這組**命令名**本身不是 skill——未安裝 command adapters 時,它們
276
+ 只是 AI 從 workflow 表識別的文字 trigger;安裝
277
+ `dflow configure-agents --command-adapters` 後,新增的是薄 command wrapper,
278
+ 不是 workflow 的第二份定義。
273
279
 
274
280
  **legacy Claude skill 與 installed adapter 擇一。** 如果專案仍保留舊的
275
281
  `.claude/skills/sdd-ddd-*` skill,請在 legacy skill 與 `--command-adapters`
@@ -179,8 +179,9 @@ triggers only. It does not create Codex command files. Codex v1 has no Dflow
179
179
  command-file adapter equivalent to Claude `.claude/commands` or Copilot
180
180
  `.github/prompts`.
181
181
 
182
- **Auto-trigger skills come from `--skills`, not `--command-adapters`.** See
183
- "Codex Behavior With Optional Skills" below.
182
+ **Auto-trigger skills come from the skill install (init's default, or
183
+ `--skills`), not `--command-adapters`.** See "Codex Behavior With Skills"
184
+ below.
184
185
 
185
186
  When you select `AGENTS.md - Codex / Copilot coding agent` in
186
187
  `--command-adapters` mode, Dflow writes a trigger list generated from the
@@ -219,10 +220,16 @@ Both snippets appear only on a marker conflict. A clean custom `AGENTS.md` with
219
220
  no conflicting markers does not produce a snippet at all — Dflow just appends the
220
221
  adjacent marked block in place.
221
222
 
222
- ### Codex Behavior With Optional Skills (Auto-Trigger)
223
+ ### Codex Behavior With Skills (Auto-Trigger, Installed by Default)
223
224
 
224
- `dflow configure-agents --skills` projects a thin, tool-neutral skill to
225
- `.agents/skills/dflow/SKILL.md` — Codex's project-level skill path. This gives
225
+ Dflow projects a thin, tool-neutral skill to
226
+ `.agents/skills/dflow/SKILL.md` — Codex's project-level skill path. The skill
227
+ now installs **by default**: `dflow init` installs it when Codex was selected
228
+ (interactive runs ask one default-yes question; non-interactive runs install
229
+ without reading extra stdin), and `dflow configure-agents` asks the same
230
+ question when Codex is newly selected without a skill;
231
+ `dflow configure-agents --skills` backfills a previously skipped skill or
232
+ force-regenerates it. This gives
226
233
  Codex **natural-language auto-trigger on par with Claude Code**: when you
227
234
  describe intent like "help me start a new feature", Codex can judge relevance
228
235
  from the skill's `description`, suggest the matching `dflow:<id>` workflow, and
@@ -320,9 +327,9 @@ workflow by reading `AI-AGENT-GUIDE.md`.
320
327
  Codex only strengthens text-trigger guidance in marked blocks inside
321
328
  `AGENTS.md`; fallback merge snippets are created only on marker conflicts. Do
322
329
  not expect Codex-specific **command** files under `.claude/commands` or
323
- `.github/prompts`. (Auto-trigger **skills** are separate: `--skills` projects
324
- one to `.agents/skills/dflow/SKILL.md`, see "Codex Behavior With Optional
325
- Skills" above.)
330
+ `.github/prompts`. (Auto-trigger **skills** are separate: init installs one to
331
+ `.agents/skills/dflow/SKILL.md` by default and `--skills` regenerates it, see
332
+ "Codex Behavior With Skills" above.)
326
333
 
327
334
  **Do not confuse Codex `/init` with Dflow `init`.** Codex `/init` creates a
328
335
  generic `AGENTS.md` scaffold for Codex. Dflow setup is `dflow init` (or
@@ -158,8 +158,8 @@ guide 中記為 `/dflow:*`)。
158
158
  Codex 命令檔。Codex v1 沒有與 Claude `.claude/commands` 或 Copilot `.github/prompts`
159
159
  對等的 Dflow command-file adapter。
160
160
 
161
- **自動觸發 skill 走的是 `--skills`(非 `--command-adapters`)。** 見下方
162
- 〈選配 Skill 的 Codex 行為〉。
161
+ **自動觸發 skill 走的是 skill 安裝(init 預設、或 `--skills`),非
162
+ `--command-adapters`。** 見下方〈Skill 的 Codex 行為〉。
163
163
 
164
164
  當你在 `--command-adapters` 模式下選擇 `AGENTS.md - Codex / Copilot coding agent`
165
165
  時,Dflow 會把從 canonical command registry 產生的 trigger 清單寫進 `AGENTS.md`。
@@ -189,10 +189,13 @@ marker」分成兩種小抄:
189
189
  兩種小抄都只在 marker conflict 時出現。乾淨、沒有 marker 衝突的自訂 `AGENTS.md` 不會
190
190
  產生任何小抄——Dflow 會直接把相鄰 marked block append 進去。
191
191
 
192
- ### 選配 Skill 的 Codex 行為(自動觸發)
192
+ ### Skill 的 Codex 行為(自動觸發,init 預設安裝)
193
193
 
194
- `dflow configure-agents --skills` 會把一份精簡、工具中立的 skill 投影到
195
- `.agents/skills/dflow/SKILL.md`——Codex 的專案層 skill 路徑。這讓 Codex 取得與
194
+ Dflow 會把一份精簡、工具中立的 skill 投影到
195
+ `.agents/skills/dflow/SKILL.md`——Codex 的專案層 skill 路徑。這份 skill 現在
196
+ **預設安裝**:`dflow init` 有選 Codex 就裝(互動問一題預設 Y、非互動直接裝)、
197
+ `dflow configure-agents` 對新選且尚無 skill 的 Codex 也補問;
198
+ `dflow configure-agents --skills` 用於補裝先前略過的、或強制重生成。這讓 Codex 取得與
196
199
  Claude Code **對等的自然語言自動觸發**:你用「help me start a new feature」這類描述
197
200
  時,Codex 可依該 skill 的 `description` 自動判斷是否相關,建議對應的 `dflow:<id>`
198
201
  workflow,而不必每次都記得手打命令。
@@ -272,8 +275,8 @@ canonical `/dflow:<id>` workflow。
272
275
  **Codex 不產生命令檔。** 即使使用 `--command-adapters`,Codex 也只強化
273
276
  `AGENTS.md` 中 marked block 的文字 trigger 說明;只有 marker conflict 才會產生
274
277
  fallback merge snippet。不要期待 `.claude/commands` 或 `.github/prompts` 形式的
275
- Codex 專屬**命令**檔。(自動觸發 **skill** 是另一回事,由 `--skills` 投影到
276
- `.agents/skills/dflow/SKILL.md`,見上方〈選配 Skill 的 Codex 行為〉。)
278
+ Codex 專屬**命令**檔。(自動觸發 **skill** 是另一回事,init 預設安裝、`--skills`
279
+ 可重生成,路徑 `.agents/skills/dflow/SKILL.md`,見上方〈Skill 的 Codex 行為〉。)
277
280
 
278
281
  **不要混淆 Codex `/init` 與 Dflow `init`。** Codex `/init` 為 Codex 建立
279
282
  通用的 `AGENTS.md` scaffold。Dflow 的設定是 `dflow init`(或免安裝路徑的
@@ -142,11 +142,16 @@ steps. Note the command syntax uses the **hyphen** `/dflow-<id>`, not the
142
142
  canonical **colon** `/dflow:<id>` — the colon form is Claude / Codex's command
143
143
  syntax and in Copilot can only be a text reference, never typed as a command.
144
144
 
145
- ### The `--skills` Flag and Skill Triggering on Copilot
145
+ ### Skill Triggering on Copilot (Installed by Default)
146
146
 
147
- `dflow configure-agents --skills` projects the same tool-neutral thin skill for
147
+ Dflow projects the same tool-neutral thin skill for
148
148
  **Claude Code, Codex, and GitHub Copilot**, each at its own project-level skill
149
- path; Copilot's is `.github/skills/dflow/SKILL.md`. Testing (2026-06-05) confirmed
149
+ path; Copilot's is `.github/skills/dflow/SKILL.md`. The skill now installs **by
150
+ default**: `dflow init` installs it when Copilot was selected (interactive runs
151
+ ask one default-yes question; non-interactive runs install without reading
152
+ extra stdin), `dflow configure-agents` asks the same question when Copilot is
153
+ newly selected without a skill, and `dflow configure-agents --skills` backfills
154
+ or force-regenerates it. Testing (2026-06-05) confirmed
150
155
  Copilot discovers and runs the skill from its own native `.github/skills/` path
151
156
  (it still works with the cross-read `.claude`/`.agents` paths removed); the
152
157
  trigger differs by surface — **VS Code Chat auto-triggers on natural language**,
@@ -137,11 +137,14 @@ dflow configure-agents --command-adapters
137
137
  **連字號** `/dflow-<id>`,不是 canonical 的**冒號** `/dflow:<id>`——後者是
138
138
  Claude / Codex 的命令寫法,在 Copilot 只能當文字稱呼、不能當命令輸入。
139
139
 
140
- ### `--skills` flag 與 Copilot 的 skill 觸發
140
+ ### Copilot 的 skill 觸發(init 預設安裝)
141
141
 
142
- `dflow configure-agents --skills` 會為 **Claude Code、Codex 與 GitHub Copilot**
142
+ Dflow 會為 **Claude Code、Codex 與 GitHub Copilot**
143
143
  各自投影同一份工具中立的 thin skill 到它們的 project-level skill 路徑;Copilot 的是
144
- `.github/skills/dflow/SKILL.md`。實測(2026-06-05)確認 Copilot 會從**自己原生的
144
+ `.github/skills/dflow/SKILL.md`。這份 skill 現在**預設安裝**:`dflow init` 有選
145
+ Copilot 就裝(互動問一題預設 Y、非互動直接裝)、`dflow configure-agents` 對新選且
146
+ 尚無 skill 的 Copilot 也補問;`dflow configure-agents --skills` 用於補裝或強制
147
+ 重生成。實測(2026-06-05)確認 Copilot 會從**自己原生的
145
148
  `.github/skills/`** 探索並運作(即使移除 `.claude`/`.agents` 的跨讀路徑也成立),
146
149
  觸發方式依介面而異——**VS Code Chat 自然語言自動觸發**、**Copilot CLI 需打 `/dflow`
147
150
  手動喚起**(細節見上方介面 A / B)。
package/lib/init.js CHANGED
@@ -250,6 +250,14 @@ async function runInit(options = {}) {
250
250
 
251
251
  const detection = await detectProjectSignals(cwd);
252
252
  const answers = await promptForAnswers(rl, stdout, stderr, detection);
253
+ // PROPOSAL-074: skill question sits after the AI-agents question and before the
254
+ // preview; asked only when a skill-capable agent was selected, and only on TTY.
255
+ answers.skills = await resolveSkillInstall(
256
+ rl,
257
+ stdout,
258
+ Boolean(stdin.isTTY && stdout.isTTY),
259
+ answers.aiAgents.some((agent) => SKILL_ADAPTER_TARGETS[agent])
260
+ );
253
261
  const plan = await buildFilePlan(cwd, answers);
254
262
  const warnings = [...preflight.warnings, ...buildDetectionWarnings(answers, detection), ...(plan.warnings || []), ...(plan.bundleWarnings || [])];
255
263
 
@@ -268,7 +276,7 @@ async function runInit(options = {}) {
268
276
  result.warnings.push(...collectUnresolvedPlaceholderWarnings(plan, result.created));
269
277
 
270
278
  printResultReport(stdout, result, plan.deferred);
271
- printNextSteps(stdout);
279
+ printNextSteps(stdout, answers.skills);
272
280
  return 0;
273
281
  } catch (error) {
274
282
  if (rl) {
@@ -331,11 +339,40 @@ async function runConfigureAgents(options = {}) {
331
339
  throw new UserAbort('No AI agents selected. Nothing changed.');
332
340
  }
333
341
 
342
+ // PROPOSAL-074 (OQ2 branch b): without --skills, a selected agent that has no
343
+ // project-level skill yet gets the same default-yes install contract as init
344
+ // (TTY asks, non-TTY installs without reading stdin). Agents whose skill file
345
+ // already exists — Dflow-generated or user-owned — never re-ask and are NOT
346
+ // regenerated (skillAgents carries only the missing ones); explicit --skills
347
+ // keeps its original regenerate-all meaning.
348
+ let skillAgents = [];
349
+ if (options.skills) {
350
+ skillAgents = aiAgents;
351
+ } else {
352
+ const missingSkillAgents = [];
353
+ for (const agent of aiAgents) {
354
+ const target = SKILL_ADAPTER_TARGETS[agent];
355
+ if (target && !(await pathExists(path.join(cwd, target.relativePath)))) {
356
+ missingSkillAgents.push(agent);
357
+ }
358
+ }
359
+ const install = await resolveSkillInstall(
360
+ rl,
361
+ stdout,
362
+ Boolean(stdin.isTTY && stdout.isTTY),
363
+ missingSkillAgents.length > 0
364
+ );
365
+ if (install) {
366
+ skillAgents = missingSkillAgents;
367
+ }
368
+ }
369
+
334
370
  const plan = await buildConfigureAgentsPlan(cwd, {
335
371
  ...projectContext,
336
372
  aiAgents,
337
373
  commandAdapters: Boolean(options.commandAdapters),
338
- skills: Boolean(options.skills)
374
+ skills: Boolean(options.skills),
375
+ skillAgents
339
376
  });
340
377
 
341
378
  const warnings = plan.warnings || [];
@@ -355,7 +392,7 @@ async function runConfigureAgents(options = {}) {
355
392
 
356
393
  printResultReport(stdout, result, plan.deferred);
357
394
  const usedSnippetFallback = plan.items.some((item) => item.snippetFallback);
358
- printConfigureAgentsNextSteps(stdout, Boolean(options.commandAdapters), usedSnippetFallback);
395
+ printConfigureAgentsNextSteps(stdout, Boolean(options.commandAdapters), usedSnippetFallback, skillAgents.length > 0);
359
396
  return 0;
360
397
  } catch (error) {
361
398
  if (rl) {
@@ -978,6 +1015,38 @@ async function askConfirmation(rl, prompt) {
978
1015
  return answer === 'y' || answer === 'yes';
979
1016
  }
980
1017
 
1018
+ // PROPOSAL-074: dedicated default-yes contract for the skill-install question.
1019
+ // askConfirmation treats blank as false (final-confirmation semantics), so reusing
1020
+ // it under a `(Y/n)` prompt would invert the advertised default.
1021
+ async function askYesNoDefaultYes(rl, prompt) {
1022
+ const answer = (await askLine(rl, prompt)).trim().toLowerCase();
1023
+ return answer === '' || answer === 'y' || answer === 'yes';
1024
+ }
1025
+
1026
+ // PROPOSAL-074: the project-level skill installs by default. Ask only on an
1027
+ // interactive terminal; a non-TTY run never consumes a stdin slot — existing piped
1028
+ // answer sequences end with the final confirmation `y`, and a new question before
1029
+ // it would swallow that `y` and turn the run into a silent no-op abort — so
1030
+ // non-TTY installs by default without reading stdin.
1031
+ async function resolveSkillInstall(rl, stdout, interactive, hasSkillTargets) {
1032
+ if (!hasSkillTargets) {
1033
+ return false;
1034
+ }
1035
+
1036
+ if (!interactive) {
1037
+ return true;
1038
+ }
1039
+
1040
+ const install = await askYesNoDefaultYes(
1041
+ rl,
1042
+ '\nInstall the project-level Dflow skill for natural-language auto-trigger? (Y/n) '
1043
+ );
1044
+ if (!install) {
1045
+ stdout.write('Skipped the project-level skill; add it later with `dflow configure-agents --skills`.\n');
1046
+ }
1047
+ return install;
1048
+ }
1049
+
981
1050
  function parseSelectAnswer(answer, options, defaultKey) {
982
1051
  const trimmed = answer.trim();
983
1052
  if (!trimmed && defaultKey) {
@@ -1124,6 +1193,11 @@ async function buildFilePlan(cwd, answers) {
1124
1193
 
1125
1194
  await finalizePlanItems(cwd, items);
1126
1195
 
1196
+ // PROPOSAL-074: init projects the project-level skill by default; answers.skills
1197
+ // carries the Q-flow / non-TTY resolution from runInit (absent = false, which
1198
+ // keeps buildFilePlan backward-compatible for direct callers).
1199
+ await addSkillAdapterItems(cwd, items, answers.aiAgents, answers.skills, warnings);
1200
+
1127
1201
  // Always project the workflow bundle (required for /dflow:* workflows to be reachable).
1128
1202
  const bundleWarnings = [];
1129
1203
  await addWorkflowBundleItems(cwd, items, bundleWarnings, answers.edition);
@@ -1172,7 +1246,11 @@ async function buildConfigureAgentsPlan(cwd, answers) {
1172
1246
  await addLegacyCommandAdapterCleanupItems(cwd, items, answers.aiAgents, warnings);
1173
1247
  }
1174
1248
 
1175
- await addSkillAdapterItems(cwd, items, answers.aiAgents, answers.skills, warnings);
1249
+ // PROPOSAL-074: skillAgents is the projection subset — all selected agents under
1250
+ // --skills, only the missing ones on a flagless default install (existing skills
1251
+ // are never regenerated without the flag).
1252
+ const skillAgents = answers.skillAgents || (answers.skills ? answers.aiAgents : []);
1253
+ await addSkillAdapterItems(cwd, items, skillAgents, skillAgents.length > 0, warnings);
1176
1254
 
1177
1255
  // Project the workflow bundle on configure-agents too, so pre-039 projects (no bundle)
1178
1256
  // and edition-switch repairs get the runtime references/templates reachable. The function
@@ -2991,7 +3069,12 @@ function printResultReport(stdout, result, deferred) {
2991
3069
  }
2992
3070
  }
2993
3071
 
2994
- function printNextSteps(stdout) {
3072
+ // PROPOSAL-074 / PROPOSAL-037: generated skill files are Dflow-managed derivatives;
3073
+ // the recommended default is gitignore + re-project after clone.
3074
+ const SKILL_VERSION_CONTROL_STEP = '- Project-level skill files (.claude/skills/, .agents/skills/, .github/skills/) are Dflow-managed derivatives: the recommended default is to gitignore them and re-run `dflow configure-agents --skills` after cloning; committing them also works if the team prefers.\n';
3075
+
3076
+ function printNextSteps(stdout, skillsInstalled = false) {
3077
+ const skillStep = skillsInstalled ? SKILL_VERSION_CONTROL_STEP : '';
2995
3078
  stdout.write(`
2996
3079
  Dflow init complete.
2997
3080
 
@@ -3000,10 +3083,10 @@ Recommended next steps:
3000
3083
  - For brownfield changes, use the Dflow modify-existing workflow when it becomes available as a CLI command.
3001
3084
  - Before generating more specs, make sure dflow/specs/shared/_conventions.md has the correct Prose Language section.
3002
3085
  - For stack-specific examples (.NET, Java/Spring, Node/TypeScript, Python, Go, PHP/Laravel), see docs/examples-by-stack.md in the Dflow repo.
3003
- `);
3086
+ ${skillStep}`);
3004
3087
  }
3005
3088
 
3006
- function printConfigureAgentsNextSteps(stdout, commandAdapters = false, snippetFallback = false) {
3089
+ function printConfigureAgentsNextSteps(stdout, commandAdapters = false, snippetFallback = false, skillsInstalled = false) {
3007
3090
  const commandAdapterStep = commandAdapters
3008
3091
  ? '- Command adapters use tool-specific invocation names: Claude Code `/dflow:<id>`; GitHub Copilot prompt menu `/dflow-<id>` or canonical `/dflow:<id>` as text; Codex CLI plain text without a slash, such as `dflow:status`. Canonical `/dflow:*` names remain defined in dflow/specs/shared/AI-AGENT-GUIDE.md. If upgrading from Dflow 0.5.0, stale `.claude/commands/dflow/dflow-*.md` files generated by 0.5.0 are detected and listed for removal in the confirmation preview, so Claude Code does not show both old and new command names; edited or non-Dflow files are kept with a warning.\n'
3009
3092
  : '';
@@ -3015,13 +3098,15 @@ function printConfigureAgentsNextSteps(stdout, commandAdapters = false, snippetF
3015
3098
  ? '- A merge snippet was written because an existing agent file had conflicting Dflow markers; review it, fix or remove the stray markers, then merge the Dflow block into that file (or re-run to let Dflow manage it).\n'
3016
3099
  : '';
3017
3100
 
3101
+ const skillStep = skillsInstalled ? SKILL_VERSION_CONTROL_STEP : '';
3102
+
3018
3103
  stdout.write(`
3019
3104
  Dflow AI agent configuration complete.
3020
3105
 
3021
3106
  Recommended next steps:
3022
3107
  - Keep AI-agent-specific root files small.
3023
3108
  - Put durable workflow changes in dflow/specs/shared/AI-AGENT-GUIDE.md.
3024
- ${snippetStep}${commandAdapterStep}`);
3109
+ ${snippetStep}${skillStep}${commandAdapterStep}`);
3025
3110
  }
3026
3111
 
3027
3112
  function printList(stdout, values) {