@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,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.
|