mixdog 1.3.3 → 1.3.5

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 (210) hide show
  1. package/LICENSES/oh-my-pi-MIT.txt +23 -0
  2. package/NOTICE.md +15 -0
  3. package/README.md +11 -0
  4. package/package.json +3 -2
  5. package/scripts/embed-google-oauth-client.mjs +49 -0
  6. package/scripts/lib/test-spawn-ledger.mjs +46 -1
  7. package/scripts/test.mjs +5 -0
  8. package/src/defaults/shipped-history.json +8 -0
  9. package/src/defaults/skills/browser-use/SKILL.md +21 -9
  10. package/src/defaults/skills/setup/SKILL.md +7 -2
  11. package/src/defaults/skills/setup/references/actions.md +82 -27
  12. package/src/defaults/skills/setup/references/surfaces.md +67 -34
  13. package/src/defaults/skills/setup-guide/SKILL.md +3 -3
  14. package/src/lib/keychain-cjs.cjs +359 -29
  15. package/src/rules/agent-mode/AGENT_MODE.md +10 -2
  16. package/src/rules/agent-mode/MIXY.md +12 -0
  17. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +193 -0
  18. package/src/runtime/agent/orchestrator/config.mjs +18 -0
  19. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +2 -2
  20. package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
  21. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +31 -2
  22. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +16 -3
  23. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +42 -7
  24. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +21 -2
  25. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +23 -0
  26. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +11 -1
  27. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +68 -23
  28. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +22 -1
  29. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +18 -5
  30. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  31. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +15 -3
  32. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +52 -8
  33. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +10 -1
  34. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +22 -6
  35. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +15 -4
  36. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +17 -2
  37. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +19 -2
  38. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +10 -4
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +10 -217
  41. package/src/runtime/agent/orchestrator/providers/cursor.mjs +7 -0
  42. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +409 -0
  43. package/src/runtime/agent/orchestrator/providers/devin-wire-families.mjs +187 -0
  44. package/src/runtime/agent/orchestrator/providers/devin-wire-identity.mjs +342 -0
  45. package/src/runtime/agent/orchestrator/providers/devin-wire-models.mjs +541 -0
  46. package/src/runtime/agent/orchestrator/providers/devin-wire-protobuf.mjs +305 -0
  47. package/src/runtime/agent/orchestrator/providers/devin-wire-request.mjs +558 -0
  48. package/src/runtime/agent/orchestrator/providers/devin-wire-schema.mjs +880 -0
  49. package/src/runtime/agent/orchestrator/providers/devin-wire-session.mjs +190 -0
  50. package/src/runtime/agent/orchestrator/providers/devin-wire-tool-args.mjs +351 -0
  51. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +560 -0
  52. package/src/runtime/agent/orchestrator/providers/devin.mjs +491 -0
  53. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +3 -0
  54. package/src/runtime/agent/orchestrator/providers/gemini-output-limit.mjs +46 -0
  55. package/src/runtime/agent/orchestrator/providers/gemini-reasoning-relay.mjs +30 -0
  56. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +7 -11
  57. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +61 -22
  58. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -0
  59. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +71 -4
  60. package/src/runtime/agent/orchestrator/providers/gemini.mjs +25 -2
  61. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +96 -5
  63. package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +23 -5
  64. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +17 -0
  65. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +39 -3
  66. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  67. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +2 -0
  68. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +6 -1
  69. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/providers/provider-availability.mjs +19 -0
  71. package/src/runtime/agent/orchestrator/providers/registry.mjs +17 -3
  72. package/src/runtime/agent/orchestrator/providers/wire-protobuf-codec.mjs +368 -0
  73. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +2 -0
  74. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +1 -1
  75. package/src/runtime/agent/orchestrator/runtime-core/reaction-tool-defs.mjs +133 -0
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  77. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +23 -5
  78. package/src/runtime/agent/orchestrator/runtime-core/tool-profile.mjs +35 -10
  79. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +57 -10
  80. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +9 -6
  81. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  83. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +0 -3
  84. package/src/runtime/agent/orchestrator/session/agent-room.mjs +10 -4
  85. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +15 -3
  86. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +5 -0
  87. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +36 -4
  88. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +6 -0
  89. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +15 -3
  90. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +8 -0
  91. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  92. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -1
  93. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +50 -2
  94. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +3 -0
  95. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +11 -2
  96. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +11 -2
  97. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +60 -0
  98. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +2 -0
  99. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +14 -0
  100. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -1
  101. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +13 -0
  102. package/src/runtime/agent/orchestrator/session/message-ids.mjs +5 -3
  103. package/src/runtime/agent/orchestrator/session/message-reactions.mjs +89 -0
  104. package/src/runtime/agent/orchestrator/session/message-reactions.test-support.mjs +75 -0
  105. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +0 -2
  106. package/src/runtime/agent/orchestrator/session/routine-result.mjs +11 -2
  107. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +20 -2
  108. package/src/runtime/agent/orchestrator/session/store-agent-worker-header-cache.mjs +85 -0
  109. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +125 -12
  110. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +11 -5
  111. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +4 -0
  112. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +5 -0
  113. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +7 -1
  114. package/src/runtime/channels/lib/schedule-errors.mjs +51 -0
  115. package/src/runtime/channels/lib/scheduler.mjs +109 -14
  116. package/src/runtime/channels/lib/schedules-db.mjs +49 -0
  117. package/src/runtime/channels/lib/tool-dispatch.mjs +13 -0
  118. package/src/runtime/channels/lib/worker-main.mjs +9 -0
  119. package/src/runtime/office/com/com-adapter.mjs +17 -1
  120. package/src/runtime/office/com/office-com-host.ps1 +51 -1
  121. package/src/runtime/office/pdf/cfb-fixture.mjs +328 -0
  122. package/src/runtime/office/pdf/cfb-protection.mjs +311 -0
  123. package/src/runtime/office/pdf/document-preview.mjs +326 -8
  124. package/src/runtime/office/pdf/ooxml-crypto.mjs +469 -0
  125. package/src/runtime/office/pdf/ooxml-key-worker.mjs +14 -0
  126. package/src/runtime/office/portable/portable-soffice.mjs +45 -5
  127. package/src/runtime/shared/agent-room-host.mjs +1 -1
  128. package/src/runtime/shared/bot-hops.mjs +62 -2
  129. package/src/runtime/shared/config.mjs +49 -22
  130. package/src/runtime/shared/connector-catalog.d.mts +4 -2
  131. package/src/runtime/shared/connector-catalog.mjs +16 -8
  132. package/src/runtime/shared/developer-options.mjs +32 -1
  133. package/src/runtime/shared/google-oauth-client.generated.json +4 -0
  134. package/src/runtime/shared/google-oauth-client.mjs +34 -9
  135. package/src/runtime/shared/llm/anthropic-betas.mjs +7 -0
  136. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +12 -0
  137. package/src/runtime/shared/llm/provider-catalog-registry.mjs +1 -0
  138. package/src/runtime/shared/llm/usage-rollup.mjs +4 -383
  139. package/src/runtime/shared/llm/well-formed.mjs +66 -0
  140. package/src/runtime/shared/provider-accounts.mjs +224 -58
  141. package/src/runtime/shared/provider-api-key.mjs +19 -8
  142. package/src/runtime/shared/routine-trigger.mjs +42 -0
  143. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  144. package/src/runtime/shared/transcript-metadata.mjs +38 -0
  145. package/src/runtime/shared/user-data-guard.mjs +30 -2
  146. package/src/runtime/shared/worktrees/activity-gate.mjs +12 -5
  147. package/src/session-runtime/agent-home-delivery.mjs +57 -13
  148. package/src/session-runtime/agent-room-delivery.mjs +28 -1
  149. package/src/session-runtime/agent-task-sessions.mjs +292 -79
  150. package/src/session-runtime/agent-tool-routing.mjs +49 -4
  151. package/src/session-runtime/boot/begin.mjs +3 -2
  152. package/src/session-runtime/boot/tools.mjs +4 -0
  153. package/src/session-runtime/bot-chain.mjs +32 -0
  154. package/src/session-runtime/bot-status.mjs +7 -4
  155. package/src/session-runtime/channel-config-api.mjs +63 -17
  156. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +45 -0
  157. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +72 -5
  158. package/src/session-runtime/internal-tool-executor.mjs +4 -0
  159. package/src/session-runtime/mcp-glue/server-catalog.mjs +7 -1
  160. package/src/session-runtime/mixy-heartbeat.mjs +807 -0
  161. package/src/session-runtime/model-route/route-tuning.mjs +10 -6
  162. package/src/session-runtime/owned-automation-run.mjs +33 -12
  163. package/src/session-runtime/provider-auth/login.mjs +7 -0
  164. package/src/session-runtime/provider-models/row-hydration.mjs +13 -2
  165. package/src/session-runtime/routine-home-turn.mjs +33 -6
  166. package/src/session-runtime/schedule-session-run.mjs +7 -3
  167. package/src/session-runtime/services/agent-tool/close-flow.mjs +14 -2
  168. package/src/session-runtime/services/agent-tool/execute.mjs +6 -1
  169. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +11 -2
  170. package/src/session-runtime/services/agent-tool/render.mjs +3 -1
  171. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +8 -12
  172. package/src/session-runtime/services/agent-tool/tool-def.mjs +1 -1
  173. package/src/session-runtime/services/channel-admin.mjs +66 -18
  174. package/src/session-runtime/services/channel-worker.mjs +1 -1
  175. package/src/session-runtime/services/provider-admin.mjs +128 -25
  176. package/src/session-runtime/services/schedule-access.mjs +14 -0
  177. package/src/session-runtime/services/usage-dashboard-model.mjs +1 -0
  178. package/src/session-runtime/session-create/session-options.mjs +7 -4
  179. package/src/session-runtime/settings-system-api.mjs +16 -1
  180. package/src/session-runtime/setup-tool/executor.mjs +49 -14
  181. package/src/session-runtime/setup-tool/extended-actions.mjs +29 -3
  182. package/src/session-runtime/setup-tool/settings-contract.mjs +65 -4
  183. package/src/session-runtime/setup-tool/tool-defs.mjs +30 -3
  184. package/src/session-runtime/task-session-route.mjs +99 -0
  185. package/src/session-runtime/tool-policy/policy-stage.mjs +5 -2
  186. package/src/session-runtime/tool-policy/surface-helpers.mjs +2 -3
  187. package/src/session-runtime/tool-surface.mjs +4 -0
  188. package/src/session-runtime/usage-stats-api.mjs +1 -1
  189. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +98 -21
  190. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -1
  191. package/src/session-runtime/workspace/transitions.mjs +10 -2
  192. package/src/standalone/daemon-session-control.mjs +88 -20
  193. package/src/standalone/daemon.mjs +8 -0
  194. package/src/standalone/session-protocol.mjs +5 -0
  195. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +6 -2
  196. package/src/standalone/session-service/session-calls/session-turns.mjs +6 -0
  197. package/src/standalone/session-service.mjs +13 -0
  198. package/src/standalone/session-tool-output.mjs +8 -5
  199. package/src/tui/app/model-options.mjs +2 -0
  200. package/src/tui/dist/index.mjs +335 -172
  201. package/src/tui/session/notice-surface.mjs +17 -1
  202. package/src/tui/session/session-api/integrations.mjs +1 -0
  203. package/src/tui/session/session-api/lifecycle.mjs +8 -0
  204. package/src/tui/session/session-api/settings.mjs +14 -2
  205. package/src/tui/session/turn-stream.mjs +17 -1
  206. package/src/tui/session/turn.mjs +22 -2
  207. package/src/vendor/statusline/src/gateway/claude-current.mjs +0 -58
  208. package/src/vendor/statusline/src/gateway/route-meta.mjs +1 -361
  209. package/src/vendor/statusline/src/gateway/session-routes.mjs +0 -55
  210. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +0 -285
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mario Zechner
4
+ Copyright (c) 2025-2026 Can Bölük
5
+ Copyright (c) 2026 Stencil Labs, Inc.
6
+
7
+ Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ of this software and associated documentation files (the "Software"), to deal
9
+ in the Software without restriction, including without limitation the rights
10
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ copies of the Software, and to permit persons to whom the Software is
12
+ furnished to do so, subject to the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be included in all
15
+ copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ SOFTWARE.
package/NOTICE.md CHANGED
@@ -284,3 +284,18 @@ Full license text: `LICENSES/mago-MIT.txt`
284
284
  <https://github.com/posit-dev/air>
285
285
 
286
286
  Full license text: `LICENSES/air-MIT.txt`
287
+
288
+ ### oh-my-pi — MIT
289
+
290
+ <https://github.com/can1357/oh-my-pi>
291
+
292
+ The Devin provider follows its Devin integration. The model-family table in
293
+ `src/runtime/agent/orchestrator/providers/devin-wire-families.mjs` is data
294
+ taken from its model-collapse rules, and these files contain code derived from
295
+ it: `devin-wire-models.mjs` (catalog discovery and family collapsing),
296
+ `devin-wire-session.mjs` (client identity values), `devin-wire-identity.mjs`
297
+ (model classification and thinking rendering), `devin-wire-schema.mjs` (tool
298
+ schema normalization) and `devin-wire-tool-args.mjs` (tool-argument repair),
299
+ all under `src/runtime/agent/orchestrator/providers/`.
300
+
301
+ Full license text: `LICENSES/oh-my-pi-MIT.txt`
package/README.md CHANGED
@@ -26,6 +26,7 @@ https://github.com/user-attachments/assets/af515dc9-b0fb-4b6a-aaa1-1d82db792ed0
26
26
  <a href="https://github.com/tribgames/mixdog/releases/latest"><img alt="Release" src="https://img.shields.io/github/v/release/tribgames/mixdog?style=flat-square"></a>
27
27
  <a href="https://www.npmjs.com/package/mixdog"><img alt="npm" src="https://img.shields.io/npm/v/mixdog?style=flat-square"></a>
28
28
  <a href="LICENSE"><img alt="License" src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square"></a>
29
+ <a href="https://github.com/sponsors/JYP8877"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/JYP8877?style=flat-square&logo=githubsponsors&label=Sponsors"></a>
29
30
  </p>
30
31
 
31
32
  <p align="center">
@@ -174,6 +175,16 @@ Found a bug or missing a feature?
174
175
  [Open an issue](https://github.com/tribgames/mixdog/issues). If Mixdog saves
175
176
  you tokens, a star helps others find it.
176
177
 
178
+ ## Sponsor
179
+
180
+ Mixdog is free and developed by one person. Sponsorship pays for development
181
+ time and the model tokens used for testing:
182
+ [github.com/sponsors/JYP8877](https://github.com/sponsors/JYP8877).
183
+
184
+ ### Supporters
185
+
186
+ Your name here — [become a sponsor](https://github.com/sponsors/JYP8877).
187
+
177
188
  ## License
178
189
 
179
190
  Mixdog is licensed under [Apache-2.0](LICENSE). Third-party components retain
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "1.3.3",
3
+ "version": "1.3.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Open-source coding agent that matches Codex on Terminal-Bench 2.1 with 63% fewer tokens.",
@@ -153,7 +153,7 @@
153
153
  "arm64"
154
154
  ],
155
155
  "dependencies": {
156
- "@anthropic-ai/sdk": "^0.105.0",
156
+ "@anthropic-ai/sdk": "^0.135.0",
157
157
  "@formulajs/formulajs": "^4.6.1",
158
158
  "@google/generative-ai": "^0.24.1",
159
159
  "@huggingface/transformers": "^4.3.1",
@@ -181,6 +181,7 @@
181
181
  "pptxgenjs": "^4.0.1",
182
182
  "puppeteer-core": "^25.2.0",
183
183
  "react": "^19.2.7",
184
+ "saxes": "^6.0.0",
184
185
  "sharp": "^0.35.5",
185
186
  "string-width": "^8.2.1",
186
187
  "strip-ansi": "^7.2.0",
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Release packaging step: write Mixdog's Google OAuth "Desktop app" client from
4
+ // MIXDOG_GOOGLE_OAUTH_CLIENT_ID / MIXDOG_GOOGLE_OAUTH_CLIENT_SECRET (repository
5
+ // secrets) into the generated, gitignored file that googleOAuthClient() reads.
6
+ // Run it before `npm pack` and before apps/desktop `prepare:runtime`, so the
7
+ // npm package and every runtime.asar include the file.
8
+ //
9
+ // --require fail when either value is missing (release and publish jobs).
10
+ // Without it a missing value is skipped, so PR, fork and local
11
+ // builds go on without a built-in Google sign-in.
12
+ //
13
+ // The values are never printed.
14
+
15
+ import { writeFileSync } from 'node:fs';
16
+ import { pathToFileURL } from 'node:url';
17
+
18
+ import { GOOGLE_OAUTH_CLIENT_FILE } from '../src/runtime/shared/google-oauth-client.mjs';
19
+
20
+ const text = (value) => String(value || '').trim();
21
+
22
+ /** Write the client file; returns false when skipped for missing values. */
23
+ export function embedGoogleOAuthClient({ env = process.env, file = GOOGLE_OAUTH_CLIENT_FILE, required = false } = {}) {
24
+ const clientId = text(env.MIXDOG_GOOGLE_OAUTH_CLIENT_ID);
25
+ const clientSecret = text(env.MIXDOG_GOOGLE_OAUTH_CLIENT_SECRET);
26
+ if (!clientId || !clientSecret) {
27
+ if (!required) return false;
28
+ throw new Error(
29
+ 'MIXDOG_GOOGLE_OAUTH_CLIENT_ID and MIXDOG_GOOGLE_OAUTH_CLIENT_SECRET must both be set: ' +
30
+ 'a release without them ships no built-in Google sign-in. Add them as repository secrets.'
31
+ );
32
+ }
33
+ writeFileSync(file, `${JSON.stringify({ clientId, clientSecret }, null, 2)}\n`);
34
+ return true;
35
+ }
36
+
37
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
38
+ try {
39
+ const embedded = embedGoogleOAuthClient({ required: process.argv.includes('--require') });
40
+ console.log(
41
+ embedded
42
+ ? 'Embedded the Google OAuth client for this build.'
43
+ : 'No Google OAuth client configured; this build has no built-in Google sign-in.'
44
+ );
45
+ } catch (error) {
46
+ console.error(`::error title=Google OAuth client missing::${error.message}`);
47
+ process.exitCode = 1;
48
+ }
49
+ }
@@ -4,9 +4,54 @@
4
4
  // (scripts/lib/run-node-tests.mjs). Without the runner's environment it does
5
5
  // nothing.
6
6
  import { ChildProcess } from 'node:child_process';
7
- import { appendFileSync } from 'node:fs';
7
+ import { appendFileSync, readFileSync } from 'node:fs';
8
+ import { dirname, join } from 'node:path';
9
+ import { pathToFileURL } from 'node:url';
8
10
  import { FAILURE_RECORDS_ENV, spawnLedgerPath } from './test-failure-records.mjs';
9
11
 
12
+ // --test-force-exit ends a test file's process once every test registered so
13
+ // far has finished. A test registered after a top-level await that is still
14
+ // pending by then (e.g. `await import()` between tests) is never run, and the
15
+ // file would exit 0 with those tests unreported. The entry module is already
16
+ // being evaluated by the time this runs, so importing it again only observes
17
+ // it: if the process exits before its top-level evaluation completed, fail the
18
+ // file instead. Stricter on purpose: an entry whose top-level evaluation never
19
+ // completes under force-exit (e.g. an intentionally never-resolving await after
20
+ // its last test) cannot be told apart from dropped tests, so it fails too.
21
+ // Only ESM entries are observed: importing a CommonJS entry would run it a
22
+ // second time and change `require.main === module`.
23
+ const isEsmEntry = (file) => {
24
+ if (/\.(mjs|mts)$/.test(file)) return true;
25
+ if (/\.(cjs|cts)$/.test(file)) return false;
26
+ for (let dir = dirname(file); ; dir = dirname(dir)) {
27
+ try {
28
+ return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8')).type === 'module';
29
+ } catch {
30
+ // no readable package.json here: keep walking up
31
+ }
32
+ if (dirname(dir) === dir) return false;
33
+ }
34
+ };
35
+ if (
36
+ process.env.NODE_TEST_CONTEXT === 'child-v8' &&
37
+ process.execArgv.includes('--test-force-exit') &&
38
+ isEsmEntry(process.argv[1])
39
+ ) {
40
+ let settled = false;
41
+ const settle = () => {
42
+ settled = true;
43
+ };
44
+ import(pathToFileURL(process.argv[1]).href).then(settle, settle);
45
+ process.on('exit', (code) => {
46
+ if (settled) return;
47
+ console.error(
48
+ `${process.argv[1]}: the process was force-exited before the file's top-level evaluation completed (a top-level await was still pending); tests registered after it never ran, and an await that never settles is treated the same way`
49
+ );
50
+ // Never replace a failure code the file already set.
51
+ if (!code) process.exitCode = 1;
52
+ });
53
+ }
54
+
10
55
  const ledger = spawnLedgerPath(process.env[FAILURE_RECORDS_ENV]);
11
56
  if (ledger) {
12
57
  // spawn, exec, execFile and fork all start their process here.
package/scripts/test.mjs CHANGED
@@ -56,6 +56,11 @@ export const USAGE = `Usage: node scripts/test.mjs [--lane ${LANES.join('|')}] [
56
56
  Selection, lanes, reporting and exit codes are untouched.
57
57
  --list print the selected files with their lane, run nothing.
58
58
 
59
+ Test-file rule: files run with --test-force-exit, so a file's top-level
60
+ evaluation (including any top-level await) must finish before its registered
61
+ tests do. A file that is force-exited first fails — tests registered after the
62
+ await would never run, and an await that never settles cannot be told apart.
63
+
59
64
  Every run ends with a "[failure-summary]" block, printed after all other
60
65
  output, naming each failed and flaky test by file and test name; every line of
61
66
  it carries that tag, so it survives line filtering.`;
@@ -190,6 +190,7 @@
190
190
  "af1d1b975fc4b6a50f3a1775d890582f",
191
191
  "d46676d3d80327445c36e70bb291ae52",
192
192
  "dc812114c135d1d2716b219e1009e670",
193
+ "f70b87761ac6a7c6f0ef39b65b1592b3",
193
194
  "ff5607144eaf51be56217319431cb90e"
194
195
  ],
195
196
  "code-tidy": [
@@ -355,6 +356,7 @@
355
356
  "242f11864abdef90fa0cc9cb4599a579",
356
357
  "29a347c4d3a2f773fa92c627260301ba",
357
358
  "336ced846a9e4f774cbb109417856c3b",
359
+ "3716b2d2c2d973ae022694ed5cb756ad",
358
360
  "3f72247651ad9d777b6754bfd46732aa",
359
361
  "50bdf35d06913236855080fdea6b50dc",
360
362
  "5b4586a44104b26ae7dd45da101079bf",
@@ -363,13 +365,18 @@
363
365
  "6711dbc9d84023b8eabfa928b8d33d18",
364
366
  "6f9e9338f560fa9acd839a67b5e2d1cc",
365
367
  "70c54f802c77b630863b9e17a16d8224",
368
+ "7254f153fd7e492e205834bc2f2781ab",
369
+ "7c55bebd9e28dc2e03794861dde3f775",
366
370
  "81e979463e0066e7a45cf511a31c5d68",
367
371
  "8476c811b2f02da3a434bcb23a1c3d12",
368
372
  "8af2b614e2a07b58dad6c0f1318d22e2",
373
+ "99d76213e70c6900d6af48ffa4045886",
369
374
  "9f90d3872b1ecd312977ce661b770b31",
370
375
  "ade615dd0f6ae6ed1601023e5b9cb692",
371
376
  "b4f9c79dcb08151e6275b5ee35c2bca4",
377
+ "bca9732a1cecd2ce3a26e905b57d3b25",
372
378
  "c6db973f51166fc42814808ae0001797",
379
+ "c82197acd9111f4a6dcda24baccffb86",
373
380
  "c8826387a65631b63e8023f55ef807a3",
374
381
  "cb6f66d14ba75b11e7470eb3fd5ec94c",
375
382
  "de9727a48e52673258bf5f9670564d56",
@@ -383,6 +390,7 @@
383
390
  ],
384
391
  "setup-guide": [
385
392
  "633e15b84dbe22f2b578b67cc35853d4",
393
+ "72e474711ecd18cfcae6c8365e08286e",
386
394
  "920d5b29ccfe6c88f623cf0892b29285",
387
395
  "ec88a82ab5e511c0afb1738162150648"
388
396
  ],
@@ -180,6 +180,7 @@ not as two blocks joined.
180
180
  - Routing is automatic; never supply a session id.
181
181
  - A panel closed by the user stays closed until the user reopens it. Automation
182
182
  may continue on its hidden page; do not repeat `open` to override that choice.
183
+ A later user request to see the page reopens it with `open`.
183
184
 
184
185
  ## Finish or hand off
185
186
 
@@ -212,15 +213,26 @@ not as two blocks joined.
212
213
 
213
214
  ## Common flows
214
215
 
215
- **Log in** — navigate to the sign-in form (or its password step) → `fill`
216
- with `savedAccount:"<email or masked label>"` when the user has stored logins
217
- for that HTTPS site; the host fills user + password itself and the password
218
- never appears in any reply. Without a stored login, use the returned refs and
219
- `fill.fields` for user + password. Then `click` submit (or `submit:true`) with
220
- `expect.url` or `expect.text`. A `savedAccount` miss lists the site's stored
221
- logins as masked labels; the user chooses which to use. If the page shows a
222
- CAPTCHA, 2FA prompt, or identity check, stop and hand control to the user;
223
- never try to solve or bypass it.
216
+ **Log in** — navigate to the sign-in form (or its password step). When the
217
+ user has exactly one stored login for that HTTPS site, the host signs in by
218
+ itself right after the command that shows the form: it waits for the page's
219
+ human check (Turnstile, reCAPTCHA, hCaptcha) to hold its token, fills user +
220
+ password, submits, and replies with one line — `Saved sign-in: signed in to
221
+ <site>` (done: verify with the returned page, do not fill or submit again) or
222
+ `Saved sign-in: the site still needs the user at <site>` (a check that did not
223
+ finish, a code, CAPTCHA, passkey, or an error: hand the sign-in to the user,
224
+ do not retry). It tries once per site per turn, and the password never
225
+ appears in any reply. When the host did not sign in by itself (several
226
+ stored logins, or automatic sign-in did not run), call `fill` with
227
+ `savedAccount:"<email or masked label>"` (and `submit:true` to sign in). Do
228
+ not press Enter or click submit yourself after a `savedAccount` fill that
229
+ already used `submit:true`. A
230
+ `savedAccount` miss lists the site's stored logins as masked labels; the user
231
+ chooses which to use. Without a stored login, use the returned refs and
232
+ `fill.fields` for user + password, then `click` submit (or `submit:true`) with
233
+ `expect.url` or `expect.text`. If the page shows a CAPTCHA, 2FA prompt, or
234
+ identity check, stop and hand control to the user; never try to solve or
235
+ bypass it.
224
236
 
225
237
  **Form** — use the latest returned refs → `fill.fields` (text, `values` for selects, `checked`
226
238
  for boxes) → submit via `click` or `fill` with `submit:true` → verify with
@@ -20,10 +20,15 @@ supported `setup` action, and read its result as the change receipt.
20
20
 
21
21
  - Use the `setup` tool for persisted Mixdog configuration. Never edit
22
22
  `mixdog-config.json` or internal stores directly; if the tool and UI expose no
23
- supported path, report that limitation.
23
+ supported path, report that limitation. The one exception is the definition
24
+ file a workflow or agent `read_definition` returns as `path`.
24
25
  - API keys, OAuth credentials, tokens, and usage sign-ins stay out of tool
25
26
  arguments and the transcript. Open the Providers surface and let the user
26
27
  enter them.
28
+ - Developer option "Allow all actions" (`allowAllActions`) can only be turned
29
+ on by the person in the desktop app; the tool refuses it even with
30
+ `riskAccepted:true`, and remote enablement is refused too. Open `developer`
31
+ instead.
27
32
  - A mutation follows the active workflow's approval rules. Status, catalog,
28
33
  definition and MCP-config reads do not change persisted settings.
29
34
  - Most changes affect new sessions. Report `appliedToCurrentSession` and
@@ -70,7 +75,7 @@ that a call returned without transport error.
70
75
  background cycles. Core Memory entries
71
76
  are read and changed with the `memory` tool, not setup.
72
77
  - Built-ins have installation state separate from enabled state; Visualize
73
- is toggle-only (on by default, no install step). Browser Use,
78
+ (on by default) and Media generation are toggle-only (no install step). Browser Use,
74
79
  Computer Use actions require this conversation open in the local Desktop
75
80
  window; voice runs on the runtime and needs no Desktop.
76
81
  - Hook rules are before-tool policy, separate from MCP and plugins. Deleting a
@@ -24,18 +24,21 @@ Read this when choosing a `setup` mutation.
24
24
  |---|---|
25
25
  | Main model route | `set_route` |
26
26
  | Agent-specific route or inheritance | `set_agent_route` |
27
- | Web Search model route | `set_web_search_route` |
27
+ | Web Search model route (and its `route.fallbacks`) | `set_web_search_route` |
28
28
  | Active workflow pack | `set_workflow` |
29
29
  | Output style | `set_output_style` |
30
30
  | User title, language, or experience level | `set_profile` |
31
31
  | Idle session clearing, per provider, including `unlimited` | `set_autoclear` |
32
- | Automatic context compaction | `set_compaction` |
32
+ | Automatic context compaction, compaction on model change, summary model | `set_compaction` |
33
+ | Context → Let AI rename sessions | `set_ai_session_titles` |
34
+ | Providers → Usage limits → Resume automatically when the limit resets | `set_quota_auto_resume` |
35
+ | Model management: "Show in /model" and favorites, per provider model | `set_model_preferences` |
33
36
  | Memory capability | `set_memory_enabled` |
34
37
  | Background memory cycles | `set_recap_enabled` |
35
38
  | Web Search tool exposure | `set_web_search_enabled` |
36
39
  | Which user instruction files (AGENTS.md / CLAUDE.md) new sessions load: all, agents, claude, or off | `set_instruction_files` |
37
40
  | The reasoning effort Auto works around: low, medium (default), or high | `set_auto_effort_base` |
38
- | Git, Office, Code Tidy, Local Provider, Auto Effort, Browser, Computer, voice, or Visualize enabled state | `set_builtin_enabled` |
41
+ | Git, Office, Code Tidy, Local Provider, Auto Effort, Browser, Computer, voice, Visualize, or Media generation enabled state | `set_builtin_enabled` |
39
42
  | Git, Memory, Office, Code Tidy, Local Provider, Auto Effort, Browser, Computer, or voice preparation | `install_builtin` |
40
43
  | Managed local model installation | `install_local_model` |
41
44
  | Start or resume a background runtime/model download | `start_local_installation` |
@@ -49,11 +52,13 @@ Read this when choosing a `setup` mutation.
49
52
  | Permanently delete confirmed, unchanged, unused model files | `delete_local_model` |
50
53
  | TUI system shell | `set_system_shell` |
51
54
  | Automatic updates | `set_auto_update` |
55
+ | Mixy's heartbeat: a check every 30 minutes that wakes her only when something needs attention (on by default; `status features` reports `heartbeat.enabled`) | `set_heartbeat_enabled` |
56
+ | Bots' emoji reactions on the user's messages (on by default; `status features` reports `reactions.enabled`) | `set_reactions_enabled` |
52
57
  | Worktree defaults: new tasks on the current branch or a new worktree, branch prefix, large-repository warning size, automatic cleanup | `set_worktree_settings` |
53
- | Remove stored provider authentication (one OAuth account at a time) | `forget_provider_auth` |
54
- | Select, rename, or reorder OAuth accounts, set the switching policy, or allow paid credits | `set_provider_account` |
55
- | Developer options such as risk-gated OAuth providers | `set_developer_option` |
56
- | Connect a catalog service (Notion, Linear, Gmail, …; not GitHub, which is the GitHub CLI) for the user: shows a one-click connect card | `connect_connector` |
58
+ | Remove stored provider authentication (one OAuth account at a time, or an API-key provider's key) | `forget_provider_auth` |
59
+ | Select, rename, or reorder OAuth accounts, set automatic switching or the switching policy, or allow paid credits | `set_provider_account` |
60
+ | Developer options (approvals, risk-gated providers); `allowAllActions` can only be turned off | `set_developer_option` |
61
+ | Connect a catalog service (Notion, Linear, Gmail, …; not GitHub, which is the GitHub CLI) for the user: shows a connect card (sign-in, key sheet, or app-password dialog) | `connect_connector` |
57
62
  | Add an MCP server | `add_mcp_server` |
58
63
  | Edit or rename an MCP server | `save_mcp_server` |
59
64
  | Remove an MCP server | `remove_mcp_server` |
@@ -78,12 +83,12 @@ Read this when choosing a `setup` mutation.
78
83
  | Enable/disable (pause/resume) a schedule/webhook | `set_automation_enabled` |
79
84
  | Run a schedule once now, or re-run a webhook on its latest received payload; the result posts into the owning agent's thread | `run_automation` |
80
85
  | Webhook listener enabled state, port, or domain | `set_webhook_config` |
81
- | Desktop keep-awake, run in background after window close, turn-completion notifications, notification volume (Windows), usage pin, usage rail short + long bars, or Computer observe-only state | `set_desktop_settings` |
82
- | Desktop theme, imported color theme, UI/code font, skin transparency (outer or main panels), display language, side panels, markdown default view, link previews, or tool activity expansion | `set_appearance` |
86
+ | Desktop keep-awake, run in background after window close, turn-completion notifications, notification volume (Windows), usage pin, usage rail short + long bars, expanded usage accounts, usage rail slots (three / all), Computer observe-only, Browser auto sign-in, or the representative bot overlay (`desktop.botOverlay`) | `set_desktop_settings` |
87
+ | Desktop theme, imported color theme, UI/code font, UI scale, code size and ligatures, chat text size, skin transparency (outer or main panels), display language, time format, side panels and their position, markdown default view, link previews, or tool activity expansion | `set_appearance` |
83
88
  | Add a before-tool hook rule | `add_hook_rule` |
84
89
  | Enable or disable a hook rule by its `status hooks` index | `set_hook_rule_enabled` |
85
90
  | Delete a hook rule by its `status hooks` index | `delete_hook_rule` |
86
- | Remembered image/video lane and model used when a generation omits them | `set_media_default` |
91
+ | Settings "Default generator" pin per kind (image/video): lane, model, account; `lane: ""` clears it (Auto) | `set_media_default` |
87
92
  | Which activity rail items are pinned, in order (current list in `status desktop`) | `set_activity_rail_pins` |
88
93
  | Register a Project and optionally set its display alias | `save_project` |
89
94
  | Unregister a Project without deleting its files | `remove_project` |
@@ -108,6 +113,11 @@ workflow` before changing the corresponding domain.
108
113
  - A Web Search route must support native web search; tool exposure is changed
109
114
  separately.
110
115
  - Definition actions use `definitionKind` (workflow, agent, skill).
116
+ A workflow or agent `read_definition` returns `path` when a user copy exists:
117
+ to change part of its body, edit that file with the ordinary file edit tool
118
+ instead of re-sending the whole body; keep its frontmatter as it is. Without
119
+ `path` (a shipped-only definition), make the change with `save_definition`:
120
+ a save equal to the shipped copy keeps no user file.
111
121
  Workflow/agent ids cannot be renamed through
112
122
  a save; change their display name instead. User skills may be renamed with
113
123
  `originalName` and `name`. A user skill's trigger line (`when_to_use`) is
@@ -122,7 +132,9 @@ workflow` before changing the corresponding domain.
122
132
  - `set_route` is the Lead default for new sessions. A model chosen in New Task
123
133
  changes that default only when the user actually picks one there.
124
134
  `route.fallbacks` (ordered models on other providers; `[]` clears) works the
125
- same on `set_route` (Lead), `set_agent_route` (agents and bots, Mixy included).
135
+ same on `set_route` (Lead), `set_agent_route` (agents and bots, Mixy included)
136
+ and `set_web_search_route`. `status model` returns `route.autoEffort` and
137
+ `route.fallbacks`.
126
138
  - A workflow switch reaches a running conversation as a reminder on its next
127
139
  turn (the cached prompt is not swapped). A bot definition's instruction,
128
140
  persona or name applies when the user presses 적용, with one cache break.
@@ -138,7 +150,21 @@ key's source.
138
150
 
139
151
  - API-key and OAuth providers: `open providers`, then the user completes
140
152
  authentication in the visible UI.
141
- - Custom providers are registered, tested, and removed in the Providers UI;
153
+ - An SSH server's models run on this PC's logins by default. A server can use
154
+ its own instead (Settings → Connection → the server → Model login → Server
155
+ accounts); its logins are then managed in "Manage server logins" (a
156
+ subscription login opens in this PC's browser; an API key is stored on the
157
+ server, in an owner-only private file where it has no keychain, as on
158
+ Linux). No setup action exists for this. Changing the model login restarts
159
+ the server's Mixdog and stops its running sessions, so say so before the
160
+ user confirms. The login key file (Advanced options of the connect dialog,
161
+ or the server's settings) is also UI-only; it applies to every connection
162
+ to that server. The connect dialog refuses a different key or folder for a
163
+ server that is connected already (disconnect first); the server's own
164
+ settings accept and save a changed key file while connected, and it applies
165
+ from the next connection.
166
+ - Custom providers are registered, edited (non-secret fields too), tested, and
167
+ removed in the Providers UI; no setup action exists yet;
142
168
  `status providers` with `detail: true` lists them as API rows with `custom: true`.
143
169
  Their model list (Nano-GPT included) loads there with up to a 60 s wait; the
144
170
  user can skip it and type model ids by hand.
@@ -148,9 +174,11 @@ key's source.
148
174
  and recovery. Its narrow status domain exposes installed models and progress;
149
175
  the detail dialog lists installed models rather than the download catalog.
150
176
  - Forgetting authentication is destructive and requires explicit approval.
151
- It removes one OAuth account; a provider with several accounts requires
152
- `accountId` from the account list in `status providers` with `detail: true`.
153
- - `set_provider_account` changes the selected account, paid-credit use after
177
+ It removes one OAuth account (a provider with several accounts requires
178
+ `accountId` from the account list in `status providers` with `detail: true`)
179
+ or an API-key provider's key (no `accountId`).
180
+ - `set_provider_account` changes the selected account, automatic switching
181
+ when one is exhausted (`auto`), paid-credit use after
154
182
  plan limits (`useCredits`), account order (every account id exactly once),
155
183
  an account label, or the switching `policy`: `manual` stays on the selected
156
184
  account, `limit` switches when it hits a limit, `headroom` starts each new
@@ -159,7 +187,14 @@ key's source.
159
187
  happens in the Providers UI.
160
188
  - `status developer` lists developer options. An option with a `warning` is
161
189
  enabled only after the user explicitly accepts that warning, passed as
162
- `riskAccepted:true`; never assume acceptance.
190
+ `riskAccepted:true`; never assume acceptance. `allowAllActions` ("Allow all
191
+ actions") can be turned off here, but turning it on is refused even then:
192
+ only the person turns it on, so `open developer`.
193
+ - `set_quota_auto_resume` is read back as `quotaAutoResume` in `status
194
+ providers`; turning it off cancels pending resumes.
195
+ - `set_model_preferences` (`hidden`, `favorite`; omitted = unchanged) matches
196
+ Model management. `list_models` rows show `hidden` / `favorite`; a hidden
197
+ custom-provider model no longer appears in `list_models`.
163
198
 
164
199
  ## Profile, session, and Memory
165
200
 
@@ -184,7 +219,11 @@ key's source.
184
219
  window, e.g. DeepSeek 24h; 1h for Codex/ChatGPT logins); unlimited does not
185
220
  disable it.
186
221
  - Compaction supports `enabled` and a `compaction` object with either
187
- `mainBufferTokens` or `mainBufferPercent`. Changing representation replaces the previous budget.
222
+ `mainBufferTokens` or `mainBufferPercent` (changing representation replaces
223
+ the previous budget), `onModelChange` (compact before switching models) and
224
+ `summaryMode`: `smart`, `maintainer`, or `self` (Conversation model).
225
+ `status compaction` returns them plus `aiSessionTitles`
226
+ (`set_ai_session_titles`).
188
227
  - If no supported action exposes a requested Memory interval, report it as
189
228
  unavailable rather than editing configuration.
190
229
 
@@ -209,8 +248,8 @@ markers are read with `status desktop`.
209
248
  reasoning effort with a local judge model downloaded in the background.
210
249
  Enabling or installing it fails on unsupported machines; `status features`
211
250
  reports `supported`, `installing` (judge download running) and `ready`.
212
- - Visualize is toggle-only through `set_builtin_enabled` (on by default);
213
- `install_builtin` does not accept it.
251
+ - Visualize (on by default) and Media generation are toggle-only through
252
+ `set_builtin_enabled`; `install_builtin` does not accept them.
214
253
  - Terminal follows the live Desktop terminal bridge and has no toggle.
215
254
  - Environment feature overrides (`MIXDOG_FEATURE_*`) win over these toggles;
216
255
  they are diagnostics for headless or benchmark environments, not user
@@ -237,9 +276,13 @@ markers are read with `status desktop`.
237
276
  named rule; disabling with `set_hook_rule_enabled` preserves it.
238
277
  - Hook rule changes apply to open sessions and their sub-agents on the next
239
278
  tool call; no new session or restart is needed.
240
- - `status media` shows the remembered lane/model per kind. `set_media_default`
241
- accepts only a signed-in lane that offers the kind (and the model, when
242
- given) in the live media catalog; the media tool's `list` reads that catalog.
279
+ - `status media` returns `pinned` and `remembered` ({image, video} each). The
280
+ pin is the Settings "Default generator"; the remembered entry is the last-used
281
+ generator, and the pin wins over it. A generation naming no lane/model uses
282
+ the pin, else the remembered one. `set_media_default` takes
283
+ `{kind, lane, model?, accountId?}` and accepts only a signed-in lane that
284
+ offers the kind (and the model, when given) in the live media catalog; the
285
+ media tool's `list` reads that catalog. `lane: ""` clears the pin (Auto).
243
286
 
244
287
  ## Skills, MCP, and plugins
245
288
 
@@ -272,8 +315,8 @@ markers are read with `status desktop`.
272
315
  `declarationErrors` and `warnings`.
273
316
  - `connect_connector` is how to connect a catalog service the user asks for
274
317
  ("Slack 연결해 줘"): it leaves a connect card in the conversation whose
275
- press runs the browser sign-in (or the key sheet) in Desktop; nothing
276
- connects until the user presses it, so tell them to press the card and read
318
+ press runs the service's sign-in, key sheet or (Gmail: app password only)
319
+ dialog in Desktop; nothing connects until the user presses it, so tell them to press the card and read
277
320
  `status mcp` afterwards. `add_mcp_server` with the service URL is not the
278
321
  sign-in flow; never use it for a catalog service.
279
322
  - `enable_plugin_mcp` turns every server the plugin declares back on and
@@ -285,7 +328,9 @@ markers are read with `status desktop`.
285
328
  - `status capabilities` lists supported actions and deliberate handoffs.
286
329
  - Desktop-only operations require the owning conversation visible in the local
287
330
  Desktop app. Never claim a persisted change from merely delivering a request.
288
- - A display-language change returns `requiresReload`.
331
+ - A display-language change returns `requiresReload`; so does a changed
332
+ `timeFormat` (already-shown times update after the window reloads, which is
333
+ never automatic).
289
334
  - `set_appearance` also takes `uiFont` / `codeFont` (a family name, `""` =
290
335
  built-in; text it lacks falls back to the built-in fonts), skin transparency
291
336
  (0–100, defaults outer 20 / main 40; higher shows more of the skin picture):
@@ -293,8 +338,18 @@ markers are read with `status desktop`.
293
338
  `skinMainTransparency` (conversation area and its cards), or `skinTransparency`
294
339
  to set both; and `colorTheme`
295
340
  (an imported theme id from `status appearance` `colorThemes`, or `"builtin"`).
296
- All are stored on that Desktop device only. Importing a theme file and
297
- choosing a skin or custom picture stay in the UI.
341
+ Also `timeFormat` (system|12h|24h), `sidePanelPosition` (right|bottom|auto),
342
+ `uiScale` (0.85–1.2, step 0.05), `codeSize` (10–20), `codeLigatures`
343
+ (bool) and `chatTextSize` (small|default|large|extra-large). The UI label
344
+ "Light" is `theme: "white"`.
345
+ Importing, exporting or removing a theme file and choosing a skin picture
346
+ or its plate/accent/photo stay in the UI.
347
+ - `set_desktop_settings` `desktop.botOverlay` takes `enabled`, `position`
348
+ (`pinned` above the message box, `pinnedHere`, `free` in the app window,
349
+ `onScreen` free on screen), `keepAbove`, `collapsed`, `autoAdvance`,
350
+ `autoClose` and `scale` (50–200, step 10). Enabling needs the
351
+ representative bot; `status desktop` returns `botOverlay`. Reset position
352
+ stays in the UI.
298
353
  - A Project removal unregisters it only.
299
354
  - Inspect schedules/webhooks before editing. `overwrite:true` updates an
300
355
  existing named entry and preserves omitted fields; a new schedule needs