@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
@@ -0,0 +1,208 @@
1
+ # S0061: Hosted Defaults And CLI Command Surface
2
+
3
+ ## Goal
4
+
5
+ Make the post-M8 user path match the deployed product:
6
+
7
+ ```text
8
+ local terminal -> local Scorel Host -> official Relay -> hosted WebUI
9
+ ```
10
+
11
+ The CLI should expose product concepts instead of implementation leakage:
12
+
13
+ - `scorel` is the normal interactive project command, similar to `claude`.
14
+ - `scorel host serve` starts this device's local Host and connects it to Relay by default.
15
+ - `scorel pair <code>` authorizes the hosted WebUI Entry through the default Relay.
16
+ - `scorel relay serve` is only for operating a self-hosted Relay service.
17
+
18
+ ## Current Deployment Baseline
19
+
20
+ - Hosted WebUI: `https://scorel.chanler.dev`
21
+ - Relay WebSocket URL: `wss://scorel-relay.chanler.dev`
22
+
23
+ Self-hosted and development flows can override the Relay URL with `SCOREL_RELAY_URL` or `--relay <url>`.
24
+
25
+ ## Scope
26
+
27
+ - Add first-class hosted defaults:
28
+ - official WebUI origin
29
+ - official Relay URL
30
+ - environment/config override for self-hosted deployments
31
+ - Redesign user-facing CLI commands:
32
+ - `scorel` defaults to interactive project execution in `process.cwd()`
33
+ - `scorel chat` remains as an explicit alias for the same interactive mode
34
+ - `scorel host serve` replaces user-facing `scorel daemon serve`
35
+ - `scorel host serve` registers `process.cwd()` as the initial Project by default
36
+ - `scorel host serve` connects outbound to the official Relay by default
37
+ - `scorel host serve --no-relay` starts local-only
38
+ - `scorel host serve --relay <url>` uses a self-hosted Relay
39
+ - `scorel host serve --replace` stops an already-running local Host and starts a fresh one
40
+ - `scorel pair <code>` uses the official Relay by default
41
+ - `scorel pair <code> --relay <url>` remains for self-hosted Relay
42
+ - `scorel relay serve` runs a Relay service for self-hosting/development
43
+ - Keep implementation aliases where needed:
44
+ - `scorel daemon ...` may remain as a compatibility/internal alias during pre-1.0
45
+ - docs and usage output must prefer `host`
46
+ - Update CLI help, README, docs, and tests to match the new command model.
47
+ - Keep `scorel up` as a development convenience for local Host + local WebUI, not the primary hosted user path.
48
+ - Ensure previously landed S0061 Vercel install/build support is represented in the docs where relevant.
49
+
50
+ ## Non-Goals
51
+
52
+ - Do not add accounts or OAuth.
53
+ - Do not add hosted execution.
54
+ - Do not make Relay store Project, Session, prompt, tool result, provider response, or replay state.
55
+ - Do not implement desktop GUI.
56
+ - Do not implement SSH remote bootstrap.
57
+ - Do not introduce a second daemon/Host protocol.
58
+ - Do not silently kill an actively running Host without an explicit replacement rule.
59
+
60
+ ## Contract
61
+
62
+ ### Normal CLI Execution
63
+
64
+ ```bash
65
+ scorel
66
+ ```
67
+
68
+ Runs interactive Scorel in the current shell directory. That directory is the current Project. The command should create/register the Project through the existing Host/project registry path as needed, not invent a separate cwd-only execution path.
69
+
70
+ Explicit form:
71
+
72
+ ```bash
73
+ scorel chat
74
+ scorel chat --cwd <dir>
75
+ ```
76
+
77
+ `--cwd` remains an advanced override. Product docs should teach `cd <project> && scorel`.
78
+
79
+ ### Local Host
80
+
81
+ ```bash
82
+ scorel host serve
83
+ ```
84
+
85
+ Starts this device's Scorel Host. Default behavior:
86
+
87
+ - local WS Host starts with the existing persistent token/state model
88
+ - `process.cwd()` is registered as the initial Project
89
+ - Host connects outbound to the official Relay
90
+ - Host keeps Relay connection alive with automatic reconnect
91
+ - stdout prints local Host URL, device identity, Relay status, and hosted WebUI URL
92
+
93
+ Local-only:
94
+
95
+ ```bash
96
+ scorel host serve --no-relay
97
+ ```
98
+
99
+ Self-hosted Relay:
100
+
101
+ ```bash
102
+ scorel host serve --relay <relay-url>
103
+ ```
104
+
105
+ Replacement:
106
+
107
+ ```bash
108
+ scorel host serve --replace
109
+ ```
110
+
111
+ If a previous Host state is stale/dead, `host serve` may clean it up automatically. If a Host is live, default behavior must not silently kill it. It should fail with a clear message telling the user to pass `--replace`.
112
+
113
+ ### Pairing
114
+
115
+ ```bash
116
+ scorel pair <code>
117
+ ```
118
+
119
+ Redeems a hosted WebUI pair code through the official Relay by default.
120
+
121
+ Self-hosted override:
122
+
123
+ ```bash
124
+ scorel pair <code> --relay <relay-url>
125
+ ```
126
+
127
+ ### Relay Operator
128
+
129
+ ```bash
130
+ scorel relay serve
131
+ ```
132
+
133
+ Runs a Relay service for self-hosting/development. This command maps to the existing `apps/relay` process and should expose host, port, and data-dir flags.
134
+
135
+ ## Acceptance Criteria
136
+
137
+ - `scorel --help` shows `scorel`, `scorel host serve`, `scorel pair`, and `scorel relay serve` as the primary command surface.
138
+ - `scorel` with no subcommand enters the same interactive project flow currently reached by `scorel chat`.
139
+ - `scorel host serve` starts a local Host, registers the current cwd as an initial Project, and attempts Relay connection by default.
140
+ - `scorel host serve --no-relay` starts without opening a Relay connection.
141
+ - `scorel host serve --relay <url>` connects to the provided Relay.
142
+ - `scorel host serve` auto-recovers stale daemon state but refuses to replace a live Host unless `--replace` is provided.
143
+ - `scorel host serve --replace` stops the live previous Host and starts a fresh Host.
144
+ - Relay reconnect is automatic after transient Relay socket loss.
145
+ - `scorel pair <code>` works against the official Relay without requiring `--relay`.
146
+ - `scorel pair <code> --relay <url>` still works for self-hosted Relay tests.
147
+ - `scorel relay serve` can start the Relay service with a file-backed store.
148
+ - `scorel daemon ...` aliases either continue to work or produce a clear pre-1.0 migration message; they must not be the documented primary path.
149
+ - Root README and `docs/SHIP.md` quickstart no longer teach `scorel daemon serve --cwd --relay` as the user-facing hosted path.
150
+ - Hosted WebUI quickstart references `https://scorel.chanler.dev`.
151
+
152
+ ## Test Requirements
153
+
154
+ - CLI unit tests cover:
155
+ - no-subcommand `scorel` dispatches to chat/interactive flow
156
+ - `host serve` parses default Relay, `--no-relay`, `--relay`, and `--replace`
157
+ - live Host replacement requires `--replace`
158
+ - `pair` uses the default Relay when `--relay` is omitted
159
+ - `relay serve` parses host/port/data-dir and starts through the existing Relay server path
160
+ - Daemon/Host tests cover Relay reconnect behavior without adding test-only product branches.
161
+ - Existing Relay tests continue to use real local WebSocket servers and file stores.
162
+ - Run:
163
+
164
+ ```bash
165
+ pnpm typecheck
166
+ pnpm test
167
+ ```
168
+
169
+ - If hosted deploy readiness is claimed in this spec's implementation, also run the relevant Vercel/build verification command and record the exact command in a verification note.
170
+
171
+ ## Verification
172
+
173
+ Completed on 2026-06-06:
174
+
175
+ ```bash
176
+ pnpm --filter @scorel/app-cli test
177
+ pnpm --filter @scorel/daemon test -- src/relay/host-client.test.ts
178
+ pnpm typecheck
179
+ pnpm test
180
+ git diff --check
181
+ ```
182
+
183
+ ## Affected Paths
184
+
185
+ - `apps/cli/src/index.ts`
186
+ - `apps/cli/src/daemon-cli.ts`
187
+ - `apps/cli/src/relay-cli.ts`
188
+ - `apps/cli/src/up-cli.ts`
189
+ - `apps/cli/src/*.test.ts`
190
+ - `apps/relay/src/index.ts`
191
+ - `packages/daemon/src/relay/*`
192
+ - `packages/daemon/src/*`
193
+ - `docs/SHIP.md`
194
+ - `docs/ROADMAP.md`
195
+ - `README.md`
196
+ - `docs/README.md`
197
+ - `docs/spec/relay.md`
198
+ - `package.json`
199
+ - `pnpm-lock.yaml`
200
+ - `pnpm-workspace.yaml`
201
+
202
+ ## Risks
203
+
204
+ - Renaming `daemon` to `host` can churn tests and docs. Keep aliases or explicit migration messages during pre-1.0.
205
+ - Default Relay connection can make local startup depend on public service availability. `--no-relay` must be obvious and reliable.
206
+ - `--replace` can interrupt running sessions. Do not make live-process replacement silent.
207
+ - Treating no-subcommand `scorel` as chat must not hide parse errors for known commands.
208
+ - Hosted defaults must not become hard-coded in places that prevent self-hosting.
@@ -0,0 +1,166 @@
1
+ # S0062: Npm Package And Release Workflow
2
+
3
+ ## Goal
4
+
5
+ Make the first public npm release path executable:
6
+
7
+ ```text
8
+ pnpm release patch --dry-run
9
+ pnpm release patch
10
+ ```
11
+
12
+ The public package is one user-facing package named `@chanlerdev/scorel`. It installs the `scorel` CLI command and includes the CLI, local Host/daemon runtime, pairing command, and Relay operator command. Internal workspace packages remain unpublished for now.
13
+
14
+ ## Scope
15
+
16
+ - Publish surface:
17
+ - root package name: `@chanlerdev/scorel`
18
+ - bin: `scorel`
19
+ - first version: `0.0.1`
20
+ - Add package build:
21
+ - bundle `apps/cli/src/index.ts` to `dist/index.js`
22
+ - keep the generated bin executable
23
+ - do not require `tsx` at runtime
24
+ - Add local release command:
25
+ - `pnpm release patch`
26
+ - `pnpm release minor`
27
+ - `pnpm release major`
28
+ - `--dry-run` validates without committing, tagging, pushing, or publishing
29
+ - `--no-publish` commits/tags without npm publish
30
+ - Add npm pack smoke:
31
+ - pack the root package
32
+ - install it into a temporary project
33
+ - run `scorel --help`
34
+ - Add manual GitHub Actions release workflow:
35
+ - `workflow_dispatch`
36
+ - default `bump=patch`
37
+ - default `dry_run=true`
38
+ - uses the same `pnpm release` command
39
+ - Update docs/roadmap/changelog for release readiness.
40
+
41
+ ## Non-Goals
42
+
43
+ - Do not publish `@scorel/protocol`, `@scorel/client`, `@scorel/core`, `@scorel/daemon`, `@scorel/app-cli`, or `@scorel/relay`.
44
+ - Do not bundle hosted WebUI into the npm package.
45
+ - Do not change hosted WebUI deployment. It remains a Vercel/monorepo build.
46
+ - Do not implement accounts, OAuth, or hosted execution.
47
+ - Do not automatically publish from CI unless the workflow is manually triggered with `dry_run=false`.
48
+
49
+ ## Contract
50
+
51
+ ### Package Build
52
+
53
+ ```bash
54
+ pnpm build:package
55
+ ```
56
+
57
+ must create:
58
+
59
+ ```text
60
+ dist/index.js
61
+ ```
62
+
63
+ The generated file must:
64
+
65
+ - start with a node shebang
66
+ - be executable
67
+ - run without `tsx`
68
+ - include internal workspace code needed by the CLI/Host/Relay commands
69
+
70
+ ### Release Command
71
+
72
+ ```bash
73
+ pnpm release patch --dry-run
74
+ ```
75
+
76
+ must:
77
+
78
+ - require a clean working tree, except generated release artifacts it creates during the run
79
+ - run repo checks
80
+ - build WebUI
81
+ - build the npm package
82
+ - run npm pack smoke
83
+ - compute the next version
84
+ - report what would happen
85
+ - not mutate package versions, changelog, git commit, git tag, push, or publish
86
+
87
+ ```bash
88
+ pnpm release patch
89
+ ```
90
+
91
+ must:
92
+
93
+ - require clean working tree
94
+ - run the same verification path
95
+ - bump all package/app versions in lockstep
96
+ - update `docs/CHANGELOG.md`
97
+ - build the npm package
98
+ - run npm pack smoke
99
+ - commit `release: vX.Y.Z`
100
+ - tag `vX.Y.Z`
101
+ - publish the root `@chanlerdev/scorel` package to npm
102
+
103
+ The release script may support `--no-publish` for preparing a release commit/tag without publishing.
104
+
105
+ ### GitHub Actions
106
+
107
+ Manual workflow inputs:
108
+
109
+ ```text
110
+ bump: patch | minor | major
111
+ dry_run: true | false
112
+ publish: true | false
113
+ ```
114
+
115
+ The workflow must:
116
+
117
+ - install pnpm from `packageManager`
118
+ - run `pnpm install --frozen-lockfile`
119
+ - run `pnpm release <bump> --dry-run` by default
120
+ - require `NPM_TOKEN` only for a real publish
121
+
122
+ ## Acceptance Criteria
123
+
124
+ - Root `package.json` is a publishable `@chanlerdev/scorel` package with `bin`, `files`, `engines`, and release/build scripts.
125
+ - `pnpm build:package` creates an executable `dist/index.js`.
126
+ - `node dist/index.js --help` works.
127
+ - `pnpm pack:smoke` packs and installs the tarball into a temporary project, then runs `scorel --help`.
128
+ - `pnpm release patch --dry-run` runs the full dry-run path and exits 0.
129
+ - `.github/workflows/release.yml` exists and manually triggers the same release command.
130
+ - `docs/ROADMAP.md` includes S0062 as Done only after verification.
131
+ - `docs/CHANGELOG.md` records release infrastructure under Unreleased until the first release moves it to a version section.
132
+
133
+ ## Test Requirements
134
+
135
+ Run:
136
+
137
+ ```bash
138
+ pnpm build:package
139
+ node dist/index.js --help
140
+ pnpm pack:smoke
141
+ pnpm release patch --dry-run
142
+ pnpm typecheck
143
+ pnpm test
144
+ pnpm --filter @scorel/app-webui build
145
+ git diff --check
146
+ ```
147
+
148
+ ## Affected Paths
149
+
150
+ - `package.json`
151
+ - `scripts/build-package.mjs`
152
+ - `scripts/pack-smoke.mjs`
153
+ - `scripts/release.mjs`
154
+ - `.github/workflows/release.yml`
155
+ - `docs/SHIP.md`
156
+ - `docs/ROADMAP.md`
157
+ - `docs/CHANGELOG.md`
158
+ - `docs/spec/ship/S0062-npm-package-and-release-workflow.md`
159
+ - `docs/plans/2026-06-07-s0062-npm-package-release.md`
160
+
161
+ ## Risks
162
+
163
+ - Bundling can accidentally include development-only code. Keep `files` restricted to `dist`, README, and selected docs.
164
+ - Publishing internal packages too early would create API stability pressure. Keep only root `@chanlerdev/scorel` public in S0062.
165
+ - Real npm publish requires `chanlerdev` authentication locally or `NPM_TOKEN` in GitHub Actions.
166
+ - 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,173 @@
1
+ # 工具系统:内置工具 + MCP
2
+
3
+ > 上游:`architecture.md`
4
+ > 主题:Agent 的能力边界由工具决定。这份文档说明 Scorel 如何定义、组织、接入工具。
5
+
6
+ ---
7
+
8
+ ## 1. 设计目标
9
+
10
+ 工具系统需要同时回答三个问题:
11
+
12
+ 1. **怎么定义**——工具签名、参数、返回值如何描述给 LLM 和 runtime
13
+ 2. **怎么组合**——哪些工具默认开启、哪些按需加载
14
+ 3. **怎么扩展**——外部 MCP 服务器如何无缝接入
15
+
16
+ 三个问题都 **复用 pi-ai + pi-agent-core 已有的抽象**,Scorel 不重新发明;但上层代码只依赖 Scorel 自己 re-export / adapter 后的类型,避免把底层包名泄漏到 app、daemon、extension。
17
+
18
+ **M2 / S0012 不做权限审批、沙箱和快照恢复**:先把 Coding Agent Alpha 跑通,让用户能在本地工作区完成真实搜索、读写、命令验证和 Todo 进度跟踪。当前安全边界来自清晰工具语义、read coverage / stale check、精确编辑失败规则、超时与输出截断,而不是恢复机制。
19
+
20
+ ---
21
+
22
+ ## 2. 工具定义:复用 `AgentTool` 语义
23
+
24
+ Scorel 对外暴露自己的 `AgentTool` / `Type` adapter,语义对齐 pi-ai 的 `Tool` + pi-agent-core 的 `AgentTool`:
25
+
26
+ ```typescript
27
+ import { Type, type AgentTool } from '@scorel/core/tools';
28
+
29
+ const readTool: AgentTool = {
30
+ name: 'Read',
31
+ label: 'Read File',
32
+ description: '读取文件内容',
33
+ parameters: Type.Object({
34
+ file_path: Type.String(),
35
+ offset: Type.Optional(Type.Number()),
36
+ limit: Type.Optional(Type.Number()),
37
+ full: Type.Optional(Type.Boolean()),
38
+ }),
39
+ execute: async (toolCallId, args, signal, onUpdate) => {
40
+ const content = await fs.readFile(args.path, 'utf-8');
41
+ return {
42
+ content: [{ type: 'text', text: content }],
43
+ details: { path: args.path, size: content.length },
44
+ };
45
+ },
46
+ };
47
+ ```
48
+
49
+ 参数用 TypeBox 风格表达,底层 adapter 负责转成 provider 需要的 JSON Schema。
50
+
51
+ ---
52
+
53
+ ## 3. 内置工具集
54
+
55
+ M2 落地七个用户可见工具,语义参考 Claude Code 的基础 coding 工具,但按 Scorel 的 daemon/client/session 边界实现:
56
+
57
+ | 工具 | 说明 | 执行模式 | M2 关键约束 |
58
+ |------|------|---------|------------|
59
+ | `Read` | 读取文本文件,支持行范围 | parallel | 只读文件不读目录;结果带稳定行号;默认最多返回 2000 个完整行,并同时受当前模型 context window 1% 的估算 token 预算限制;`full: true` 使用 10% 预算;无 context window 时 fallback 为 200000;token 估算按带行号的返回文本计算,暂按约 3 字符/token;预算截断只按整行回退;结果带 startLine/endLine/totalLines/truncated/nextOffset/canWrite/estimatedTokens/tokenBudget;同一文件版本下读段可累积,覆盖完整文件后解锁写入 |
60
+ | `Write` | 创建新文件或完整重写文件 | sequential | 写既有文件前必须已读覆盖完整当前文件;读后文件被外部修改必须失败;模型侧结果不返回旧/新完整内容;优先用 `Edit` 修改既有文件 |
61
+ | `Edit` | 精确字符串替换 | sequential | 编辑前必须已读覆盖完整当前文件;读后文件被外部修改必须失败;`old_string` 不存在或不唯一时失败,除非显式 replace_all;模型侧结果只返回成功与替换计数 |
62
+ | `Bash` | 命令执行 | sequential | 指定 cwd;超时保护;输出截断;失败作为 tool result 返回 |
63
+ | `Glob` | 按文件名 / glob pattern 找文件 | parallel | 基于 ripgrep file discovery;返回结构化路径列表;排序稳定;支持分页 |
64
+ | `Grep` | 基于 ripgrep 的内容搜索 | parallel | 支持 glob/type/-A/-B/-C/context/-n/-i/multiline 过滤;支持 content/files/count 输出;限制结果数量,并用 max-columns 控制超长行 |
65
+ | `TodoWrite` | 完整替换 Todo List | sequential | 参数是完整 todos;返回 oldTodos/currentTodos;全 completed 时系统清空 currentTodos |
66
+
67
+ **执行模式**:只读工具 parallel、写类或有副作用的工具 sequential。底层 pi-agent-core 已有对应抽象时优先复用,Scorel 只通过 adapter 透出,不自建复杂调度。
68
+
69
+ **工具使用原则**:
70
+ - 读文件用 `Read`,不要让 `Bash` 代替 `cat` / `head` / `tail`。长文件默认截断;继续阅读用 `offset`,同一版本下读段覆盖完整文件后即可写。`full: true` 请求一次读完整文件,并使用 10% context window 预算。`Read` 不会为了满足预算截断单行;如果单行过长会失败并提示换搜索/专用工具。
71
+ - 改既有文件优先用 `Edit`,不要让 `Bash` 代替 `sed -i` / heredoc / redirect。
72
+ - `Write` 只用于创建新文件或完整重写。
73
+ - 找文件用 `Glob`,搜内容用 `Grep`;不要把常规搜索塞进 `Bash rg/find`。
74
+ - `Bash` 负责构建、测试、Git 状态、项目脚本等命令型工作。
75
+ - 多步骤 coding task 用 `TodoWrite` 记录当前计划和状态;CLI 必须能展示这些变化。
76
+
77
+ **M2 之后再扩展**:`LS`、Web、LSP、notebook、subagent、MCP 动态工具等能力在基础 coding loop 稳定后再补齐。
78
+
79
+ ---
80
+
81
+ ## 4. 工具集预设
82
+
83
+ 通过配置选择一组工具启用:
84
+
85
+ | 预设 | 包含 |
86
+ |------|------|
87
+ | `coding` | `Read` / `Write` / `Edit` / `Bash` / `Glob` / `Grep` / `TodoWrite` |
88
+ | `readonly` | `Read` / `Glob` / `Grep` |
89
+ | `all` | 内置 + 已连接的 MCP(M2 后) |
90
+ | `none` | 不启用任何工具 |
91
+
92
+ 预设在 `config.toml` 的 `[tools]` 段声明(见 `spec/extensions.md §5`)。Extension 可以额外追加工具。
93
+
94
+ ---
95
+
96
+ ## 5. MCP 集成(M2 后)
97
+
98
+ pi-ai 本身不内置 MCP,Scorel 自己接——TypeScript 生态的 MCP SDK 已经成熟,接入成本不高。
99
+
100
+ MCP 不属于 M2。M2 先把内置 coding 工具和 session/daemon/client/CLI 主链路跑通;MCP 在后续 ecosystem 阶段接入。
101
+
102
+ ### 5.1 MCP 工具转换
103
+
104
+ 每个 MCP 服务器暴露的 tool 被包装成一条 `AgentTool`:
105
+
106
+ ```typescript
107
+ function mcpToAgentTool(client: McpClient, tool: McpTool): AgentTool {
108
+ return {
109
+ name: `${client.name}_${tool.name}`,
110
+ label: tool.name,
111
+ description: tool.description,
112
+ parameters: convertJsonSchemaToTypeBox(tool.inputSchema),
113
+ execute: async (_, args) => {
114
+ const result = await client.callTool(tool.name, args);
115
+ return {
116
+ content: result.content,
117
+ details: { server: client.name, tool: tool.name },
118
+ };
119
+ },
120
+ };
121
+ }
122
+ ```
123
+
124
+ MCP 生态里很多 server 用 Zod / 原生 JSON Schema,Scorel 工具签名统一在 TypeBox 风格 schema。JSON Schema 到 TypeBox 的转换由 adapter 层负责。
125
+
126
+ ### 5.2 后续:启动时加载
127
+
128
+ ```typescript
129
+ interface McpServerConfig {
130
+ name: string;
131
+ transport: 'sse' | 'stdio';
132
+ url?: string; // sse
133
+ command?: string; // stdio
134
+ }
135
+ ```
136
+
137
+ 所有配置的 MCP 服务器在 session 启动时连接并加载工具描述,全部作为 `all` 预设的一部分。是否进入 `coding` 预设,需要等内置 M2 工具稳定后再决定。
138
+
139
+ ### 5.3 更后续:按需分级加载
140
+
141
+ 初期不做的:按 keyword 触发的 **Tier 2** 动态加载(`transformContext` 拦截用户消息,命中关键词才 attach 对应工具)。
142
+
143
+ 延后的理由:
144
+ - 初期 MCP 服务器数量可控,工具描述全加载也不会撑爆 system prompt
145
+ - 分级策略依赖真实使用数据调参,在没有数据前先简单做
146
+
147
+ ---
148
+
149
+ ## 6. 错误是数据
150
+
151
+ 工具执行失败时 **不抛异常**,而是返回包含错误信息的 `content`。pi-agent-core 会把错误编码成 `ToolResultMessage.isError` / `AssistantMessage.stopReason`,LLM 下一轮可以读取并决定是否重试。
152
+
153
+ 这条原则和 `architecture.md §6` 的"错误是数据,不是异常"对齐——异常通道只保留给真正的编程错误(例如参数类型不对),业务失败都走数据通道。
154
+
155
+ ---
156
+
157
+ ## 7. 初期范围与延后项
158
+
159
+ **初期落地**
160
+ - M2/S0012 内置工具集:`Read` / `Write` / `Edit` / `Bash` / `Glob` / `Grep` / `TodoWrite`
161
+ - 工具集预设:`coding` / `readonly` / `all` / `none`
162
+
163
+ **延后**
164
+ - `LS` 等便利只读工具
165
+ - WebFetch / WebSearch、LSP、notebook editing、worktree mode
166
+ - **权限审批(PermissionPolicy)**:默认全允许,后期补黑名单 / 询问 / 拒绝规则
167
+ - MCP 启动时加载
168
+ - MCP Tier 2 按需加载
169
+ - Subagent 工具(工具内 `new Agent()` 递归调用,隔离上下文)
170
+
171
+ ---
172
+
173
+ *工具系统的复杂度主要在"组合与扩展",定义层复用 pi 栈语义,但通过 Scorel adapter 固化边界。*
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@chanlerdev/scorel",
3
+ "version": "0.0.1",
4
+ "description": "Replayable, recoverable, remotely controllable AI Agent workspace.",
5
+ "type": "module",
6
+ "packageManager": "pnpm@11.1.2",
7
+ "bin": {
8
+ "scorel": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "docs/SHIP.md",
14
+ "docs/ROADMAP.md",
15
+ "docs/CHANGELOG.md",
16
+ "docs/spec"
17
+ ],
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+ssh://git@github.com/ChanlerDev/Scorel.git"
21
+ },
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "dependencies": {
26
+ "@mariozechner/pi-ai": "0.73.1",
27
+ "ws": "^8.21.0"
28
+ },
29
+ "scripts": {
30
+ "build:package": "node scripts/build-package.mjs",
31
+ "check": "pnpm typecheck && pnpm test",
32
+ "pack:smoke": "node scripts/pack-smoke.mjs",
33
+ "release": "node scripts/release.mjs",
34
+ "typecheck": "pnpm -r typecheck",
35
+ "test": "pnpm -r test",
36
+ "verify:m8-relay": "node --import tsx scripts/verify-m8-relay-e2e.ts",
37
+ "scorel": "node --import tsx apps/cli/src/index.ts",
38
+ "dev": "node --import tsx apps/cli/src/index.ts up"
39
+ },
40
+ "devDependencies": {
41
+ "@types/node": "^24.10.1",
42
+ "esbuild": "0.28.0",
43
+ "next": "^14.2.35",
44
+ "tsx": "^4.21.0",
45
+ "typescript": "^5.9.3",
46
+ "vitest": "4.0.13"
47
+ },
48
+ "engines": {
49
+ "node": ">=22.19.0"
50
+ }
51
+ }