duaer-spec 0.16.0 → 0.17.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 (102) hide show
  1. package/.duaer/active-job.json +4 -4
  2. package/.duaer/specs/061-satisfactory-delivery/delivery.json +10 -0
  3. package/.duaer/specs/061-satisfactory-delivery/spec.md +39 -0
  4. package/.duaer/specs/061-satisfactory-delivery/tasks.md +5 -0
  5. package/.duaer/specs/062-deepseek-cli/delivery.json +10 -0
  6. package/.duaer/specs/062-deepseek-cli/spec.md +37 -0
  7. package/.duaer/specs/062-deepseek-cli/tasks.md +4 -0
  8. package/.duaer/specs/063-queued-count/delivery.json +10 -0
  9. package/.duaer/specs/063-queued-count/spec.md +12 -0
  10. package/.duaer/specs/063-queued-count/tasks.md +3 -0
  11. package/.duaer/specs/064-cli-install-show/delivery.json +10 -0
  12. package/.duaer/specs/064-cli-install-show/spec.md +17 -0
  13. package/.duaer/specs/064-cli-install-show/tasks.md +3 -0
  14. package/.duaer/specs/065-detailed-progress/delivery.json +18 -0
  15. package/.duaer/specs/065-detailed-progress/spec.md +19 -0
  16. package/.duaer/specs/065-detailed-progress/tasks.md +4 -0
  17. package/.duaer/specs/066-duaer-fed/delivery.json +16 -0
  18. package/.duaer/specs/066-duaer-fed/spec.md +18 -0
  19. package/.duaer/specs/066-duaer-fed/tasks.md +4 -0
  20. package/.duaer/specs/067-duaer-spec-fed/delivery.json +11 -0
  21. package/.duaer/specs/067-duaer-spec-fed/spec.md +16 -0
  22. package/.duaer/specs/067-duaer-spec-fed/tasks.md +3 -0
  23. package/.duaer/specs/068-fed-ux-polish/delivery.json +11 -0
  24. package/.duaer/specs/068-fed-ux-polish/spec.md +18 -0
  25. package/.duaer/specs/068-fed-ux-polish/tasks.md +4 -0
  26. package/.duaer/specs/069-history-btn-size/delivery.json +6 -0
  27. package/.duaer/specs/069-history-btn-size/spec.md +14 -0
  28. package/.duaer/specs/069-history-btn-size/tasks.md +3 -0
  29. package/.duaer/specs/070-validate-autofix-btn/delivery.json +9 -0
  30. package/.duaer/specs/070-validate-autofix-btn/spec.md +17 -0
  31. package/.duaer/specs/070-validate-autofix-btn/tasks.md +3 -0
  32. package/.duaer/specs/071-req-structured-display/delivery.json +9 -0
  33. package/.duaer/specs/071-req-structured-display/spec.md +17 -0
  34. package/.duaer/specs/071-req-structured-display/tasks.md +3 -0
  35. package/.duaer/specs/072-chat-send/delivery.json +14 -0
  36. package/.duaer/specs/072-chat-send/spec.md +48 -0
  37. package/.duaer/specs/072-chat-send/tasks.md +5 -0
  38. package/.duaer/specs/073-empty-structured/delivery.json +10 -0
  39. package/.duaer/specs/073-empty-structured/spec.md +28 -0
  40. package/.duaer/specs/073-empty-structured/tasks.md +4 -0
  41. package/.duaer/specs/074-chat-blank/delivery.json +10 -0
  42. package/.duaer/specs/074-chat-blank/spec.md +22 -0
  43. package/.duaer/specs/074-chat-blank/tasks.md +4 -0
  44. package/.duaer/specs/075-header-beginner/delivery.json +10 -0
  45. package/.duaer/specs/075-header-beginner/spec.md +17 -0
  46. package/.duaer/specs/075-header-beginner/tasks.md +4 -0
  47. package/.duaer/specs/076-click-options/delivery.json +10 -0
  48. package/.duaer/specs/076-click-options/spec.md +23 -0
  49. package/.duaer/specs/076-click-options/tasks.md +4 -0
  50. package/.duaer/specs/077-dispatch-unique/delivery.json +10 -0
  51. package/.duaer/specs/077-dispatch-unique/spec.md +18 -0
  52. package/.duaer/specs/077-dispatch-unique/tasks.md +4 -0
  53. package/.duaer/specs/078-chip-tone/delivery.json +10 -0
  54. package/.duaer/specs/078-chip-tone/spec.md +16 -0
  55. package/.duaer/specs/078-chip-tone/tasks.md +4 -0
  56. package/.duaer/specs/079-desk-equal-cols/delivery.json +10 -0
  57. package/.duaer/specs/079-desk-equal-cols/spec.md +17 -0
  58. package/.duaer/specs/079-desk-equal-cols/tasks.md +4 -0
  59. package/.duaer/specs/080-progress-polish/delivery.json +10 -0
  60. package/.duaer/specs/080-progress-polish/spec.md +18 -0
  61. package/.duaer/specs/080-progress-polish/tasks.md +4 -0
  62. package/.duaer/specs/081-beginner-copy/delivery.json +10 -0
  63. package/.duaer/specs/081-beginner-copy/spec.md +14 -0
  64. package/.duaer/specs/081-beginner-copy/tasks.md +4 -0
  65. package/.duaer/specs/082-git-cli-ensure/delivery.json +15 -0
  66. package/.duaer/specs/082-git-cli-ensure/spec.md +27 -0
  67. package/.duaer/specs/082-git-cli-ensure/tasks.md +5 -0
  68. package/.duaer/specs/083-deepseek-w-flag/delivery.json +14 -0
  69. package/.duaer/specs/083-deepseek-w-flag/spec.md +23 -0
  70. package/.duaer/specs/083-deepseek-w-flag/tasks.md +4 -0
  71. package/.duaer/specs/084-drop-deepseek-cli/delivery.json +14 -0
  72. package/.duaer/specs/084-drop-deepseek-cli/spec.md +25 -0
  73. package/.duaer/specs/084-drop-deepseek-cli/tasks.md +6 -0
  74. package/.duaer/specs/085-repo-mkdir/delivery.json +14 -0
  75. package/.duaer/specs/085-repo-mkdir/spec.md +26 -0
  76. package/.duaer/specs/085-repo-mkdir/tasks.md +5 -0
  77. package/.duaer/specs/086-claude-auto-perms/delivery.json +14 -0
  78. package/.duaer/specs/086-claude-auto-perms/spec.md +17 -0
  79. package/.duaer/specs/086-claude-auto-perms/tasks.md +4 -0
  80. package/.duaer/specs/087-release-017/spec.md +15 -0
  81. package/.duaer/specs/087-release-017/tasks.md +4 -0
  82. package/CHANGELOG.md +144 -0
  83. package/DUADER.md +11 -6
  84. package/README.md +21 -13
  85. package/README.zh-CN.md +10 -7
  86. package/bin/duaer-live.mjs +303 -90
  87. package/bin/duaer.mjs +1 -1
  88. package/bin/live-progress.mjs +189 -0
  89. package/bin/live-repo-path.mjs +88 -0
  90. package/bin/live-tooling.mjs +308 -0
  91. package/bin/live-worktree-name.mjs +57 -0
  92. package/docs/agent/README.md +2 -0
  93. package/docs/agent/e2e-test-plan.md +32 -2
  94. package/docs/agent/worker-models.md +75 -0
  95. package/docs/agent/worker-models.zh-CN.md +68 -0
  96. package/package.json +2 -2
  97. package/web/live-dev/app.js +395 -129
  98. package/web/live-dev/choice-options.mjs +59 -0
  99. package/web/live-dev/i18n.js +116 -40
  100. package/web/live-dev/index.html +50 -15
  101. package/web/live-dev/structured-html.mjs +121 -0
  102. package/web/live-dev/styles.css +546 -114
@@ -1,6 +1,6 @@
1
1
  {
2
- "featureDir": ".duaer/specs/060-release-016",
3
- "branch": "feat/release-016",
4
- "worktree": ".worktree/feat-release-016",
5
- "status": "accepted"
2
+ "featureDir": ".duaer/specs/087-release-017",
3
+ "slug": "087-release-017",
4
+ "branch": "chore/release-017",
5
+ "worktree": ".worktree/chore-release-017"
6
6
  }
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T01:00:00.000Z",
4
+ "summary": "Position norms → satisfactory delivery; stricter checkable acceptance gate for confirm/revise; docs and live hints updated.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": ["npm test"],
8
+ "result": "pass (18 tests)"
9
+ }
10
+ }
@@ -0,0 +1,39 @@
1
+ # Feature Specification: Spec AI for satisfactory delivery
2
+
3
+ **Feature Branch**: `feat/satisfactory-delivery`
4
+
5
+ **Created**: 2026-09-18
6
+
7
+ **Status**: Accepted
8
+
9
+ ## Goal
10
+
11
+ Position Duaer as **规范 AI → 满意交付**: acceptance must be objectively
12
+ checkable before confirm/revise dispatch, and public docs lead with that
13
+ promise—not phase/skill names.
14
+
15
+ ## In scope
16
+
17
+ - Stricter local + LLM validate gate for confirm and revise cards
18
+ - Positioning copy: README EN/ZH, package description, DUADER, live desk tag/hints
19
+ - Dispatch/revise agent prompts emphasize meeting Acceptance + openable preview
20
+ - Tests + CHANGELOG / E2E note
21
+
22
+ ## Out of scope
23
+
24
+ - npm release / promote to main (ship when asked)
25
+ - Layout redesign
26
+ - New columns or cloud hosting
27
+
28
+ ## Acceptance
29
+
30
+ 1. Vague acceptance (e.g.「更好用」/ “looks better”) fails `/api/validate` locally
31
+ 2. Checkable acceptance (open X / see Y / command passes) can still pass the gate
32
+ 3. README EN/ZH lead with 规范 → 满意交付 (English: norms → satisfactory delivery)
33
+ 4. `npm test` passes
34
+
35
+ ## Assumptions
36
+
37
+ - Worktree: `.worktree/feat-satisfactory-delivery`
38
+ - Brief: `.duaer/specs/061-satisfactory-delivery/`
39
+ - User confirmed evolution direction; no further intent wait
@@ -0,0 +1,5 @@
1
+ # Tasks: Spec AI for satisfactory delivery
2
+
3
+ - [x] Stricter acceptance gate (local heuristics + ACCEPT_PROMPT)
4
+ - [x] Positioning docs + live i18n hints
5
+ - [x] Agent prompts; tests; merge develop
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T01:20:00.000Z",
4
+ "summary": "Live desk launches DeepSeek TUI (deepseek) as a third CLI digital employee with PATH discovery for npm/nvm/cargo.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": ["npm test"],
8
+ "result": "pass (19 tests)"
9
+ }
10
+ }
@@ -0,0 +1,37 @@
1
+ # Feature Specification: DeepSeek CLI digital employee
2
+
3
+ **Feature Branch**: `feat/deepseek-cli`
4
+
5
+ **Created**: 2026-09-18
6
+
7
+ **Status**: Accepted
8
+
9
+ ## Goal
10
+
11
+ Live desk can launch **DeepSeek TUI** (`deepseek` / `deepseek-tui`) as a third
12
+ CLI digital employee alongside Cursor Agent and Claude Code.
13
+
14
+ ## In scope
15
+
16
+ - Detect `deepseek` on PATH (incl. npm global / nvm / cargo bins under launchd)
17
+ - Dispatch + revise Terminal launch with workspace, YOLO tools, optional `--continue`
18
+ - Preempt matching for deepseek processes; install hint `npm install -g deepseek-tui`
19
+ - README / i18n / tests
20
+
21
+ ## Out of scope
22
+
23
+ - Embedding DeepSeek API chat (already used for desk validate) as the worker
24
+ - Shipping npm release unless asked
25
+
26
+ ## Acceptance
27
+
28
+ 1. With `deepseek` installed, desk lists **DeepSeek** as available CLI
29
+ 2. Dispatch/revise enqueue a Terminal command using `deepseek -w <worktree> …`
30
+ 3. Without `deepseek`, missing list shows install command
31
+ 4. `npm test` passes
32
+
33
+ ## Assumptions
34
+
35
+ - Target CLI: DeepSeek-TUI entrypoint `deepseek` (`npm i -g deepseek-tui`)
36
+ - Worktree: `.worktree/feat-deepseek-cli`
37
+ - Brief: `.duaer/specs/062-deepseek-cli/`
@@ -0,0 +1,4 @@
1
+ # Tasks: DeepSeek CLI digital employee
2
+
3
+ - [x] Catalog + detect + PATH dirs; launch + preempt
4
+ - [x] Docs/i18n/tests; merge develop
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T01:50:00.000Z",
4
+ "summary": "Define queuedCount on fresh Terminal open path to stop ReferenceError.",
5
+ "verification": {
6
+ "levels": ["L0", "L1"],
7
+ "commands": ["npm test"],
8
+ "result": "pass"
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ # Feature Specification: Fix queuedCount ReferenceError
2
+
3
+ **Feature Branch**: `fix/queued-count`
4
+ **Brief**: `.duaer/specs/063-queued-count/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+ Fresh Terminal open path must not throw `queuedCount is not defined`.
9
+
10
+ ## Acceptance
11
+ 1. Unhealthy-runner launch return uses a defined queue depth
12
+ 2. `npm test` passes
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Define queuedCount on fresh Terminal open path
3
+ - [x] Test + merge develop
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T02:00:00.000Z",
4
+ "summary": "Missing CLI chips show install commands; install panel + redetect for PATH refresh.",
5
+ "verification": {
6
+ "levels": ["L0", "L1", "L3"],
7
+ "commands": ["npm test"],
8
+ "result": "pass (19 tests)"
9
+ }
10
+ }
@@ -0,0 +1,17 @@
1
+ # Feature Specification: Show CLI install commands when missing
2
+
3
+ **Feature Branch**: `feat/cli-install-show`
4
+ **Brief**: `.duaer/specs/064-cli-install-show/`
5
+ **Status**: Accepted
6
+
7
+ ## Goal
8
+
9
+ 「用哪个 CLI 数字员工启动」must detect install status; if not installed,
10
+ show the install command clearly (on the chip + install panel), with redetect.
11
+
12
+ ## Acceptance
13
+
14
+ 1. Missing CLIs render as distinct chips with install command text visible
15
+ 2. Install panel lists the selected missing CLI’s command + copy button
16
+ 3. Redetect button refreshes `/api/agents`
17
+ 4. `npm test` passes
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Missing chips show install cmd; panel + redetect
3
+ - [x] i18n/CSS/tests; merge develop
@@ -0,0 +1,18 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "featureDir": ".duaer/specs/065-detailed-progress",
5
+ "branch": "feat/detailed-progress",
6
+ "worktree": ".worktree/feat-detailed-progress",
7
+ "verification": {
8
+ "levels": ["L0", "L1", "L3"],
9
+ "commands": [
10
+ "node --check bin/duaer-live.mjs",
11
+ "node --check bin/live-progress.mjs",
12
+ "node --check web/live-dev/app.js",
13
+ "npm test",
14
+ "npm run test:live"
15
+ ],
16
+ "notes": "Richer default tasks.md, status.activity, progress-activity UI"
17
+ }
18
+ }
@@ -0,0 +1,19 @@
1
+ # Feature Specification: Detailed coding progress
2
+
3
+ **Feature Branch**: `feat/detailed-progress`
4
+ **Brief**: `.duaer/specs/065-detailed-progress/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Live desk progress shows more than 3 coarse tasks: a finer `tasks.md`
10
+ checklist on dispatch, stronger agent check-off rules, and live worktree
11
+ file activity while the CLI runs.
12
+
13
+ ## Acceptance
14
+
15
+ 1. New dispatch writes ≥6 checkbox tasks (not only T001–T003)
16
+ 2. `/api/status` includes `activity` (recent changed files / git porcelain)
17
+ 3. Progress column shows activity under the task list while work is running
18
+ 4. Agent launch prompt requires expanding/checking detailed tasks
19
+ 5. `npm test` passes
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+ - [x] Richer default tasks.md + agent prompt
3
+ - [x] worktree activity on status + UI
4
+ - [x] Tests/docs; merge develop
@@ -0,0 +1,16 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "featureDir": ".duaer/specs/066-duaer-fed",
5
+ "branch": "feat/duaer-fed",
6
+ "worktree": ".worktree/feat-duaer-fed",
7
+ "verification": {
8
+ "levels": ["L0", "L1", "L3"],
9
+ "commands": [
10
+ "node --check bin/duaer-live.mjs",
11
+ "node --check web/live-dev/i18n.js",
12
+ "npm test",
13
+ "npm run test:live"
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,18 @@
1
+ # Feature Specification: Brand live desk as Duaer FED
2
+
3
+ **Feature Branch**: `feat/duaer-fed`
4
+ **Brief**: `.duaer/specs/066-duaer-fed/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ User-facing name for the web confirm desk is **Duaer FED** (Field
10
+ Engineering Desk). Chinese keeps「现场开发」as the secondary mark.
11
+
12
+ ## Acceptance
13
+
14
+ 1. Desk header brand + document title show `Duaer FED`
15
+ 2. zh mark is「现场开发」; en mark is `Field Engineering Desk`
16
+ 3. README EN/ZH section titles use Duaer FED; CLI help / start banner say FED
17
+ 4. Agent/system prompts refer to Duaer FED (not only「现场开发」)
18
+ 5. `duaer live` command path unchanged; `npm test` + `npm run test:live` pass
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+ - [x] UI i18n + index title/brand
3
+ - [x] CLI banner, README, agent prompts
4
+ - [x] Tests/docs; merge develop
@@ -0,0 +1,11 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "featureDir": ".duaer/specs/067-duaer-spec-fed",
5
+ "branch": "feat/duaer-spec-fed",
6
+ "worktree": ".worktree/feat-duaer-spec-fed",
7
+ "verification": {
8
+ "levels": ["L0", "L1", "L3"],
9
+ "commands": ["npm test", "npm run test:live"]
10
+ }
11
+ }
@@ -0,0 +1,16 @@
1
+ # Feature Specification: Brand as Duaer-spec FED
2
+
3
+ **Feature Branch**: `feat/duaer-spec-fed`
4
+ **Brief**: `.duaer/specs/067-duaer-spec-fed/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Correct the live desk product name from `Duaer FED` to **Duaer-spec FED**
10
+ (tied to the duaer-spec product).
11
+
12
+ ## Acceptance
13
+
14
+ 1. Header, title, CLI banner/help, README, and agent prompts say `Duaer-spec FED`
15
+ 2. Secondary marks unchanged (zh on-site desk / en Field Engineering Desk)
16
+ 3. Brand tests updated; `npm test` + `npm run test:live` pass
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Rename Duaer FED → Duaer-spec FED across UI/docs/CLI
3
+ - [x] Update brand test; verify; merge develop
@@ -0,0 +1,11 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "featureDir": ".duaer/specs/068-fed-ux-polish",
5
+ "branch": "feat/fed-ux-polish",
6
+ "worktree": ".worktree/feat-fed-ux-polish",
7
+ "verification": {
8
+ "levels": ["L0", "L1", "L3"],
9
+ "commands": ["npm test", "npm run test:live"]
10
+ }
11
+ }
@@ -0,0 +1,18 @@
1
+ # Feature Specification: FED UX polish
2
+
3
+ **Feature Branch**: `feat/fed-ux-polish`
4
+ **Brief**: `.duaer/specs/068-fed-ux-polish/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Raise Duaer-spec FED visual and interaction quality: fix missing surface
10
+ styles, clearer hierarchy (brand / CTAs / empty states), without a layout
11
+ redesign or light-theme flip.
12
+
13
+ ## Acceptance
14
+
15
+ 1. History drawer and install/code chips have readable dark surfaces
16
+ 2. Brand shows `Duaer-spec` + accented `FED`; chat + progress have empty states
17
+ 3. Primary / confirm CTAs read as stronger go-actions; scrollbars + selection styled
18
+ 4. `npm test` + `npm run test:live` pass
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+ - [x] Surfaces, CTAs, brand, empty states (CSS/HTML/i18n)
3
+ - [x] Wire chat-empty hide on first bubble
4
+ - [x] Tests/docs; merge develop
@@ -0,0 +1,6 @@
1
+ {
2
+ "status": "accepted",
3
+ "featureDir": ".duaer/specs/069-history-btn-size",
4
+ "branch": "fix/history-btn-size",
5
+ "verification": { "levels": ["L1", "L3"], "commands": ["npm test", "npm run test:live"] }
6
+ }
@@ -0,0 +1,14 @@
1
+ # Feature Specification: Align history button size
2
+
3
+ **Feature Branch**: `fix/history-btn-size`
4
+ **Brief**: `.duaer/specs/069-history-btn-size/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Header **History** control matches the language `<select>` height and padding.
10
+
11
+ ## Acceptance
12
+
13
+ 1. History button and lang select share the same control height / type size
14
+ 2. `npm test` + `npm run test:live` pass
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Match history btn to lang select size
3
+ - [x] Verify; merge develop
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "featureDir": ".duaer/specs/070-validate-autofix-btn",
4
+ "branch": "feat/validate-autofix-btn",
5
+ "verification": {
6
+ "levels": ["L1", "L3"],
7
+ "commands": ["npm test", "npm run test:live"]
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ # Feature Specification: Auto-handle on validate fail
2
+
3
+ **Feature Branch**: `feat/validate-autofix-btn`
4
+ **Brief**: `.duaer/specs/070-validate-autofix-btn/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ When the confirm/revise card shows validation failed, offer an **自动处理**
10
+ button that runs auto-fix and reports progress in the chat column.
11
+
12
+ ## Acceptance
13
+
14
+ 1. Failed validate shows an **自动处理** button near the fail hint
15
+ 2. Click posts a chat bubble and calls `/api/validate/fix`, then updates the card
16
+ 3. Success unlocks confirm/revise dispatch without forcing silent lock; failure stays retryable in chat
17
+ 4. `npm test` + `npm run test:live` pass
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Auto-handle button + chat flow
3
+ - [x] Tests; merge develop
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "featureDir": ".duaer/specs/071-req-structured-display",
4
+ "branch": "feat/req-structured-display",
5
+ "verification": {
6
+ "levels": ["L1", "L3"],
7
+ "commands": ["npm test", "npm run test:live"]
8
+ }
9
+ }
@@ -0,0 +1,17 @@
1
+ # Feature Specification: Structured requirements display
2
+
3
+ **Feature Branch**: `feat/req-structured-display`
4
+ **Brief**: `.duaer/specs/071-req-structured-display/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Middle confirm/revise card fields show structured blocks (lists / items),
10
+ not one jammed paragraph when the model returns `;` / `;` / numbered clauses.
11
+
12
+ ## Acceptance
13
+
14
+ 1. Semicolon-joined acceptance renders as separate list items
15
+ 2. Inline `1、… 2、…` renders as an ordered list
16
+ 3. List items have clear visual separation (req-item)
17
+ 4. `npm test` + `npm run test:live` pass
@@ -0,0 +1,3 @@
1
+ # Tasks
2
+ - [x] Normalize + structuredHtml module + CSS
3
+ - [x] Tests; merge develop
@@ -0,0 +1,14 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": [
7
+ "node --check web/live-dev/app.js",
8
+ "npm test",
9
+ "npm run test:live"
10
+ ],
11
+ "result": "pass"
12
+ },
13
+ "summary": "Chat send no longer silent when locked; Enter-to-send; composer sync; locked card skips applyCard writes."
14
+ }
@@ -0,0 +1,48 @@
1
+ # Feature Specification: Chat send not silent / stuck
2
+
3
+ **Feature Branch**: `fix/chat-send`
4
+ **Brief**: `.duaer/specs/072-chat-send/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Live desk chat must always give clear feedback when send is blocked, keep the
10
+ Send control in sync with gate state, support Enter-to-send, and remain usable
11
+ after Confirm / History restore (conversation without silently mutating a
12
+ locked Brief).
13
+
14
+ ## Problem
15
+
16
+ Composer submit returns early when `locked` / `busy` / not ready with **no**
17
+ UI feedback; Send stays enabled while locked, so clicks look broken. Enter in
18
+ the textarea only inserts a newline. After Confirm or History restore, chat is
19
+ fully blocked even for clarifying dialogue.
20
+
21
+ ## In scope
22
+
23
+ - `chatAllowed` / block reasons surfaced in chat (not silent)
24
+ - `syncComposerEnabled` for Send (+ optional placeholder)
25
+ - Enter sends; Shift+Enter newline
26
+ - When specify card is locked: still allow chat; skip applying card field
27
+ updates from the model (direct user to Revise for Brief changes)
28
+ - Stuck `busy` recovery when user retries after a long wait
29
+
30
+ ## Out of scope
31
+
32
+ - Changing validate-before-confirm gate
33
+ - Revise dispatch / Terminal behavior
34
+
35
+ ## Acceptance
36
+
37
+ 1. Locked specify job: typing + Send (or Enter) posts a user bubble and gets a
38
+ reply (or a clear busy/not-ready message); locked card fields are not
39
+ overwritten by chat `goal`/`acceptance` patches
40
+ 2. While busy / not ready / revise-dispatching: Send is disabled or a bot bubble
41
+ explains why; no silent no-op
42
+ 3. Enter sends; Shift+Enter keeps newline
43
+ 4. `node --check web/live-dev/app.js`; `npm test`; `npm run test:live`
44
+
45
+ ## Assumptions
46
+
47
+ - Worktree: `.worktree/fix-chat-send` (not named `072-chat-send`)
48
+ - Hotfix: clear repro → implement after Brief without blocking confirm wait
@@ -0,0 +1,5 @@
1
+ # Tasks: Chat send
2
+
3
+ - [x] Composer gate: allow chat when locked; feedback + syncComposerEnabled + Enter
4
+ - [x] applyCard skips specify writes while locked; i18n + E2E + CHANGELOG
5
+ - [x] Verify L0/L1/L3; stamp delivery; merge develop; handoff
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": ["node --check web/live-dev/i18n.js", "npm test", "npm run test:live"],
7
+ "result": "pass"
8
+ },
9
+ "summary": "Chat empty hint is three numbered steps instead of one semicolon line."
10
+ }
@@ -0,0 +1,28 @@
1
+ # Feature Specification: Structured chat empty hint
2
+
3
+ **Feature Branch**: `feat/empty-structured`
4
+ **Brief**: `.duaer/specs/073-empty-structured/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Chat empty-state guidance (“用大白话说想要什么…”) shows as a **structured
10
+ step list**, not one jammed semicolon sentence.
11
+
12
+ ## In scope
13
+
14
+ - Empty hint as ordered / stepped blocks (zh + en)
15
+ - Styles matching desk (no cards clutter)
16
+ - Locale switch updates the steps
17
+
18
+ ## Out of scope
19
+
20
+ - Confirm-card structuredHtml changes
21
+ - Onboarding wizard beyond empty state
22
+
23
+ ## Acceptance
24
+
25
+ 1. Empty state shows discrete steps (plain words → confirm/dispatch → deliver
26
+ to acceptance), not a single `;`/`;` line
27
+ 2. Locale switch updates steps; first bubble still hides empty state
28
+ 3. `npm test` + `npm run test:live` pass
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+
3
+ - [x] HTML/CSS/i18n structured empty steps + sync on locale
4
+ - [x] E2E + CHANGELOG; verify L0/L1/L3; merge develop; handoff
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L1", "L3"],
6
+ "commands": ["node --check bin/duaer-live.mjs", "npm test", "npm run test:live"],
7
+ "result": "pass"
8
+ },
9
+ "summary": "Serve .mjs as text/javascript so structured-html module loads and desk chat UI runs."
10
+ }
@@ -0,0 +1,22 @@
1
+ # Feature Specification: Fix .mjs MIME so desk JS loads
2
+
3
+ **Feature Branch**: `fix/chat-blank`
4
+ **Brief**: `.duaer/specs/074-chat-blank/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ Live desk ES modules load in the browser. Chat / desk UI works again.
10
+
11
+ ## Problem
12
+
13
+ `web/live-dev/app.js` imports `structured-html.mjs`. Static serve mapped
14
+ unknown extensions to `application/octet-stream`. Browsers reject module
15
+ scripts with that MIME, so `app.js` never runs: desk stays hidden, chat
16
+ shows nothing after “send”.
17
+
18
+ ## Acceptance
19
+
20
+ 1. `GET /structured-html.mjs` returns `content-type: text/javascript`
21
+ 2. Headless load: desk unhides; send produces visible `.bubble` nodes
22
+ 3. `npm test` + `npm run test:live` pass
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+
3
+ - [x] Fix `contentType` for `.mjs`; add smoke assert
4
+ - [x] Restart live; verify browser load; merge develop
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T00:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L1", "L3"],
6
+ "commands": ["npm test", "npm run test:live"],
7
+ "result": "pass"
8
+ },
9
+ "summary": "Beginner slogan in header center; chat empty steps only."
10
+ }
@@ -0,0 +1,17 @@
1
+ # Feature Specification: Beginner line in header center
2
+
3
+ **Feature Branch**: `feat/header-beginner`
4
+ **Brief**: `.duaer/specs/075-header-beginner/`
5
+ **Status**: Active
6
+
7
+ ## Goal
8
+
9
+ 「小白也能用 FED」 lives in the **top nav center** (always visible). It no
10
+ longer sits in the chat empty state where it only flashes before the ready
11
+ bubble hides the empty block.
12
+
13
+ ## Acceptance
14
+
15
+ 1. Header center shows beginner line (zh + en); chat empty no longer uses that title
16
+ 2. Chat empty keeps the three how-to steps only (no flash of the beginner slogan)
17
+ 3. `npm test` + `npm run test:live` pass
@@ -0,0 +1,4 @@
1
+ # Tasks
2
+
3
+ - [x] Header center beginner copy; slim chat empty; CSS/i18n/E2E
4
+ - [x] Verify; merge develop; handoff