mixdog 0.9.160 → 0.9.161

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 (648) hide show
  1. package/README.md +3 -1
  2. package/package.json +16 -7
  3. package/scripts/lib/local-provider-live-scenarios.mjs +22 -0
  4. package/scripts/lib/test-timing-reporter.mjs +38 -0
  5. package/scripts/local-provider-live-check.mjs +141 -0
  6. package/scripts/office/aesthetics-probe.mjs +59 -0
  7. package/scripts/office/author-deck.mjs +56 -0
  8. package/scripts/office/build-pptx-icons.mjs +48 -0
  9. package/scripts/office-live-test-plan.mjs +34 -0
  10. package/scripts/pdf-rotation-stress.mjs +74 -0
  11. package/scripts/perf/cold-reconnect-probe.mjs +109 -0
  12. package/scripts/perf/transcript-baseline.mjs +56 -0
  13. package/scripts/perf/transcript-runtime-probe.mjs +62 -0
  14. package/scripts/release-paths.mjs +8 -38
  15. package/scripts/run-advisory-spec.mjs +6 -0
  16. package/scripts/run-office-live-tests.mjs +51 -18
  17. package/scripts/suite-health.mjs +3 -5
  18. package/scripts/test.mjs +100 -0
  19. package/src/app.mjs +2 -14
  20. package/src/defaults/cycle3-review-prompt.md +32 -14
  21. package/src/defaults/plugin.json +6 -0
  22. package/src/defaults/skills/browser-use/SKILL.md +159 -0
  23. package/src/defaults/skills/computer-use/SKILL.md +157 -0
  24. package/src/defaults/skills/docx/SKILL.md +52 -0
  25. package/src/defaults/skills/image/SKILL.md +94 -0
  26. package/src/defaults/skills/local-provider/SKILL.md +115 -0
  27. package/src/defaults/skills/pdf/SKILL.md +51 -0
  28. package/src/defaults/skills/pptx/SKILL.md +145 -0
  29. package/src/defaults/skills/pptx/references/charts.md +153 -0
  30. package/src/defaults/skills/pptx/references/composition.md +182 -0
  31. package/src/defaults/skills/pptx/references/direction.md +70 -0
  32. package/src/defaults/skills/pptx/references/kit.md +551 -0
  33. package/src/defaults/skills/pptx/references/pictures.md +76 -0
  34. package/src/defaults/skills/pptx/references/review.md +104 -0
  35. package/src/defaults/skills/pptx/scripts/qc-pages.mjs +368 -0
  36. package/src/defaults/skills/pptx/scripts/review-deck.mjs +155 -0
  37. package/src/defaults/skills/pptx/scripts/source-extract.mjs +121 -0
  38. package/src/defaults/skills/setup/SKILL.md +86 -460
  39. package/src/defaults/skills/setup/references/actions.md +127 -0
  40. package/src/defaults/skills/setup/references/surfaces.md +72 -0
  41. package/src/defaults/skills/skill-creator/SKILL.md +191 -0
  42. package/src/defaults/skills/skill-creator/references/design.md +182 -0
  43. package/src/defaults/skills/skill-creator/references/evaluation.md +111 -0
  44. package/src/defaults/skills/skill-creator/references/source-review.md +94 -0
  45. package/src/defaults/skills/skill-creator/scripts/validate-skill.mjs +166 -0
  46. package/src/defaults/skills/video/SKILL.md +63 -0
  47. package/src/defaults/skills/xlsx/SKILL.md +72 -0
  48. package/src/defaults/skills/xlsx/references/model-conventions.md +52 -0
  49. package/src/headless-exec.mjs +1 -4
  50. package/src/headless-role.mjs +2 -5
  51. package/src/help.mjs +1 -1
  52. package/src/lib/output-style-meta.cjs +5 -1
  53. package/src/lib/rules-builder.cjs +24 -23
  54. package/src/mixdog-session-runtime.mjs +16 -7
  55. package/src/output-styles/extreme-minimal.md +1 -1
  56. package/src/rules/lead/01-general.md +5 -4
  57. package/src/rules/shared/00-general.md +4 -0
  58. package/src/rules/shared/30-exploration.md +2 -1
  59. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +2 -2
  60. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +1 -6
  61. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -63
  62. package/src/runtime/agent/orchestrator/agent-runtime/completion-text.mjs +13 -0
  63. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +0 -1
  64. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +4 -15
  65. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -1
  66. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +1 -2
  67. package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -4
  68. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +1 -1
  69. package/src/runtime/agent/orchestrator/config.mjs +64 -7
  70. package/src/runtime/agent/orchestrator/context/collect.mjs +122 -58
  71. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/internal-tools.mjs +0 -5
  73. package/src/runtime/agent/orchestrator/mcp/client.mjs +2 -34
  74. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +5 -16
  75. package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +10 -0
  76. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +7 -0
  77. package/src/runtime/agent/orchestrator/providers/anthropic-fable-history.mjs +77 -0
  78. package/src/runtime/agent/orchestrator/providers/anthropic-leaked-toolcall.mjs +1 -1
  79. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +1 -15
  80. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +14 -63
  81. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +5 -5
  82. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -136
  84. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +100 -43
  85. package/src/runtime/agent/orchestrator/providers/anthropic-thinking-contract.mjs +13 -0
  86. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +50 -42
  87. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +5 -22
  88. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +7 -10
  89. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +2 -85
  90. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +91 -0
  91. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +4 -19
  92. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +21 -0
  93. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +63 -6
  95. package/src/runtime/agent/orchestrator/providers/cursor-wire-normalization.mjs +12 -7
  96. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +27 -7
  97. package/src/runtime/agent/orchestrator/providers/cursor.mjs +16 -10
  98. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +150 -0
  99. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +1 -1
  100. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +29 -0
  101. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +5 -4
  102. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +5 -6
  103. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +48 -0
  104. package/src/runtime/agent/orchestrator/providers/gemini.mjs +23 -26
  105. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +5 -36
  106. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +19 -38
  107. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -7
  108. package/src/runtime/agent/orchestrator/providers/lib/anthropic-image-input.mjs +105 -0
  109. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +50 -94
  110. package/src/runtime/agent/orchestrator/providers/lib/json-memory-cache.mjs +27 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/oauth-pkce.mjs +27 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +29 -0
  113. package/src/runtime/agent/orchestrator/providers/lib/provider-replay.mjs +9 -6
  114. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +143 -0
  115. package/src/runtime/agent/orchestrator/providers/mixdog-local-wire.mjs +25 -0
  116. package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +79 -0
  117. package/src/runtime/agent/orchestrator/providers/model-catalog-projection.mjs +8 -0
  118. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +18 -1
  119. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -2
  120. package/src/runtime/agent/orchestrator/providers/model-service-tiers.mjs +11 -0
  121. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +1 -1
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +0 -8
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +205 -0
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +5 -3
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +17 -14
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +1 -1
  127. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +22 -25
  128. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +18 -0
  129. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +2 -15
  130. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +4 -29
  131. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +3 -4
  132. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +48 -84
  133. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +152 -0
  134. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +15 -243
  135. package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +1 -36
  136. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +2 -3
  137. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +6 -38
  138. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +7 -20
  139. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +44 -19
  140. package/src/runtime/agent/orchestrator/providers/registry.mjs +15 -0
  141. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +44 -5
  142. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +0 -5
  143. package/src/runtime/agent/orchestrator/providers/stream-json-pool.mjs +2 -6
  144. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +41 -57
  145. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +38 -11
  146. package/src/runtime/agent/orchestrator/session/cache/util.mjs +3 -3
  147. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +1 -112
  148. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +1 -1
  149. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +7 -2
  150. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +3 -5
  151. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +0 -12
  152. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +18 -23
  153. package/src/runtime/agent/orchestrator/session/context-fingerprint.mjs +54 -0
  154. package/src/runtime/agent/orchestrator/session/context-utils.mjs +9 -58
  155. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -5
  156. package/src/runtime/agent/orchestrator/session/evidence-union.mjs +3 -7
  157. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -8
  158. package/src/runtime/agent/orchestrator/session/loop/arg-schema-coerce.mjs +92 -0
  159. package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +2 -10
  160. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +38 -63
  161. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +14 -14
  162. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  163. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +17 -0
  164. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +5 -2
  165. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +6 -1
  166. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +7 -2
  167. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +87 -38
  168. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -14
  169. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +30 -33
  170. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +355 -0
  171. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -6
  172. package/src/runtime/agent/orchestrator/session/manager/message-sanitize.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +324 -0
  174. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +62 -688
  175. package/src/runtime/agent/orchestrator/session/manager/prompt-surface-publish.mjs +35 -0
  176. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +15 -2
  177. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +38 -79
  178. package/src/runtime/agent/orchestrator/session/manager/rules-source-cache.mjs +61 -0
  179. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +44 -14
  181. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
  182. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +3 -3
  183. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +2 -28
  184. package/src/runtime/agent/orchestrator/session/manager.mjs +1 -0
  185. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +1 -1
  186. package/src/runtime/agent/orchestrator/session/result-classification.mjs +0 -67
  187. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -0
  188. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +62 -0
  189. package/src/runtime/agent/orchestrator/session/store/fs-probe.mjs +1 -20
  190. package/src/runtime/agent/orchestrator/session/store/listing.mjs +60 -9
  191. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +0 -19
  192. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +0 -11
  193. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +117 -134
  194. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +4 -4
  195. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +131 -0
  196. package/src/runtime/agent/orchestrator/session/store.mjs +20 -46
  197. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +133 -0
  198. package/src/runtime/agent/orchestrator/session/thinking-replay-recovery.mjs +1 -4
  199. package/src/runtime/agent/orchestrator/session/token-estimate-floors.mjs +34 -0
  200. package/src/runtime/agent/orchestrator/session/token-estimate.mjs +3 -36
  201. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +4 -0
  202. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +5 -5
  203. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +1 -7
  204. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +2 -1
  205. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +1 -1
  206. package/src/runtime/agent/orchestrator/tools/builtin/binary-file.mjs +0 -25
  207. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -5
  208. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +2 -7
  209. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +1 -5
  210. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +19 -0
  211. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +1 -2
  212. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +1 -1
  213. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +26 -2
  214. package/src/runtime/agent/orchestrator/tools/builtin/local-search-telemetry.mjs +0 -9
  215. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +0 -20
  216. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -6
  217. package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +7 -16
  218. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +1 -14
  219. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  220. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +5 -22
  221. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +0 -1
  222. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/search-admission.mjs +1 -1
  224. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-tool.mjs +17 -75
  225. package/src/runtime/agent/orchestrator/tools/builtin/search-grep-tool.mjs +3 -19
  226. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +4 -57
  227. package/src/runtime/agent/orchestrator/tools/builtin/shell-lossless-compact.mjs +0 -12
  228. package/src/runtime/agent/orchestrator/tools/builtin/shell-output.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +1 -1
  230. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +1 -7
  231. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +3 -25
  232. package/src/runtime/agent/orchestrator/tools/builtin.mjs +9 -7
  233. package/src/runtime/agent/orchestrator/tools/code-graph/aggregate-roots.mjs +276 -0
  234. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +38 -16
  235. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +11 -3
  236. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +23 -355
  237. package/src/runtime/agent/orchestrator/tools/code-graph/exact-file-graph.mjs +92 -0
  238. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  239. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +1 -11
  240. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +2 -4
  241. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +8 -0
  242. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  243. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +51 -124
  244. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +2 -68
  245. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +1 -10
  246. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +0 -1
  247. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +1 -2
  248. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +2 -1
  249. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -1
  250. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +2 -14
  251. package/src/runtime/agent/orchestrator/tools/patch-binary-fetcher.mjs +57 -138
  252. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +4 -0
  253. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +2 -2
  254. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +4 -8
  255. package/src/runtime/agent/orchestrator/tools/spawn-binary-fetcher.mjs +45 -122
  256. package/src/runtime/attachments/pdf-extract.mjs +14 -6
  257. package/src/runtime/attachments/pdfjs-runtime.mjs +12 -0
  258. package/src/runtime/attachments/store.mjs +8 -8
  259. package/src/runtime/bridge-discovery.mjs +67 -0
  260. package/src/runtime/browser-bridge/action-schema.d.mts +6 -0
  261. package/src/runtime/browser-bridge/action-schema.mjs +6 -2
  262. package/src/runtime/browser-bridge/client.mjs +18 -31
  263. package/src/runtime/browser-bridge/tool-defs.mjs +12 -3
  264. package/src/runtime/channels/lib/boot-profile.mjs +3 -16
  265. package/src/runtime/channels/lib/config.mjs +0 -1
  266. package/src/runtime/channels/lib/runtime-paths.mjs +2 -15
  267. package/src/runtime/channels/lib/scheduler.mjs +0 -15
  268. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +7 -59
  269. package/src/runtime/channels/lib/worker-main.mjs +2 -30
  270. package/src/runtime/computer-bridge/action-schema.mjs +7 -5
  271. package/src/runtime/computer-bridge/actions.d.mts +6 -0
  272. package/src/runtime/computer-bridge/actions.mjs +75 -0
  273. package/src/runtime/computer-bridge/client.mjs +21 -39
  274. package/src/runtime/computer-bridge/core-actions.mjs +2 -3
  275. package/src/runtime/computer-bridge/error-recovery.mjs +15 -3
  276. package/src/runtime/computer-bridge/limits.d.mts +8 -0
  277. package/src/runtime/computer-bridge/limits.mjs +67 -0
  278. package/src/runtime/computer-bridge/tool-defs.mjs +10 -16
  279. package/src/runtime/github/client.d.mts +17 -0
  280. package/src/runtime/github/client.mjs +127 -0
  281. package/src/runtime/github/commands.mjs +106 -0
  282. package/src/runtime/github/contract.d.mts +58 -0
  283. package/src/runtime/github/contract.mjs +147 -0
  284. package/src/runtime/github/tool.mjs +64 -0
  285. package/src/runtime/local-provider/asset-installer.mjs +261 -0
  286. package/src/runtime/local-provider/asset-storage.mjs +36 -0
  287. package/src/runtime/local-provider/catalog.mjs +151 -0
  288. package/src/runtime/local-provider/data/manifest.json +48 -0
  289. package/src/runtime/local-provider/gguf-header.mjs +92 -0
  290. package/src/runtime/local-provider/hardware.mjs +83 -0
  291. package/src/runtime/local-provider/hugging-face.mjs +111 -0
  292. package/src/runtime/local-provider/input-capabilities.mjs +19 -0
  293. package/src/runtime/local-provider/install-progress.mjs +77 -0
  294. package/src/runtime/local-provider/managed-runtime.mjs +45 -0
  295. package/src/runtime/local-provider/model-maintenance.mjs +114 -0
  296. package/src/runtime/local-provider/model-state.mjs +53 -0
  297. package/src/runtime/local-provider/registered-models.mjs +67 -0
  298. package/src/runtime/local-provider/request-queue.mjs +125 -0
  299. package/src/runtime/local-provider/resumable-installations.mjs +27 -0
  300. package/src/runtime/local-provider/server-process.mjs +209 -0
  301. package/src/runtime/local-provider/server.mjs +99 -0
  302. package/src/runtime/media/download.mjs +1 -1
  303. package/src/runtime/media/lanes.mjs +1 -1
  304. package/src/runtime/media/renditions.mjs +1 -1
  305. package/src/runtime/media/store.mjs +1 -1
  306. package/src/runtime/media/tool-defs.mjs +40 -0
  307. package/src/runtime/media/tool.mjs +277 -0
  308. package/src/runtime/memory/index.mjs +11 -29
  309. package/src/runtime/memory/lib/core-memory-candidates.mjs +0 -5
  310. package/src/runtime/memory/lib/core-memory-file.mjs +2 -2
  311. package/src/runtime/memory/lib/core-memory-store.mjs +37 -8
  312. package/src/runtime/memory/lib/cycle-scheduler.mjs +16 -2
  313. package/src/runtime/memory/lib/embedding-model-config.mjs +2 -4
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +2 -4
  315. package/src/runtime/memory/lib/http-router.mjs +13 -1
  316. package/src/runtime/memory/lib/http-wire.mjs +1 -1
  317. package/src/runtime/memory/lib/memory-action-handlers.mjs +4 -1
  318. package/src/runtime/memory/lib/memory-config-flags.mjs +8 -12
  319. package/src/runtime/memory/lib/memory-cycle-requests.mjs +0 -40
  320. package/src/runtime/memory/lib/memory-cycle1.mjs +1 -5
  321. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +30 -9
  322. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +35 -4
  323. package/src/runtime/memory/lib/memory-cycle2.mjs +1 -1
  324. package/src/runtime/memory/lib/memory-cycle3-evidence.mjs +117 -0
  325. package/src/runtime/memory/lib/memory-cycle3-guards.mjs +272 -0
  326. package/src/runtime/memory/lib/memory-cycle3.mjs +81 -238
  327. package/src/runtime/memory/lib/memory-embed.mjs +1 -4
  328. package/src/runtime/memory/lib/memory-score.mjs +0 -13
  329. package/src/runtime/memory/lib/memory-text-utils.mjs +7 -1
  330. package/src/runtime/memory/lib/pg/adapter.mjs +2 -2
  331. package/src/runtime/memory/lib/phase-merge-verdicts.mjs +54 -0
  332. package/src/runtime/memory/lib/prompt-surface-file.mjs +98 -0
  333. package/src/runtime/memory/lib/query-handlers.mjs +4 -1
  334. package/src/runtime/memory/lib/recall-embedding-readiness.mjs +1 -1
  335. package/src/runtime/memory/lib/recall-format.mjs +15 -7
  336. package/src/runtime/memory/lib/recall-order.mjs +6 -0
  337. package/src/runtime/memory/lib/runtime-fetcher.mjs +25 -52
  338. package/src/runtime/memory/lib/session-ingest.mjs +3 -3
  339. package/src/runtime/memory/lib/trace-mode.mjs +1 -1
  340. package/src/runtime/memory/lib/trace-store.mjs +1 -10
  341. package/src/runtime/memory/lib/transcript-ingest.mjs +2 -2
  342. package/src/runtime/office/README.md +14 -9
  343. package/src/runtime/office/authoring/pptx-author-action.mjs +166 -0
  344. package/src/runtime/office/authoring/pptx-author-session.mjs +112 -0
  345. package/src/runtime/office/authoring/pptx-brief.mjs +270 -0
  346. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +54 -0
  347. package/src/runtime/office/authoring/pptx-icons.json +1 -0
  348. package/src/runtime/office/authoring/pptx-icons.mjs +50 -0
  349. package/src/runtime/office/authoring/pptx-kit.mjs +33 -0
  350. package/src/runtime/office/authoring/pptx-receipt.mjs +388 -0
  351. package/src/runtime/office/authoring/pptx-review-artifacts.mjs +32 -0
  352. package/src/runtime/office/authoring/pptx-script-contract.mjs +15 -0
  353. package/src/runtime/office/authoring/pptx-script-normalize.mjs +244 -0
  354. package/src/runtime/office/authoring/pptx-script-runner.mjs +142 -0
  355. package/src/runtime/office/bench/assurance-benchmark.mjs +5 -95
  356. package/src/runtime/office/bench/bench-support.mjs +1 -1
  357. package/src/runtime/office/bench/benchmark.mjs +1 -1
  358. package/src/runtime/office/bench/contract-benchmark.mjs +2 -2
  359. package/src/runtime/office/bench/deck-bench.mjs +78 -0
  360. package/src/runtime/office/bench/quality-live-benchmark.mjs +3 -201
  361. package/src/runtime/office/capabilities.mjs +104 -44
  362. package/src/runtime/office/com/com-adapter.mjs +56 -48
  363. package/src/runtime/office/com/office-com-cleanup.ps1 +126 -0
  364. package/src/runtime/office/com/office-com-host.ps1 +361 -79
  365. package/src/runtime/office/com/office-com-session-host.ps1 +117 -90
  366. package/src/runtime/office/com/office-session-client.mjs +91 -0
  367. package/src/runtime/office/core/journal.mjs +1 -1
  368. package/src/runtime/office/core/office-actions-batch.mjs +35 -3
  369. package/src/runtime/office/core/office-actions-inspect.mjs +7 -0
  370. package/src/runtime/office/core/office-actions-lifecycle.mjs +48 -21
  371. package/src/runtime/office/core/office-actions-render.mjs +53 -81
  372. package/src/runtime/office/core/office-actions.mjs +1 -1
  373. package/src/runtime/office/core/office-core.mjs +25 -4
  374. package/src/runtime/office/core/office-render-preview.mjs +160 -0
  375. package/src/runtime/office/core/office-sessions.mjs +135 -3
  376. package/src/runtime/office/core/office-transactions.mjs +1 -0
  377. package/src/runtime/office/core/pptx-page-cache.mjs +70 -0
  378. package/src/runtime/office/core/snapshot-contract.mjs +28 -0
  379. package/src/runtime/office/design/composition-system.mjs +1 -1
  380. package/src/runtime/office/design/design-art-direction.mjs +51 -42
  381. package/src/runtime/office/design/design-creative-director.mjs +6 -46
  382. package/src/runtime/office/design/design-discipline.mjs +310 -0
  383. package/src/runtime/office/design/design-system.mjs +12 -101
  384. package/src/runtime/office/design/design-tokens.mjs +32 -30
  385. package/src/runtime/office/design/library/design-library-core.mjs +5 -6
  386. package/src/runtime/office/design/library/design-library.mjs +1 -1
  387. package/src/runtime/office/index.mjs +89 -27
  388. package/src/runtime/office/pdf/pdf-adapter.mjs +590 -357
  389. package/src/runtime/office/pdf/pdf-analysis.mjs +368 -64
  390. package/src/runtime/office/pdf/pdf-draw.mjs +91 -0
  391. package/src/runtime/office/pdf/pdf-fonts.mjs +91 -0
  392. package/src/runtime/office/pdf/pdf-forms.mjs +265 -0
  393. package/src/runtime/office/pdf/pdf-render.mjs +42 -36
  394. package/src/runtime/office/pdf/pdf-safety.mjs +50 -0
  395. package/src/runtime/office/pdf/pdf-search.mjs +187 -0
  396. package/src/runtime/office/pdf/pdf-security.mjs +7 -3
  397. package/src/runtime/office/pdf/pdf-writer.mjs +195 -0
  398. package/src/runtime/office/portable/docx-revisions.mjs +474 -0
  399. package/src/runtime/office/portable/docx-runs.mjs +293 -0
  400. package/src/runtime/office/portable/docx-tracked-edits.mjs +165 -0
  401. package/src/runtime/office/portable/font-provisioner.mjs +210 -0
  402. package/src/runtime/office/portable/ooxml-validator.mjs +26 -3
  403. package/src/runtime/office/portable/portable-cells.mjs +10 -1
  404. package/src/runtime/office/portable/portable-chart-faults.mjs +96 -0
  405. package/src/runtime/office/portable/portable-chart.mjs +3 -3
  406. package/src/runtime/office/portable/portable-docx-parts.mjs +97 -0
  407. package/src/runtime/office/portable/portable-docx-xml.mjs +2 -2
  408. package/src/runtime/office/portable/portable-docx.mjs +211 -36
  409. package/src/runtime/office/portable/portable-opc.mjs +11 -3
  410. package/src/runtime/office/portable/portable-package.mjs +1 -1
  411. package/src/runtime/office/portable/portable-pivot.mjs +1 -1
  412. package/src/runtime/office/portable/portable-pptx-chart.mjs +4 -2
  413. package/src/runtime/office/portable/portable-pptx-charts.mjs +5 -19
  414. package/src/runtime/office/portable/portable-pptx-core.mjs +14 -3
  415. package/src/runtime/office/portable/portable-pptx-package.mjs +62 -5
  416. package/src/runtime/office/portable/portable-pptx-shapes.mjs +1 -1
  417. package/src/runtime/office/portable/portable-pptx.mjs +11 -2
  418. package/src/runtime/office/portable/portable-sheet-styles.mjs +70 -0
  419. package/src/runtime/office/portable/portable-slide-shapes.mjs +1 -1
  420. package/src/runtime/office/portable/portable-snapshot.mjs +254 -27
  421. package/src/runtime/office/portable/portable-soffice.mjs +45 -1
  422. package/src/runtime/office/portable/portable-validation.mjs +73 -34
  423. package/src/runtime/office/portable/portable-xlsx.mjs +3 -1
  424. package/src/runtime/office/portable/portable-xml.mjs +20 -0
  425. package/src/runtime/office/portable/pptx-relations.mjs +92 -0
  426. package/src/runtime/office/portable/pptx-targets.mjs +30 -0
  427. package/src/runtime/office/portable/review-editability.mjs +111 -0
  428. package/src/runtime/office/portable/text-metrics.mjs +232 -28
  429. package/src/runtime/office/portable/xlsx-assertions.mjs +3 -15
  430. package/src/runtime/office/portable/xlsx-audit-support.mjs +132 -0
  431. package/src/runtime/office/portable/xlsx-contract.mjs +49 -5
  432. package/src/runtime/office/portable/xlsx-conventions.mjs +75 -0
  433. package/src/runtime/office/portable/xlsx-formula-audit.mjs +247 -0
  434. package/src/runtime/office/portable/xlsx-sheet-hygiene.mjs +100 -0
  435. package/src/runtime/office/quality/assurance-rendered.mjs +17 -2
  436. package/src/runtime/office/quality/assurance-structure.mjs +86 -15
  437. package/src/runtime/office/quality/design-aesthetics-metrics.mjs +271 -0
  438. package/src/runtime/office/quality/design-aesthetics.mjs +46 -218
  439. package/src/runtime/office/quality/design-deck-diversity.mjs +31 -1
  440. package/src/runtime/office/quality/design-review-authored.mjs +113 -0
  441. package/src/runtime/office/quality/design-review-critique.mjs +120 -0
  442. package/src/runtime/office/quality/design-review.mjs +140 -117
  443. package/src/runtime/office/quality/inline-audit.mjs +139 -0
  444. package/src/runtime/office/quality/pptx-deck-rubric.mjs +93 -0
  445. package/src/runtime/office/quality/pptx-slide-roles.mjs +136 -0
  446. package/src/runtime/office/quality/quality-pipeline.mjs +131 -5
  447. package/src/runtime/office/quality/render-air.mjs +114 -0
  448. package/src/runtime/office/tool-defs.mjs +35 -29
  449. package/src/runtime/shared/agent-route-config.mjs +3 -3
  450. package/src/runtime/shared/atomic-file.mjs +27 -20
  451. package/src/runtime/shared/background-tasks.mjs +2 -37
  452. package/src/runtime/shared/boot-profile.mjs +26 -0
  453. package/src/runtime/shared/bounded-download.mjs +40 -0
  454. package/src/runtime/shared/bridge-tool-args.mjs +1 -1
  455. package/src/runtime/shared/buffered-appender.mjs +1 -1
  456. package/src/runtime/shared/child-guardian.mjs +1 -5
  457. package/src/runtime/shared/child-spawn-gate.mjs +2 -2
  458. package/src/runtime/shared/clean.mjs +5 -0
  459. package/src/runtime/shared/config.mjs +8 -30
  460. package/src/runtime/shared/edit-tool-dialect.mjs +19 -6
  461. package/src/runtime/shared/env.mjs +41 -0
  462. package/src/runtime/shared/err-text.mjs +15 -5
  463. package/src/runtime/shared/error-presentation.mjs +101 -0
  464. package/src/runtime/shared/extension-scopes.mjs +139 -0
  465. package/src/runtime/shared/json-file.mjs +6 -0
  466. package/src/runtime/shared/llm/cost.mjs +2 -2
  467. package/src/runtime/shared/llm/http-agent.mjs +18 -6
  468. package/src/runtime/shared/markdown-frontmatter.mjs +2 -4
  469. package/src/runtime/shared/memory-snapshot.mjs +0 -4
  470. package/src/runtime/shared/native-asset.mjs +149 -0
  471. package/src/runtime/shared/numbers.mjs +12 -0
  472. package/src/runtime/shared/object.mjs +7 -0
  473. package/src/runtime/shared/owner-fair-gate.mjs +1 -5
  474. package/src/runtime/shared/plugin-manifest.mjs +44 -0
  475. package/src/runtime/shared/pristine-execution.mjs +4 -7
  476. package/src/runtime/shared/process-lifecycle.mjs +1 -5
  477. package/src/runtime/shared/resource-admission.mjs +4 -7
  478. package/src/runtime/shared/service-discovery.mjs +1 -22
  479. package/src/runtime/shared/session-runtime-health.mjs +15 -1
  480. package/src/runtime/shared/skill-document.mjs +36 -8
  481. package/src/runtime/shared/task-notification-envelope.mjs +0 -25
  482. package/src/runtime/shared/time-format.mjs +1 -1
  483. package/src/runtime/shared/tool-execution-contract.mjs +29 -7
  484. package/src/runtime/shared/tool-result-summary.mjs +1 -1
  485. package/src/runtime/shared/tool-surface.mjs +21 -21
  486. package/src/runtime/shared/tool-workload-gates.mjs +1 -5
  487. package/src/runtime/shared/transcript-writer.mjs +5 -2
  488. package/src/runtime/shared/transport-error-text.mjs +128 -0
  489. package/src/runtime/shared/turn-snapshot-store.mjs +81 -7
  490. package/src/runtime/shared/turn-snapshot.mjs +147 -19
  491. package/src/runtime/shared/user-data-guard.mjs +1 -73
  492. package/src/runtime/web-search/lib/web-tools.mjs +0 -157
  493. package/src/session-runtime/agent-tool-routing.mjs +56 -0
  494. package/src/session-runtime/boot-profile.mjs +6 -18
  495. package/src/session-runtime/builtin-features.d.mts +8 -0
  496. package/src/session-runtime/builtin-features.mjs +42 -4
  497. package/src/session-runtime/config-helpers.mjs +1 -1
  498. package/src/session-runtime/context-status.mjs +44 -11
  499. package/src/session-runtime/effort.mjs +28 -32
  500. package/src/session-runtime/extension-scopes.mjs +94 -0
  501. package/src/session-runtime/fs-utils.mjs +1 -3
  502. package/src/session-runtime/goal-facade-api.mjs +52 -0
  503. package/src/session-runtime/goal-reminder.mjs +12 -5
  504. package/src/session-runtime/goal-runtime.mjs +196 -305
  505. package/src/session-runtime/goal-storage.mjs +60 -0
  506. package/src/session-runtime/goal-tasks.mjs +125 -0
  507. package/src/session-runtime/goal-text.mjs +8 -5
  508. package/src/session-runtime/goal-tool-defs.mjs +91 -0
  509. package/src/session-runtime/hitch-profile.mjs +1 -1
  510. package/src/session-runtime/hook-payload.mjs +32 -0
  511. package/src/session-runtime/internal-tool-executor.mjs +171 -0
  512. package/src/session-runtime/lifecycle-api.mjs +7 -2
  513. package/src/session-runtime/local-model-api.mjs +22 -0
  514. package/src/session-runtime/local-provider-settings.mjs +49 -0
  515. package/src/session-runtime/mcp-glue.mjs +8 -3
  516. package/src/session-runtime/model-capabilities.mjs +3 -15
  517. package/src/session-runtime/model-recency.mjs +3 -0
  518. package/src/session-runtime/model-route-api.mjs +26 -51
  519. package/src/session-runtime/native-teardown.mjs +42 -0
  520. package/src/session-runtime/notification-bus.mjs +13 -1
  521. package/src/session-runtime/plugin-mcp.mjs +9 -30
  522. package/src/session-runtime/provider-auth-api.mjs +2 -13
  523. package/src/session-runtime/provider-models.mjs +5 -0
  524. package/src/session-runtime/provider-readiness.mjs +131 -0
  525. package/src/session-runtime/provider-request-snapshot.mjs +0 -19
  526. package/src/session-runtime/resource-api.mjs +70 -3
  527. package/src/session-runtime/runtime-core.mjs +176 -705
  528. package/src/session-runtime/runtime-facade.mjs +112 -0
  529. package/src/session-runtime/runtime-modules.mjs +56 -0
  530. package/src/session-runtime/runtime-review-api.mjs +19 -0
  531. package/src/session-runtime/runtime-tunables.mjs +1 -1
  532. package/src/session-runtime/session-lifecycle.mjs +14 -4
  533. package/src/session-runtime/session-route-policy.mjs +26 -0
  534. package/src/session-runtime/session-text.mjs +3 -32
  535. package/src/session-runtime/session-turn-api.mjs +16 -4
  536. package/src/session-runtime/settings-api.mjs +56 -3
  537. package/src/session-runtime/setup-tool/executor.mjs +316 -0
  538. package/src/session-runtime/setup-tool/tool-defs.mjs +164 -0
  539. package/src/session-runtime/skills-api.mjs +39 -13
  540. package/src/session-runtime/tool-catalog-data.mjs +3 -2
  541. package/src/session-runtime/tool-catalog-schema.mjs +1 -16
  542. package/src/session-runtime/tool-catalog.mjs +0 -6
  543. package/src/session-runtime/tool-defs.mjs +1 -1
  544. package/src/session-runtime/tool-policy-refresh.mjs +4 -1
  545. package/src/session-runtime/tool-profile.mjs +1 -0
  546. package/src/session-runtime/tool-surface.mjs +2 -0
  547. package/src/session-runtime/workflow-agents-api.mjs +2 -1
  548. package/src/session-runtime/workflow.mjs +2 -2
  549. package/src/standalone/agent-tool/helpers.mjs +31 -7
  550. package/src/standalone/agent-tool/lead-worker-index.mjs +3 -27
  551. package/src/standalone/agent-tool/notify.mjs +1 -0
  552. package/src/standalone/agent-tool/worker-index.mjs +1 -25
  553. package/src/standalone/agent-tool.mjs +0 -24
  554. package/src/standalone/channel-admin.mjs +1 -42
  555. package/src/standalone/channel-transport.mjs +21 -4
  556. package/src/standalone/daemon-boot-coordinator.mjs +14 -0
  557. package/src/standalone/daemon.mjs +26 -14
  558. package/src/standalone/desktop-service-registry.mjs +226 -0
  559. package/src/standalone/fair-call-scheduler.mjs +1 -4
  560. package/src/standalone/hook-bus/config.mjs +1 -1
  561. package/src/standalone/hook-bus.mjs +11 -0
  562. package/src/standalone/plugin-admin.mjs +3 -15
  563. package/src/standalone/provider-admin.mjs +40 -53
  564. package/src/standalone/seeds.mjs +62 -18
  565. package/src/standalone/session-attachment-pool.mjs +127 -0
  566. package/src/standalone/session-client.mjs +51 -669
  567. package/src/standalone/session-protocol.mjs +12 -1
  568. package/src/standalone/session-proxy.mjs +538 -0
  569. package/src/standalone/session-runtime-worker.mjs +13 -3
  570. package/src/standalone/session-service/agent-tree.mjs +477 -0
  571. package/src/standalone/session-service/project-catalog.mjs +86 -0
  572. package/src/standalone/session-service/projection.mjs +295 -0
  573. package/src/standalone/session-service-api.mjs +56 -0
  574. package/src/standalone/session-service.mjs +150 -1087
  575. package/src/standalone/session-state-projection.mjs +57 -0
  576. package/src/standalone/session-transport.mjs +17 -2
  577. package/src/standalone/session-wire-values.mjs +54 -0
  578. package/src/standalone/session-wire.mjs +1 -1
  579. package/src/standalone/usage-dashboard.mjs +3 -30
  580. package/src/tui/App.jsx +14 -0
  581. package/src/tui/app/app-format.mjs +4 -12
  582. package/src/tui/app/app-view.jsx +1 -0
  583. package/src/tui/app/extension-pickers.mjs +20 -4
  584. package/src/tui/app/input-parsers.mjs +3 -21
  585. package/src/tui/app/model-options.mjs +7 -5
  586. package/src/tui/app/prompt-submit.mjs +0 -18
  587. package/src/tui/app/provider-setup-picker.mjs +24 -76
  588. package/src/tui/app/transcript-row-estimate.mjs +0 -1
  589. package/src/tui/app/transcript-window.mjs +2 -13
  590. package/src/tui/app/use-transcript-window.mjs +1 -1
  591. package/src/tui/dist/index.mjs +5321 -5068
  592. package/src/tui/index.jsx +3 -1
  593. package/src/tui/markdown/format-token.mjs +0 -5
  594. package/src/tui/markdown/streaming-markdown.mjs +2 -157
  595. package/src/tui/prompt-history-store.mjs +0 -13
  596. package/src/tui/session/agent-envelope.mjs +38 -5
  597. package/src/tui/session/agent-job-feed.mjs +8 -0
  598. package/src/tui/session/boot-profile.mjs +2 -14
  599. package/src/tui/session/context-state.mjs +0 -4
  600. package/src/tui/session/goal-continuation.mjs +1 -10
  601. package/src/tui/session/notification-plan.mjs +8 -0
  602. package/src/tui/session/render-frame-source.mjs +22 -0
  603. package/src/tui/session/render-timing.mjs +13 -3
  604. package/src/tui/session/session-api-ext.mjs +18 -9
  605. package/src/tui/session/session-api.mjs +28 -0
  606. package/src/tui/session/session-stats.mjs +7 -41
  607. package/src/tui/session/transcript-spill.mjs +2 -83
  608. package/src/tui/session/turn-aggregate-cards.mjs +252 -0
  609. package/src/tui/session/turn-deferred-cards.mjs +127 -0
  610. package/src/tui/session/turn.mjs +77 -379
  611. package/src/tui/session-local.mjs +19 -69
  612. package/src/ui/model-display.mjs +57 -1
  613. package/src/ui/statusline-agents.mjs +1 -5
  614. package/src/ui/statusline-segments.mjs +1 -5
  615. package/src/ui/statusline.mjs +16 -6
  616. package/src/ui/streaming-markdown-heal.mjs +147 -0
  617. package/src/vendor/statusline/bin/statusline-route.mjs +1 -1
  618. package/src/vendor/statusline/src/gateway/route-meta.mjs +1 -1
  619. package/src/workflows/default/WORKFLOW.md +5 -3
  620. package/src/workflows/solo/WORKFLOW.md +5 -3
  621. package/src/runtime/agent/orchestrator/agent-runtime/commit-message-completion.mjs +0 -67
  622. package/src/runtime/agent/orchestrator/providers/lib/env-utils.mjs +0 -15
  623. package/src/runtime/agent/orchestrator/session/compact/file-reattach.mjs +0 -112
  624. package/src/runtime/agent/orchestrator/session/compact/handoff.mjs +0 -476
  625. package/src/runtime/agent/orchestrator/session/loop/env.mjs +0 -14
  626. package/src/runtime/agent/orchestrator/session/manager/env-utils.mjs +0 -8
  627. package/src/runtime/office/bench/freeform-live-benchmark.mjs +0 -792
  628. package/src/runtime/office/core/office-candidate-actions.mjs +0 -459
  629. package/src/runtime/office/design/design-freeform-board.mjs +0 -409
  630. package/src/runtime/office/design/design-layout-grammar.mjs +0 -618
  631. package/src/runtime/office/design/design-layout-tournament.mjs +0 -163
  632. package/src/runtime/office/design/design-reference-genome.mjs +0 -132
  633. package/src/runtime/office/design/design-reference-visual-catalog.mjs +0 -130
  634. package/src/runtime/office/design/pptx/design-pptx-authored-project.mjs +0 -172
  635. package/src/runtime/office/design/pptx/design-pptx-authored-scene.mjs +0 -436
  636. package/src/runtime/office/design/pptx/design-pptx-executive-revisions.mjs +0 -429
  637. package/src/runtime/office/design/pptx/design-pptx-executive-scenes.mjs +0 -304
  638. package/src/runtime/office/design/pptx/design-pptx-executive.mjs +0 -336
  639. package/src/runtime/office/design/pptx/design-pptx-plan.mjs +0 -1020
  640. package/src/runtime/office/design/pptx/design-pptx-primitives.mjs +0 -94
  641. package/src/runtime/office/design/pptx/design-pptx-review-gate.mjs +0 -199
  642. package/src/runtime/office/design/pptx/design-pptx-scene-builders.mjs +0 -27
  643. package/src/runtime/office/design/pptx/design-pptx-semantic-flow.mjs +0 -111
  644. package/src/runtime/office/design/pptx/design-pptx-semantic-visuals.mjs +0 -995
  645. package/src/runtime/office/design/pptx/design-pptx-stack.mjs +0 -58
  646. package/src/runtime/office/design/pptx/design-pptx.mjs +0 -777
  647. package/src/runtime/office/quality/design-frontier-review.mjs +0 -279
  648. package/src/session-runtime/env.mjs +0 -16
package/README.md CHANGED
@@ -259,7 +259,9 @@ npm start
259
259
 
260
260
  npm run smoke
261
261
  npm run smoke:all
262
- npm run test:tool-contracts
262
+ npm test # every *.test.mjs under src/ and scripts/
263
+ npm test -- src/runtime/memory # one directory
264
+ npm run test:slow # *.slow.test.mjs
263
265
  npm run build:tui
264
266
  npm run audit:models
265
267
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.160",
3
+ "version": "0.9.161",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -53,6 +53,9 @@
53
53
  "prepack": "npm run build:tui",
54
54
  "prepublishOnly": "node -e \"if(!process.env.CI){console.error('local npm publish is disabled — run npm run release:patch');process.exit(1)}\"",
55
55
  "start": "node src/cli.mjs",
56
+ "test": "node scripts/test.mjs",
57
+ "test:slow": "node scripts/test.mjs --lane slow",
58
+ "test:live": "node scripts/test.mjs --lane live",
56
59
  "smoke": "node scripts/smoke.mjs",
57
60
  "smoke:all": "npm run smoke && npm run smoke:boot && npm run smoke:patch && npm run smoke:compact",
58
61
  "smoke:boot": "node scripts/boot-smoke.mjs",
@@ -75,8 +78,15 @@
75
78
  "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",
76
79
  "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 src/runtime/bridge-clients.test.mjs src/runtime/computer-bridge/client-semantic-error.test.mjs src/runtime/agent/orchestrator/session/tool-envelope.test.mjs src/runtime/agent/orchestrator/session/eager-dispatch.test.mjs",
77
80
  "test:quick": "npm run test:session && npm run test:session-transport && npm run test:desktop-main --prefix apps/desktop",
78
- "test:office": "node --test scripts/run-office-live-tests.test.mjs src/runtime/office/office-runtime-contract.test.mjs src/runtime/office/office-runtime-com.test.mjs src/runtime/office/office-runtime-portable.test.mjs src/runtime/office/office-runtime-pdf.test.mjs src/runtime/office/office-runtime-design.test.mjs src/runtime/office/office-freeform-pipeline.test.mjs src/runtime/office/office-assurance.test.mjs src/runtime/office/office-design-aesthetics.test.mjs src/runtime/office/portable-authoring.test.mjs src/runtime/office/slide-quality.test.mjs && npm run test:office-approval --prefix apps/desktop",
81
+ "test:office": "node --test scripts/run-office-live-tests.test.mjs src/runtime/office/office-runtime-contract.test.mjs src/runtime/office/office-runtime-com.test.mjs src/runtime/office/office-runtime-portable.test.mjs src/runtime/office/xlsx-formula-audit.test.mjs src/runtime/office/xlsx-portable-snapshot.test.mjs src/runtime/office/office-runtime-pdf.test.mjs src/runtime/office/office-runtime-design.test.mjs src/runtime/office/office-assurance.test.mjs src/runtime/office/office-design-aesthetics.test.mjs src/runtime/office/portable-authoring.test.mjs src/runtime/office/slide-quality.test.mjs src/runtime/office/authoring/pptx-brief.test.mjs src/runtime/office/authoring/pptx-receipt.test.mjs src/runtime/office/quality/render-air.test.mjs src/runtime/office/quality/pptx-deck-rubric.test.mjs && npm run test:office-approval --prefix apps/desktop",
79
82
  "test:office:live": "node scripts/run-office-live-tests.mjs",
83
+ "test:office:preview": "node --test src/runtime/office/office-render-preview.test.mjs",
84
+ "test:office:review": "node --test src/runtime/office/pptx-independent-review.test.mjs src/runtime/office/pptx-chart-styling.test.mjs",
85
+ "test:office:cleanup": "node --test src/runtime/office/com/office-cleanup.test.mjs src/runtime/office/office-runtime-com.test.mjs",
86
+ "test:office:compat": "node scripts/run-office-live-tests.mjs compat",
87
+ "test:office:live:all": "node scripts/run-office-live-tests.mjs all",
88
+ "test:office:render": "node --test src/runtime/office/pptx-skill-kit.slow.test.mjs",
89
+ "office:icons": "node scripts/office/build-pptx-icons.mjs",
80
90
  "test:media": "node --test src/runtime/media/store.test.mjs src/runtime/media/renditions.test.mjs src/runtime/media/adapters/codex-image.test.mjs",
81
91
  "failures": "node scripts/tool-failures.mjs",
82
92
  "trace:llm": "node scripts/llm-trace-summary.mjs",
@@ -84,8 +94,8 @@
84
94
  "bench:office:contract": "node src/runtime/office/bench/contract-benchmark.mjs",
85
95
  "bench:office:assurance": "node src/runtime/office/bench/assurance-benchmark.mjs",
86
96
  "bench:office:polish": "node src/runtime/office/bench/polish-benchmark.mjs",
97
+ "bench:office:deck": "node src/runtime/office/bench/deck-bench.mjs",
87
98
  "bench:office:quality:live": "node src/runtime/office/bench/quality-live-benchmark.mjs",
88
- "bench:office:freeform:live": "node src/runtime/office/bench/freeform-live-benchmark.mjs",
89
99
  "diag:sessions": "node scripts/session-diag.mjs",
90
100
  "diag:tools": "node scripts/tool-efficiency-diag.mjs",
91
101
  "diag:sweep": "node scripts/session-sweep.mjs",
@@ -149,6 +159,7 @@
149
159
  "pdf-lib": "^1.17.1",
150
160
  "pdfjs-dist": "^6.2.108",
151
161
  "pg": "^8.22.0",
162
+ "pptxgenjs": "^4.0.1",
152
163
  "puppeteer-core": "^25.2.0",
153
164
  "react": "^19.2.7",
154
165
  "sharp": "^0.35.3",
@@ -172,10 +183,8 @@
172
183
  "devDependencies": {
173
184
  "acorn": "^8.17.0",
174
185
  "esbuild": "^0.28.1",
175
- "eslint-scope": "^9.1.2"
176
- },
177
- "optionalDependencies": {
178
- "@vscode/ripgrep": "^1.18.0"
186
+ "eslint-scope": "^9.1.2",
187
+ "lucide-static": "^1.41.0"
179
188
  },
180
189
  "main": "index.js",
181
190
  "directories": {
@@ -0,0 +1,22 @@
1
+ export async function completeToolConversation({ send, messages, tools, executeTool, maxSteps = 8 }) {
2
+ const transcript = [...messages];
3
+ for (let step = 0; step < maxSteps; step++) {
4
+ const result = await send(transcript, tools);
5
+ if (result.truncated) throw new Error(`Tool conversation was truncated: ${JSON.stringify(result).slice(0, 2000)}`);
6
+ if (!result.toolCalls?.length) return { result, toolSteps: step };
7
+ transcript.push({ role: 'assistant', content: result.content,
8
+ toolCalls: result.toolCalls, reasoningContent: result.reasoningContent });
9
+ for (const tool of result.toolCalls) {
10
+ transcript.push({ role: 'tool', toolCallId: tool.id, content: await executeTool(tool) });
11
+ }
12
+ }
13
+ throw new Error(`Tool conversation exceeded its ${maxSteps}-step bound`);
14
+ }
15
+
16
+ export function assertResponseContains(result, expected) {
17
+ if (typeof result?.content !== 'string' || !result.content.includes(expected)) {
18
+ throw new Error(`Model response did not include ${JSON.stringify(expected)}: ${JSON.stringify({
19
+ content: result?.content, toolCalls: result?.toolCalls, stopReason: result?.stopReason, truncated: result?.truncated,
20
+ }).slice(0, 3000)}`);
21
+ }
22
+ }
@@ -0,0 +1,38 @@
1
+ // Secondary node:test reporter: per-file wall time, slowest files first.
2
+ // Runs beside the spec reporter (scripts/test.mjs) so a slow default lane
3
+ // always names its cause instead of hiding it inside one total. A file over
4
+ // SLOW_HINT_MS belongs in the slow lane (rename to *.slow.test.mjs).
5
+ import { relative } from 'node:path';
6
+
7
+ const SLOW_HINT_MS = 10_000;
8
+ const TOP = 8;
9
+
10
+ // Each test file runs in its own process; its top-level tests arrive as
11
+ // nesting-0 events tagged with the file, so a file's time is the sum of its
12
+ // top-level test durations (module load excluded).
13
+ export default async function* timingReporter(source) {
14
+ const byFile = new Map();
15
+ for await (const event of source) {
16
+ if (event.type !== 'test:pass' && event.type !== 'test:fail') continue;
17
+ if (event.data.nesting !== 0 || !event.data.file) continue;
18
+ const file = relative(process.cwd(), String(event.data.file)).replaceAll('\\', '/');
19
+ const entry = byFile.get(file) ?? { file, ms: 0, failed: false };
20
+ entry.ms += Number(event.data.details?.duration_ms) || 0;
21
+ entry.failed ||= event.type === 'test:fail';
22
+ byFile.set(file, entry);
23
+ }
24
+ const files = [...byFile.values()];
25
+ if (files.length === 0) return;
26
+ files.sort((a, b) => b.ms - a.ms);
27
+ const total = files.reduce((sum, entry) => sum + entry.ms, 0);
28
+ const lines = [
29
+ '',
30
+ `slowest files (${files.length} files, ${(total / 1000).toFixed(1)}s file-time):`,
31
+ ...files.slice(0, TOP).map((entry) => ` ${String(Math.round(entry.ms)).padStart(7)}ms ${entry.file}${entry.failed ? ' (failed)' : ''}`),
32
+ ];
33
+ const slow = files.filter((entry) => entry.ms >= SLOW_HINT_MS && !/\.(?:slow|live)\.test\.mjs$/.test(entry.file));
34
+ if (slow.length) {
35
+ lines.push(` ${slow.length} file(s) over ${SLOW_HINT_MS / 1000}s in the default lane; rename to *.slow.test.mjs to move them out.`);
36
+ }
37
+ yield `${lines.join('\n')}\n`;
38
+ }
@@ -0,0 +1,141 @@
1
+ // Explicit live acceptance runner. It uses an existing owner process only:
2
+ // no server launch, unload, app restart, download, or real tool side effects.
3
+ import assert from 'node:assert/strict';
4
+ import { execFile } from 'node:child_process';
5
+ import { promisify } from 'node:util';
6
+ import { mkdirSync, writeFileSync } from 'node:fs';
7
+ import { dirname, resolve } from 'node:path';
8
+ import { setTimeout as delay } from 'node:timers/promises';
9
+ import { MixdogLocalProvider } from '../src/runtime/agent/orchestrator/providers/mixdog-local.mjs';
10
+ import { recordLocalModelLoad, localModelState } from '../src/runtime/local-provider/model-state.mjs';
11
+ import { completeToolConversation, assertResponseContains } from './lib/local-provider-live-scenarios.mjs';
12
+
13
+ const flags = Object.fromEntries(process.argv.slice(2).map((arg) => {
14
+ const [key, ...rest] = arg.replace(/^--/, '').split('=');
15
+ return [key, rest.join('=')];
16
+ }));
17
+ const pid = Number(flags.pid);
18
+ const durationSeconds = Number(flags.seconds || 600);
19
+ const targetCycles = flags.cycles ? Number(flags.cycles) : null;
20
+ const selectedCase = flags.case || null;
21
+ const cases = ['long-context', 'multi-turn', 'tool-roundtrip', 'concurrent-queue', 'cancel-and-recover'];
22
+ if (!Number.isInteger(pid) || pid <= 0 || !Number.isInteger(durationSeconds) || durationSeconds < 600
23
+ || (targetCycles !== null && (!Number.isInteger(targetCycles) || targetCycles < 1 || targetCycles > 100))
24
+ || (selectedCase && !cases.includes(selectedCase))) {
25
+ throw new Error('Explicit --pid and --seconds>=600 are required; optional --cycles=1..100 and --case select a bounded follow-up.');
26
+ }
27
+ const reportPath = resolve(flags.report || '.runtime/local-provider-live/report.json');
28
+ const exec = promisify(execFile);
29
+ const { stdout } = await exec('powershell', ['-NoProfile', '-NonInteractive', '-Command',
30
+ `(Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}').CommandLine`], { windowsHide: true, maxBuffer: 128 * 1024 });
31
+ const line = stdout.trim();
32
+ if (!/llama-server\.exe/i.test(line)) throw new Error('The supplied process is not llama-server.');
33
+ const argument = (name) => {
34
+ const match = new RegExp(`--${name}\\s+(?:"([^"]+)"|(\\S+))`).exec(line);
35
+ return match?.[1] || match?.[2] || '';
36
+ };
37
+ const port = Number(argument('port')), apiKey = argument('api-key'), model = argument('alias');
38
+ if (!Number.isInteger(port) || !apiKey || !model) throw new Error('Required local server arguments are unavailable.');
39
+ const baseURL = `http://127.0.0.1:${port}/v1`;
40
+ const headers = { Authorization: `Bearer ${apiKey}` };
41
+ const propsResponse = await fetch(`http://127.0.0.1:${port}/props`, { headers, signal: AbortSignal.timeout(10_000) });
42
+ if (!propsResponse.ok) throw new Error(`Local props HTTP ${propsResponse.status}`);
43
+ recordLocalModelLoad(model, await propsResponse.json(), null);
44
+ const provider = new MixdogLocalProvider({}, { ensureServer: async () => ({ baseURL, apiKey }) });
45
+ const report = { startedAt: new Date().toISOString(), pid, model, durationSeconds, targetCycles, selectedCase, busySkips: 0, cases: [], failures: [] };
46
+ const started = Date.now();
47
+ const persist = () => {
48
+ mkdirSync(dirname(reportPath), { recursive: true });
49
+ writeFileSync(reportPath, JSON.stringify(report, null, 2) + '\n');
50
+ };
51
+ const send = (messages, tools = [], options = {}) => provider.send(messages, model, tools, {
52
+ maxOutputTokens: 2048, ...options,
53
+ signal: options.signal ? AbortSignal.any([options.signal, AbortSignal.timeout(120_000)]) : AbortSignal.timeout(120_000),
54
+ });
55
+ async function check(name, action) {
56
+ if (selectedCase && name.replace(/-\d+$/, '') !== selectedCase) return;
57
+ const at = Date.now();
58
+ try {
59
+ const detail = await action();
60
+ report.cases.push({ name, ok: true, elapsedMs: Date.now() - at, metrics: localModelState(model).inference, detail });
61
+ console.log(`PASS ${name} ${Date.now() - at}ms`);
62
+ } catch (error) {
63
+ const failure = { name, elapsedMs: Date.now() - at, error: String(error?.message || error) };
64
+ report.failures.push(failure);
65
+ console.log(`FAIL ${name}: ${failure.error}`);
66
+ }
67
+ persist();
68
+ }
69
+ let cycle = 0;
70
+ try {
71
+ while (targetCycles !== null ? cycle < targetCycles : Date.now() - started < durationSeconds * 1000 || cycle < 2) {
72
+ if (Date.now() - started > (durationSeconds + 600) * 1000) throw new Error('Live acceptance exceeded its bounded completion window.');
73
+ const slotsResponse = await fetch(`http://127.0.0.1:${port}/slots`, { headers, signal: AbortSignal.timeout(10_000) });
74
+ if (!slotsResponse.ok) throw new Error(`Cannot establish server idleness: HTTP ${slotsResponse.status}`);
75
+ const slots = await slotsResponse.json();
76
+ if (!Array.isArray(slots)) throw new Error('Invalid server slots response');
77
+ if (slots.some((slot) => slot.is_processing)) { report.busySkips++; await delay(2000); continue; }
78
+ cycle++;
79
+ await check(`long-context-${cycle}`, async () => {
80
+ const records = Array.from({ length: 768 }, (_, index) => `Record ${index}: stored value is entry-${index}-copper.`);
81
+ const result = await send([{ role: 'user', content: `${records.join('\n')}\nWhat is the exact stored value of Record 731? Reply with that value only.` }]);
82
+ assert.ok(result.content.includes('entry-731-copper'));
83
+ });
84
+ await check(`multi-turn-${cycle}`, async () => {
85
+ const marker = `marker-${cycle}-amber`;
86
+ const messages = [{ role: 'system', content: 'Answer concisely and accurately.' },
87
+ { role: 'system', content: 'This conversation uses short factual answers.' },
88
+ { role: 'user', content: `Remember this marker for the next question: ${marker}. Briefly acknowledge it.` }];
89
+ const first = await send(messages);
90
+ assert.ok(first.content);
91
+ messages.push({ role: 'assistant', content: first.content, reasoningContent: first.reasoningContent });
92
+ messages.push({ role: 'user', content: 'What was the exact marker? Reply with the marker only.' });
93
+ assert.ok((await send(messages)).content.includes(marker));
94
+ });
95
+ await check(`tool-roundtrip-${cycle}`, async () => {
96
+ const tools = [{ name: 'read_probe_value', description: 'Read the current test value for a named field.',
97
+ inputSchema: { type: 'object', properties: { field: { type: 'string', enum: ['marker'] } }, required: ['field'], additionalProperties: false } }];
98
+ const messages = [{ role: 'user', content: 'Use read_probe_value to read the marker field. Then tell me its returned value.' }];
99
+ const completed = await completeToolConversation({ send, messages, tools, executeTool: async (tool) => {
100
+ assert.equal(tool.name, 'read_probe_value');
101
+ assert.equal(tool.arguments.field, 'marker');
102
+ return `probe-value-${cycle}`;
103
+ } });
104
+ assert.ok(completed.toolSteps > 0, `Model did not use the offered tool: ${JSON.stringify(completed.result).slice(0, 2000)}`);
105
+ assertResponseContains(completed.result, `probe-value-${cycle}`);
106
+ return { toolSteps: completed.toolSteps };
107
+ });
108
+ await check(`concurrent-queue-${cycle}`, async () => {
109
+ const results = await Promise.all([
110
+ send([{ role: 'user', content: 'What is 7 plus 8? Reply with just the result.' }]),
111
+ send([{ role: 'user', content: 'What is 12 minus 5? Reply with just the result.' }]),
112
+ ]);
113
+ assert.match(results[0].content, /15/);
114
+ assert.match(results[1].content, /7/);
115
+ });
116
+ await check(`cancel-and-recover-${cycle}`, async () => {
117
+ const controller = new AbortController();
118
+ let emitted = false;
119
+ await assert.rejects(send([{ role: 'user', content: 'Explain the tradeoffs between caching, memory consumption, and request scheduling in a local inference server.' }], [], {
120
+ signal: controller.signal,
121
+ onStreamDelta(kind) {
122
+ if (kind !== 'transport' && !emitted) { emitted = true; controller.abort(new Error('live check cancellation')); }
123
+ },
124
+ }));
125
+ assert.equal(emitted, true);
126
+ const recovered = await send([{ role: 'user', content: 'Reply with exactly RECOVERED.' }]);
127
+ assert.match(recovered.content, /RECOVERED/);
128
+ });
129
+ }
130
+ } catch (error) {
131
+ report.failures.push({ name: 'runner', error: String(error?.message || error) });
132
+ }
133
+ report.finishedAt = new Date().toISOString();
134
+ report.elapsedMs = Date.now() - started;
135
+ report.cycles = cycle;
136
+ report.passed = report.failures.length === 0 && cycle >= (targetCycles || 2);
137
+ report.scope = 'Existing model process; long-running multi-turn/tool/queue/cancel recovery. No OS sleep, app restart, model reload or new model installation.';
138
+ persist();
139
+ console.log(JSON.stringify({ reportPath, passed: report.passed, cycles: cycle, elapsedMs: report.elapsedMs,
140
+ failures: report.failures.length, maxToolSteps: Math.max(0, ...report.cases.map((entry) => entry.detail?.toolSteps || 0)) }));
141
+ if (!report.passed) process.exitCode = 1;
@@ -0,0 +1,59 @@
1
+ // Stage a rendered deck for SlidesGen-Bench's aesthetics metrics (refs/slidesgen-bench/eval/aesthetics_metrics.py):
2
+ // node scripts/office/aesthetics-probe.mjs <deck.pptx> <page-image-prefix> <out-dir>
3
+ // Copies <prefix>-page-N.png into <out-dir>/slide_images/slide_000N.png and writes the deck's own text-box geometry
4
+ // into <out-dir>/detection/slide_000N.json in the benchmark's layout-detection format ({ boxes: [{ label, coordinate }] }),
5
+ // so the figure-ground contrast (Usability) metric reads text regions from the file the way the benchmark reads its
6
+ // PaddleOCR output — the geometry comes from the saved deck, not from a detector. Then:
7
+ // python eval/aesthetics_metrics.py <out-dir>/slide_images --compute-score --config eval/aesthetics_config.json --no-parallel -o <result.json>
8
+ import { copyFile, mkdir, writeFile } from 'node:fs/promises';
9
+ import { join, resolve } from 'node:path';
10
+ import sharp from 'sharp';
11
+ import { snapshotPortableOoxml } from '../../src/runtime/office/portable/portable-snapshot.mjs';
12
+ import { measureTextBlock } from '../../src/runtime/office/portable/text-metrics.mjs';
13
+
14
+ // A detector's box hugs the glyphs; a kit box is often wider than its text (a kicker in a 6 in box, a source line,
15
+ // a hero label). Width is tightened to the measured text so the contrast reads the type, not the empty paper beside
16
+ // it; height is kept, since the snapshot does not say where in the box the text is anchored.
17
+ function tightWidth(shape) {
18
+ if (shape.table) return shape.width;
19
+ const size = Number(shape.font?.size) || 18;
20
+ const measured = measureTextBlock([{ text: String(shape.text), fontName: shape.font?.name || 'Noto Sans KR', fontSize: size, bold: Boolean(shape.font?.bold) }], { width: shape.width });
21
+ return Math.min(shape.width, Math.max(size, measured.width + 4));
22
+ }
23
+
24
+ const [deck, prefix, out] = process.argv.slice(2);
25
+ if (!deck || !prefix || !out) {
26
+ console.error('usage: node scripts/office/aesthetics-probe.mjs <deck.pptx> <page-image-prefix> <out-dir>');
27
+ process.exit(1);
28
+ }
29
+ const CANVAS = { width: 960, height: 540 }; // 13.33 × 7.5 in, in points — the snapshot's unit
30
+ const snapshot = await snapshotPortableOoxml(resolve(deck), 'pptx', {});
31
+ const slides = snapshot?.slides || snapshot?.document?.slides || [];
32
+ if (!slides.length) throw new Error(`no slides read from ${deck}`);
33
+ await mkdir(join(out, 'slide_images'), { recursive: true });
34
+ await mkdir(join(out, 'detection'), { recursive: true });
35
+ let total = 0;
36
+ for (const slide of slides) {
37
+ const stem = `slide_${String(slide.index).padStart(4, '0')}`;
38
+ const source = `${prefix}-page-${slide.index}.png`;
39
+ const target = join(out, 'slide_images', `${stem}.png`);
40
+ await copyFile(source, target);
41
+ const { width, height } = await sharp(target).metadata();
42
+ const sx = width / CANVAS.width, sy = height / CANVAS.height;
43
+ // Text carriers only: text boxes and native tables. Charts draw their own labels; pictures and fields carry none.
44
+ const boxes = (slide.shapes || [])
45
+ .filter((shape) => String(shape.text || '').trim() && !shape.chart && [shape.left, shape.top, shape.width, shape.height].every(Number.isFinite))
46
+ .map((shape) => ({
47
+ label: 'text',
48
+ score: 1,
49
+ coordinate: [
50
+ Math.max(0, Math.round(shape.left * sx)), Math.max(0, Math.round(shape.top * sy)),
51
+ Math.min(width, Math.round((shape.left + tightWidth(shape)) * sx)), Math.min(height, Math.round((shape.top + shape.height) * sy)),
52
+ ],
53
+ }))
54
+ .filter((box) => box.coordinate[2] - box.coordinate[0] > 2 && box.coordinate[3] - box.coordinate[1] > 2);
55
+ await writeFile(join(out, 'detection', `${stem}.json`), JSON.stringify({ source: 'pptx-snapshot', image: `${stem}.png`, boxes }, null, 2));
56
+ total += boxes.length;
57
+ console.log(`${stem}: ${boxes.length} text regions (${width}×${height})`);
58
+ }
59
+ console.log(`${slides.length} pages staged under ${out} with ${total} text regions`);
@@ -0,0 +1,56 @@
1
+ // Author a deck from the working tree's office runtime (the installed app runs its own copy):
2
+ // node scripts/office/author-deck.mjs <script.js> <deck.pptx> [--mode portable|auto] [--render] [--critique critique.json] [--out result.json]
3
+ // author (measured, no render) → qa → measured issues; --render adds the page images, contact sheet, receipt,
4
+ // and reviewToken; --critique finalizes with the critique file (its reviewToken is filled from the render).
5
+ import { readFile, writeFile } from 'node:fs/promises';
6
+ import { resolve } from 'node:path';
7
+ import { executeOfficeTool } from '../../src/runtime/office/index.mjs';
8
+ import { isAdvisoryOfficeIssue } from '../../src/runtime/office/quality/quality-pipeline.mjs';
9
+
10
+ const value = (result) => JSON.parse(result.content[0].text);
11
+ const argv = process.argv.slice(2);
12
+ const flag = (name) => { const at = argv.indexOf(name); return at >= 0 ? argv[at + 1] : null; };
13
+ const positional = argv.filter((arg, index) => !arg.startsWith('--') && !(index > 0 && argv[index - 1].startsWith('--') && !['--render'].includes(argv[index - 1])));
14
+ const [scriptPath, deckPath] = positional;
15
+ if (!scriptPath || !deckPath) {
16
+ console.error('usage: node scripts/office/author-deck.mjs <script.js> <deck.pptx> [--mode portable|auto] [--render] [--critique critique.json] [--out result.json]');
17
+ process.exit(1);
18
+ }
19
+ const cwd = resolve('.');
20
+ const script = await readFile(scriptPath, 'utf8');
21
+ const mode = flag('--mode') || 'portable';
22
+ const authored = value(await executeOfficeTool({ action: 'author', path: deckPath, script, mode, overwrite: true, render: false }, { cwd }));
23
+ if (!authored.ok) {
24
+ console.error(`author failed: ${authored.error?.message}\n line ${authored.error?.line}\n${authored.error?.excerpt || ''}`);
25
+ process.exit(2);
26
+ }
27
+ const session = authored.session;
28
+ console.log(`authored ${deckPath} (${authored.backend}, kit ${authored.kit}, gradients ${authored.nativeGradients || 0}, ${authored.elapsedMs} ms)`);
29
+ const qa = value(await executeOfficeTool({ action: 'qa', session, render: false }, { cwd }));
30
+ const issues = (qa.issuesAfter || qa.issues || []);
31
+ const measured = issues.filter((issue) => !isAdvisoryOfficeIssue(issue));
32
+ console.log(`qa: ${measured.length} measured, ${issues.length - measured.length} advisory`);
33
+ for (const issue of issues) console.log(` ${measured.includes(issue) ? '!' : '·'} ${issue.code} ${issue.path || ''} ${issue.message || ''}`);
34
+ const result = { deck: deckPath, session, authored: { kit: authored.kit, nativeGradients: authored.nativeGradients || 0, bytes: authored.bytes }, issues };
35
+ if (argv.includes('--render') || flag('--critique')) {
36
+ const rendered = value(await executeOfficeTool({ action: 'render', session }, { cwd }));
37
+ result.render = { output: rendered.output, pageCount: rendered.pageCount, reviewToken: rendered.reviewToken, images: (rendered.images || []).map((image) => image.path), contactSheet: rendered.contactSheet?.path || rendered.contactSheet };
38
+ result.receipt = rendered.receipt;
39
+ console.log(`rendered ${rendered.pageCount} pages → ${rendered.output}`);
40
+ for (const image of rendered.images || []) console.log(` page ${image.page}: ${image.path}`);
41
+ if (rendered.contactSheet?.path) console.log(` contact sheet: ${rendered.contactSheet.path}`);
42
+ if (rendered.receipt?.deck?.rhythm) console.log(` rhythm: ${JSON.stringify(rendered.receipt.deck.rhythm)}`);
43
+ }
44
+ const critiquePath = flag('--critique');
45
+ if (critiquePath) {
46
+ const critique = JSON.parse(await readFile(critiquePath, 'utf8'));
47
+ const finalized = value(await executeOfficeTool({ action: 'finalize', session, design: { reviewed: true, reviewToken: result.render.reviewToken, critique } }, { cwd }));
48
+ result.finalize = finalized;
49
+ console.log(`finalize: ${finalized.ok ? 'ok' : 'blocked'} ${JSON.stringify(finalized.summary || finalized.reason || finalized.issues?.slice(0, 5) || '')}`);
50
+ if (!finalized.ok) for (const issue of finalized.issues || []) console.log(` ! ${issue.code} ${issue.path || ''} ${issue.message || ''}`);
51
+ } else {
52
+ await executeOfficeTool({ action: 'close', session, save: false }, { cwd }).catch(() => {});
53
+ }
54
+ const out = flag('--out');
55
+ if (out) await writeFile(out, JSON.stringify(result, null, 2));
56
+ process.exit(critiquePath && !result.finalize?.ok ? 3 : measured.length ? 4 : 0);
@@ -0,0 +1,48 @@
1
+ // Builds the offline icon set the pptx authoring runtime injects as ICON(name):
2
+ // a curated subset of Lucide (ISC) read from the lucide-static dev dependency,
3
+ // stored as the icons' inner SVG markup so the kit can render them at any color.
4
+ // node scripts/office/build-pptx-icons.mjs
5
+ import { readFile, writeFile } from 'node:fs/promises';
6
+ import { createRequire } from 'node:module';
7
+ import { dirname, join } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ const require = createRequire(import.meta.url);
11
+ const root = dirname(require.resolve('lucide-static/package.json'));
12
+ const { version, license } = JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
13
+ const out = join(dirname(fileURLToPath(import.meta.url)), '../../src/runtime/office/authoring/pptx-icons.json');
14
+
15
+ // One line per family so a reader can see what the deck can reach for. Names are Lucide's.
16
+ export const ICON_NAMES = [
17
+ // direction and process
18
+ 'arrow-right', 'arrow-left', 'arrow-up', 'arrow-down', 'arrow-up-right', 'arrow-down-right', 'move-right', 'chevron-right', 'chevrons-right', 'corner-down-right', 'repeat', 'refresh-cw', 'rotate-cw', 'route', 'workflow', 'git-branch', 'git-merge', 'git-fork', 'milestone', 'flag', 'goal', 'target', 'crosshair', 'compass', 'map', 'map-pin', 'navigation', 'footprints', 'play', 'pause', 'square', 'circle', 'timer', 'hourglass', 'clock', 'calendar', 'calendar-check', 'history',
19
+ // data and evidence
20
+ 'bar-chart-3', 'bar-chart-4', 'chart-bar', 'chart-column', 'chart-line', 'chart-pie', 'chart-area', 'chart-scatter', 'chart-no-axes-combined', 'trending-up', 'trending-down', 'activity', 'gauge', 'percent', 'hash', 'sigma', 'table', 'table-2', 'database', 'server', 'hard-drive', 'file-text', 'file-check', 'file-search', 'file-bar-chart', 'clipboard-list', 'clipboard-check', 'list-checks', 'list-ordered', 'scale', 'ruler', 'binary', 'calculator',
21
+ // people and organisation
22
+ 'user', 'users', 'user-check', 'user-plus', 'user-round', 'users-round', 'contact', 'building', 'building-2', 'factory', 'landmark', 'store', 'briefcase', 'handshake', 'crown', 'award', 'medal', 'trophy', 'graduation-cap', 'presentation', 'megaphone', 'speech', 'message-circle', 'message-square', 'messages-square', 'mail', 'phone', 'headphones', 'mic', 'vote', 'heart-handshake',
23
+ // money and value
24
+ 'coins', 'banknote', 'wallet', 'credit-card', 'piggy-bank', 'receipt', 'shopping-cart', 'shopping-bag', 'tag', 'tags', 'ticket', 'badge-dollar-sign', 'circle-dollar-sign', 'dollar-sign', 'euro', 'landmark',
25
+ // technology and product
26
+ 'cpu', 'microchip', 'circuit-board', 'bot', 'brain', 'brain-circuit', 'sparkles', 'wand-2', 'code', 'code-2', 'terminal', 'braces', 'bug', 'cloud', 'cloud-upload', 'cloud-download', 'wifi', 'radio', 'satellite', 'smartphone', 'tablet', 'laptop', 'monitor', 'tv', 'camera', 'image', 'video', 'layers', 'layout-grid', 'layout-dashboard', 'component', 'boxes', 'box', 'package', 'container', 'plug', 'zap', 'battery-charging', 'settings', 'settings-2', 'sliders-horizontal', 'wrench', 'hammer', 'cog', 'puzzle', 'blocks', 'link', 'unlink', 'globe', 'network', 'share-2',
27
+ // safety, status, judgement
28
+ 'check', 'check-check', 'circle-check', 'circle-x', 'x', 'circle-alert', 'triangle-alert', 'octagon-alert', 'info', 'circle-help', 'shield', 'shield-check', 'shield-alert', 'lock', 'lock-open', 'key', 'key-round', 'eye', 'eye-off', 'fingerprint', 'scan', 'search', 'filter', 'thumbs-up', 'thumbs-down', 'star', 'heart', 'bookmark', 'bell', 'siren', 'life-buoy', 'ban', 'minus', 'plus', 'equal', 'lightbulb', 'flame', 'rocket', 'anchor', 'scale-3d',
29
+ // nature, place, matter
30
+ 'sun', 'moon', 'cloud-rain', 'snowflake', 'wind', 'droplet', 'leaf', 'sprout', 'trees', 'mountain', 'waves', 'earth', 'recycle', 'thermometer', 'home', 'warehouse', 'truck', 'ship', 'plane', 'train-front', 'car', 'bike', 'fuel', 'utensils', 'coffee', 'pill', 'stethoscope', 'heart-pulse', 'syringe', 'dna', 'atom', 'flask-conical', 'microscope', 'book-open', 'library', 'pen-line', 'pencil', 'paintbrush', 'palette', 'scissors', 'shapes', 'type', 'quote', 'gem', 'gift', 'umbrella', 'infinity', 'orbit',
31
+ ];
32
+
33
+ const icons = {};
34
+ const missing = [];
35
+ for (const name of [...new Set(ICON_NAMES)]) {
36
+ let svg;
37
+ try { svg = await readFile(join(root, 'icons', `${name}.svg`), 'utf8'); } catch { missing.push(name); continue; }
38
+ const inner = svg.replace(/<!--[\s\S]*?-->/g, '').replace(/^[\s\S]*?<svg\b[^>]*>/, '').replace(/<\/svg>\s*$/, '')
39
+ .replace(/\s+/g, ' ').replace(/> </g, '><').trim();
40
+ if (!inner) { missing.push(name); continue; }
41
+ icons[name] = inner;
42
+ }
43
+ if (missing.length) {
44
+ console.error(`missing in lucide-static ${version}: ${missing.join(', ')}`);
45
+ process.exit(1);
46
+ }
47
+ await writeFile(out, `${JSON.stringify({ source: 'lucide-static', version, license, viewBox: '0 0 24 24', stroke: true, icons }, null, 0)}\n`);
48
+ console.log(`${Object.keys(icons).length} icons → ${out}`);
@@ -0,0 +1,34 @@
1
+ import { resolve } from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+
4
+ const defaultTestPath = fileURLToPath(new URL('../src/runtime/office/office-live-runtime.test.mjs', import.meta.url));
5
+ export const liveProfiles = Object.freeze(['excel', 'word', 'powerpoint', 'author', 'attach', 'contract', 'compat', 'all']);
6
+
7
+ export const liveTestHelp = `실제 Office 검증은 실행 범위를 지정해 주세요.
8
+ npm run test:office:live -- <excel|word|powerpoint|author|attach|contract>
9
+ npm run test:office:compat 매크로·서식 9종 호환성 검증
10
+ npm run test:office:live:all 모든 라이브 검증
11
+ npm run test:office Office를 실행하지 않는 일반 검증
12
+ npm run test:office:render 별도 렌더 검증
13
+ 기존 호출도 지원합니다: <테스트 파일> [테스트 이름 정규식]
14
+ `;
15
+
16
+ export function buildLiveTestPlan(argv, testPath = defaultTestPath) {
17
+ const [selector, namePattern, ...extra] = argv;
18
+ if (!selector || selector === '--help' || selector === '-h') return null;
19
+ if (extra.length) throw new Error('인자가 너무 많습니다.');
20
+ let pattern;
21
+ if (liveProfiles.includes(selector)) {
22
+ if (namePattern) throw new Error('기능 이름 뒤에는 추가 인자를 받지 않습니다.');
23
+ pattern = selector === 'all' ? null : `^\\[${selector}\\]`;
24
+ } else {
25
+ if (!/\.(?:mjs|cjs|js)$/u.test(selector)) throw new Error(`알 수 없는 검증 범위: ${selector}`);
26
+ testPath = resolve(selector);
27
+ pattern = namePattern || null;
28
+ }
29
+ if (pattern) new RegExp(pattern); // Reject malformed filters before starting a child.
30
+ return {
31
+ label: selector,
32
+ args: ['--test', '--test-reporter=tap', ...(pattern ? ['--test-name-pattern', pattern] : []), testPath],
33
+ };
34
+ }
@@ -0,0 +1,74 @@
1
+ import assert from 'node:assert/strict';
2
+ import { mkdtemp, readFile, writeFile } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { PDFDocument, degrees } from 'pdf-lib';
6
+ import { applyPdfBatch } from '../src/runtime/office/pdf/pdf-adapter.mjs';
7
+ import { extractPdfTextLayout, findPdfText } from '../src/runtime/office/pdf/pdf-analysis.mjs';
8
+
9
+ // Deterministic differential stress: compare search-derived PDF marks with
10
+ // the coordinates used to draw the source, varying page rotation and boxes.
11
+ // This is opt-in and never runs as part of the default unit suite.
12
+ const until = Date.parse(process.argv[2] || '');
13
+ assert.ok(Number.isFinite(until), 'Pass an ISO end time');
14
+ const directory = await mkdtemp(join(tmpdir(), 'pdf-rotation-stress-'));
15
+ const path = join(directory, 'latest.pdf');
16
+ let state = 0x5eed2026;
17
+ const random = () => {
18
+ state = (Math.imul(state, 1664525) + 1013904223) >>> 0;
19
+ return state / 0x100000000;
20
+ };
21
+ const between = (min, max) => min + random() * (max - min);
22
+ let rounds = 0;
23
+ let pagesChecked = 0;
24
+ let nextReport = Date.now();
25
+ do {
26
+ const pdf = await PDFDocument.create();
27
+ const font = await pdf.embedFont('Helvetica');
28
+ const expected = [];
29
+ for (let index = 0; index < 16; index += 1) {
30
+ const width = between(400, 700);
31
+ const height = between(350, 800);
32
+ const originX = between(-100, 150);
33
+ const originY = between(-100, 150);
34
+ const page = pdf.addPage([width, height]);
35
+ page.setMediaBox(originX, originY, width, height);
36
+ page.setCropBox(originX + 10, originY + 10, width - 20, height - 20);
37
+ page.setRotation(degrees([0, 90, 180, 270][index % 4]));
38
+ const size = between(9, 30);
39
+ const x = originX + 40;
40
+ const y = originY + height - 80;
41
+ const prefix = font.widthOfTextAtSize('Al', size);
42
+ // Separate text runs exercise joining in reversed as well as upright text.
43
+ page.drawText('Alpha', { x, y, size, font });
44
+ page.drawText('beta', { x: x + font.widthOfTextAtSize('Alpha ', size), y, size, font });
45
+ expected.push({ x: x + prefix, y, width: font.widthOfTextAtSize('pha beta', size), height: size });
46
+ }
47
+ await writeFile(path, await pdf.save());
48
+ const results = await applyPdfBatch(path, [
49
+ { op: 'highlight', find: 'pha beta' },
50
+ { op: 'add_link', find: 'pha beta', toPage: 1 },
51
+ { op: 'add_text', text: 'After measurement', page: 1, x: 40, y: 40, size: 10 },
52
+ ]);
53
+ for (const result of results.slice(0, 2)) {
54
+ assert.equal(result.boxes.length, expected.length);
55
+ for (const box of result.boxes) {
56
+ for (const key of ['x', 'y', 'width', 'height']) {
57
+ assert.ok(Math.abs(box[key] - expected[box.page - 1][key]) < 0.08,
58
+ JSON.stringify({ round: rounds, state, key, box, expected: expected[box.page - 1], path }));
59
+ }
60
+ }
61
+ }
62
+ const layout = await extractPdfTextLayout(path, { shapes: false });
63
+ assert.equal(findPdfText(layout, 'pha beta').matchCount, expected.length);
64
+ const saved = await PDFDocument.load(await readFile(path));
65
+ assert.deepEqual(saved.getPages().map((page) => page.getRotation().angle),
66
+ expected.map((_, index) => [0, 90, 180, 270][index % 4]));
67
+ rounds += 1;
68
+ pagesChecked += expected.length;
69
+ if (Date.now() >= nextReport) {
70
+ console.log(JSON.stringify({ rounds, pagesChecked, rssMB: Math.round(process.memoryUsage().rss / 1024 / 1024) }));
71
+ nextReport = Date.now() + 60_000;
72
+ }
73
+ } while (Date.now() < until);
74
+ console.log(JSON.stringify({ ok: true, rounds, pagesChecked, directory }));