duaer-spec 0.17.0 → 0.18.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 +11 -1
- package/.cursor/rules/ai-ui-copy.mdc +11 -1
- package/.duaer/active-job.json +1 -6
- package/.duaer/handoff.json +5 -3
- package/.duaer/specs/087-release-017/delivery.json +9 -0
- package/.duaer/specs/088-result-versions/delivery.json +14 -0
- package/.duaer/specs/088-result-versions/spec.md +37 -0
- package/.duaer/specs/088-result-versions/tasks.md +8 -0
- package/.duaer/specs/089-deploy-target-tasks/delivery.json +13 -0
- package/.duaer/specs/089-deploy-target-tasks/spec.md +28 -0
- package/.duaer/specs/089-deploy-target-tasks/tasks.md +9 -0
- package/.duaer/specs/090-project-first/delivery.json +13 -0
- package/.duaer/specs/090-project-first/spec.md +41 -0
- package/.duaer/specs/090-project-first/tasks.md +7 -0
- package/.duaer/specs/091-project-meta/delivery.json +13 -0
- package/.duaer/specs/091-project-meta/spec.md +35 -0
- package/.duaer/specs/091-project-meta/tasks.md +6 -0
- package/.duaer/specs/092-project-chat-gate/delivery.json +9 -0
- package/.duaer/specs/092-project-chat-gate/spec.md +17 -0
- package/.duaer/specs/092-project-chat-gate/tasks.md +4 -0
- package/.duaer/specs/093-project-auto-chat/delivery.json +9 -0
- package/.duaer/specs/093-project-auto-chat/spec.md +16 -0
- package/.duaer/specs/093-project-auto-chat/tasks.md +4 -0
- package/.duaer/specs/094-dispatch-project-simple/delivery.json +9 -0
- package/.duaer/specs/094-dispatch-project-simple/spec.md +17 -0
- package/.duaer/specs/094-dispatch-project-simple/tasks.md +4 -0
- package/.duaer/specs/095-project-chat-persist/delivery.json +9 -0
- package/.duaer/specs/095-project-chat-persist/spec.md +17 -0
- package/.duaer/specs/095-project-chat-persist/tasks.md +5 -0
- package/.duaer/specs/096-project-card-persist/delivery.json +15 -0
- package/.duaer/specs/096-project-card-persist/spec.md +25 -0
- package/.duaer/specs/096-project-card-persist/tasks.md +9 -0
- package/.duaer/specs/097-validate-persist/delivery.json +15 -0
- package/.duaer/specs/097-validate-persist/spec.md +24 -0
- package/.duaer/specs/097-validate-persist/tasks.md +7 -0
- package/.duaer/specs/098-req-structured-edit/delivery.json +14 -0
- package/.duaer/specs/098-req-structured-edit/spec.md +18 -0
- package/.duaer/specs/098-req-structured-edit/tasks.md +7 -0
- package/.duaer/specs/099-setup-cli-guide/delivery.json +14 -0
- package/.duaer/specs/099-setup-cli-guide/spec.md +19 -0
- package/.duaer/specs/099-setup-cli-guide/tasks.md +7 -0
- package/.duaer/specs/100-architecture-archify/delivery.json +16 -0
- package/.duaer/specs/100-architecture-archify/spec.md +39 -0
- package/.duaer/specs/100-architecture-archify/tasks.md +8 -0
- package/.duaer/specs/101-archify-ir-sanitize/delivery.json +11 -0
- package/.duaer/specs/101-archify-ir-sanitize/spec.md +22 -0
- package/.duaer/specs/101-archify-ir-sanitize/tasks.md +5 -0
- package/.duaer/specs/102-archify-brand-duaer/delivery.json +5 -0
- package/.duaer/specs/102-archify-brand-duaer/spec.md +9 -0
- package/.duaer/specs/103-arch-chat-kickoff/delivery.json +11 -0
- package/.duaer/specs/103-arch-chat-kickoff/spec.md +13 -0
- package/.duaer/specs/103-arch-chat-kickoff/tasks.md +5 -0
- package/.duaer/specs/104-settings-modal/delivery.json +8 -0
- package/.duaer/specs/104-settings-modal/spec.md +14 -0
- package/.duaer/specs/104-settings-modal/tasks.md +5 -0
- package/.duaer/specs/105-arch-chat-continue/delivery.json +11 -0
- package/.duaer/specs/105-arch-chat-continue/spec.md +12 -0
- package/.duaer/specs/105-arch-chat-continue/tasks.md +5 -0
- package/.duaer/specs/106-arch-hint-copy/delivery.json +5 -0
- package/.duaer/specs/106-arch-hint-copy/spec.md +9 -0
- package/.duaer/specs/107-arch-frame-layout/delivery.json +8 -0
- package/.duaer/specs/107-arch-frame-layout/spec.md +12 -0
- package/.duaer/specs/107-arch-frame-layout/tasks.md +5 -0
- package/.duaer/specs/108-arch-no-chrome/delivery.json +8 -0
- package/.duaer/specs/108-arch-no-chrome/spec.md +11 -0
- package/.duaer/specs/109-arch-layout-repair/delivery.json +8 -0
- package/.duaer/specs/109-arch-layout-repair/spec.md +12 -0
- package/.duaer/specs/109-arch-layout-repair/tasks.md +5 -0
- package/.duaer/specs/110-arch-ready-copy/delivery.json +10 -0
- package/.duaer/specs/110-arch-ready-copy/spec.md +12 -0
- package/.duaer/specs/110-arch-ready-copy/tasks.md +7 -0
- package/.duaer/specs/111-arch-confirm-click/delivery.json +10 -0
- package/.duaer/specs/111-arch-confirm-click/spec.md +18 -0
- package/.duaer/specs/111-arch-confirm-click/tasks.md +5 -0
- package/.duaer/specs/112-duaer-brand-copy/delivery.json +10 -0
- package/.duaer/specs/112-duaer-brand-copy/spec.md +27 -0
- package/.duaer/specs/112-duaer-brand-copy/tasks.md +5 -0
- package/.duaer/specs/113-arch-diagram-height/delivery.json +10 -0
- package/.duaer/specs/113-arch-diagram-height/spec.md +14 -0
- package/.duaer/specs/113-arch-diagram-height/tasks.md +5 -0
- package/.duaer/specs/114-guide-doc-github/delivery.json +10 -0
- package/.duaer/specs/114-guide-doc-github/spec.md +15 -0
- package/.duaer/specs/114-guide-doc-github/tasks.md +5 -0
- package/.duaer/specs/115-panel-scroll-hold/delivery.json +10 -0
- package/.duaer/specs/115-panel-scroll-hold/spec.md +19 -0
- package/.duaer/specs/115-panel-scroll-hold/tasks.md +5 -0
- package/.duaer/specs/116-arch-node-zoom/delivery.json +10 -0
- package/.duaer/specs/116-arch-node-zoom/spec.md +18 -0
- package/.duaer/specs/116-arch-node-zoom/tasks.md +5 -0
- package/.duaer/specs/117-dispatch-done-state/delivery.json +14 -0
- package/.duaer/specs/117-dispatch-done-state/spec.md +30 -0
- package/.duaer/specs/117-dispatch-done-state/tasks.md +6 -0
- package/.duaer/specs/118-preview-result-visible/delivery.json +14 -0
- package/.duaer/specs/118-preview-result-visible/spec.md +30 -0
- package/.duaer/specs/118-preview-result-visible/tasks.md +5 -0
- package/.duaer/specs/119-arch-revise-keep/delivery.json +14 -0
- package/.duaer/specs/119-arch-revise-keep/spec.md +34 -0
- package/.duaer/specs/119-arch-revise-keep/tasks.md +5 -0
- package/.duaer/specs/120-preview-required/delivery.json +14 -0
- package/.duaer/specs/120-preview-required/spec.md +31 -0
- package/.duaer/specs/120-preview-required/tasks.md +5 -0
- package/.duaer/specs/121-preview-start-service/delivery.json +15 -0
- package/.duaer/specs/121-preview-start-service/spec.md +26 -0
- package/.duaer/specs/121-preview-start-service/tasks.md +5 -0
- package/.duaer/specs/122-revise-chat-persist/delivery.json +13 -0
- package/.duaer/specs/122-revise-chat-persist/spec.md +18 -0
- package/.duaer/specs/122-revise-chat-persist/tasks.md +5 -0
- package/.duaer/specs/123-remove-beginner-slogan/delivery.json +9 -0
- package/.duaer/specs/123-remove-beginner-slogan/spec.md +26 -0
- package/.duaer/specs/123-remove-beginner-slogan/tasks.md +6 -0
- package/.duaer/specs/124-header-github-stars/delivery.json +9 -0
- package/.duaer/specs/124-header-github-stars/spec.md +31 -0
- package/.duaer/specs/124-header-github-stars/tasks.md +6 -0
- package/.duaer/specs/125-result-service-status/delivery.json +10 -0
- package/.duaer/specs/125-result-service-status/spec.md +32 -0
- package/.duaer/specs/125-result-service-status/tasks.md +5 -0
- package/.duaer/specs/126-new-project-full-reset/delivery.json +10 -0
- package/.duaer/specs/126-new-project-full-reset/spec.md +30 -0
- package/.duaer/specs/126-new-project-full-reset/tasks.md +4 -0
- package/.duaer/specs/127-progress-text-overflow/delivery.json +8 -0
- package/.duaer/specs/127-progress-text-overflow/spec.md +12 -0
- package/.duaer/specs/127-progress-text-overflow/tasks.md +4 -0
- package/.duaer/specs/128-claude-trust-dialog/delivery.json +9 -0
- package/.duaer/specs/128-claude-trust-dialog/spec.md +31 -0
- package/.duaer/specs/128-claude-trust-dialog/tasks.md +5 -0
- package/.duaer/specs/129-result-one-line/delivery.json +8 -0
- package/.duaer/specs/129-result-one-line/spec.md +14 -0
- package/.duaer/specs/129-result-one-line/tasks.md +4 -0
- package/.duaer/specs/130-result-bar-layout/delivery.json +8 -0
- package/.duaer/specs/130-result-bar-layout/spec.md +13 -0
- package/.duaer/specs/130-result-bar-layout/tasks.md +5 -0
- package/.duaer/specs/131-revise-card-versions/delivery.json +9 -0
- package/.duaer/specs/131-revise-card-versions/spec.md +27 -0
- package/.duaer/specs/131-revise-card-versions/tasks.md +7 -0
- package/.duaer/specs/132-revise-arch-after-plan/delivery.json +9 -0
- package/.duaer/specs/132-revise-arch-after-plan/spec.md +29 -0
- package/.duaer/specs/132-revise-arch-after-plan/tasks.md +7 -0
- package/.duaer/specs/133-button-styles/delivery.json +5 -0
- package/.duaer/specs/133-button-styles/spec.md +14 -0
- package/.duaer/specs/133-button-styles/tasks.md +6 -0
- package/.duaer/specs/134-revise-version-expand/delivery.json +9 -0
- package/.duaer/specs/134-revise-version-expand/spec.md +21 -0
- package/.duaer/specs/134-revise-version-expand/tasks.md +6 -0
- package/.duaer/specs/135-revise-chat-visible/delivery.json +5 -0
- package/.duaer/specs/135-revise-chat-visible/spec.md +13 -0
- package/.duaer/specs/135-revise-chat-visible/tasks.md +3 -0
- package/.duaer/specs/136-revise-click/delivery.json +1 -0
- package/.duaer/specs/136-revise-click/spec.md +16 -0
- package/.duaer/specs/136-revise-click/tasks.md +5 -0
- package/.duaer/specs/137-btn-chrome/delivery.json +11 -0
- package/.duaer/specs/137-btn-chrome/spec.md +11 -0
- package/.duaer/specs/137-btn-chrome/tasks.md +5 -0
- package/.duaer/specs/138-revise-send-msg/delivery.json +11 -0
- package/.duaer/specs/138-revise-send-msg/spec.md +18 -0
- package/.duaer/specs/138-revise-send-msg/tasks.md +5 -0
- package/.duaer/specs/139-revise-first-click/delivery.json +11 -0
- package/.duaer/specs/139-revise-first-click/spec.md +22 -0
- package/.duaer/specs/139-revise-first-click/tasks.md +6 -0
- package/.duaer/specs/140-revise-kickoff-stack/delivery.json +11 -0
- package/.duaer/specs/140-revise-kickoff-stack/spec.md +19 -0
- package/.duaer/specs/140-revise-kickoff-stack/tasks.md +6 -0
- package/.duaer/specs/141-revise-stack-2/delivery.json +11 -0
- package/.duaer/specs/141-revise-stack-2/spec.md +19 -0
- package/.duaer/specs/141-revise-stack-2/tasks.md +6 -0
- package/.duaer/specs/142-arch-node-popup/delivery.json +11 -0
- package/.duaer/specs/142-arch-node-popup/spec.md +18 -0
- package/.duaer/specs/142-arch-node-popup/tasks.md +4 -0
- package/.duaer/specs/143-arch-popup-upgrade/delivery.json +10 -0
- package/.duaer/specs/143-arch-popup-upgrade/spec.md +12 -0
- package/.duaer/specs/143-arch-popup-upgrade/tasks.md +4 -0
- package/.duaer/specs/144-arch-popup-offset/delivery.json +10 -0
- package/.duaer/specs/144-arch-popup-offset/spec.md +11 -0
- package/.duaer/specs/144-arch-popup-offset/tasks.md +4 -0
- package/.duaer/specs/145-arch-popup-visible/delivery.json +10 -0
- package/.duaer/specs/145-arch-popup-visible/spec.md +13 -0
- package/.duaer/specs/145-arch-popup-visible/tasks.md +4 -0
- package/.duaer/specs/146-arch-popup-gutter/delivery.json +10 -0
- package/.duaer/specs/146-arch-popup-gutter/spec.md +17 -0
- package/.duaer/specs/146-arch-popup-gutter/tasks.md +4 -0
- package/.duaer/specs/147-arch-expand-noscroll/delivery.json +10 -0
- package/.duaer/specs/147-arch-expand-noscroll/spec.md +14 -0
- package/.duaer/specs/147-arch-expand-noscroll/tasks.md +5 -0
- package/.duaer/specs/148-release-018/spec.md +12 -0
- package/.duaer/specs/148-release-018/tasks.md +4 -0
- package/AGENTS.md +15 -4
- package/CHANGELOG.md +123 -0
- package/README.md +12 -4
- package/README.zh-CN.md +8 -4
- package/bin/deploy-targets.mjs +148 -0
- package/bin/duaer-live.mjs +1064 -144
- package/bin/duaer.mjs +13 -2
- package/bin/live-archify.mjs +808 -0
- package/bin/live-claude-trust.mjs +111 -0
- package/bin/live-preview.mjs +362 -0
- package/bin/live-progress.mjs +34 -20
- package/bin/live-project-chat.mjs +319 -0
- package/bin/live-projects.mjs +113 -0
- package/bin/update-check.mjs +1 -1
- package/docs/agent/README.md +1 -0
- package/docs/agent/deploy-github.md +1 -1
- package/docs/agent/deploy-targets.md +81 -0
- package/docs/agent/e2e-test-plan.md +82 -6
- package/docs/agent/worker-models.md +49 -16
- package/docs/agent/worker-models.zh-CN.md +45 -14
- package/package.json +1 -1
- package/web/live-dev/app.js +3289 -361
- package/web/live-dev/architecture-ir.mjs +170 -0
- package/web/live-dev/i18n.js +321 -68
- package/web/live-dev/index.html +203 -66
- package/web/live-dev/structured-html.mjs +100 -17
- package/web/live-dev/styles.css +788 -55
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<!--
|
|
1
|
+
<!-- Desk UI copy — minimal + Duaer brand (duaer-spec agent ops) -->
|
|
2
2
|
|
|
3
3
|
# AI-generated page content
|
|
4
4
|
|
|
@@ -7,3 +7,13 @@ AI-generated pages must not contain redundant explanatory text.
|
|
|
7
7
|
- No filler introductions, repeated summaries, or prose that only explains an obvious control
|
|
8
8
|
- Prefer concise labels, headings, helper text, and empty states
|
|
9
9
|
- Put rationale and implementation detail in docs or code comments, not in the UI, unless the user asks for explanatory content
|
|
10
|
+
|
|
11
|
+
## Duaer brand (site-wide)
|
|
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).
|
|
15
|
+
|
|
16
|
+
- Do not write anonymous「台面」/ “desk” alone when referring to this product’s
|
|
17
|
+
chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk”
|
|
18
|
+
- Keep helper text short; branding is a name signal, not a slogan paragraph
|
|
19
|
+
- Applies to i18n strings, HTML fallbacks, empty states, and setup/settings copy
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description:
|
|
2
|
+
description: Desk UI copy — minimal + Duaer brand (duaer-spec agent ops)
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
@@ -10,3 +10,13 @@ AI-generated pages must not contain redundant explanatory text.
|
|
|
10
10
|
- No filler introductions, repeated summaries, or prose that only explains an obvious control
|
|
11
11
|
- Prefer concise labels, headings, helper text, and empty states
|
|
12
12
|
- Put rationale and implementation detail in docs or code comments, not in the UI, unless the user asks for explanatory content
|
|
13
|
+
|
|
14
|
+
## Duaer brand (site-wide)
|
|
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).
|
|
18
|
+
|
|
19
|
+
- Do not write anonymous「台面」/ “desk” alone when referring to this product’s
|
|
20
|
+
chat surface or model setup — prefer「Duaer 台面」/ “Duaer desk”
|
|
21
|
+
- Keep helper text short; branding is a name signal, not a slogan paragraph
|
|
22
|
+
- Applies to i18n strings, HTML fallbacks, empty states, and setup/settings copy
|
package/.duaer/active-job.json
CHANGED
package/.duaer/handoff.json
CHANGED
|
@@ -1,9 +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).",
|
|
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.",
|
|
5
5
|
"restartFromPrimary": true,
|
|
6
|
-
"commands": [
|
|
6
|
+
"commands": [
|
|
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
|
+
]
|
|
7
9
|
},
|
|
8
|
-
"notes": "After
|
|
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."
|
|
9
11
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "accepted",
|
|
3
|
+
"acceptedAt": "2026-09-18T01:10:00.000Z",
|
|
4
|
+
"verification": {
|
|
5
|
+
"levels": ["L0", "L1", "L3"],
|
|
6
|
+
"commands": [
|
|
7
|
+
"node --check bin/duaer-live.mjs",
|
|
8
|
+
"node --check web/live-dev/app.js",
|
|
9
|
+
"npm test",
|
|
10
|
+
"npm run test:live"
|
|
11
|
+
],
|
|
12
|
+
"result": "pass"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Feature Specification: Result versions follow progress
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/result-versions`
|
|
4
|
+
**Brief**: `.duaer/specs/088-result-versions/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Live desk「查看结果」tracks each accepted dispatch/revision as its own
|
|
10
|
+
previewable version, with a unified version list. Drop dead links after
|
|
11
|
+
worktree cleanup. Clear stuck「续派中」when the job is finished.
|
|
12
|
+
|
|
13
|
+
## In scope
|
|
14
|
+
|
|
15
|
+
1. Rename CTA / labels: 查看成品 → 查看结果 (EN: View result)
|
|
16
|
+
2. On each delivery accept (初版 + each revision), record a result version
|
|
17
|
+
3. Unified UI to open any still-previewable version
|
|
18
|
+
4. Persist previewable snapshots under the live job so artifacts survive
|
|
19
|
+
worktree removal; prune entries that cannot be opened
|
|
20
|
+
5. Fix status/UI stuck on revising /「续派中」after delivery accepted and
|
|
21
|
+
work finished (or worktree already cleaned)
|
|
22
|
+
|
|
23
|
+
## Out of scope
|
|
24
|
+
|
|
25
|
+
- Full site asset bundling beyond the preview entry file
|
|
26
|
+
- Changing Terminal queue semantics beyond status inference
|
|
27
|
+
|
|
28
|
+
## Acceptance
|
|
29
|
+
|
|
30
|
+
1. i18n + HTML use「查看结果」/ View result
|
|
31
|
+
2. `/api/status` returns `results[]` of previewable versions; grows with
|
|
32
|
+
each accept; non-previewable entries omitted after worktree gone
|
|
33
|
+
3. Preview panel lists versions; latest opens via primary CTA
|
|
34
|
+
4. When delivery accepted and worktree gone (or no open revise work),
|
|
35
|
+
status is `accepted` — not stuck `revising`; client clears
|
|
36
|
+
`reviseDispatching`
|
|
37
|
+
5. L0 + L1 + `npm run test:live`; E2E catalog updated
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Tasks: 088-result-versions
|
|
2
|
+
|
|
3
|
+
- [x] T001 Spec + active-job
|
|
4
|
+
- [x] T002 Server: result versions + prune + activelyRevising fix
|
|
5
|
+
- [x] T003 Client: 查看结果 + version list + clear 续派中
|
|
6
|
+
- [x] T004 i18n / HTML / CSS
|
|
7
|
+
- [x] T005 Tests + E2E catalog + CHANGELOG
|
|
8
|
+
- [x] T006 Verify L0/L1/L3; stamp delivery
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Feature Specification: Deploy target choice + fine tasks + self-update bootstrap
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/deploy-target-tasks`
|
|
4
|
+
**Brief**: `.duaer/specs/089-deploy-target-tasks/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
1. Global CLI users on old builds can upgrade: `self-update` works on current
|
|
10
|
+
package; banners tell people to run `npm i -g duaer-spec@latest` when the
|
|
11
|
+
installed CLI lacks the command.
|
|
12
|
+
2. On live dispatch, choose planned hosting: Cloudflare / 阿里云 / AWS /
|
|
13
|
+
GitHub Pages / none. Code and agent prompts follow that platform’s rules
|
|
14
|
+
(Cloudflare: Workers/Pages constraints documented).
|
|
15
|
+
3. Drop hard task-count caps (no max 12). Split into single-function,
|
|
16
|
+
independently acceptable tasks; do not couple acceptance into one mega-task.
|
|
17
|
+
|
|
18
|
+
## Acceptance
|
|
19
|
+
|
|
20
|
+
1. `duaer self-update` / `upgrade` run npm global install; unknown-command and
|
|
21
|
+
update hints show `npm i -g duaer-spec@latest` bootstrap
|
|
22
|
+
2. Dispatch UI has deploy-target control; `/api/dispatch` persists target;
|
|
23
|
+
agent prompt + Spec notes reference the chosen platform doc
|
|
24
|
+
3. Cloudflare choice adds Workers/Pages coding constraints in prompt +
|
|
25
|
+
`docs/agent/deploy-targets.md`
|
|
26
|
+
4. `buildDetailedProductTasksMd` / revision builders do not slice acceptance
|
|
27
|
+
to 6/4; prompts say split finely with no upper count
|
|
28
|
+
5. Tests + E2E + CHANGELOG; `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Tasks: 089-deploy-target-tasks
|
|
2
|
+
|
|
3
|
+
- [x] T001 Brief + active-job
|
|
4
|
+
- [x] T002 self-update bootstrap + aliases + hint copy
|
|
5
|
+
- [x] T003 deploy-targets module + docs (Cloudflare/阿里云/AWS/Pages)
|
|
6
|
+
- [x] T004 live dispatch API + agent prompts
|
|
7
|
+
- [x] T005 desk UI + i18n for deploy target
|
|
8
|
+
- [x] T006 fine-grained tasks (remove caps) + prompts
|
|
9
|
+
- [x] T007 tests / E2E / CHANGELOG / verify / stamp
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Feature Specification: Project-first desk (no SQLite)
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/project-first`
|
|
4
|
+
**Brief**: `.duaer/specs/090-project-first/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Duaer-spec FED is **project-first**: the human must select or create a product
|
|
10
|
+
project before chatting. Conversations (former flat「历史」) hang under that
|
|
11
|
+
project. Top bar label is「项目」. Storage stays file-based (`~/.duaer/live/`);
|
|
12
|
+
no SQLite in this job.
|
|
13
|
+
|
|
14
|
+
## In scope
|
|
15
|
+
|
|
16
|
+
- Persist `activeProjectPath` (+ keep `projectsRoot`) in live config
|
|
17
|
+
- Top bar「历史」→「项目」; drawer: create/select project, then conversations
|
|
18
|
+
- Gate chat / composer until a project is active
|
|
19
|
+
- Stamp project path on confirm; dispatch defaults to active project
|
|
20
|
+
- Move「产品父目录」into the project create block (out of mid-dispatch clutter)
|
|
21
|
+
- Group jobs by `repoPath` under each project
|
|
22
|
+
- Tests, E2E catalog, CHANGELOG
|
|
23
|
+
|
|
24
|
+
## Out of scope
|
|
25
|
+
|
|
26
|
+
- SQLite / `desk.db`
|
|
27
|
+
- Cloud sync; multi-user
|
|
28
|
+
- Renaming CSS class names wholesale (`history-*` may remain as hooks)
|
|
29
|
+
|
|
30
|
+
## Acceptance
|
|
31
|
+
|
|
32
|
+
1. Without active project: Send disabled; bot/empty state tells user to open「项目」
|
|
33
|
+
2. Create project (parent + name) or browse/select sets active project and unlocks chat
|
|
34
|
+
3. Drawer lists projects; under active/selected project, jobs for that path; restore works
|
|
35
|
+
4. Confirm/dispatch uses active project path (no need to re-pick unless changed)
|
|
36
|
+
5. `npm test` + `npm run test:live` pass
|
|
37
|
+
|
|
38
|
+
## Assumptions
|
|
39
|
+
|
|
40
|
+
- Worktree: `.worktree/feat-project-first`
|
|
41
|
+
- User confirmed: must select/create first; top bar「项目」; SQLite deferred
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Tasks: 090-project-first
|
|
2
|
+
|
|
3
|
+
- [x] T001 Brief + active-job
|
|
4
|
+
- [x] T002 Config + API: activeProjectPath, GET/POST projects, confirm stamp
|
|
5
|
+
- [x] T003 Desk UI: 项目 drawer, create block, chat gate, dispatch default
|
|
6
|
+
- [x] T004 i18n EN/ZH + empty-state copy
|
|
7
|
+
- [x] T005 Tests / E2E / CHANGELOG / verify / stamp
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Feature Specification: Project name + background
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/project-meta`
|
|
4
|
+
**Brief**: `.duaer/specs/091-project-meta/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
When creating/opening a product project on the FED desk, the human must enter a
|
|
10
|
+
**display name** and a short **background** description (not only a folder path).
|
|
11
|
+
These persist with the project and show in the project list.
|
|
12
|
+
|
|
13
|
+
## In scope
|
|
14
|
+
|
|
15
|
+
- Persist `title` (display name) + `description` on remembered projects (`repos.json`)
|
|
16
|
+
- Create form: folder path/name + 项目名称 + 背景描述
|
|
17
|
+
- List / active line show title; description as secondary line
|
|
18
|
+
- Activate API accepts and saves title/description
|
|
19
|
+
- Tests + E2E note + CHANGELOG
|
|
20
|
+
|
|
21
|
+
## Out of scope
|
|
22
|
+
|
|
23
|
+
- SQLite; editing history of descriptions; LLM-generated backgrounds
|
|
24
|
+
|
|
25
|
+
## Acceptance
|
|
26
|
+
|
|
27
|
+
1. Create/activate requires a non-empty project title
|
|
28
|
+
2. Background description is saved and shown on the project row (may be empty only if user left blank — prefer prompting a short line)
|
|
29
|
+
3. Folder path still works as before (parent + short name or absolute path)
|
|
30
|
+
4. `npm test` + `npm run test:live` pass
|
|
31
|
+
|
|
32
|
+
## Assumptions
|
|
33
|
+
|
|
34
|
+
- Require **title**; description optional but UI labels it clearly as「背景描述」
|
|
35
|
+
- Worktree: `.worktree/feat-project-meta`
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Feature Specification: Harden project-before-chat gate
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `fix/project-chat-gate`
|
|
4
|
+
**Brief**: `.duaer/specs/092-project-chat-gate/`
|
|
5
|
+
**Status**: Active
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Chat must stay locked until a current project is selected/created. Make the
|
|
10
|
+
gate impossible to bypass and show the active project (or「未选项目」) in the UI.
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
1. Composer starts disabled; Send / Enter / chips call sendChat which refuses without project
|
|
15
|
+
2. Header shows current project title or「未选项目」
|
|
16
|
+
3. `/api/chat` still returns NEED_PROJECT when config has no activeProjectPath
|
|
17
|
+
4. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Feature Specification: Auto-start chat after project select
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/project-auto-chat`
|
|
4
|
+
**Brief**: `.duaer/specs/093-project-auto-chat/`
|
|
5
|
+
**Status**: Active
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
After the human selects or creates the current project, the desk immediately
|
|
10
|
+
starts the requirements dialogue (LLM chat kickoff) — no extra Send needed.
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
1. Successful「选为当前项目」/ list select closes the drawer and calls chat with a kickoff that includes project name + background
|
|
15
|
+
2. Composer is unlocked; conversation bubble appears
|
|
16
|
+
3. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Feature Specification: Simplify dispatch when project already set
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/dispatch-project-simple`
|
|
4
|
+
**Brief**: `.duaer/specs/094-dispatch-project-simple/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
After the current project is chosen (Projects drawer), the dispatch panel must
|
|
10
|
+
not re-ask for a product repo. Show a short project summary only; keep deploy
|
|
11
|
+
target + agent + launch.
|
|
12
|
+
|
|
13
|
+
## Acceptance
|
|
14
|
+
|
|
15
|
+
1. With active project: hide browse/scan/filter/list/path; show「当前项目:名称」+ path
|
|
16
|
+
2. Title reads「启动数字员工」/ Launch digital employee (not「派工到当前项目」)
|
|
17
|
+
3. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Feature Specification: Persist project chat across refresh
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/project-chat-persist`
|
|
4
|
+
**Brief**: `.duaer/specs/095-project-chat-persist/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Each project's desk conversation is saved under `~/.duaer/live/project-chats/`
|
|
10
|
+
and restored when that project is active (including after page refresh).
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
1. After chatting on a project, refresh restores the same messages
|
|
15
|
+
2. Switching projects saves the previous chat and loads the other
|
|
16
|
+
3. Empty project still auto-kickoffs; project with history restores (no re-kickoff)
|
|
17
|
+
4. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "accepted",
|
|
3
|
+
"acceptedAt": "2026-09-18T02:45:00.000Z",
|
|
4
|
+
"verification": {
|
|
5
|
+
"levels": ["L0", "L1", "L3"],
|
|
6
|
+
"commands": [
|
|
7
|
+
"node --check bin/duaer-live.mjs",
|
|
8
|
+
"node --check bin/live-project-chat.mjs",
|
|
9
|
+
"node --check web/live-dev/app.js",
|
|
10
|
+
"npm test",
|
|
11
|
+
"npm run test:live"
|
|
12
|
+
],
|
|
13
|
+
"result": "pass"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Feature Specification: Persist requirements card + job binding
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/project-card-persist`
|
|
4
|
+
**Brief**: `.duaer/specs/096-project-card-persist/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
When a project is selected, the desk restores not only chat messages but also
|
|
10
|
+
the **requirements card** (需求) and **task binding** (任务 / jobId + dispatch
|
|
11
|
+
UI), so refresh does not lose mid-confirm or in-progress work.
|
|
12
|
+
|
|
13
|
+
## Why
|
|
14
|
+
|
|
15
|
+
Chat persistence (095) left the confirm/revise card and job progress empty
|
|
16
|
+
after refresh. Users expect the full desk session to come back with the
|
|
17
|
+
project.
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
1. Editing confirm/revise fields is saved under the project session file
|
|
22
|
+
2. After Confirm, refresh restores locked card + jobId and shows dispatch/progress
|
|
23
|
+
3. After Dispatch / revise, refresh restores job binding and resumes status poll
|
|
24
|
+
4. Switching projects saves the previous desk session and loads the other
|
|
25
|
+
5. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Tasks: 096-project-card-persist
|
|
2
|
+
|
|
3
|
+
- [x] Extend `live-project-chat` schema: card, reviseCard, jobId, locked, mode
|
|
4
|
+
- [x] PUT `/api/projects/chat` accepts full desk session fields
|
|
5
|
+
- [x] Client persist on card input (debounced), confirm, dispatch, revise
|
|
6
|
+
- [x] Client restore applies cards + starts status poll when jobId present
|
|
7
|
+
- [x] Unit + source-wiring tests
|
|
8
|
+
- [x] E2E catalog + CHANGELOG
|
|
9
|
+
- [x] Verify L0/L1/L3 and accept
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "accepted",
|
|
3
|
+
"acceptedAt": "2026-09-18T02:50:00.000Z",
|
|
4
|
+
"verification": {
|
|
5
|
+
"levels": ["L0", "L1", "L3"],
|
|
6
|
+
"commands": [
|
|
7
|
+
"node --check bin/live-project-chat.mjs",
|
|
8
|
+
"node --check bin/duaer-live.mjs",
|
|
9
|
+
"node --check web/live-dev/app.js",
|
|
10
|
+
"npm test",
|
|
11
|
+
"npm run test:live"
|
|
12
|
+
],
|
|
13
|
+
"result": "pass"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Feature Specification: Persist validate gate with desk session
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `fix/validate-persist`
|
|
4
|
+
**Brief**: `.duaer/specs/097-validate-persist/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
After refresh, if the requirements card was already auto-validated
|
|
10
|
+
(passed), the Confirm button stays enabled — do not force a silent
|
|
11
|
+
idle gate that blocks Confirm.
|
|
12
|
+
|
|
13
|
+
## Why
|
|
14
|
+
|
|
15
|
+
096 restored card text and jobId, but `state.validate` reset to idle.
|
|
16
|
+
Confirm requires `validationAllowsSend` (passed + matching fingerprint),
|
|
17
|
+
so users see a filled card that “already passed” but cannot click Confirm.
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
1. Passing auto-validate is saved in the project session file
|
|
22
|
+
2. Refresh with unchanged card restores passed gate → Confirm clickable
|
|
23
|
+
3. Editing the card after restore invalidates / re-validates as today
|
|
24
|
+
4. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "accepted",
|
|
3
|
+
"acceptedAt": "2026-09-18T02:55:00.000Z",
|
|
4
|
+
"verification": {
|
|
5
|
+
"levels": ["L0", "L1", "L3"],
|
|
6
|
+
"commands": [
|
|
7
|
+
"node --check web/live-dev/app.js",
|
|
8
|
+
"node --check web/live-dev/structured-html.mjs",
|
|
9
|
+
"npm test",
|
|
10
|
+
"npm run test:live"
|
|
11
|
+
],
|
|
12
|
+
"result": "pass"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Feature Specification: Structured requirements edit
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/req-structured-edit`
|
|
4
|
+
**Brief**: `.duaer/specs/098-req-structured-edit/`
|
|
5
|
+
**Status**: Accepted
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
Requirements fields keep the same structured look while editing — row/list
|
|
10
|
+
items with add/remove — instead of collapsing into a raw textarea.
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
1. Clicking a requirements field opens structured item rows (same chrome as view)
|
|
15
|
+
2. Enter /「添加一条」adds a row; empty Backspace / × removes a row
|
|
16
|
+
3. Blur commits text back to the card (bullet/numbered/para serialization)
|
|
17
|
+
4. Confirm + revise cards both use this editor
|
|
18
|
+
5. `npm test` + `npm run test:live` pass
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"status": "accepted",
|
|
3
|
+
"acceptedAt": "2026-09-18T03:00:00.000Z",
|
|
4
|
+
"verification": {
|
|
5
|
+
"levels": ["L0", "L1", "L3"],
|
|
6
|
+
"commands": [
|
|
7
|
+
"node --check web/live-dev/app.js",
|
|
8
|
+
"node --check bin/duaer-live.mjs",
|
|
9
|
+
"npm test",
|
|
10
|
+
"npm run test:live"
|
|
11
|
+
],
|
|
12
|
+
"result": "pass"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Feature Specification: Setup guide for CLI install + other models
|
|
2
|
+
|
|
3
|
+
**Feature Branch**: `feat/setup-cli-guide`
|
|
4
|
+
**Brief**: `.duaer/specs/099-setup-cli-guide/`
|
|
5
|
+
**Status**: In progress
|
|
6
|
+
|
|
7
|
+
## Goal
|
|
8
|
+
|
|
9
|
+
The FED model setup **说明** explains how to install Cursor Agent / Claude Code
|
|
10
|
+
and how to wire other desk / coding models.
|
|
11
|
+
|
|
12
|
+
## Acceptance
|
|
13
|
+
|
|
14
|
+
1. Setup page has a 说明/Guide block with Cursor + Claude install commands
|
|
15
|
+
2. Guide covers Custom desk models and Claude→DeepSeek (etc.) for coding
|
|
16
|
+
3. Header **模型** reopens setup (with 返回台面 when already ready)
|
|
17
|
+
4. `worker-models(.zh-CN).md` and README match the install commands
|
|
18
|
+
5. Missing Claude installCommand is the concrete npm install line
|
|
19
|
+
6. `npm test` + `npm run test:live` pass
|