duaer-spec 0.27.1 → 0.27.3

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 (80) hide show
  1. package/.duaer/active-job.json +3 -3
  2. package/.duaer/specs/275-release-0271/delivery.json +9 -0
  3. package/.duaer/specs/275-release-0271/tasks.md +1 -1
  4. package/.duaer/specs/276-fde08-perf-budget/delivery.json +9 -0
  5. package/.duaer/specs/276-fde08-perf-budget/spec.md +38 -0
  6. package/.duaer/specs/276-fde08-perf-budget/tasks.md +5 -0
  7. package/.duaer/specs/277-project-dir-reuse/delivery.json +9 -0
  8. package/.duaer/specs/277-project-dir-reuse/spec.md +31 -0
  9. package/.duaer/specs/277-project-dir-reuse/tasks.md +5 -0
  10. package/.duaer/specs/278-project-create-unique/delivery.json +9 -0
  11. package/.duaer/specs/278-project-create-unique/spec.md +27 -0
  12. package/.duaer/specs/278-project-create-unique/tasks.md +5 -0
  13. package/.duaer/specs/279-arch-side-detour/delivery.json +8 -0
  14. package/.duaer/specs/279-arch-side-detour/spec.md +28 -0
  15. package/.duaer/specs/279-arch-side-detour/tasks.md +5 -0
  16. package/.duaer/specs/280-arch-bottom-via-label/delivery.json +8 -0
  17. package/.duaer/specs/280-arch-bottom-via-label/spec.md +22 -0
  18. package/.duaer/specs/280-arch-bottom-via-label/tasks.md +5 -0
  19. package/.duaer/specs/281-release-0272/delivery.json +8 -0
  20. package/.duaer/specs/281-release-0272/spec.md +13 -0
  21. package/.duaer/specs/281-release-0272/tasks.md +4 -0
  22. package/.duaer/specs/282-dispatch-confirm-lock/delivery.json +12 -0
  23. package/.duaer/specs/282-dispatch-confirm-lock/spec.md +26 -0
  24. package/.duaer/specs/282-dispatch-confirm-lock/tasks.md +5 -0
  25. package/.duaer/specs/283-desk-theme-compact/delivery.json +12 -0
  26. package/.duaer/specs/283-desk-theme-compact/spec.md +26 -0
  27. package/.duaer/specs/283-desk-theme-compact/tasks.md +5 -0
  28. package/.duaer/specs/284-dispatch-graph-regen/delivery.json +12 -0
  29. package/.duaer/specs/284-dispatch-graph-regen/spec.md +33 -0
  30. package/.duaer/specs/284-dispatch-graph-regen/tasks.md +5 -0
  31. package/.duaer/specs/285-desk-light-compact/delivery.json +11 -0
  32. package/.duaer/specs/285-desk-light-compact/spec.md +13 -0
  33. package/.duaer/specs/285-desk-light-compact/tasks.md +5 -0
  34. package/.duaer/specs/286-modules-bug-theme/delivery.json +10 -0
  35. package/.duaer/specs/286-modules-bug-theme/spec.md +26 -0
  36. package/.duaer/specs/286-modules-bug-theme/tasks.md +5 -0
  37. package/.duaer/specs/287-progress-modules-ux/delivery.json +10 -0
  38. package/.duaer/specs/287-progress-modules-ux/spec.md +31 -0
  39. package/.duaer/specs/287-progress-modules-ux/tasks.md +5 -0
  40. package/.duaer/specs/288-settings-close-compact/delivery.json +10 -0
  41. package/.duaer/specs/288-settings-close-compact/spec.md +17 -0
  42. package/.duaer/specs/288-settings-close-compact/tasks.md +5 -0
  43. package/.duaer/specs/289-settings-close-click/delivery.json +10 -0
  44. package/.duaer/specs/289-settings-close-click/spec.md +16 -0
  45. package/.duaer/specs/289-settings-close-click/tasks.md +4 -0
  46. package/.duaer/specs/290-remove-quicknav/delivery.json +10 -0
  47. package/.duaer/specs/290-remove-quicknav/spec.md +11 -0
  48. package/.duaer/specs/290-remove-quicknav/tasks.md +4 -0
  49. package/.duaer/specs/291-release-0273/spec.md +12 -0
  50. package/.duaer/specs/291-release-0273/tasks.md +4 -0
  51. package/CHANGELOG.md +90 -0
  52. package/bin/duaer-live.mjs +104 -39
  53. package/bin/live-archify.mjs +382 -26
  54. package/bin/live-deliverables.mjs +4 -0
  55. package/bin/live-modules.mjs +40 -3
  56. package/bin/live-project-chat.mjs +2 -0
  57. package/bin/live-repo-path.mjs +91 -2
  58. package/docs/agent/e2e-test-plan.md +20 -4
  59. package/docs/agent/live-desk.md +39 -14
  60. package/package.json +1 -1
  61. package/web/live-dev/app.js +357 -169
  62. package/web/live-dev/baseline.mjs +1 -0
  63. package/web/live-dev/confirm-card.mjs +1 -0
  64. package/web/live-dev/dispatch-center.html +29 -1
  65. package/web/live-dev/dispatch-center.js +25 -1
  66. package/web/live-dev/i18n-de.js +19 -8
  67. package/web/live-dev/i18n-es.js +19 -8
  68. package/web/live-dev/i18n-fr.js +19 -8
  69. package/web/live-dev/i18n-ja.js +19 -8
  70. package/web/live-dev/i18n-ko.js +19 -8
  71. package/web/live-dev/i18n-pt-BR.js +19 -8
  72. package/web/live-dev/i18n-ru.js +19 -8
  73. package/web/live-dev/i18n-vi.js +19 -8
  74. package/web/live-dev/i18n-zh-TW.js +19 -8
  75. package/web/live-dev/i18n.js +38 -16
  76. package/web/live-dev/index.html +43 -38
  77. package/web/live-dev/perf-budget.mjs +38 -0
  78. package/web/live-dev/styles.css +296 -315
  79. package/web/live-dev/task-graph.mjs +4 -1
  80. package/web/live-dev/theme.mjs +63 -0
@@ -1,5 +1,5 @@
1
1
  {
2
- "feature": "275-release-0271",
3
- "branch": "feat/release-0271",
4
- "worktree": ".worktree/feat-release-0271"
2
+ "feature": "291-release-0273",
3
+ "branch": "chore/release-0273",
4
+ "worktree": ".worktree/chore-release-0273"
5
5
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "0.27.1 is on main as v0.27.1, GitHub Release published, npm Trusted Publishing succeeded.",
4
+ "verification": {
5
+ "publish": "git push origin main develop v0.27.1 — fast-forward 1d6d164..26ede20",
6
+ "release": "https://github.com/Duaer/duaer-spec/releases/tag/v0.27.1",
7
+ "npm": "gh run 35558574069 success — + duaer-spec@0.27.1"
8
+ }
9
+ }
@@ -1,4 +1,4 @@
1
1
  # Tasks — 275-release-0271
2
2
 
3
3
  - [x] Bump 0.27.1 and move changelog notes
4
- - [ ] Tag v0.27.1 on main and publish the GitHub Release
4
+ - [x] Tag v0.27.1 on main and publish the GitHub Release
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Feature confirm requires LCP, INP, bundle size, virtualized long lists, a weak-network check, and a large-data check, or a no-page-performance opt-out. A vague speed line fails. Kickoff schedules the budget before implement.",
4
+ "verification": {
5
+ "L0": "node --check bin/duaer-live.mjs bin/live-modules.mjs web/live-dev/app.js web/live-dev/perf-budget.mjs — pass",
6
+ "L1": "npm test — 254 pass",
7
+ "L3": "npm run test:live — pass"
8
+ }
9
+ }
@@ -0,0 +1,38 @@
1
+ # Feature Specification: FDE-08 performance budget
2
+
3
+ ## Goal
4
+
5
+ A feature confirm card cannot pass on a vague speed claim. It must record
6
+ LCP, INP, bundle size, virtualized long lists, a weak-network check, and a
7
+ large-data check. Kickoff schedules that budget before implementation.
8
+
9
+ ## In scope
10
+
11
+ - Local validate on perfBudget
12
+ - One FDE-08 task per confirmed module that declares page performance,
13
+ placed before implement and after the env probe, data precheck, and
14
+ external-dependency board when those exist
15
+ - Hint, placeholder, and chat/accept prompts
16
+ - Explicit opt-out: no page performance requirement
17
+
18
+ ## Out of scope
19
+
20
+ - Bug desk
21
+ - Running a customer performance lab from the desk
22
+
23
+ ## Assumptions
24
+
25
+ - The desk records the budget; the digital employee runs the weak-network
26
+ and large-data checks.
27
+ - 「本模块无页面性能要求」 / "no page performance" skips the six items
28
+ and the kickoff task.
29
+ - "挺快的" and other vague speed lines fail.
30
+
31
+ ## Acceptance
32
+
33
+ 1. A vague speed line, or a line missing any of the six items, fails
34
+ local validate
35
+ 2. All six present, or the no-page-performance opt-out, passes
36
+ 3. Kickoff adds an FDE-08 task before implement when page performance is
37
+ declared, and skips it on the opt-out
38
+ 4. npm test and npm run test:live pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 276-fde08-perf-budget
2
+
3
+ - [x] Validate the performance budget (LCP, INP, bundle, long list, weak network, large data, or opt-out)
4
+ - [x] Inject an FDE-08 kickoff task before implement
5
+ - [x] Update hints, prompts, docs, and tests
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Create mode refuses when the target project directory already exists. Open from the list or browse still works. Existing folder contents are left untouched.",
4
+ "verification": {
5
+ "L0": "node --check bin/live-repo-path.mjs bin/duaer-live.mjs web/live-dev/app.js — pass",
6
+ "L1": "npm test — pass",
7
+ "L3": "npm run test:live — pass"
8
+ }
9
+ }
@@ -0,0 +1,31 @@
1
+ # Feature Specification: Refuse reusing an existing project directory on create
2
+
3
+ ## Goal
4
+
5
+ Creating a new project must not reuse a directory that already exists.
6
+ An existing folder can only be opened from the project list or by browse-open.
7
+
8
+ ## In scope
9
+
10
+ - `/api/projects/activate` create mode refuses when the target path already exists
11
+ - Create form sends create mode; list click opens without create
12
+ - Clear Chinese error telling the user to rename or open the existing project
13
+ - Unit / smoke coverage
14
+
15
+ ## Out of scope
16
+
17
+ - Deleting or renaming old project folders
18
+ - Changing how desk sessions are keyed
19
+
20
+ ## Assumptions
21
+
22
+ - "选为当前项目" on the create form means create when the path is new
23
+ - Clicking an item under 「已有项目」 means open
24
+ - Browse into an existing folder opens it; it does not create over it
25
+
26
+ ## Acceptance
27
+
28
+ 1. Create with a folder name that already exists under the parent returns an error; disk contents are unchanged
29
+ 2. Opening the same path from the project list still works
30
+ 3. Create with a never-used name still creates the directory
31
+ 4. `npm test` and `npm run test:live` pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 277-project-dir-reuse
2
+
3
+ - [x] Refuse create when the target project directory already exists
4
+ - [x] Keep open-from-list / browse-open working for existing paths
5
+ - [x] Add tests, copy, and E2E row
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Create uses only a short folder name under the product parent. Absolute paths, existing folders, and duplicate project titles are refused. Open from the list or browse still works.",
4
+ "verification": {
5
+ "L0": "node --check bin/live-repo-path.mjs bin/duaer-live.mjs — pass",
6
+ "L1": "npm test — pass",
7
+ "L3": "npm run test:live — pass"
8
+ }
9
+ }
@@ -0,0 +1,27 @@
1
+ # Feature Specification: Unique create — short name under parent only
2
+
3
+ ## Goal
4
+
5
+ Create and open are separate. Creating a project only uses a short folder
6
+ name under the product parent. Absolute paths, duplicate folders, and
7
+ duplicate project titles are refused.
8
+
9
+ ## In scope
10
+
11
+ - Create mode: short name only, must have parent set, refuse if folder exists
12
+ - Create mode: refuse if an existing project already uses that path or title
13
+ - Open from list / browse still accepts absolute paths
14
+ - Copy and labels match the rule
15
+
16
+ ## Out of scope
17
+
18
+ - Moving or renaming existing project folders on disk
19
+ - Deleting stale list entries
20
+
21
+ ## Acceptance
22
+
23
+ 1. Create with `/Users/.../pcdemo` fails; asks for a short name under the parent
24
+ 2. Create with a short name that already exists on disk or in the project list fails
25
+ 3. Create with a title already used by another project fails
26
+ 4. Open from the list still works with absolute paths
27
+ 5. `npm test` and `npm run test:live` pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 278-project-create-unique
2
+
3
+ - [x] Create resolves only a short name under the product parent
4
+ - [x] Refuse duplicate folder and duplicate project title on create
5
+ - [x] Update labels, hints, and tests
@@ -0,0 +1,8 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Corridor-aware Archify edge detours (validated bottom/top/side/gutter) plus vertical labelAt so stacked clean-flow IR renders.",
4
+ "verification": {
5
+ "commands": ["node --test test/live-archify.test.mjs"],
6
+ "result": "16 pass / 0 fail"
7
+ }
8
+ }
@@ -0,0 +1,28 @@
1
+ # Feature Specification: Architecture corridor detour for clean-flow
2
+
3
+ ## Goal
4
+
5
+ When Archify rejects edges that cross unrelated components, auto-routing
6
+ must pick a corridor whose segments stay clear of other boxes — not a
7
+ naive bottom exit through column neighbors, and not a side via whose
8
+ horizontal leg clips co-row nodes. Vertical edge labels must sit in the
9
+ gap between stacked boxes.
10
+
11
+ ## In scope
12
+
13
+ - `routeCrossingEdges` validates candidate routes (bottom/top wrap, side
14
+ corridor, gutter wrap) and applies the first clear detour
15
+ - Re-route edges that already have a bad bottom via
16
+ - Vertical edge labels get `labelAt` in the inter-box gap
17
+ - Regression test matching the speaker/editor/store failure
18
+
19
+ ## Out of scope
20
+
21
+ - Changing Archify itself
22
+ - Full force-directed relayout
23
+
24
+ ## Acceptance
25
+
26
+ 1. The reproduced IR (speaker→editor, store→gen, 初稿/定稿 labels) renders
27
+ 2. Existing same-row reverse-edge test still passes
28
+ 3. `npm test` live-archify tests pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 279-arch-side-detour
2
+
3
+ - [x] Corridor-aware detour for edges that cross unrelated components
4
+ - [x] Place vertical edge labels in the gap (`labelAt`)
5
+ - [x] Regression test + docs
@@ -0,0 +1,8 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Bottom/top via edge labels pin labelAt on the via corridor so 改稿 no longer overlaps artifact.",
4
+ "verification": {
5
+ "commands": ["node --check bin/live-archify.mjs", "node --test test/live-archify.test.mjs"],
6
+ "result": "17 pass / 0 fail"
7
+ }
8
+ }
@@ -0,0 +1,22 @@
1
+ # Feature Specification: Bottom-via edge labels clear mid-row boxes
2
+
3
+ ## Goal
4
+
5
+ When a same-row edge detours under the floor, its label must stay on the
6
+ via (below) — not be pulled up with `labelDy: -36` onto mid-row components
7
+ such as `artifact`.
8
+
9
+ ## In scope
10
+
11
+ - `repairEdgeLabelPlacement` pins `labelAt` under bottom vias / above top vias
12
+ - Overlap nudge when an offset mid still hits a box
13
+ - Regression for speaker→revise「改稿」 overlapping artifact
14
+
15
+ ## Out of scope
16
+
17
+ - Changing Archify itself
18
+
19
+ ## Acceptance
20
+
21
+ 1. Reproduced IR renders via Archify
22
+ 2. `node --test test/live-archify.test.mjs` passes
@@ -0,0 +1,5 @@
1
+ # Tasks — 280-arch-bottom-via-label
2
+
3
+ - [x] Pin bottom/top via labels with labelAt on the via corridor
4
+ - [x] Regression test for 改稿 / artifact overlap
5
+ - [x] Docs + delivery stamp
@@ -0,0 +1,8 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Released 0.27.2: architecture clean-flow, project create uniqueness, FDE-08. Tag v0.27.2 published.",
4
+ "verification": {
5
+ "commands": ["gh release view v0.27.2"],
6
+ "result": "GitHub Release published; npm Trusted Publishing via release event"
7
+ }
8
+ }
@@ -0,0 +1,13 @@
1
+ # Feature Specification: Release 0.27.2
2
+
3
+ ## Goal
4
+
5
+ Ship 0.27.2: architecture clean-flow corridor detours, bottom-via label
6
+ placement, unique project create paths, and FDE-08 performance budget.
7
+ Promote develop to main, publish a GitHub Release, and let npm Trusted
8
+ Publishing run.
9
+
10
+ ## Acceptance
11
+
12
+ 1. `package.json` is `0.27.2`; CHANGELOG has `0.27.2` and an empty Unreleased section.
13
+ 2. Tag `v0.27.2` is on `main`; GitHub Release is published.
@@ -0,0 +1,4 @@
1
+ # Tasks — 281-release-0272
2
+
3
+ - [x] Bump package.json to 0.27.2 and move CHANGELOG Unreleased
4
+ - [x] Promote develop → main, tag, GitHub Release
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "After confirm+build, 确认人数并生成派工图 stays locked (chips too) until the dispatch graph is invalidated.",
4
+ "verification": {
5
+ "commands": [
6
+ "node --check web/live-dev/app.js",
7
+ "node --test test/task-graph.test.mjs test/live-i18n-common.test.mjs test/live-i18n-ja.test.mjs",
8
+ "npm run test:live"
9
+ ],
10
+ "result": "all pass"
11
+ }
12
+ }
@@ -0,0 +1,26 @@
1
+ # Feature Specification: Lock confirm-workers after dispatch graph
2
+
3
+ ## Goal
4
+
5
+ After the operator confirms worker count and the dispatch graph builds
6
+ successfully, **确认人数并生成派工图** stays locked so it cannot be
7
+ re-clicked. Worker-count chips lock with it. Unlock only when the graph
8
+ becomes stale (count/decompose/architecture invalidate).
9
+
10
+ ## In scope
11
+
12
+ - Keep confirm button disabled + locked label when `dispatchGraphReady`
13
+ - Lock worker-count chips while the graph is ready
14
+ - Re-enable when the graph is marked stale or cleared
15
+ - i18n + desk docs + E2E catalog + regression markers
16
+
17
+ ## Out of scope
18
+
19
+ - Changing how the graph is generated
20
+ - Locking「查看派工图」
21
+
22
+ ## Acceptance
23
+
24
+ 1. After a successful confirm+build, the confirm button is disabled and shows a locked label.
25
+ 2. Changing architecture / re-decompose / clearing ready unlocks the button again.
26
+ 3. `node --test test/task-graph.test.mjs` and live i18n key parity pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 282-dispatch-confirm-lock
2
+
3
+ - [x] Lock confirm button + worker chips when dispatchGraphReady
4
+ - [x] Unlock on stale / arch invalidate; sync on project restore
5
+ - [x] i18n + docs + tests
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Compact FDE desk with calm slate light/dark themes and a persistent top-bar toggle.",
4
+ "verification": {
5
+ "commands": [
6
+ "node --check web/live-dev/app.js",
7
+ "node --test test/desk-theme.test.mjs test/live-i18n-common.test.mjs test/live-i18n-ja.test.mjs",
8
+ "npm run test:live"
9
+ ],
10
+ "result": "all pass"
11
+ }
12
+ }
@@ -0,0 +1,26 @@
1
+ # Feature Specification: Compact desk theme with light/dark toggle
2
+
3
+ ## Goal
4
+
5
+ Make the FDE desk easier to stare at for long sessions: tighter spacing,
6
+ calmer colors (less orange glow / hatch noise), and a light/dark theme
7
+ toggle that persists.
8
+
9
+ ## In scope
10
+
11
+ - Compact shell / header / layout / panel spacing
12
+ - Soft dark + light palettes via `html[data-theme]`
13
+ - Top-bar theme toggle; persist in `localStorage`; early boot to avoid flash
14
+ - Same theme on dispatch-center page
15
+ - i18n + docs + smoke markers
16
+
17
+ ## Out of scope
18
+
19
+ - Redesigning Archify diagram chrome
20
+ - Per-project theme overrides
21
+
22
+ ## Acceptance
23
+
24
+ 1. Desk feels denser (smaller brand, tighter gaps/padding).
25
+ 2. Light and dark themes both readable; toggle switches and persists across reload.
26
+ 3. `npm run test:live` and i18n key parity pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 283-desk-theme-compact
2
+
3
+ - [x] CSS: compact density + light/dark palettes
4
+ - [x] Theme toggle + persist + dispatch-center wire
5
+ - [x] i18n + docs + tests
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Each architecture/improve wave forces a fresh 派工图; confirm button shows regenerate when rebuilding; stale clears old URL.",
4
+ "verification": {
5
+ "commands": [
6
+ "node --check web/live-dev/app.js",
7
+ "node --test test/task-graph.test.mjs test/live-i18n-common.test.mjs test/live-i18n-ja.test.mjs",
8
+ "npm run test:live"
9
+ ],
10
+ "result": "all pass"
11
+ }
12
+ }
@@ -0,0 +1,33 @@
1
+ # Feature Specification: Regenerate dispatch graph each wave
2
+
3
+ ## Goal
4
+
5
+ Every kickoff wave (first delivery and each **改进**) must build a **new**
6
+ 派工图. Confirm/lock buttons follow the operator flow: unlock and ask to
7
+ regenerate when the wave changes; stay locked only for the current ready graph.
8
+
9
+ ## Findings (current gaps)
10
+
11
+ 1. `showDispatchPanel` reuses an old `taskPool` after architecture confirm and
12
+ does not force a fresh decompose / clear graph URL.
13
+ 2. `enterReviseMode` (再改一版) does not clear graph ready/URL/pool.
14
+ 3. `markDispatchGraphStale` leaves `dispatchGraphUrl` pointing at an old file.
15
+ 4. Button copy does not distinguish first confirm vs regenerate after stale.
16
+
17
+ ## In scope
18
+
19
+ - Reset + redecompose on architecture confirm and revise entry
20
+ - Clear URL on stale/invalidate; sync chips/button
21
+ - Button labels: confirm / regenerate / locked
22
+ - Docs + tests
23
+
24
+ ## Out of scope
25
+
26
+ - Changing Archify render pipeline internals
27
+
28
+ ## Acceptance
29
+
30
+ 1. After「再改一版」→ plan → architecture confirm, confirm-workers is unlocked
31
+ and builds a new graph (new URL); old ready state is not reused.
32
+ 2. Stale / re-decompose / baseline open-change unlocks and prompts regenerate.
33
+ 3. `node --test` markers and live smoke pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 284-dispatch-graph-regen
2
+
3
+ - [x] Central resetDispatchGraphForNewWave; call from arch confirm / revise / baseline
4
+ - [x] showDispatchPanel always fresh pool after arch confirm; clear URL on stale
5
+ - [x] Button labels confirm / regen / locked + i18n + tests
@@ -0,0 +1,11 @@
1
+ {
2
+ "status": "accepted",
3
+ "summary": "Light theme uses shared tokens for inputs/composer/bubbles; denser compact spacing.",
4
+ "verification": {
5
+ "commands": [
6
+ "node --test test/desk-theme.test.mjs",
7
+ "npm run test:live"
8
+ ],
9
+ "result": "all pass"
10
+ }
11
+ }
@@ -0,0 +1,13 @@
1
+ # Feature Specification: Light theme contrast + denser compact
2
+
3
+ ## Goal
4
+
5
+ Fix unreadable black/dark hardcodes in light theme and tighten desk density
6
+ another step.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Light theme inputs, composer, chat bubbles, and primary/confirm buttons
11
+ use theme tokens and stay readable.
12
+ 2. Shell spacing is tighter than the previous compact pass.
13
+ 3. `node --test test/desk-theme.test.mjs` and `npm run test:live` pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 285-desk-light-compact
2
+
3
+ - [x] Replace dark hardcodes with theme tokens; improve light contrast
4
+ - [x] Tighten compact spacing tokens
5
+ - [x] Docs + tests + delivery
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-23T09:45:00.000Z",
4
+ "verification": {
5
+ "L0": "node --check web/live-dev/app.js bin/live-modules.mjs web/live-dev/task-graph.mjs",
6
+ "L1": "npm test (pass)",
7
+ "L3": "npm run test:live (pass)"
8
+ },
9
+ "summary": "Bug path appends defect tab without wiping modules; light theme inset tokens; bug pool prefers id=bug."
10
+ }
@@ -0,0 +1,26 @@
1
+ # Feature Specification: Keep modules clickable during bug + theme leftovers
2
+
3
+ ## Goal
4
+
5
+ After「改缺陷」, prior requirement module tabs must stay visible and clickable
6
+ (view). Fix remaining light-theme dark overlays that still look wrong.
7
+
8
+ ## Cause
9
+
10
+ `enterDeskKind("bug")` / `beginBugFixFromCta` replaced `state.modules` with a
11
+ single bug card, and `renderModuleTabs` hid tabs when `deskKind === "bug"`.
12
+
13
+ ## In scope
14
+
15
+ - Preserve feature modules; append/select a `bug` module instead of wiping
16
+ - Show module tabs in bug mode; feature tabs viewable (readonly when confirmed)
17
+ - Theme: replace leftover `rgba(8,14,20,…)` wells with tokens
18
+ - Docs + tests
19
+
20
+ ## Acceptance
21
+
22
+ 1. After starting a defect from a multi-module feature project, prior module
23
+ tabs remain and switching shows that module's card (readonly if confirmed).
24
+ 2. Bug module is editable; confirming the defect does not delete feature modules.
25
+ 3. Light theme no longer uses fixed near-black overlay fills on wells.
26
+ 4. Targeted tests pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 286-modules-bug-theme
2
+
3
+ - [x] Preserve modules on bug entry; show tabs; chat merge keeps features
4
+ - [x] Theme overlay leftovers → tokens
5
+ - [x] Tests + docs + delivery
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-23T09:55:00.000Z",
4
+ "verification": {
5
+ "L0": "node --check web/live-dev/app.js bin/duaer-live.mjs bin/live-modules.mjs",
6
+ "L1": "npm test (pass)",
7
+ "L3": "npm run test:live (pass)"
8
+ },
9
+ "summary": "Bug confirm merges modules so prior tabs survive; progress run-blocks use inset tokens; denser desk spacing."
10
+ }
@@ -0,0 +1,31 @@
1
+ # Feature Specification: Progress theme + bug modules survive confirm
2
+
3
+ ## Goal
4
+
5
+ Light theme「派工进度」must not look dark. Desk denser / smoother. After
6
+ entering defect path (and after confirming the defect), prior requirement
7
+ module tabs must stay visible.
8
+
9
+ ## Cause
10
+
11
+ `/api/confirm` (bug) returned a one-item `modules` list (`bug` only). Client
12
+ `applyConfirmSuccess` replaced `state.modules`, wiping feature tabs. Progress
13
+ `.run-block` still used fixed dark `rgba(26,40,54,…)` fills.
14
+
15
+ ## In scope
16
+
17
+ - Server + client: bug confirm merges into existing modules (keep features)
18
+ - Progress column theme tokens + denser spacing / smoother scroll feel
19
+ - Docs + tests (E2E catalog)
20
+
21
+ ## Out of scope
22
+
23
+ - Changing bug task pool shape or hotfix branch rules
24
+
25
+ ## Acceptance
26
+
27
+ 1. Enter「改缺陷」with ≥1 prior module → tabs show prior + bug; after confirm
28
+ defect, prior tabs remain.
29
+ 2. Light theme progress run blocks / meters use theme inset tokens (no near-black
30
+ hardcodes).
31
+ 3. Progress column padding/gaps tighter than pre-fix; targeted tests pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 287-progress-modules-ux
2
+
3
+ - [x] Bug confirm merge keeps feature modules (API + client)
4
+ - [x] Progress column theme + denser compact
5
+ - [x] Tests + docs + delivery + merge handoff
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-23T10:05:00.000Z",
4
+ "verification": {
5
+ "L0": "node --check web/live-dev/app.js",
6
+ "L1": "npm test (pass)",
7
+ "L3": "npm run test:live (pass)"
8
+ },
9
+ "summary": "Settings closes without ready gate; gear reopen keeps ready; denser drawers/shell."
10
+ }
@@ -0,0 +1,17 @@
1
+ # Feature Specification: Settings always closable + denser desk
2
+
3
+ ## Goal
4
+
5
+ Settings drawer must close via 关闭 / backdrop / gear toggle / Escape even when
6
+ the model is not configured. Make drawers and shell denser.
7
+
8
+ ## Cause
9
+
10
+ Close handlers gated on `state.ready`; gear toggle only closes when ready.
11
+ Escape did not dismiss drawers.
12
+
13
+ ## Acceptance
14
+
15
+ 1. Settings closes without `state.ready` (button, backdrop, gear, Escape).
16
+ 2. Drawers and shell spacing tighter than pre-fix.
17
+ 3. Targeted tests pass.
@@ -0,0 +1,5 @@
1
+ # Tasks — 288-settings-close-compact
2
+
3
+ - [x] Remove ready gate on settings close; Escape closes drawers
4
+ - [x] Densify drawers + shell tokens
5
+ - [x] Tests + docs + delivery + merge
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-23T10:35:00.000Z",
4
+ "verification": {
5
+ "L0": "node --check web/live-dev/app.js",
6
+ "L1": "npm test (pass)",
7
+ "L3": "npm run test:live (pass)"
8
+ },
9
+ "summary": "Cache-bust app.js/styles.css; harden Settings close with closeSettingsDrawer + capture listener."
10
+ }
@@ -0,0 +1,16 @@
1
+ # Feature Specification: Settings close click must work
2
+
3
+ ## Goal
4
+
5
+ The Settings「关闭」button must dismiss the drawer on click.
6
+
7
+ ## Cause
8
+
9
+ Close was gated on `state.ready` in older builds; `app.js?v=perf-budget-1`
10
+ cache kept serving that gate after the logic fix.
11
+
12
+ ## Acceptance
13
+
14
+ 1. Clicking「关闭」hides `#settingsPanel` (with or without model ready).
15
+ 2. Cache-bust query on `app.js` / `styles.css` so operators get the fix.
16
+ 3. Tests assert no ready-gate and bumped asset version.