@chanlerdev/scorel 0.0.1

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 (80) hide show
  1. package/README.md +110 -0
  2. package/dist/index.js +6675 -0
  3. package/dist/index.js.map +7 -0
  4. package/docs/CHANGELOG.md +12 -0
  5. package/docs/README.md +116 -0
  6. package/docs/ROADMAP.md +669 -0
  7. package/docs/SHIP.md +242 -0
  8. package/docs/spec/channels.md +156 -0
  9. package/docs/spec/client.md +326 -0
  10. package/docs/spec/daemon.md +408 -0
  11. package/docs/spec/events.md +423 -0
  12. package/docs/spec/extensions.md +255 -0
  13. package/docs/spec/relay.md +391 -0
  14. package/docs/spec/runtime.md +251 -0
  15. package/docs/spec/session.md +380 -0
  16. package/docs/spec/ship/S0001-docs-baseline.md +41 -0
  17. package/docs/spec/ship/S0002-package-skeleton.md +56 -0
  18. package/docs/spec/ship/S0003-protocol-contracts.md +49 -0
  19. package/docs/spec/ship/S0004-session-core.md +50 -0
  20. package/docs/spec/ship/S0005-runtime-loop.md +48 -0
  21. package/docs/spec/ship/S0006-embedded-daemon-client.md +51 -0
  22. package/docs/spec/ship/S0007-cli-alpha.md +49 -0
  23. package/docs/spec/ship/S0008-coding-tools.md +107 -0
  24. package/docs/spec/ship/S0009-code-discovery-tools.md +82 -0
  25. package/docs/spec/ship/S0010-todo-tool-and-cli.md +81 -0
  26. package/docs/spec/ship/S0011-coding-agent-alpha-smoke.md +110 -0
  27. package/docs/spec/ship/S0012-coding-tools-maturity.md +143 -0
  28. package/docs/spec/ship/S0013-local-daemon-protocol.md +57 -0
  29. package/docs/spec/ship/S0014-local-daemon-lifecycle.md +64 -0
  30. package/docs/spec/ship/S0015-local-attach-and-broadcast.md +58 -0
  31. package/docs/spec/ship/S0016-local-daemon-resync-smoke.md +60 -0
  32. package/docs/spec/ship/S0017-grep-files-output-mode.md +49 -0
  33. package/docs/spec/ship/S0018-daemon-entrypoint-smoke.md +48 -0
  34. package/docs/spec/ship/S0019-remote-transport-contract.md +59 -0
  35. package/docs/spec/ship/S0020-remote-websocket-server.md +56 -0
  36. package/docs/spec/ship/S0021-remote-websocket-client-transport.md +55 -0
  37. package/docs/spec/ship/S0022-remote-daemon-cli-lifecycle.md +60 -0
  38. package/docs/spec/ship/S0023-remote-control-e2e-validation.md +66 -0
  39. package/docs/spec/ship/S0024-remote-attach-interactive-stream.md +49 -0
  40. package/docs/spec/ship/S0025-remote-attach-session-event-view.md +57 -0
  41. package/docs/spec/ship/S0026-attach-project-cache-and-dual-seq-reconnect.md +87 -0
  42. package/docs/spec/ship/S0027-session-diagnostics-log.md +77 -0
  43. package/docs/spec/ship/S0028-client-attach-diagnostics-log.md +70 -0
  44. package/docs/spec/ship/S0029-project-index-for-session-lookup.md +119 -0
  45. package/docs/spec/ship/S0030-webui-product-intent.md +73 -0
  46. package/docs/spec/ship/S0031-daemon-projectslug-rule.md +72 -0
  47. package/docs/spec/ship/S0032-daemon-protocol-completion.md +123 -0
  48. package/docs/spec/ship/S0033-webui-skeleton-routing.md +92 -0
  49. package/docs/spec/ship/S0034-webui-device-settings.md +121 -0
  50. package/docs/spec/ship/S0035-webui-device-handshake.md +83 -0
  51. package/docs/spec/ship/S0036-webui-project-session-sync.md +70 -0
  52. package/docs/spec/ship/S0037-webui-chatbox-v1.md +97 -0
  53. package/docs/spec/ship/S0038-webui-cancel-multiclient.md +65 -0
  54. package/docs/spec/ship/S0039-webui-e2e-newchat.md +74 -0
  55. package/docs/spec/ship/S0040-webui-codex-visual-tokens.md +227 -0
  56. package/docs/spec/ship/S0041-webui-markdown-and-tool-block.md +248 -0
  57. package/docs/spec/ship/S0042-webui-streaming-ux-autoscroll.md +130 -0
  58. package/docs/spec/ship/S0043-startup-ergonomics.md +278 -0
  59. package/docs/spec/ship/S0044-webui-chatbox-rebuild.md +556 -0
  60. package/docs/spec/ship/S0045-webui-card-sidebar-and-session-fixes.md +469 -0
  61. package/docs/spec/ship/S0046-webui-empty-composer-and-lazy-session.md +428 -0
  62. package/docs/spec/ship/S0047-webui-project-hover-newchat-and-dynamic-greeting.md +176 -0
  63. package/docs/spec/ship/S0048-device-level-host-project-registry.md +253 -0
  64. package/docs/spec/ship/S0049-webui-add-project-directory-browser.md +217 -0
  65. package/docs/spec/ship/S0050-instruction-snapshot-and-agents-assembly.md +338 -0
  66. package/docs/spec/ship/S0051-harness-item-and-system-reminder.md +190 -0
  67. package/docs/spec/ship/S0052-follow-up-queue-and-dual-loop.md +195 -0
  68. package/docs/spec/ship/S0053-skill-index-and-skill-tool.md +252 -0
  69. package/docs/spec/ship/S0054-webui-running-message-behavior.md +72 -0
  70. package/docs/spec/ship/S0055-webui-composer-acceptance-and-queue-strip.md +68 -0
  71. package/docs/spec/ship/S0056-relay-and-hosted-webui-contract.md +106 -0
  72. package/docs/spec/ship/S0057-relay-service-protocol-skeleton.md +161 -0
  73. package/docs/spec/ship/S0058-host-outbound-relay-and-pair-command.md +138 -0
  74. package/docs/spec/ship/S0059-relay-transport-and-hosted-webui-connector.md +140 -0
  75. package/docs/spec/ship/S0060-relay-hosted-webui-e2e-validation.md +132 -0
  76. package/docs/spec/ship/S0060-relay-hosted-webui-e2e-validation.verification.md +90 -0
  77. package/docs/spec/ship/S0061-hosted-defaults-and-cli-command-surface.md +208 -0
  78. package/docs/spec/ship/S0062-npm-package-and-release-workflow.md +166 -0
  79. package/docs/spec/tools.md +173 -0
  80. package/package.json +51 -0
package/docs/SHIP.md ADDED
@@ -0,0 +1,242 @@
1
+ # Scorel Ship Protocol
2
+
3
+ > 给 AI 和人类工程师的交付入口。实现前先读本文件,再读 Roadmap、目标 S spec、相关抽象 spec 和 ADR。
4
+
5
+ ---
6
+
7
+ ## Source Of Truth
8
+
9
+ 读取顺序:
10
+
11
+ 1. `docs/architecture.md` — 系统分层、包边界、数据流。
12
+ 2. `docs/decisions/*.md` — 已锁定的架构决策。
13
+ 3. `docs/ROADMAP.md` — 产品阶段目标。
14
+ 4. `docs/spec/*.md` — 抽象规约。
15
+ 5. `docs/spec/ship/*.md` — 当前 active S spec。
16
+
17
+ `docs/IMPLEMENTATION_PROMPT.md` 和旧实现不作为 source of truth。
18
+
19
+ `self/` 只用于本机探索性草稿,不纳入 Git handoff,也不得成为实现所需上下文。确认后的结论必须同步到 `docs/`。
20
+
21
+ ---
22
+
23
+ ## Quickstart
24
+
25
+ ```bash
26
+ pnpm install
27
+ pnpm scorel # 在当前目录进入交互式项目会话
28
+ ```
29
+
30
+ Hosted WebUI 路径:
31
+
32
+ ```bash
33
+ pnpm scorel host serve
34
+ open https://scorel.chanler.dev
35
+ pnpm scorel pair <pair-code>
36
+ ```
37
+
38
+ `scorel host serve` 会启动本机 Host、注册当前目录为初始 Project,并默认连接官方 Relay。`scorel up` / `pnpm dev` 只作为本地开发便利入口:本地 Host + 本地 WebUI。
39
+
40
+ ---
41
+
42
+ ## Check
43
+
44
+ 当前一键验证:
45
+
46
+ ```bash
47
+ pnpm typecheck && pnpm test
48
+ ```
49
+
50
+ 默认验证原则:
51
+
52
+ - 走真实、统一、通用的产品路径。
53
+ - 不用 mock/fake provider 作为完成证明。
54
+ - 不为测试添加隐藏分支、特殊协议、特殊 transport 或只在测试里存在的产品行为。
55
+ - 临时目录、临时端口、真实本地进程、真实 JSONL session 属于可接受的真实资源;mock/fake 和为测试绕过产品路径不接受,除非用户明确要求。
56
+
57
+ 涉及 `scorel chat` 真实产品路径的 spec,还必须补一条手工端到端验证:用真实 LLM provider、真实临时工作区和真实 JSONL session 验证端到端行为。不能用 mock/fake provider 作为完成证明。
58
+
59
+ 后续可以收敛成 `pnpm check` 或 `node scripts/check.mjs`,但 SHIP 里记录的命令必须始终可直接执行。
60
+
61
+ ---
62
+
63
+ ## Development Stage Rule
64
+
65
+ Scorel 当前仍处于 pre-1.0 开发阶段。除非某个 spec 明确要求兼容,否则默认规则是:
66
+
67
+ - 优先选择长期正确、边界清晰的架构,不为未发布的旧实现保留兼容层。
68
+ - 可以删除旧命令、旧 schema、旧 transport、旧缓存和旧本地状态文件。
69
+ - 不添加 deprecated alias、双写逻辑、自动迁移器或 fallback 分支来延长错误抽象。
70
+ - 发生 wire protocol 不兼容变更时,直接更新 protocol 类型、调用方、测试和 `protocolVersion`。
71
+ - 发生本地状态不兼容变更时,在 spec 中写清楚需要删除或重建的 `~/.scorel` 工件。
72
+
73
+ 这条规则不代表可以无说明地破坏用户数据。Session JSONL 是否保留、重建或删除,必须由当前 spec 显式决定。
74
+
75
+ ---
76
+
77
+ ## Ship Loop
78
+
79
+ ### 1. Idea
80
+
81
+ 新想法先讨论,不直接写代码。本机可选草稿位置:
82
+
83
+ ```text
84
+ self/discussions/YYYY-MM-DD-topic.md
85
+ ```
86
+
87
+ 确认为方向后,写成编号 spec:
88
+
89
+ ```text
90
+ docs/spec/ship/S####-slug.md
91
+ ```
92
+
93
+ ### 2. Spec
94
+
95
+ 每个 S spec 是实现合同,必须包含:
96
+
97
+ - 目标
98
+ - 范围
99
+ - 不做什么
100
+ - 验收标准
101
+ - 测试要求
102
+ - 影响文件 / 包
103
+ - 风险与边界
104
+
105
+ 没有 S spec,不开始实现。Bug fix 也需要 S spec,可以很短。
106
+
107
+ ### 3. Ship
108
+
109
+ 实现一个 S spec 时:
110
+
111
+ 1. 只读当前 spec 相关上下文。
112
+ 2. 先写失败测试或类型约束。
113
+ 3. 做最小实现。
114
+ 4. 运行精确测试。
115
+ 5. 运行全量 check。
116
+ 6. 更新必要文档。
117
+ 7. 提交时使用 S 编号。
118
+
119
+ 实现中发现延伸能力,不混入当前 spec;写入 Roadmap 或新 S spec。
120
+
121
+ ---
122
+
123
+ ## Commit And PR
124
+
125
+ 格式:
126
+
127
+ ```text
128
+ S####: <type>: <description>
129
+ ```
130
+
131
+ `type`:
132
+
133
+ - `feat`
134
+ - `fix`
135
+ - `refactor`
136
+ - `perf`
137
+ - `chore`
138
+ - `docs`
139
+ - `test`
140
+
141
+ 规则:
142
+
143
+ - 一个 PR 对应一个 S spec。
144
+ - Commit message 使用 title-only semantic commit:只写标题,不写正文。
145
+ - 按业务含义拆 commit,不把无关实现混在一起。
146
+ - 文档、实现、测试可以拆 commit,但 PR title 必须带 S 编号。
147
+ - 首个 docs baseline 已完成;后续提交只按当前 S spec 收敛范围。
148
+
149
+ ---
150
+
151
+ ## Version
152
+
153
+ Scorel 使用统一版本号:所有 `@scorel/*` package 与 apps 同步版本发布。
154
+
155
+ 默认版本 bump:
156
+
157
+ - `patch`:默认。所有普通 spec、bug fix、refactor、内部协议演进都走 patch。
158
+ - `minor`:只有用户明确指定,通常用于 milestone 级能力开放。
159
+ - `major`:只有用户明确指定。`1.0.0` 前原则上不自动 major。
160
+
161
+ 初始版本:
162
+
163
+ ```text
164
+ 0.0.0
165
+ ```
166
+
167
+ 第一次 release:
168
+
169
+ ```text
170
+ 0.0.1
171
+ ```
172
+
173
+ Wire protocol 另有兼容版本:
174
+
175
+ ```text
176
+ protocolVersion: 1
177
+ ```
178
+
179
+ `protocolVersion` 只在 daemon/client 握手不兼容时增加。package version 和 protocolVersion 不混用。
180
+
181
+ ---
182
+
183
+ ## Release
184
+
185
+ 发布前置条件:
186
+
187
+ - working tree clean
188
+ - 当前分支不是 detached HEAD
189
+ - 目标 S spec 已完成并可验证
190
+ - check 通过
191
+ - version bump 默认为 patch,除非用户明确指定 minor / major
192
+
193
+ 推荐命令形态:
194
+
195
+ ```bash
196
+ pnpm release patch --dry-run
197
+ pnpm release patch
198
+ pnpm release minor
199
+ pnpm release major
200
+ ```
201
+
202
+ 正式 release 脚本职责包括:
203
+
204
+ - 检查 working tree
205
+ - 执行 check
206
+ - 执行 WebUI production build
207
+ - 构建 public `scorel` npm package
208
+ - 执行 `npm pack` 安装烟雾测试
209
+ - bump 所有 package version
210
+ - 更新 changelog
211
+ - commit `release: vX.Y.Z`
212
+ - tag `vX.Y.Z`
213
+ - push branch + tag
214
+ - publish root `scorel` package to npm
215
+
216
+ GitHub Actions 提供手动触发入口,默认执行 `patch` dry-run。正式 publish 需要仓库 secret `NPM_TOKEN`,对应 npm 账号当前为 `chanlerdev`。
217
+
218
+ ---
219
+
220
+ ## Branch
221
+
222
+ 默认分支前缀遵循当前 Codex 工作约定:
223
+
224
+ ```text
225
+ codex/S####-slug
226
+ ```
227
+
228
+ 如果用户明确要求其他前缀,以用户要求为准。
229
+
230
+ ---
231
+
232
+ ## Documentation Sync
233
+
234
+ - 架构边界变化 → `docs/architecture.md` + `docs/decisions/ADR`
235
+ - 模块接口变化 → 对应 `docs/spec/*.md`
236
+ - 新工作单元 → `docs/spec/ship/S####-*.md`(只在准备实现或范围已确认时创建)
237
+ - 计划变化 → `docs/ROADMAP.md`
238
+ - 配置 schema / provider 接入变化 → `docs/spec/extensions.md` + 当前 S spec
239
+ - 讨论和取舍 → 可选本机草稿 `self/discussions/`
240
+ - 决策锁定 → 必须同步 `docs/decisions/`
241
+
242
+ 探索性笔记不混进 ADR;未确认方向不写成正式决策。任何需要跨机器继续开发的上下文都必须写入 Git 跟踪的 `docs/`。
@@ -0,0 +1,156 @@
1
+ # Channel — Daemon 内部的消息注入适配器
2
+
3
+ > 上游:`architecture.md`、`spec/daemon.md`
4
+ > 主题:把 IM 消息、cron 触发等外部输入归一为 Daemon 内部的 `AgentMessage` 注入。
5
+
6
+ ---
7
+
8
+ ## 1. 设计目标
9
+
10
+ Channel 是 **Daemon 内部的子模块**,负责将非交互式的外部输入(IM、cron、webhook)转化为标准的 `AgentMessage` 注入 Runtime。
11
+
12
+ **不再是**:Entry 的统一入口(Entry 通过 DaemonClient 协议直连 Daemon)。
13
+
14
+ Channel 只处理那些"不是人坐在终端前打字"的输入源。CLI / GUI / WebUI 这些交互式 Entry 直接通过 DaemonClient 协议发送指令,不经过 Channel。
15
+
16
+ ---
17
+
18
+ ## 2. Channel 与 Entry 的区别
19
+
20
+ | | Entry(交互式) | Channel(非交互式) |
21
+ |---|---|---|
22
+ | 例子 | CLI / GUI / WebUI | Telegram Bot / cron / webhook |
23
+ | 连接方式 | DaemonClient 协议 | Daemon 内部模块 |
24
+ | 生命周期 | 用户主动连接/断开 | Daemon 启动时加载,持续运行 |
25
+ | 双向通信 | ✅ 收发 event | ❌ 只注入消息,不接收实时事件流 |
26
+ | 输出回传 | DaemonClient event stream | Channel 自行轮询或 hook 回调 |
27
+
28
+ ---
29
+
30
+ ## 3. ChannelAdapter 接口
31
+
32
+ ```typescript
33
+ interface ChannelAdapter {
34
+ readonly id: string; // 'telegram' | 'wechat' | 'cron' | 'webhook'
35
+ start(ctx: ChannelContext): Promise<void>;
36
+ stop(): Promise<void>;
37
+ }
38
+
39
+ interface ChannelContext {
40
+ inject: MessageInjector;
41
+ subscribe: (cb: (event: ScorelEvent) => void) => () => void;
42
+ config: ChannelConfig;
43
+ }
44
+
45
+ type MessageInjector = (msg: AgentMessage) => Promise<void>;
46
+ ```
47
+
48
+ Channel 职责:
49
+ 1. 从外部源接收消息
50
+ 2. 调 `inject(msg)` 注入 Daemon
51
+ 3. 可选:订阅 event 流用于回传结果(如 Telegram bot 需要把 assistant 回复发回群里)
52
+
53
+ ---
54
+
55
+ ## 4. Injector:Daemon 内部路由
56
+
57
+ ```typescript
58
+ // Daemon 内部实现
59
+ function createInjector(daemon: Daemon): MessageInjector {
60
+ return async (msg) => {
61
+ // 走 session lane 串行化,与 DaemonClient.prompt() 同等待遇
62
+ await daemon.enqueue({ method: "prompt", params: { text: msg } });
63
+ };
64
+ }
65
+ ```
66
+
67
+ Channel 注入的消息和 DaemonClient 发来的 prompt **走同一条路径**,享受同样的并发控制和事件广播。
68
+
69
+ ---
70
+
71
+ ## 5. 消息载体:`<system_reminder>` 包裹
72
+
73
+ 非交互式 Channel 注入时,用 `<system_reminder>` XML 包裹,让 LLM 区分来源:
74
+
75
+ ```typescript
76
+ await inject({
77
+ role: 'user',
78
+ content: `<system_reminder source="telegram" from="${msg.from}">
79
+ ${msg.content}
80
+ </system_reminder>`,
81
+ timestamp: Date.now(),
82
+ });
83
+ ```
84
+
85
+ ---
86
+
87
+ ## 6. 初期落地的 Channel
88
+
89
+ | Channel | 形态 | 阶段 |
90
+ |---------|------|------|
91
+ | `telegram` | Bot API,收到 mention/DM 时注入 | 后期 |
92
+ | `wechat` | WeCom / 非官方桥 | 后期 |
93
+ | `cron` | 定时任务触发(`node-cron`) | 后期 |
94
+ | `webhook` | HTTP POST 触发注入 | 后期 |
95
+
96
+ **初期不需要任何 Channel**。CLI/GUI 通过 DaemonClient 直连 Daemon,Channel 是 IM/自动化场景的补充。
97
+
98
+ ---
99
+
100
+ ## 7. Channel 输出回传
101
+
102
+ IM Bot 需要把 agent 回复发回对话。两种方式:
103
+
104
+ **方式 A:subscribe event stream(推荐)**
105
+ ```typescript
106
+ class TelegramChannel implements ChannelAdapter {
107
+ async start(ctx: ChannelContext) {
108
+ // 订阅 assistant 消息,发回 Telegram
109
+ ctx.subscribe((event) => {
110
+ if (event.type === "message_end" && event.message.role === "assistant") {
111
+ this.sendToTelegram(event.message);
112
+ }
113
+ });
114
+ // 监听 Telegram 消息,注入 Daemon
115
+ this.bot.on("message", (msg) => ctx.inject(wrapMessage(msg)));
116
+ }
117
+ }
118
+ ```
119
+
120
+ **方式 B:afterTurn hook(简单场景)**
121
+ ```typescript
122
+ // 作为 Extension 实现,在每轮结束后回传
123
+ onEvent: async (event) => {
124
+ if (event.type === "turn_end") { ... }
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## 8. 与 Daemon 的关系
131
+
132
+ ```
133
+ Daemon
134
+ ├── DaemonServer(处理 client 连接:CLI/GUI/WebUI)
135
+ ├── ChannelManager(管理非交互式输入源)
136
+ │ ├── TelegramChannel
137
+ │ ├── CronChannel
138
+ │ └── WebhookChannel
139
+ ├── SessionManager
140
+ └── ScorelRuntime
141
+ ```
142
+
143
+ Channel 是 Daemon 的可选模块。纯本地 embedded 模式下不加载任何 Channel。
144
+
145
+ ---
146
+
147
+ ## 9. 延后项
148
+
149
+ - IM Channel 具体实现(Telegram、企业微信、Slack)
150
+ - cron Channel 调度模型
151
+ - Channel 级别的消息去重/防抖(IM 群消息风暴)
152
+ - Channel 权限(哪些群/用户能触发 agent)
153
+
154
+ ---
155
+
156
+ *Channel 从"所有输入的统一入口"收窄为"Daemon 内部的非交互式消息源适配器"。交互式 Entry 通过 DaemonClient 协议直连,不经过 Channel。*