mixdog 0.9.151 → 0.9.152

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 (175) hide show
  1. package/README.md +110 -68
  2. package/package.json +3 -2
  3. package/scripts/tool-stress.mjs +0 -2
  4. package/src/defaults/skills/setup/SKILL.md +18 -27
  5. package/src/headless-exec.mjs +3 -10
  6. package/src/headless-exec.test.mjs +2 -7
  7. package/src/runtime/agent/orchestrator/config.mjs +6 -66
  8. package/src/runtime/agent/orchestrator/context/collect-skills.test.mjs +153 -0
  9. package/src/runtime/agent/orchestrator/context/collect.mjs +49 -45
  10. package/src/runtime/agent/orchestrator/mcp/client.mjs +242 -15
  11. package/src/runtime/agent/orchestrator/mcp/features.test.mjs +66 -0
  12. package/src/runtime/agent/orchestrator/mcp/security.test.mjs +36 -20
  13. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +54 -33
  14. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +1 -0
  15. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  16. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +7 -0
  17. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +3 -8
  18. package/src/runtime/agent/orchestrator/providers/gemini.mjs +7 -0
  19. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +10 -2
  20. package/src/runtime/agent/orchestrator/providers/lib/provider-replay.mjs +50 -0
  21. package/src/runtime/agent/orchestrator/providers/lib/sse-framing.mjs +93 -0
  22. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +3 -3
  23. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +8 -0
  24. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -0
  25. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +25 -2
  26. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +35 -4
  27. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +22 -0
  28. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -2
  29. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +13 -0
  30. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +4 -7
  31. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +9 -0
  32. package/src/runtime/agent/orchestrator/providers/provider-replay.test.mjs +235 -0
  33. package/src/runtime/agent/orchestrator/providers/sse-framing.test.mjs +719 -0
  34. package/src/runtime/agent/orchestrator/providers/stream-json-pool.mjs +399 -39
  35. package/src/runtime/agent/orchestrator/providers/stream-json-worker.mjs +26 -0
  36. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +14 -4
  37. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +13 -0
  38. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +24 -1
  39. package/src/runtime/agent/orchestrator/session/compaction-read-reset.test.mjs +161 -0
  40. package/src/runtime/agent/orchestrator/session/context-utils.mjs +14 -4
  41. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +2 -2
  42. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +12 -1
  43. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +31 -18
  44. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +2 -0
  45. package/src/runtime/agent/orchestrator/session/manager/message-sanitize.mjs +3 -0
  46. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +6 -1
  47. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +1 -3
  48. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +556 -0
  49. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.test.mjs +457 -0
  50. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +105 -186
  51. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +115 -0
  52. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +2 -0
  53. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +7 -0
  54. package/src/runtime/agent/orchestrator/session/store.mjs +23 -1
  55. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool-cwd-env.test.mjs +14 -0
  56. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -10
  57. package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +30 -14
  58. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +15 -4
  59. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +73 -15
  60. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +76 -2
  61. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +24 -683
  62. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +64 -72
  63. package/src/runtime/agent/orchestrator/tools/builtin/native-search-runner.mjs +2 -5
  64. package/src/runtime/agent/orchestrator/tools/builtin/native-search-transport.mjs +75 -0
  65. package/src/runtime/agent/orchestrator/tools/builtin/native-search-transport.test.mjs +24 -0
  66. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +12 -0
  67. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +24 -5
  69. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.test.mjs +44 -0
  70. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +12 -2
  71. package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +35 -21
  72. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +28 -13
  73. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.test.mjs +54 -0
  74. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +11 -11
  75. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
  76. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +8 -0
  77. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +11 -11
  78. package/src/runtime/browser-bridge/client.mjs +103 -0
  79. package/src/runtime/browser-bridge/tool-defs.mjs +42 -0
  80. package/src/runtime/computer-bridge/client.mjs +101 -0
  81. package/src/runtime/computer-bridge/tool-defs.mjs +53 -0
  82. package/src/runtime/media/store.mjs +18 -8
  83. package/src/runtime/media/store.test.mjs +14 -0
  84. package/src/runtime/memory/index.mjs +1 -1
  85. package/src/runtime/memory/lib/transcript-ingest.mjs +8 -6
  86. package/src/runtime/memory/lib/transcript-ingest.test.mjs +52 -0
  87. package/src/runtime/shared/child-spawn-gate.mjs +17 -0
  88. package/src/runtime/shared/child-spawn-remote.mjs +69 -7
  89. package/src/runtime/shared/child-spawn-remote.test.mjs +124 -0
  90. package/src/runtime/shared/pristine-execution-contract.json +2 -1
  91. package/src/runtime/shared/provider-api-key.mjs +1 -0
  92. package/src/runtime/shared/session-runtime-health.mjs +91 -0
  93. package/src/runtime/shared/session-runtime-health.test.mjs +53 -0
  94. package/src/runtime/shared/skill-document.mjs +86 -0
  95. package/src/runtime/shared/skill-document.test.mjs +81 -0
  96. package/src/runtime/shared/tool-surface.mjs +18 -0
  97. package/src/runtime/shared/turn-snapshot-store.mjs +1 -0
  98. package/src/runtime/shared/turn-snapshot.mjs +32 -9
  99. package/src/runtime/shared/user-cwd.mjs +33 -14
  100. package/src/runtime/shared/user-cwd.test.mjs +43 -0
  101. package/src/session-runtime/cwd-plugins.mjs +26 -26
  102. package/src/session-runtime/cwd-plugins.test.mjs +75 -0
  103. package/src/session-runtime/cwd-tool-routing.test.mjs +5 -0
  104. package/src/session-runtime/global-extensions.mjs +26 -0
  105. package/src/session-runtime/global-extensions.test.mjs +28 -0
  106. package/src/session-runtime/goal-runtime.mjs +721 -0
  107. package/src/session-runtime/goal-runtime.test.mjs +108 -0
  108. package/src/session-runtime/lifecycle-api.mjs +18 -4
  109. package/src/session-runtime/lifecycle-api.test.mjs +21 -0
  110. package/src/session-runtime/mcp-glue.mjs +49 -47
  111. package/src/session-runtime/plugin-mcp-standard.test.mjs +177 -0
  112. package/src/session-runtime/plugin-mcp.mjs +96 -22
  113. package/src/session-runtime/prewarm.mjs +1 -10
  114. package/src/session-runtime/resource-api-global.test.mjs +69 -0
  115. package/src/session-runtime/resource-api.mjs +173 -58
  116. package/src/session-runtime/runtime-core.mjs +148 -20
  117. package/src/session-runtime/runtime-tunables.mjs +6 -8
  118. package/src/session-runtime/session-turn-api.mjs +22 -11
  119. package/src/session-runtime/skills-api.mjs +79 -25
  120. package/src/session-runtime/skills-api.test.mjs +99 -0
  121. package/src/session-runtime/tool-catalog-schema.mjs +0 -5
  122. package/src/session-runtime/tool-catalog.mjs +4 -13
  123. package/src/session-runtime/tool-policy-surface.test.mjs +33 -11
  124. package/src/session-runtime/tool-surface.mjs +12 -0
  125. package/src/standalone/agent-dispatch-broker.mjs +5 -9
  126. package/src/standalone/agent-tool/notify.mjs +6 -8
  127. package/src/standalone/agent-tool/notify.test.mjs +37 -0
  128. package/src/standalone/daemon.mjs +31 -15
  129. package/src/standalone/hook-bus/config.mjs +1 -0
  130. package/src/standalone/plugin-admin.mjs +17 -0
  131. package/src/standalone/plugin-admin.test.mjs +7 -0
  132. package/src/standalone/provider-admin.mjs +1 -0
  133. package/src/standalone/session-protocol.mjs +5 -0
  134. package/src/standalone/session-runtime-agent-control-client.mjs +133 -0
  135. package/src/standalone/session-runtime-agent-control-client.test.mjs +71 -0
  136. package/src/standalone/session-runtime-dispatch-cancel.test.mjs +139 -0
  137. package/src/standalone/session-runtime-host-factory.mjs +17 -0
  138. package/src/standalone/session-runtime-host-factory.test.mjs +31 -0
  139. package/src/standalone/session-runtime-host-health.test.mjs +5 -0
  140. package/src/standalone/session-runtime-host.mjs +696 -58
  141. package/src/standalone/session-runtime-inline-host.mjs +351 -0
  142. package/src/standalone/session-runtime-inline-host.test.mjs +83 -0
  143. package/src/standalone/session-runtime-provider-cooldown.mjs +78 -0
  144. package/src/standalone/session-runtime-provider-cooldown.test.mjs +80 -0
  145. package/src/standalone/session-runtime-shard-host.test.mjs +569 -0
  146. package/src/standalone/session-runtime-shard-router.mjs +149 -0
  147. package/src/standalone/session-runtime-shard-router.test.mjs +101 -0
  148. package/src/standalone/session-runtime-worker.mjs +476 -18
  149. package/src/standalone/session-service.mjs +81 -6
  150. package/src/tui/app/app-view.jsx +1 -0
  151. package/src/tui/app/core-memory-picker.mjs +2 -0
  152. package/src/tui/app/extension-pickers.mjs +1 -1
  153. package/src/tui/app/maintenance-pickers.mjs +3 -3
  154. package/src/tui/app/model-options.mjs +2 -0
  155. package/src/tui/app/model-picker.mjs +14 -4
  156. package/src/tui/app/panel-handoff.test.mjs +311 -0
  157. package/src/tui/app/project-picker.mjs +1 -0
  158. package/src/tui/app/route-pickers.mjs +21 -6
  159. package/src/tui/app/settings-picker.mjs +26 -3
  160. package/src/tui/app/slash-commands.mjs +1 -0
  161. package/src/tui/app/slash-dispatch.mjs +73 -22
  162. package/src/tui/app/theme-effort-pickers.mjs +7 -2
  163. package/src/tui/components/Picker.jsx +10 -1
  164. package/src/tui/dist/index.mjs +163 -44
  165. package/src/tui/session/context-state.mjs +1 -0
  166. package/src/tui/session/goal-continuation.mjs +110 -0
  167. package/src/tui/session/goal-continuation.test.mjs +84 -0
  168. package/src/tui/session/queue-helpers.mjs +5 -2
  169. package/src/tui/session/session-action-surface.test.mjs +108 -0
  170. package/src/tui/session/session-api-ext.mjs +39 -8
  171. package/src/tui/session/session-api.mjs +58 -0
  172. package/src/tui/session/session-flow.mjs +6 -0
  173. package/src/tui/session/turn.mjs +1 -0
  174. package/src/tui/session-local.mjs +15 -1
  175. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -301
package/README.md CHANGED
@@ -1,20 +1,35 @@
1
- # mixdog
1
+ # Mixdog
2
2
 
3
3
  [![npm](https://img.shields.io/npm/v/mixdog)](https://www.npmjs.com/package/mixdog)
4
4
  ![node](https://img.shields.io/badge/node-%3E%3D22-brightgreen)
5
5
  ![license](https://img.shields.io/badge/license-MIT-blue)
6
6
 
7
- Mixdog is a standalone coding agent for orchestrated, multi-provider workflows.
8
- Use it from a full-screen terminal UI or the Windows desktop app.
7
+ ## Better results. Less cost. More work.
8
+
9
+ Mixdog is an efficiency-first AI coding harness designed to deliver equal or
10
+ better performance with less context, time, and cost—so you can complete more
11
+ work within the same API budget or subscription quota.
12
+
13
+ With simple setup and an intuitive UX, Mixdog makes powerful orchestration,
14
+ parallel tasks, and seamless work across terminal, desktop, and web accessible
15
+ to everyone—from beginners to experts.
16
+
17
+ **The easiest way to get more out of every coding model.**
9
18
 
10
19
  ## Get started
11
20
 
12
- ### Windows desktop
21
+ ### Desktop
13
22
 
14
- [Download Mixdog Desktop for Windows (x64)](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-win-x64.exe)
23
+ | Platform | Download |
24
+ | --- | --- |
25
+ | Windows x64 | [Installer](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-win-x64.exe) |
26
+ | macOS Apple silicon | [DMG](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-mac-arm64.dmg) |
27
+ | macOS Intel | [DMG](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-mac-x64.dmg) |
28
+ | Linux x86_64 | [AppImage](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-linux-x86_64.AppImage) |
29
+ | Linux arm64 | [AppImage](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-linux-arm64.AppImage) |
15
30
 
16
- The desktop package is currently unsigned, so Windows SmartScreen may show a
17
- security warning during installation.
31
+ Desktop packages are currently unsigned, so Windows SmartScreen or macOS
32
+ Gatekeeper may show a security warning.
18
33
 
19
34
  ### CLI
20
35
 
@@ -28,28 +43,68 @@ mixdog
28
43
  First run guides you through provider authentication, model selection, and
29
44
  workflow setup.
30
45
 
46
+ ## Benchmarks
47
+
48
+ Terminal-Bench 2.1 — same model, same 89 tasks, same official verifier, with
49
+ only the harness changed. Against the native CLI of each model family, Mixdog
50
+ scores higher while spending less to get there.
51
+
52
+ ### GPT-5.6 Sol xhigh — Mixdog vs Codex CLI
53
+
54
+ ![Terminal-Bench 2.1: Mixdog with GPT-5.6 Sol xhigh versus Codex CLI](https://raw.githubusercontent.com/tribgames/mixdog/main/benchmarks/terminal-bench-2.1/tb21-sol-vs-codex.svg)
55
+
56
+ - **86.5%** (385/445) vs Codex CLI's **84.3%** (75/89)
57
+ - **42%** lower priced cost — $0.641 vs $1.096 per trial
58
+ - **45%** smaller median final context — 18.5k vs 33.5k tokens
59
+ - **1.11×** faster — 339s vs 378s per trial
60
+
61
+ ### Claude Opus 5 — Mixdog vs Claude Code
62
+
63
+ ![Terminal-Bench 2.1: Mixdog with Claude Opus 5 versus Claude Code](https://raw.githubusercontent.com/tribgames/mixdog/main/benchmarks/terminal-bench-2.1/tb21-opus-vs-claude-code.svg)
64
+
65
+ - **79/89** vs Claude Code's **77/89**
66
+ - **19%** lower priced cost — $104.29 vs $129.21 per run
67
+ - **28%** smaller median final context — 27.6k vs 38.2k tokens
68
+ - **1.15×** faster
69
+
70
+ Every run uses the official Harbor verifier, fast mode off, a 272k context
71
+ window, and zero retries. The Mixdog Sol run follows the protocol the official
72
+ Terminal-Bench leaderboard requires — all 89 tasks repeated five times (`k=5`,
73
+ 445 trials); the Codex CLI baseline and both Opus-side runs are single passes
74
+ (`k=1`, 89 trials each).
75
+
76
+ The leaderboard is not accepting community submissions, so every run here ships
77
+ its raw artifacts instead — Harbor verdicts, official verifier output, pinned
78
+ task checksums, and the usage snapshots behind every cost figure — alongside
79
+ the harness, presets, and metric scripts that recompute each number above:
80
+ [`benchmarks/terminal-bench-2.1/`](benchmarks/terminal-bench-2.1/).
81
+
31
82
  ## Highlights
32
83
 
33
84
  - **Multi-provider routing** — assign different providers and models by role.
85
+ - **Shared live sessions** — move between the TUI, desktop windows, and paired
86
+ browsers without starting a second copy of the session.
34
87
  - **Efficient context** — cache-aware prompts, compaction, resumable sessions,
35
88
  and focused repo-native tools.
36
89
  - **Complete coding surface** — read, search, edit, test, review, web search,
37
90
  MCP, skills, hooks, and plugins.
38
91
  - **Local memory** — semantic and lexical recall with project-scoped context
39
92
  and multilingual retrieval.
40
- - **Remote workflows** — optional web relay, Discord, Telegram, voice, and cron
41
- schedules.
42
- - **Windows desktop app** — agent panes, Monaco editor, git, terminal, file
43
- explorer, Studio, automation, and settings in one workbench.
93
+ - **Encrypted remote access** — pair the installable web app with Desktop and
94
+ use Mixdog from a browser or phone over authenticated E2EE.
95
+ - **Desktop coding app** — agent panes, Monaco editor, Git, terminals, file
96
+ explorer, Studio, automation, voice input, and settings in one app.
44
97
 
45
98
  ## Providers
46
99
 
47
100
  Mixdog supports subscription OAuth and API-key routes, including:
48
101
 
49
- - Anthropic and Claude accounts
50
- - OpenAI and ChatGPT/Codex accounts
51
- - Google Gemini
52
- - xAI Grok
102
+ - Anthropic API keys and Claude account OAuth
103
+ - OpenAI API keys and ChatGPT/Codex account OAuth
104
+ - Google Gemini and Antigravity OAuth
105
+ - xAI API keys and Grok account OAuth
106
+ - OpenRouter API keys and its unified model catalog
107
+ - Experimental Cursor account OAuth
53
108
  - DeepSeek and OpenCode Go
54
109
  - OpenAI-compatible APIs
55
110
  - Ollama and LM Studio
@@ -107,40 +162,57 @@ stdout; diagnostics remain on stderr.
107
162
  ## TUI commands
108
163
 
109
164
  ```text
110
- /providers configure provider authentication and local endpoints
111
- /model choose the main provider and model
112
- /workflow choose the active workflow
113
- /agents inspect agents and model overrides
114
- /project switch the current project
115
- /resume resume a saved session
116
- /memory inspect and edit core memory
117
- /mcp manage MCP servers and tools
118
- /skills select a skill
119
- /channels manage remote channels
120
- /compact compact older context
121
- /setting open settings
122
- /update check for updates
123
- /doctor diagnose installation health
165
+ /clear start a fresh chat
166
+ /project switch the current project
167
+ /resume resume a saved chat
168
+ /compact compact older conversation context
169
+ /autoclear manage idle-time context clearing
170
+ /context inspect the current context surface
171
+ /usage show provider quota and balance
172
+ /providers configure authentication and local endpoints
173
+ /model choose the main provider and model
174
+ /websearch choose the web search route
175
+ /workflow choose the active workflow
176
+ /agents inspect agents and model overrides
177
+ /effort set reasoning effort
178
+ /fast toggle supported model fast mode
179
+ /OutputStyle choose the Lead response style
180
+ /theme change the TUI color theme
181
+ /memory inspect and edit core memory
182
+ /mcp manage MCP servers and tools
183
+ /skills choose a skill for the next request
184
+ /plugins manage local plugin integrations
185
+ /hooks manage before-tool hooks and events
186
+ /setting open runtime settings
187
+ /profile set your title and response language
188
+ /update check for updates
189
+ /doctor diagnose installation health
190
+ /quit quit the TUI
124
191
  ```
125
192
 
126
193
  Workflows and agents are Markdown definition packs (`WORKFLOW.md`, `AGENT.md`).
127
194
  Built-in packs ship with Mixdog; custom packs live under the Mixdog data
128
195
  directory.
129
196
 
130
- ## Windows desktop app
197
+ ## Desktop app
131
198
 
132
- Mixdog Desktop runs the same agent runtime as the CLI in an Electron
133
- workbench:
199
+ Mixdog Desktop runs the same agent runtime as the CLI:
134
200
 
135
201
  - Split panes for parallel, independently routed agent sessions
202
+ - Live session handoff between the TUI, desktop windows, and paired browsers
136
203
  - Monaco editor, LSP integration, diffs, and turn-by-turn edit review
137
204
  - Git staging, commits, branches, and generated commit messages
138
- - Windows file explorer with previews, thumbnails, and drag-and-drop
139
- - Integrated PowerShell and ConPTY terminal tabs
205
+ - File explorer with previews, thumbnails, search, and drag-and-drop
206
+ - Integrated terminal tabs using the local system shell
140
207
  - Image and video generation Studio with a persistent local gallery
141
- - Visual workflow, agent, and schedule editors
208
+ - Visual workflow, agent, schedule, and webhook editors
209
+ - Voice dictation with an optional local transcription runtime
142
210
  - Provider setup, usage, git identity, and remote pairing settings
143
211
 
212
+ The paired remote web app is installable on desktop and mobile browsers. It
213
+ uses an authenticated end-to-end encrypted connection before session state,
214
+ terminal data, files, or operation requests cross the relay.
215
+
144
216
  For desktop development:
145
217
 
146
218
  ```bash
@@ -148,37 +220,6 @@ cd apps/desktop
148
220
  npm run dev
149
221
  ```
150
222
 
151
- ## Terminal-Bench 2.1
152
-
153
- Head-to-head runs against other agent CLIs on the same 89 tasks, holding the
154
- model fixed and changing only the harness. Every run uses the official Harbor
155
- verifier, fast mode off, a 272k context window, and zero retries.
156
-
157
- **GPT-5.6 Sol xhigh — Mixdog vs Codex CLI**
158
-
159
- - Score: **86.5%** (385/445) vs Codex CLI's **84.3%** (75/89)
160
- - **1.11×** faster per trial (339s vs 378s)
161
- - **42%** lower priced cost ($0.641 vs $1.096 per trial)
162
- - **45%** smaller median final context (18.5k vs 33.5k tokens)
163
-
164
- **Claude Opus 5 — Mixdog vs Claude Code**
165
-
166
- - Score: **79/89** vs Claude Code's **77/89**
167
- - **1.15×** faster and **19%** lower priced cost ($104.29 vs $129.21 per run)
168
- - **28%** smaller median final context (27.6k vs 38.2k tokens)
169
-
170
- Measurement: the Mixdog Sol run follows the same protocol the official
171
- Terminal-Bench leaderboard requires — all 89 tasks repeated five times
172
- (`k=5`, 445 trials), scored by the official Harbor verifier. The Codex CLI
173
- baseline and both Opus-side runs are single passes (`k=1`, 89 trials each).
174
-
175
- The official leaderboard is not accepting community submissions, so every run
176
- here ships its raw artifacts instead — Harbor verdicts, official verifier
177
- output, pinned task checksums, and the usage snapshots behind every cost
178
- figure — alongside the harness, presets, and metric scripts that recompute
179
- each number above:
180
- [`benchmarks/terminal-bench-2.1/`](benchmarks/terminal-bench-2.1/).
181
-
182
223
  ## Data and configuration
183
224
 
184
225
  Mixdog uses `~/.mixdog` as its home root and `~/.mixdog/data` for runtime data
@@ -213,10 +254,11 @@ Main directories:
213
254
 
214
255
  ```text
215
256
  src/ CLI, TUI, runtime, workflows, agents, and rules
216
- apps/desktop/ Windows desktop workbench
217
- apps/relay/ remote web relay
257
+ apps/desktop/ cross-platform desktop app
258
+ apps/relay/ remote web app and relay
218
259
  native/ native process, search, patch, and support binaries
219
260
  scripts/ tests, diagnostics, benchmarks, and build scripts
261
+ benchmarks/ reproducible benchmark harnesses, results, and raw artifacts
220
262
  vendor/ vendored runtime components
221
263
  ```
222
264
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.151",
3
+ "version": "0.9.152",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -66,7 +66,7 @@
66
66
  "test:native-edit-wire": "node scripts/native-edit-wire-test.mjs",
67
67
  "test:release-critical": "npm run test:release-assets && npm run smoke:patch && npm run test:providers",
68
68
  "test:spec-advisory": "node scripts/advisory-spec-test.mjs && npm run test:spec-advisory --prefix apps/desktop",
69
- "test:session-transport": "node --test scripts/session-transport-test.mjs scripts/daemon-bootstrap-test.mjs",
69
+ "test:session-transport": "node --test scripts/session-transport-test.mjs scripts/daemon-bootstrap-test.mjs src/runtime/shared/child-spawn-remote.test.mjs src/standalone/session-runtime-agent-control-client.test.mjs src/standalone/session-runtime-dispatch-cancel.test.mjs src/standalone/session-runtime-host-factory.test.mjs src/standalone/session-runtime-inline-host.test.mjs src/standalone/session-runtime-provider-cooldown.test.mjs src/standalone/session-runtime-shard-host.test.mjs src/standalone/session-runtime-shard-router.test.mjs",
70
70
  "test:session": "node --test scripts/runtime-turn-contract-test.mjs scripts/session-save-fault-store-test.mjs scripts/turn-review-revert-test.mjs src/runtime/shared/tool-surface.test.mjs",
71
71
  "test:media": "node --test src/runtime/media/store.test.mjs src/runtime/media/renditions.test.mjs src/runtime/media/adapters/codex-image.test.mjs",
72
72
  "failures": "node scripts/tool-failures.mjs",
@@ -139,6 +139,7 @@
139
139
  "undici": "^8.5.0",
140
140
  "wrap-ansi": "^10.0.0",
141
141
  "ws": "^8.21.0",
142
+ "yaml": "^2.9.0",
142
143
  "zod": "^3.25.76"
143
144
  },
144
145
  "overrides": {
@@ -17,7 +17,6 @@ import { executePatchTool } from '../src/runtime/agent/orchestrator/tools/patch.
17
17
  import { normalizeToolEnvelope } from '../src/runtime/agent/orchestrator/session/tool-envelope.mjs';
18
18
  import { warmNativeSpawnServer } from '../src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs';
19
19
  import { warmNativeSearchServer } from '../src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs';
20
- import { prewarmFindEnumeration } from '../src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs';
21
20
 
22
21
  if (!process.argv.includes('--unsafe-live')) {
23
22
  console.error('Refusing high-impact tool stress without --unsafe-live; run `node scripts/tool-search-bench.mjs` for safe exploration diagnostics.');
@@ -66,7 +65,6 @@ try {
66
65
  await Promise.all([
67
66
  warmNativeSpawnServer(),
68
67
  warmNativeSearchServer(),
69
- prewarmFindEnumeration(root),
70
68
  ]);
71
69
  prewarmMs = Date.now() - prewarmStarted;
72
70
  // ── Phase A+C: concurrent multi-session waves (search/read/graph/shell +
@@ -15,7 +15,7 @@ description: Use this skill only to inspect or modify a Mixdog user's persisted
15
15
 
16
16
  - `<mixdogData>` 해석 순서: `MIXDOG_DATA_DIR` → `<MIXDOG_HOME|~/.mixdog>/data` (`src/runtime/shared/plugin-paths.mjs`)
17
17
  - 통합 config: `<mixdogData>/mixdog-config.json`
18
- - 프로젝트 config: `<cwd>/.mcp.json`, `<cwd>/.mixdog/skills/`, `<cwd>/.mixdog/hooks.json`
18
+ - 프로젝트 config: `<cwd>/.mixdog/hooks.json`
19
19
  - TUI 명령 목록: `src/tui/app/slash-commands.mjs`
20
20
  - TUI 설정 허브: `/setting` (별칭 `/settings`, `/config`) → `src/tui/app/settings-picker.mjs`
21
21
  - Desktop 설정: `Ctrl+,` → General / Context / Output style / Providers / Git / Skills / MCP / Plugins / Hooks / Connection / System / Shortcuts / About
@@ -111,7 +111,8 @@ API 키·토큰·OAuth 자격은 config에 쓰지 않는다.
111
111
  1. **확인**: Desktop **Settings → General → Web search**, TUI `/setting → Web search`.
112
112
  2. **변경**: toggle → `setWebSearchEnabled()`.
113
113
  3. **저장**: `agent.modules.webSearch.enabled`.
114
- 4. **검증**: 다음 세션의 tool surface.
114
+ 4. **검색 범위**: 전역 `<mixdogData>/skills/`와 활성 Plugin skill만 사용한다. Project `.mixdog/skills/`는 읽지 않는다.
115
+ 5. **검증**: 열린 runtime과 다음 세션의 tool surface.
115
116
 
116
117
  ### reasoning effort / Fast
117
118
 
@@ -263,18 +264,15 @@ TUI·Desktop interval 편집 UI는 없다.
263
264
 
264
265
  ### MCP 추가
265
266
 
266
- UI에는 서버 추가·삭제·전체 재연결 액션이 없다.
267
-
268
- 1. **확인**: `/mcp` 또는 Desktop **Settings → MCP**, `mcpStatus()`, `<cwd>/.mcp.json`.
267
+ 1. **확인**: `/mcp` 또는 Desktop **Settings → MCP**, `mcpStatus()`, `agent.mcpServers`.
269
268
  2. **변경**:
270
- - 전역: 디스크 `agent.mcpServers.<name>` 편집
271
- - 프로젝트: `<cwd>/.mcp.json`의 `mcpServers` wrapper 또는 bare name map 편집
269
+ - Desktop: **Settings MCP → Add**
270
+ - 디스크: `agent.mcpServers.<name>` 편집
272
271
  - API 자동화: `addMcpServer()`, `removeMcpServer()`, `reconnectMcp()`
273
272
  3. **transport**:
274
273
  - stdio: `type`, `command`, `args`, `cwd`, `env`
275
274
  - URL: `http`, `sse`, `ws`와 `url`, 선택 `headers`
276
- 4. **제약**: API로 stdio를 추가할 `cwd`는 현재 프로젝트 아래여야 한다.
277
- 5. **검증**: `connected`, `toolCount`, `source`, `transport`, `error`.
275
+ 4. **검증**: `connected`, `toolCount`, `transport`, `error`.
278
276
 
279
277
  파일을 직접 편집했다면 mixdog 재시작이 기본 적용 경로다.
280
278
 
@@ -282,17 +280,15 @@ UI에는 서버 추가·삭제·전체 재연결 액션이 없다.
282
280
 
283
281
  TUI `/mcp`와 Desktop MCP 모두 서버별 toggle을 지원하며 live connection과 세션 tool surface를 재동기화한다.
284
282
 
285
- - `source: project`: `<cwd>/.mcp.json` 항목의 `enabled`를 직접 저장
286
- - `source: config`: 서버 정의는 유지하고 현재 프로젝트용 override `agent.mcpProjectOverrides[normalizedCwd][name].enabled`에 저장
287
- - 즉, 전역 config 서버를 toggle해도 전역 `agent.mcpServers.<name>.enabled`를 바꾸지 않는다.
283
+ - 서버 정의는 유지하고 `agent.mcpServers.<name>.enabled`를 전역으로 변경한다.
284
+ - Project `.mcp.json`과 Project별 override 읽지 않는다.
288
285
  - turn 실행 중 toggle은 turn 종료 경계에서 세션을 재생성한다.
289
286
 
290
287
  ### MCP 진단
291
288
 
292
- 1. `/mcp`의 source/transport/error를 먼저 읽는다.
293
- 2. 프로젝트와 전역 이름 충돌 `<cwd>/.mcp.json`이 우선한다.
294
- 3. stdio는 command·args·cwd·자식 env, URL transport는 scheme·endpoint·headers·방화벽을 확인한다.
295
- 4. `connected:true`와 기대 tool 노출로 검증한다.
289
+ 1. `/mcp`의 transport/error를 먼저 읽는다.
290
+ 2. stdio는 command·args·cwd·자식 env, URL transport는 scheme·endpoint·headers·방화벽을 확인한다.
291
+ 3. `connected:true`와 기대 tool 노출로 검증한다.
296
292
 
297
293
  ### Skills enable / disable
298
294
 
@@ -317,11 +313,11 @@ UI 생성 액션은 없다.
317
313
 
318
314
  1. **확인**: `/plugins` 또는 Desktop **Settings → Plugins**.
319
315
  2. **추가**: Git URL, `owner/repo`, 기존 local path → `addPlugin()`.
320
- 3. **관리**: update/metadata refresh, plugin MCP enable/reconfigure, root/MCP name 복사, uninstall.
316
+ 3. **관리**: 전역 enable/disable, update/metadata refresh, plugin MCP enable/reconfigure, root/MCP name 복사, uninstall.
321
317
  4. **저장**: `<mixdogData>/plugins/registry.json`; managed Git checkout은 `<mixdogData>/plugins/installed/`.
322
318
  5. **검증**: `pluginsStatus()`, plugin skill 수, MCP server 노출.
323
319
 
324
- Plugins 화면에는 일반적인 “plugin 활성/비활성” toggle이 없다. MCP와 skill 활성 상태는 각각 MCP/Skills 화면에서 관리한다.
320
+ Plugin toggle은 해당 Plugin의 Skills와 MCP를 전역으로 함께 활성화/비활성화한다. 개별 MCP와 Skill은 화면에서도 관리할 있다.
325
321
 
326
322
  ### Hooks
327
323
 
@@ -380,8 +376,8 @@ Discord/Telegram messaging은 제거됐다. schedules/webhooks 자동화와 voic
380
376
 
381
377
  1. **확인**: 상태줄 cwd, `/project`, Desktop rail **Projects**.
382
378
  2. **변경**: `/project [path]` 또는 picker. TUI picker는 등록·생성·rename도 지원한다.
383
- 3. **적용**: cwd 변경 프로젝트 `.mcp.json`과 skills를 다시 읽고 MCP를 재연결한다.
384
- 4. **검증**: cwd, `/mcp` source, `/skills` project 항목.
379
+ 3. **적용**: cwd 변경은 실행 경로만 바꾸며 전역 Skills·Plugins·MCP 상태는 유지한다.
380
+ 4. **검증**: cwd 실행 경로.
385
381
 
386
382
  ### Git (Desktop 전용)
387
383
 
@@ -438,11 +434,6 @@ Desktop과 현재 runtime에서 소비되지 않는 아래 key는 사용자 옵
438
434
  "cwd": "<project-subdir>",
439
435
  "env": {}
440
436
  }
441
- },
442
- "mcpProjectOverrides": {
443
- "<normalized-cwd>": {
444
- "<name>": { "enabled": false }
445
- }
446
437
  }
447
438
  }
448
439
  }
@@ -466,8 +457,8 @@ URL transport는 `type` + `url` + 선택 `headers`를 사용한다.
466
457
 
467
458
  ### 우선순위와 금지
468
459
 
469
- - MCP 이름 충돌: project `.mcp.json` > `agent.mcpServers`
470
- - Skill 이름 충돌: project > global > plugin
460
+ - MCP 전역 `agent.mcpServers`만 사용한다.
461
+ - Skill 이름 충돌: global > plugin
471
462
  - `Mixdog.md` 자동 프롬프트 로드는 없다. skill/core memory를 사용한다.
472
463
  - 확인되지 않은 key는 추측하지 말고 TODO로 남긴다.
473
464
  - UI에 없는 runtime API를 사용자 UI처럼 설명하지 않는다.
@@ -23,17 +23,10 @@ function clean(value) {
23
23
 
24
24
  export async function prewarmHeadlessSearch(cwd, {
25
25
  loadNativeSearch = () => import('./runtime/agent/orchestrator/tools/builtin/native-search-client.mjs'),
26
- loadListTool = () => import('./runtime/agent/orchestrator/tools/builtin/list-tool.mjs'),
27
26
  } = {}) {
28
- const root = clean(cwd) || process.cwd();
29
- const [nativeSearch, listTool] = await Promise.all([
30
- loadNativeSearch(),
31
- loadListTool(),
32
- ]);
33
- await Promise.all([
34
- nativeSearch.warmNativeSearchServer(),
35
- listTool.prewarmFindEnumeration(root),
36
- ]);
27
+ void cwd;
28
+ const nativeSearch = await loadNativeSearch();
29
+ await nativeSearch.warmNativeSearchServer();
37
30
  }
38
31
 
39
32
  function nonNegativeNumber(value) {
@@ -9,7 +9,7 @@ import { prewarmHeadlessSearch, runHeadlessExec } from './headless-exec.mjs';
9
9
  import { resolveCursorOAuthAccessToken } from './runtime/agent/orchestrator/providers/cursor-auth.mjs';
10
10
  import { createPristineExecutionBoundary } from './runtime/shared/pristine-execution.mjs';
11
11
 
12
- test('headless search prewarm starts the native server and Project inventory together', async () => {
12
+ test('headless search prewarm starts only the canonical native server', async () => {
13
13
  const calls = [];
14
14
  await prewarmHeadlessSearch('/app/project', {
15
15
  loadNativeSearch: async () => ({
@@ -18,13 +18,8 @@ test('headless search prewarm starts the native server and Project inventory tog
18
18
  return true;
19
19
  },
20
20
  }),
21
- loadListTool: async () => ({
22
- async prewarmFindEnumeration(root) {
23
- calls.push(`index:${root}`);
24
- },
25
- }),
26
21
  });
27
- assert.deepEqual(calls.sort(), ['index:/app/project', 'server']);
22
+ assert.deepEqual(calls, ['server']);
28
23
  });
29
24
 
30
25
  test('pristine headless execution binds Cursor OAuth credentials in process', async () => {
@@ -203,29 +203,6 @@ function hasKeys(value) {
203
203
  return !!value && typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length > 0;
204
204
  }
205
205
 
206
- // Process-local write intent for project MCP overrides. A loaded config contains
207
- // snapshots for every project, but only entries toggled by this process may
208
- // override a newer value read from disk inside the save lock.
209
- const dirtyMcpProjectOverrides = new Map();
210
- let mcpProjectOverrideDirtySeq = 0;
211
- function mcpProjectOverrideDirtyKey(projectKey, serverName) {
212
- return `${String(projectKey)}\u0000${String(serverName)}`;
213
- }
214
- export function markMcpProjectOverrideDirty(projectKey, serverName, enabled) {
215
- const pairKey = mcpProjectOverrideDirtyKey(projectKey, serverName);
216
- dirtyMcpProjectOverrides.set(pairKey, {
217
- enabled: enabled !== false,
218
- seq: ++mcpProjectOverrideDirtySeq,
219
- });
220
- }
221
- function clearDurablySavedMcpProjectOverrides(appliedDirty) {
222
- for (const { pairKey, seq } of appliedDirty) {
223
- if (dirtyMcpProjectOverrides.get(pairKey)?.seq === seq) {
224
- dirtyMcpProjectOverrides.delete(pairKey);
225
- }
226
- }
227
- }
228
-
229
206
  function normalizeWebSearchRoute(route) {
230
207
  if (!route || typeof route !== 'object' || Array.isArray(route))
231
208
  return null;
@@ -435,6 +412,7 @@ function canonicalizeLegacyAgentStorage(value = {}) {
435
412
  delete next.capabilities;
436
413
  delete next.defaultProvider;
437
414
  delete next.guide;
415
+ delete next.mcpProjectOverrides;
438
416
  return next;
439
417
  }
440
418
 
@@ -451,6 +429,7 @@ function agentConfigStorageNeedsMigration(value = {}) {
451
429
  || Object.prototype.hasOwnProperty.call(value || {}, 'searchRoute')
452
430
  || Object.prototype.hasOwnProperty.call(value || {}, 'capabilities')
453
431
  || Object.prototype.hasOwnProperty.call(value || {}, 'defaultProvider')
432
+ || Object.prototype.hasOwnProperty.call(value || {}, 'mcpProjectOverrides')
454
433
  || presets.some((preset) => !normalizePreset(preset))
455
434
  || (modules && typeof modules === 'object' && Object.prototype.hasOwnProperty.call(modules, 'memory'))
456
435
  || normalizedFields.some((key) => JSON.stringify(value?.[key]) !== JSON.stringify(canonical?.[key]));
@@ -560,9 +539,6 @@ export function loadConfig(options = {}) {
560
539
  const loaded = canonicalizeAgentRouteStorage({
561
540
  providers: mergedProviders,
562
541
  mcpServers,
563
- mcpProjectOverrides: raw.mcpProjectOverrides && typeof raw.mcpProjectOverrides === 'object' && !Array.isArray(raw.mcpProjectOverrides)
564
- ? raw.mcpProjectOverrides
565
- : {},
566
542
  presets: normalizedPresets,
567
543
  default: raw.default || null,
568
544
  maintenance: { ...DEFAULT_MAINTENANCE, ...normalizedMaint },
@@ -628,7 +604,6 @@ export function loadConfig(options = {}) {
628
604
  return {
629
605
  ...defaults,
630
606
  mcpServers: {},
631
- mcpProjectOverrides: {},
632
607
  presets: DEFAULT_PRESETS.map(p => ({ ...p })),
633
608
  default: null,
634
609
  maintenance: { ...DEFAULT_MAINTENANCE },
@@ -691,7 +666,7 @@ export async function patchSkillsDisabledAsync(disabledNames) {
691
666
  return nextSkills;
692
667
  }
693
668
 
694
- function buildAgentSaveBuilder(config, appliedDirty) {
669
+ function buildAgentSaveBuilder(config) {
695
670
  const canonicalRoutes = canonicalizeLegacyAgentStorage(config);
696
671
  // Strip ephemeral defaults from providers but preserve any unknown
697
672
  // per-provider subkey so future schema additions round-trip through the
@@ -745,42 +720,10 @@ function buildAgentSaveBuilder(config, appliedDirty) {
745
720
  // a concurrent instance survive the save (lost-update guard).
746
721
  return (existingRaw) => {
747
722
  const mcpServers = config.mcpServers || {};
748
- const diskOverrides = existingRaw.mcpProjectOverrides && typeof existingRaw.mcpProjectOverrides === 'object'
749
- ? existingRaw.mcpProjectOverrides
750
- : {};
751
- const memoryOverrides = config.mcpProjectOverrides && typeof config.mcpProjectOverrides === 'object'
752
- ? config.mcpProjectOverrides
753
- : {};
754
- const mcpProjectOverrides = {};
755
- for (const projectKey of new Set([...Object.keys(diskOverrides), ...Object.keys(memoryOverrides)])) {
756
- const diskProject = diskOverrides[projectKey] && typeof diskOverrides[projectKey] === 'object'
757
- ? diskOverrides[projectKey]
758
- : {};
759
- const memoryProject = memoryOverrides[projectKey] && typeof memoryOverrides[projectKey] === 'object'
760
- ? memoryOverrides[projectKey]
761
- : {};
762
- // Disk wins for untouched snapshot entries. Only an override this
763
- // process explicitly toggled may replace the in-lock disk value.
764
- const mergedProject = { ...memoryProject, ...diskProject };
765
- for (const serverName of Object.keys(memoryProject)) {
766
- const pairKey = mcpProjectOverrideDirtyKey(projectKey, serverName);
767
- const dirty = dirtyMcpProjectOverrides.get(pairKey);
768
- if (dirty) {
769
- const appliedValue = { enabled: dirty.enabled };
770
- mergedProject[serverName] = appliedValue;
771
- appliedDirty.push({ pairKey, seq: dirty.seq, appliedValue });
772
- }
773
- }
774
- for (const serverName of Object.keys(mergedProject)) {
775
- if (!Object.prototype.hasOwnProperty.call(mcpServers, serverName)) delete mergedProject[serverName];
776
- }
777
- if (Object.keys(mergedProject).length > 0) mcpProjectOverrides[projectKey] = mergedProject;
778
- }
779
723
  const next = {
780
724
  ...existingRaw,
781
725
  providers: persistedProviders,
782
726
  mcpServers,
783
- mcpProjectOverrides,
784
727
  presets,
785
728
  default: config.default || null,
786
729
  maintenance: canonicalRoutes.maintenance,
@@ -810,19 +753,16 @@ function buildAgentSaveBuilder(config, appliedDirty) {
810
753
  delete next.capabilities;
811
754
  delete next.defaultProvider;
812
755
  delete next.guide;
756
+ delete next.mcpProjectOverrides;
813
757
  return next;
814
758
  };
815
759
  }
816
760
  export function saveConfig(config) {
817
- const appliedDirty = [];
818
- persistAgentConfig(buildAgentSaveBuilder(config, appliedDirty));
819
- clearDurablySavedMcpProjectOverrides(appliedDirty);
761
+ persistAgentConfig(buildAgentSaveBuilder(config));
820
762
  }
821
763
  // Async twin used by the debounced config-save flush timer.
822
764
  export async function saveConfigAsync(config) {
823
- const appliedDirty = [];
824
- await persistAgentConfigAsync(buildAgentSaveBuilder(config, appliedDirty));
825
- clearDurablySavedMcpProjectOverrides(appliedDirty);
765
+ await persistAgentConfigAsync(buildAgentSaveBuilder(config));
826
766
  }
827
767
  // --- Preset helpers ---
828
768
  // preset shape: { id, name, type: 'agent', provider, model, effort?, fast?, tools? }