mixdog 0.9.129 → 0.9.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +134 -246
- package/package.json +1 -1
- package/scripts/release-timing-report.mjs +112 -0
- package/scripts/tool-stress.mjs +27 -13
- package/src/rules/shared/01-tool.md +10 -9
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +2 -2
- package/src/runtime/agent/orchestrator/agent-trace-io.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +24 -3
- package/src/runtime/agent/orchestrator/providers/gemini.mjs +5 -2
- package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +5 -0
- package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +174 -12
- package/src/runtime/agent/orchestrator/session/agent-loop.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/compact/messages.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +90 -0
- package/src/runtime/agent/orchestrator/session/image-strip-recovery.test.mjs +62 -0
- package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +4 -3
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +74 -8
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +36 -0
- package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +42 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +8 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -170
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +19 -21
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +93 -8
- package/src/runtime/agent/orchestrator/tools/builtin/fs-reachability.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +20 -2
- package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +14 -7
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +6 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +13 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +0 -106
- package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +12 -57
- package/src/runtime/agent/orchestrator/tools/builtin.mjs +2 -0
- package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +1 -0
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +11 -11
- package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +19 -3
- package/src/runtime/memory/lib/trace-store.mjs +43 -8
- package/src/runtime/memory/lib/trace-store.test.mjs +57 -0
- package/src/runtime/shared/background-tasks.mjs +0 -4
- package/src/runtime/shared/err-text.mjs +37 -0
- package/src/runtime/shared/llm/http-agent.mjs +19 -0
- package/src/runtime/shared/tool-execution-contract.mjs +1 -1
- package/src/session-runtime/lifecycle-api.mjs +3 -0
- package/src/session-runtime/prewarm.mjs +13 -16
- package/src/session-runtime/runtime-core.mjs +1 -0
- package/src/session-runtime/session-lifecycle.mjs +4 -0
- package/src/session-runtime/session-turn-api.mjs +11 -0
- package/src/standalone/agent-tool/tag-registry.mjs +7 -1
- package/src/standalone/agent-tool/worker-index.mjs +29 -3
- package/src/standalone/agent-tool/worker-rows.mjs +9 -0
- package/src/standalone/agent-tool.mjs +9 -1
- package/src/tui/dist/index.mjs +30 -0
- package/src/tui/session/session-api-ext.mjs +3 -0
- package/src/tui/session/tool-result-text.mjs +1 -1
- package/src/tui/session/turn.mjs +9 -3
package/README.md
CHANGED
|
@@ -4,27 +4,19 @@
|
|
|
4
4
|

|
|
5
5
|

|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
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.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
packages are built on native CI runners and pass packaged-runtime smoke tests,
|
|
12
|
-
but remain preview builds. Desktop packages are currently unsigned, so Windows
|
|
13
|
-
SmartScreen or macOS Gatekeeper may show a security warning.
|
|
10
|
+
## Get started
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
workflow from one terminal — or from a full desktop workbench — built to
|
|
17
|
-
get the same quality out of the same models with less time, cost, and
|
|
18
|
-
context.
|
|
12
|
+
### Windows desktop
|
|
19
13
|
|
|
20
|
-
Mixdog
|
|
21
|
-
providers, workflow agents, MCP/plugin/skill/hook support, lightweight
|
|
22
|
-
memory, web search, channel integrations, and repo-native tools for reading,
|
|
23
|
-
editing, testing, and reviewing code. Mixdog Desktop wraps the same runtime
|
|
24
|
-
in an Electron workbench with editor, git, terminal, file-explorer, media,
|
|
25
|
-
and automation surfaces.
|
|
14
|
+
[Download Mixdog Desktop for Windows (x64)](https://github.com/tribgames/mixdog/releases/latest/download/mixdog-desktop-win-x64.exe)
|
|
26
15
|
|
|
27
|
-
|
|
16
|
+
The desktop package is currently unsigned, so Windows SmartScreen may show a
|
|
17
|
+
security warning during installation.
|
|
18
|
+
|
|
19
|
+
### CLI
|
|
28
20
|
|
|
29
21
|
Requires Node.js >= 22.
|
|
30
22
|
|
|
@@ -33,132 +25,66 @@ npm install -g mixdog
|
|
|
33
25
|
mixdog
|
|
34
26
|
```
|
|
35
27
|
|
|
36
|
-
First run
|
|
28
|
+
First run guides you through provider authentication, model selection, and
|
|
37
29
|
workflow setup.
|
|
38
30
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
**Same model, same quality — in a fraction of the time, context, and
|
|
42
|
-
cost.** On the same 89 tasks, mixdog scored on par with both native
|
|
43
|
-
harnesses — **78/89** vs Claude Code's **77/89** (within single-run noise)
|
|
44
|
-
and **75/89** matching Codex CLI — while finishing faster, ending leaner,
|
|
45
|
-
and costing less.
|
|
46
|
-
|
|
47
|
-
The published mixdog runs are strict single-model benchmarks: one primary
|
|
48
|
-
model, one session, no sub-agent delegation or helper-model lookups. Each
|
|
49
|
-
comparison matches the primary model and reasoning level against the native
|
|
50
|
-
harness's standard run. Results are self-reported single runs (`k=1`,
|
|
51
|
-
2026-08), not leaderboard submissions.
|
|
52
|
-
|
|
53
|
-
#### Claude Opus 5 vs Claude Code
|
|
54
|
-
|
|
55
|
-

|
|
56
|
-
|
|
57
|
-
#### GPT-5.6 Sol xhigh vs Codex CLI
|
|
58
|
-
|
|
59
|
-

|
|
60
|
-
|
|
61
|
-
- Speed: **1.43×** vs Claude Code, **1.27×** vs Codex CLI
|
|
62
|
-
(baseline elapsed agent time ÷ mixdog elapsed agent time)
|
|
63
|
-
- Final context: **40–47% smaller** at task end (median tokens, measured
|
|
64
|
-
from both harnesses' session logs)
|
|
65
|
-
- Priced cost: **29% lower** vs Claude Code, **at least 39.7% lower** vs
|
|
66
|
-
Codex CLI (mixdog $54.50–$58.84 vs Codex's recorded $97.54)
|
|
67
|
-
|
|
68
|
-
Both sides run their standard single-agent loop. Anthropic cost includes
|
|
69
|
-
measured cache writes; the archived OpenAI runs did not retain
|
|
70
|
-
`cache_write_tokens`, so the Codex cost delta is a lower bound. Raw
|
|
71
|
-
artifacts, the exact run commands, and the metric scripts that recompute
|
|
72
|
-
every number above live under `benchmarks/terminal-bench-2.1/`.
|
|
73
|
-
|
|
74
|
-
## Why mixdog
|
|
75
|
-
|
|
76
|
-
**Maximum performance at minimum cost**
|
|
77
|
-
|
|
78
|
-
- Orchestrated agent workflow that mixes providers and models per role, so
|
|
79
|
-
each step runs on the cheapest model that can do the job well.
|
|
80
|
-
- Cache-aware prompt layout and aggressive context savings across turns.
|
|
81
|
-
- Lean output policy plus fine-grained session management: compaction,
|
|
82
|
-
resumable sessions, and usage dashboards.
|
|
83
|
-
- A custom harness with tool-call routing tuned for the fewest, most
|
|
84
|
-
effective calls (`code_graph`, batched `read`/`grep`, windowed reads).
|
|
85
|
-
|
|
86
|
-
**Any provider**
|
|
87
|
-
|
|
88
|
-
- Sign in with the subscriptions you already pay for: OAuth device flows for
|
|
89
|
-
Claude and ChatGPT/Codex accounts work alongside plain API keys.
|
|
90
|
-
- Anthropic, OpenAI, Google/Gemini, xAI/Grok, DeepSeek, OpenCode Go,
|
|
91
|
-
OpenAI-compatible APIs, Ollama, and LM Studio/local endpoints.
|
|
92
|
-
- Live model catalog from provider `/models` endpoints, enriched with
|
|
93
|
-
LiteLLM/models.dev metadata for context windows, output limits, pricing,
|
|
94
|
-
tool support, reasoning, and recency.
|
|
95
|
-
- Customizable web search and repo exploration tools.
|
|
96
|
-
|
|
97
|
-
**Any environment**
|
|
98
|
-
|
|
99
|
-
- Full-screen TUI with slash commands, provider setup, model/workflow
|
|
100
|
-
pickers, statusline integration, and detailed tool cards — plus `exec`
|
|
101
|
-
mode for headless scripting.
|
|
102
|
-
- Mixdog Desktop: a full agent workbench for Windows/macOS/Linux (see
|
|
103
|
-
below).
|
|
104
|
-
- Installable web app over relay pairing — scan a QR code to open your
|
|
105
|
-
running sessions in a phone browser and keep going from any network.
|
|
106
|
-
- Optional Discord/Telegram channels and cron schedules with quiet hours for
|
|
107
|
-
remote/event-driven workflows; channel voice messages are transcribed
|
|
108
|
-
locally with a managed Whisper server.
|
|
109
|
-
- First-class Windows support: ConPTY terminals, PowerShell-aware shell
|
|
110
|
-
profiles, and a one-click desktop installer.
|
|
111
|
-
|
|
112
|
-
**Memory**
|
|
113
|
-
|
|
114
|
-
- Every session is ingested into a local memory store in the background, so
|
|
115
|
-
prior work, decisions, and fixes stay recallable across sessions via the
|
|
116
|
-
`recall` tool and `/memory`.
|
|
117
|
-
- Semantic + lexical recall with local embeddings, time-window queries, and
|
|
118
|
-
project-scoped pools — multilingual, including Korean morphology.
|
|
119
|
-
- A multi-pass consolidation cycle promotes important memories into a
|
|
120
|
-
compact core set — and demotes them when stale — so memory stays small
|
|
121
|
-
and current instead of growing without bound.
|
|
122
|
-
|
|
123
|
-
**Agent-ecosystem compatible**
|
|
124
|
-
|
|
125
|
-
- Skills, MCP servers, hooks, and plugins load through standard-compatible
|
|
126
|
-
interfaces.
|
|
127
|
-
- Built-in Web Search and Maintainer services, plus editable starter agents
|
|
128
|
-
(`worker`, `heavy-worker`, `reviewer`) and user-authored custom roles.
|
|
31
|
+
## Highlights
|
|
129
32
|
|
|
130
|
-
|
|
33
|
+
- **Multi-provider routing** — assign different providers and models by role.
|
|
34
|
+
- **Efficient context** — cache-aware prompts, compaction, resumable sessions,
|
|
35
|
+
and focused repo-native tools.
|
|
36
|
+
- **Complete coding surface** — read, search, edit, test, review, web search,
|
|
37
|
+
MCP, skills, hooks, and plugins.
|
|
38
|
+
- **Local memory** — semantic and lexical recall with project-scoped context
|
|
39
|
+
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.
|
|
131
44
|
|
|
132
|
-
|
|
45
|
+
## Providers
|
|
133
46
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
47
|
+
Mixdog supports subscription OAuth and API-key routes, including:
|
|
48
|
+
|
|
49
|
+
- Anthropic and Claude accounts
|
|
50
|
+
- OpenAI and ChatGPT/Codex accounts
|
|
51
|
+
- Google Gemini
|
|
52
|
+
- xAI Grok
|
|
53
|
+
- DeepSeek and OpenCode Go
|
|
54
|
+
- OpenAI-compatible APIs
|
|
55
|
+
- Ollama and LM Studio
|
|
56
|
+
|
|
57
|
+
The model picker combines live provider catalogs with model metadata for
|
|
58
|
+
context limits, pricing, tool support, reasoning, and recency.
|
|
59
|
+
|
|
60
|
+
## Run
|
|
138
61
|
|
|
139
62
|
```bash
|
|
140
|
-
# Start
|
|
63
|
+
# Start in the current project
|
|
141
64
|
mixdog
|
|
142
65
|
|
|
143
|
-
#
|
|
66
|
+
# Select a provider and model
|
|
144
67
|
mixdog --provider anthropic-oauth --model claude-haiku-4-5-20251001
|
|
145
68
|
|
|
146
|
-
#
|
|
69
|
+
# Select a workflow
|
|
147
70
|
mixdog --workflow solo
|
|
148
71
|
|
|
149
|
-
#
|
|
72
|
+
# Use read-only tools
|
|
150
73
|
mixdog --readonly
|
|
151
74
|
|
|
152
|
-
# Enable remote
|
|
75
|
+
# Enable remote and channel features
|
|
153
76
|
mixdog --remote
|
|
154
77
|
|
|
155
|
-
#
|
|
78
|
+
# Run onboarding again
|
|
156
79
|
mixdog --onboarding
|
|
157
80
|
```
|
|
158
81
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
82
|
+
Run `mixdog --help` for the complete option reference.
|
|
83
|
+
|
|
84
|
+
## Headless exec
|
|
85
|
+
|
|
86
|
+
`mixdog exec` runs one non-interactive, single-model session with ephemeral
|
|
87
|
+
configuration. It requires an explicit provider and model:
|
|
162
88
|
|
|
163
89
|
```bash
|
|
164
90
|
mixdog exec --provider anthropic-oauth --model claude-opus-5 "fix the failing test"
|
|
@@ -166,155 +92,117 @@ mixdog exec --provider openai-oauth --model gpt-5.6-sol --effort xhigh --fast "r
|
|
|
166
92
|
mixdog exec --provider openai-oauth --model gpt-5.6-sol --json "fix the failing test"
|
|
167
93
|
```
|
|
168
94
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
95
|
+
Web search and memory are disabled by default in headless runs. Enable them
|
|
96
|
+
per run when needed:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
mixdog exec --provider openai-oauth --model gpt-5.6-sol --web-search "research this issue"
|
|
100
|
+
mixdog exec --provider openai-oauth --model gpt-5.6-sol --memory "continue the previous work"
|
|
101
|
+
```
|
|
175
102
|
|
|
176
|
-
|
|
103
|
+
Without `--web-search`, shell child processes use an offline network policy
|
|
104
|
+
while loopback remains available. `--json` emits timestamped JSONL events to
|
|
105
|
+
stdout; diagnostics remain on stderr.
|
|
177
106
|
|
|
178
|
-
|
|
107
|
+
## TUI commands
|
|
179
108
|
|
|
180
109
|
```text
|
|
181
|
-
/providers
|
|
182
|
-
/model
|
|
183
|
-
/workflow
|
|
184
|
-
/agents
|
|
185
|
-
/project
|
|
186
|
-
/resume
|
|
187
|
-
/
|
|
188
|
-
/
|
|
189
|
-
/
|
|
190
|
-
/
|
|
191
|
-
/
|
|
192
|
-
/
|
|
193
|
-
/
|
|
194
|
-
/
|
|
195
|
-
/autoclear reduce cache-miss cost after long idle gaps
|
|
196
|
-
/theme change the TUI color theme
|
|
197
|
-
/clear reset the conversation and screen
|
|
198
|
-
/OutputStyle show or switch Lead output style
|
|
199
|
-
/update check version and update mixdog
|
|
200
|
-
/doctor diagnose installation health
|
|
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
|
|
201
124
|
```
|
|
202
125
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
`AGENT.md`). Built-ins ship with mixdog; custom packs live under the data
|
|
212
|
-
directory (`workflows/<id>/`, `agents/<id>/`) and are edited on the desktop
|
|
213
|
-
app's Workflows page. Schedules are managed in the desktop app as well.
|
|
214
|
-
|
|
215
|
-
## Desktop app
|
|
216
|
-
|
|
217
|
-
Mixdog Desktop (Electron) runs the same runtime as the CLI inside a full
|
|
218
|
-
agent workbench. Installers are published on GitHub Releases (Windows
|
|
219
|
-
one-click NSIS, macOS dmg/zip, Linux AppImage), and a guided onboarding
|
|
220
|
-
wizard covers first-run setup. For development run `npm run dev` inside
|
|
221
|
-
`apps/desktop`.
|
|
222
|
-
|
|
223
|
-
- **Workbench shell** — VS Code-style activity rail and tab strip,
|
|
224
|
-
drag-and-drop tabs across pane groups, and unlimited splits that run
|
|
225
|
-
parallel agent sessions side by side — every pane hosts a live session
|
|
226
|
-
surface with its own draft and model controls — plus a command surface,
|
|
227
|
-
bottom panel, and problems view.
|
|
228
|
-
- **Sessions and projects** — project-scoped session lists, resumable
|
|
229
|
-
sessions with per-pane route restore, live agent-activity indicators, and
|
|
230
|
-
usage dashboards in the sidebar.
|
|
231
|
-
- **Editor and review** — Monaco editor pane with LSP integration, git and
|
|
232
|
-
inline diff viewers, and turn-by-turn review of agent edits with approval
|
|
233
|
-
cards.
|
|
234
|
-
- **Source control** — git dock for staging, commits, and branches, with
|
|
235
|
-
auto-generated commit messages.
|
|
236
|
-
- **File explorer** — Windows-Explorer-grade folder pane: breadcrumbs and
|
|
237
|
-
path box, ribbon toolbar, places/drives/tree sidebar, grouped grid and
|
|
238
|
-
details views with shell icons and thumbnails, rubber-band selection,
|
|
239
|
-
clipboard and OS drag-and-drop, preview pane, and file properties.
|
|
240
|
-
- **Terminal** — integrated terminal tabs on the native shell (ConPTY on
|
|
241
|
-
Windows) with shell-profile detection, isolated in a worker process so a
|
|
242
|
-
runaway shell never takes the app down.
|
|
243
|
-
- **Studio** — media studio for image and video generation over
|
|
244
|
-
authenticated provider lanes, with a persistent local gallery, reference
|
|
245
|
-
images, and per-model resolution/aspect/duration controls.
|
|
246
|
-
- **Automation** — visual editors for workflow and agent packs, plus cron
|
|
247
|
-
schedules.
|
|
248
|
-
- **Settings hub** — provider auth, capability sweep, git identity, and
|
|
249
|
-
QR device pairing for the installable web app, preloaded so every
|
|
250
|
-
category opens instantly.
|
|
126
|
+
Workflows and agents are Markdown definition packs (`WORKFLOW.md`, `AGENT.md`).
|
|
127
|
+
Built-in packs ship with Mixdog; custom packs live under the Mixdog data
|
|
128
|
+
directory.
|
|
129
|
+
|
|
130
|
+
## Windows desktop app
|
|
131
|
+
|
|
132
|
+
Mixdog Desktop runs the same agent runtime as the CLI in an Electron
|
|
133
|
+
workbench:
|
|
251
134
|
|
|
252
|
-
|
|
135
|
+
- Split panes for parallel, independently routed agent sessions
|
|
136
|
+
- Monaco editor, LSP integration, diffs, and turn-by-turn edit review
|
|
137
|
+
- 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
|
|
140
|
+
- Image and video generation Studio with a persistent local gallery
|
|
141
|
+
- Visual workflow, agent, and schedule editors
|
|
142
|
+
- Provider setup, usage, git identity, and remote pairing settings
|
|
143
|
+
|
|
144
|
+
For desktop development:
|
|
253
145
|
|
|
254
146
|
```bash
|
|
255
|
-
|
|
256
|
-
npm run
|
|
257
|
-
npm run test:tool-contracts # optional tool contract suite
|
|
258
|
-
npm run build:tui # build the bundled Ink TUI
|
|
259
|
-
npm run audit:models # inspect model catalog metadata
|
|
147
|
+
cd apps/desktop
|
|
148
|
+
npm run dev
|
|
260
149
|
```
|
|
261
150
|
|
|
262
|
-
|
|
151
|
+
## Terminal-Bench 2.1
|
|
152
|
+
|
|
153
|
+
Controlled single-model runs on the same 89 tasks produced:
|
|
154
|
+
|
|
155
|
+
- **78/89** with Claude Opus 5 vs Claude Code's **77/89**
|
|
156
|
+
- **75/89** with GPT-5.6 Sol xhigh, matching Codex CLI
|
|
157
|
+
- **1.43×** faster vs Claude Code and **1.27×** faster vs Codex CLI
|
|
158
|
+
- **40–47%** smaller median final context
|
|
159
|
+
- **29%** lower priced cost vs Claude Code and at least **39.7%** lower vs
|
|
160
|
+
Codex CLI
|
|
161
|
+
|
|
162
|
+
These are self-reported single runs (`k=1`, 2026-08), not leaderboard
|
|
163
|
+
submissions. Raw artifacts, commands, comparison charts, and metric scripts
|
|
164
|
+
live under [`benchmarks/terminal-bench-2.1/`](benchmarks/terminal-bench-2.1/).
|
|
263
165
|
|
|
264
166
|
## Data and configuration
|
|
265
167
|
|
|
266
|
-
Mixdog uses `~/.mixdog` as its home root
|
|
267
|
-
|
|
168
|
+
Mixdog uses `~/.mixdog` as its home root and `~/.mixdog/data` for runtime data
|
|
169
|
+
by default.
|
|
268
170
|
|
|
269
171
|
```bash
|
|
270
172
|
MIXDOG_HOME=/path/to/home mixdog
|
|
271
173
|
MIXDOG_DATA_DIR=/path/to/data mixdog
|
|
272
174
|
```
|
|
273
175
|
|
|
274
|
-
Useful environment
|
|
176
|
+
Useful environment variables:
|
|
275
177
|
|
|
276
|
-
- `MIXDOG_TUI_MOUSE=0` — use terminal-native mouse behavior
|
|
277
|
-
|
|
278
|
-
- `
|
|
279
|
-
- `
|
|
280
|
-
- `MIXDOG_MODEL_STALE_MONTHS=<months>` — tune catalog staleness filtering.
|
|
281
|
-
- `MIXDOG_MODE=ship|dev` — explicit shipping/dev mode. Shipping disables
|
|
282
|
-
best-effort diagnostic trace/log file IO (agent-trace.jsonl,
|
|
283
|
-
tool-failures.jsonl) by default; dev/debug opts back in. Default is `dev`
|
|
284
|
-
from a git checkout and `ship` for a published install.
|
|
285
|
-
- `MIXDOG_DIAGNOSTICS=1` — force diagnostic trace/log file IO on even under
|
|
286
|
-
shipping mode.
|
|
178
|
+
- `MIXDOG_TUI_MOUSE=0` — use terminal-native mouse behavior.
|
|
179
|
+
- `MIXDOG_DISABLE_MODEL_PREFETCH=1` — disable provider model prefetch.
|
|
180
|
+
- `MIXDOG_MODE=ship|dev` — select shipping or development diagnostics.
|
|
181
|
+
- `MIXDOG_DIAGNOSTICS=1` — force diagnostic trace and log output.
|
|
287
182
|
|
|
288
|
-
##
|
|
183
|
+
## Development
|
|
289
184
|
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
agents/ # workflow agent definitions
|
|
300
|
-
workflows/ # workflow definitions
|
|
301
|
-
rules/ # Lead and agent instructions
|
|
302
|
-
apps/
|
|
303
|
-
desktop/ # Mixdog Desktop — Electron workbench (main/preload/renderer)
|
|
304
|
-
relay/ # relay server for remote web-app access
|
|
305
|
-
scripts/
|
|
306
|
-
smoke*.mjs # smoke checks
|
|
307
|
-
*test.mjs # focused node:test checks
|
|
308
|
-
build-tui.mjs # esbuild bundle for the React TUI
|
|
309
|
-
vendor/
|
|
310
|
-
ink/ # Mixdog Ink renderer
|
|
185
|
+
```bash
|
|
186
|
+
npm install
|
|
187
|
+
npm start
|
|
188
|
+
|
|
189
|
+
npm run smoke
|
|
190
|
+
npm run smoke:all
|
|
191
|
+
npm run test:tool-contracts
|
|
192
|
+
npm run build:tui
|
|
193
|
+
npm run audit:models
|
|
311
194
|
```
|
|
312
195
|
|
|
313
|
-
|
|
196
|
+
Main directories:
|
|
314
197
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
198
|
+
```text
|
|
199
|
+
src/ CLI, TUI, runtime, workflows, agents, and rules
|
|
200
|
+
apps/desktop/ Windows desktop workbench
|
|
201
|
+
apps/relay/ remote web relay
|
|
202
|
+
native/ native process, search, patch, and support binaries
|
|
203
|
+
scripts/ tests, diagnostics, benchmarks, and build scripts
|
|
204
|
+
vendor/ vendored runtime components
|
|
205
|
+
```
|
|
318
206
|
|
|
319
207
|
## License
|
|
320
208
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { appendFile, readFile } from 'node:fs/promises';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
|
|
7
|
+
function payloadJobs(payload) {
|
|
8
|
+
const pages = Array.isArray(payload) ? payload : [payload];
|
|
9
|
+
return pages.flatMap((page) => Array.isArray(page?.jobs) ? page.jobs : []);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function elapsedSeconds(startedAt, completedAt) {
|
|
13
|
+
const start = Date.parse(startedAt || '');
|
|
14
|
+
const end = Date.parse(completedAt || '');
|
|
15
|
+
if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return null;
|
|
16
|
+
return Math.round((end - start) / 1000);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function timingRows(payload) {
|
|
20
|
+
return payloadJobs(payload).flatMap((job) => (job.steps || []).flatMap((step) => {
|
|
21
|
+
const seconds = elapsedSeconds(step.started_at, step.completed_at);
|
|
22
|
+
if (seconds === null) return [];
|
|
23
|
+
return [{
|
|
24
|
+
key: `${job.name} / ${step.name}`,
|
|
25
|
+
job: job.name,
|
|
26
|
+
step: step.name,
|
|
27
|
+
seconds,
|
|
28
|
+
}];
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function workflowSeconds(payload) {
|
|
33
|
+
const jobs = payloadJobs(payload);
|
|
34
|
+
const starts = jobs.map((job) => Date.parse(job.started_at || '')).filter(Number.isFinite);
|
|
35
|
+
const ends = jobs.map((job) => Date.parse(job.completed_at || '')).filter(Number.isFinite);
|
|
36
|
+
if (starts.length === 0 || ends.length === 0) return null;
|
|
37
|
+
return Math.round((Math.max(...ends) - Math.min(...starts)) / 1000);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function percentChange(current, baseline) {
|
|
41
|
+
if (!(baseline > 0)) return null;
|
|
42
|
+
return Math.round(((current - baseline) / baseline) * 100);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function buildReleaseTimingReport(currentPayload, baselinePayload = []) {
|
|
46
|
+
const currentRows = timingRows(currentPayload);
|
|
47
|
+
const baselineRows = timingRows(baselinePayload);
|
|
48
|
+
const baselineByKey = new Map(baselineRows.map((row) => [row.key, row]));
|
|
49
|
+
const regressions = currentRows.flatMap((row) => {
|
|
50
|
+
const baseline = baselineByKey.get(row.key);
|
|
51
|
+
if (!baseline) return [];
|
|
52
|
+
const percent = percentChange(row.seconds, baseline.seconds);
|
|
53
|
+
if (percent === null || percent <= 10 || row.seconds - baseline.seconds < 15) return [];
|
|
54
|
+
return [{ ...row, baselineSeconds: baseline.seconds, percent }];
|
|
55
|
+
}).sort((a, b) => b.percent - a.percent || b.seconds - a.seconds);
|
|
56
|
+
|
|
57
|
+
const currentWorkflowSeconds = workflowSeconds(currentPayload);
|
|
58
|
+
const baselineWorkflowSeconds = workflowSeconds(baselinePayload);
|
|
59
|
+
const workflowPercent = currentWorkflowSeconds !== null && baselineWorkflowSeconds !== null
|
|
60
|
+
? percentChange(currentWorkflowSeconds, baselineWorkflowSeconds)
|
|
61
|
+
: null;
|
|
62
|
+
const slowest = [...currentRows].sort((a, b) => b.seconds - a.seconds).slice(0, 15);
|
|
63
|
+
const markdown = [
|
|
64
|
+
'## Release timing',
|
|
65
|
+
'',
|
|
66
|
+
`- Current workflow span: ${currentWorkflowSeconds ?? 'n/a'}s`,
|
|
67
|
+
`- Previous successful span: ${baselineWorkflowSeconds ?? 'n/a'}s`,
|
|
68
|
+
`- Material step regressions (>10% and ≥15s): ${regressions.length}`,
|
|
69
|
+
'',
|
|
70
|
+
'| Slowest step | Current | Previous | Change |',
|
|
71
|
+
'| --- | ---: | ---: | ---: |',
|
|
72
|
+
...slowest.map((row) => {
|
|
73
|
+
const baseline = baselineByKey.get(row.key);
|
|
74
|
+
const change = baseline ? percentChange(row.seconds, baseline.seconds) : null;
|
|
75
|
+
return `| ${row.key.replaceAll('|', '\\|')} | ${row.seconds}s | ${baseline ? `${baseline.seconds}s` : 'n/a'} | ${change === null ? 'n/a' : `${change > 0 ? '+' : ''}${change}%`} |`;
|
|
76
|
+
}),
|
|
77
|
+
'',
|
|
78
|
+
].join('\n');
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
currentWorkflowSeconds,
|
|
82
|
+
baselineWorkflowSeconds,
|
|
83
|
+
workflowPercent,
|
|
84
|
+
regressions,
|
|
85
|
+
markdown,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function commandValue(value) {
|
|
90
|
+
return String(value).replaceAll('%', '%25').replaceAll('\r', '%0D').replaceAll('\n', '%0A');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const invokedPath = process.argv[1] ? pathToFileURL(resolve(process.argv[1])).href : '';
|
|
94
|
+
if (invokedPath === import.meta.url) {
|
|
95
|
+
const currentPath = process.argv[2];
|
|
96
|
+
const baselinePath = process.argv[3];
|
|
97
|
+
if (!currentPath) throw new Error('Usage: release-timing-report.mjs <current-jobs.json> [baseline-jobs.json]');
|
|
98
|
+
const current = JSON.parse(await readFile(currentPath, 'utf8'));
|
|
99
|
+
const baseline = baselinePath ? JSON.parse(await readFile(baselinePath, 'utf8')) : [];
|
|
100
|
+
const report = buildReleaseTimingReport(current, baseline);
|
|
101
|
+
if (process.env.GITHUB_STEP_SUMMARY) {
|
|
102
|
+
await appendFile(process.env.GITHUB_STEP_SUMMARY, `${report.markdown}\n`);
|
|
103
|
+
}
|
|
104
|
+
if (report.workflowPercent > 10
|
|
105
|
+
&& report.currentWorkflowSeconds - report.baselineWorkflowSeconds >= 30) {
|
|
106
|
+
console.log(`::warning title=Release duration regression::Workflow span increased ${report.workflowPercent}% to ${report.currentWorkflowSeconds}s`);
|
|
107
|
+
}
|
|
108
|
+
for (const row of report.regressions) {
|
|
109
|
+
console.log(`::warning title=Release step regression::${commandValue(row.key)} increased ${row.percent}% (${row.baselineSeconds}s to ${row.seconds}s)`);
|
|
110
|
+
}
|
|
111
|
+
console.log(`Release timing recorded: ${report.currentWorkflowSeconds ?? 'n/a'}s, ${report.regressions.length} material step regressions.`);
|
|
112
|
+
}
|