@chanlerdev/scorel 0.0.1 → 0.0.2
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/README.md +356 -69
- package/dist/index.js +4237 -1759
- package/dist/index.js.map +4 -4
- package/docs/CHANGELOG.md +62 -0
- package/docs/ROADMAP.md +93 -9
- package/docs/SHIP.md +9 -3
- package/docs/spec/channels.md +97 -100
- package/docs/spec/client.md +11 -5
- package/docs/spec/extensions.md +115 -43
- package/docs/spec/ship/S0062-npm-package-and-release-workflow.md +3 -0
- package/docs/spec/ship/S0063-ai-release-notes.md +129 -0
- package/docs/spec/ship/S0064-gui-product-intent-and-boundary.md +79 -0
- package/docs/spec/ship/S0065-gui-electron-shell-and-embedded-host.md +73 -0
- package/docs/spec/ship/S0066-gui-local-project-workspace.md +79 -0
- package/docs/spec/ship/S0067-gui-relay-device-and-remote-project-selection.md +97 -0
- package/docs/spec/ship/S0068-gui-codex-app-polish-and-e2e.md +102 -0
- package/docs/spec/ship/S0068-gui-e2e-verification.md +50 -0
- package/docs/spec/ship/S0069-gui-codex-ui-refactor.md +371 -0
- package/docs/spec/ship/S0070-gui-streaming-and-tool-blocks.md +202 -0
- package/docs/spec/ship/S0071-gui-visual-fidelity-and-settings-shell.md +360 -0
- package/docs/spec/ship/S0072-gui-glass-sidebar-and-picker-anchoring.md +116 -0
- package/docs/spec/ship/S0073-provider-model-profile-contract.md +241 -0
- package/docs/spec/ship/S0074-gui-model-provider-settings-split.md +113 -0
- package/docs/spec/ship/S0075-provider-catalog-model-cards.md +93 -0
- package/docs/spec/ship/S0076-provider-modal-search-and-direct-key.md +70 -0
- package/docs/spec/ship/S0077-auxiliary-session-title-generation.md +95 -0
- package/docs/spec/ship/S0078-gui-provider-settings-forward-config-and-simplification.md +150 -0
- package/docs/spec/ship/S0079-gui-sidebar-layout-controls.md +49 -0
- package/docs/spec/ship/S0080-session-title-hook-and-gui-markdown-dark-code.md +58 -0
- package/docs/spec/ship/S0081-automatic-memory.md +117 -0
- package/docs/spec/ship/S0082-memory-journal-tool-and-idle-dream.md +107 -0
- package/docs/spec/ship/S0083-extension-manifest-and-im-channel-runtime.md +338 -0
- package/docs/spec/ship/S0084-built-in-telegram-im-extension.md +188 -0
- package/docs/spec/ship/S0085-gui-im-extension-settings.md +47 -0
- package/docs/spec/ship/S0086-auto-compact-and-session-memory.md +124 -0
- package/extensions/builtin/loopback/adapter.js +13 -0
- package/extensions/builtin/loopback/scorel.extension.json +7 -0
- package/extensions/builtin/loopback/skills/loopback/SKILL.md +7 -0
- package/extensions/builtin/telegram/adapter.d.ts +43 -0
- package/extensions/builtin/telegram/adapter.js +252 -0
- package/extensions/builtin/telegram/scorel.extension.json +7 -0
- package/extensions/builtin/telegram/skills/telegram/SKILL.md +9 -0
- package/package.json +6 -2
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# S0070: GUI Streaming UX And Specialized Tool Blocks
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Light up real-time streaming UX in the GUI renderer (built on the IPC channels added in `S0069`) and replace the `DefaultJsonBlock` fallback for the seven first-class coding tools with specialized renderers. Validate the full GUI surface end to end against a real LLM provider on both local and Relay project paths.
|
|
6
|
+
|
|
7
|
+
This is the second half of the M9 Follow-up: GUI Codex App polish.
|
|
8
|
+
|
|
9
|
+
Reference screenshots from M9 Follow-up brief:
|
|
10
|
+
|
|
11
|
+
- image2 — populated session view: action chips (`已探索 3 个文件`, `Connect Chrome`, `已使用 浏览器`), assistant message no-bubble, user bubble right-aligned.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Scope
|
|
16
|
+
|
|
17
|
+
### 1. Streaming projector wiring
|
|
18
|
+
|
|
19
|
+
`apps/gui/src/renderer/chatbox/projector.ts` already accepts the full `ScorelEvent` union from S0069. Activate handling for transient events:
|
|
20
|
+
|
|
21
|
+
- `turn_start` / `turn_end` — toggle per-turn `streaming` flag.
|
|
22
|
+
- `message_start` — initialize an in-flight assistant message in the current turn with empty text parts and `streaming: true`.
|
|
23
|
+
- `message_end` — flip `streaming: false`, attach `usage` / `stopReason`.
|
|
24
|
+
- `text_delta` — append delta to the in-flight message's first text part.
|
|
25
|
+
- `error` — surface as a per-turn error chip without ending the projector state.
|
|
26
|
+
|
|
27
|
+
Use `delta-batch.ts` (RAF batcher) to coalesce `text_delta` events to one React update per animation frame.
|
|
28
|
+
|
|
29
|
+
### 2. Streaming cursor
|
|
30
|
+
|
|
31
|
+
`apps/gui/src/renderer/chatbox/StreamingCursor.tsx`:
|
|
32
|
+
|
|
33
|
+
- inline-block span, 1ch × 1.1em, `--color-text-faint` background.
|
|
34
|
+
- CSS keyframe `scorel-caret-blink` 1s steps(2, end), defined in `styles.css`.
|
|
35
|
+
- Mounted as the last sibling inside the streaming assistant message (not inside the markdown subtree, so DOM updates don't disturb it).
|
|
36
|
+
|
|
37
|
+
### 3. Autoscroll region + jump-to-bottom
|
|
38
|
+
|
|
39
|
+
`apps/gui/src/renderer/chatbox/AutoscrollRegion.tsx`:
|
|
40
|
+
|
|
41
|
+
- IntersectionObserver on a 1px sentinel at the bottom of the transcript scroll container.
|
|
42
|
+
- "At bottom" sticky flag: while `true`, every transcript update scrolls the sentinel into view.
|
|
43
|
+
- Exit "at bottom" on user-initiated scroll-up (wheel, touchpad, keyboard PageUp).
|
|
44
|
+
- Re-enter "at bottom" only when sentinel reaches viewport.
|
|
45
|
+
- `JumpToBottom` floating button (28×28 circle, `--color-surface-raised`, `ChevronDown` icon) appears bottom-right when not at bottom; click resets sticky flag and scrolls.
|
|
46
|
+
|
|
47
|
+
Logic ported from `apps/webui/components/chatbox/autoscroll-region.tsx`; CSS migrated from Tailwind to `styles.css` classes.
|
|
48
|
+
|
|
49
|
+
### 4. Specialized tool blocks
|
|
50
|
+
|
|
51
|
+
Register specialized renderers via `registerToolBlock(name, Component)` in `apps/gui/src/renderer/chatbox/tool-blocks/registry.ts`:
|
|
52
|
+
|
|
53
|
+
#### 4.1 ReadBlock
|
|
54
|
+
|
|
55
|
+
For `Read`:
|
|
56
|
+
|
|
57
|
+
- Action chip header: `{ChipIcon} 已读取 {file}` (line range if provided).
|
|
58
|
+
- Collapsed by default.
|
|
59
|
+
- Expand reveals file path and read range; **does not** rerender file contents (transcript stays scannable).
|
|
60
|
+
- Error result swaps icon to `--color-status-err` and auto-expands.
|
|
61
|
+
|
|
62
|
+
#### 4.2 GlobGrepBlock
|
|
63
|
+
|
|
64
|
+
For `Glob` and `Grep` (single component, registered for both names):
|
|
65
|
+
|
|
66
|
+
- Action chip header: `已探索 N 个文件` (Glob) or `已搜索 "{pattern}"` (Grep).
|
|
67
|
+
- Expand: list of matched paths or grep hits with line numbers; truncated to 50, "show more" reveals all.
|
|
68
|
+
|
|
69
|
+
#### 4.3 EditWriteBlock
|
|
70
|
+
|
|
71
|
+
For `Edit` and `Write`:
|
|
72
|
+
|
|
73
|
+
- Action chip header: `{Pencil} 已编辑 {file}` or `{FilePlus} 已创建 {file}`, with `+N -M` change counters.
|
|
74
|
+
- Inline collapsible diff view: unified diff with red/green line backgrounds (background only, not full-line color floods). Diff parsed from `tool_call.args.old_string` / `new_string` (Edit) or `tool_call.args.content` (Write, treats prior empty as new file). No external diff library; a small in-renderer line-by-line LCS suffices for the visual.
|
|
75
|
+
- Errors expand by default.
|
|
76
|
+
|
|
77
|
+
#### 4.4 BashBlock
|
|
78
|
+
|
|
79
|
+
For `Bash`:
|
|
80
|
+
|
|
81
|
+
- Action chip header: `{Terminal} {command}` truncated to 80 chars.
|
|
82
|
+
- Body: `<pre>` with stdout/stderr; collapsible after 12 lines, "expand" reveals all.
|
|
83
|
+
- Exit code shown as `→ exit 0` (`--color-status-ok`) or `→ exit N` (`--color-status-err`).
|
|
84
|
+
|
|
85
|
+
#### 4.5 TodoWriteBlock
|
|
86
|
+
|
|
87
|
+
For `TodoWrite`:
|
|
88
|
+
|
|
89
|
+
- Header: `{ClipboardList} 任务列表 (n / total)`.
|
|
90
|
+
- Body: list of todos with status checkboxes:
|
|
91
|
+
- `pending` → `Square` icon.
|
|
92
|
+
- `in_progress` → `Loader` icon (animated spin via CSS).
|
|
93
|
+
- `completed` → `CheckSquare` icon.
|
|
94
|
+
- Strikethrough completed items in `--color-text-muted`.
|
|
95
|
+
|
|
96
|
+
#### 4.6 Default fallback unchanged
|
|
97
|
+
|
|
98
|
+
Tools without a registered specialized block fall back to `DefaultJsonBlock` from S0069.
|
|
99
|
+
|
|
100
|
+
### 5. End-to-end verification
|
|
101
|
+
|
|
102
|
+
Add `apps/gui/scripts/verify-m9-gui-followup.mjs` (or extend existing `verify:m9-gui` if present). Steps:
|
|
103
|
+
|
|
104
|
+
1. Launch GUI build via Electron headless (or via the existing pnpm pipeline).
|
|
105
|
+
2. Local project path: register a temp git workspace, send a prompt that exercises Read, Edit, Bash, TodoWrite. Assert each tool renders its specialized block.
|
|
106
|
+
3. Relay project path: use the existing Relay verification harness (`pnpm verify:m9-gui` from S0068) to run the same prompt over Relay; assert the same tool blocks render.
|
|
107
|
+
4. Persistence smoke: after sending, kill renderer, relaunch, reopen session, confirm tool blocks rerender from JSONL persistence.
|
|
108
|
+
|
|
109
|
+
Save evidence to `docs/spec/ship/S0070-gui-e2e-verification.md` (screenshots optional but encouraged).
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Non-Goals
|
|
114
|
+
|
|
115
|
+
- No further sidebar / composer / settings restructuring beyond what S0069 shipped.
|
|
116
|
+
- No additional tool kinds beyond the seven listed (Read / Glob / Grep / Edit / Write / Bash / TodoWrite). Skill / Subagent / Web tools are deferred.
|
|
117
|
+
- No diff-viewer for non-Edit/Write tools.
|
|
118
|
+
- No Markdown table-of-contents, link previews, syntax-aware folding, or other prose UX.
|
|
119
|
+
- No dark-mode implementation.
|
|
120
|
+
- No reverse-reuse of the GUI components inside WebUI. (Future product direction.)
|
|
121
|
+
- No new IPC channels. All streaming flows through the channel set added in S0069.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Acceptance Criteria
|
|
126
|
+
|
|
127
|
+
- Sending a prompt streams visible character-by-character text into the assistant turn, with a blinking cursor at the trailing edge.
|
|
128
|
+
- `text_delta` events do not cause one React re-render per delta; `delta-batch.ts` coalesces them.
|
|
129
|
+
- Scroll behavior: while scrolled to bottom, transcript follows new tokens. Scroll up — autoscroll pauses. Jump-to-bottom button appears; click returns to live tail.
|
|
130
|
+
- All seven coding tools render through their specialized blocks. `DefaultJsonBlock` is reserved for unknown tool names only.
|
|
131
|
+
- Errors in tool calls auto-expand the relevant block and surface `--color-status-err` accents.
|
|
132
|
+
- Edit / Write blocks render a visible unified diff with `+` / `-` line markers and per-line tinting.
|
|
133
|
+
- TodoWrite renders a checkbox list whose state updates live as new `tool_result` events arrive.
|
|
134
|
+
- Real provider e2e on local + Relay project paths passes; `pnpm verify:m9-gui` (or its successor command) reports green.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Test Requirements
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
pnpm --filter @scorel/app-gui build
|
|
142
|
+
pnpm --filter @scorel/app-gui typecheck
|
|
143
|
+
pnpm --filter @scorel/app-gui test
|
|
144
|
+
pnpm typecheck
|
|
145
|
+
pnpm test
|
|
146
|
+
pnpm pack:smoke
|
|
147
|
+
pnpm verify:m9-gui
|
|
148
|
+
git diff --check
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Manual e2e (real provider, both paths):
|
|
152
|
+
|
|
153
|
+
- Local project: clone or use an existing temp repo; ask the GUI to "list the README, then add a TODO row, then run echo hello". Confirm Read, TodoWrite, Bash blocks render correctly.
|
|
154
|
+
- Relay project: pair a Relay device, register a remote project, repeat the prompt. Confirm identical behavior over Relay.
|
|
155
|
+
- Streaming visual: send a long prompt that produces ≥ 1k tokens of text; confirm cursor blinks, autoscroll follows until user scrolls up, jump-to-bottom returns to live tail.
|
|
156
|
+
- Reload mid-stream: kill renderer during streaming; relaunch and reopen the session; confirm persisted events replay through the projector and tool blocks render the same way.
|
|
157
|
+
|
|
158
|
+
Record evidence in `docs/spec/ship/S0070-gui-e2e-verification.md`.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Affected Paths
|
|
163
|
+
|
|
164
|
+
- `apps/gui/src/renderer/chatbox/projector.ts` — light up transient event handling.
|
|
165
|
+
- `apps/gui/src/renderer/chatbox/delta-batch.ts` — wired into Transcript.
|
|
166
|
+
- `apps/gui/src/renderer/chatbox/StreamingCursor.tsx` — new.
|
|
167
|
+
- `apps/gui/src/renderer/chatbox/AutoscrollRegion.tsx` — new.
|
|
168
|
+
- `apps/gui/src/renderer/chatbox/Transcript.tsx` — wrap children in `AutoscrollRegion`, mount `StreamingCursor` on the in-flight message.
|
|
169
|
+
- `apps/gui/src/renderer/chatbox/tool-blocks/ReadBlock.tsx`, `GlobGrepBlock.tsx`, `EditWriteBlock.tsx`, `BashBlock.tsx`, `TodoWriteBlock.tsx`, `diff/UnifiedDiff.tsx` — new.
|
|
170
|
+
- `apps/gui/src/renderer/chatbox/tool-blocks/registry.ts` — register the seven tool names.
|
|
171
|
+
- `apps/gui/src/renderer/styles.css` — keyframes for cursor + spin, jump-to-bottom button style.
|
|
172
|
+
- `apps/gui/scripts/verify-m9-gui-followup.mjs` (or extension of existing verify script).
|
|
173
|
+
- `docs/spec/ship/S0070-gui-streaming-and-tool-blocks.md` — this file.
|
|
174
|
+
- `docs/spec/ship/S0070-gui-e2e-verification.md` — verification artifact.
|
|
175
|
+
- `docs/ROADMAP.md` — flip M9 Follow-up status to Done after verification.
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Implementation Notes
|
|
180
|
+
|
|
181
|
+
- Adopt webui's `apps/webui/lib/events/delta-batch.ts` `RAFBatcher` shape verbatim. The batcher is already copied into the GUI source tree by S0069.
|
|
182
|
+
- Keep `StreamingCursor` and `AutoscrollRegion` framework-agnostic: no Tailwind classes, no Next assumptions; use plain class names defined in `styles.css`.
|
|
183
|
+
- Diff parsing in `EditWriteBlock`: a 60-line LCS over already-split lines is sufficient; this is visualization, not authoritative semantics. `Edit` already pre-supplies `old_string`/`new_string` so the line ranges are bounded.
|
|
184
|
+
- `TodoWriteBlock` reads the latest `tool_result.result` (a JSON array per `S0012`); render purely from that array. No separate state machine.
|
|
185
|
+
- Specialized blocks must remain robust against partial data (`tool_call` arrived but `tool_result` not yet, or `tool_result.isError = true` with malformed payload). Fall back to `DefaultJsonBlock` rendering for the unparsable case rather than crashing the transcript.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Risks
|
|
190
|
+
|
|
191
|
+
- High-frequency `text_delta` over Relay can drop frames if RAF batcher cadence is misaligned with WebSocket pacing. Mitigation: batch by `requestAnimationFrame` and `flushSync` only on `message_end`.
|
|
192
|
+
- Diff renderer for Write of very large files could blow up Markdown render cost. Mitigation: cap diff body to first 200 changed lines, "show more" reveals all, plain `<pre>` rendering (not Markdown).
|
|
193
|
+
- Real-provider e2e flakiness: tool ordering depends on model behavior. Verification asserts the per-tool render path, not exact sequence.
|
|
194
|
+
- IPC `sessionEvent` push frequency under streaming may saturate Electron renderer. Mitigation: RAF batcher; rely on the same coalescing webui has shipped.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Out Of Scope (Reaffirmed)
|
|
199
|
+
|
|
200
|
+
- No new product surface beyond M9 + M9 Follow-up.
|
|
201
|
+
- No webui changes.
|
|
202
|
+
- No SSH / HTTP API / Ecosystem work — those remain on the M10+ roadmap.
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
# S0071: GUI Visual Fidelity Refit And Settings macOS Shell
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Bring `apps/gui` visual quality up to the Codex App reference screenshots (image2–image7). M9 Follow-up shipped structure + streaming + tool blocks (S0069/S0070), but acceptance was structural — type/test only, no visual diff. Net result: all the right pieces are present, none of them look right.
|
|
6
|
+
|
|
7
|
+
This spec closes the visual gap in two scopes, no new product surface:
|
|
8
|
+
|
|
9
|
+
1. **Global visual refit** — rewrite tokens + per-component CSS so sidebar, topbar, composer, empty state, project picker overlay, transcript, tool blocks, and markdown match the Codex aesthetic.
|
|
10
|
+
2. **Settings macOS shell** — rebuild `renderer/settings/` as a two-pane macOS-style settings window matching image7: left nav with grouped sections, header (back / device selector / search), right card surface with row-based controls (label+desc / dropdown / toggle / link / button).
|
|
11
|
+
|
|
12
|
+
Reference screenshots:
|
|
13
|
+
|
|
14
|
+
- image2 — populated session: hero title 600 weight, action chips with leading icons, composer with bottom mini pill.
|
|
15
|
+
- image3 — empty: H1 32px / weight 500 / center, composer pill 24 radius, project picker mini pill below composer.
|
|
16
|
+
- image4 — picker overlay: 8px round, 1px hairline, soft surface backing, leading 16px folder icons, divider before add rows.
|
|
17
|
+
- image5 — Add Remote Project modal: card 16 radius, host dropdown native chevron, path input + reset, directory list with folder icons, primary CTA black.
|
|
18
|
+
- image6 — sidebar: warm gray surface, project rows compact, inline sessions slightly indented, online dot tight to label.
|
|
19
|
+
- image7 — settings: left nav 256px with `个人 / 集成 / 编码` section captions, active row raised white with 1px hairline, right pane card-grouped rows with right-aligned controls, blue link `了解更多`, blue toggle, red destructive CTA.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Scope
|
|
24
|
+
|
|
25
|
+
### 1. Token reset
|
|
26
|
+
|
|
27
|
+
Update `apps/gui/src/renderer/styles.css` `:root`:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
--color-bg: #FFFFFF;
|
|
31
|
+
--color-surface: #F5F5F5; /* sidebar / settings nav */
|
|
32
|
+
--color-surface-soft: #FAFAFA; /* card body in settings */
|
|
33
|
+
--color-surface-hover: #ECECEE;
|
|
34
|
+
--color-surface-raised: #FFFFFF; /* active sidebar / picker overlay backing */
|
|
35
|
+
--color-border: #E4E4E7;
|
|
36
|
+
--color-border-hairline: #EFEFEF;
|
|
37
|
+
--color-border-strong: #D4D4D8;
|
|
38
|
+
--color-text: #0D0D0D;
|
|
39
|
+
--color-text-muted: #5D5D5D;
|
|
40
|
+
--color-text-faint: #9CA3AF;
|
|
41
|
+
--color-accent: #0D0D0D;
|
|
42
|
+
--color-accent-soft: #F0F0F2;
|
|
43
|
+
--color-link: #2563EB; /* settings link, toggle */
|
|
44
|
+
--color-status-warn: #F0712C; /* composer "完全访问" warn chip */
|
|
45
|
+
--color-status-err: #DC2626;
|
|
46
|
+
--color-status-ok: #16A34A;
|
|
47
|
+
--color-status-idle: #9CA3AF;
|
|
48
|
+
|
|
49
|
+
--shadow-ring: inset 0 0 0 1px var(--color-border);
|
|
50
|
+
--shadow-ring-strong: inset 0 0 0 1px var(--color-border-strong);
|
|
51
|
+
|
|
52
|
+
--radius-sm: 6px;
|
|
53
|
+
--radius-md: 10px;
|
|
54
|
+
--radius-lg: 14px;
|
|
55
|
+
--radius-pill: 24px;
|
|
56
|
+
--radius-full: 9999px;
|
|
57
|
+
|
|
58
|
+
--text-xs: 12px;
|
|
59
|
+
--text-sm: 13px;
|
|
60
|
+
--text-base: 14px;
|
|
61
|
+
--text-md: 15px;
|
|
62
|
+
--text-lg: 18px;
|
|
63
|
+
--text-xl: 24px;
|
|
64
|
+
--text-hero: 32px;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Sidebar width drops 280 → 264. Empty-state H1 uses `--text-hero` 32px / weight 500 / letter-spacing -0.018em.
|
|
68
|
+
|
|
69
|
+
### 2. Sidebar visual refit
|
|
70
|
+
|
|
71
|
+
`renderer/shell/Sidebar.tsx` + `ProjectTree.tsx` + `styles.css`:
|
|
72
|
+
|
|
73
|
+
- Background `--color-surface` (#F5F5F5), no border-right separator (use 1px hairline color match instead).
|
|
74
|
+
- Section caption: 11px / 600 / uppercase / tracking 0.06em / `--color-text-faint`, sits 16px below preceding block, 6px above first row.
|
|
75
|
+
- Row paddings: 6/10. Active row: `--color-surface-raised` + `--shadow-ring`. Hover row (non-active): `--color-surface-hover`. No `--surface-hover` on active.
|
|
76
|
+
- Project row layout: `[14 caret] [16 folder icon, color text-faint] [name flex] [8 right-pad] [8 online-dot]`. Drop the redundant secondary-name line — when relay device is bound, render the device label as smaller muted line under name only when project displayName != device label (avoid duplicate text).
|
|
77
|
+
- Online dot: 6×6, `--color-status-ok` or `--color-status-idle`, no border.
|
|
78
|
+
- Session row: indent 26 (caret column + 12 gap), 4/8 padding, font 13 / weight 400, muted color in inactive, full text on active. No icon.
|
|
79
|
+
- Bottom `设置` row: same row geometry, no trailing mobile icon (trailing reserved for future hot-key chip).
|
|
80
|
+
- Top action rows: `+ 新对话` keeps icon 14, label 13, hover `--color-surface-hover`. `搜索 / 插件 / 自动化` rows render disabled with 0.42 opacity but no `cursor: not-allowed` if it visually breaks the row — rely on the system pointer.
|
|
81
|
+
|
|
82
|
+
### 3. Topbar refit
|
|
83
|
+
|
|
84
|
+
`renderer/workspace/Topbar.tsx`:
|
|
85
|
+
|
|
86
|
+
- Height 44 → 40. Padding `16 18 0`.
|
|
87
|
+
- Title 14 / 600 with 1.4 line-height (was 600 default font weight chunk).
|
|
88
|
+
- Right: drop the unused `PanelRight` placeholder. Keep error/host-message inline as 12 muted/err text.
|
|
89
|
+
- No bottom border. The transcript inner already has its own first-row spacing.
|
|
90
|
+
|
|
91
|
+
### 4. Composer + picker pill refit
|
|
92
|
+
|
|
93
|
+
`renderer/composer/Composer.tsx` + `ProjectPickerPill.tsx`:
|
|
94
|
+
|
|
95
|
+
- Composer pill: padding `14 18 12`, `border-radius: 24`, hairline border, no surface fill.
|
|
96
|
+
- Textarea: min-height 44, max-height 200, font-size 15 / line-height 1.55, placeholder color `--color-text-faint`.
|
|
97
|
+
- Bar row: 36 height, gap 10. Left group: `+` icon button 28px circle, then `完全访问` chip — render as `<AlertTriangle 12> 完全访问 <ChevronDown 12>` in `--color-status-warn`, weight 600, font-size 13, hover `--color-surface-hover` 6px radius pill, padding `4 8`.
|
|
98
|
+
- Right group: `5.5 超高 ⌄` chip — 13 / 600 / `--color-text` / hover surface-hover. Mic 16. Send 32×32 black circle with `ArrowUp 14` white. While `inFlight`, swap to `--color-status-err` circle with `Square 12`.
|
|
99
|
+
- Project picker pill (below composer): align-self start, `[Folder 14] {name} [ChevronDown 14]`, 13 / 500, `--color-text`, hover `--color-surface-hover`, padding `4 10`, radius full. Sits 8px below composer, NOT inside the form.
|
|
100
|
+
|
|
101
|
+
### 5. Empty state refit
|
|
102
|
+
|
|
103
|
+
`renderer/workspace/EmptyState.tsx`:
|
|
104
|
+
|
|
105
|
+
- Wrapper grid: `auto 1fr`, content vertically centered with 8vh bottom offset.
|
|
106
|
+
- H1: 32 / 500, letter-spacing -0.018em, max-width 680, center.
|
|
107
|
+
- Composer-shell width: `min(720px, 100%)`.
|
|
108
|
+
- Picker pill 12px below composer.
|
|
109
|
+
- Drop the `composer-shell` `gap` — replaced with explicit margins to control composer ↔ pill rhythm.
|
|
110
|
+
|
|
111
|
+
### 6. Project picker overlay refit
|
|
112
|
+
|
|
113
|
+
`renderer/composer/ProjectPickerMenu.tsx`:
|
|
114
|
+
|
|
115
|
+
- Backdrop: `rgba(15, 15, 15, 0.18)` (was 0.16) with 4px blur — keeps focus on overlay without a hard scrim.
|
|
116
|
+
- Popover: 320 wide, `--color-surface-raised` background, `--shadow-ring`, radius 12, padding 6, gap 2. Position centered for now (until anchored placement is wired) — no inline `Search` icon nested inside a composer-pill class (current bug). Search input is a clean rounded-sm input with leading icon.
|
|
117
|
+
- Search input: 32 height, `--color-surface` fill, hairline border, `--color-text` text.
|
|
118
|
+
- Item row: 30 height, `[16 icon] [label flex] [16 trailing]`, padding `4 8`, radius 6. Hover `--color-surface-hover`. Selected check sits in trailing slot.
|
|
119
|
+
- Divider: 1px hairline, 6px vertical margin.
|
|
120
|
+
- `添加本地项目` / `添加远程项目` rows below divider use `FolderPlus` and `Globe` 14px leading icons, no chevron suffix.
|
|
121
|
+
- `不使用项目` remains explicitly out of scope.
|
|
122
|
+
|
|
123
|
+
### 7. Add Remote Project modal refit
|
|
124
|
+
|
|
125
|
+
`renderer/composer/AddRemoteProjectDialog.tsx`:
|
|
126
|
+
|
|
127
|
+
- Backdrop: `rgba(15, 15, 15, 0.32)` plus 4px blur.
|
|
128
|
+
- Panel: 520 wide, radius 16, padding 24 24 20, gap 14.
|
|
129
|
+
- Header: 18 / 600 title, 14 muted subtitle on its own row.
|
|
130
|
+
- Field label: 12 / 500 muted, 6 below input.
|
|
131
|
+
- Inputs/select use 36 height, 8 radius, hairline border, `--color-bg` fill, `--color-text`.
|
|
132
|
+
- Reset button: 28 icon button, no border, hover surface-hover.
|
|
133
|
+
- Directory list row: 28 height, `[Folder 14] {name}` 13, hover surface-hover, radius 6.
|
|
134
|
+
- Footer buttons: `取消` ghost (transparent, hover surface-hover), `添加项目` primary (`--color-accent` bg, white text, 36 height, padding `0 16`, 8 radius).
|
|
135
|
+
|
|
136
|
+
### 8. Transcript / turn refit
|
|
137
|
+
|
|
138
|
+
`renderer/chatbox/TurnUser.tsx` + `TurnAssistant.tsx` + tool block CSS:
|
|
139
|
+
|
|
140
|
+
- User bubble: max-width 70%, radius 14, `--color-accent-soft` bg, padding `10 14`, font 15 / 1.55. Margin 0 (rely on transcript gap).
|
|
141
|
+
- Assistant article: no border, no padding x. Margin 0. Streaming cursor sits at trailing edge of last text part.
|
|
142
|
+
- Transcript inner: width `min(720px, 100%)`, gap 22.
|
|
143
|
+
- Markdown: paragraph margin-bottom 10, h2 mt 18 mb 8, h3 mt 14 mb 6, list margin-bottom 10, table border-color `--color-border-hairline`, code block `--color-surface` bg, font-mono 13.
|
|
144
|
+
|
|
145
|
+
### 9. Tool block chip rebuild
|
|
146
|
+
|
|
147
|
+
Tool blocks currently render as bordered cards. Codex aesthetic is **chip-style action lines**: 14 height row, leading 14 icon, single-line title, optional collapsed body.
|
|
148
|
+
|
|
149
|
+
Update `renderer/chatbox/tool-blocks/*` (CSS only on most, structural on a few):
|
|
150
|
+
|
|
151
|
+
- New CSS class `tool-chip` replacing `tool-block` for the closed state:
|
|
152
|
+
- row: `[16 icon] [label flex 13/500/text-muted] [12 chevron]`.
|
|
153
|
+
- no border, no background, padding `2 0`, hover changes label color to `--color-text` (no background swap).
|
|
154
|
+
- Open state shows a body block below: 1px left rule (`box-shadow: inset 2px 0 0 var(--color-border)`), padding `6 0 6 12`, font 12 muted.
|
|
155
|
+
- `ReadBlock` chip: `已读取 {basename(path)}{range?}`. Body collapsed by default — when open, show full file_path on first line and read range on second.
|
|
156
|
+
- `GlobGrepBlock` chip: `已搜索 "{pattern}"` for Grep, `已探索 N 个文件` for Glob (drop `· N 个匹配` from chip; show count in body header).
|
|
157
|
+
- `EditWriteBlock` chip: `已编辑 {basename(path)}` or `已创建 {basename(path)}` followed by `+N -M` colored counters as right-aligned secondary text. Body keeps unified diff (already implemented).
|
|
158
|
+
- `BashBlock` chip: `$ {truncate(command, 64)}`. Body unchanged.
|
|
159
|
+
- `TodoWriteBlock` stays as a non-collapsing card (it IS the content), but switch to chip-style header `任务 ({done}/{total})` and inline list with 12px checkbox icon column. Drop the explicit border around the whole card; rely on transcript gap and a 1px left rule on open items.
|
|
160
|
+
- `DefaultJsonBlock` chip: `{toolName}{pending?" · pending":""}`.
|
|
161
|
+
|
|
162
|
+
### 10. Settings macOS shell
|
|
163
|
+
|
|
164
|
+
Replace `renderer/settings/SettingsPage.tsx` + `RelayDevicesPanel.tsx` with a tree:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
renderer/settings/
|
|
168
|
+
├── SettingsShell.tsx # grid: nav 256 / main
|
|
169
|
+
├── SettingsNav.tsx # back row + device selector + search + sectioned items
|
|
170
|
+
├── SettingsHeader.tsx # H1 + subtitle + optional 了解更多 link
|
|
171
|
+
├── SettingsCard.tsx # white card container, divider per child row
|
|
172
|
+
├── SettingsRow.tsx # [label + desc] [trailing control]
|
|
173
|
+
├── controls/
|
|
174
|
+
│ ├── Toggle.tsx # 28×16 pill, blue when on
|
|
175
|
+
│ ├── Select.tsx # native <select> styled to look like macOS button with chevron
|
|
176
|
+
│ └── LinkAccent.tsx # blue inline link with optional trailing arrow icon
|
|
177
|
+
└── sections/
|
|
178
|
+
├── GeneralSection.tsx
|
|
179
|
+
├── AppearanceSection.tsx
|
|
180
|
+
├── ConfigSection.tsx # contains Relay URL + pair + device list (was RelayDevicesPanel content)
|
|
181
|
+
├── PersonalizationSection.tsx
|
|
182
|
+
├── KeyboardSection.tsx
|
|
183
|
+
├── UsageSection.tsx
|
|
184
|
+
├── McpSection.tsx
|
|
185
|
+
├── ConnectionsSection.tsx
|
|
186
|
+
└── GitSection.tsx
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Section list (matches image7 ordering):
|
|
190
|
+
|
|
191
|
+
- Group `个人`: 常规 / 个人资料 / 外观 / 配置 / 个性化 / 键盘快捷键 / 使用情况和计费.
|
|
192
|
+
- Group `集成`: 应用快照 / MCP 服务器 / 浏览器 / 电脑操控.
|
|
193
|
+
- Group `编码`: 钩子 / 连接 / Git / 环境.
|
|
194
|
+
|
|
195
|
+
**Only `配置` (Config) and `常规` (General) ship real content in S0071.** Others render `SectionPlaceholder` with title + 14 muted "待开发" hint. Acceptance is the macOS shell + nav + Config section functionality, not 14 fully-built sections.
|
|
196
|
+
|
|
197
|
+
#### 10.1 SettingsNav
|
|
198
|
+
|
|
199
|
+
- 256 wide, `--color-surface` background.
|
|
200
|
+
- Top: `← 返回应用` row 32 height, hover surface-hover.
|
|
201
|
+
- Below back row: device selector — `[Monitor 14] 此电脑 [ChevronDown 12]` styled as a dropdown trigger 36 height, padding `0 10`, radius 8, surface-soft fill, hairline border. Disabled placeholder for S0071 (only "此电脑" exists). Native `<select>` underlying so future devices light it up without UI work.
|
|
202
|
+
- Search input: 32 height, `--color-surface-soft` fill, hairline border, leading `Search 13`. Currently a no-op visual that filters nav items by label substring (S0071: nav-only filter).
|
|
203
|
+
- Group caption: 11 / 600 muted-faint uppercase, padding `12 12 4`.
|
|
204
|
+
- Item row: 30 height, padding `4 10`, radius 8, gap 10, font 13. Active = `--color-surface-raised` + `--shadow-ring`. Hover = `--color-surface-hover`. Active wins over hover.
|
|
205
|
+
|
|
206
|
+
#### 10.2 SettingsHeader
|
|
207
|
+
|
|
208
|
+
- H1 24 / 500, sub 13 muted, `了解更多` rendered as `<LinkAccent>`.
|
|
209
|
+
- Sits inside main pane top, padding `28 32 8`.
|
|
210
|
+
|
|
211
|
+
#### 10.3 SettingsCard / SettingsRow
|
|
212
|
+
|
|
213
|
+
- Card: `--color-surface-raised` (#FFFFFF), `--shadow-ring`, radius 12, no shadow. Children stacked vertically with 1px inner divider (`box-shadow: inset 0 -1px 0 var(--color-border-hairline)` on each row except last).
|
|
214
|
+
- Row: `[grow: label 14/500 + desc 12 muted] [shrink: control]`, padding `12 16`, min-height 56.
|
|
215
|
+
|
|
216
|
+
#### 10.4 ConfigSection
|
|
217
|
+
|
|
218
|
+
S0071 fold the existing Relay device functionality into the Config section:
|
|
219
|
+
|
|
220
|
+
- Card 1 — `自定义 config.toml 设置` (placeholder; toml editing out of scope).
|
|
221
|
+
- Profile select (placeholder): `用户配置 ▾`, with ghost link `打开 config.toml ↗` aligned right.
|
|
222
|
+
- Row `批准策略 / 选择何时请求批准` + Select(`从不 / 失败时 / 始终`) — disabled in S0071.
|
|
223
|
+
- Row `沙盒设置 / 选择命令执行权限` + Select(`完全访问 / 工作区写入 / 只读`) — disabled.
|
|
224
|
+
- Card 2 — `Relay Devices` (real, replaces old RelayDevicesPanel).
|
|
225
|
+
- Row `Relay URL` with input control (right side) + small `Pair` button.
|
|
226
|
+
- Row `已配对设备` with `Refresh` button trailing; below the row, render the device list as nested rows (no separate card) showing label, online dot, relay URL muted.
|
|
227
|
+
- When pair code present, render as a sub-card hint with the 6-digit code.
|
|
228
|
+
|
|
229
|
+
#### 10.5 GeneralSection
|
|
230
|
+
|
|
231
|
+
- Card — `外观` (theme).
|
|
232
|
+
- Row `主题 / 跟随系统、亮、暗` + Select disabled, defaults `跟随系统`.
|
|
233
|
+
- Card — `语言`.
|
|
234
|
+
- Row `语言` + Select disabled, defaults `中文`.
|
|
235
|
+
|
|
236
|
+
These are placeholders that look real but do nothing — keeps the nav from feeling empty without scope creep.
|
|
237
|
+
|
|
238
|
+
### 11. Sidebar settings entry
|
|
239
|
+
|
|
240
|
+
Sidebar bottom `设置` row keeps its place. Drop the trailing mobile icon. Click switches workspace → settings, settings header back row switches back. Same as before, just visual cleanup.
|
|
241
|
+
|
|
242
|
+
### 12. Files affected
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
apps/gui/src/renderer/styles.css # token reset + class rewrites
|
|
246
|
+
apps/gui/src/renderer/shell/Sidebar.tsx # tweaks
|
|
247
|
+
apps/gui/src/renderer/shell/ProjectTree.tsx # row layout
|
|
248
|
+
apps/gui/src/renderer/workspace/Topbar.tsx # drop PanelRight, height
|
|
249
|
+
apps/gui/src/renderer/workspace/EmptyState.tsx # H1 + spacing
|
|
250
|
+
apps/gui/src/renderer/composer/Composer.tsx # pill spacing + chip refits
|
|
251
|
+
apps/gui/src/renderer/composer/ProjectPickerPill.tsx # geometry
|
|
252
|
+
apps/gui/src/renderer/composer/ProjectPickerMenu.tsx # overlay rebuild
|
|
253
|
+
apps/gui/src/renderer/composer/AddRemoteProjectDialog.tsx # field + button refit
|
|
254
|
+
apps/gui/src/renderer/chatbox/TurnUser.tsx # bubble
|
|
255
|
+
apps/gui/src/renderer/chatbox/TurnAssistant.tsx # spacing
|
|
256
|
+
apps/gui/src/renderer/chatbox/Transcript.tsx # gap + width
|
|
257
|
+
apps/gui/src/renderer/chatbox/tool-blocks/*.tsx # chip rewrite
|
|
258
|
+
apps/gui/src/renderer/settings/SettingsPage.tsx # DELETED
|
|
259
|
+
apps/gui/src/renderer/settings/RelayDevicesPanel.tsx # DELETED
|
|
260
|
+
apps/gui/src/renderer/settings/SettingsShell.tsx # NEW
|
|
261
|
+
apps/gui/src/renderer/settings/SettingsNav.tsx # NEW
|
|
262
|
+
apps/gui/src/renderer/settings/SettingsHeader.tsx # NEW
|
|
263
|
+
apps/gui/src/renderer/settings/SettingsCard.tsx # NEW
|
|
264
|
+
apps/gui/src/renderer/settings/SettingsRow.tsx # NEW
|
|
265
|
+
apps/gui/src/renderer/settings/controls/Toggle.tsx # NEW
|
|
266
|
+
apps/gui/src/renderer/settings/controls/Select.tsx # NEW
|
|
267
|
+
apps/gui/src/renderer/settings/controls/LinkAccent.tsx # NEW
|
|
268
|
+
apps/gui/src/renderer/settings/sections/*.tsx # NEW (9 sections, 7 placeholders + 2 real)
|
|
269
|
+
apps/gui/src/renderer/App.tsx # mount SettingsShell instead of SettingsPage
|
|
270
|
+
apps/gui/src/renderer/icons/index.ts # add Monitor, ArrowUpRight if missing
|
|
271
|
+
docs/ROADMAP.md # add M9.F1.3 row + Active Specs row
|
|
272
|
+
docs/spec/ship/S0071-gui-visual-fidelity-and-settings-shell.md # this file
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## Non-Goals
|
|
278
|
+
|
|
279
|
+
- No new product features. No real toggling of `完全访问`, model picker, mic, theme, language, sandbox setting, or approval policy — all stay disabled placeholders or pure-visual selects.
|
|
280
|
+
- No anchored / floating-ui-style positioning for the picker overlay; centered overlay continues. Anchored placement is a follow-up if needed.
|
|
281
|
+
- No native macOS vibrancy / transparency effects. Solid surfaces only.
|
|
282
|
+
- No light/dark theme — single light theme; dark deferred.
|
|
283
|
+
- No new IPC channels.
|
|
284
|
+
- No webui changes.
|
|
285
|
+
- No `不使用项目`, no plugin recommendation cards, no review banner, no global `对话` history group (re-affirmed from S0069).
|
|
286
|
+
- No scroll-spy / search-jump in settings — search filters nav items by label substring only.
|
|
287
|
+
- No real config.toml parsing or editing.
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Acceptance Criteria
|
|
292
|
+
|
|
293
|
+
- Side-by-side visual diff against image2 / image3 / image6 / image7: layout proportions, type weight, spacing, color usage, chip styles, card geometry match within visual tolerance (no pixel-perfect requirement, but no obviously wrong typeface weight, padding, or color).
|
|
294
|
+
- Sidebar uses warm gray surface, sectioned project rows with inline sessions, active row reads as raised white card via inset ring (not surface-hover), no double-icon clutter on project rows.
|
|
295
|
+
- Composer pill matches image3: 24 radius, hairline border, warn-orange `完全访问` chip, black 32 send circle.
|
|
296
|
+
- Empty H1 reads as `我们应该在 {project} 中做些什么?` at 32px / 500 / center, with composer below at min(720, 100%) and project picker mini pill 12px below composer.
|
|
297
|
+
- Project picker overlay matches image4 visually: rounded card, hairline ring, leading 14 icons, divider, add-local / add-remote rows.
|
|
298
|
+
- Add Remote Project modal matches image5 visually: 520 panel, host select, path input + reset, directory list, footer cancel + black primary.
|
|
299
|
+
- Settings view matches image7: 256 nav, three caption groups, active item raised white, header with back / device selector / search input, right pane card-grouped rows. `配置` section opens by default and shows Relay URL + Pair + device list folded into the Codex-style card layout (toml settings rows are visual-only placeholders, but render with correct geometry).
|
|
300
|
+
- Tool blocks render as inline chip rows with leading icon, not bordered cards, except `TodoWriteBlock`.
|
|
301
|
+
- Markdown table borders, code block tint, paragraph spacing match the refit values above.
|
|
302
|
+
- All previously-working flows still work: add local project, send message, attach session, stream tokens, render specialized tool blocks, pair Relay device, refresh, add remote project, navigate sessions, switch settings ↔ workspace.
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## Test Requirements
|
|
307
|
+
|
|
308
|
+
```
|
|
309
|
+
pnpm --filter @scorel/app-gui build
|
|
310
|
+
pnpm --filter @scorel/app-gui typecheck
|
|
311
|
+
pnpm --filter @scorel/app-gui test
|
|
312
|
+
pnpm typecheck
|
|
313
|
+
pnpm test
|
|
314
|
+
pnpm pack:smoke
|
|
315
|
+
git diff --check
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Manual visual e2e (`pnpm --filter @scorel/app-gui dev`):
|
|
319
|
+
|
|
320
|
+
- Compare each surface against the matching reference screenshot.
|
|
321
|
+
- Settings: open every section in the nav; confirm placeholders render geometry without errors; confirm `配置` Relay URL / Pair / Refresh / device list still functions through the IPC path.
|
|
322
|
+
- Send one prompt that triggers Read + Edit + Bash + TodoWrite tool calls; confirm chip-style rendering and that opening a chip reveals body content.
|
|
323
|
+
|
|
324
|
+
No new automated tests are required beyond the existing `local-host`, `relay-service`, `gui-store`, `package-boundaries`, and `diff` suites continuing to pass. Visual fidelity is acceptance-by-eye.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Implementation Notes
|
|
329
|
+
|
|
330
|
+
- Token reset is the high-leverage change. Most "ugly" feedback on the current build comes from wrong neutrals (border too dark, surface too gray, raised state indistinguishable from hover) and wrong type sizes (H1 30 with default tracking, sidebar 13 muted across all rows). Hit those first.
|
|
331
|
+
- Where current Tailwind-flavored class names live in copied webui files (e.g. inside markdown components or shiki block), keep the renames lightweight: prefer extending plain class names defined in `styles.css` rather than inline styles. Inline styles are acceptable for one-off layout tweaks.
|
|
332
|
+
- `Select.tsx` wraps a native `<select>` so accessibility + keyboard nav come for free. Style the wrapper to look like a macOS popup button (chevron via lucide `ChevronDown`).
|
|
333
|
+
- `Toggle.tsx` is a controlled `<button role="switch" aria-checked>` — 28×16 track, 12 thumb, 100ms transform transition. Blue track when on, gray when off. (Animation duration is a hard cap; spec.md design.md disallows shadows but transitions are fine.)
|
|
334
|
+
- `SettingsNav` search filters the items array by `item.label.includes(query)`. No fuzzy matching.
|
|
335
|
+
- `SettingsShell` keeps view-mode local state (no router, consistent with S0069). Default selected section is `config` (matches image7 active row).
|
|
336
|
+
- For tool block chip refit, the visual change is significant but the data shape stays — only `tool-block` CSS plus per-block JSX restructure (icon order, no border container).
|
|
337
|
+
- Keep all chip rows accessible: `<button type="button" aria-expanded>` for the chip itself, body wrapped in a region with `aria-hidden` toggled by `open`.
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
## Risks
|
|
342
|
+
|
|
343
|
+
- Risk: token reset breaks existing component visuals (e.g. transcript-empty). Mitigation: refit goes class-by-class; run `pnpm --filter @scorel/app-gui build` after each major class group.
|
|
344
|
+
- Risk: native `<select>` styling diverges across macOS / Linux Electron builds. Mitigation: accept divergence; the Codex App reference is macOS — Linux/Windows users get a slightly different but still functional control.
|
|
345
|
+
- Risk: chip refit hides too much info on first render. Mitigation: error states (`isError = true`) auto-expand, matching S0070 behavior.
|
|
346
|
+
- Risk: settings nav gains 14 rows of which only 2 work — feels misleading. Mitigation: placeholders render `待开发` muted hint, no fake controls.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Out Of Scope (Reaffirmed)
|
|
351
|
+
|
|
352
|
+
- Real toml editing.
|
|
353
|
+
- Plugin recommendation cards.
|
|
354
|
+
- Bottom sidebar global "对话" history group.
|
|
355
|
+
- Composer review banner.
|
|
356
|
+
- "不使用项目" picker option.
|
|
357
|
+
- Functional model / mic / 完全访问 toggles.
|
|
358
|
+
- Dark mode.
|
|
359
|
+
- Reverse-reuse of GUI components in webui.
|
|
360
|
+
- SSH / direct WS + token / HTTP API.
|