@chanlerdev/scorel 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +409 -69
  2. package/dist/index.js +4593 -1751
  3. package/dist/index.js.map +4 -4
  4. package/docs/CHANGELOG.md +115 -0
  5. package/docs/ROADMAP.md +112 -9
  6. package/docs/SHIP.md +9 -3
  7. package/docs/spec/channels.md +107 -100
  8. package/docs/spec/client.md +11 -5
  9. package/docs/spec/extensions.md +115 -43
  10. package/docs/spec/ship/S0062-npm-package-and-release-workflow.md +3 -0
  11. package/docs/spec/ship/S0063-ai-release-notes.md +129 -0
  12. package/docs/spec/ship/S0064-gui-product-intent-and-boundary.md +79 -0
  13. package/docs/spec/ship/S0065-gui-electron-shell-and-embedded-host.md +73 -0
  14. package/docs/spec/ship/S0066-gui-local-project-workspace.md +79 -0
  15. package/docs/spec/ship/S0067-gui-relay-device-and-remote-project-selection.md +97 -0
  16. package/docs/spec/ship/S0068-gui-codex-app-polish-and-e2e.md +102 -0
  17. package/docs/spec/ship/S0068-gui-e2e-verification.md +50 -0
  18. package/docs/spec/ship/S0069-gui-codex-ui-refactor.md +371 -0
  19. package/docs/spec/ship/S0070-gui-streaming-and-tool-blocks.md +202 -0
  20. package/docs/spec/ship/S0071-gui-visual-fidelity-and-settings-shell.md +360 -0
  21. package/docs/spec/ship/S0072-gui-glass-sidebar-and-picker-anchoring.md +116 -0
  22. package/docs/spec/ship/S0073-provider-model-profile-contract.md +241 -0
  23. package/docs/spec/ship/S0074-gui-model-provider-settings-split.md +113 -0
  24. package/docs/spec/ship/S0075-provider-catalog-model-cards.md +93 -0
  25. package/docs/spec/ship/S0076-provider-modal-search-and-direct-key.md +70 -0
  26. package/docs/spec/ship/S0077-auxiliary-session-title-generation.md +95 -0
  27. package/docs/spec/ship/S0078-gui-provider-settings-forward-config-and-simplification.md +150 -0
  28. package/docs/spec/ship/S0079-gui-sidebar-layout-controls.md +49 -0
  29. package/docs/spec/ship/S0080-session-title-hook-and-gui-markdown-dark-code.md +58 -0
  30. package/docs/spec/ship/S0081-automatic-memory.md +117 -0
  31. package/docs/spec/ship/S0082-memory-journal-tool-and-idle-dream.md +107 -0
  32. package/docs/spec/ship/S0083-extension-manifest-and-im-channel-runtime.md +338 -0
  33. package/docs/spec/ship/S0084-built-in-telegram-im-extension.md +188 -0
  34. package/docs/spec/ship/S0085-gui-im-extension-settings.md +47 -0
  35. package/docs/spec/ship/S0086-auto-compact-and-session-memory.md +124 -0
  36. package/docs/spec/ship/S0087-gui-ui-polish-sweep.md +153 -0
  37. package/docs/spec/ship/S0088-gui-streaming-thinking-contract.md +35 -0
  38. package/docs/spec/ship/S0089-memory-reliability-and-dream-trigger.md +84 -0
  39. package/docs/spec/ship/S0090-gui-provider-delete-and-dark-code-theme.md +77 -0
  40. package/docs/spec/ship/S0091-built-in-qq-and-wechat-im-extensions.md +125 -0
  41. package/docs/spec/ship/S0092-im-message-media-and-human-cadence.md +83 -0
  42. package/docs/spec/ship/S0093-gui-im-settings-platform-layout.md +66 -0
  43. package/docs/spec/ship/S0094-im-inbound-runtime.md +67 -0
  44. package/docs/spec/ship/S0095-gui-im-session-list-refresh.md +36 -0
  45. package/extensions/builtin/loopback/adapter.js +13 -0
  46. package/extensions/builtin/loopback/scorel.extension.json +7 -0
  47. package/extensions/builtin/loopback/skills/loopback/SKILL.md +9 -0
  48. package/extensions/builtin/qq/adapter.d.ts +27 -0
  49. package/extensions/builtin/qq/adapter.js +384 -0
  50. package/extensions/builtin/qq/scorel.extension.json +7 -0
  51. package/extensions/builtin/qq/skills/qq/SKILL.md +9 -0
  52. package/extensions/builtin/telegram/adapter.d.ts +43 -0
  53. package/extensions/builtin/telegram/adapter.js +259 -0
  54. package/extensions/builtin/telegram/scorel.extension.json +7 -0
  55. package/extensions/builtin/telegram/skills/telegram/SKILL.md +11 -0
  56. package/extensions/builtin/wechat/adapter.d.ts +24 -0
  57. package/extensions/builtin/wechat/adapter.js +226 -0
  58. package/extensions/builtin/wechat/scorel.extension.json +7 -0
  59. package/extensions/builtin/wechat/skills/wechat/SKILL.md +9 -0
  60. package/package.json +6 -2
@@ -0,0 +1,116 @@
1
+ # S0072: GUI Glass Sidebar And Picker Anchoring
2
+
3
+ ## Goal
4
+
5
+ Tighten the Codex App alignment after S0071 using the latest reference screenshots:
6
+ make the GUI sidebar read as transparent macOS glass, remove user-visible entries for
7
+ features that are not implemented, fix the empty workspace copy, and anchor the project
8
+ picker to the project pill instead of floating in the center of the workspace.
9
+
10
+ This is a GUI polish follow-up only. It does not change Host, Relay, Session JSONL,
11
+ provider execution, or package distribution boundaries.
12
+
13
+ ## Scope
14
+
15
+ - Make the main sidebar and settings sidebar use translucent glass-like surfaces over
16
+ the Electron vibrancy window, while keeping light and dark theme tokens.
17
+ - Remove disabled placeholders for features that do not exist. In this spec that means
18
+ Search, Plugins, Automations, attachment add, permission policy dropdown, model picker,
19
+ microphone, placeholder Settings sections, disabled config controls, and fake config
20
+ links. Keep New Chat, Settings, Add Local Project, Add Remote Project, and Relay
21
+ pairing/refresh because those are implemented paths.
22
+ - Empty workspace copy:
23
+ - with no selected Project: `我们要构建什么?`
24
+ - with a selected Project: `我们应该在 {Project} 中构建什么?`
25
+ - Project picker visibility:
26
+ - when no Project is selected, keep a compact `选择项目` pill.
27
+ - when a Project is selected, show a compact project pill in the composer footer area,
28
+ not a long row that visually consumes the composer context strip.
29
+ - Sidebar `添加项目` must reuse the same project picker component and menu behavior as
30
+ the composer project pill. It must not bypass the picker and directly open the local
31
+ folder dialog.
32
+ - Project picker placement follows the trigger pill. The popover must be anchored near
33
+ the clicked pill and must not float in the center of the workspace.
34
+ - In the selected-project empty heading, `{Project}` is clickable and opens the same
35
+ project picker.
36
+ - Hide project metadata that is not currently backed by user-controllable GUI features,
37
+ including `本地模式`, `Relay 远程`, and `main`.
38
+ - Focusing the composer textarea must not add an extra outer ring around the whole
39
+ composer shell.
40
+ - Remove `不使用项目` from the picker. GUI remains Project-first per S0064.
41
+ - It is acceptable to keep implemented add actions: Add Local Project and Add Remote
42
+ Project.
43
+
44
+ ## Not In Scope
45
+
46
+ - Global Search implementation.
47
+ - Plugin, Automation, model picker, microphone, or permission-policy implementation.
48
+ - SSH remote device, direct WS + token, or HTTP API.
49
+ - WebUI reuse of GUI components.
50
+ - Replacing Electron with SwiftUI/AppKit.
51
+
52
+ ## Acceptance Criteria
53
+
54
+ - Sidebar visually reads as a macOS glass/source-list surface in both light and dark
55
+ themes, rather than an opaque flat panel.
56
+ - Primary sidebar shows only implemented top-level commands: New Chat and Settings,
57
+ plus Project list/add controls.
58
+ - Settings exposes only implemented controls in this pass: Relay pairing/refresh. It
59
+ must not show placeholder sections like MCP, Browser, Computer Control, Hooks, Git,
60
+ or disabled config controls.
61
+ - Empty workspace without a selected Project says `我们要构建什么?`.
62
+ - Empty workspace with a selected Project says `我们应该在 {Project} 中构建什么?`.
63
+ - The selected Project name inside that heading is an interactive project picker trigger.
64
+ - The sidebar add-project control and composer project control share the same picker
65
+ component and expose the same Add Local / Add Remote actions.
66
+ - Project picker opens next to the triggering pill, both from empty workspace and session
67
+ workspace, and is not centered on the page.
68
+ - Selected-project pill stays compact; it does not become a full-width `选择项目` strip.
69
+ - Picker contains Add Local Project and Add Remote Project, but no null-project option.
70
+ - Composer project context does not render unsupported mode/branch labels such as
71
+ `本地模式` or `main`.
72
+ - Textarea focus keeps the composer surface visually stable; no extra outer focus ring.
73
+ - Light and dark theme screenshots show the same structure, spacing, and hierarchy.
74
+
75
+ ## Test Requirements
76
+
77
+ - Add renderer tests that lock the empty workspace heading behavior and ensure disabled
78
+ placeholder sidebar/composer actions are not rendered.
79
+ - Add renderer tests that lock the selected Project heading trigger and ensure unsupported
80
+ mode/branch labels are not rendered.
81
+ - Add renderer tests that ensure Settings does not expose unimplemented placeholder
82
+ sections or fake config controls.
83
+ - Add a renderer test that locks the picker option set and confirms it does not include
84
+ `不使用项目`.
85
+ - Run:
86
+ - `pnpm --filter @scorel/app-gui typecheck`
87
+ - `pnpm --filter @scorel/app-gui test`
88
+ - `pnpm --filter @scorel/app-gui build`
89
+ - Run a real Electron visual smoke through CDP or Computer Use:
90
+ - empty workspace
91
+ - picker opened from the project pill
92
+ - settings shell
93
+ - dark theme using system theme or `data-theme="dark"` test override
94
+
95
+ ## Impacted Files
96
+
97
+ - `apps/gui/src/renderer/styles.css`
98
+ - `apps/gui/src/renderer/shell/Sidebar.tsx`
99
+ - `apps/gui/src/renderer/workspace/EmptyState.tsx`
100
+ - `apps/gui/src/renderer/workspace/SessionView.tsx`
101
+ - `apps/gui/src/renderer/composer/ProjectPickerMenu.tsx`
102
+ - `apps/gui/src/renderer/composer/ProjectPickerPill.tsx`
103
+ - `apps/gui/src/renderer/settings/SettingsNav.tsx`
104
+ - `apps/gui/src/renderer/settings/SettingsShell.tsx`
105
+ - `apps/gui/src/renderer/settings/sections/ConfigSection.tsx`
106
+ - GUI renderer tests under `apps/gui/src/renderer/`
107
+ - `docs/ROADMAP.md`
108
+
109
+ ## Risks And Boundaries
110
+
111
+ - Electron vibrancy differs by OS and accessibility settings. CSS must still provide
112
+ readable fallback colors when vibrancy is unavailable.
113
+ - Hidden placeholder removal should not delete future roadmap intent; it only removes
114
+ non-functional user-visible controls from the current GUI.
115
+ - The picker anchor should use DOM geometry only in the renderer. It must not introduce
116
+ new IPC channels or main-process UI state.
@@ -0,0 +1,241 @@
1
+ # S0073: Provider Model Profile Contract
2
+
3
+ ## Goal
4
+
5
+ Turn Scorel's current single configured model into a real provider/model profile
6
+ contract that GUI, Host runtime, CLI, and future subagents can share:
7
+
8
+ - keep pi-ai as the lower provider/model abstraction;
9
+ - let users configure pi-ai built-in providers and custom compatible endpoints;
10
+ - expose a curated available-model pool instead of every provider catalog entry;
11
+ - assign three role aliases from that pool: `primary`, `standard`, and `auxiliary`;
12
+ - use the selected model's real metadata for runtime execution, session metadata, and
13
+ context-window-sensitive tools;
14
+ - make GUI Settings and composer model selection reflect implemented product paths.
15
+
16
+ The business outcome is simple: Scorel stops pretending there is only one model, but
17
+ does not jump into a full provider marketplace or routing policy engine.
18
+
19
+ ## Scope
20
+
21
+ ### 1. Config contract
22
+
23
+ Update `docs/spec/extensions.md` and the runtime config schema from one `[model]`
24
+ section to a model profile contract.
25
+
26
+ The new shape must support:
27
+
28
+ - provider definitions:
29
+ - pi-ai built-in provider entries;
30
+ - custom compatible endpoint entries with explicit API shape;
31
+ - provider model entries under those providers:
32
+ - stable `id`;
33
+ - provider reference;
34
+ - pi-ai model id;
35
+ - display name;
36
+ - optional role suitability metadata only when it is needed by UI;
37
+ - required metadata for custom models: `contextWindow`, `maxTokens`, `reasoning`,
38
+ and compatibility flags where needed;
39
+ - available model entries:
40
+ - stable available-model id;
41
+ - reference to one provider model;
42
+ - optional display override;
43
+ - role assignments:
44
+ - `primary`;
45
+ - `standard`;
46
+ - `auxiliary`.
47
+
48
+ The schema must reject unknown sections/keys through the shared schema path. Do not add
49
+ ad hoc special cases for one invalid key.
50
+
51
+ Backward compatibility with the old single `[model]` config or intermediate
52
+ `[models.*]` config is not required. Scorel is pre-1.0, has no production config
53
+ inventory to preserve, and `docs/SHIP.md` allows explicit config breaks when the
54
+ current spec says so.
55
+
56
+ ### 2. Provider/model resolution
57
+
58
+ Keep provider execution under `packages/core/src/provider/pi-ai.ts`.
59
+
60
+ Add a resolver that can:
61
+
62
+ - list the configured available model summaries;
63
+ - resolve a model by available-model id;
64
+ - resolve a model by role alias;
65
+ - create the correct pi-ai `Model<Api>` for both built-in and custom entries;
66
+ - return the model's `contextWindow` for tool budgets.
67
+
68
+ Scorel must not reimplement provider request protocols. It should continue to pass the
69
+ resolved pi-ai model and API key to pi-ai.
70
+
71
+ ### 3. Host/runtime selection
72
+
73
+ Host runtime must use the selected model for each session/turn:
74
+
75
+ - default new sessions use `standard` unless the caller explicitly chooses another
76
+ available model or role;
77
+ - CLI can continue using the default role without exposing a new command flag in this
78
+ spec;
79
+ - GUI composer can choose an available model for new prompts/sessions;
80
+ - session metadata records the selected model id and role when known;
81
+ - session header persists enough selected-model metadata to keep resume auditable if
82
+ config later changes;
83
+ - assistant events keep recording actual provider/model metadata from pi-ai.
84
+
85
+ Tool creation must use the actual selected model's context window, not a global model
86
+ from startup config.
87
+
88
+ ### 4. Protocol/client surface
89
+
90
+ Expose a Host API that lets clients inspect provider connections, provider models, the
91
+ available model pool, and role assignment.
92
+
93
+ The response must be display-safe:
94
+
95
+ - no API keys;
96
+ - no raw provider payloads;
97
+ - no Relay-visible credentials;
98
+ - enough provider connection metadata for UI labels, role badges, and disabled/error
99
+ states;
100
+ - `apiKeyEnv` is allowed in display responses, but raw `apiKey` values are not;
101
+ - missing provider env vars are reported as credential status, not as `list_models`
102
+ failures;
103
+ - if the target Project has no model profile config yet, `list_models` returns an empty
104
+ model list instead of surfacing config-not-found as a user-facing error.
105
+
106
+ Expose a Host API for adding/updating a Project's provider/model profile. GUI must use
107
+ this Host-owned path for both local and Relay Projects; renderer code must not write
108
+ `.scorel/config.toml` directly.
109
+
110
+ Saving a provider/model profile is a config edit, not a provider call. It must validate
111
+ shape and merge into the existing Project config, but it must not require the target
112
+ Host process to already have the provider API key env var set. Missing credentials
113
+ should block runtime use, not saving.
114
+
115
+ ### 5. GUI surface
116
+
117
+ Settings separates model management from connection management:
118
+
119
+ - `模型`: provider/model profile and available models;
120
+ - `连接`: Relay pair/refresh and remote devices.
121
+
122
+ The Model settings page must support adding a provider/model profile:
123
+
124
+ - show configured provider connections as source entries;
125
+ - show provider models under the configured provider connections;
126
+ - show available models / use pool separately from provider models;
127
+ - show role assignments for `primary`, `standard`, and `auxiliary`;
128
+ - add or update a provider connection;
129
+ - add or update provider models under a provider connection;
130
+ - add a provider model into available models before it can be used by composer, main
131
+ agent, or future subagents;
132
+ - support one provider connection with multiple configured models without overwriting
133
+ previously-added models;
134
+ - show missing credential status clearly without treating it as a save failure;
135
+ - show invalid model/profile errors clearly.
136
+
137
+ Composer gets a real model picker:
138
+
139
+ - it lists available models from the connected Host;
140
+ - selecting a model affects the current new session / next prompt path according to the
141
+ runtime contract;
142
+ - it must not list arbitrary provider catalog entries that are not in available models.
143
+
144
+ The UI should use generic role language, not Anthropic-specific names such as Opus,
145
+ Sonnet, or Haiku.
146
+
147
+ ### 6. Subagent contract only
148
+
149
+ This spec defines the model-selection contract future subagents must use:
150
+
151
+ - default subagent selection is role-based (`primary`, `standard`, `auxiliary`);
152
+ - explicit subagent model override, when added later, must point to an available model id;
153
+ - subagents must not bypass the available-model pool.
154
+
155
+ This spec does not implement a new subagent execution engine.
156
+
157
+ ## Not In Scope
158
+
159
+ - OAuth or browser-based provider login.
160
+ - Provider marketplace, pricing comparison, latency benchmarking, automatic model ranking,
161
+ fallback chains, or policy-based routing.
162
+ - Dynamic remote catalog sync for every provider. Built-in pi-ai catalog and configured
163
+ custom model entries are enough for V1.
164
+ - Storing raw API keys in GUI state or config. GUI only stores `apiKeyEnv`; users set
165
+ the environment variable on the target Host.
166
+ - Full subagent orchestration.
167
+ - Per-tool model routing.
168
+ - Per-message hidden model switching not visible in session metadata.
169
+ - Relay storage of provider credentials, prompt text, provider payloads, or model routing
170
+ internals.
171
+
172
+ ## Acceptance Criteria
173
+
174
+ - `docs/spec/extensions.md` documents the new provider/model profile config and clearly
175
+ states that old single `[model]` config is replaced.
176
+ - Config tests cover:
177
+ - one built-in provider with three available role assignments;
178
+ - one custom compatible endpoint with manual metadata;
179
+ - rejecting unknown model/profile keys;
180
+ - rejecting a role that points outside the available model pool;
181
+ - rejecting a missing provider credential env var.
182
+ - Core/provider tests cover:
183
+ - resolving a built-in available model through pi-ai;
184
+ - resolving a custom available model;
185
+ - resolving role aliases to available models;
186
+ - using the selected model's context window.
187
+ - Daemon/client tests cover:
188
+ - model profile summary is exposed without API keys;
189
+ - a Project with no model config returns an empty model profile summary;
190
+ - adding/updating a provider/model profile writes a valid `.scorel/config.toml`
191
+ without requiring API key env vars;
192
+ - adding a second model under the same provider preserves the existing provider and
193
+ model entries;
194
+ - new sessions default to `standard`;
195
+ - explicit selected model id and resolved display metadata are persisted in session
196
+ metadata;
197
+ - resumed sessions use the persisted selected model rather than silently switching
198
+ because current config changed;
199
+ - runtime uses the selected model when creating the provider and coding tools.
200
+ - GUI tests cover:
201
+ - Settings renders separate `模型` and `连接` pages;
202
+ - Model settings supports adding a provider/model profile;
203
+ - composer renders a real model picker, not a disabled placeholder;
204
+ - picker options are limited to available models;
205
+ - role labels are generic (`primary`, `standard`, `auxiliary`) and not hard-coded to
206
+ Anthropic names.
207
+ - Run:
208
+ - `pnpm --filter @scorel/core test`
209
+ - `pnpm --filter @scorel/daemon test`
210
+ - `pnpm --filter @scorel/app-gui typecheck`
211
+ - `pnpm --filter @scorel/app-gui test`
212
+ - `pnpm typecheck && pnpm test`
213
+ - Run one real-provider product smoke with a real configured model profile. Mock/fake
214
+ provider is not accepted as completion proof for the product path.
215
+
216
+ ## Impacted Files
217
+
218
+ - `docs/spec/extensions.md`
219
+ - `docs/ROADMAP.md`
220
+ - `packages/core/src/config/index.ts`
221
+ - `packages/core/src/config/config.test.ts`
222
+ - `packages/core/src/provider/pi-ai.ts`
223
+ - `packages/core/src/provider/pi-ai.test.ts`
224
+ - `packages/core/src/tools/coding-tools.ts`
225
+ - `packages/daemon/src/index.ts`
226
+ - daemon tests under `packages/daemon/src/`
227
+ - protocol/client types under `packages/protocol/src/` and `packages/client/src/` if the
228
+ Host API needs new messages
229
+ - GUI renderer and tests under `apps/gui/src/renderer/`
230
+
231
+ ## Risks And Boundaries
232
+
233
+ - pi-ai built-in catalog metadata is local package data; provider-side model availability
234
+ can drift. Runtime errors must clearly say which configured provider/model failed.
235
+ - Custom endpoints may not expose reliable model catalogs. V1 should require explicit
236
+ custom model metadata instead of guessing.
237
+ - Changing default role assignments must not rewrite historical session events.
238
+ - Larger context windows directly affect Read output budgets. Tests must prove the
239
+ selected model drives the budget.
240
+ - A broad "login provider" abstraction would be misleading for API-key custom endpoints.
241
+ Use "provider connection" or "provider config" unless real OAuth/login is implemented.
@@ -0,0 +1,113 @@
1
+ # S0074: GUI Model And Provider Settings Split
2
+
3
+ ## Goal
4
+
5
+ Make GUI Settings model configuration match the user workflow:
6
+
7
+ 1. choose the three working models Scorel actually uses;
8
+ 2. maintain the curated available-model pool;
9
+ 3. manage LLM provider connections and provider-level models separately.
10
+
11
+ The business outcome is that users can understand where a model comes from, whether it
12
+ is allowed for Scorel use, and which model powers each agent role without reading TOML.
13
+
14
+ ## Scope
15
+
16
+ ### 1. Settings navigation
17
+
18
+ Split the current model/provider combined page into three settings pages:
19
+
20
+ - `模型`: working model role assignment and available models;
21
+ - `Provider`: LLM provider connections and provider model/source management;
22
+ - `连接`: Relay pairing and remote device connection management.
23
+
24
+ `Provider` is intentionally separate from `连接`: LLM providers are model suppliers,
25
+ while `连接` is about remote Scorel devices and Relay.
26
+
27
+ ### 2. Model page
28
+
29
+ The `模型` page must show:
30
+
31
+ - a top section for choosing `Primary`, `Standard`, and `Auxiliary` from available
32
+ models only;
33
+ - an available models section showing alias, display name, source provider model,
34
+ provider/model id, and current role usage;
35
+ - controls to add a provider model into available models.
36
+
37
+ The page must not expose provider connection fields such as `baseUrl`, `apiKeyEnv`, or
38
+ provider protocol controls.
39
+
40
+ ### 3. Provider page
41
+
42
+ The `Provider` page must show:
43
+
44
+ - a left provider list;
45
+ - a right scrollable provider details panel with `providerId`, provider type, protocol
46
+ / API shape, `baseUrl`, and `apiKeyEnv`;
47
+ - the provider's models below the provider details, with an action to stage/add a model
48
+ into available models;
49
+ - manual provider model entry for V1.
50
+
51
+ V1 can display configured provider models as the provider model source list. Real remote
52
+ catalog sync from provider `/v1/models` is not part of this spec, but the UI should be
53
+ shaped so that future catalog data can replace the configured list without changing the
54
+ page hierarchy.
55
+
56
+ ### 4. Existing Host contract
57
+
58
+ Continue using the Host-owned `list_models` and `upsert_model_profile` path. Renderer
59
+ code must not write `.scorel/config.toml` directly.
60
+
61
+ This spec can reuse the S0073 data model and does not need a new protocol message unless
62
+ the UI needs one for clean implementation.
63
+
64
+ ## Not In Scope
65
+
66
+ - Fetching provider `/v1/models` catalogs.
67
+ - OAuth/browser provider login.
68
+ - Storing raw API keys.
69
+ - Pricing, benchmarking, automatic model ranking, routing policy, or fallback chains.
70
+ - Changing runtime model selection semantics from S0073.
71
+ - Renaming `primary`, `standard`, or `auxiliary`.
72
+
73
+ ## Acceptance Criteria
74
+
75
+ - Settings nav shows separate `模型`, `Provider`, and `连接` pages.
76
+ - `模型` page renders working model role selectors before available models.
77
+ - `模型` page does not render provider connection fields.
78
+ - `Provider` page renders a provider list and a scrollable provider details area.
79
+ - `Provider` page exposes provider fields and provider models/source list.
80
+ - Available models can still be added from a provider model through the Host upsert path.
81
+ - Missing credentials remain status-only in Settings and do not block saving config.
82
+ - A project with no model config still renders empty model/provider settings without
83
+ throwing.
84
+
85
+ ## Test Requirements
86
+
87
+ - GUI rendering tests cover the three settings nav entries.
88
+ - GUI rendering tests assert `模型` and `Provider` content are separated.
89
+ - Existing daemon/config tests for S0073 must continue to pass.
90
+ - Run:
91
+ - `pnpm --filter @scorel/app-gui test`
92
+ - `pnpm --filter @scorel/app-gui build`
93
+ - `pnpm typecheck`
94
+ - `pnpm test`
95
+
96
+ ## Impacted Files
97
+
98
+ - `docs/spec/ship/S0074-gui-model-provider-settings-split.md`
99
+ - `docs/ROADMAP.md`
100
+ - `apps/gui/src/renderer/settings/SettingsShell.tsx`
101
+ - `apps/gui/src/renderer/settings/sections/ModelSection.tsx`
102
+ - new provider settings section under `apps/gui/src/renderer/settings/sections/`
103
+ - `apps/gui/src/renderer/styles.css`
104
+ - GUI renderer tests under `apps/gui/src/renderer/`
105
+
106
+ ## Risks And Boundaries
107
+
108
+ - Splitting pages must not duplicate divergent save logic. Both pages should continue
109
+ using the same Host profile upsert API.
110
+ - Provider model source list can be mistaken for live catalog sync. V1 copy must be
111
+ clear that it is the configured provider models list until remote catalog sync exists.
112
+ - `Provider` must not be folded into `连接`, or users will confuse LLM suppliers with
113
+ Relay/remote device connectivity.
@@ -0,0 +1,93 @@
1
+ # S0075: Provider Catalog Model Cards
2
+
3
+ ## Goal
4
+
5
+ Make the GUI Provider settings page usable for real provider setup:
6
+
7
+ - "新建 provider" must visibly reset the details panel for a new provider;
8
+ - provider models should be shown as selectable model cards, not a table plus an
9
+ always-expanded form;
10
+ - the Provider page should fetch models from the provider `/models` endpoint from the
11
+ Host side, then let users choose which fetched models become available models.
12
+
13
+ ## Scope
14
+
15
+ ### 1. Host catalog API
16
+
17
+ Add a Host-owned request that fetches a provider's model catalog for a Project:
18
+
19
+ - input: `projectId`, `providerId`;
20
+ - output: a display-safe list of catalog models with `id` and `displayName`;
21
+ - renderer never reads raw API keys;
22
+ - missing credentials return a user-facing error;
23
+ - custom OpenAI-compatible providers use `GET {baseUrl}/models` with bearer auth.
24
+
25
+ For V1, only OpenAI-compatible `/models` catalog fetch is required. Built-in pi-ai
26
+ catalog and non-OpenAI protocols can be handled by later specs.
27
+
28
+ ### 2. Provider page interaction
29
+
30
+ Update `Provider` settings:
31
+
32
+ - right top header has a `获取模型` button;
33
+ - provider model source list is rendered as compact cards/blocks;
34
+ - cards are collapsed by default;
35
+ - clicking a card expands its model config details;
36
+ - each card has a button state representing whether the model is selected into
37
+ available models (`选用` / `已选用`);
38
+ - manual add remains available for users to add a model not returned by `/models`;
39
+ - clicking `新建 provider` clears/selects a new-provider editing state instead of
40
+ appearing to do nothing.
41
+
42
+ ## Not In Scope
43
+
44
+ - Full provider catalog sync persistence or background refresh.
45
+ - Pricing, latency, model ranking, routing policy, or fallback chains.
46
+ - OAuth/browser login.
47
+ - API key storage.
48
+ - Dynamic metadata discovery for `contextWindow`, `maxTokens`, or reasoning support.
49
+
50
+ ## Acceptance Criteria
51
+
52
+ - GUI shows a `获取模型` button on the Provider page.
53
+ - Clicking `新建 provider` changes the details panel to a new provider draft.
54
+ - Provider model entries render as collapsed cards by default.
55
+ - Clicking a model card expands details/config controls.
56
+ - Model card action shows `选用` when not in available models and `已选用` when already
57
+ selected.
58
+ - Host catalog fetch uses `/models` for custom OpenAI-compatible providers.
59
+ - Renderer uses IPC/client API for catalog fetch and never reads provider API keys.
60
+
61
+ ## Test Requirements
62
+
63
+ - Protocol/client tests cover the new catalog fetch request shape.
64
+ - Daemon test covers fetching from a real local HTTP `/models` endpoint.
65
+ - GUI rendering test covers `获取模型`, collapsed model cards, and selected state text.
66
+ - Run:
67
+ - `pnpm --filter @scorel/daemon test`
68
+ - `pnpm --filter @scorel/app-gui test`
69
+ - `pnpm --filter @scorel/app-gui build`
70
+ - `pnpm typecheck`
71
+ - `pnpm test`
72
+
73
+ ## Impacted Files
74
+
75
+ - `docs/spec/ship/S0075-provider-catalog-model-cards.md`
76
+ - `docs/ROADMAP.md`
77
+ - `packages/protocol/src/events.ts`
78
+ - `packages/protocol/src/wire.ts`
79
+ - `packages/client/src/index.ts`
80
+ - `packages/daemon/src/index.ts`
81
+ - `apps/gui/src/shared/ipc.ts`
82
+ - `apps/gui/src/main.ts`
83
+ - `apps/gui/src/main/local-host.ts`
84
+ - `apps/gui/src/main/relay-service.ts`
85
+ - `apps/gui/src/renderer/settings/sections/ProviderSection.tsx`
86
+ - `apps/gui/src/renderer/styles.css`
87
+
88
+ ## Risks And Boundaries
89
+
90
+ - `/models` responses often lack context window and max token metadata. Users may still
91
+ need to expand a card and fill metadata before saving custom provider models.
92
+ - Some providers do not implement OpenAI-compatible `/models`; V1 should fail clearly
93
+ instead of pretending every protocol has a shared catalog endpoint.
@@ -0,0 +1,70 @@
1
+ # S0076: Provider Modal Search And Direct API Key
2
+
3
+ ## Goal
4
+
5
+ Polish the GUI model/provider settings flow so users can configure real providers
6
+ without confusing provider names, drafts, or credential setup:
7
+
8
+ - provider display should show the LLM provider name, not a model path;
9
+ - `Models from provider` should be searchable;
10
+ - creating a provider should happen in a modal and only persist after save;
11
+ - users can paste a direct API key instead of only referencing an env var.
12
+
13
+ ## Scope
14
+
15
+ ### 1. Provider name display
16
+
17
+ Provider values may arrive as path-like strings during development, such as
18
+ `AMP/codex/gpt-5.3-codex-spark`. GUI model summaries should display only the
19
+ provider segment before the first `/`, while model ids keep the full model id.
20
+
21
+ When saving a provider from GUI, normalize the provider field to that first segment.
22
+
23
+ ### 2. Provider catalog search
24
+
25
+ The Provider page `Models from provider` panel gets a search input that filters
26
+ configured provider models and fetched `/models` catalog cards by display name,
27
+ provider model key, or provider model id.
28
+
29
+ ### 3. New provider modal
30
+
31
+ Clicking `新建 provider` opens a modal form. The provider list and detail panel do not
32
+ change until the user saves the modal. Canceling closes the modal without creating or
33
+ selecting a draft provider.
34
+
35
+ ### 4. Direct API key
36
+
37
+ Provider config supports either:
38
+
39
+ - `apiKeyEnv`, resolved from environment variables; or
40
+ - `apiKey`, stored directly in `.scorel/config.toml`.
41
+
42
+ GUI never receives direct API key values when listing providers. Editing an existing
43
+ direct-key provider shows only that a direct key is configured. Saving a provider with
44
+ the API key field left blank preserves the existing direct key.
45
+
46
+ ## Not In Scope
47
+
48
+ - OS keychain storage or encryption-at-rest.
49
+ - Migrating existing env-key providers to direct-key providers automatically.
50
+ - Provider delete / duplicate / reorder controls.
51
+ - Advanced catalog metadata beyond `/models` id/name.
52
+
53
+ ## Acceptance Criteria
54
+
55
+ - Model settings show provider names using the segment before `/`.
56
+ - Provider page has a search input for `Models from provider`.
57
+ - `新建 provider` opens a modal; canceling it persists nothing.
58
+ - Saving a provider from the modal creates the provider and then selects it.
59
+ - Users can provide either an env var name or a direct API key.
60
+ - Provider list/status differentiates env and direct credentials without exposing raw
61
+ direct API key values through IPC.
62
+ - `/models` fetch works with both env-key and direct-key providers.
63
+
64
+ ## Test Requirements
65
+
66
+ - Config tests cover direct API key loading, redacted profile listing, and provider
67
+ model upsert preserving existing direct keys.
68
+ - GUI rendering tests cover provider search, new provider modal trigger, direct API key
69
+ fields, and provider display normalization.
70
+ - Typecheck and GUI build pass.