duaer-spec 0.18.0 → 0.20.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 (169) hide show
  1. package/.claude/rules/ai-ui-copy.md +2 -2
  2. package/.cursor/rules/ai-ui-copy.mdc +2 -2
  3. package/.duaer/active-job.json +5 -1
  4. package/.duaer/handoff.json +2 -2
  5. package/.duaer/memory/testing.md +9 -4
  6. package/.duaer/specs/148-release-018/delivery.json +24 -0
  7. package/.duaer/specs/148-release-018/tasks.md +1 -1
  8. package/.duaer/specs/149-docs-brand-logo/delivery.json +10 -0
  9. package/.duaer/specs/149-docs-brand-logo/spec.md +12 -0
  10. package/.duaer/specs/149-docs-brand-logo/tasks.md +5 -0
  11. package/.duaer/specs/150-revise-kickoff-err/delivery.json +11 -0
  12. package/.duaer/specs/150-revise-kickoff-err/spec.md +15 -0
  13. package/.duaer/specs/150-revise-kickoff-err/tasks.md +5 -0
  14. package/.duaer/specs/151-revise-ir-stack/delivery.json +9 -0
  15. package/.duaer/specs/151-revise-ir-stack/spec.md +15 -0
  16. package/.duaer/specs/151-revise-ir-stack/tasks.md +6 -0
  17. package/.duaer/specs/152-revise-kickoff-lite/delivery.json +9 -0
  18. package/.duaer/specs/152-revise-kickoff-lite/spec.md +16 -0
  19. package/.duaer/specs/152-revise-kickoff-lite/tasks.md +6 -0
  20. package/.duaer/specs/153-kickoff-stringify/delivery.json +9 -0
  21. package/.duaer/specs/153-kickoff-stringify/spec.md +14 -0
  22. package/.duaer/specs/153-kickoff-stringify/tasks.md +4 -0
  23. package/.duaer/specs/154-revise-arch-order/delivery.json +9 -0
  24. package/.duaer/specs/154-revise-arch-order/spec.md +16 -0
  25. package/.duaer/specs/154-revise-arch-order/tasks.md +5 -0
  26. package/.duaer/specs/155-arch-canvas-expand/delivery.json +9 -0
  27. package/.duaer/specs/155-arch-canvas-expand/spec.md +14 -0
  28. package/.duaer/specs/155-arch-canvas-expand/tasks.md +5 -0
  29. package/.duaer/specs/156-arch-inline-mount/delivery.json +13 -0
  30. package/.duaer/specs/156-arch-inline-mount/spec.md +17 -0
  31. package/.duaer/specs/156-arch-inline-mount/tasks.md +5 -0
  32. package/.duaer/specs/157-arch-mount-fx/delivery.json +12 -0
  33. package/.duaer/specs/157-arch-mount-fx/spec.md +15 -0
  34. package/.duaer/specs/157-arch-mount-fx/tasks.md +5 -0
  35. package/.duaer/specs/158-arch-click-fx/delivery.json +13 -0
  36. package/.duaer/specs/158-arch-click-fx/spec.md +13 -0
  37. package/.duaer/specs/158-arch-click-fx/tasks.md +5 -0
  38. package/.duaer/specs/159-arch-auto-height/delivery.json +12 -0
  39. package/.duaer/specs/159-arch-auto-height/spec.md +14 -0
  40. package/.duaer/specs/159-arch-auto-height/tasks.md +4 -0
  41. package/.duaer/specs/160-preview-deploy-btn/delivery.json +12 -0
  42. package/.duaer/specs/160-preview-deploy-btn/spec.md +15 -0
  43. package/.duaer/specs/160-preview-deploy-btn/tasks.md +5 -0
  44. package/.duaer/specs/161-deploy-picker/delivery.json +12 -0
  45. package/.duaer/specs/161-deploy-picker/spec.md +13 -0
  46. package/.duaer/specs/161-deploy-picker/tasks.md +5 -0
  47. package/.duaer/specs/162-intro-pages/delivery.json +14 -0
  48. package/.duaer/specs/162-intro-pages/spec.md +23 -0
  49. package/.duaer/specs/162-intro-pages/tasks.md +5 -0
  50. package/.duaer/specs/163-intro-grand/delivery.json +14 -0
  51. package/.duaer/specs/163-intro-grand/spec.md +22 -0
  52. package/.duaer/specs/163-intro-grand/tasks.md +4 -0
  53. package/.duaer/specs/164-intro-layout/delivery.json +13 -0
  54. package/.duaer/specs/164-intro-layout/spec.md +11 -0
  55. package/.duaer/specs/164-intro-layout/tasks.md +4 -0
  56. package/.duaer/specs/165-aliyun-settings/delivery.json +13 -0
  57. package/.duaer/specs/165-aliyun-settings/spec.md +24 -0
  58. package/.duaer/specs/165-aliyun-settings/tasks.md +5 -0
  59. package/.duaer/specs/166-cloud-aws-settings/delivery.json +13 -0
  60. package/.duaer/specs/166-cloud-aws-settings/spec.md +18 -0
  61. package/.duaer/specs/166-cloud-aws-settings/tasks.md +5 -0
  62. package/.duaer/specs/167-settings-compact/delivery.json +9 -0
  63. package/.duaer/specs/167-settings-compact/spec.md +11 -0
  64. package/.duaer/specs/167-settings-compact/tasks.md +4 -0
  65. package/.duaer/specs/168-rename-fde/delivery.json +15 -0
  66. package/.duaer/specs/168-rename-fde/spec.md +22 -0
  67. package/.duaer/specs/168-rename-fde/tasks.md +4 -0
  68. package/.duaer/specs/169-modular-fde-confirm/delivery.json +9 -0
  69. package/.duaer/specs/169-modular-fde-confirm/spec.md +36 -0
  70. package/.duaer/specs/169-modular-fde-confirm/tasks.md +7 -0
  71. package/.duaer/specs/170-readme-on-delivery/delivery.json +9 -0
  72. package/.duaer/specs/170-readme-on-delivery/spec.md +30 -0
  73. package/.duaer/specs/170-readme-on-delivery/tasks.md +4 -0
  74. package/.duaer/specs/171-chat-markdown/delivery.json +8 -0
  75. package/.duaer/specs/171-chat-markdown/spec.md +11 -0
  76. package/.duaer/specs/171-chat-markdown/tasks.md +3 -0
  77. package/.duaer/specs/172-module-tab-active/delivery.json +1 -0
  78. package/.duaer/specs/172-module-tab-active/spec.md +10 -0
  79. package/.duaer/specs/172-module-tab-active/tasks.md +2 -0
  80. package/.duaer/specs/173-parallel-terminal-lanes/delivery.json +5 -0
  81. package/.duaer/specs/173-parallel-terminal-lanes/spec.md +12 -0
  82. package/.duaer/specs/173-parallel-terminal-lanes/tasks.md +3 -0
  83. package/.duaer/specs/174-docs-fde-flow-sync/delivery.json +5 -0
  84. package/.duaer/specs/174-docs-fde-flow-sync/spec.md +29 -0
  85. package/.duaer/specs/174-docs-fde-flow-sync/tasks.md +7 -0
  86. package/.duaer/specs/175-confirm-btn-state/delivery.json +5 -0
  87. package/.duaer/specs/175-confirm-btn-state/spec.md +22 -0
  88. package/.duaer/specs/175-confirm-btn-state/tasks.md +6 -0
  89. package/.duaer/specs/176-deliverables-page/delivery.json +5 -0
  90. package/.duaer/specs/176-deliverables-page/spec.md +31 -0
  91. package/.duaer/specs/176-deliverables-page/tasks.md +6 -0
  92. package/.duaer/specs/177-deliverables-client-look/delivery.json +5 -0
  93. package/.duaer/specs/177-deliverables-client-look/spec.md +13 -0
  94. package/.duaer/specs/177-deliverables-client-look/tasks.md +4 -0
  95. package/.duaer/specs/178-arch-panel-visible/delivery.json +5 -0
  96. package/.duaer/specs/178-arch-panel-visible/spec.md +22 -0
  97. package/.duaer/specs/178-arch-panel-visible/tasks.md +6 -0
  98. package/.duaer/specs/179-arch-layout-hang/delivery.json +5 -0
  99. package/.duaer/specs/179-arch-layout-hang/spec.md +17 -0
  100. package/.duaer/specs/179-arch-layout-hang/tasks.md +5 -0
  101. package/.duaer/specs/180-deliverables-structure/delivery.json +8 -0
  102. package/.duaer/specs/180-deliverables-structure/spec.md +16 -0
  103. package/.duaer/specs/180-deliverables-structure/tasks.md +8 -0
  104. package/.duaer/specs/181-multi-worker-progress/delivery.json +11 -0
  105. package/.duaer/specs/181-multi-worker-progress/spec.md +15 -0
  106. package/.duaer/specs/181-multi-worker-progress/tasks.md +7 -0
  107. package/.duaer/specs/182-task-orchestrate/delivery.json +11 -0
  108. package/.duaer/specs/182-task-orchestrate/spec.md +14 -0
  109. package/.duaer/specs/182-task-orchestrate/tasks.md +8 -0
  110. package/.duaer/specs/183-deliverables-structure-v2/delivery.json +8 -0
  111. package/.duaer/specs/183-deliverables-structure-v2/spec.md +16 -0
  112. package/.duaer/specs/183-deliverables-structure-v2/tasks.md +6 -0
  113. package/.duaer/specs/184-deliverables-layout/delivery.json +8 -0
  114. package/.duaer/specs/184-deliverables-layout/spec.md +14 -0
  115. package/.duaer/specs/184-deliverables-layout/tasks.md +5 -0
  116. package/.duaer/specs/185-req-card-structure/delivery.json +10 -0
  117. package/.duaer/specs/185-req-card-structure/spec.md +26 -0
  118. package/.duaer/specs/185-req-card-structure/tasks.md +8 -0
  119. package/.duaer/specs/186-req-edit-wipe/delivery.json +9 -0
  120. package/.duaer/specs/186-req-edit-wipe/spec.md +16 -0
  121. package/.duaer/specs/186-req-edit-wipe/tasks.md +6 -0
  122. package/.duaer/specs/187-req-card-modules/delivery.json +9 -0
  123. package/.duaer/specs/187-req-card-modules/spec.md +28 -0
  124. package/.duaer/specs/187-req-card-modules/tasks.md +7 -0
  125. package/.duaer/specs/188-release-019/delivery.json +18 -0
  126. package/.duaer/specs/188-release-019/spec.md +12 -0
  127. package/.duaer/specs/188-release-019/tasks.md +6 -0
  128. package/.duaer/specs/189-fde-portfolio/delivery.json +10 -0
  129. package/.duaer/specs/189-fde-portfolio/spec.md +29 -0
  130. package/.duaer/specs/189-fde-portfolio/tasks.md +8 -0
  131. package/.duaer/specs/190-live-open-no-model/delivery.json +9 -0
  132. package/.duaer/specs/190-live-open-no-model/spec.md +17 -0
  133. package/.duaer/specs/190-live-open-no-model/tasks.md +6 -0
  134. package/.duaer/specs/191-projects-root-pick/delivery.json +11 -0
  135. package/.duaer/specs/191-projects-root-pick/spec.md +14 -0
  136. package/.duaer/specs/191-projects-root-pick/tasks.md +6 -0
  137. package/.duaer/specs/192-release-020/spec.md +12 -0
  138. package/.duaer/specs/192-release-020/tasks.md +6 -0
  139. package/AGENTS.md +2 -2
  140. package/CHANGELOG.md +199 -0
  141. package/README.md +49 -20
  142. package/README.zh-CN.md +26 -18
  143. package/bin/duaer-live.mjs +1436 -227
  144. package/bin/duaer.mjs +1 -1
  145. package/bin/live-archify.mjs +46 -25
  146. package/bin/live-claude-trust.mjs +3 -3
  147. package/bin/live-deliverables.mjs +1236 -0
  148. package/bin/live-modules.mjs +400 -0
  149. package/bin/live-orchestrate.mjs +207 -0
  150. package/bin/live-progress.mjs +165 -1
  151. package/bin/live-project-chat.mjs +51 -2
  152. package/bin/live-projects.mjs +34 -1
  153. package/docs/agent/README.md +1 -0
  154. package/docs/agent/deploy-targets.md +18 -0
  155. package/docs/agent/e2e-test-plan.md +77 -5
  156. package/docs/agent/live-desk.md +111 -0
  157. package/docs/agent/worker-models.md +14 -10
  158. package/docs/agent/worker-models.zh-CN.md +13 -11
  159. package/docs/assets/duaer-spec-fde.svg +33 -0
  160. package/package.json +2 -1
  161. package/web/live-dev/app.js +1879 -325
  162. package/web/live-dev/architecture-ir.mjs +18 -11
  163. package/web/live-dev/architecture-mount.mjs +428 -0
  164. package/web/live-dev/chat-markdown.mjs +55 -0
  165. package/web/live-dev/delivery-status.mjs +135 -0
  166. package/web/live-dev/i18n.js +283 -50
  167. package/web/live-dev/index.html +238 -79
  168. package/web/live-dev/structured-html.mjs +121 -29
  169. package/web/live-dev/styles.css +631 -7
@@ -10,8 +10,8 @@ AI-generated pages must not contain redundant explanatory text.
10
10
 
11
11
  ## Duaer brand (site-wide)
12
12
 
13
- Visible live-desk / FED copy that names the product surface must include the
14
- **Duaer** brand (or **Duaer-spec FED** where that full mark is already used).
13
+ Visible live-desk / FDE copy that names the product surface must include the
14
+ **Duaer** brand (or **Duaer-spec FDE** where that full mark is already used).
15
15
 
16
16
  - Do not write anonymous「台面」/ “desk” alone when referring to this product’s
17
17
  chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk”
@@ -13,8 +13,8 @@ AI-generated pages must not contain redundant explanatory text.
13
13
 
14
14
  ## Duaer brand (site-wide)
15
15
 
16
- Visible live-desk / FED copy that names the product surface must include the
17
- **Duaer** brand (or **Duaer-spec FED** where that full mark is already used).
16
+ Visible live-desk / FDE copy that names the product surface must include the
17
+ **Duaer** brand (or **Duaer-spec FDE** where that full mark is already used).
18
18
 
19
19
  - Do not write anonymous「台面」/ “desk” alone when referring to this product’s
20
20
  chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk”
@@ -1 +1,5 @@
1
- {"slug":"148-release-018","spec":".duaer/specs/148-release-018/spec.md"}
1
+ {
2
+ "feature": "192-release-020",
3
+ "spec": ".duaer/specs/192-release-020/spec.md",
4
+ "updatedAt": "2026-09-19T02:50:00.000Z"
5
+ }
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "onWorktreeRemove": {
4
- "stop": "Stop any process whose working directory is under the request worktree (dev servers, file watchers, local APIs). Also stop the FED desk if it was started from a worktree copy of duaer-live.",
4
+ "stop": "Stop any process whose working directory is under the request worktree (dev servers, file watchers, local APIs). Also stop the FDE desk if it was started from a worktree copy of duaer-live.",
5
5
  "restartFromPrimary": true,
6
6
  "commands": [
7
7
  "launchctl kickstart -k \"gui/$(id -u)/com.duaer.live8787\" 2>/dev/null || (lsof -t -iTCP:8787 -sTCP:LISTEN | xargs kill 2>/dev/null; sleep 1; node bin/duaer-live.mjs --port 8787)"
8
8
  ]
9
9
  },
10
- "notes": "After merge to develop: remove worktree, then restart Duaer-spec FED (LaunchAgent com.duaer.live8787) so /api/projects and other new routes load from primary checkout."
10
+ "notes": "After merge to develop: remove worktree, then restart Duaer-spec FDE (LaunchAgent com.duaer.live8787) so /api/projects and other new routes load from primary checkout."
11
11
  }
@@ -36,18 +36,23 @@ level without an explicit waiver in the feature docs (`tasks.md` or Spec).
36
36
  Covers without a paid LLM:
37
37
 
38
38
  1. Desk shell HTML/CSS/JS markers (three columns, structured confirm fields,
39
- `validationAllowsSend`)
39
+ `validationAllowsSend`, modular module-tab / kickoff markers when present)
40
40
  2. Local validate failures (empty / too-short card)
41
41
  3. `/api/validate` pass and `/api/validate/fix` via an in-process mock
42
42
  OpenAI-compatible server
43
43
 
44
44
  Also run `npm test` (includes revise-reliability contract tests: Brief
45
45
  snapshot/rollback helpers + source markers for `PREEMPT_FAILED` / longer
46
- client timeout).
46
+ client timeout; modular / task-pool / chat-markdown / terminal-lane unit
47
+ coverage when those modules change).
47
48
 
48
49
  Does **not** cover: real model quality, live Terminal CLI launch against a
49
- real Cursor/Claude session. Those stay manual E2E catalog rows (E2E-055) or
50
- future suites.
50
+ real Cursor/Claude session, or full multi-worker Terminal orchestration.
51
+ Those stay manual E2E catalog rows (E2E-055, E2E-136, E2E-139) or future suites.
52
+
53
+ Modular desk behavior (per-module confirm, late kickoff, README-on-delivery,
54
+ chat Markdown, parallel lanes, deliverables page): see E2E-135…E2E-141 and
55
+ [`docs/agent/live-desk.md`](../../docs/agent/live-desk.md).
51
56
 
52
57
  ## Opt-in (still need an explicit ask or Spec note)
53
58
 
@@ -0,0 +1,24 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "148-release-018",
4
+ "acceptedAt": "2026-09-18T13:06:30.000Z",
5
+ "summary": "0.18.0 shipped: develop+main pushed, tag v0.18.0, GitHub Release, npm publish success.",
6
+ "verification": {
7
+ "levels": [
8
+ "L3",
9
+ "release"
10
+ ],
11
+ "commands": [
12
+ "npm run test:live",
13
+ "git push origin develop main v0.18.0",
14
+ "gh release create v0.18.0",
15
+ "gh run watch npm-publish"
16
+ ],
17
+ "results": "git+release pass; npm 0.18.0 staged (E409 on republish) — approve on npmjs or enable Allowed actions: npm publish then re-run"
18
+ },
19
+ "preview": {
20
+ "url": "https://www.npmjs.com/package/duaer-spec/v/0.18.0",
21
+ "label": "npm 0.18.0"
22
+ },
23
+ "notes": "Actions logged + duaer-spec@0.18.0 with provenance, but registry has no public 0.18.0; workflow_dispatch got Cannot publish over previously staged version."
24
+ }
@@ -1,4 +1,4 @@
1
1
  # Tasks — 148-release-018
2
2
 
3
3
  - [x] Bump 0.18.0 + CHANGELOG
4
- - [ ] Promote develop → main; push; GitHub Release
4
+ - [x] Promote develop → main; push; GitHub Release
@@ -0,0 +1,10 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "149-docs-brand-logo",
4
+ "acceptedAt": "2026-09-18T13:25:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0"],
7
+ "commands": ["node assert README + SVG brand colors"],
8
+ "results": "pass"
9
+ }
10
+ }
@@ -0,0 +1,12 @@
1
+ # 149 — Put Duaer-spec FED brand mark in docs
2
+
3
+ ## Goal
4
+
5
+ Show the same top-left desk brand (**Duaer-spec** + orange **FED**) at the
6
+ top of the English and Chinese README.
7
+
8
+ ## Acceptance
9
+
10
+ 1. SVG brand asset matches desk colors (ink + register orange on steel plate)
11
+ 2. `README.md` and `README.zh-CN.md` open with that image
12
+ 3. Asset is included in the npm package `files` list
@@ -0,0 +1,5 @@
1
+ # Tasks — 149-docs-brand-logo
2
+
3
+ - [x] Add docs/assets/duaer-spec-fed.svg
4
+ - [x] Wire README EN/ZH; package files
5
+ - [x] Verify; merge develop
@@ -0,0 +1,11 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "150-revise-kickoff-err",
4
+ "acceptedAt": "2026-09-18T13:30:00.000Z",
5
+ "summary": "Revise kickoff shows real errors; defer chrome; stop focus race.",
6
+ "verification": {
7
+ "levels": ["L0", "L3"],
8
+ "commands": ["node --check web/live-dev/app.js", "npm run test:live"],
9
+ "results": "pass"
10
+ }
11
+ }
@@ -0,0 +1,15 @@
1
+ # 150 — Revise kickoff: show real errors, stop chrome races
2
+
3
+ ## Goal
4
+
5
+ 「再改一版」must start the revise dialogue reliably. When it fails, show the
6
+ real reason — not only the generic「改进对话启动失败」. Stop right-panel
7
+ focus/rebuild from racing the streaming kickoff.
8
+
9
+ ## Acceptance
10
+
11
+ 1. Kickoff catch paints real `err.message` (stack-overflow → friendly copy)
12
+ 2. Failed kickoff still persists an assistant error turn into reviseMessages
13
+ 3. `renderRevisePanel` does not focusRight while reviseDialogueOpen
14
+ 4. enterReviseMode defers accordion/chrome until after kickoff starts cleanly
15
+ 5. L0/L3 pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 150-revise-kickoff-err
2
+
3
+ - [x] Real error copy + persist failure turn
4
+ - [x] Stop focus race; harden kickoff ordering
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T13:40:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0", "L3-live-smoke"],
6
+ "commands": ["npm test", "npm run test:live"]
7
+ },
8
+ "notes": "Drop deep architecture IR from desk memory after render; dispatch resolves from architecture/<key>.json; revise SSE omits jsonBlock."
9
+ }
@@ -0,0 +1,15 @@
1
+ # 151 — Drop deep architecture IR from desk memory
2
+
3
+ ## Goal
4
+
5
+ 「再改一版」must not hit Maximum call stack from architecture IR
6
+ serialization. Keep only url / summary / fingerprint / viewBox in memory
7
+ after render; resolve IR from disk on dispatch; omit jsonBlock from revise SSE.
8
+
9
+ ## Acceptance
10
+
11
+ 1. After architecture render, `state.architecture.ir` is null (viewBox kept)
12
+ 2. enterReviseMode / kickoff never JSON.stringify full IR
13
+ 3. Dispatch loads IR from `architecture/<key>.json` when client sends null
14
+ 4. Revise chat done SSE has no jsonBlock
15
+ 5. L0 + live smoke pass; revise kickoff works
@@ -0,0 +1,6 @@
1
+ # Tasks — 151-revise-ir-stack
2
+
3
+ - [x] Slim architecture state + height from viewBox
4
+ - [x] Server resolve IR from url; revise SSE omit jsonBlock
5
+ - [x] Harden kickoff stringify; light setBusy
6
+ - [x] Verify; merge; restart live
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T14:00:00.000Z",
4
+ "verification": {
5
+ "levels": ["L3-live-smoke"],
6
+ "commands": ["npm run test:live"]
7
+ },
8
+ "notes": "Lite revise kickoff: no heavy chrome before fetch; chrome after success; stage-tagged errors; ResizeObserver re-entry guard."
9
+ }
@@ -0,0 +1,16 @@
1
+ # 152 — Revise kickoff must not run heavy chrome
2
+
3
+ ## Goal
4
+
5
+ 「再改一版」starts the model reply without Maximum call stack. Prior fix
6
+ dropped IR from memory; kickoff still called full `syncReviseDispatchButton`
7
+ (accordion / field sync) before fetch, and any stack overflow was mislabeled
8
+ as architecture serialization.
9
+
10
+ ## Acceptance
11
+
12
+ 1. Kickoff start only flips busy / dispatch disabled — no accordion rebuild
13
+ 2. Chrome sync runs only after a successful kickoff reply
14
+ 3. Stack errors show stage + real message (not always「架构图序列化爆栈」)
15
+ 4. ResizeObserver for architecture frame is re-entry safe
16
+ 5. L0 + live smoke pass
@@ -0,0 +1,6 @@
1
+ # Tasks — 152-revise-kickoff-lite
2
+
3
+ - [x] Lite kickoff busy path; chrome after success only
4
+ - [x] Stage-tagged errors; scrub fail bubbles on retry
5
+ - [x] ResizeObserver re-entry guard
6
+ - [x] Verify; merge; restart live
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T14:05:00.000Z",
4
+ "verification": {
5
+ "levels": ["L3-live-smoke"],
6
+ "commands": ["npm run test:live"]
7
+ },
8
+ "notes": "Break reviseCardValues ↔ stashReviseDraftFromFields infinite recursion that surfaced as kickoff-stringify stack overflow."
9
+ }
@@ -0,0 +1,14 @@
1
+ # 153 — Bulletproof revise kickoff JSON body
2
+
3
+ ## Goal
4
+
5
+ 「再改一版」must not fail with `kickoff-stringify: Maximum call stack`.
6
+ Build the /api/chat body from primitive strings only (no Object.prototype.toJSON,
7
+ no String(deepObject) traps).
8
+
9
+ ## Acceptance
10
+
11
+ 1. Kickoff body built via safe primitive JSON helper
12
+ 2. reviseMessages sanitized to {role, content:string} before kickoff
13
+ 3. Non-string message content dropped (not String()'d)
14
+ 4. L3 live smoke passes
@@ -0,0 +1,4 @@
1
+ # Tasks — 153-kickoff-stringify
2
+
3
+ - [x] safe kickoff body builder + sanitize messages
4
+ - [x] Verify; merge; restart live
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T14:25:00.000Z",
4
+ "verification": {
5
+ "levels": ["L3-live-smoke"],
6
+ "commands": ["npm run test:live"]
7
+ },
8
+ "notes": "After 改进方案确认, architecture panel moves under「请先确认架构」CTA."
9
+ }
@@ -0,0 +1,16 @@
1
+ # 154 — Architecture confirm after「请先确认架构」CTA
2
+
3
+ ## Goal
4
+
5
+ After 改进方案确认, UX order must be:
6
+ 1. 改进卡 + CTA「请先确认架构,再派这一版」
7
+ 2. Architecture diagram + confirm button (immediately below the CTA)
8
+
9
+ Do not leave the diagram above under 计划托管 while the CTA sits far below.
10
+
11
+ ## Acceptance
12
+
13
+ 1. When revisePlanConfirmed && architecture not confirmed, architecturePanel sits after doReviseDispatch
14
+ 2. Otherwise architecturePanel stays under deploy targets (first-dispatch flow)
15
+ 3. openReviseArchitectureGate places then scrolls the panel
16
+ 4. L3 live smoke passes
@@ -0,0 +1,5 @@
1
+ # Tasks — 154-revise-arch-order
2
+
3
+ - [x] Slots + placeArchitecturePanelForFlow
4
+ - [x] Wire gate / sync / confirm
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,9 @@
1
+ {
2
+ "status": "accepted",
3
+ "acceptedAt": "2026-09-18T14:45:00.000Z",
4
+ "verification": {
5
+ "levels": ["L0-archify", "L3-live-smoke"],
6
+ "commands": ["node --test test/live-archify.test.mjs", "npm run test:live"]
7
+ },
8
+ "notes": "Architecture iframe expands to viewBox canvas + gutters; scrolling=no; embed height from SVG bbox."
9
+ }
@@ -0,0 +1,14 @@
1
+ # 155 — Architecture iframe expands to canvas (no inner scroll)
2
+
3
+ ## Goal
4
+
5
+ Where the architecture diagram sits, expand the iframe to the full
6
+ canvas (viewBox + embed gutter). No scrollbar inside the diagram —
7
+ the desk column may scroll as a whole.
8
+
9
+ ## Acceptance
10
+
11
+ 1. Frame height = scaled viewBox height + 100px top gutter + pad
12
+ 2. iframe scrolling=no; CSS overflow hidden on the frame
13
+ 3. Embed height postMessage measures SVG/container bottom
14
+ 4. L0 archify + L3 live smoke pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 155-arch-canvas-expand
2
+
3
+ - [x] Height from canvas + gutter; no iframe scroll
4
+ - [x] Embed reportHeight from SVG bbox
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "156-arch-inline-mount",
4
+ "acceptedAt": "2026-09-18T14:45:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs",
9
+ "live smoke: architecture-mount (no iframe)"
10
+ ],
11
+ "notes": "Shadow DOM mount + GET .json; same canvas/passport without iframe"
12
+ }
13
+ }
@@ -0,0 +1,17 @@
1
+ # 156 — Inline architecture mount (no iframe)
2
+
3
+ ## Goal
4
+
5
+ Show the Archify architecture diagram with the same look (full canvas SVG,
6
+ node passport on click) **without an iframe**. Mount into a normal page
7
+ host via Shadow DOM so Archify CSS stays isolated and height flows with
8
+ the canvas.
9
+
10
+ ## Acceptance
11
+
12
+ 1. Desk architecture hosts are `<div class="architecture-mount">`, not iframe
13
+ 2. SVG + Archify diagram CSS mount in shadow root; height is content-driven
14
+ 3. Node click shows passport (label/type/links from IR JSON)
15
+ 4. Previous + accordion diagrams use the same mount
16
+ 5. GET `/api/architecture/<key>.json` served for passport data
17
+ 6. L0 + L3 live smoke pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 156-arch-inline-mount
2
+
3
+ - [x] architecture-mount.mjs + JSON API
4
+ - [x] Replace iframes; wire panel / accordion / previous
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "157-arch-mount-fx",
4
+ "acceptedAt": "2026-09-18T15:00:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs"
9
+ ],
10
+ "notes": "Full Archify container + scoped CSS + viewer runtime proxy; no iframe"
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ # 157 — Full Archify styles & FX in inline mount
2
+
3
+ ## Goal
4
+
5
+ Inline (no-iframe) architecture mount must match Archify viewer look:
6
+ theme CSS variables, fonts, motion/pulse, node zoom, and real `.focus-chip`
7
+ passport — not a stripped SVG + custom card.
8
+
9
+ ## Acceptance
10
+
11
+ 1. Mount includes Archify `.container` + styles scoped to `.archify-root`
12
+ 2. Archify viewer script runs against the mount (focus-chip + reveal zoom)
13
+ 3. Desk chrome hides toolbar/header only; keep diagram FX overlays
14
+ 4. No iframe; height still content-driven
15
+ 5. L0 tests updated; live desk restarted
@@ -0,0 +1,5 @@
1
+ # Tasks — 157-arch-mount-fx
2
+
3
+ - [x] Remount full container + scoped CSS + Archify runtime proxy
4
+ - [x] Wire focus-chip / zoom; drop crude passport
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,13 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "158-arch-click-fx",
4
+ "acceptedAt": "2026-09-18T15:10:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs",
9
+ "playwright smoke: click opens focus-chip"
10
+ ],
11
+ "notes": "Mount full body so Archify viewer can bind toolbar ids; click FX works"
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ # 158 — Architecture click FX (viewer boot)
2
+
3
+ ## Goal
4
+
5
+ Node click must open Archify focus-chip and zoom. Root cause: mount omitted
6
+ body toolbar nodes (`#btn-preset` etc.), so the viewer threw on init.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Mount includes full body chrome (hidden) + id'd styles (`#archify-fonts`)
11
+ 2. Viewer initializes (`host._archify.view.reveal`)
12
+ 3. Click node → focus-chip visible with label; aria-pressed true
13
+ 4. L0 + Playwright smoke pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 158-arch-click-fx
2
+
3
+ - [x] Mount full body + preserve style ids
4
+ - [x] Playwright: click opens focus-chip
5
+ - [x] Merge; restart live
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "159-arch-auto-height",
4
+ "acceptedAt": "2026-09-18T15:20:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs",
9
+ "playwright: host height content-driven; click chip ok"
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,14 @@
1
+ # 159 — Architecture mount auto height
2
+
3
+ ## Goal
4
+
5
+ Inline architecture host height follows the SVG canvas (gutters included),
6
+ not the viewport. Archify reader CSS (`min-height:100vh`,
7
+ `height:calc(100dvh…)`) was locking a black fixed box.
8
+
9
+ ## Acceptance
10
+
11
+ 1. Host chrome CSS overrides 100vh/100dvh; placed after Archify styles
12
+ 2. Mount height ≈ svg + gutters, not `window.innerHeight`
13
+ 3. Click focus-chip still works
14
+ 4. L0 + playwright height smoke pass
@@ -0,0 +1,4 @@
1
+ # Tasks — 159-arch-auto-height
2
+
3
+ - [x] Override viewport height locks; host chrome last
4
+ - [x] Verify height + click; merge; restart live
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "160-preview-deploy-btn",
4
+ "acceptedAt": "2026-09-18T15:30:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs"
9
+ ],
10
+ "notes": "Result-bar Deploy → POST /api/deploy; none defaults to github-pages"
11
+ }
12
+ }
@@ -0,0 +1,15 @@
1
+ # 160 — Result bar Deploy button
2
+
3
+ ## Goal
4
+
5
+ After a satisfactory preview, operators can click **Deploy** next to
6
+ 「打开看看」to publish. Planned-host chips stay where they are. If the
7
+ choice is still「暂不部署」, Deploy defaults to **GitHub Pages**.
8
+
9
+ ## Acceptance
10
+
11
+ 1. Preview actions include a Deploy button when the result panel is visible
12
+ 2. Click Deploy with target `none` → effective target becomes `github-pages`
13
+ 3. `POST /api/deploy` launches the digital employee with a deploy prompt
14
+ (push/`gh` authorized for that publish)
15
+ 4. Desk shows a bot line and resumes status poll; L0 tests cover the wiring
@@ -0,0 +1,5 @@
1
+ # Tasks — 160-preview-deploy-btn
2
+
3
+ - [x] POST /api/deploy + deployDispatchedJob
4
+ - [x] Preview Deploy button + i18n + client trigger
5
+ - [x] Tests; merge; restart live
@@ -0,0 +1,12 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "161-deploy-picker",
4
+ "acceptedAt": "2026-09-18T15:40:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0", "L3-live"],
7
+ "commands": [
8
+ "node --test test/live-smoke.test.mjs test/live-archify.test.mjs"
9
+ ],
10
+ "notes": "Deploy button opens host picker; confirm calls /api/deploy"
11
+ }
12
+ }
@@ -0,0 +1,13 @@
1
+ # 161 — Deploy target picker on Deploy click
2
+
3
+ ## Goal
4
+
5
+ Clicking「部署」opens a dialog:「要部署到哪里?」with concrete hosts
6
+ (Cloudflare / 阿里云 / AWS / GitHub Pages). Confirm starts deploy.
7
+
8
+ ## Acceptance
9
+
10
+ 1. Deploy click opens picker (not silent default)
11
+ 2. Options exclude「暂不部署」; preselect current host or GitHub Pages
12
+ 3. Confirm runs existing `/api/deploy` with chosen target
13
+ 4. Cancel closes without deploy; L0 wiring tests pass
@@ -0,0 +1,5 @@
1
+ # Tasks — 161-deploy-picker
2
+
3
+ - [x] Dialog UI + i18n + CSS
4
+ - [x] Wire Deploy → picker → /api/deploy
5
+ - [x] Verify; merge; restart live
@@ -0,0 +1,14 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "162-intro-pages",
4
+ "acceptedAt": "2026-09-18T15:50:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0"],
7
+ "commands": ["static review of site/index.html; pages.yml path=site"],
8
+ "notes": "Publish via GitHub Pages after merge to main"
9
+ },
10
+ "preview": {
11
+ "url": "https://fujiezee.github.io/duaer-spec/",
12
+ "label": "View result"
13
+ }
14
+ }
@@ -0,0 +1,23 @@
1
+ # 162 — Intro site on GitHub Pages
2
+
3
+ ## Goal
4
+
5
+ Public landing page introducing Duaer-spec / FED, published via GitHub Pages
6
+ from `site/`.
7
+
8
+ ## In scope
9
+
10
+ - Static `site/index.html` (Chinese-primary): brand, pitch, delivery flow, FED, install
11
+ - Workflow `.github/workflows/pages.yml` deploying `site/`
12
+ - Publish so `https://fujiezee.github.io/duaer-spec/` is reachable
13
+
14
+ ## Out of scope
15
+
16
+ - Live desk hosting
17
+ - Multi-page docs site rebuild
18
+
19
+ ## Acceptance
20
+
21
+ 1. Landing presents brand hero, system intro, install CTA
22
+ 2. Pages workflow deploys `site/` on `main` (and workflow_dispatch)
23
+ 3. Merged, pushed, Pages enabled; URL loads
@@ -0,0 +1,5 @@
1
+ # Tasks — 162-intro-pages
2
+
3
+ - [x] Author `site/index.html` + brand asset
4
+ - [x] Add `.github/workflows/pages.yml`
5
+ - [x] Spec / E2E note; merge develop; promote main; enable Pages
@@ -0,0 +1,14 @@
1
+ {
2
+ "status": "accepted",
3
+ "feature": "163-intro-grand",
4
+ "acceptedAt": "2026-09-18T15:50:00.000Z",
5
+ "verification": {
6
+ "levels": ["L0"],
7
+ "commands": ["static review of site/index.html scale/motion"],
8
+ "notes": "Grander hero; republish Pages"
9
+ },
10
+ "preview": {
11
+ "url": "https://fujiezee.github.io/duaer-spec/",
12
+ "label": "View result"
13
+ }
14
+ }