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.
- package/.claude/rules/ai-ui-copy.md +2 -2
- package/.cursor/rules/ai-ui-copy.mdc +2 -2
- package/.duaer/active-job.json +5 -1
- package/.duaer/handoff.json +2 -2
- package/.duaer/memory/testing.md +9 -4
- package/.duaer/specs/148-release-018/delivery.json +24 -0
- package/.duaer/specs/148-release-018/tasks.md +1 -1
- package/.duaer/specs/149-docs-brand-logo/delivery.json +10 -0
- package/.duaer/specs/149-docs-brand-logo/spec.md +12 -0
- package/.duaer/specs/149-docs-brand-logo/tasks.md +5 -0
- package/.duaer/specs/150-revise-kickoff-err/delivery.json +11 -0
- package/.duaer/specs/150-revise-kickoff-err/spec.md +15 -0
- package/.duaer/specs/150-revise-kickoff-err/tasks.md +5 -0
- package/.duaer/specs/151-revise-ir-stack/delivery.json +9 -0
- package/.duaer/specs/151-revise-ir-stack/spec.md +15 -0
- package/.duaer/specs/151-revise-ir-stack/tasks.md +6 -0
- package/.duaer/specs/152-revise-kickoff-lite/delivery.json +9 -0
- package/.duaer/specs/152-revise-kickoff-lite/spec.md +16 -0
- package/.duaer/specs/152-revise-kickoff-lite/tasks.md +6 -0
- package/.duaer/specs/153-kickoff-stringify/delivery.json +9 -0
- package/.duaer/specs/153-kickoff-stringify/spec.md +14 -0
- package/.duaer/specs/153-kickoff-stringify/tasks.md +4 -0
- package/.duaer/specs/154-revise-arch-order/delivery.json +9 -0
- package/.duaer/specs/154-revise-arch-order/spec.md +16 -0
- package/.duaer/specs/154-revise-arch-order/tasks.md +5 -0
- package/.duaer/specs/155-arch-canvas-expand/delivery.json +9 -0
- package/.duaer/specs/155-arch-canvas-expand/spec.md +14 -0
- package/.duaer/specs/155-arch-canvas-expand/tasks.md +5 -0
- package/.duaer/specs/156-arch-inline-mount/delivery.json +13 -0
- package/.duaer/specs/156-arch-inline-mount/spec.md +17 -0
- package/.duaer/specs/156-arch-inline-mount/tasks.md +5 -0
- package/.duaer/specs/157-arch-mount-fx/delivery.json +12 -0
- package/.duaer/specs/157-arch-mount-fx/spec.md +15 -0
- package/.duaer/specs/157-arch-mount-fx/tasks.md +5 -0
- package/.duaer/specs/158-arch-click-fx/delivery.json +13 -0
- package/.duaer/specs/158-arch-click-fx/spec.md +13 -0
- package/.duaer/specs/158-arch-click-fx/tasks.md +5 -0
- package/.duaer/specs/159-arch-auto-height/delivery.json +12 -0
- package/.duaer/specs/159-arch-auto-height/spec.md +14 -0
- package/.duaer/specs/159-arch-auto-height/tasks.md +4 -0
- package/.duaer/specs/160-preview-deploy-btn/delivery.json +12 -0
- package/.duaer/specs/160-preview-deploy-btn/spec.md +15 -0
- package/.duaer/specs/160-preview-deploy-btn/tasks.md +5 -0
- package/.duaer/specs/161-deploy-picker/delivery.json +12 -0
- package/.duaer/specs/161-deploy-picker/spec.md +13 -0
- package/.duaer/specs/161-deploy-picker/tasks.md +5 -0
- package/.duaer/specs/162-intro-pages/delivery.json +14 -0
- package/.duaer/specs/162-intro-pages/spec.md +23 -0
- package/.duaer/specs/162-intro-pages/tasks.md +5 -0
- package/.duaer/specs/163-intro-grand/delivery.json +14 -0
- package/.duaer/specs/163-intro-grand/spec.md +22 -0
- package/.duaer/specs/163-intro-grand/tasks.md +4 -0
- package/.duaer/specs/164-intro-layout/delivery.json +13 -0
- package/.duaer/specs/164-intro-layout/spec.md +11 -0
- package/.duaer/specs/164-intro-layout/tasks.md +4 -0
- package/.duaer/specs/165-aliyun-settings/delivery.json +13 -0
- package/.duaer/specs/165-aliyun-settings/spec.md +24 -0
- package/.duaer/specs/165-aliyun-settings/tasks.md +5 -0
- package/.duaer/specs/166-cloud-aws-settings/delivery.json +13 -0
- package/.duaer/specs/166-cloud-aws-settings/spec.md +18 -0
- package/.duaer/specs/166-cloud-aws-settings/tasks.md +5 -0
- package/.duaer/specs/167-settings-compact/delivery.json +9 -0
- package/.duaer/specs/167-settings-compact/spec.md +11 -0
- package/.duaer/specs/167-settings-compact/tasks.md +4 -0
- package/.duaer/specs/168-rename-fde/delivery.json +15 -0
- package/.duaer/specs/168-rename-fde/spec.md +22 -0
- package/.duaer/specs/168-rename-fde/tasks.md +4 -0
- package/.duaer/specs/169-modular-fde-confirm/delivery.json +9 -0
- package/.duaer/specs/169-modular-fde-confirm/spec.md +36 -0
- package/.duaer/specs/169-modular-fde-confirm/tasks.md +7 -0
- package/.duaer/specs/170-readme-on-delivery/delivery.json +9 -0
- package/.duaer/specs/170-readme-on-delivery/spec.md +30 -0
- package/.duaer/specs/170-readme-on-delivery/tasks.md +4 -0
- package/.duaer/specs/171-chat-markdown/delivery.json +8 -0
- package/.duaer/specs/171-chat-markdown/spec.md +11 -0
- package/.duaer/specs/171-chat-markdown/tasks.md +3 -0
- package/.duaer/specs/172-module-tab-active/delivery.json +1 -0
- package/.duaer/specs/172-module-tab-active/spec.md +10 -0
- package/.duaer/specs/172-module-tab-active/tasks.md +2 -0
- package/.duaer/specs/173-parallel-terminal-lanes/delivery.json +5 -0
- package/.duaer/specs/173-parallel-terminal-lanes/spec.md +12 -0
- package/.duaer/specs/173-parallel-terminal-lanes/tasks.md +3 -0
- package/.duaer/specs/174-docs-fde-flow-sync/delivery.json +5 -0
- package/.duaer/specs/174-docs-fde-flow-sync/spec.md +29 -0
- package/.duaer/specs/174-docs-fde-flow-sync/tasks.md +7 -0
- package/.duaer/specs/175-confirm-btn-state/delivery.json +5 -0
- package/.duaer/specs/175-confirm-btn-state/spec.md +22 -0
- package/.duaer/specs/175-confirm-btn-state/tasks.md +6 -0
- package/.duaer/specs/176-deliverables-page/delivery.json +5 -0
- package/.duaer/specs/176-deliverables-page/spec.md +31 -0
- package/.duaer/specs/176-deliverables-page/tasks.md +6 -0
- package/.duaer/specs/177-deliverables-client-look/delivery.json +5 -0
- package/.duaer/specs/177-deliverables-client-look/spec.md +13 -0
- package/.duaer/specs/177-deliverables-client-look/tasks.md +4 -0
- package/.duaer/specs/178-arch-panel-visible/delivery.json +5 -0
- package/.duaer/specs/178-arch-panel-visible/spec.md +22 -0
- package/.duaer/specs/178-arch-panel-visible/tasks.md +6 -0
- package/.duaer/specs/179-arch-layout-hang/delivery.json +5 -0
- package/.duaer/specs/179-arch-layout-hang/spec.md +17 -0
- package/.duaer/specs/179-arch-layout-hang/tasks.md +5 -0
- package/.duaer/specs/180-deliverables-structure/delivery.json +8 -0
- package/.duaer/specs/180-deliverables-structure/spec.md +16 -0
- package/.duaer/specs/180-deliverables-structure/tasks.md +8 -0
- package/.duaer/specs/181-multi-worker-progress/delivery.json +11 -0
- package/.duaer/specs/181-multi-worker-progress/spec.md +15 -0
- package/.duaer/specs/181-multi-worker-progress/tasks.md +7 -0
- package/.duaer/specs/182-task-orchestrate/delivery.json +11 -0
- package/.duaer/specs/182-task-orchestrate/spec.md +14 -0
- package/.duaer/specs/182-task-orchestrate/tasks.md +8 -0
- package/.duaer/specs/183-deliverables-structure-v2/delivery.json +8 -0
- package/.duaer/specs/183-deliverables-structure-v2/spec.md +16 -0
- package/.duaer/specs/183-deliverables-structure-v2/tasks.md +6 -0
- package/.duaer/specs/184-deliverables-layout/delivery.json +8 -0
- package/.duaer/specs/184-deliverables-layout/spec.md +14 -0
- package/.duaer/specs/184-deliverables-layout/tasks.md +5 -0
- package/.duaer/specs/185-req-card-structure/delivery.json +10 -0
- package/.duaer/specs/185-req-card-structure/spec.md +26 -0
- package/.duaer/specs/185-req-card-structure/tasks.md +8 -0
- package/.duaer/specs/186-req-edit-wipe/delivery.json +9 -0
- package/.duaer/specs/186-req-edit-wipe/spec.md +16 -0
- package/.duaer/specs/186-req-edit-wipe/tasks.md +6 -0
- package/.duaer/specs/187-req-card-modules/delivery.json +9 -0
- package/.duaer/specs/187-req-card-modules/spec.md +28 -0
- package/.duaer/specs/187-req-card-modules/tasks.md +7 -0
- package/.duaer/specs/188-release-019/delivery.json +18 -0
- package/.duaer/specs/188-release-019/spec.md +12 -0
- package/.duaer/specs/188-release-019/tasks.md +6 -0
- package/.duaer/specs/189-fde-portfolio/delivery.json +10 -0
- package/.duaer/specs/189-fde-portfolio/spec.md +29 -0
- package/.duaer/specs/189-fde-portfolio/tasks.md +8 -0
- package/.duaer/specs/190-live-open-no-model/delivery.json +9 -0
- package/.duaer/specs/190-live-open-no-model/spec.md +17 -0
- package/.duaer/specs/190-live-open-no-model/tasks.md +6 -0
- package/.duaer/specs/191-projects-root-pick/delivery.json +11 -0
- package/.duaer/specs/191-projects-root-pick/spec.md +14 -0
- package/.duaer/specs/191-projects-root-pick/tasks.md +6 -0
- package/.duaer/specs/192-release-020/spec.md +12 -0
- package/.duaer/specs/192-release-020/tasks.md +6 -0
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +199 -0
- package/README.md +49 -20
- package/README.zh-CN.md +26 -18
- package/bin/duaer-live.mjs +1436 -227
- package/bin/duaer.mjs +1 -1
- package/bin/live-archify.mjs +46 -25
- package/bin/live-claude-trust.mjs +3 -3
- package/bin/live-deliverables.mjs +1236 -0
- package/bin/live-modules.mjs +400 -0
- package/bin/live-orchestrate.mjs +207 -0
- package/bin/live-progress.mjs +165 -1
- package/bin/live-project-chat.mjs +51 -2
- package/bin/live-projects.mjs +34 -1
- package/docs/agent/README.md +1 -0
- package/docs/agent/deploy-targets.md +18 -0
- package/docs/agent/e2e-test-plan.md +77 -5
- package/docs/agent/live-desk.md +111 -0
- package/docs/agent/worker-models.md +14 -10
- package/docs/agent/worker-models.zh-CN.md +13 -11
- package/docs/assets/duaer-spec-fde.svg +33 -0
- package/package.json +2 -1
- package/web/live-dev/app.js +1879 -325
- package/web/live-dev/architecture-ir.mjs +18 -11
- package/web/live-dev/architecture-mount.mjs +428 -0
- package/web/live-dev/chat-markdown.mjs +55 -0
- package/web/live-dev/delivery-status.mjs +135 -0
- package/web/live-dev/i18n.js +283 -50
- package/web/live-dev/index.html +238 -79
- package/web/live-dev/structured-html.mjs +121 -29
- 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 /
|
|
14
|
-
**Duaer** brand (or **Duaer-spec
|
|
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 /
|
|
17
|
-
**Duaer** brand (or **Duaer-spec
|
|
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”
|
package/.duaer/active-job.json
CHANGED
package/.duaer/handoff.json
CHANGED
|
@@ -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
|
|
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
|
|
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
|
}
|
package/.duaer/memory/testing.md
CHANGED
|
@@ -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
|
|
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
|
+
}
|
|
@@ -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,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,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,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,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,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,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,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,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,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,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,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,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,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,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
|
+
}
|