@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
@@ -57,45 +57,42 @@ type ScorelEvent =
57
57
 
58
58
  ## 3. Extensions 系统
59
59
 
60
- ### 3.1 接口
60
+ S0083 后,已落地的 Extension 形态是 manifest-driven IM extension。它先服务 IM channel 接入,不把完整 plugin marketplace 一次性做完。
61
+
62
+ ### 3.1 Manifest
63
+
64
+ 每个 extension 目录包含:
65
+
66
+ ```text
67
+ scorel.extension.json
68
+ adapter.js
69
+ skills/
70
+ ```
71
+
72
+ 最小 schema:
61
73
 
62
74
  ```typescript
63
- interface Extension {
75
+ type ExtensionManifest = {
64
76
  id: string;
65
- name: string;
66
- version: string;
67
-
68
- activate?(ctx: ExtensionContext): Promise<void>;
69
- deactivate?(): Promise<void>;
70
-
71
- tools?(): AgentTool[]; // 追加工具
72
- commands?(): Record<string, SlashCommand>; // 追加斜杠命令
73
- onEvent?(event: ScorelEvent, ctx: ExtensionContext): Promise<void>;
74
- hooks?(): Partial<{
75
- beforeToolCall: BeforeToolCallHook;
76
- afterToolCall: AfterToolCallHook;
77
- transformContext: TransformContextHook;
78
- }>;
79
- }
80
-
81
- interface ExtensionContext {
82
- readonly agent: Agent;
83
- readonly session: SessionStore;
84
- readonly config: Config;
85
- readonly logger: Logger;
86
- }
77
+ kind: "im";
78
+ displayName: string;
79
+ adapter: string;
80
+ skills?: string[];
81
+ mcp?: unknown[];
82
+ };
87
83
  ```
88
84
 
89
- Extension 可以注入四种能力:工具、斜杠命令、事件监听、原生 Hook。四种都不是必选,一个扩展可以只做最小的一件事。
85
+ `mcp` S0083 只解析保留,不启动 MCP server。
90
86
 
91
87
  ### 3.2 加载路径与时机
92
88
 
93
- ```
94
- ~/.scorel/extensions/ 全局
95
- .scorel/extensions/ 项目级
89
+ ```text
90
+ extensions/builtin/ 内置,只读,随包发布
91
+ ~/.scorel/extensions/ 用户级
92
+ .scorel/extensions/ ← 项目级,后续扩展
96
93
  ```
97
94
 
98
- 启动时扫描 `.ts` / `.js`,动态 `import()`,调用 `activate()`。项目级覆盖全局。
95
+ Host 启动时读取 config 中 enabled 的 extension,然后加载对应 manifest。V1 已实现 built-in/user root;项目级 root 仍是后续扩展点。
99
96
 
100
97
  ### 3.3 错误隔离
101
98
 
@@ -117,7 +114,7 @@ class ExtensionRunner {
117
114
  }
118
115
  ```
119
116
 
120
- **单个 Extension 挂掉绝不影响核心和其他 Extension。** 原生 Hook 的链式包装里同样有 try/catch 兜底,但拦截失败会直接跳过该层。
117
+ **单个 Extension 挂掉绝不影响核心和其他 Extension。** IM adapter 启动失败只写 diagnostics 并跳过该 extension。
121
118
 
122
119
  ---
123
120
 
@@ -163,33 +160,104 @@ class PromptBuilder {
163
160
 
164
161
  环境变量不参与通用配置覆盖,只通过 `apiKeyEnv` 指向具体密钥。CLI 参数也不复制完整 config schema;只有明确属于交互控制的参数才进入 CLI。
165
162
 
166
- ### 5.2 初期配置示例
163
+ 配置保存和配置展示只记录 / 返回 `apiKeyEnv`,不读取或保存 raw API key。缺少对应环境变量时,Settings 可以显示 credential missing 状态;真正创建 runtime 或调用 provider 时才把缺失 env 作为错误抛出。
164
+
165
+ ### 5.2 Provider / Model Profile 配置示例
166
+
167
+ S0073 后,旧的单 `[model]` 配置被替换为 provider / provider models / available models / role profile 四层合同。
167
168
 
168
- pi-ai 已支持的内置 provider 使用 `type = "builtin"`,Scorel 只把 provider/model/api key 交给 pi-ai,不在本仓库重写 provider 协议:
169
+ pi-ai 已支持的内置 provider 使用 `type = "builtin"`。Scorel 只把 provider/model/api key 交给 pi-ai,不在本仓库重写 provider 协议:
169
170
 
170
171
  ```toml
171
- [model]
172
+ [providers.openai]
172
173
  type = "builtin"
173
174
  provider = "openai"
174
- id = "gpt-5.4-mini"
175
175
  apiKeyEnv = "SCOREL_API_KEY"
176
+
177
+ [provider_models.openai_gpt_54_mini]
178
+ provider = "openai"
179
+ id = "gpt-5.4-mini"
180
+ displayName = "GPT 5.4 Mini"
181
+
182
+ [provider_models.openai_gpt_54_nano]
183
+ provider = "openai"
184
+ id = "gpt-5.4-nano"
185
+ displayName = "GPT 5.4 Nano"
186
+
187
+ [available_models.main]
188
+ model = "openai_gpt_54_mini"
189
+ displayName = "GPT 5.4 Mini"
190
+
191
+ [available_models.aux]
192
+ model = "openai_gpt_54_nano"
193
+ displayName = "GPT 5.4 Nano"
194
+
195
+ [model_profile.roles]
196
+ primary = "main"
197
+ standard = "main"
198
+ auxiliary = "aux"
176
199
  ```
177
200
 
178
- 自定义兼容 endpoint 使用 `type = "custom"`,并显式声明兼容协议。这个分支和 builtin provider 分开,避免把任意自定义 endpoint 混成 pi-ai 内置 provider:
201
+ 自定义兼容 endpoint 使用 `type = "custom"`,并显式声明兼容协议。这个分支和 builtin provider 分开,避免把任意自定义 endpoint 混成 pi-ai 内置 provider。Custom model 必须手动声明 context metadata,因为自定义 endpoint 不一定能可靠 discover model catalog
179
202
 
180
203
  ```toml
181
- [model]
204
+ [providers.chanleramp]
182
205
  type = "custom"
183
206
  api = "openai-completions"
184
207
  provider = "chanleramp"
185
- id = "gpt-5.4-mini"
186
208
  baseUrl = "https://amp.chanler.dev/v1"
187
209
  apiKeyEnv = "SCOREL_API_KEY"
210
+
211
+ [provider_models.chanleramp_gpt_54_mini]
212
+ provider = "chanleramp"
213
+ id = "gpt-5.4-mini"
214
+ displayName = "GPT 5.4 Mini"
188
215
  contextWindow = 400000
189
216
  maxTokens = 128000
190
217
  reasoning = true
218
+
219
+ [provider_models.chanleramp_deepseek_v4_flash]
220
+ provider = "chanleramp"
221
+ id = "deepseek-v4-flash"
222
+ displayName = "DeepSeek Flash"
223
+ contextWindow = 128000
224
+ maxTokens = 32000
225
+ reasoning = false
226
+
227
+ [available_models.main]
228
+ model = "chanleramp_gpt_54_mini"
229
+ displayName = "GPT 5.4 Mini"
230
+
231
+ [available_models.aux]
232
+ model = "chanleramp_deepseek_v4_flash"
233
+ displayName = "DeepSeek Flash"
234
+
235
+ [model_profile.roles]
236
+ primary = "main"
237
+ standard = "main"
238
+ auxiliary = "aux"
191
239
  ```
192
240
 
241
+ `providers.*` 是 LLM provider connection:供应商名称、协议/API shape、base URL 和 API key env var。一个 provider connection 可以对应多个 `provider_models.*`。
242
+
243
+ `provider_models.*` 是 provider connection 下记录的候选模型。它描述真实 provider model id、展示名和自定义 endpoint 必需的 context metadata。
244
+
245
+ `available_models.*` 是 Scorel 的 available model / use pool。它们从 `provider_models.*` 里引用少量真正允许 Scorel 使用的模型;Runtime、GUI composer 和未来 subagent selection 只能选择 pool 内模型,不能直接选择 provider catalog 或 provider model 里的任意条目。
246
+
247
+ GUI 的 provider/model 写入必须 merge 到现有 `.scorel/config.toml`:同一 provider 下追加第二个 provider model,或把 provider model 加入 available models 时,不能删除已存在 provider、provider model、available model 或 role assignment,除非用户明确覆盖对应字段。
248
+
249
+ Scorel 仍处在开发阶段,没有存量配置兼容要求。旧 `[models.*]` section 不再支持;遇到旧 section 必须按未知 section 报错。
250
+
251
+ `model_profile.roles` 是 V1 的用途绑定:
252
+
253
+ ```text
254
+ primary -> 最强/最稳的主 agent 模型
255
+ standard -> 默认日常模型
256
+ auxiliary -> 轻量辅助模型
257
+ ```
258
+
259
+ 这些 role 名是通用产品语义,不绑定 Opus / Sonnet / Haiku 这类具体供应商命名。
260
+
193
261
  `api` 初期只接受以下四个值:
194
262
 
195
263
  ```text
@@ -214,20 +282,24 @@ name = "github"
214
282
  transport = "stdio"
215
283
  command = "mcp-server-github"
216
284
 
217
- [extensions]
218
- disabled = ["experimental-memory"]
285
+ [extensions.loopback]
286
+ enabled = true
287
+ kind = "im"
288
+
289
+ [extensions.loopback.config]
290
+ botTokenEnv = "SCOREL_LOOPBACK_TOKEN"
219
291
  ```
220
292
 
221
293
  ### 5.3 Schema 规则
222
294
 
223
295
  配置必须通过 `SCOREL_CONFIG_SCHEMA` 校验。未知 section 和未知 key 都应由通用 schema 校验拒绝,例如根级 `sessionsDir = "/tmp/nope"` 必须报 `Unsupported config key: sessionsDir`,不能为单个字段写特殊判断。
224
296
 
225
- 当前已落地的稳定 section 只有 `[model]`。未来新增 `[tools]` / `[mcp]` / `[extensions]` 时,必须先把字段加入 schema,再接入加载逻辑和测试。
297
+ 当前已落地的稳定 section `[providers.*]`、`[provider_models.*]`、`[available_models.*]`、`[model_profile.roles]`、`[memory]`、`[extensions.*]` `[extensions.*.config]`。未来新增 `[tools]` / `[mcp]` 时,必须先把字段加入 schema,再接入加载逻辑和测试。
226
298
 
227
299
  ### 5.4 延后段落
228
300
 
229
301
  - `[permissions]` — 权限策略。初期工具默认全允许,权限审批整体后补
230
- - `[channels.telegram]` / `[channels.wechat]` IM Channel 配置
302
+ - 真实 IM 配置,例如 Telegram bot token env,由对应 extension spec 定义
231
303
  - `[mcp.servers.*.tier]` / `keywords` — MCP 分级加载配置
232
304
 
233
305
  这些段落的 schema 会在对应模块落地时补入,初期不预留任何半成品字段。
@@ -241,13 +313,13 @@ disabled = ["experimental-memory"]
241
313
  - 广播事件:`turn_finish` / `turn_error` / `rewind` / `compact`
242
314
  - Extension 加载 + 错误隔离(`tools` / `commands` / `onEvent`)
243
315
  - System Prompt 组装与预算
244
- - TOML 配置的核心段:`[model]`,并通过 `SCOREL_CONFIG_SCHEMA` 统一拒绝未知 section/key
316
+ - TOML 配置的核心段:`[providers.*]` / `[provider_models.*]` / `[available_models.*]` / `[model_profile.roles]`,并通过 `SCOREL_CONFIG_SCHEMA` 统一拒绝未知 section/key
245
317
 
246
318
  **延后**
247
319
  - Extension 的沙箱与权限边界(现阶段信任本地扩展)
248
320
  - Prompt 的模板化与多语种切换
249
321
  - 热更新配置(初期启动时读一次即可)
250
- - `[tools]` / `[channels]` / `[mcp]` / `[extensions]` 的完整配置 schema
322
+ - `[tools]` / `[mcp]` 的完整配置 schema
251
323
  - Skills 加载(`~/.scorel/skills/*/SKILL.md`)
252
324
 
253
325
  ---
@@ -115,6 +115,7 @@ publish: true | false
115
115
  The workflow must:
116
116
 
117
117
  - install pnpm from `packageManager`
118
+ - install system tools required by the release check path, including `ripgrep` for the `Glob` and `Grep` coding-tool tests
118
119
  - run `pnpm install --frozen-lockfile`
119
120
  - run `pnpm release <bump> --dry-run` by default
120
121
  - require `NPM_TOKEN` only for a real publish
@@ -127,6 +128,7 @@ The workflow must:
127
128
  - `pnpm pack:smoke` packs and installs the tarball into a temporary project, then runs `scorel --help`.
128
129
  - `pnpm release patch --dry-run` runs the full dry-run path and exits 0.
129
130
  - `.github/workflows/release.yml` exists and manually triggers the same release command.
131
+ - `.github/workflows/release.yml` installs `ripgrep` before running the release command, so the repo-level test suite matches the product's rg-backed coding tools.
130
132
  - `docs/ROADMAP.md` includes S0062 as Done only after verification.
131
133
  - `docs/CHANGELOG.md` records release infrastructure under Unreleased until the first release moves it to a version section.
132
134
 
@@ -163,4 +165,5 @@ git diff --check
163
165
  - Bundling can accidentally include development-only code. Keep `files` restricted to `dist`, README, and selected docs.
164
166
  - Publishing internal packages too early would create API stability pressure. Keep only root `@chanlerdev/scorel` public in S0062.
165
167
  - Real npm publish requires `chanlerdev` authentication locally or `NPM_TOKEN` in GitHub Actions.
168
+ - GitHub hosted runners do not guarantee `rg` is available. Install `ripgrep` explicitly in release workflow setup instead of skipping the rg-backed tool tests.
166
169
  - A release script that mutates versions before verification can leave the repo dirty after failures. Run verification before mutation for normal release, and keep dry-run non-mutating.
@@ -0,0 +1,129 @@
1
+ # S0063: AI Release Notes
2
+
3
+ ## Goal
4
+
5
+ Make every normal Scorel release produce transparent, user-readable changelog notes by default. The notes are generated from the commits since the previous `v*` release tag using DeepSeek V4 Flash, then inserted into `docs/CHANGELOG.md` before the release commit is created.
6
+
7
+ ## Scope
8
+
9
+ - Add a release-notes generator that:
10
+ - finds commits in a supplied release range
11
+ - collects commit file names and diff stats before collecting patches
12
+ - skips generated files such as `dist/`, source maps, lockfiles, `.next/`, and `node_modules/` before reading patch content
13
+ - summarizes each commit as structured JSON evidence
14
+ - aggregates commit summaries into release-level structured JSON
15
+ - renders Markdown suitable for `docs/CHANGELOG.md`
16
+ - Use DeepSeek official Chat Completions endpoint:
17
+ - default base URL: `https://api.deepseek.com/v1`
18
+ - default model: `deepseek-v4-flash`
19
+ - API key env: `DEEPSEEK_API_KEY`
20
+ - non-thinking request: `thinking: { "type": "disabled" }`
21
+ - JSON mode: `response_format: { "type": "json_object" }`
22
+ - Treat `docs/spec/ship/S*.md` diffs as important product context in the system prompt, without parsing spec structure.
23
+ - Make `pnpm release <patch|minor|major>` generate notes by default.
24
+ - Add `--no-generate-notes` as the explicit release escape hatch.
25
+ - Add a standalone preview/debug command:
26
+
27
+ ```bash
28
+ pnpm release-notes --from v0.0.1 --to HEAD --version 0.0.2
29
+ ```
30
+
31
+ - Update the manual GitHub Actions release workflow so CI releases use the same default notes behavior and can disable it explicitly.
32
+
33
+ ## Non-Goals
34
+
35
+ - Do not build a full release management product.
36
+ - Do not parse SHIP spec sections such as Goal, Scope, or Acceptance Criteria in S0063.
37
+ - Do not publish GitHub Releases in S0063.
38
+ - Do not require AI release notes when the operator explicitly passes `--no-generate-notes`.
39
+ - Do not use mock provider behavior as proof for any real product path. Script unit tests may use injected fetch and git runners.
40
+
41
+ ## Contract
42
+
43
+ ### Default Release
44
+
45
+ ```bash
46
+ pnpm release patch
47
+ ```
48
+
49
+ must:
50
+
51
+ - compute the next version from the current package version
52
+ - find the previous `v*` tag for the release range
53
+ - generate AI release notes before mutating versions
54
+ - insert rendered notes under `## Unreleased` in `docs/CHANGELOG.md`
55
+ - continue the existing verification, version bump, build, pack smoke, commit, tag, publish, and push path
56
+
57
+ ### Explicit Skip
58
+
59
+ ```bash
60
+ pnpm release patch --no-generate-notes
61
+ ```
62
+
63
+ must preserve the previous minimal changelog section behavior.
64
+
65
+ ### Dry Run
66
+
67
+ ```bash
68
+ pnpm release patch --dry-run
69
+ ```
70
+
71
+ must print the generated release notes preview when DeepSeek credentials are available. If credentials are missing or DeepSeek fails during dry run, the script may print a deterministic fallback preview and continue.
72
+
73
+ ### Standalone Preview
74
+
75
+ ```bash
76
+ pnpm release-notes --from v0.0.1 --to HEAD --version 0.0.2
77
+ ```
78
+
79
+ must print Markdown notes only. It must not bump versions, write files, create commits, tag, publish, or push.
80
+
81
+ ## Acceptance Criteria
82
+
83
+ - `scripts/release-notes.mjs` exists and can be used as both an importable module and a CLI.
84
+ - Root `package.json` includes `release-notes`.
85
+ - Commit summary and release aggregation prompts require strict JSON output and mention SHIP specs as important context.
86
+ - DeepSeek requests use `https://api.deepseek.com/v1` and `deepseek-v4-flash` by default, with large output token limits appropriate for a high-context release task.
87
+ - Generated diffs are skipped before patch reads, so release-note collection does not depend on reading large bundled artifacts into a Node child-process buffer.
88
+ - Oversized non-generated diffs are truncated before being sent to the model.
89
+ - `scripts/release.mjs` generates notes by default and supports `--no-generate-notes`.
90
+ - `.github/workflows/release.yml` exposes a `generate_notes` input that defaults to true and passes `DEEPSEEK_API_KEY` for release-note generation.
91
+ - `docs/CHANGELOG.md` receives a full Markdown release section when notes generation is enabled.
92
+ - `docs/ROADMAP.md` lists S0063 as Done after implementation and verification.
93
+
94
+ ## Test Requirements
95
+
96
+ Run:
97
+
98
+ ```bash
99
+ node --test scripts/release-notes.test.mjs
100
+ pnpm release-notes --from v0.0.1 --to HEAD --version 0.0.2
101
+ pnpm release patch --dry-run
102
+ pnpm typecheck
103
+ pnpm test
104
+ git diff --check
105
+ ```
106
+
107
+ The standalone `pnpm release-notes` command may require `DEEPSEEK_API_KEY` for the AI path. Tests must cover the deterministic collector, prompt payload, Markdown renderer, changelog insertion, and dry-run fallback behavior without calling the real API.
108
+
109
+ Collector tests must cover a commit that changes generated files plus a real release script file, and assert that the collector never calls `git show --patch` for generated files or for the whole commit patch.
110
+
111
+ ## Affected Paths
112
+
113
+ - `package.json`
114
+ - `scripts/release.mjs`
115
+ - `scripts/release-notes.mjs`
116
+ - `scripts/release-notes.test.mjs`
117
+ - `.github/workflows/release.yml`
118
+ - `docs/SHIP.md`
119
+ - `docs/ROADMAP.md`
120
+ - `docs/CHANGELOG.md`
121
+ - `docs/spec/ship/S0063-ai-release-notes.md`
122
+ - `docs/superpowers/plans/2026-06-08-s0063-ai-release-notes.md`
123
+
124
+ ## Risks
125
+
126
+ - AI may overstate work. Mitigate with commit-level evidence, strict JSON validation, conservative prompts, and explicit handling of SHIP specs as context rather than proof of shipped behavior.
127
+ - Large diffs can exceed practical request size, and generated bundle diffs can exceed Node child-process output buffers before the model is called. Exclude generated files before patch reads, then truncate oversized non-generated patches while preserving file names and diff stats.
128
+ - Release should not silently ship empty notes. Formal releases fail on AI generation errors unless `--no-generate-notes` is explicit; dry-run can fall back for preview.
129
+ - DeepSeek API shape may drift. Keep base URL, model, and token limits configurable through environment variables.
@@ -0,0 +1,79 @@
1
+ # S0064: GUI Product Intent And Boundary
2
+
3
+ ## Goal
4
+
5
+ Lock M9 GUI as a Project-first desktop app before implementation. The GUI should feel and behave like a Codex App-style workbench: local-first, project-centric, quiet, dense, and built for repeated engineering work.
6
+
7
+ ## Scope
8
+
9
+ - Define GUI as an independent desktop app under `apps/gui`.
10
+ - Use Electron for the first GUI implementation because the current Scorel runtime, Host, CLI, Relay client, and package graph are TypeScript / Node-first.
11
+ - Keep the public `@chanlerdev/scorel` npm package focused on the CLI / Host / Relay operator surface; GUI distribution is separate.
12
+ - Define GUI information architecture:
13
+ - Project-first main workspace.
14
+ - Settings manages Devices and connectors.
15
+ - Device identity is metadata and connection source, not the main navigation root.
16
+ - Define local behavior:
17
+ - GUI main process uses embedded local Host.
18
+ - Local Host Registry projects are all visible in the GUI project list.
19
+ - Define remote behavior:
20
+ - M9 remote scope is Relay-only.
21
+ - Settings can add Relay Devices.
22
+ - Remote Projects appear only after the user explicitly selects them in GUI.
23
+ - GUI must not auto-display the full remote Host Registry the way WebUI does.
24
+ - Define design direction:
25
+ - Codex App is the primary product reference.
26
+ - Existing WebUI components and style rules may be reused where they match the GUI product model.
27
+
28
+ ## Non-Goals
29
+
30
+ - Do not scaffold Electron in S0064.
31
+ - Do not implement GUI screens.
32
+ - Do not add SSH, direct WS + token, OAuth, account systems, or GUI auto-update.
33
+ - Do not publish or package desktop installers.
34
+ - Do not change the public npm CLI package surface.
35
+
36
+ ## Contract
37
+
38
+ ### Product Model
39
+
40
+ WebUI and GUI intentionally differ:
41
+
42
+ - WebUI is Device-first. After a Device is connected, WebUI shows the Device Host Registry's full Project list.
43
+ - GUI is Project-first. Local Projects are shown in full, but remote Projects are curated by explicit user selection.
44
+
45
+ ### Desktop Boundary
46
+
47
+ Electron main process may depend on Node-only Scorel packages and own local Host lifecycle. Electron renderer must remain an Entry UI: it may call GUI bridge APIs or `@scorel/client`, but it must not hold Runtime, write JSONL, or duplicate Host domain logic.
48
+
49
+ ### Remote Boundary
50
+
51
+ M9 remote work uses Relay only. SSH Remote Device remains M10. Direct WS + token remains an advanced/non-M9 path.
52
+
53
+ ## Acceptance Criteria
54
+
55
+ - `docs/ROADMAP.md` splits M9 into executable S specs.
56
+ - `docs/spec/ship/S0064-gui-product-intent-and-boundary.md` records the GUI product boundary.
57
+ - The spec clearly states Electron is a GUI app distribution choice, not a change to the public npm CLI package.
58
+ - The spec clearly states remote Project visibility differs from WebUI.
59
+ - The spec clearly states M9 remote scope is Relay-only.
60
+
61
+ ## Test Requirements
62
+
63
+ Docs-only:
64
+
65
+ ```bash
66
+ git diff --check
67
+ ```
68
+
69
+ ## Affected Paths
70
+
71
+ - `docs/ROADMAP.md`
72
+ - `docs/spec/ship/S0064-gui-product-intent-and-boundary.md`
73
+ - `self/discussions/2026-06-08-repo-sync-and-m9-next-step.md`
74
+
75
+ ## Risks
76
+
77
+ - Electron may inflate install size. This is acceptable for GUI distribution but must not leak into the CLI npm package.
78
+ - Reusing WebUI too directly can accidentally preserve Device-first information architecture. S0064 locks Project-first as the GUI product rule.
79
+ - Showing all remote Projects would expose too much remote workspace state and weaken the desktop curation model.
@@ -0,0 +1,73 @@
1
+ # S0065: GUI Electron Shell And Embedded Host
2
+
3
+ ## Goal
4
+
5
+ Create the first `apps/gui` Electron app shell and connect it to the local embedded Scorel Host. After this spec, opening the GUI should prove that desktop main process, renderer, and local Host lifecycle can cooperate without duplicating Runtime or Session ownership.
6
+
7
+ ## Scope
8
+
9
+ - Add `apps/gui` workspace package.
10
+ - Add Electron main process and renderer entry.
11
+ - Add a small GUI bridge between renderer and main process.
12
+ - Start or attach to an embedded local Host from the GUI main process.
13
+ - Expose local Host connection state to the renderer.
14
+ - List local Host Registry Projects through Host / client APIs.
15
+ - Keep UI minimal: enough shell to show local connection and Project list placeholder.
16
+ - Keep GUI distribution separate from `@chanlerdev/scorel` npm CLI package.
17
+
18
+ ## Non-Goals
19
+
20
+ - Do not implement full chat UX.
21
+ - Do not implement Relay Device settings.
22
+ - Do not implement remote Project selection.
23
+ - Do not package signed desktop installers.
24
+ - Do not implement auto-start, tray behavior, or auto-update.
25
+ - Do not add SSH or direct WS connector support.
26
+
27
+ ## Acceptance Criteria
28
+
29
+ - `apps/gui` exists and is included in the workspace.
30
+ - GUI can be launched in development from a root script or package script.
31
+ - Electron main owns embedded local Host startup / connection.
32
+ - Renderer can display local Host status and local Project list from the embedded Host.
33
+ - Renderer does not import `@scorel/core` or directly write session JSONL.
34
+ - Existing CLI release package does not include GUI files unless a later spec explicitly changes desktop distribution.
35
+
36
+ ## Test Requirements
37
+
38
+ Run focused checks for the GUI package plus existing repo checks:
39
+
40
+ ```bash
41
+ pnpm --filter @scorel/app-gui build
42
+ pnpm --filter @scorel/app-gui typecheck
43
+ pnpm --filter @scorel/app-gui test
44
+ pnpm typecheck
45
+ pnpm test
46
+ pnpm pack:smoke
47
+ git diff --check
48
+ ```
49
+
50
+ GUI smoke command:
51
+
52
+ ```bash
53
+ pnpm gui
54
+ ```
55
+
56
+ If GUI smoke cannot run in the current environment, document the limitation in the final handoff.
57
+
58
+ ## Affected Paths
59
+
60
+ - `package.json`
61
+ - `pnpm-lock.yaml`
62
+ - `pnpm-workspace.yaml`
63
+ - `.gitignore`
64
+ - `apps/gui/**`
65
+ - `packages/client/**` if bridge/client APIs need small reuse adjustments
66
+ - `docs/ROADMAP.md`
67
+ - `docs/spec/ship/S0065-gui-electron-shell-and-embedded-host.md`
68
+
69
+ ## Risks
70
+
71
+ - Electron dependency churn can bloat the monorepo. Keep GUI dependencies scoped to `apps/gui`.
72
+ - Renderer/main boundaries can become leaky. Treat renderer as an Entry UI and keep Host ownership in main.
73
+ - Embedded Host lifecycle may diverge from CLI `scorel` behavior. Reuse existing Host APIs where possible instead of creating GUI-only behavior.
@@ -0,0 +1,79 @@
1
+ # S0066: GUI Local Project Workspace
2
+
3
+ ## Goal
4
+
5
+ Make the GUI useful for local work: show all local Projects in a Project-first workspace, let the user create or open Sessions, and provide the first local chat surface over the embedded Host.
6
+
7
+ ## Scope
8
+
9
+ - Build the Project-first main GUI layout:
10
+ - Project list as the primary navigation.
11
+ - Session list scoped to the selected Project.
12
+ - Chat / composer surface for the selected Session.
13
+ - Show all Projects from the local Host Registry.
14
+ - Add local Project through a desktop folder picker and `registerProject(workDir)`.
15
+ - Create a new Session for a selected local Project.
16
+ - Load existing Sessions via `listSessions({ projectId })`.
17
+ - Send prompts through the same Host / DaemonClient path used by other entries.
18
+ - Reuse WebUI rendering pieces only where they fit Codex App-style desktop UX.
19
+
20
+ ## Non-Goals
21
+
22
+ - Do not add Relay Device settings.
23
+ - Do not add remote Project selection.
24
+ - Do not implement SSH or direct WS.
25
+ - Do not implement advanced Codex App features such as diffs, file tree, approval UI, terminal panes, or task tabs.
26
+ - Do not add model picker functionality unless it already exists as a shared product path.
27
+
28
+ ## Acceptance Criteria
29
+
30
+ - GUI starts with local Projects visible without requiring Device selection.
31
+ - Selecting a local Project shows its Sessions.
32
+ - New Session creates a Session bound to the selected `projectId`.
33
+ - Sending a prompt uses the embedded local Host and writes a real JSONL Session.
34
+ - Local Project addition uses the system folder picker and Host `registerProject`.
35
+ - Local Project list updates after registration.
36
+ - UI is Project-first; Device is not the main navigation hierarchy.
37
+
38
+ ## Test Requirements
39
+
40
+ Run:
41
+
42
+ ```bash
43
+ pnpm --filter @scorel/app-gui build
44
+ pnpm --filter @scorel/app-gui typecheck
45
+ pnpm --filter @scorel/app-gui test
46
+ pnpm typecheck
47
+ pnpm test
48
+ pnpm pack:smoke
49
+ git diff --check
50
+ ```
51
+
52
+ GUI smoke command:
53
+
54
+ ```bash
55
+ pnpm gui
56
+ ```
57
+
58
+ Manual smoke must use:
59
+
60
+ - real local temporary Project directory
61
+ - embedded local Host
62
+ - real JSONL Session
63
+ - real provider for at least one prompt if this spec wires chat sending end to end
64
+
65
+ If provider credentials are unavailable, automated GUI tests must still cover the prompt-send path with a real `ScorelRuntime` and fake provider.
66
+
67
+ ## Affected Paths
68
+
69
+ - `apps/gui/**`
70
+ - `packages/client/**` if shared session projection needs extraction
71
+ - `packages/daemon/**` only for reusable embedded Host API gaps
72
+ - `docs/ROADMAP.md`
73
+ - `docs/spec/ship/S0066-gui-local-project-workspace.md`
74
+
75
+ ## Risks
76
+
77
+ - Over-copying WebUI can recreate Device-first navigation. Keep Project as the first-level object.
78
+ - Local folder picker can tempt renderer-side filesystem access. Use main process bridge and Host APIs; renderer should not become the owner of Project canonicalization.
79
+ - Chat surface scope can grow. Keep S0066 focused on local session creation, display, and prompt sending.