@chanlerdev/scorel 0.0.3 → 0.0.4

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/docs/CHANGELOG.md CHANGED
@@ -2,6 +2,59 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.0.4 - 2026-06-14
6
+
7
+ ### Highlights
8
+
9
+ - Config is now device-scoped only; project-level config is no longer read or written.
10
+ - GUI settings are device-scoped with relay device rename and project scope selector.
11
+ - Local daemon is a singleton background process with idle shutdown and shared state root.
12
+ - RTK token saving settings available in GUI for Bash execution.
13
+
14
+ ### Changes
15
+
16
+ - GUI connection settings default to official Relay URL; editing requires explicit click.
17
+ - Pairing button label changed to 'Get Pair Code'.
18
+ - Paired Relay devices can be renamed locally; name persists across refresh.
19
+ - Provider delete button moved to a danger zone at bottom of settings panel.
20
+ - Token-saving statistics labels changed to Chinese (Bash 输出 Token / 已节省 Token).
21
+ - RTK token saving can be enabled/disabled in GUI settings, persisted in project config.
22
+ - Cumulative RTK savings stats are maintained across sessions and projects.
23
+ - RTK is detected from default shell; can be installed via Homebrew if missing.
24
+
25
+ ### Fixes
26
+
27
+ - Glob results are now sorted by workspace-relative path for deterministic ordering across platforms.
28
+
29
+ ### Breaking Changes
30
+
31
+ - Runtime no longer reads project `.scorel/config.toml`; existing project configs are ignored.
32
+ - GUI local projects and sessions are now stored under `~/.scorel/` instead of `~/.scorel/gui/`; old state is not migrated automatically.
33
+
34
+ ### Verification
35
+
36
+ - Core config tests prove project config is ignored and device config is used.
37
+ - Daemon embedded tests prove settings writes with projectId write device config only.
38
+ - GUI rendering tests confirm device-scoped selector, provider delete placement, and Chinese token labels.
39
+ - New local-host test verifies device config writes to ~/.scorel/config.toml.
40
+ - E2E CDP script validates shared state paths and daemon lifecycle.
41
+ - Unit tests cover RTK detection, Bash execution with RTK, and runtime stats recording.
42
+
43
+ ### Internal
44
+
45
+ - `scorel host start` launches a singleton background daemon; `scorel host serve` gains `--idle-timeout-ms` flag.
46
+ - `scorel up` ensures daemon is running but no longer owns its lifecycle.
47
+ - GUI attaches to singleton daemon instead of running embedded Host.
48
+ - gui-store.json lives at `~/.scorel/gui-store.json`.
49
+
50
+ - Add `scorel host start` for background singleton Host startup; `scorel up` now leaves the singleton Host running when WebUI exits.
51
+ - GUI local Host state now uses the shared `~/.scorel` root for Projects and Sessions, with `gui-store.json` stored at `~/.scorel/gui-store.json`.
52
+ - GUI starts and attaches to the singleton local daemon instead of starting a second local Host writer.
53
+ - Local daemon now idle-shuts down when there are no clients, no active work, and no active IM extensions; active IM keeps it alive until explicit stop.
54
+ - GUI connection settings now default to the official Relay, hide Relay URL editing behind an edit action, show `Get Pair Code`, support paired-device rename/details, and use a device-scoped settings selector.
55
+ - GUI Provider settings now place `删除提供商` in the Provider configuration block, token-saving stats use clear Chinese labels, and Relay device rows expose expand/edit affordances.
56
+ - Config loading now uses the device config only; Project `.scorel/config.toml` is no longer a runtime or Settings config source.
57
+
5
58
  ## 0.0.3 - 2026-06-12
6
59
 
7
60
  ### Highlights
package/docs/ROADMAP.md CHANGED
@@ -303,7 +303,7 @@ M5 WebUI 的正式产品方向记录在 [`S0030`](spec/ship/S0030-webui-product-
303
303
  - `scorel daemon serve` 全部 flag 有合理默认;token 在 `~/.scorel/daemon.json` 持久化,跨重启复用。
304
304
  - `~/.scorel/daemon.json` 不再每次启动删除;通过 pid liveness + `stoppedAt` 判存活。
305
305
  - WebUI Settings 页面通过 `/api/local-daemon` server route 自动发现本地 daemon,一键添加 device。
306
- - `scorel up` 同时拉起 daemon serve + webui,Ctrl+C 一并退出。
306
+ - `scorel up` 确保 singleton daemon 可用并启动 WebUI;退出 `scorel up` 不关闭后台 daemon;无 client/无 active work/无 active IM 后 idle 自动退出。
307
307
  - 全部改动通过自动测试,真实 LLM 手工烟雾通过。
308
308
 
309
309
  **Steps**:
@@ -315,7 +315,7 @@ M5 WebUI 的正式产品方向记录在 [`S0030`](spec/ship/S0030-webui-product-
315
315
  **Not in M5.6**:
316
316
 
317
317
  - WebUI 多 daemon 切换 UI;每用户单 daemon 假设。
318
- - 自动 supervisor / restart;仍需手工 `scorel daemon stop && serve`。
318
+ - restart-on-crash supervisor;仍需手工 `scorel host stop && start`。
319
319
  - Windows 专属 PID 语义。
320
320
  - TLS / OAuth / 公网隧道。
321
321
 
@@ -592,6 +592,12 @@ M5 WebUI 的正式产品方向记录在 [`S0030`](spec/ship/S0030-webui-product-
592
592
  | M9.F1.16 | [`S0087`](spec/ship/S0087-gui-ui-polish-sweep.md) | Codex-inspired GUI visual pass:学习 Codex 的比例、层级和克制风格,并把 GUI tool blocks 收敛为低噪声执行证据流 | Done |
593
593
  | M9.F1.17 | [`S0088`](spec/ship/S0088-gui-streaming-thinking-contract.md) | Streaming thinking contract:补 thinking/content delta,使 thinking 在 turn 运行中按序显示,而不是最终 assistant_message 后才插入 | Done |
594
594
  | M9.F1.18 | [`S0089`](spec/ship/S0089-memory-reliability-and-dream-trigger.md) | Memory reliability:修复 AppendDaily 调用质量、dreaming 触发与可观测性,让 M9 后半段聚焦真实使用中的质量优化 | Done |
595
+ | M9.F1.19 | [`S0097`](spec/ship/S0097-rtk-token-saving-settings.md) | GUI Token 节省设置 + RTK Bash output proxy + runtime config | Done |
596
+ | M9.F1.20 | [`S0098`](spec/ship/S0098-local-daemon-singleton-unified-state.md) | 统一本机 Host state root、后台 singleton start、GUI/CLI auto-start + attach、idle shutdown、active IM 保活 | Done |
597
+ | M9.F1.21 | [`S0099`](spec/ship/S0099-gui-connection-device-settings.md) | GUI 连接设置默认官方 Relay、配对设备命名/详情、Settings scope 初版 | Done |
598
+ | M9.F1.22 | [`S0100`](spec/ship/S0100-gui-provider-danger-zone.md) | GUI Provider 删除按钮位置初版 | Done |
599
+ | M9.F1.23 | [`S0101`](spec/ship/S0101-gui-device-settings-polish.md) | GUI Settings 改为设备级配置,修正 Provider 删除位置、Token 文案、设备展开/重命名交互 | Done |
600
+ | M9.F1.24 | [`S0102`](spec/ship/S0102-device-only-config.md) | Config 彻底收敛为设备级唯一配置,移除 Project config 运行时语义 | Done |
595
601
 
596
602
  **Not in M9 Follow-up**:
597
603
 
@@ -761,6 +767,13 @@ HTTP adapter 必须映射已有 Host use cases,不复制领域逻辑。
761
767
  | [`S0093`](spec/ship/S0093-gui-im-settings-platform-layout.md) | GUI IM Settings platform layout | Done |
762
768
  | [`S0094`](spec/ship/S0094-im-inbound-runtime.md) | IM inbound runtime receive paths | Done |
763
769
  | [`S0095`](spec/ship/S0095-gui-im-session-list-refresh.md) | GUI IM session list refresh | Done |
770
+ | [`S0096`](spec/ship/S0096-glob-stable-order.md) | Glob stable cross-platform ordering | Done |
771
+ | [`S0097`](spec/ship/S0097-rtk-token-saving-settings.md) | RTK token saving settings and Bash output proxy | Done |
772
+ | [`S0098`](spec/ship/S0098-local-daemon-singleton-unified-state.md) | Local daemon singleton and unified state | Done |
773
+ | [`S0099`](spec/ship/S0099-gui-connection-device-settings.md) | GUI connection device settings | Done |
774
+ | [`S0100`](spec/ship/S0100-gui-provider-danger-zone.md) | GUI Provider danger-zone placement | Done |
775
+ | [`S0101`](spec/ship/S0101-gui-device-settings-polish.md) | GUI device-scoped Settings polish | Done |
776
+ | [`S0102`](spec/ship/S0102-device-only-config.md) | Device-only config | Done |
764
777
 
765
778
  ---
766
779
 
package/docs/SHIP.md CHANGED
@@ -35,7 +35,7 @@ open https://scorel.chanler.dev
35
35
  pnpm scorel pair <pair-code>
36
36
  ```
37
37
 
38
- `scorel host serve` 会启动本机 Host、注册当前目录为初始 Project,并默认连接官方 Relay。`scorel up` / `pnpm dev` 只作为本地开发便利入口:本地 Host + 本地 WebUI。
38
+ `scorel host serve` 会以前台调试模式启动本机 Host、注册当前目录为初始 Project,并默认连接官方 Relay。`scorel host start` 会启动或复用后台 singleton Host,并返回到 shell;`scorel host stop` 显式关闭它。`scorel up` / `pnpm dev` 只作为本地开发便利入口:确保后台 Host 可用,然后启动本地 WebUI,但不拥有 Host 生命周期。后台 Host 无 client、无 active work、无 active IM 时会按 idle timeout 自动退出;active IM 会保持 Host 存活。
39
39
 
40
40
  ---
41
41
 
@@ -152,11 +152,12 @@ class PromptBuilder {
152
152
 
153
153
  **格式**:TOML
154
154
 
155
- **读取顺序**(高 → 低):
156
- 1. `.scorel/config.toml`(项目级)
157
- 2. `~/.scorel/config.toml`(用户级)
155
+ **读取路径**:
156
+ 1. `~/.scorel/config.toml`(用户级 / 设备级唯一 config)
158
157
 
159
- `~/.scorel` 是固定用户级根目录;`~/.scorel/config.toml` 是固定用户级配置文件;JSONL session 默认固定写入 `~/.scorel/sessions`。这些路径是产品约定,不作为可配置字段暴露。测试和内部嵌入场景可以通过代码注入临时 session 目录,但这不是用户配置面。
158
+ 一个设备只有一份 config。Project workspace/session 对象,不拥有 Provider、Model、Memory、Runtime 或 Extension 配置;运行时不会读取项目目录下的 `.scorel/config.toml`。
159
+
160
+ `~/.scorel` 是固定用户级根目录;`~/.scorel/config.toml` 是固定用户级配置文件;JSONL session 默认固定写入 `~/.scorel/sessions`。这些路径是产品约定,不作为可配置字段暴露。测试和内部嵌入场景可以通过代码注入临时 `scorelHomeDir` / session 目录,但这不是用户配置面。
160
161
 
161
162
  环境变量不参与通用配置覆盖,只通过 `apiKeyEnv` 指向具体密钥。CLI 参数也不复制完整 config schema;只有明确属于交互控制的参数才进入 CLI。
162
163
 
@@ -244,7 +245,7 @@ auxiliary = "aux"
244
245
 
245
246
  `available_models.*` 是 Scorel 的 available model / use pool。它们从 `provider_models.*` 里引用少量真正允许 Scorel 使用的模型;Runtime、GUI composer 和未来 subagent selection 只能选择 pool 内模型,不能直接选择 provider catalog 或 provider model 里的任意条目。
246
247
 
247
- GUI 的 provider/model 写入必须 merge 到现有 `.scorel/config.toml`:同一 provider 下追加第二个 provider model,或把 provider model 加入 available models 时,不能删除已存在 provider、provider model、available model 或 role assignment,除非用户明确覆盖对应字段。
248
+ GUI 的 provider/model 写入必须 merge 到现有设备级 `config.toml`:同一 provider 下追加第二个 provider model,或把 provider model 加入 available models 时,不能删除已存在 provider、provider model、available model 或 role assignment,除非用户明确覆盖对应字段。
248
249
 
249
250
  Scorel 仍处在开发阶段,没有存量配置兼容要求。旧 `[models.*]` section 不再支持;遇到旧 section 必须按未知 section 报错。
250
251
 
@@ -38,7 +38,7 @@ The verifier starts:
38
38
  - a real local Relay process with durable file store
39
39
  - a real local Host daemon process connected outbound to Relay
40
40
  - a real WebUI Next dev server
41
- - a temporary real Project with project-level `.scorel/config.toml`
41
+ - a temporary real Project using the device-level `~/.scorel/config.toml`
42
42
  - a Relay Entry using `RelayTransport` and `DaemonClient`
43
43
 
44
44
  The verifier then:
@@ -103,12 +103,12 @@ The response must be display-safe:
103
103
  - if the target Project has no model profile config yet, `list_models` returns an empty
104
104
  model list instead of surfacing config-not-found as a user-facing error.
105
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.
106
+ Expose a Host API for adding/updating the device provider/model profile. GUI must use
107
+ this Host-owned path for both local and Relay devices; renderer code must not write
108
+ `~/.scorel/config.toml` directly.
109
109
 
110
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
111
+ shape and merge into the existing device config, but it must not require the target
112
112
  Host process to already have the provider API key env var set. Missing credentials
113
113
  should block runtime use, not saving.
114
114
 
@@ -186,8 +186,8 @@ This spec does not implement a new subagent execution engine.
186
186
  - using the selected model's context window.
187
187
  - Daemon/client tests cover:
188
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`
189
+ - a device with no model config returns an empty model profile summary;
190
+ - adding/updating a provider/model profile writes a valid `~/.scorel/config.toml`
191
191
  without requiring API key env vars;
192
192
  - adding a second model under the same provider preserves the existing provider and
193
193
  model entries;
@@ -56,7 +56,7 @@ page hierarchy.
56
56
  ### 4. Existing Host contract
57
57
 
58
58
  Continue using the Host-owned `list_models` and `upsert_model_profile` path. Renderer
59
- code must not write `.scorel/config.toml` directly.
59
+ code must not write `~/.scorel/config.toml` directly.
60
60
 
61
61
  This spec can reuse the S0073 data model and does not need a new protocol message unless
62
62
  the UI needs one for clean implementation.
@@ -37,7 +37,7 @@ selecting a draft provider.
37
37
  Provider config supports either:
38
38
 
39
39
  - `apiKeyEnv`, resolved from environment variables; or
40
- - `apiKey`, stored directly in `.scorel/config.toml`.
40
+ - `apiKey`, stored directly in the device `~/.scorel/config.toml`.
41
41
 
42
42
  GUI never receives direct API key values when listing providers. Editing an existing
43
43
  direct-key provider shows only that a direct key is configured. Saving a provider with
@@ -69,7 +69,7 @@ GUI Settings Memory section exposes:
69
69
  - session memory toggle;
70
70
  - auto compact threshold select.
71
71
 
72
- These controls use the existing project-scoped memory config path.
72
+ These controls use the device-scoped memory config path; memory status and persisted memory artifacts remain project-aware activity data.
73
73
 
74
74
  ## Not In Scope
75
75
 
@@ -0,0 +1,32 @@
1
+ # S0096: Glob Stable Order
2
+
3
+ ## Goal
4
+
5
+ Make the `Glob` tool return deterministic results across local macOS and Linux CI.
6
+
7
+ ## Scope
8
+
9
+ - Sort `Glob` file results by workspace-relative path before applying `head_limit` / `offset`.
10
+ - Preserve existing `Grep` behavior and pagination shape.
11
+
12
+ ## Not In Scope
13
+
14
+ - Changing ripgrep invocation.
15
+ - Changing Grep content/count ordering.
16
+
17
+ ## Acceptance Criteria
18
+
19
+ - `Glob` result limiting does not depend on filesystem or ripgrep output order.
20
+ - Existing coding tool tests pass on Linux and macOS.
21
+
22
+ ## Test Requirements
23
+
24
+ ```bash
25
+ pnpm --filter @scorel/core test -- src/tools/coding-tools.test.ts
26
+ pnpm typecheck
27
+ pnpm test
28
+ ```
29
+
30
+ ## Status
31
+
32
+ Done.
@@ -0,0 +1,61 @@
1
+ # S0097: RTK Token Saving Settings
2
+
3
+ ## Goal
4
+
5
+ Add an opt-in GUI setting that enables RTK-backed token saving for Scorel Bash tool execution without changing session replay, model prompts, or existing tool input contracts.
6
+
7
+ RTK here means Rust Token Killer: a CLI command rewriter/filter that compresses shell command output before it reaches the LLM context.
8
+
9
+ ## Scope
10
+
11
+ - Add device-scoped `[runtime] tokenSavingRtk = boolean` config.
12
+ - Add GUI Settings page `Token 节省` with an RTK enable toggle and status.
13
+ - When the user enables the setting, Host ensures the `rtk` binary is available:
14
+ - first detect `rtk` on PATH;
15
+ - if missing on macOS/Linux with Homebrew available, attempt `brew install rtk`;
16
+ - if install fails, keep the setting but report RTK as unavailable.
17
+ - Bash tool execution and RTK discovery use the user's default shell path (`options.defaultShell` where provided, then `SHELL`, then OS user shell, then `/bin/sh` fallback), not a hard-coded `/bin/bash`.
18
+ - Shell invocation preserves the command string and uses shell-compatible command flags (`-lc` for sh/bash/zsh-like shells, `-c` for csh/tcsh/fish-like shells).
19
+ - When enabled and available, the Bash tool asks RTK to rewrite the original command and executes the rewritten command, while preserving the original tool input contract and cwd semantics.
20
+ - Bash tool result details expose RTK application state plus estimated output/saved tokens for Scorel-owned UI/diagnostics.
21
+ - Runtime Settings summarizes RTK token savings from a maintained Scorel runtime stats file across projects on the current host.
22
+ - Chat transcript rendering continues to display the original Bash tool-call command, not the RTK rewritten execution command.
23
+ - Session JSONL and persistent events keep the same tool result shape; no prompt or input assembly contract changes.
24
+
25
+ ## Not In Scope
26
+
27
+ - Changing model message assembly.
28
+ - Compressing Read / Grep / Glob built-in tool results.
29
+ - Provider-specific token accounting.
30
+ - A per-session savings breakdown view.
31
+ - Global shell hook installation through `rtk init`.
32
+ - Silent install at app startup.
33
+
34
+ ## Acceptance Criteria
35
+
36
+ - `tokenSavingRtk = false` keeps Bash behavior equivalent to the current path.
37
+ - `tokenSavingRtk = true` uses RTK rewrite for Bash command execution when RTK is available, without changing the tool-call input command string.
38
+ - Tool results sent back into model context include only the user-visible content, not RTK execution metadata or rewritten command details.
39
+ - GUI Bash tool blocks display the original tool-call command even when RTK rewrites the command at execution time.
40
+ - RTK detection and first-enable install checks run in the same default shell environment as command execution, so zsh-configured PATH entries are visible.
41
+ - Runtime creation resolves the RTK executable whenever `tokenSavingRtk` is enabled, so saved settings affect actual Bash tool execution, not only the Settings UI.
42
+ - Runtime Settings token totals come from Scorel-maintained RTK stats updated when Scorel persists tool results, so other agents' RTK usage in the same project is not counted.
43
+ - GUI Settings can enable/disable RTK token saving and shows available/unavailable status.
44
+ - Config parsing rejects unknown `[runtime]` keys.
45
+ - RTK install is only attempted after the user enables the setting.
46
+ - Existing tests, typecheck, and full test suite pass.
47
+
48
+ ## Test Requirements
49
+
50
+ ```bash
51
+ pnpm --filter @scorel/core test -- src/config/config.test.ts src/tools/coding-tools.test.ts
52
+ pnpm --filter @scorel/daemon test -- src/embedded/embedded.test.ts
53
+ pnpm --filter @scorel/app-gui test -- src/renderer/gui-shell.test.tsx
54
+ pnpm verify:m9-gui # service-level local/relay plus Electron CDP settings + prompt smoke
55
+ pnpm typecheck
56
+ pnpm test
57
+ ```
58
+
59
+ ## Status
60
+
61
+ Done.
@@ -0,0 +1,96 @@
1
+ # S0098: Local Daemon Singleton And Unified State
2
+
3
+ ## Goal
4
+
5
+ Make the local Scorel Host a single user-level daemon with one local state root, so CLI, GUI, WebUI, IM, and Relay clients attach to the same Project registry, Session JSONL, runtime stats, and config.
6
+
7
+ ## Scope
8
+
9
+ - Use `~/.scorel` as the only local Host state root:
10
+ - `daemon.json`
11
+ - `projects.json`
12
+ - `sessions/*.jsonl`
13
+ - `runtime-stats.json`
14
+ - `config.toml`
15
+ - `gui-store.json`
16
+ - Remove GUI-local Host state ownership:
17
+ - no new `~/.scorel/gui/projects.json`;
18
+ - no new `~/.scorel/gui/sessions`;
19
+ - GUI still has GUI UI state, but it lives at `~/.scorel/gui-store.json`.
20
+ - Add `scorel host start`, a background daemon start path that starts the singleton local daemon without tying daemon lifetime to the CLI process that launched it.
21
+ - Make local GUI attach to the singleton daemon when available.
22
+ - Make local GUI start the singleton daemon in the background when no live daemon exists, then attach to it.
23
+ - Make `scorel up` ensure the singleton daemon is running, register the current cwd as a Project, and launch/serve UI without owning daemon lifetime.
24
+ - Keep foreground `scorel host serve` for debugging; Ctrl-C on foreground serve still stops that foreground process.
25
+ - Daemon lifecycle:
26
+ - daemon is not killed when one client exits;
27
+ - explicit `scorel host stop` stops it;
28
+ - if no IM extensions are active, daemon idle-shuts down after no connected clients and no active work for the configured timeout;
29
+ - if any IM extension is active, daemon remains alive until explicit stop.
30
+
31
+ ## Not In Scope
32
+
33
+ - Migrating old `~/.scorel/gui/projects.json` or `~/.scorel/gui/sessions` into the unified state. Scorel is pre-1.0; users may remove old GUI-local files manually if needed.
34
+ - System LaunchAgent/login-item installation.
35
+ - Multi-user or system-wide daemon.
36
+ - Remote daemon lifecycle changes.
37
+ - Per-session RTK stats breakdown UI.
38
+ - Restart-on-crash supervisor.
39
+
40
+ ## Acceptance Criteria
41
+
42
+ - GUI local Projects and Sessions are created under `~/.scorel/projects.json` and `~/.scorel/sessions`, not under `~/.scorel/gui`.
43
+ - `gui-store.json` is stored at `~/.scorel/gui-store.json`.
44
+ - `scorel host start` starts or reuses a background singleton daemon and returns without waiting for daemon shutdown.
45
+ - `scorel up` reuses an existing running daemon instead of spawning a child daemon that dies with `scorel up`.
46
+ - Starting GUI when a daemon is alive attaches to it and does not start a second Host writer.
47
+ - Starting GUI when no daemon is alive starts the background singleton daemon, then attaches to it.
48
+ - If no clients remain, no work is active, and no IM extension is active, daemon exits after its idle timeout.
49
+ - If an IM extension is active, daemon does not idle-exit solely because there are no GUI/CLI clients.
50
+ - Model/tool messages remain unchanged: daemon lifecycle and state unification do not alter tool call args or provider tool result context.
51
+
52
+ ## Test Requirements
53
+
54
+ ```bash
55
+ pnpm --filter @scorel/app-cli test -- src/daemon-cli.test.ts src/up-cli.test.ts
56
+ pnpm --filter @scorel/app-gui test -- src/main/local-host.test.ts
57
+ pnpm --filter @scorel/daemon test -- src/embedded/embedded.test.ts
58
+ pnpm verify:m9-gui
59
+ pnpm typecheck
60
+ pnpm test
61
+ ```
62
+
63
+ Manual/E2E:
64
+
65
+ - Start GUI from a clean temp HOME through Electron CDP.
66
+ - Verify local Project registration creates `~/.scorel/projects.json`.
67
+ - Verify local Session creation creates `~/.scorel/sessions/*.jsonl`.
68
+ - Verify no `~/.scorel/gui/projects.json` or `~/.scorel/gui/sessions` is created.
69
+ - Verify GUI start from a clean HOME creates `~/.scorel/daemon.json` and attaches to that daemon.
70
+ - Verify `scorel host start` returns while `scorel host status` still reports a running daemon.
71
+ - Verify `scorel up` exit does not stop the singleton daemon it started.
72
+ - Verify short idle timeout stops a daemon with no clients and no active IM.
73
+ - Verify active IM prevents idle shutdown.
74
+
75
+ ## Impacted Files
76
+
77
+ - `apps/cli/src/daemon-cli.ts`
78
+ - `apps/cli/src/up-cli.ts`
79
+ - `apps/cli/src/index.ts`
80
+ - `apps/gui/src/main.ts`
81
+ - `apps/gui/src/main/local-host.ts`
82
+ - `packages/daemon/src/index.ts`
83
+ - `scripts/verify-m9-gui-cdp-e2e.ts`
84
+ - `docs/SHIP.md`
85
+ - `docs/ROADMAP.md`
86
+
87
+ ## Risks And Boundaries
88
+
89
+ - Background daemon process management must not leave stale `daemon.json` as a false-positive running daemon.
90
+ - The singleton daemon must remain the only local writer for Project and Session files.
91
+ - Electron GUI starts the daemon through the CLI entrypoint; packaged builds must provide `SCOREL_CLI_ENTRYPOINT` when the source tree is unavailable.
92
+ - Old GUI-local state under `~/.scorel/gui` is intentionally not migrated in this spec.
93
+
94
+ ## Status
95
+
96
+ Done.
@@ -0,0 +1,85 @@
1
+ # S0099: GUI Connection And Device Settings
2
+
3
+ ## Goal
4
+
5
+ Make GUI connection setup match the hosted Relay product path, so users can pair devices, rename paired devices, and inspect connection details.
6
+
7
+ S0101 supersedes the original settings-scope part of this spec: settings configuration is device-scoped, not Project-scoped.
8
+
9
+ ## Scope
10
+
11
+ - GUI Relay pairing:
12
+ - default to the official Relay without showing an editable URL field;
13
+ - expose Relay URL editing only behind an explicit edit affordance;
14
+ - rename the pairing action from `Pair` to `Get Pair Code`.
15
+ - GUI paired devices:
16
+ - allow users to rename a paired Relay Device locally in GUI state;
17
+ - preserve the Relay-reported label as fallback when no local name exists;
18
+ - show device details from the generic device view: status, Device ID, IP when available, and Relay URL.
19
+ - GUI Settings scope:
20
+ - superseded by S0101;
21
+ - the correct product model is device-scoped configuration.
22
+ - Tests and docs:
23
+ - cover local device rename persistence;
24
+ - cover the connection section rendering contract;
25
+ - keep ROADMAP in sync.
26
+
27
+ ## Not In Scope
28
+
29
+ - Relay protocol changes or IP discovery in Relay V1. The UI may expose an optional IP field, but Relay currently does not guarantee one.
30
+ - SSH Remote Device, remote installation, or SSH stdio proxy.
31
+ - Direct WS + token GUI setup.
32
+ - Account/OAuth identity.
33
+ - Importing every remote Host Project automatically into the GUI Project list.
34
+ - Moving IM extension settings to remote scope; IM settings remain local GUI/Host extension settings in this spec.
35
+
36
+ ## Acceptance Criteria
37
+
38
+ - Opening GUI Settings -> Connections shows the official Relay as the default endpoint and does not show a Relay URL input until the user chooses edit.
39
+ - The pair action reads `Get Pair Code`.
40
+ - A pair code is still created with the default official Relay when the URL field has not been edited.
41
+ - Paired devices can be renamed from the Connections page, and the local name persists in `~/.scorel/gui-store.json`.
42
+ - Paired device details expose status, Device ID, Relay URL, and an IP row that is populated only when the device view has IP information.
43
+ - Settings nav behavior is governed by S0101: it shows devices, not Projects.
44
+
45
+ ## Test Requirements
46
+
47
+ ```bash
48
+ pnpm --filter @scorel/app-gui test -- src/main/gui-store.test.ts src/renderer/gui-shell.test.tsx
49
+ pnpm typecheck
50
+ pnpm test
51
+ ```
52
+
53
+ Manual:
54
+
55
+ - Open GUI Settings -> Connections.
56
+ - Confirm the Relay URL input is hidden by default and `Get Pair Code` returns a pair code against the official Relay.
57
+ - Click edit, change Relay URL, and confirm pair/refresh use the edited URL.
58
+ - Pair or seed a Relay Device, rename it, refresh, and confirm the local name remains.
59
+ - Open Settings and confirm the settings selector follows S0101 device-scoped behavior.
60
+
61
+ ## Impacted Files
62
+
63
+ - `apps/gui/src/main/gui-store.ts`
64
+ - `apps/gui/src/main.ts`
65
+ - `apps/gui/src/preload.ts`
66
+ - `apps/gui/src/shared/ipc.ts`
67
+ - `apps/gui/src/renderer/App.tsx`
68
+ - `apps/gui/src/renderer/settings/SettingsShell.tsx`
69
+ - `apps/gui/src/renderer/settings/SettingsNav.tsx`
70
+ - `apps/gui/src/renderer/settings/sections/ConfigSection.tsx`
71
+ - `apps/gui/src/renderer/styles.css`
72
+ - `apps/gui/src/main/gui-store.test.ts`
73
+ - `apps/gui/src/renderer/gui-shell.test.tsx`
74
+ - `docs/CHANGELOG.md`
75
+ - `docs/ROADMAP.md`
76
+
77
+ ## Risks And Boundaries
78
+
79
+ - Device rename is GUI-local metadata, not a Relay identity mutation. Refresh must not overwrite a user's local name with a Relay label.
80
+ - Settings scope is device-based as of S0101. Projects are workspace/session objects, not configuration owners.
81
+ - IP is optional because the current Relay protocol does not report it; the UI contract must tolerate absence without inventing a fake value.
82
+
83
+ ## Status
84
+
85
+ Done.
@@ -0,0 +1,57 @@
1
+ # S0100: GUI Provider Danger Zone Placement
2
+
3
+ ## Goal
4
+
5
+ Move destructive Provider management actions out of the primary Provider edit form, so normal configuration fields remain the first visual focus and deletion is clearly presented as a secondary dangerous action.
6
+
7
+ S0101 supersedes the final placement: `删除提供商` now lives in the Provider configuration block's lower-right action area instead of a bottom danger row.
8
+
9
+ ## Scope
10
+
11
+ - In GUI Settings -> Provider:
12
+ - this spec recorded the first placement pass;
13
+ - S0101 defines the current placement in the Provider configuration block;
14
+ - keep the existing `removeModelProvider` behavior unchanged.
15
+ - Add rendering coverage that verifies the destructive action is below normal model-management controls.
16
+
17
+ ## Not In Scope
18
+
19
+ - Changing Provider deletion semantics, confirmation behavior, or daemon/client APIs.
20
+ - Redesigning the Provider page layout beyond the destructive-action placement.
21
+ - Changing model catalog, model selection, or provider form fields.
22
+
23
+ ## Acceptance Criteria
24
+
25
+ - Current acceptance is governed by S0101: `删除提供商` appears in the Provider configuration block.
26
+ - Existing Provider add/edit/model actions remain unchanged.
27
+ - GUI rendering tests cover the current placement.
28
+
29
+ ## Test Requirements
30
+
31
+ ```bash
32
+ pnpm --filter @scorel/app-gui test -- src/renderer/gui-shell.test.tsx
33
+ pnpm --filter @scorel/app-gui typecheck
34
+ ```
35
+
36
+ Manual:
37
+
38
+ - Start the GUI with a Project that has a configured Provider.
39
+ - Open Settings -> Provider.
40
+ - Confirm S0101 current behavior: the delete button appears in the Provider configuration block's lower-right action area.
41
+
42
+ ## Impacted Files
43
+
44
+ - `apps/gui/src/renderer/settings/sections/ProviderSection.tsx`
45
+ - `apps/gui/src/renderer/styles.css`
46
+ - `apps/gui/src/renderer/gui-shell.test.tsx`
47
+ - `docs/CHANGELOG.md`
48
+ - `docs/ROADMAP.md`
49
+
50
+ ## Risks And Boundaries
51
+
52
+ - The delete action remains destructive and immediate, matching existing behavior. This spec only changes placement.
53
+ - The danger row should not introduce another card nested inside the Provider card; it stays as an inline separated row.
54
+
55
+ ## Status
56
+
57
+ Done.
@@ -0,0 +1,66 @@
1
+ # S0101 GUI Device Settings Polish
2
+
3
+ ## Goal
4
+
5
+ Fix GUI settings so configuration is device-scoped, not Project-scoped, and polish the settings interactions surfaced by the latest Provider / Token / Connection review.
6
+
7
+ One device has one configuration. The Settings scope selector chooses a device:
8
+
9
+ - `此电脑` configures the local device.
10
+ - A Relay device configures that remote device.
11
+ - Projects remain workspace/session objects and must not appear as the settings configuration scope.
12
+
13
+ ## Scope
14
+
15
+ - Settings left scope selector becomes device-based.
16
+ - GUI settings IPC for model profile, Provider catalog/deletion, memory settings, and runtime settings targets only a device.
17
+ - Daemon/client config requests used by GUI are device-level and write the device user config at `~/.scorel/config.toml` for that daemon.
18
+ - Provider deletion moves into the top Provider configuration form area, aligned to the lower-right of the Provider parameter block.
19
+ - Runtime token statistics use understandable Chinese labels and expose both output token total and saved token estimate.
20
+ - Relay device rows have an explicit expand affordance.
21
+ - Relay device rename is inline: a small edit icon next to the device name turns the name into an input.
22
+
23
+ ## Not In Scope
24
+
25
+ - Changing session/project ownership: sessions still belong to Projects.
26
+ - Redesigning Project registry or remote Project selection.
27
+ - Creating per-Project settings overrides.
28
+ - Reworking IM extension settings beyond existing user-config behavior.
29
+ - Changing RTK savings math.
30
+
31
+ ## Acceptance Criteria
32
+
33
+ - Settings selector labels are device names only, for example `此电脑` and `Remote Device`; it does not render `此电脑 / ProjectName` or `Device / ProjectName`.
34
+ - Settings Provider/Model/Memory/Runtime mutations do not accept a Project in GUI IPC.
35
+ - Daemon writes GUI settings requests to device-level user config.
36
+ - Provider delete is visually close to Provider credentials/configuration, not in a separate bottom danger row.
37
+ - Runtime token stats are Chinese and self-explanatory.
38
+ - Relay device rows visibly indicate expand/collapse and rename through a name-adjacent edit icon.
39
+
40
+ ## Test Requirements
41
+
42
+ - Update renderer tests for device settings scope, Provider delete placement, Runtime labels, and inline Relay device rename affordance.
43
+ - Add or update daemon/local-host tests proving projectless settings write `config.toml` under device user config.
44
+ - Run targeted GUI/protocol/daemon tests covering changed paths.
45
+ - Run `pnpm typecheck && pnpm test` before shipping.
46
+
47
+ ## Impacted Files
48
+
49
+ - `packages/protocol/src/events.ts`
50
+ - `packages/protocol/src/wire.ts`
51
+ - `packages/client/src/index.ts`
52
+ - `packages/daemon/src/index.ts`
53
+ - `apps/gui/src/main.ts`
54
+ - `apps/gui/src/main/local-host.ts`
55
+ - `apps/gui/src/main/relay-service.ts`
56
+ - `apps/gui/src/preload.ts`
57
+ - `apps/gui/src/shared/ipc.ts`
58
+ - `apps/gui/src/renderer/App.tsx`
59
+ - `apps/gui/src/renderer/settings/*`
60
+ - `apps/gui/src/renderer/styles.css`
61
+ - `docs/ROADMAP.md`
62
+ - `docs/CHANGELOG.md`
63
+
64
+ ## Risks And Boundaries
65
+
66
+ - Memory status is a Project activity/status concept; this spec keeps Settings focused on Memory configuration, not Project activity status.