@chanlerdev/scorel 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +409 -69
  2. package/dist/index.js +4593 -1751
  3. package/dist/index.js.map +4 -4
  4. package/docs/CHANGELOG.md +115 -0
  5. package/docs/ROADMAP.md +112 -9
  6. package/docs/SHIP.md +9 -3
  7. package/docs/spec/channels.md +107 -100
  8. package/docs/spec/client.md +11 -5
  9. package/docs/spec/extensions.md +115 -43
  10. package/docs/spec/ship/S0062-npm-package-and-release-workflow.md +3 -0
  11. package/docs/spec/ship/S0063-ai-release-notes.md +129 -0
  12. package/docs/spec/ship/S0064-gui-product-intent-and-boundary.md +79 -0
  13. package/docs/spec/ship/S0065-gui-electron-shell-and-embedded-host.md +73 -0
  14. package/docs/spec/ship/S0066-gui-local-project-workspace.md +79 -0
  15. package/docs/spec/ship/S0067-gui-relay-device-and-remote-project-selection.md +97 -0
  16. package/docs/spec/ship/S0068-gui-codex-app-polish-and-e2e.md +102 -0
  17. package/docs/spec/ship/S0068-gui-e2e-verification.md +50 -0
  18. package/docs/spec/ship/S0069-gui-codex-ui-refactor.md +371 -0
  19. package/docs/spec/ship/S0070-gui-streaming-and-tool-blocks.md +202 -0
  20. package/docs/spec/ship/S0071-gui-visual-fidelity-and-settings-shell.md +360 -0
  21. package/docs/spec/ship/S0072-gui-glass-sidebar-and-picker-anchoring.md +116 -0
  22. package/docs/spec/ship/S0073-provider-model-profile-contract.md +241 -0
  23. package/docs/spec/ship/S0074-gui-model-provider-settings-split.md +113 -0
  24. package/docs/spec/ship/S0075-provider-catalog-model-cards.md +93 -0
  25. package/docs/spec/ship/S0076-provider-modal-search-and-direct-key.md +70 -0
  26. package/docs/spec/ship/S0077-auxiliary-session-title-generation.md +95 -0
  27. package/docs/spec/ship/S0078-gui-provider-settings-forward-config-and-simplification.md +150 -0
  28. package/docs/spec/ship/S0079-gui-sidebar-layout-controls.md +49 -0
  29. package/docs/spec/ship/S0080-session-title-hook-and-gui-markdown-dark-code.md +58 -0
  30. package/docs/spec/ship/S0081-automatic-memory.md +117 -0
  31. package/docs/spec/ship/S0082-memory-journal-tool-and-idle-dream.md +107 -0
  32. package/docs/spec/ship/S0083-extension-manifest-and-im-channel-runtime.md +338 -0
  33. package/docs/spec/ship/S0084-built-in-telegram-im-extension.md +188 -0
  34. package/docs/spec/ship/S0085-gui-im-extension-settings.md +47 -0
  35. package/docs/spec/ship/S0086-auto-compact-and-session-memory.md +124 -0
  36. package/docs/spec/ship/S0087-gui-ui-polish-sweep.md +153 -0
  37. package/docs/spec/ship/S0088-gui-streaming-thinking-contract.md +35 -0
  38. package/docs/spec/ship/S0089-memory-reliability-and-dream-trigger.md +84 -0
  39. package/docs/spec/ship/S0090-gui-provider-delete-and-dark-code-theme.md +77 -0
  40. package/docs/spec/ship/S0091-built-in-qq-and-wechat-im-extensions.md +125 -0
  41. package/docs/spec/ship/S0092-im-message-media-and-human-cadence.md +83 -0
  42. package/docs/spec/ship/S0093-gui-im-settings-platform-layout.md +66 -0
  43. package/docs/spec/ship/S0094-im-inbound-runtime.md +67 -0
  44. package/docs/spec/ship/S0095-gui-im-session-list-refresh.md +36 -0
  45. package/extensions/builtin/loopback/adapter.js +13 -0
  46. package/extensions/builtin/loopback/scorel.extension.json +7 -0
  47. package/extensions/builtin/loopback/skills/loopback/SKILL.md +9 -0
  48. package/extensions/builtin/qq/adapter.d.ts +27 -0
  49. package/extensions/builtin/qq/adapter.js +384 -0
  50. package/extensions/builtin/qq/scorel.extension.json +7 -0
  51. package/extensions/builtin/qq/skills/qq/SKILL.md +9 -0
  52. package/extensions/builtin/telegram/adapter.d.ts +43 -0
  53. package/extensions/builtin/telegram/adapter.js +259 -0
  54. package/extensions/builtin/telegram/scorel.extension.json +7 -0
  55. package/extensions/builtin/telegram/skills/telegram/SKILL.md +11 -0
  56. package/extensions/builtin/wechat/adapter.d.ts +24 -0
  57. package/extensions/builtin/wechat/adapter.js +226 -0
  58. package/extensions/builtin/wechat/scorel.extension.json +7 -0
  59. package/extensions/builtin/wechat/skills/wechat/SKILL.md +9 -0
  60. package/package.json +6 -2
@@ -0,0 +1,153 @@
1
+ # S0087: Codex-Inspired GUI Visual Pass
2
+
3
+ ## Goal
4
+
5
+ Move the Scorel desktop GUI closer to a mature Codex-style workbench without copying Codex screen-for-screen.
6
+
7
+ The business value is product trust. Scorel should stop feeling like an engineering demo and start feeling like a quiet, high-density desktop tool for project-scoped agent work.
8
+
9
+ This spec is a visual-system pass over existing GUI surfaces. It does not introduce new product capabilities.
10
+
11
+ ## Design Direction
12
+
13
+ Learn from Codex at the level of visual principles:
14
+
15
+ - restrained source-list sidebar;
16
+ - white main workspace with low visual noise;
17
+ - natural heading text instead of badge-heavy emphasis;
18
+ - composer as a command surface with a clear input/control row;
19
+ - metadata controls visually attached to the composer;
20
+ - quiet active states, subtle borders, and shallow elevation;
21
+ - compact but readable typography.
22
+
23
+ Do not copy Codex literally. Scorel remains Project-first and should only show real controls backed by existing product paths.
24
+
25
+ ## Scope
26
+
27
+ ### Visual Pass Targets
28
+
29
+ - Sidebar source list:
30
+ - reduce heavy active row treatment;
31
+ - tighten project/session row rhythm;
32
+ - make empty session rows quieter;
33
+ - load session lists for the selected Project and expanded Projects so startup stays responsive without stale empty states;
34
+ - keep Add Project as the real project-management entry.
35
+
36
+ - Empty workspace:
37
+ - hide the empty topbar when it has no useful content;
38
+ - render the project name as natural heading text, not a large grey badge;
39
+ - keep the hero centered but calmer and less heavy.
40
+
41
+ - Composer:
42
+ - reduce shadow and heavy pill feel;
43
+ - add whole-surface focus feedback;
44
+ - make model selection and send action read as a compact control row;
45
+ - keep fake controls such as attachment, voice, and permission mode hidden.
46
+
47
+ - Project metadata:
48
+ - keep project picker as a real control;
49
+ - visually attach the project picker to the composer area;
50
+ - keep the popover anchored and searchable.
51
+
52
+ - Active session:
53
+ - keep a stable topbar title fallback (`未命名对话`) until auxiliary title generation updates it.
54
+ - keep expanded thinking content within the message column, with long prose wrapping and code blocks scrolling internally.
55
+ - render code-block language and copy controls inside the code-block header.
56
+ - keep markdown code blocks aligned with the GUI light surface and token system; do not use a fixed dark code-block theme in the light workspace.
57
+ - render tool calls as compact execution evidence rows: clear tool name, target object, status, counters, and expandable details.
58
+ - keep successful tool output collapsed by default, while making errors, diffs, and pending/running state visible.
59
+
60
+ ### Tool Display Contract
61
+
62
+ - `Read`: collapsed header shows file basename and line range; expanded details show the returned read text and full path/range evidence.
63
+ - `Glob` / `Grep`: collapsed header shows pattern/result count; expanded details show the returned file or match list plus pagination/mode metadata when present.
64
+ - `Bash`: collapsed header shows command and exit status when known; expanded details show stdout/stderr/cwd evidence returned by the tool.
65
+ - `Edit` / `Write`: collapsed header shows operation, file basename, and `+/-` counters; diff details are visible by default and remain collapsible.
66
+ - `TodoWrite`: collapsed header shows active progress; expanded details show the current todo list and item states.
67
+ - Fallback tools: collapsed header shows tool name; expanded details show args/result JSON.
68
+
69
+ ## Not In Scope
70
+
71
+ - New GUI product capability such as SSH remote device, HTTP API, account/auth, review banner, or changed-files diff surface.
72
+ - Runtime, provider/model, memory, channel, extension, or daemon contract changes.
73
+ - Reintroducing disabled placeholder commands.
74
+ - Empty-state plugin recommendation cards.
75
+ - Global conversation history grouping.
76
+ - Voice, attachment, permission-mode, or null-project mode.
77
+ - WebUI component reuse or shared UI package extraction.
78
+ - Streaming thinking/runtime protocol changes. Thinking currently arrives with final persistent assistant messages; streaming thinking requires a follow-up protocol/runtime spec.
79
+
80
+ ## Acceptance Criteria
81
+
82
+ - Empty workspace has no blank topbar.
83
+ - Empty heading uses natural text, with no badge-like project-name background.
84
+ - Composer has low-shadow elevation, stable focus feedback, and no unimplemented controls.
85
+ - Project picker remains visible and attached to the composer cluster.
86
+ - Sidebar active and empty states are quiet and source-list-like.
87
+ - Startup loads session summaries for the selected Project and expanded Projects, not every Project.
88
+ - Expanded thinking content cannot horizontally stretch the workspace.
89
+ - Long prose wraps inside thinking/markdown content, while code blocks keep formatting and scroll internally.
90
+ - Code blocks show the fenced language as non-interactive metadata on the top-left and a copy control on the top-right.
91
+ - Code block theme and chrome match the GUI light mode instead of rendering as a visually detached dark block.
92
+ - GUI tool blocks read as a low-noise execution trace, not generic JSON dumps.
93
+ - Bash, Read, Glob/Grep, Edit/Write, TodoWrite, and fallback JSON tools share consistent header/body/error/pending styling.
94
+ - File edits surface filename and diff counters in the header; expanded details keep diff/output internally scrollable.
95
+ - Clicking a tool header reveals the right evidence for that tool type, not just raw arguments.
96
+ - Active sessions show `未命名对话` when no generated title exists.
97
+ - Existing GUI behavior remains Project-first.
98
+ - Text remains readable and non-overlapping across narrow and normal desktop widths.
99
+ - Sidebar collapse/resize behavior still works.
100
+ - GUI shell render tests cover the changed contracts.
101
+ - Full `pnpm typecheck && pnpm test` passes.
102
+
103
+ ## Testing Requirements
104
+
105
+ - Focused GUI tests:
106
+
107
+ ```bash
108
+ pnpm --filter @scorel/app-gui test
109
+ ```
110
+
111
+ - GUI build:
112
+
113
+ ```bash
114
+ pnpm --filter @scorel/app-gui build
115
+ ```
116
+
117
+ - Full check:
118
+
119
+ ```bash
120
+ pnpm typecheck && pnpm test
121
+ ```
122
+
123
+ - Whitespace check:
124
+
125
+ ```bash
126
+ git diff --check
127
+ ```
128
+
129
+ - Run Electron GUI and visually inspect the empty workspace.
130
+
131
+ ## Impacted Files
132
+
133
+ - `apps/gui/src/renderer/workspace/Workspace.tsx`
134
+ - `apps/gui/src/renderer/App.tsx`
135
+ - `apps/gui/src/renderer/shell/Sidebar.tsx`
136
+ - `apps/gui/src/renderer/shell/ProjectTree.tsx`
137
+ - `apps/gui/src/renderer/workspace/EmptyState.tsx`
138
+ - `apps/gui/src/renderer/composer/Composer.tsx`
139
+ - `apps/gui/src/renderer/chatbox/ShikiCodeBlock.tsx`
140
+ - `apps/gui/src/renderer/chatbox/ShikiCodeBlock.test.tsx`
141
+ - `apps/gui/src/renderer/chatbox/tool-blocks/*`
142
+ - `apps/gui/src/renderer/styles.css`
143
+ - `apps/gui/src/renderer/gui-shell.test.tsx`
144
+ - `apps/gui/src/renderer/app-session-preload.test.tsx`
145
+ - `apps/gui/src/sidebar-layout.test.ts`
146
+ - `docs/ROADMAP.md`
147
+ - `docs/spec/ship/S0087-gui-ui-polish-sweep.md`
148
+
149
+ ## Risks And Boundaries
150
+
151
+ - Visual polish can sprawl. Keep this pass focused on existing workbench surfaces.
152
+ - A better-looking fake feature is still bad product design. Hide unimplemented controls instead of styling them.
153
+ - Render tests prove structure but not taste. Use manual GUI inspection before handoff.
@@ -0,0 +1,35 @@
1
+ # S0088: GUI Streaming Thinking Contract
2
+
3
+ ## Goal
4
+
5
+ Make thinking visible while a turn is running instead of inserting the thinking block only after the final persistent `assistant_message` arrives.
6
+
7
+ The business value is process trust. Users should see the agent's work unfold in order, not as a post-hoc replay after the visible answer has already completed.
8
+
9
+ ## Context
10
+
11
+ Today Scorel streams only `text_delta`. Thinking content exists in the final persistent assistant message, so GUI can only render it after the turn is finalized. A GUI-only placeholder would be misleading because it would imply thinking is streaming when the runtime has not emitted it.
12
+
13
+ ## Scope
14
+
15
+ - Add a protocol/runtime event for streaming thinking, likely `thinking_delta` or a more general ordered `content_delta`.
16
+ - Preserve ordered assistant content blocks so thinking, text, and tool calls reconcile cleanly with the final persistent assistant message.
17
+ - Update GUI projector to create and update thinking parts incrementally.
18
+ - Keep final `assistant_message` as authoritative reconciliation, not a second visual insertion.
19
+
20
+ ## Not In Scope
21
+
22
+ - Tool block visual polish; covered by `S0087`.
23
+ - Fake GUI placeholders for thinking content.
24
+ - Changing provider reasoning semantics beyond the event stream needed to display already-produced thinking.
25
+
26
+ ## Acceptance Criteria
27
+
28
+ - Thinking appears during the active turn when the provider/runtime emits thinking content.
29
+ - Final assistant reconciliation does not duplicate or reorder thinking/text/tool parts.
30
+ - Existing text streaming remains smooth.
31
+ - Protocol, daemon/client, GUI projector, and tests all agree on the new event contract.
32
+
33
+ ## Status
34
+
35
+ Done.
@@ -0,0 +1,84 @@
1
+ # S0089: Memory Reliability And Dream Trigger
2
+
3
+ ## Goal
4
+
5
+ Make Scorel memory actually useful in normal GUI/agent use by tightening the `AppendDaily -> idle dream -> memory injection` loop.
6
+
7
+ The business value is continuity. If users finish meaningful work and later return to the project, Scorel should remember durable progress, decisions, and follow-ups without relying on fragile manual reminders.
8
+
9
+ ## Context
10
+
11
+ S0081/S0082 established the memory architecture:
12
+
13
+ - daily evidence is written through the agent-owned `AppendDaily` tool;
14
+ - successful append marks the project dirty;
15
+ - daemon schedules dreaming after project idle time;
16
+ - memory content re-enters future turns through the hidden memory harness.
17
+
18
+ In practice this is not reliable enough yet:
19
+
20
+ - `AppendDaily` depends too much on the model remembering a prompt instruction near the end of work;
21
+ - daily entries can be low quality when the model records vague summaries instead of durable evidence;
22
+ - dream triggering is hard to observe and easy to miss;
23
+ - idle-only scheduling means memory may not update before the app/host exits;
24
+ - GUI has no clear signal that daily/dream/memory actually happened.
25
+
26
+ ## Scope
27
+
28
+ ### AppendDaily Quality
29
+
30
+ - Make the tool contract harder to ignore in completed meaningful turns.
31
+ - Improve the journal schema/prompt so entries prefer concrete completed work, decisions, evidence paths, and follow-ups over generic summaries.
32
+ - Add validation or lightweight scoring for empty, duplicate, or low-signal entries.
33
+ - Keep `AppendDaily` project-scoped and append-only.
34
+
35
+ ### Dream Trigger Reliability
36
+
37
+ - Audit the current daemon dirty-project and idle-timer path.
38
+ - Ensure a successful `AppendDaily` reliably schedules a dream attempt.
39
+ - Add a recovery path for pending daily evidence when the process restarts before idle dream fires.
40
+ - Consider a manual or debug trigger if it materially improves verification and support.
41
+
42
+ ### Observability
43
+
44
+ - Expose enough local state to answer:
45
+ - when was the last daily append;
46
+ - whether the project is dirty;
47
+ - whether dream is scheduled/running/failed;
48
+ - when project memory was last updated.
49
+ - Surface this in GUI Settings or a compact project memory status area.
50
+ - Keep failures non-blocking for chat turns, but visible enough to debug.
51
+
52
+ ### Injection Verification
53
+
54
+ - Verify that updated project memory is actually injected into subsequent model context.
55
+ - Add tests or a local verification path proving `AppendDaily` evidence can become project memory and then influence a later turn.
56
+
57
+ ## Not In Scope
58
+
59
+ - Full activity recorder.
60
+ - Vector search or semantic memory.
61
+ - Topic memory file fan-out.
62
+ - Root/global memory promotion beyond the existing guarded behavior.
63
+ - Replacing the memory harness with provider system prompt content.
64
+
65
+ ## Acceptance Criteria
66
+
67
+ - Meaningful completed work has a reliable path to daily evidence without depending only on user reminders.
68
+ - Successful `AppendDaily` schedules or queues dream work even across host restarts.
69
+ - Dream status is inspectable from local state and surfaced in GUI.
70
+ - Low-quality or duplicate daily entries are reduced by contract, validation, or tests.
71
+ - A verified path proves daily evidence can update project memory and be injected into a later turn.
72
+ - Existing memory settings remain backward compatible.
73
+
74
+ ## Testing Requirements
75
+
76
+ - Core tests for `AppendDaily` schema/quality validation.
77
+ - Daemon tests for dirty-project scheduling, idle dream, restart recovery, and failure visibility.
78
+ - GUI tests for memory status rendering if a GUI surface is added.
79
+ - Integration-style test or scripted verification for `AppendDaily -> dream -> memory injection`.
80
+ - Full `pnpm typecheck && pnpm test`.
81
+
82
+ ## Status
83
+
84
+ Done.
@@ -0,0 +1,77 @@
1
+ # S0090: GUI Provider Delete And Dark Code Theme
2
+
3
+ ## Goal
4
+
5
+ Fix two GUI regressions before the next IM expansion:
6
+
7
+ - dark theme code blocks must use a dark Shiki theme instead of light-token colors;
8
+ - Provider settings must expose a real delete path for configured providers.
9
+
10
+ The business value is basic settings trust. Users should be able to remove bad provider config and read code blocks in the selected GUI theme.
11
+
12
+ ## Scope
13
+
14
+ ### Dark Code Blocks
15
+
16
+ - Load both light and dark Shiki themes in the GUI code block highlighter.
17
+ - Select the rendered theme from `:root[data-theme]` / system dark preference.
18
+ - Re-render when the GUI theme changes.
19
+ - Keep code block chrome styled by Scorel tokens; only syntax token colors switch.
20
+
21
+ ### Provider Delete
22
+
23
+ - Add a protocol/client/daemon request for removing one provider from a project model profile.
24
+ - Deleting a provider removes:
25
+ - `[providers.<id>]`;
26
+ - provider models owned by that provider;
27
+ - available models pointing at removed provider models;
28
+ - role selections that pointed at removed available models, with stable fallback when possible.
29
+ - GUI Provider Settings exposes a delete button for the selected provider.
30
+ - If no provider remains, the Provider page returns to the empty state without stale selected-provider UI.
31
+
32
+ ## Not In Scope
33
+
34
+ - Deleting individual provider model definitions unless required by provider deletion.
35
+ - Bulk reset of all model profile config.
36
+ - Provider secret migration.
37
+ - Changing provider catalog fetch behavior.
38
+ - IM platform work; covered by S0091-S0093.
39
+
40
+ ## Acceptance Criteria
41
+
42
+ - Dark GUI theme renders Shiki tokens with a dark theme.
43
+ - Light GUI theme keeps the current light code block behavior.
44
+ - Switching GUI theme updates future code block renders without app restart.
45
+ - Provider delete removes the provider and all dependent model profile entries from persisted config.
46
+ - Provider delete does not leave roles pointing at removed models.
47
+ - GUI can delete the selected provider and updates the selected provider to the next available provider or empty state.
48
+ - Remote GUI provider deletion uses the same daemon/client request as local GUI.
49
+
50
+ ## Testing Requirements
51
+
52
+ - GUI Shiki tests prove both light and dark themes are loaded/selected.
53
+ - Config renderer tests cover provider deletion and role fallback.
54
+ - Protocol/client/daemon tests cover the delete request.
55
+ - GUI render test covers delete button and empty-state transition.
56
+ - Full `pnpm typecheck && pnpm test`.
57
+
58
+ ## Impacted Files
59
+
60
+ - `apps/gui/src/renderer/chatbox/ShikiCodeBlock.tsx`
61
+ - `apps/gui/src/renderer/chatbox/ShikiCodeBlock.test.tsx`
62
+ - `apps/gui/src/shiki-theme.test.ts`
63
+ - `apps/gui/src/renderer/settings/sections/ProviderSection.tsx`
64
+ - `apps/gui/src/shared/ipc.ts`
65
+ - `apps/gui/src/main.ts`
66
+ - `apps/gui/src/main/local-host.ts`
67
+ - `apps/gui/src/main/relay-service.ts`
68
+ - `packages/protocol/src/events.ts`
69
+ - `packages/protocol/src/wire.ts`
70
+ - `packages/client/src/index.ts`
71
+ - `packages/core/src/config/index.ts`
72
+ - `packages/core/src/config/*.test.ts`
73
+ - `packages/daemon/src/index.ts`
74
+
75
+ ## Status
76
+
77
+ Done.
@@ -0,0 +1,125 @@
1
+ # S0091: Built-In QQ And WeChat IM Extensions
2
+
3
+ ## Goal
4
+
5
+ Add QQ Bot and WeChat as built-in IM extensions on the existing extension-backed channel bridge.
6
+
7
+ The business value is channel reach. Telegram proved the bridge; QQ and WeChat force the adapter contract to stay generic enough for multiple IM platforms without forking Scorel runtime behavior.
8
+
9
+ ## Product Boundary
10
+
11
+ Scorel must use official or documented bot/server APIs. This spec does not support personal-account reverse engineering, browser automation of consumer clients, unofficial Web WeChat scraping, or any path likely to get user accounts restricted.
12
+
13
+ ## Scope
14
+
15
+ ### Shared IM Adapter Utilities
16
+
17
+ - Extract reusable helpers for HTTP polling/webhook-shaped adapters where the current Telegram code has platform-neutral logic.
18
+ - Keep platform-specific authentication, payload parsing, mention rules, and send APIs inside each built-in extension.
19
+ - Preserve the S0083 adapter boundary: adapters do platform IO only and never create sessions or write JSONL.
20
+
21
+ ### QQ Bot Extension
22
+
23
+ Add:
24
+
25
+ ```text
26
+ extensions/builtin/qq/
27
+ scorel.extension.json
28
+ adapter.js
29
+ adapter.d.ts
30
+ skills/qq/SKILL.md
31
+ ```
32
+
33
+ Expected config shape:
34
+
35
+ ```toml
36
+ [extensions.qq]
37
+ enabled = true
38
+ kind = "im"
39
+
40
+ [extensions.qq.config]
41
+ appId = "..."
42
+ appSecret = "..."
43
+ botId = "..."
44
+ allowedConversationIds = "..."
45
+ ```
46
+
47
+ QQ Bot uses the current official server-side credential flow: Scorel stores the developer-console `App ID` and `App Secret`, calls `https://bots.qq.com/app/getAppAccessToken`, caches the returned access token until shortly before expiry, and sends API requests with `Authorization: QQBot ACCESS_TOKEN`.
48
+
49
+ `apiBaseUrl` and `accessTokenUrl` may remain internal override hooks for tests and sandbox work, but GUI Settings must not expose them as the default setup path.
50
+
51
+ ### WeChat Extension
52
+
53
+ Add:
54
+
55
+ ```text
56
+ extensions/builtin/wechat/
57
+ scorel.extension.json
58
+ adapter.js
59
+ adapter.d.ts
60
+ skills/wechat/SKILL.md
61
+ ```
62
+
63
+ Expected config shape:
64
+
65
+ ```toml
66
+ [extensions.wechat]
67
+ enabled = true
68
+ kind = "im"
69
+
70
+ [extensions.wechat.config]
71
+ webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=..."
72
+ callbackToken = "..."
73
+ callbackHost = "127.0.0.1"
74
+ callbackPort = 0
75
+ ```
76
+
77
+ Use WeCom group robot webhook semantics for outbound send only. The user copies the full webhook URL from the official group robot configuration and pastes it into Scorel. This webhook cannot receive user messages from the group.
78
+
79
+ Inbound WeChat receive is covered by S0094: Scorel can expose an official-account style plaintext callback server when `callbackToken` is configured. Do not make users split `key`, env var names, or base URLs in the default outbound setup path. Do not implement consumer WeChat personal account automation.
80
+
81
+ ### Skills
82
+
83
+ Each built-in extension must include a platform-specific skill that tells the model:
84
+
85
+ - what kind of conversation it is replying to;
86
+ - how mentions/group context should be interpreted;
87
+ - platform etiquette and short-response expectations;
88
+ - when to use `SendChannelMessage`;
89
+ - what not to assume about raw platform ids.
90
+
91
+ ## Not In Scope
92
+
93
+ - Consumer QQ/WeChat personal account login.
94
+ - Public callback deployment, TLS, or hosted ingress.
95
+ - Rich media send support; covered by S0092.
96
+ - GUI Settings layout; covered by S0093.
97
+ - Remote Relay management of IM settings.
98
+
99
+ ## Acceptance Criteria
100
+
101
+ - QQ and WeChat built-in extension manifests are discoverable by the existing loader.
102
+ - Each extension starts only when explicitly enabled and required credentials are present.
103
+ - QQ requires `appId` and `appSecret`; WeChat requires either a full outbound `webhookUrl` or an inbound `callbackToken`.
104
+ - Each adapter normalizes incoming text messages into the existing `ImIncomingMessage` shape.
105
+ - Each adapter sends plain text replies through the existing `SendChannelMessage` path.
106
+ - QQ send obtains and reuses an official access token instead of accepting deprecated bot token config.
107
+ - Adapter diagnostics redact secrets.
108
+ - QQ, WeChat, Telegram, and loopback share the same channel bridge and session binding behavior.
109
+ - No QQ/WeChat-specific branch is added to runtime/session/core channel orchestration.
110
+
111
+ ## Testing Requirements
112
+
113
+ - Manifest loader coverage for QQ and WeChat built-ins.
114
+ - Adapter normalization tests using local HTTP stubs or pure parser fixtures.
115
+ - Send-message tests proving each adapter maps `SendChannelMessage` to its platform send API shape.
116
+ - Secret redaction tests.
117
+ - Full `pnpm typecheck && pnpm test`.
118
+
119
+ ## Local State Boundary
120
+
121
+ Pre-1.0 local config may contain older `tokenEnv`, `token`, `webhookKeyEnv`, `webhookKey`, or `webhookBaseUrl` keys from earlier S0091 drafts. Those keys are no longer the supported setup surface. Users should re-enter QQ `App ID` / `App Secret` or WeChat `Outbound Webhook` / `Callback Token` in GUI Settings.
122
+
123
+ ## Status
124
+
125
+ Done.
@@ -0,0 +1,83 @@
1
+ # S0092: IM Message Media And Human Cadence
2
+
3
+ ## Goal
4
+
5
+ Make IM conversations feel alive and trustworthy by improving outgoing message capability and IM-specific response cadence.
6
+
7
+ The business value is user confidence. In IM, silence for minutes reads as failure; Scorel needs visible progress and short human-style replies without compromising the existing agent loop.
8
+
9
+ ## Scope
10
+
11
+ ### SendChannelMessage Payload
12
+
13
+ Extend `SendChannelMessage` from text-only to a structured outgoing message:
14
+
15
+ ```ts
16
+ type SendChannelMessageInput = {
17
+ text?: string;
18
+ attachments?: Array<{
19
+ type: "image" | "file";
20
+ path?: string;
21
+ url?: string;
22
+ mimeType?: string;
23
+ caption?: string;
24
+ }>;
25
+ channel?: string;
26
+ target?: "current";
27
+ };
28
+ ```
29
+
30
+ Rules:
31
+
32
+ - At least one of `text` or `attachments` is required.
33
+ - Adapters may downgrade unsupported attachments to a clear tool error.
34
+ - Local file paths must be explicit and must not be guessed from raw platform ids.
35
+ - Tool result details report per-attachment status.
36
+
37
+ ### Adapter Capability Contract
38
+
39
+ - Add optional adapter capabilities for outgoing attachment support.
40
+ - Telegram/QQ/WeChat can initially support text and explicitly reject unsupported media.
41
+ - Loopback should support structured capture of text and attachment metadata for tests.
42
+
43
+ ### IM System Prompt / Harness Guidance
44
+
45
+ Add IM-specific guidance to channel context:
46
+
47
+ - acknowledge quickly when work will take time;
48
+ - send brief progress updates through `SendChannelMessage` during long tasks;
49
+ - prefer concise, conversational wording;
50
+ - do not wait until every tool finishes before sending any reply;
51
+ - avoid exposing internal tool names unless useful to the user;
52
+ - keep business-critical facts and file references precise.
53
+
54
+ This guidance must enter through the existing channel harness item / skill path, not a second provider-level system prompt.
55
+
56
+ ## Not In Scope
57
+
58
+ - Full media upload implementation for every platform.
59
+ - Voice, stickers, albums, interactive buttons, or payments.
60
+ - Cross-conversation proactive messages.
61
+ - A new IM runtime loop or queue.
62
+ - Fake progress timers outside the agent loop.
63
+
64
+ ## Acceptance Criteria
65
+
66
+ - `SendChannelMessage` accepts text, image, and file attachment metadata.
67
+ - Text-only calls remain backward compatible.
68
+ - Unsupported attachment sends fail as tool errors, not silent no-ops.
69
+ - IM channel reminders tell the agent to respond early and keep long-running users informed.
70
+ - Built-in IM skills include platform-specific response cadence guidance.
71
+ - Tests prove the model-facing tool schema rejects empty sends and preserves attachment metadata.
72
+
73
+ ## Testing Requirements
74
+
75
+ - Core channel tool tests for structured payload parsing.
76
+ - Loopback adapter tests for captured attachment metadata.
77
+ - Telegram/QQ/WeChat tests for unsupported media errors or implemented send mapping.
78
+ - Instruction/channel context tests for IM cadence guidance.
79
+ - Full `pnpm typecheck && pnpm test`.
80
+
81
+ ## Status
82
+
83
+ Done.
@@ -0,0 +1,66 @@
1
+ # S0093: GUI IM Settings Platform Layout
2
+
3
+ ## Goal
4
+
5
+ Redesign GUI IM Settings so multiple platforms fit without crowding the page.
6
+
7
+ The business value is scale. Telegram was one provider; Telegram + QQ + WeChat needs a repeatable platform row pattern where details expand only when the user asks.
8
+
9
+ ## Scope
10
+
11
+ - Replace the current Telegram-only large form with a platform list.
12
+ - Each platform row shows:
13
+ - platform name;
14
+ - enabled/disabled toggle;
15
+ - active/inactive status;
16
+ - concise credential/config summary;
17
+ - expand/collapse affordance.
18
+ - Clicking a row expands its detailed config below that row.
19
+ - Clicking the expanded row again collapses it.
20
+ - The page defaults to all platforms collapsed unless a previous expanded platform is stored locally.
21
+ - The last expanded platform is remembered locally; collapsing clears that remembered state.
22
+ - Support Telegram, QQ, and WeChat using one reusable component shape.
23
+ - Preserve existing Telegram config fields and persistence behavior.
24
+ - Add QQ and WeChat config fields that match S0091/S0094.
25
+ - For QQ and WeChat, expose the current quick setup fields only: QQ `App ID` / `App Secret`, WeChat `Outbound Webhook` plus inbound callback `Callback Token` / `Callback Host` / `Callback Port`.
26
+ - Keep settings stored through the existing `getExtensionSettings` / `upsertExtensionSettings` IPC path.
27
+ - Absorb immediate GUI review fixes found before push:
28
+ - expanded platform details must have a visible ownership boundary;
29
+ - the composer must not submit while an IME composition is active.
30
+
31
+ ## Not In Scope
32
+
33
+ - Remote Relay IM settings.
34
+ - Diagnostics timeline.
35
+ - Live credential validation beyond existing adapter refresh behavior.
36
+ - Account OAuth or QR login.
37
+
38
+ ## Acceptance Criteria
39
+
40
+ - The IM Settings page renders three compact platform rows.
41
+ - The first render does not expand Telegram by default.
42
+ - No single disabled platform consumes a full settings page height.
43
+ - Expanding Telegram reveals the existing credential/poll/allow-list fields.
44
+ - Expanding QQ or WeChat reveals their S0091 config fields.
45
+ - QQ and WeChat do not expose env-var-first credential fields in the default Settings flow.
46
+ - Re-clicking the expanded platform collapses details.
47
+ - Re-opening IM Settings restores the previously expanded platform when one was stored.
48
+ - Toggling a platform writes the correct extension config and refreshes local Host IM extensions.
49
+ - Direct secret fields are password inputs and are never displayed in summaries.
50
+ - Layout remains readable in narrow GUI widths.
51
+ - Expanded fields are visually grouped under the active platform, not blended into sibling platform rows.
52
+ - Pressing Enter while Chinese/Japanese/Korean IME composition is active does not submit or block candidate selection.
53
+ - Plain Enter still submits when enabled; Shift+Enter remains available for newline input.
54
+
55
+ ## Testing Requirements
56
+
57
+ - GUI render tests for compact rows and expansion.
58
+ - GUI interaction tests for default-collapsed, toggle-to-collapse, and stored expansion restore.
59
+ - GUI interaction tests for toggling and field blur persistence.
60
+ - Existing Telegram settings behavior remains covered.
61
+ - GUI composer tests cover IME composition Enter, plain Enter, and Shift+Enter.
62
+ - Full `pnpm typecheck && pnpm test`.
63
+
64
+ ## Status
65
+
66
+ Done.