@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.
- package/README.md +110 -0
- package/dist/index.js +6675 -0
- package/dist/index.js.map +7 -0
- package/docs/CHANGELOG.md +12 -0
- package/docs/README.md +116 -0
- package/docs/ROADMAP.md +669 -0
- package/docs/SHIP.md +242 -0
- package/docs/spec/channels.md +156 -0
- package/docs/spec/client.md +326 -0
- package/docs/spec/daemon.md +408 -0
- package/docs/spec/events.md +423 -0
- package/docs/spec/extensions.md +255 -0
- package/docs/spec/relay.md +391 -0
- package/docs/spec/runtime.md +251 -0
- package/docs/spec/session.md +380 -0
- package/docs/spec/ship/S0001-docs-baseline.md +41 -0
- package/docs/spec/ship/S0002-package-skeleton.md +56 -0
- package/docs/spec/ship/S0003-protocol-contracts.md +49 -0
- package/docs/spec/ship/S0004-session-core.md +50 -0
- package/docs/spec/ship/S0005-runtime-loop.md +48 -0
- package/docs/spec/ship/S0006-embedded-daemon-client.md +51 -0
- package/docs/spec/ship/S0007-cli-alpha.md +49 -0
- package/docs/spec/ship/S0008-coding-tools.md +107 -0
- package/docs/spec/ship/S0009-code-discovery-tools.md +82 -0
- package/docs/spec/ship/S0010-todo-tool-and-cli.md +81 -0
- package/docs/spec/ship/S0011-coding-agent-alpha-smoke.md +110 -0
- package/docs/spec/ship/S0012-coding-tools-maturity.md +143 -0
- package/docs/spec/ship/S0013-local-daemon-protocol.md +57 -0
- package/docs/spec/ship/S0014-local-daemon-lifecycle.md +64 -0
- package/docs/spec/ship/S0015-local-attach-and-broadcast.md +58 -0
- package/docs/spec/ship/S0016-local-daemon-resync-smoke.md +60 -0
- package/docs/spec/ship/S0017-grep-files-output-mode.md +49 -0
- package/docs/spec/ship/S0018-daemon-entrypoint-smoke.md +48 -0
- package/docs/spec/ship/S0019-remote-transport-contract.md +59 -0
- package/docs/spec/ship/S0020-remote-websocket-server.md +56 -0
- package/docs/spec/ship/S0021-remote-websocket-client-transport.md +55 -0
- package/docs/spec/ship/S0022-remote-daemon-cli-lifecycle.md +60 -0
- package/docs/spec/ship/S0023-remote-control-e2e-validation.md +66 -0
- package/docs/spec/ship/S0024-remote-attach-interactive-stream.md +49 -0
- package/docs/spec/ship/S0025-remote-attach-session-event-view.md +57 -0
- package/docs/spec/ship/S0026-attach-project-cache-and-dual-seq-reconnect.md +87 -0
- package/docs/spec/ship/S0027-session-diagnostics-log.md +77 -0
- package/docs/spec/ship/S0028-client-attach-diagnostics-log.md +70 -0
- package/docs/spec/ship/S0029-project-index-for-session-lookup.md +119 -0
- package/docs/spec/ship/S0030-webui-product-intent.md +73 -0
- package/docs/spec/ship/S0031-daemon-projectslug-rule.md +72 -0
- package/docs/spec/ship/S0032-daemon-protocol-completion.md +123 -0
- package/docs/spec/ship/S0033-webui-skeleton-routing.md +92 -0
- package/docs/spec/ship/S0034-webui-device-settings.md +121 -0
- package/docs/spec/ship/S0035-webui-device-handshake.md +83 -0
- package/docs/spec/ship/S0036-webui-project-session-sync.md +70 -0
- package/docs/spec/ship/S0037-webui-chatbox-v1.md +97 -0
- package/docs/spec/ship/S0038-webui-cancel-multiclient.md +65 -0
- package/docs/spec/ship/S0039-webui-e2e-newchat.md +74 -0
- package/docs/spec/ship/S0040-webui-codex-visual-tokens.md +227 -0
- package/docs/spec/ship/S0041-webui-markdown-and-tool-block.md +248 -0
- package/docs/spec/ship/S0042-webui-streaming-ux-autoscroll.md +130 -0
- package/docs/spec/ship/S0043-startup-ergonomics.md +278 -0
- package/docs/spec/ship/S0044-webui-chatbox-rebuild.md +556 -0
- package/docs/spec/ship/S0045-webui-card-sidebar-and-session-fixes.md +469 -0
- package/docs/spec/ship/S0046-webui-empty-composer-and-lazy-session.md +428 -0
- package/docs/spec/ship/S0047-webui-project-hover-newchat-and-dynamic-greeting.md +176 -0
- package/docs/spec/ship/S0048-device-level-host-project-registry.md +253 -0
- package/docs/spec/ship/S0049-webui-add-project-directory-browser.md +217 -0
- package/docs/spec/ship/S0050-instruction-snapshot-and-agents-assembly.md +338 -0
- package/docs/spec/ship/S0051-harness-item-and-system-reminder.md +190 -0
- package/docs/spec/ship/S0052-follow-up-queue-and-dual-loop.md +195 -0
- package/docs/spec/ship/S0053-skill-index-and-skill-tool.md +252 -0
- package/docs/spec/ship/S0054-webui-running-message-behavior.md +72 -0
- package/docs/spec/ship/S0055-webui-composer-acceptance-and-queue-strip.md +68 -0
- package/docs/spec/ship/S0056-relay-and-hosted-webui-contract.md +106 -0
- package/docs/spec/ship/S0057-relay-service-protocol-skeleton.md +161 -0
- package/docs/spec/ship/S0058-host-outbound-relay-and-pair-command.md +138 -0
- package/docs/spec/ship/S0059-relay-transport-and-hosted-webui-connector.md +140 -0
- package/docs/spec/ship/S0060-relay-hosted-webui-e2e-validation.md +132 -0
- package/docs/spec/ship/S0060-relay-hosted-webui-e2e-validation.verification.md +90 -0
- package/docs/spec/ship/S0061-hosted-defaults-and-cli-command-surface.md +208 -0
- package/docs/spec/ship/S0062-npm-package-and-release-workflow.md +166 -0
- package/docs/spec/tools.md +173 -0
- package/package.json +51 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# S0014: Local Daemon Lifecycle
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Implement a local standalone daemon process that can be started, discovered, and stopped independently from `scorel chat`.
|
|
6
|
+
|
|
7
|
+
This spec establishes the process and lifecycle foundation for multiple local clients to share one daemon.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Implement a Node local server transport for the daemon side using Unix socket on macOS/Linux and a clear named-pipe-compatible abstraction boundary.
|
|
12
|
+
- Implement the matching Node socket transport entrypoint for `@scorel/client/node`.
|
|
13
|
+
- Add `scorel daemon start`, `scorel daemon status`, and `scorel daemon stop` command behavior.
|
|
14
|
+
- Persist local daemon connection state under Scorel-owned product state, including socket path, pid, started time, local token, and connection metadata.
|
|
15
|
+
- Keep `~/.scorel` and `~/.scorel/sessions` as fixed product paths, not user-exposed config flags.
|
|
16
|
+
- Ensure clean shutdown closes the socket and removes stale state when possible.
|
|
17
|
+
- Return clear errors for stale socket/state files and unavailable daemon processes.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- `scorel attach` interactive UX.
|
|
22
|
+
- Multi-client broadcast smoke.
|
|
23
|
+
- Remote WebSocket daemon.
|
|
24
|
+
- Token refresh UX, remote token distribution, or permission tiers.
|
|
25
|
+
- Crash recovery supervisor, auto-restart, launchd/systemd integration, Docker service.
|
|
26
|
+
- Channel manager, GUI, WebUI, or IM integration.
|
|
27
|
+
|
|
28
|
+
## Acceptance Criteria
|
|
29
|
+
|
|
30
|
+
- `scorel daemon start` creates local daemon connection state and reserves the socket path/token needed by the standalone daemon lifecycle.
|
|
31
|
+
- The reusable local socket server primitive can accept authenticated local connections; `scorel attach` consumes this lifecycle in S0015.
|
|
32
|
+
- `scorel daemon status` reports whether a local daemon is reachable and includes pid/socket/session count when available.
|
|
33
|
+
- `scorel daemon stop` gracefully shuts down the local daemon and cleans up local connection state.
|
|
34
|
+
- A second start command detects an already-running daemon instead of starting a duplicate.
|
|
35
|
+
- Stale state is detected and reported with an actionable error.
|
|
36
|
+
- Local socket connections validate the stored local token or an equivalent local-only connection secret.
|
|
37
|
+
- Socket transport tests cover successful connect, ping/pong, clean close, and connection failure.
|
|
38
|
+
- Package boundary tests still enforce `@scorel/daemon` does not depend on `@scorel/client` or `apps/*`.
|
|
39
|
+
|
|
40
|
+
## Tests
|
|
41
|
+
|
|
42
|
+
- `pnpm --filter @scorel/client test`
|
|
43
|
+
- `pnpm --filter @scorel/daemon test`
|
|
44
|
+
- `pnpm --filter @scorel/app-daemon test`
|
|
45
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
46
|
+
- `pnpm typecheck && pnpm test`
|
|
47
|
+
|
|
48
|
+
## Affected Paths
|
|
49
|
+
|
|
50
|
+
- `packages/client/src/`
|
|
51
|
+
- `packages/daemon/src/`
|
|
52
|
+
- `apps/daemon/src/index.ts`
|
|
53
|
+
- `apps/daemon/src/index.test.ts`
|
|
54
|
+
- `apps/cli/src/index.ts`
|
|
55
|
+
- `apps/cli/src/index.test.ts`
|
|
56
|
+
- `docs/spec/daemon.md`
|
|
57
|
+
- `docs/spec/client.md`
|
|
58
|
+
- `docs/ROADMAP.md`
|
|
59
|
+
|
|
60
|
+
## Risks And Boundaries
|
|
61
|
+
|
|
62
|
+
- A daemon process manager can grow into a supervisor. Keep this spec to explicit start/status/stop.
|
|
63
|
+
- Cross-platform socket details can pollute protocol code. Keep transport implementation behind Node-only entrypoints.
|
|
64
|
+
- Do not make product paths configurable just to simplify tests; tests can inject temporary paths through internal APIs.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# S0015: Local Attach And Broadcast
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Let local CLI clients attach to the standalone daemon and observe the same session event stream.
|
|
6
|
+
|
|
7
|
+
This spec proves that M3 is more than a background process: multiple local clients share one daemon-owned session.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Add `scorel attach` for connecting to an existing local daemon.
|
|
12
|
+
- Let `scorel chat` choose the local standalone daemon path when requested, while preserving the embedded default until the product default is intentionally changed.
|
|
13
|
+
- Support attaching to a specific session with `--session`.
|
|
14
|
+
- Broadcast persistent and transient events from one local client to all clients attached to the same session.
|
|
15
|
+
- Keep session writes daemon-owned; CLI must not bypass the daemon to read/write JSONL directly.
|
|
16
|
+
- Show CLI-visible tool calls, tool results, text deltas, and daemon errors through the existing event stream.
|
|
17
|
+
- Add integration tests with two local clients attached to one daemon/session.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- Remote attach.
|
|
22
|
+
- Browser/WebUI attach.
|
|
23
|
+
- Rewind/branch UX polish.
|
|
24
|
+
- Permission levels between local clients.
|
|
25
|
+
- Offline command queue.
|
|
26
|
+
- Automatically migrating all `scorel chat` usage to standalone daemon by default.
|
|
27
|
+
|
|
28
|
+
## Acceptance Criteria
|
|
29
|
+
|
|
30
|
+
- `scorel attach --session <id>` connects to an already-running local daemon and subscribes to that session.
|
|
31
|
+
- When Client A sends a message, Client B receives the same ordered event stream for that session.
|
|
32
|
+
- Tool call and tool result events remain visible in attached clients.
|
|
33
|
+
- A client connecting to a missing daemon receives a clear error.
|
|
34
|
+
- A client connecting to a missing session can either create it through the daemon or report the supported command path; the behavior is documented in the spec/client or CLI help text.
|
|
35
|
+
- Tests prove CLI code uses `DaemonClient` + transport and does not directly instantiate runtime/session for attach.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
- `pnpm --filter @scorel/client test`
|
|
40
|
+
- `pnpm --filter @scorel/daemon test`
|
|
41
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
42
|
+
- `pnpm typecheck && pnpm test`
|
|
43
|
+
|
|
44
|
+
## Affected Paths
|
|
45
|
+
|
|
46
|
+
- `apps/cli/src/index.ts`
|
|
47
|
+
- `apps/cli/src/index.test.ts`
|
|
48
|
+
- `packages/client/src/`
|
|
49
|
+
- `packages/daemon/src/`
|
|
50
|
+
- `docs/spec/client.md`
|
|
51
|
+
- `docs/spec/daemon.md`
|
|
52
|
+
- `docs/ROADMAP.md`
|
|
53
|
+
|
|
54
|
+
## Risks And Boundaries
|
|
55
|
+
|
|
56
|
+
- Attach UX can become a second chat implementation. Keep it as a thin client path over `DaemonClient`.
|
|
57
|
+
- Multi-client output can become noisy. Preserve machine-verifiable event behavior first; polish display later.
|
|
58
|
+
- Do not add remote URI parsing here beyond local daemon discovery.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# S0016: Local Daemon Resync Smoke
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Validate the full M3 local daemon product path: local daemon, multiple clients, disconnect/reconnect, missed event 补发, and a real `scorel chat` coding flow.
|
|
6
|
+
|
|
7
|
+
This spec closes M3 only after local daemon behavior is proven end to end.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Implement and test `lastSeq`-based resync over local socket transport.
|
|
12
|
+
- Cover the three M3 sync cases needed locally: buffer hit, JSONL persistent fallback, and clean full replay when a client has no usable seq.
|
|
13
|
+
- Verify that transient loss does not corrupt final persistent session state.
|
|
14
|
+
- Keep the existing CLI coding smoke green with a real temporary workspace and real JSONL session files.
|
|
15
|
+
- Verify the local daemon path covers socket attach, multi-client broadcast, and resync fallback. A real external provider smoke can be run as an additional manual gate when credentials are available.
|
|
16
|
+
- Update M3 Roadmap status only after the smoke and full check pass.
|
|
17
|
+
|
|
18
|
+
## Not In Scope
|
|
19
|
+
|
|
20
|
+
- Remote WebSocket reconnect.
|
|
21
|
+
- Runtime in-progress partial reconstruction beyond what is already available through local event buffering.
|
|
22
|
+
- Long-running background Bash monitor.
|
|
23
|
+
- Daemon crash recovery after hard kill.
|
|
24
|
+
- GUI/WebUI validation.
|
|
25
|
+
|
|
26
|
+
## Acceptance Criteria
|
|
27
|
+
|
|
28
|
+
- A disconnected local client can reconnect with `lastSeq` and receive missed events in order.
|
|
29
|
+
- If the in-memory buffer cannot satisfy `lastSeq`, daemon falls back to JSONL persistent events and returns a correct final session state.
|
|
30
|
+
- Reconnect without `lastSeq` can rebuild state through full session replay.
|
|
31
|
+
- Tests prove seq remains per-session and does not leak across sessions.
|
|
32
|
+
- Local daemon tests use the socket path, not only embedded in-memory transport.
|
|
33
|
+
- Existing CLI coding smoke still covers search/read/edit/bash/TodoWrite and persistence with a temporary OpenAI-compatible test server.
|
|
34
|
+
- `pnpm typecheck && pnpm test` passes.
|
|
35
|
+
- `docs/ROADMAP.md` marks all M3 steps and M3 status as `Done`.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
- `pnpm --filter @scorel/client test`
|
|
40
|
+
- `pnpm --filter @scorel/daemon test`
|
|
41
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
42
|
+
- `pnpm --filter @scorel/app-daemon test`
|
|
43
|
+
- `pnpm typecheck && pnpm test`
|
|
44
|
+
- Optional manual smoke: local standalone daemon + real provider + real temporary coding workspace.
|
|
45
|
+
|
|
46
|
+
## Affected Paths
|
|
47
|
+
|
|
48
|
+
- `packages/client/src/`
|
|
49
|
+
- `packages/daemon/src/`
|
|
50
|
+
- `apps/cli/src/index.ts`
|
|
51
|
+
- `apps/daemon/src/index.ts`
|
|
52
|
+
- `docs/ROADMAP.md`
|
|
53
|
+
- `docs/spec/client.md`
|
|
54
|
+
- `docs/spec/daemon.md`
|
|
55
|
+
|
|
56
|
+
## Risks And Boundaries
|
|
57
|
+
|
|
58
|
+
- A local daemon smoke that only uses embedded daemon does not prove M3. Local daemon behavior must go through socket transport.
|
|
59
|
+
- A resync test that only checks request/response shape does not prove user value. It must assert ordered event recovery and final session state.
|
|
60
|
+
- Do not use fake providers as proof for provider/runtime quality; M3 completion is about local daemon transport, broadcast, and resync behavior.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# S0017: Grep Files Output Mode
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Simplify the `Grep` tool `output_mode` contract to the obvious `files` mode for matching file paths.
|
|
6
|
+
|
|
7
|
+
This is a product-facing tool schema fix: agents should be able to ask for matching file paths with the obvious word `files`.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Change `Grep` schema to accept `files`, `content`, and `count`.
|
|
12
|
+
- Change the default `Grep` mode to `files`.
|
|
13
|
+
- Update `Grep` runtime details to report `mode: "files"`.
|
|
14
|
+
- Update tool documentation that names the old mode.
|
|
15
|
+
- Keep the ripgrep-backed behavior and pagination unchanged.
|
|
16
|
+
|
|
17
|
+
## Not In Scope
|
|
18
|
+
|
|
19
|
+
- Compatibility aliases for old or alternative names.
|
|
20
|
+
- New search modes.
|
|
21
|
+
- Broader provider schema description work.
|
|
22
|
+
- Claude Code parity for every `Grep` parameter.
|
|
23
|
+
|
|
24
|
+
## Acceptance Criteria
|
|
25
|
+
|
|
26
|
+
- `Grep` with `output_mode: "files"` returns matching file paths.
|
|
27
|
+
- `Grep` defaults to file-path output when `output_mode` is omitted.
|
|
28
|
+
- Unknown `output_mode` values are rejected with a concise validation error.
|
|
29
|
+
- The provider schema exposes `files`.
|
|
30
|
+
- `pnpm --filter @scorel/core test -- tools` passes.
|
|
31
|
+
- `pnpm typecheck && pnpm test` passes.
|
|
32
|
+
|
|
33
|
+
## Tests
|
|
34
|
+
|
|
35
|
+
- `pnpm --filter @scorel/core test -- tools`
|
|
36
|
+
- `pnpm typecheck && pnpm test`
|
|
37
|
+
|
|
38
|
+
## Affected Paths
|
|
39
|
+
|
|
40
|
+
- `packages/core/src/tools/coding-tools.ts`
|
|
41
|
+
- `packages/core/src/tools/coding-tools.test.ts`
|
|
42
|
+
- `packages/core/src/provider/pi-ai.ts`
|
|
43
|
+
- `docs/spec/tools.md`
|
|
44
|
+
- `docs/spec/ship/S0012-coding-tools-maturity.md`
|
|
45
|
+
|
|
46
|
+
## Risks And Boundaries
|
|
47
|
+
|
|
48
|
+
- This intentionally keeps the public tool contract small before Scorel has a stable public tool API.
|
|
49
|
+
- Existing session replays containing old tool calls may show the old error if re-executed; historical event display remains unaffected.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# S0018: Daemon Entrypoint Smoke
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Make the daemon app executable through the same direct `tsx src/index.ts ...` path used for local development.
|
|
6
|
+
|
|
7
|
+
This fixes the M3 manual lifecycle experience: `start` must actually run the daemon command, print status, and create local daemon state.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Add the missing direct entrypoint guard to `@scorel/app-daemon`.
|
|
12
|
+
- Cover the direct entrypoint path with a subprocess smoke test.
|
|
13
|
+
- Keep daemon lifecycle behavior unchanged.
|
|
14
|
+
- Move pnpm build settings out of `package.json` so modern pnpm does not print unrelated config warnings.
|
|
15
|
+
|
|
16
|
+
## Not In Scope
|
|
17
|
+
|
|
18
|
+
- Turning `scorel-daemon start` into a long-running runtime socket server.
|
|
19
|
+
- Remote WebSocket transport.
|
|
20
|
+
- Shell package installation or global binary linking.
|
|
21
|
+
|
|
22
|
+
## Acceptance Criteria
|
|
23
|
+
|
|
24
|
+
- `pnpm --filter @scorel/app-daemon exec tsx src/index.ts start` prints `scorel daemon started`.
|
|
25
|
+
- `pnpm --filter @scorel/app-cli exec tsx src/index.ts daemon status` sees the state written by `start`.
|
|
26
|
+
- `pnpm --filter @scorel/app-daemon exec tsx src/index.ts stop` clears the state.
|
|
27
|
+
- Direct entrypoint behavior is covered by tests.
|
|
28
|
+
- `pnpm typecheck && pnpm test` passes.
|
|
29
|
+
|
|
30
|
+
## Tests
|
|
31
|
+
|
|
32
|
+
- `pnpm --filter @scorel/app-daemon test`
|
|
33
|
+
- Manual lifecycle smoke:
|
|
34
|
+
- `pnpm --filter @scorel/app-daemon exec tsx src/index.ts start`
|
|
35
|
+
- `pnpm --filter @scorel/app-cli exec tsx src/index.ts daemon status`
|
|
36
|
+
- `pnpm --filter @scorel/app-daemon exec tsx src/index.ts stop`
|
|
37
|
+
- `pnpm typecheck && pnpm test`
|
|
38
|
+
|
|
39
|
+
## Affected Paths
|
|
40
|
+
|
|
41
|
+
- `apps/daemon/src/index.ts`
|
|
42
|
+
- `apps/daemon/src/index.test.ts`
|
|
43
|
+
- `package.json`
|
|
44
|
+
- `pnpm-workspace.yaml`
|
|
45
|
+
|
|
46
|
+
## Risks And Boundaries
|
|
47
|
+
|
|
48
|
+
- This only fixes command execution for the current M3 lifecycle state. It does not make the daemon process stay alive as a runtime server.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# S0019: Remote Transport Contract
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Lock the M4 remote control contract before implementing a WebSocket server.
|
|
6
|
+
|
|
7
|
+
This spec defines how a local client connects to a remote daemon, how token auth is represented, and how remote reconnect/resync must preserve the same session semantics proven in M3.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Define the remote transport shape for `DaemonTransport`, including WebSocket URL fields, token auth fields, connection metadata, and error categories.
|
|
12
|
+
- Align `@scorel/protocol` wire types with remote connection needs without breaking embedded or local socket transports.
|
|
13
|
+
- Decide the product-facing CLI shape for remote endpoints, such as `scorel attach --remote <url> --token <token> --session <id>` or an equivalent explicit form.
|
|
14
|
+
- Document which remote connection state may be stored locally and which secrets must not be written without an explicit product decision.
|
|
15
|
+
- Specify reconnect behavior: client keeps `lastSeq`, reconnects to the same session, calls resync, and receives ordered missed events.
|
|
16
|
+
- Add protocol/client/daemon documentation updates where public names or semantics change.
|
|
17
|
+
- Define validation expectations around real product paths: M4 completion cannot depend on mock/fake providers, fake transports, or test-only protocol branches.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- Implementing the actual WebSocket server.
|
|
22
|
+
- Implementing the actual WebSocket client transport.
|
|
23
|
+
- TLS certificate automation, OAuth, account login, token rotation, or permission tiers.
|
|
24
|
+
- Public relay service, tunnel service, NAT traversal, or cloud-hosted control plane.
|
|
25
|
+
- WebUI / GUI.
|
|
26
|
+
- Changing embedded or local socket behavior beyond shared protocol types.
|
|
27
|
+
|
|
28
|
+
## Acceptance Criteria
|
|
29
|
+
|
|
30
|
+
- `docs/spec/daemon.md` describes remote WebSocket transport, token auth, reconnect, and resync boundaries.
|
|
31
|
+
- `docs/spec/client.md` describes WebSocket transport selection, connection state, and remote error handling expectations.
|
|
32
|
+
- `@scorel/protocol` exposes any new remote-safe wire types needed by later S specs.
|
|
33
|
+
- Remote auth failures, protocol version mismatch, connection loss, and resync failure have concise error categories.
|
|
34
|
+
- The CLI UX for remote attach/serve is documented enough for S0022 to implement without redesigning command names.
|
|
35
|
+
- Existing embedded and local socket tests still pass.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
- `pnpm --filter @scorel/protocol test`
|
|
40
|
+
- `pnpm --filter @scorel/client test`
|
|
41
|
+
- `pnpm --filter @scorel/daemon test`
|
|
42
|
+
- `pnpm typecheck && pnpm test`
|
|
43
|
+
|
|
44
|
+
## Affected Paths
|
|
45
|
+
|
|
46
|
+
- `packages/protocol/src/`
|
|
47
|
+
- `packages/client/src/`
|
|
48
|
+
- `packages/daemon/src/`
|
|
49
|
+
- `docs/spec/daemon.md`
|
|
50
|
+
- `docs/spec/client.md`
|
|
51
|
+
- `docs/ROADMAP.md`
|
|
52
|
+
|
|
53
|
+
## Risks And Boundaries
|
|
54
|
+
|
|
55
|
+
- If M4 starts by writing WebSocket code without a contract, remote UX and auth semantics will drift across packages.
|
|
56
|
+
- If token auth is overbuilt now, M4 will become an account system instead of a remote control milestone. Use bearer-token style auth only.
|
|
57
|
+
- Do not expose secrets in logs, session JSONL, or ordinary status output.
|
|
58
|
+
- Keep remote transport behavior compatible with the existing `DaemonClient` abstraction; entry apps should not branch into a separate remote client implementation.
|
|
59
|
+
- Avoid special validation-only behavior. Tests may exercise the same code path with temporary real resources, but should not add alternate product behavior just to pass tests.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# S0020: Remote WebSocket Server
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Implement the daemon-side WebSocket server primitive needed for remote control.
|
|
6
|
+
|
|
7
|
+
This spec proves that a daemon can accept authenticated remote clients over WebSocket and route the existing protocol messages without changing session ownership.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Add a daemon-owned WebSocket server primitive for remote connections.
|
|
12
|
+
- Reuse the same protocol message model used by embedded and local socket transports.
|
|
13
|
+
- Validate token auth during connection setup or the first protocol handshake, according to S0019.
|
|
14
|
+
- Route connect, ping, request/response, subscribe, event broadcast, disconnect, and error messages through the daemon boundary.
|
|
15
|
+
- Keep daemon as the only session writer and runtime holder.
|
|
16
|
+
- Add tests for auth success, auth failure, malformed messages, clean close, event delivery, and request/response behavior.
|
|
17
|
+
- Use the same WebSocket server primitive in tests and product commands; do not add test-only transports or protocol shortcuts.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- Browser/client `WsTransport` implementation.
|
|
22
|
+
- CLI remote attach UX.
|
|
23
|
+
- TLS termination or certificate management.
|
|
24
|
+
- HTTP REST API.
|
|
25
|
+
- Supervisor, auto-restart, daemon install service, or process manager.
|
|
26
|
+
- Public network hardening beyond token validation and predictable error handling.
|
|
27
|
+
|
|
28
|
+
## Acceptance Criteria
|
|
29
|
+
|
|
30
|
+
- A daemon WebSocket server can start on an injected host/port in tests and close cleanly.
|
|
31
|
+
- An authenticated remote connection can connect to a session and receive `connected`.
|
|
32
|
+
- Invalid token connections are rejected with a structured error and do not attach to a session.
|
|
33
|
+
- Ping/pong and at least one daemon request/response path work over WebSocket.
|
|
34
|
+
- Session events generated inside the daemon are broadcast to authenticated WebSocket clients subscribed to that session.
|
|
35
|
+
- Malformed JSON or unknown message types return clear errors without crashing the server.
|
|
36
|
+
- Package boundary tests still enforce `@scorel/daemon` does not depend on `@scorel/client` or `apps/*`.
|
|
37
|
+
|
|
38
|
+
## Tests
|
|
39
|
+
|
|
40
|
+
- `pnpm --filter @scorel/daemon test`
|
|
41
|
+
- `pnpm --filter @scorel/protocol test`
|
|
42
|
+
- `pnpm typecheck && pnpm test`
|
|
43
|
+
|
|
44
|
+
## Affected Paths
|
|
45
|
+
|
|
46
|
+
- `packages/daemon/src/`
|
|
47
|
+
- `packages/protocol/src/`
|
|
48
|
+
- `docs/spec/daemon.md`
|
|
49
|
+
- `docs/ROADMAP.md`
|
|
50
|
+
|
|
51
|
+
## Risks And Boundaries
|
|
52
|
+
|
|
53
|
+
- WebSocket server code can accidentally become an app-level daemon lifecycle. Keep this as a reusable primitive; product commands belong in S0022.
|
|
54
|
+
- Avoid daemon-to-client package dependencies. The server consumes protocol messages, not `DaemonClient`.
|
|
55
|
+
- Do not claim remote production security in this spec. Token auth is the M4 minimum; TLS and deployment hardening remain separate product work.
|
|
56
|
+
- Do not introduce mock server behavior that differs from the product server path.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# S0021: Remote WebSocket Client Transport
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Implement the client-side WebSocket transport for remote daemon control.
|
|
6
|
+
|
|
7
|
+
This spec makes `DaemonClient` able to use a remote WebSocket daemon while preserving the same API used by embedded and local socket modes.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Add a `WsTransport` implementation that satisfies `DaemonTransport`.
|
|
12
|
+
- Keep the root `@scorel/client` export browser-safe while exposing remote WebSocket support from the appropriate entrypoint.
|
|
13
|
+
- Support token-authenticated connect according to S0019.
|
|
14
|
+
- Preserve request/response, event subscription, close, and parse-error behavior.
|
|
15
|
+
- Add reconnect-oriented tests that verify a client can reconnect with `lastSeq` and resync missed events when used with the daemon WebSocket server primitive.
|
|
16
|
+
- Ensure transport errors map to concise client-visible error messages.
|
|
17
|
+
- Use the same `WsTransport` implementation for tests, CLI, and future browser clients; do not add validation-only transport branches.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- CLI command UX.
|
|
22
|
+
- Daemon WebSocket server implementation beyond consuming the S0020 primitive in tests.
|
|
23
|
+
- Token persistence, token prompts, or config file storage.
|
|
24
|
+
- Browser UI.
|
|
25
|
+
- Background retry policy beyond the minimum needed to prove reconnect/resync semantics.
|
|
26
|
+
|
|
27
|
+
## Acceptance Criteria
|
|
28
|
+
|
|
29
|
+
- `WsTransport` can connect to an authenticated daemon WebSocket endpoint and resolve `connect`.
|
|
30
|
+
- `DaemonClient` can send a message, receive responses, and subscribe to events over `WsTransport`.
|
|
31
|
+
- Closing the WebSocket tears down handlers without leaking subscriptions.
|
|
32
|
+
- A reconnect path can provide `lastSeq` and recover missed events in order.
|
|
33
|
+
- Browser-safety tests prove root `@scorel/client` does not import Node-only APIs.
|
|
34
|
+
- Existing embedded and local socket client tests still pass.
|
|
35
|
+
|
|
36
|
+
## Tests
|
|
37
|
+
|
|
38
|
+
- `pnpm --filter @scorel/client test`
|
|
39
|
+
- `pnpm --filter @scorel/daemon test`
|
|
40
|
+
- `pnpm typecheck && pnpm test`
|
|
41
|
+
|
|
42
|
+
## Affected Paths
|
|
43
|
+
|
|
44
|
+
- `packages/client/src/`
|
|
45
|
+
- `packages/daemon/src/`
|
|
46
|
+
- `packages/protocol/src/`
|
|
47
|
+
- `docs/spec/client.md`
|
|
48
|
+
- `docs/ROADMAP.md`
|
|
49
|
+
|
|
50
|
+
## Risks And Boundaries
|
|
51
|
+
|
|
52
|
+
- Do not fork `DaemonClient` for remote mode. The product value is that deployment mode changes only the transport.
|
|
53
|
+
- Node and browser WebSocket implementations may differ. Keep the transport contract small and test behavior rather than implementation details.
|
|
54
|
+
- Do not add token storage here; storing secrets is a product UX/security decision for a later spec.
|
|
55
|
+
- Do not use fake transports as proof that remote control works.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# S0022: Remote Daemon CLI Lifecycle
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Expose the remote daemon and remote attach product entrypoints through CLI commands.
|
|
6
|
+
|
|
7
|
+
This spec turns the WebSocket primitives from S0020/S0021 into a user-visible remote control path.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Add a remote serve command for the daemon app, such as `scorel-daemon serve --host <host> --port <port> --token <token>`.
|
|
12
|
+
- Add or extend CLI attach so a local client can connect to a remote daemon endpoint with an explicit session id and token.
|
|
13
|
+
- Keep local attach behavior intact.
|
|
14
|
+
- Ensure status/help output clearly distinguishes embedded chat, local daemon, and remote daemon paths.
|
|
15
|
+
- Avoid writing tokens to disk by default; if a token is printed or accepted as an argument, redact it from ordinary status and error output.
|
|
16
|
+
- Add CLI tests for serve argument validation, remote attach construction, missing token, missing endpoint, and connection failure.
|
|
17
|
+
- Keep tests on the same CLI command construction and connection path users will run; do not add hidden validation-only flags.
|
|
18
|
+
|
|
19
|
+
## Not In Scope
|
|
20
|
+
|
|
21
|
+
- TLS certificate generation.
|
|
22
|
+
- Long-running service installation through launchd/systemd/Docker.
|
|
23
|
+
- Persistent remote profiles or named remotes.
|
|
24
|
+
- WebUI / GUI.
|
|
25
|
+
- Full interactive attach polish beyond sending prompts and streaming events needed for M4 end-to-end validation.
|
|
26
|
+
- Permission approval, sandbox, or policy prompts.
|
|
27
|
+
|
|
28
|
+
## Acceptance Criteria
|
|
29
|
+
|
|
30
|
+
- Daemon app exposes a remote serve command that starts the WebSocket server primitive with host/port/token options.
|
|
31
|
+
- CLI remote attach connects through `DaemonClient + WsTransport`, not by directly importing daemon internals.
|
|
32
|
+
- Local attach tests remain green and still use `NodeSocketTransport`.
|
|
33
|
+
- Missing or invalid remote options return actionable CLI errors.
|
|
34
|
+
- Help text documents the minimum command path for remote control.
|
|
35
|
+
- Tokens are not printed in normal status output.
|
|
36
|
+
|
|
37
|
+
## Tests
|
|
38
|
+
|
|
39
|
+
- `pnpm --filter @scorel/app-daemon test`
|
|
40
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
41
|
+
- `pnpm --filter @scorel/client test`
|
|
42
|
+
- `pnpm --filter @scorel/daemon test`
|
|
43
|
+
- `pnpm typecheck && pnpm test`
|
|
44
|
+
|
|
45
|
+
## Affected Paths
|
|
46
|
+
|
|
47
|
+
- `apps/daemon/src/index.ts`
|
|
48
|
+
- `apps/daemon/src/index.test.ts`
|
|
49
|
+
- `apps/cli/src/index.ts`
|
|
50
|
+
- `apps/cli/src/index.test.ts`
|
|
51
|
+
- `packages/client/src/`
|
|
52
|
+
- `packages/daemon/src/`
|
|
53
|
+
- `docs/ROADMAP.md`
|
|
54
|
+
|
|
55
|
+
## Risks And Boundaries
|
|
56
|
+
|
|
57
|
+
- Command UX can sprawl into remote profile management. Keep M4 to explicit endpoint and token arguments.
|
|
58
|
+
- A remote daemon command can be mistaken for production deployment. Keep docs clear: this is the first remote control path, not a hardened service manager.
|
|
59
|
+
- Do not make `scorel chat` remote by default. Remote control should remain opt-in until end-to-end validation and security boundaries are proven.
|
|
60
|
+
- Do not special-case test endpoints or bypass `DaemonClient + WsTransport` in CLI tests.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# S0023: Remote Control End-to-End Validation
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Validate the full M4 remote control product path end to end using real product behavior.
|
|
6
|
+
|
|
7
|
+
This spec closes M4 only after a local client can securely control a daemon running as a remote WebSocket endpoint, recover from disconnects, and complete a real coding flow without losing session state.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Build an end-to-end validation path that starts a daemon WebSocket endpoint, connects a client through remote transport, sends prompts, receives streamed events, disconnects, reconnects with `lastSeq`, and verifies missed event recovery.
|
|
12
|
+
- Use the same daemon, client, CLI, session, config, provider, and transport paths that users run.
|
|
13
|
+
- Verify token auth failure and success through the same product path.
|
|
14
|
+
- Verify persistent JSONL session state is owned by the daemon and remains correct after reconnect.
|
|
15
|
+
- Verify a real coding task in a real temporary workspace through a real LLM provider and a real JSONL session.
|
|
16
|
+
- Update `docs/ROADMAP.md` to mark M4 steps and M4 status Done only after this spec passes.
|
|
17
|
+
|
|
18
|
+
## Not In Scope
|
|
19
|
+
|
|
20
|
+
- Public Internet deployment guidance.
|
|
21
|
+
- TLS hardening or reverse proxy configuration.
|
|
22
|
+
- Remote profile persistence.
|
|
23
|
+
- WebUI / GUI validation.
|
|
24
|
+
- Daemon crash recovery after hard kill.
|
|
25
|
+
- Permission approval UI, sandbox, checkpoint restore.
|
|
26
|
+
|
|
27
|
+
## Acceptance Criteria
|
|
28
|
+
|
|
29
|
+
- A local CLI/client can connect to a daemon WebSocket endpoint using token auth.
|
|
30
|
+
- A prompt sent from the local client runs on the daemon-owned session and streams events back over WebSocket.
|
|
31
|
+
- A disconnected remote client can reconnect with `lastSeq` and receive missed events in order.
|
|
32
|
+
- If in-memory buffers cannot satisfy resync, daemon falls back to persistent JSONL session replay where applicable.
|
|
33
|
+
- Invalid tokens cannot observe or mutate session state.
|
|
34
|
+
- The validation proves remote transport, auth, event broadcast, request/response, and session persistence together.
|
|
35
|
+
- A real-provider validation proves the remote `scorel chat` product path with a real temporary workspace and real JSONL session.
|
|
36
|
+
- `pnpm typecheck && pnpm test` passes.
|
|
37
|
+
- `docs/ROADMAP.md` marks all M4 steps and M4 status as `Done` only after verification.
|
|
38
|
+
|
|
39
|
+
## Tests
|
|
40
|
+
|
|
41
|
+
- `pnpm --filter @scorel/client test`
|
|
42
|
+
- `pnpm --filter @scorel/daemon test`
|
|
43
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
44
|
+
- `pnpm --filter @scorel/app-daemon test`
|
|
45
|
+
- `pnpm typecheck && pnpm test`
|
|
46
|
+
- Required real-provider validation before marking M4 Done: remote daemon WebSocket endpoint + real LLM provider + real temporary coding workspace + real JSONL session.
|
|
47
|
+
|
|
48
|
+
## Affected Paths
|
|
49
|
+
|
|
50
|
+
- `apps/cli/src/`
|
|
51
|
+
- `apps/daemon/src/`
|
|
52
|
+
- `packages/client/src/`
|
|
53
|
+
- `packages/daemon/src/`
|
|
54
|
+
- `packages/protocol/src/`
|
|
55
|
+
- `docs/ROADMAP.md`
|
|
56
|
+
- `docs/spec/client.md`
|
|
57
|
+
- `docs/spec/daemon.md`
|
|
58
|
+
|
|
59
|
+
## Risks And Boundaries
|
|
60
|
+
|
|
61
|
+
- A validation that only tests raw WebSocket messages does not prove user value. It must use `DaemonClient` and the product CLI path where possible.
|
|
62
|
+
- A remote validation without reconnect/resync does not close M4.
|
|
63
|
+
- Do not mark M4 Done while auth or reconnect remains only unit-tested in isolation.
|
|
64
|
+
- Do not use mock/fake providers as completion proof.
|
|
65
|
+
- Do not add test-only branches, special protocol messages, fake transports, or product behavior that exists only for validation.
|
|
66
|
+
- If real provider credentials are unavailable, record that limitation and keep M4 Planned.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# S0024: Remote Attach Interactive Stream
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Fix `scorel attach` so remote attached clients behave like live session viewers, not only prompt senders.
|
|
6
|
+
|
|
7
|
+
Multiple attached clients must see the same session event stream, and a client that reconnects while a turn is still running must receive subsequent streamed events without sending another prompt.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
- Keep `scorel attach --remote` connected to the session event stream for the whole interactive process.
|
|
12
|
+
- Render text deltas, tool results, and daemon errors from any client attached to the same session.
|
|
13
|
+
- Remove the send-only temporary subscription behavior from attach.
|
|
14
|
+
- Keep local socket attach and remote attach on the same interactive attach code path.
|
|
15
|
+
- Add tests that start a real WebSocket server and verify a passive remote attach client receives session events without sending a prompt.
|
|
16
|
+
- Verify the behavior with real daemon/client processes.
|
|
17
|
+
|
|
18
|
+
## Not In Scope
|
|
19
|
+
|
|
20
|
+
- Full TUI polish, prompt rendering, scrollback, or terminal layout.
|
|
21
|
+
- Persisting per-client `lastSeq` across CLI process restarts.
|
|
22
|
+
- Automatic reconnect loop after network failure.
|
|
23
|
+
- Reconstructing partial transient deltas that were already emitted before a client connected.
|
|
24
|
+
- Cancel/interrupt propagation to stop an in-flight remote turn.
|
|
25
|
+
|
|
26
|
+
## Acceptance Criteria
|
|
27
|
+
|
|
28
|
+
- Two remote `scorel attach` clients connected to the same session can both receive streamed events from one client prompt.
|
|
29
|
+
- A passive attach client receives future events without sending input.
|
|
30
|
+
- Reattaching while the daemon continues a turn receives subsequent events.
|
|
31
|
+
- Local attach behavior remains green.
|
|
32
|
+
- `pnpm typecheck && pnpm test` passes.
|
|
33
|
+
|
|
34
|
+
## Tests
|
|
35
|
+
|
|
36
|
+
- `pnpm --filter @scorel/app-cli test`
|
|
37
|
+
- `pnpm typecheck && pnpm test`
|
|
38
|
+
- Manual real-process validation: one `scorel-daemon serve` process and two `scorel attach --remote` clients sharing one session.
|
|
39
|
+
|
|
40
|
+
## Affected Paths
|
|
41
|
+
|
|
42
|
+
- `apps/cli/src/index.ts`
|
|
43
|
+
- `apps/cli/src/index.test.ts`
|
|
44
|
+
- `docs/ROADMAP.md`
|
|
45
|
+
|
|
46
|
+
## Risks And Boundaries
|
|
47
|
+
|
|
48
|
+
- This does not promise replay of transient text that was emitted before a client connected. Only future events and persistent session recovery are covered.
|
|
49
|
+
- Do not add a fake transport or test-only CLI branch. Use the same `DaemonClient` and transport path as the product.
|