mixdog 0.9.147 → 0.9.149

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 (265) hide show
  1. package/package.json +23 -3
  2. package/scripts/build-voice-runtime-unix.sh +101 -0
  3. package/scripts/embedding-quality-probe.mjs +96 -0
  4. package/scripts/generate-voice-runtime-manifest.mjs +300 -0
  5. package/scripts/generate-voice-runtime-manifest.test.mjs +135 -0
  6. package/scripts/native-binary-arch.mjs +30 -13
  7. package/scripts/native-binary-arch.test.mjs +40 -4
  8. package/scripts/plan-voice-runtime-release.mjs +73 -0
  9. package/scripts/prepare-native-assets.mjs +50 -9
  10. package/scripts/prune-embedding-runtime.mjs +3 -3
  11. package/scripts/sync-voice-runtime-manifest.mjs +46 -0
  12. package/scripts/verify-release-assets.mjs +106 -6
  13. package/scripts/verify-voice-runtime-release.mjs +89 -0
  14. package/scripts/voice-runtime-config.json +52 -0
  15. package/src/app.mjs +42 -5
  16. package/src/headless-exec.mjs +58 -32
  17. package/src/headless-exec.test.mjs +74 -13
  18. package/src/rules/lead/01-general.md +2 -0
  19. package/src/rules/shared/10-tool-workflow.md +7 -4
  20. package/src/rules/shared/30-exploration.md +5 -1
  21. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +28 -9
  22. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +6 -1
  23. package/src/runtime/agent/orchestrator/config.mjs +53 -18
  24. package/src/runtime/agent/orchestrator/mcp/cancellation.test.mjs +139 -0
  25. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +34 -5
  26. package/src/runtime/agent/orchestrator/mcp/client.mjs +94 -10
  27. package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +5 -0
  28. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +98 -0
  29. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.test.mjs +90 -0
  30. package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +67 -16
  31. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +4 -82
  32. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +0 -5
  33. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +62 -121
  34. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +48 -0
  35. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.test.mjs +215 -0
  36. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +44 -48
  37. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +54 -31
  38. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +56 -2
  39. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +34 -2
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +61 -1
  41. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -1
  42. package/src/runtime/agent/orchestrator/providers/gemini.mjs +61 -15
  43. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +120 -1
  44. package/src/runtime/agent/orchestrator/providers/lib/env-utils.mjs +9 -0
  45. package/src/runtime/agent/orchestrator/providers/lib/stream-outcome.mjs +0 -3
  46. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +187 -84
  47. package/src/runtime/agent/orchestrator/providers/openai-codex-identity.test.mjs +32 -9
  48. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +78 -33
  49. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +21 -0
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +36 -36
  51. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +16 -6
  52. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +50 -213
  53. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +135 -126
  54. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +20 -11
  55. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +112 -36
  56. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +220 -50
  57. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +112 -9
  58. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +11 -0
  59. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +130 -60
  60. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
  61. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +28 -10
  62. package/src/runtime/agent/orchestrator/providers/registry.mjs +122 -95
  63. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +69 -3
  64. package/src/runtime/agent/orchestrator/providers/tool-stream-state.mjs +4 -22
  65. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +7 -14
  66. package/src/runtime/agent/orchestrator/session/compact-policy.test.mjs +128 -0
  67. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +5 -0
  68. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +27 -48
  69. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +19 -14
  70. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +9 -43
  71. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +5 -1
  72. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +43 -5
  73. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +15 -2
  74. package/src/runtime/agent/orchestrator/session/manager/pending-messages-persistence.test.mjs +325 -0
  75. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +599 -195
  76. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +22 -0
  77. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +9 -2
  78. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +2 -0
  79. package/src/runtime/agent/orchestrator/session/manager.mjs +3 -0
  80. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +26 -16
  81. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +23 -11
  82. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +118 -3
  83. package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +332 -0
  84. package/src/runtime/agent/orchestrator/session/store.mjs +38 -1
  85. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +27 -6
  86. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +12 -20
  87. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +291 -128
  88. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +46 -9
  89. package/src/runtime/agent/orchestrator/tools/builtin/edit-encoding-eol.test.mjs +224 -0
  90. package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +53 -3
  91. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +255 -25
  92. package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +87 -0
  93. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +132 -9
  95. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +10 -0
  96. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-pattern-fanout.mjs +29 -3
  97. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/tools/builtin/list-tool-integrity.test.mjs +14 -0
  99. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +180 -31
  100. package/src/runtime/agent/orchestrator/tools/builtin/local-search-telemetry.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +32 -5
  102. package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +5 -2
  103. package/src/runtime/agent/orchestrator/tools/builtin/native-search-runner.mjs +10 -1
  104. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +38 -10
  105. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +12 -0
  106. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +31 -1
  107. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +11 -1
  108. package/src/runtime/agent/orchestrator/tools/builtin/read-windows.mjs +22 -4
  109. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +6 -8
  110. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +25 -24
  111. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +152 -133
  112. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +114 -42
  113. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +129 -15
  114. package/src/runtime/agent/orchestrator/tools/code-graph/loose-file-target.test.mjs +72 -0
  115. package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +7 -8
  116. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +4 -4
  117. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +201 -19
  118. package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +26 -3
  119. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +10 -1
  120. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-search-scope.test.mjs +55 -0
  121. package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +115 -25
  122. package/src/runtime/agent/orchestrator/tools/code-graph/text-span-mask.test.mjs +268 -0
  123. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +3 -3
  124. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +296 -46
  125. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.test.mjs +104 -0
  126. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +136 -0
  127. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +127 -38
  128. package/src/runtime/agent/orchestrator/tools/patch/engine-contract-gate.test.mjs +661 -0
  129. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +350 -9
  130. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +418 -44
  131. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +27 -3
  132. package/src/runtime/agent/orchestrator/tools/patch/patch-codec-eol.test.mjs +552 -0
  133. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +65 -15
  134. package/src/runtime/agent/orchestrator/tools/patch-manifest.json +11 -11
  135. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +284 -109
  136. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +51 -21
  137. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +44 -27
  138. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +6 -1
  139. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +11 -11
  140. package/src/runtime/attachments/store.mjs +11 -3
  141. package/src/runtime/channels/data/voice-runtime-manifest.json +46 -70
  142. package/src/runtime/channels/lib/event-queue.mjs +51 -41
  143. package/src/runtime/channels/lib/scheduler.mjs +23 -28
  144. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -17
  145. package/src/runtime/channels/lib/voice-runtime-fetcher.test.mjs +17 -0
  146. package/src/runtime/channels/lib/webhook.mjs +39 -20
  147. package/src/runtime/channels/lib/whisper-server.mjs +46 -1
  148. package/src/runtime/channels/lib/worker-main.mjs +3 -1
  149. package/src/runtime/media/adapters/gemini-video.mjs +20 -4
  150. package/src/runtime/media/jobs.mjs +13 -0
  151. package/src/runtime/media/renditions.mjs +7 -1
  152. package/src/runtime/media/store.mjs +42 -22
  153. package/src/runtime/memory/index.mjs +4 -9
  154. package/src/runtime/memory/lib/agent-ipc.mjs +1 -6
  155. package/src/runtime/memory/lib/archive-security.test.mjs +21 -1
  156. package/src/runtime/memory/lib/core-memory-store.mjs +28 -50
  157. package/src/runtime/memory/lib/embedding-model-config.mjs +37 -1
  158. package/src/runtime/memory/lib/embedding-model-config.test.mjs +33 -0
  159. package/src/runtime/memory/lib/embedding-provider.mjs +34 -12
  160. package/src/runtime/memory/lib/embedding-worker.mjs +37 -5
  161. package/src/runtime/memory/lib/ko-morph.mjs +46 -15
  162. package/src/runtime/memory/lib/memory-action-handlers.mjs +18 -1
  163. package/src/runtime/memory/lib/memory-cycle1.mjs +1 -18
  164. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -18
  165. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +98 -45
  166. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +71 -0
  167. package/src/runtime/memory/lib/memory-cycle2-shared.test.mjs +78 -0
  168. package/src/runtime/memory/lib/memory-cycle2.mjs +37 -3
  169. package/src/runtime/memory/lib/memory-cycle3.mjs +1 -1
  170. package/src/runtime/memory/lib/memory-embedding-migration.test.mjs +50 -0
  171. package/src/runtime/memory/lib/memory-recall-store.mjs +9 -24
  172. package/src/runtime/memory/lib/memory.mjs +50 -12
  173. package/src/runtime/memory/lib/pg/process.mjs +1 -10
  174. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -9
  175. package/src/runtime/memory/lib/query-handlers.mjs +2 -4
  176. package/src/runtime/memory/lib/session-ingest-runtime.mjs +2 -2
  177. package/src/runtime/shared/background-tasks.mjs +15 -0
  178. package/src/runtime/shared/background-tasks.test.mjs +78 -0
  179. package/src/runtime/shared/child-guardian.mjs +2 -10
  180. package/src/runtime/shared/pid-liveness.mjs +27 -0
  181. package/src/runtime/shared/pristine-execution-contract.json +0 -1
  182. package/src/runtime/shared/runtime-root.mjs +1 -11
  183. package/src/runtime/shared/service-discovery.mjs +1 -17
  184. package/src/runtime/shared/singleton-owner.mjs +1 -11
  185. package/src/runtime/shared/staged-update.mjs +2 -12
  186. package/src/runtime/shared/tool-status.mjs +5 -1
  187. package/src/runtime/shared/tool-surface.mjs +15 -7
  188. package/src/runtime/shared/turn-snapshot-store.mjs +168 -0
  189. package/src/runtime/shared/turn-snapshot.mjs +137 -13
  190. package/src/runtime/shared/turn-worktree-snapshot.mjs +110 -18
  191. package/src/runtime/shared/webhook-session-run.mjs +16 -2
  192. package/src/runtime/web-search/lib/http-fetch.mjs +34 -4
  193. package/src/runtime/web-search/lib/state.mjs +15 -15
  194. package/src/runtime/web-search/lib/web-tools.mjs +46 -5
  195. package/src/session-runtime/context-status.mjs +4 -12
  196. package/src/session-runtime/runtime-core.mjs +20 -1
  197. package/src/session-runtime/session-lifecycle.mjs +9 -0
  198. package/src/standalone/agent-dispatch-broker.mjs +33 -2
  199. package/src/standalone/agent-tool/job-task-reconcile.mjs +78 -0
  200. package/src/standalone/agent-tool/notify.mjs +3 -1
  201. package/src/standalone/agent-tool/spawn-flow.mjs +52 -70
  202. package/src/standalone/agent-tool/tag-registry.mjs +116 -33
  203. package/src/standalone/agent-tool/tool-def.mjs +2 -2
  204. package/src/standalone/agent-tool/worker-index.mjs +8 -11
  205. package/src/standalone/agent-tool/worker-rows.mjs +4 -1
  206. package/src/standalone/agent-tool.mjs +20 -55
  207. package/src/standalone/agent-watchdog-registry.mjs +28 -4
  208. package/src/standalone/channel-client.mjs +47 -15
  209. package/src/standalone/channel-transport.mjs +44 -25
  210. package/src/standalone/daemon.mjs +31 -2
  211. package/src/standalone/hook-bus/config.mjs +25 -9
  212. package/src/standalone/hook-bus/handlers.mjs +16 -52
  213. package/src/standalone/hook-bus.mjs +29 -23
  214. package/src/standalone/memory-runtime-proxy.mjs +1 -16
  215. package/src/standalone/session-client.mjs +86 -23
  216. package/src/standalone/session-protocol.mjs +0 -2
  217. package/src/standalone/session-runtime-host-health.test.mjs +5 -4
  218. package/src/standalone/session-runtime-host.mjs +101 -6
  219. package/src/standalone/session-runtime-record.mjs +1 -5
  220. package/src/standalone/session-runtime-worker.mjs +52 -57
  221. package/src/standalone/session-service.mjs +4 -1
  222. package/src/standalone/session-transport.mjs +56 -25
  223. package/src/tui/App.jsx +40 -49
  224. package/src/tui/app/app-view.jsx +14 -21
  225. package/src/tui/app/core-memory-picker.mjs +29 -16
  226. package/src/tui/app/create-app-pickers.mjs +15 -36
  227. package/src/tui/app/extension-pickers.mjs +60 -49
  228. package/src/tui/app/maintenance-pickers.mjs +100 -57
  229. package/src/tui/app/message-selector.mjs +6 -5
  230. package/src/tui/app/model-picker.mjs +30 -13
  231. package/src/tui/app/onboarding-steps.mjs +21 -12
  232. package/src/tui/app/panel-epoch.mjs +56 -0
  233. package/src/tui/app/panel-epoch.test.mjs +1009 -0
  234. package/src/tui/app/panel-surface.mjs +98 -0
  235. package/src/tui/app/project-picker.mjs +30 -29
  236. package/src/tui/app/prompt-submit.mjs +192 -97
  237. package/src/tui/app/prompt-submit.test.mjs +206 -0
  238. package/src/tui/app/provider-setup-picker.mjs +74 -43
  239. package/src/tui/app/resume-picker.mjs +11 -8
  240. package/src/tui/app/route-pickers.mjs +45 -28
  241. package/src/tui/app/settings-picker.mjs +69 -18
  242. package/src/tui/app/shell-layout.mjs +1 -3
  243. package/src/tui/app/slash-commands.mjs +0 -2
  244. package/src/tui/app/slash-dispatch.mjs +4 -2
  245. package/src/tui/app/text-entry-policy.mjs +25 -0
  246. package/src/tui/app/theme-effort-pickers.mjs +11 -16
  247. package/src/tui/app/usage-context-panels.mjs +21 -25
  248. package/src/tui/app/use-global-key-input.mjs +3 -2
  249. package/src/tui/app/use-prompt-draft-flow.mjs +6 -18
  250. package/src/tui/app/use-prompt-handlers.mjs +3 -2
  251. package/src/tui/app/use-welcome-prompt-hint.mjs +17 -3
  252. package/src/tui/components/Picker.jsx +1 -1
  253. package/src/tui/components/TextEntryPanel.jsx +7 -2
  254. package/src/tui/dist/index.mjs +652 -561
  255. package/src/tui/lib/voice-setup.mjs +1 -2
  256. package/src/tui/session/agent-job-feed.mjs +73 -11
  257. package/src/tui/session/session-api-ext.mjs +5 -6
  258. package/src/tui/session/session-api.mjs +1 -0
  259. package/src/tui/session/tool-approval.mjs +15 -5
  260. package/src/tui/session/tui-steering-persist.mjs +33 -19
  261. package/src/tui/session/tui-steering-persist.test.mjs +104 -0
  262. package/src/tui/session-local.mjs +0 -22
  263. package/scripts/.tmp-coverage-report.mjs +0 -96
  264. package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.mjs +0 -57
  265. package/src/runtime/agent/orchestrator/tools/builtin/shell-monitor.test.mjs +0 -57
@@ -18,13 +18,16 @@ import { join } from 'node:path';
18
18
  import { StringDecoder } from 'node:string_decoder';
19
19
  import * as nodeUtil from 'node:util';
20
20
  import { getPluginData } from '../config.mjs';
21
+ import { TOOL_OUTPUT_MAX_BYTES } from './builtin/tool-output-limit.mjs';
21
22
 
22
- // Inline cap. Output above this size is spilled to disk and the caller
23
- // renders a path marker instead of pasting the tail. Matches the
24
- // SHELL_OUTPUT_MAX_CHARS used by the smart-truncate renderer in
25
- // builtin.mjs so spilled output and inline output share the same boundary.
23
+ // Inline cap, in BYTES. Output at or below this size is pasted whole; above
24
+ // it the rendered body becomes head+tail carrying a "full output at <path>"
25
+ // marker. Bound to the shared model-facing tool-output budget
26
+ // (TOOL_OUTPUT_MAX_BYTES, env MIXDOG_TOOL_OUTPUT_MAX_BYTES) so one shell call
27
+ // costs no more context than one read/list call, and so the spill-file
28
+ // retention rule in shell-command.mjs keys off this exact boundary.
26
29
 
27
- export const SHELL_OUTPUT_INLINE_CAP = 30_000;
30
+ export const SHELL_OUTPUT_INLINE_CAP = TOOL_OUTPUT_MAX_BYTES;
28
31
 
29
32
  // Hard ceiling on disk-backed output. Past this the SIZE_WATCHDOG (G2)
30
33
  // SIGKILLs the child to avoid filling the filesystem. 100 MB is generous
@@ -74,8 +77,10 @@ export function inspectShellTextChunk(value, channel = 'stdout') {
74
77
  || unsafeCount > Math.max(8, Math.floor(text.length * 0.1))
75
78
  || replacementCount > Math.max(4, Math.floor(text.length * 0.02));
76
79
  if (binary) {
80
+ // Sanitize, never stop: the printable remainder is often the answer the
81
+ // caller needs (a git protocol banner, a VM boot log, a PDF text run).
77
82
  return {
78
- text: `[binary output detected on ${channel}; stream stopped after ${bytes} bytes]\n`,
83
+ text: text.replace(/\u0000/g, '').replace(UNSAFE_TEXT_CONTROL_RE, ''),
79
84
  binary: true,
80
85
  bytes,
81
86
  };
@@ -188,7 +193,7 @@ export function treeKill(child) {
188
193
  // 4 B, so a small padding window lets us cut/advance on codepoint boundaries
189
194
  // instead of emitting a U+FFFD glyph at the seam.
190
195
  function _readHeadTail(filePath, fileSize) {
191
- if (fileSize <= SHELL_OUTPUT_INLINE_CAP * 4) {
196
+ if (fileSize <= SHELL_OUTPUT_INLINE_CAP) {
192
197
  return readFileSync(filePath, 'utf-8');
193
198
  }
194
199
  const padding = 4;
@@ -221,7 +226,7 @@ function _readHeadTail(filePath, fileSize) {
221
226
 
222
227
  // Owns the captured stdout/stderr buffers for a single command run. Starts
223
228
  // fully in memory; once the combined byte total exceeds the spill threshold
224
- // (SHELL_OUTPUT_INLINE_CAP*4), opens append-only files in
229
+ // (SHELL_OUTPUT_INLINE_CAP), opens append-only files in
225
230
  // $PLUGIN_DATA/shell-output/ and from then on writes go straight to disk.
226
231
  // On settle, the caller (execShellCommand) decides whether to keep the
227
232
  // spilled files based on the final size.
@@ -307,14 +312,14 @@ export class TaskOutput {
307
312
  if (this.spilled) return;
308
313
  // Threshold is in BYTES — string .length counts UTF-16 units, which
309
314
  // understates CJK output by up to 3x against the byte-sized cap.
310
- if (this._inlineBytes > SHELL_OUTPUT_INLINE_CAP * 4) {
315
+ if (this._inlineBytes > SHELL_OUTPUT_INLINE_CAP) {
311
316
  this._ensureFileBacking();
312
317
  }
313
318
  }
314
319
 
315
320
  // Force the in-memory buffers onto disk-backed files regardless of the
316
- // SHELL_OUTPUT_INLINE_CAP*4 threshold. Used by the auto-background
317
- // transition: once a foreground command is adopted into a tracked job,
321
+ // SHELL_OUTPUT_INLINE_CAP threshold. Used by the auto-background
322
+ // transition: once a foreground command is promoted into a tracked job,
318
323
  // every subsequent stdout/stderr chunk must land in the spill files so
319
324
  // task wait/read can read it (the caller has already settled and will no
320
325
  // longer drain the in-memory buffers). No-op once already spilled.
@@ -352,12 +357,13 @@ export class TaskOutput {
352
357
 
353
358
  writeStdout(s) {
354
359
  if (!s) return;
355
- if (this.binaryOutput) return;
356
360
  const inspected = inspectShellTextChunk(s, 'stdout');
357
- if (inspected.binary) {
361
+ if (inspected.binary && !this.binaryOutput) {
358
362
  this.binaryOutput = { channel: 'stdout', bytes: inspected.bytes };
363
+ s = `[binary output on stdout sanitized; non-printable bytes removed]\n${inspected.text}`;
364
+ } else {
365
+ s = inspected.text;
359
366
  }
360
- s = inspected.text;
361
367
  if (this.spilled) {
362
368
  try {
363
369
  writeSync(this.stdoutFd, s);
@@ -374,12 +380,13 @@ export class TaskOutput {
374
380
 
375
381
  writeStderr(s) {
376
382
  if (!s) return;
377
- if (this.binaryOutput) return;
378
383
  const inspected = inspectShellTextChunk(s, 'stderr');
379
- if (inspected.binary) {
384
+ if (inspected.binary && !this.binaryOutput) {
380
385
  this.binaryOutput = { channel: 'stderr', bytes: inspected.bytes };
386
+ s = `[binary output on stderr sanitized; non-printable bytes removed]\n${inspected.text}`;
387
+ } else {
388
+ s = inspected.text;
381
389
  }
382
- s = inspected.text;
383
390
  if (this.spilled) {
384
391
  try {
385
392
  writeSync(this.stderrFd, s);
@@ -423,15 +430,31 @@ export class TaskOutput {
423
430
  try { closeSync(fd); } catch {}
424
431
  }
425
432
  };
426
- return merge(
433
+ const merged = merge(
427
434
  readTail(this.stdoutPath, this.stdoutFileSize),
428
435
  readTail(this.stderrPath, this.stderrFileSize),
429
436
  );
437
+ // Display-only path: scrub escape codes in direct mode, but never record
438
+ // a binary verdict from an arbitrary tail slice.
439
+ return this.direct ? inspectShellTextChunk(merged, 'stdout').text : merged;
430
440
  } catch {
431
441
  return '';
432
442
  }
433
443
  }
434
444
 
445
+ // Direct capture has NO JS write path, so the per-chunk ANSI/binary scrub
446
+ // writeStdout applies never runs. Doing it at read time keeps what the
447
+ // caller sees identical across both capture modes.
448
+ _sanitizeDirect(text, channel) {
449
+ if (!text) return text;
450
+ const inspected = inspectShellTextChunk(text, channel);
451
+ if (inspected.binary && !this.binaryOutput) {
452
+ this.binaryOutput = { channel, bytes: inspected.bytes };
453
+ return `[binary output on ${channel} sanitized; non-printable bytes removed]\n${inspected.text}`;
454
+ }
455
+ return inspected.text;
456
+ }
457
+
435
458
  async getStdout() {
436
459
  if (this.spilled) {
437
460
  this._refreshDirectSizes();
@@ -441,7 +464,8 @@ export class TaskOutput {
441
464
  this._lastStdoutFsyncMs = now;
442
465
  }
443
466
  try {
444
- return _readHeadTail(this.stdoutPath, this.stdoutFileSize);
467
+ const text = _readHeadTail(this.stdoutPath, this.stdoutFileSize);
468
+ return this.direct ? this._sanitizeDirect(text, 'stdout') : text;
445
469
  } catch (err) {
446
470
  throw new Error(`[shell-command] spilled stdout read failed (${this.stdoutPath}): ${err.message}`);
447
471
  }
@@ -458,7 +482,8 @@ export class TaskOutput {
458
482
  this._lastStderrFsyncMs = now;
459
483
  }
460
484
  try {
461
- return _readHeadTail(this.stderrPath, this.stderrFileSize);
485
+ const text = _readHeadTail(this.stderrPath, this.stderrFileSize);
486
+ return this.direct ? this._sanitizeDirect(text, 'stderr') : text;
462
487
  } catch {
463
488
  return '';
464
489
  }
@@ -535,10 +560,15 @@ export class ExecResult {
535
560
  // foreground command outlives autoBackgroundMs the call settles with
536
561
  // backgrounded:true + the jobId for manual task control. The
537
562
  // child stays owned by the CLI process; stdout/stderr keep flowing to
538
- // the spill files now adopted by the shell-jobs registry.
563
+ // the spill files now owned by the shell-jobs registry.
539
564
  this.backgrounded = opts.backgrounded === true;
540
565
  this.jobId = opts.jobId || null;
541
566
  this.backgroundMessage = opts.backgroundMessage || null;
567
+ // Survivors observed AFTER the shell process exited (process group on
568
+ // POSIX, process tree + held stdio on win32). Non-null means the command
569
+ // finished but left live descendants, which the caller turns into a
570
+ // tracked, cancellable task. See tools/lib/shell-descendants.mjs.
571
+ this.descendants = opts.descendants || null;
542
572
  }
543
573
  }
544
574
 
@@ -3,46 +3,62 @@
3
3
  import {
4
4
  extractHeredocBodies,
5
5
  extractShellCInner,
6
- getDestructiveCommandWarning,
7
6
  stripQuotedAndHeredoc,
8
7
  } from './destructive-warning.mjs';
9
8
  import { extractPowerShellCommandInner } from './shell-command.mjs';
10
9
  import { decodePowerShellEncodedCommand, isBlockedCommand, WRAPPER_NAMES } from './shell-policy.mjs';
11
10
 
12
- /** @typedef {'allow'|'warn-prompt'|'deny'} ExecPolicyDecision */
11
+ /** @typedef {'allow'|'deny'} ExecPolicyDecision */
13
12
 
14
13
  const EXEC_POLICY_DENY_PATTERNS = [
15
14
  /\b(curl|wget|fetch|Invoke-WebRequest|iwr)\b[^\n|&;]*\|[^\n|&;]*\b(sh|bash|zsh|dash|pwsh|powershell)(?:\.exe)?\b/i,
16
15
  /\|\s*(sh|bash|zsh|dash|pwsh|powershell)(?:\.exe)?\b/i,
17
16
  /\b(?:sh|bash|zsh|dash|pwsh|powershell)(?:\.exe)?\s+<\s*\(/i,
18
17
  /\bInvoke-Expression\b/i,
19
- /\biex\s+/i,
18
+ // PowerShell's Invoke-Expression alias. `… | iex` is the actual remote-exec
19
+ // shape and a bare `iex <expression>` executes text as code, so both deny.
20
+ // A LAUNCH of the Elixir REPL (`iex -S mix`, `iex script.exs`) is an
21
+ // ordinary program start and must stay allowed — hence the expression-only
22
+ // lookahead instead of the previous bare `iex\s+`.
23
+ /\|\s*iex\b/i,
24
+ /\biex\s+[$("'@]/i,
20
25
  /\bStart-Process\b[^\n]*\s-Verb\s+RunAs\b/i,
21
26
  ];
22
27
 
28
+ // Verbs with no non-destructive invocation. `dd` is deliberately ABSENT: the
29
+ // disk-destroying form (`of=/dev/<disk>`) is hard-blocked at every command
30
+ // position by shell-policy, while `dd if=/dev/zero of=file` is the ordinary
31
+ // way to create a fixed-size file and blocking it only cost retries.
23
32
  const EXEC_POLICY_DENY_COMMANDS = new Set([
24
- 'dd', 'diskpart', 'shutdown', 'reboot', 'halt', 'poweroff', 'init', 'telinit',
33
+ 'diskpart', 'shutdown', 'reboot', 'halt', 'poweroff', 'init', 'telinit',
25
34
  'mkfs', 'mkfs.ext4', 'mkfs.ntfs', 'format', 'fdisk', 'parted',
26
35
  ]);
27
36
 
28
- const _POLICY_RANK = { allow: 0, 'warn-prompt': 1, deny: 2 };
37
+ const _POLICY_RANK = { allow: 0, deny: 1 };
29
38
 
30
- function _firstCommandName(command) {
31
- const seg = String(command || '').split(/[;&|\n]+/)[0] || '';
32
- const tokens = seg.trim().split(/\s+/).filter(Boolean);
33
- let i = 0;
34
- while (i < tokens.length) {
35
- const t = tokens[i];
36
- if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(t)) { i++; continue; }
37
- if (WRAPPER_NAMES.has(t.toLowerCase())) {
38
- i++;
39
- while (i < tokens.length && (/^[-+]/.test(tokens[i]) || /^\d+[smhd]?$/.test(tokens[i]))) i++;
40
- continue;
39
+ // EVERY command position, not just the first: a deny-listed verb after `&&`,
40
+ // `;`, `|` or a newline is still an execution request, and reading only
41
+ // segment 0 let `true && shutdown /s` through. Callers pass quote-stripped
42
+ // text, so prose inside a string ("graceful shutdown") never reaches here.
43
+ function _commandNamesAtPositions(command) {
44
+ const names = [];
45
+ for (const seg of String(command || '').split(/[;&|\n]+/)) {
46
+ const tokens = seg.trim().split(/\s+/).filter(Boolean);
47
+ let i = 0;
48
+ while (i < tokens.length) {
49
+ const t = tokens[i];
50
+ if (/^[A-Za-z_][A-Za-z0-9_]*=/.test(t)) { i++; continue; }
51
+ if (WRAPPER_NAMES.has(t.toLowerCase())) {
52
+ i++;
53
+ while (i < tokens.length && (/^[-+]/.test(tokens[i]) || /^\d+[smhd]?$/.test(tokens[i]))) i++;
54
+ continue;
55
+ }
56
+ const base = t.replace(/^.*[\\/]/, '').toLowerCase();
57
+ names.push(base.replace(/\.(exe|cmd|bat|com)$/i, ''));
58
+ break;
41
59
  }
42
- const base = t.replace(/^.*[\\/]/, '').toLowerCase();
43
- return base.replace(/\.(exe|cmd|bat|com)$/i, '');
44
60
  }
45
- return null;
61
+ return names;
46
62
  }
47
63
 
48
64
  function classifyExecPolicy(command) {
@@ -70,14 +86,15 @@ function classifyExecPolicy(command) {
70
86
  return { decision: 'deny', reason: 'high-risk shell invocation (pipe-to-shell, elevated launcher, or remote-exec pattern)' };
71
87
  }
72
88
  }
73
- const name = _firstCommandName(text);
74
- if (name && EXEC_POLICY_DENY_COMMANDS.has(name)) {
75
- return { decision: 'deny', reason: `command "${name}" is not permitted without sandbox` };
76
- }
77
- const warn = getDestructiveCommandWarning(text);
78
- if (warn) {
79
- return { decision: 'warn-prompt', reason: warn };
89
+ for (const name of _commandNamesAtPositions(executableText)) {
90
+ if (EXEC_POLICY_DENY_COMMANDS.has(name)) {
91
+ return { decision: 'deny', reason: `command "${name}" is not permitted` };
92
+ }
80
93
  }
94
+ // Destructive-but-legitimate commands are NOT judged here. The caller
95
+ // computes that non-blocking warning once (getDedupedDestructiveWarnings)
96
+ // and prepends it to the result; deriving it again per scan target only
97
+ // produced throwaway passes on every shell call.
81
98
  return { decision: 'allow', reason: '' };
82
99
  }
83
100
 
@@ -99,7 +116,7 @@ export function evaluateExecPolicyFromTargets(targets) {
99
116
  return worst;
100
117
  }
101
118
 
102
- /** Pre-spawn block message — deny only. warn-prompt is non-blocking (see destructive-warning prepend). */
119
+ /** Pre-spawn block message — deny is the only decision this scan produces. */
103
120
  export function formatExecPolicyBlockMessage(policyResult) {
104
121
  const r = policyResult || { decision: 'allow' };
105
122
  if (r.decision === 'deny') {
@@ -63,7 +63,12 @@ const BLOCKED_PATTERNS = [
63
63
  /\bformat\s+[a-z]:/i,
64
64
  new RegExp(_CMD_START + '(?:shutdown|reboot|halt)\\b', 'i'),
65
65
  new RegExp(_CMD_START + 'mkfs(?:\\.|\\b)', 'i'),
66
- new RegExp(_CMD_START + 'dd\\s+[^\\n]*\\b(?:if|of)=/dev/', 'i'),
66
+ // Raw-device WRITES only. `if=/dev/…` is a read (`dd if=/dev/zero of=file`
67
+ // is the ordinary way to create a fixed-size file), and the standard sinks
68
+ // below cannot destroy anything, so the block is scoped to a device target
69
+ // that can actually overwrite a disk. Raw-device READS still surface as a
70
+ // non-blocking destructive warning.
71
+ new RegExp(_CMD_START + 'dd\\s+[^\\n]*\\bof=/dev/(?!(?:null|zero|stdout|stderr|full|tty)\\b)', 'i'),
67
72
  new RegExp(_CMD_START + 'diskpart\\b[^\\n]*\\bclean\\b', 'i'),
68
73
  /:\(\)\s*\{[^}]*:\|:&[^}]*\};\s*:/, // bash fork-bomb signature
69
74
  ];
@@ -1,26 +1,26 @@
1
1
  {
2
- "version": "0.1.4",
2
+ "version": "0.1.6",
3
3
  "_comment": "Synced from immutable spawn-v release assets.",
4
4
  "assets": {
5
5
  "darwin-arm64": {
6
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.4/mixdog-spawn-darwin-arm64",
7
- "sha256": "f73d404bc0c96ae00951a7da385556d55c982f540e32c01803515eeace140eb0"
6
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.6/mixdog-spawn-darwin-arm64",
7
+ "sha256": "87a86e53c65911515517fd9e3b0e80a6880bb2062667103c7686b7d44d4a661f"
8
8
  },
9
9
  "darwin-x64": {
10
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.4/mixdog-spawn-darwin-x64",
11
- "sha256": "1163c97df9122358826cd92988ac7974559a7dcf5af6058021c0c01ce7c4a73e"
10
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.6/mixdog-spawn-darwin-x64",
11
+ "sha256": "0e927dd76168d7c73327f06b12ce5bb629ca24a819570ce108c2bc46e814e1b0"
12
12
  },
13
13
  "linux-arm64": {
14
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.4/mixdog-spawn-linux-arm64",
15
- "sha256": "c1e0aca0110b70805516dc6e185a4987a8fbc0c0c38040a0133586281671163b"
14
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.6/mixdog-spawn-linux-arm64",
15
+ "sha256": "c3832c33a590dc974d0671c8e4305907bec111e0860f8ea90febf2255a7e247c"
16
16
  },
17
17
  "linux-x64": {
18
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.4/mixdog-spawn-linux-x64",
19
- "sha256": "020876e4021c6d4e4095f103c55626912c78ca4fe766e5393e24b7af827fc4e1"
18
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.6/mixdog-spawn-linux-x64",
19
+ "sha256": "5578f10626467a4a7be6bb348cdce6398f2eb8bf7391fa1e99b9404315f01d59"
20
20
  },
21
21
  "win32-x64": {
22
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.4/mixdog-spawn-win32-x64.exe",
23
- "sha256": "07aa98985587be6c086f97f32dea1273246ca407dde8f7d2a01ecaa87c8146aa"
22
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.6/mixdog-spawn-win32-x64.exe",
23
+ "sha256": "058fd8318b9fad6bc4213ed2255b436e7b78dc868d96dd060d67b806fef4d36e"
24
24
  }
25
25
  }
26
26
  }
@@ -138,10 +138,18 @@ export function readAttachmentBuffer(value) {
138
138
  const path = attachmentPath(ref);
139
139
  const cached = bufferCache.get(path);
140
140
  if (cached) {
141
- cacheHits += 1;
141
+ // The cache hands out the stored Buffer instance itself, so a caller that
142
+ // mutated an earlier read would poison every later reader with content that
143
+ // no longer matches the content address. Re-verify the digest on each hit
144
+ // instead of trusting the instance.
145
+ if (createHash('sha256').update(cached).digest('hex') === ref) {
146
+ cacheHits += 1;
147
+ bufferCache.delete(path);
148
+ bufferCache.set(path, cached);
149
+ return cached;
150
+ }
142
151
  bufferCache.delete(path);
143
- bufferCache.set(path, cached);
144
- return cached;
152
+ bufferCacheBytes -= cached.length;
145
153
  }
146
154
  cacheMisses += 1;
147
155
  const info = statSync(path);
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.8.4",
3
- "source": "ggml-org/whisper.cpp official release",
2
+ "version": "1.9.2",
3
+ "source": "ggml-org/whisper.cpp@306c88f4d1286aec1bf96e544632897886af5501",
4
4
  "model": {
5
5
  "id": "large-v3-turbo-q8_0",
6
6
  "filename": "ggml-large-v3-turbo-q8_0.bin",
@@ -15,13 +15,6 @@
15
15
  "url": "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3-turbo-q8_0.bin",
16
16
  "sha256": "317eb69c11673c9de1e1f0d459b253999804ec71ac4c23c17ecf5fbe24e259a1",
17
17
  "size": 874188075
18
- },
19
- "korean": {
20
- "id": "large-v3-turbo-korean-q8_0",
21
- "filename": "whisper-large-v3-turbo-korean-q8_0.bin",
22
- "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.8.4/whisper-large-v3-turbo-korean-q8_0.bin",
23
- "sha256": "b0590271b17d683aba5bbe4ada0c310d5c9031f4c165400423271e7273d30a90",
24
- "size": 874188075
25
18
  }
26
19
  },
27
20
  "ffmpeg": {
@@ -55,6 +48,13 @@
55
48
  "size": 29354986,
56
49
  "format": "gz",
57
50
  "executable": "ffmpeg"
51
+ },
52
+ "linux-arm64": {
53
+ "url": "https://github.com/eugeneware/ffmpeg-static/releases/download/b6.1.1/ffmpeg-linux-arm64.gz",
54
+ "sha256": "754a678672298bc68156adff58aa7385a592c2b30b1d0ae8750c45c915c4bac0",
55
+ "size": 25568691,
56
+ "format": "gz",
57
+ "executable": "ffmpeg"
58
58
  }
59
59
  }
60
60
  },
@@ -62,93 +62,69 @@
62
62
  "win32-x64": {
63
63
  "variants": [
64
64
  {
65
- "id": "cublas-12.4",
66
- "requires": { "cudaMajor": 12 },
67
- "url": "https://github.com/ggml-org/whisper.cpp/releases/download/v1.8.4/whisper-cublas-12.4.0-bin-x64.zip",
68
- "sha256": "b07cff4e59831b227896018facbb6334907bf324a342c84597c44f087823d252",
69
- "size": 457024596,
70
- "format": "zip",
71
- "executable": "Release/whisper-cli.exe"
72
- },
73
- {
74
- "id": "cublas-11.8",
75
- "requires": { "cudaMajor": 11 },
76
- "url": "https://github.com/ggml-org/whisper.cpp/releases/download/v1.8.4/whisper-cublas-11.8.0-bin-x64.zip",
77
- "sha256": "194480dd24606389c4eceb98d48292f37f59138192ae491ed4f38736cdb8888c",
78
- "size": 58787783,
79
- "format": "zip",
80
- "executable": "Release/whisper-cli.exe"
81
- },
82
- {
83
- "id": "cublas-11-bundled",
84
- "requires": { "nvidiaDriver": true },
85
- "url": "https://github.com/ggml-org/whisper.cpp/releases/download/v1.8.4/whisper-cublas-11.8.0-bin-x64.zip",
86
- "sha256": "194480dd24606389c4eceb98d48292f37f59138192ae491ed4f38736cdb8888c",
87
- "size": 58787783,
65
+ "id": "vulkan",
66
+ "requires": null,
67
+ "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.9.2/whisper-server-win32-x64-vulkan.zip",
68
+ "sha256": "6ee3718696033ddbc156201eb0c097b778d8aca7388233b54fd3a966cbcb9fee",
69
+ "size": 16751300,
88
70
  "format": "zip",
89
- "executable": "Release/whisper-cli.exe",
90
- "extras": [
91
- {
92
- "url": "https://files.pythonhosted.org/packages/0b/1d/7a78cd36fd5e3da4021b3ac2c2c8b2651dd72345b7c3ecc0d3e051884f50/nvidia_cublas_cu11-11.11.3.6-py3-none-win_amd64.whl",
93
- "sha256": "6ab12b1302bef8ac1ff4414edd1c059e57f4833abef9151683fb8f4de25900be",
94
- "size": 427234740,
95
- "format": "zip",
96
- "files": [
97
- { "from": "nvidia/cublas/bin/cublas64_11.dll", "to": "Release/cublas64_11.dll" },
98
- { "from": "nvidia/cublas/bin/cublasLt64_11.dll", "to": "Release/cublasLt64_11.dll" }
99
- ]
100
- }
101
- ]
102
- },
71
+ "executable": "whisper-server.exe"
72
+ }
73
+ ]
74
+ },
75
+ "linux-x64": {
76
+ "variants": [
103
77
  {
104
- "id": "base-cpu",
78
+ "id": "vulkan",
105
79
  "requires": null,
106
- "url": "https://github.com/ggml-org/whisper.cpp/releases/download/v1.8.4/whisper-bin-x64.zip",
107
- "sha256": "74f973345cb52ef5ba3ec9e7e7af8e48cc8c71722d1528603b80588a11f82e3e",
108
- "size": 4078768,
80
+ "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.9.2/whisper-server-linux-x64-vulkan.zip",
81
+ "sha256": "c3cbf695ebc818546a8ef4d3657ef74378781948b8ff62e7f2bf1da70ccdc639",
82
+ "size": 14461318,
109
83
  "format": "zip",
110
- "executable": "Release/whisper-cli.exe"
84
+ "executable": "whisper-server"
111
85
  }
112
86
  ]
113
87
  },
114
- "darwin-arm64": {
88
+ "linux-arm64": {
115
89
  "variants": [
116
90
  {
117
- "id": "metal",
91
+ "id": "vulkan",
118
92
  "requires": null,
119
- "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.8.4/whisper-darwin-arm64-metal.zip",
120
- "sha256": "6bfbe8e06c07b87c2d7cd9a6541128781752bd2827d9f97ea9605d06c53835d7",
121
- "size": 3147446,
93
+ "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.9.2/whisper-server-linux-arm64-vulkan.zip",
94
+ "sha256": "73fc8ac7fdbc1e68ebb4a2c27faaf3c1145fcf7f4b0f04f32fdeb26bc66b20eb",
95
+ "size": 14274639,
122
96
  "format": "zip",
123
- "executable": "Release/whisper-cli"
97
+ "executable": "whisper-server"
124
98
  }
125
99
  ]
126
100
  },
127
- "darwin-x64": {
101
+ "darwin-arm64": {
128
102
  "variants": [
129
103
  {
130
- "id": "cpu",
104
+ "id": "metal",
131
105
  "requires": null,
132
- "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.8.4/whisper-darwin-x64-cpu.zip",
133
- "sha256": "eed4606e4333dacaafa3ed5a982856db98dcf7d7300200b831c71bedd6fe05e1",
134
- "size": 3041846,
106
+ "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.9.2/whisper-server-darwin-arm64-metal.zip",
107
+ "sha256": "2ebd9eec5b991716c230f9d4dace8db952f99f0faf8ca1ef3b3a5b4a1b106401",
108
+ "size": 1350283,
135
109
  "format": "zip",
136
- "executable": "Release/whisper-cli"
110
+ "executable": "whisper-server"
137
111
  }
138
112
  ]
139
113
  },
140
- "linux-x64": {
114
+ "darwin-x64": {
141
115
  "variants": [
142
116
  {
143
- "id": "vulkan",
117
+ "id": "cpu",
144
118
  "requires": null,
145
- "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.8.4/whisper-linux-x64-vulkan.zip",
146
- "sha256": "f378ad30db89b8bb710210b057539f9b18f4cdecceac093ff189ce7e904fe6de",
147
- "size": 54510528,
119
+ "url": "https://github.com/tribgames/mixdog/releases/download/voice-runtime-v1.9.2/whisper-server-darwin-x64-cpu.zip",
120
+ "sha256": "4d39a13874c380e28ae25ff922673bf8869e6e756f49e866a67e7a86ec8088a5",
121
+ "size": 1346377,
148
122
  "format": "zip",
149
- "executable": "Release/whisper-cli"
123
+ "executable": "whisper-server"
150
124
  }
151
125
  ]
152
126
  }
153
- }
127
+ },
128
+ "release_tag": "voice-runtime-v1.9.2",
129
+ "build_hash": "3705f8c9636467bb1ff9722b409dcc888bd7271e3774f13b0bc3ec64cc3d2822"
154
130
  }