@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
package/docs/spec/extensions.md
CHANGED
|
@@ -57,45 +57,42 @@ type ScorelEvent =
|
|
|
57
57
|
|
|
58
58
|
## 3. Extensions 系统
|
|
59
59
|
|
|
60
|
-
|
|
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
|
-
|
|
75
|
+
type ExtensionManifest = {
|
|
64
76
|
id: string;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
85
|
+
`mcp` 在 S0083 只解析保留,不启动 MCP server。
|
|
90
86
|
|
|
91
87
|
### 3.2 加载路径与时机
|
|
92
88
|
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
```text
|
|
90
|
+
extensions/builtin/ ← 内置,只读,随包发布
|
|
91
|
+
~/.scorel/extensions/ ← 用户级
|
|
92
|
+
.scorel/extensions/ ← 项目级,后续扩展
|
|
96
93
|
```
|
|
97
94
|
|
|
98
|
-
|
|
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。**
|
|
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
|
-
|
|
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"
|
|
169
|
+
pi-ai 已支持的内置 provider 使用 `type = "builtin"`。Scorel 只把 provider/model/api key 交给 pi-ai,不在本仓库重写 provider 协议:
|
|
169
170
|
|
|
170
171
|
```toml
|
|
171
|
-
[
|
|
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
|
-
[
|
|
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
|
-
|
|
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
|
|
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
|
-
-
|
|
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 配置的核心段:`[
|
|
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]` / `[
|
|
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.
|