mixdog 0.9.166 → 0.9.167

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 (221) hide show
  1. package/package.json +1 -1
  2. package/scripts/audit-usage-ledger.mjs +86 -0
  3. package/scripts/generate-voice-runtime-manifest.mjs +22 -17
  4. package/scripts/memory-chunk-quality.mjs +128 -0
  5. package/scripts/memory-layer2-check.mjs +133 -0
  6. package/scripts/model-catalog-audit.mjs +6 -0
  7. package/scripts/native-tool-download.mjs +14 -0
  8. package/scripts/prepare-native-assets.mjs +2 -7
  9. package/scripts/tool-failures.mjs +7 -2
  10. package/scripts/verify-release-assets.mjs +48 -90
  11. package/src/defaults/skills/browser-use/SKILL.md +33 -18
  12. package/src/defaults/skills/computer-use/SKILL.md +16 -8
  13. package/src/lib/keychain-cjs.cjs +0 -1
  14. package/src/lib/rules-builder.cjs +4 -1
  15. package/src/rules/agent/40-cycle1-agent.md +21 -13
  16. package/src/rules/lead/01-general.md +8 -3
  17. package/src/rules/shared/10-tool-workflow.md +20 -11
  18. package/src/rules/shared/30-exploration.md +11 -4
  19. package/src/rules/shared/40-editing.md +2 -3
  20. package/src/rules/shared/50-execution.md +6 -3
  21. package/src/rules/shared/60-verification.md +3 -2
  22. package/src/rules/shared/70-delivery.md +0 -4
  23. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +51 -45
  24. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +3 -4
  25. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +44 -7
  26. package/src/runtime/agent/orchestrator/agent-trace.mjs +9 -0
  27. package/src/runtime/agent/orchestrator/config.mjs +9 -4
  28. package/src/runtime/agent/orchestrator/context/collect.mjs +25 -1055
  29. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +272 -0
  30. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +296 -0
  31. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +523 -0
  32. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +7 -2
  33. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +13 -14
  34. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +214 -0
  35. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +220 -116
  36. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +74 -44
  37. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +191 -29
  38. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +13 -12
  39. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +1 -9
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +5 -2
  41. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +48 -25
  42. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +28 -2
  43. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +3 -1
  44. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +1 -8
  45. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +32 -0
  46. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +21 -6
  47. package/src/runtime/agent/orchestrator/providers/lib/grok-tool-schema.mjs +61 -13
  48. package/src/runtime/agent/orchestrator/providers/model-catalog-projection.mjs +6 -1
  49. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +123 -118
  50. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +54 -0
  51. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +5 -2
  52. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +34 -3
  53. package/src/runtime/agent/orchestrator/providers/openai-codex-endpoints.mjs +21 -0
  54. package/src/runtime/agent/orchestrator/providers/openai-oauth-catalog.mjs +154 -0
  55. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +2 -1
  56. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +322 -0
  57. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +243 -702
  58. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +2 -2
  59. package/src/runtime/agent/orchestrator/providers/openai-startup-prewarm.mjs +221 -0
  60. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +3 -2
  61. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +1 -1
  62. package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +19 -0
  63. package/src/runtime/agent/orchestrator/providers/provider-model-identities.mjs +40 -0
  64. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +120 -710
  65. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +36 -15
  66. package/src/runtime/agent/orchestrator/session/cache/util.mjs +9 -0
  67. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +17 -4
  68. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +36 -31
  69. package/src/runtime/agent/orchestrator/session/compact.mjs +4 -5
  70. package/src/runtime/agent/orchestrator/session/context-compaction-policy.mjs +6 -5
  71. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +8 -6
  72. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +121 -0
  73. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -3
  74. package/src/runtime/agent/orchestrator/session/loop/diagnostics.mjs +74 -0
  75. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +44 -17
  76. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +266 -0
  77. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +111 -0
  78. package/src/runtime/agent/orchestrator/session/loop/request-projection.mjs +99 -0
  79. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +91 -0
  80. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +36 -0
  81. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +3 -3
  82. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
  83. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +20 -11
  84. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +3 -5
  85. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +9 -3
  86. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +39 -0
  87. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +3 -2
  88. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +21 -3
  89. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -3
  91. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +25 -25
  92. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +62 -10
  93. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +17 -0
  94. package/src/runtime/agent/orchestrator/tools/builtin/read-batch.mjs +61 -4
  95. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +13 -9
  96. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +12 -2
  97. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +3 -2
  98. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +8 -3
  99. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +69 -6
  100. package/src/runtime/agent/orchestrator/tools/builtin.mjs +14 -17
  101. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +1 -1
  102. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  104. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +1 -1
  105. package/src/runtime/bridge-discovery.mjs +8 -0
  106. package/src/runtime/browser-bridge/action-schema.mjs +37 -43
  107. package/src/runtime/browser-bridge/client.mjs +111 -99
  108. package/src/runtime/browser-bridge/input-fields.mjs +187 -0
  109. package/src/runtime/browser-bridge/tool-defs.mjs +12 -227
  110. package/src/runtime/computer-bridge/action-schema.mjs +2 -46
  111. package/src/runtime/computer-bridge/client.mjs +69 -77
  112. package/src/runtime/computer-bridge/core-actions.mjs +7 -5
  113. package/src/runtime/computer-bridge/error-recovery.mjs +41 -37
  114. package/src/runtime/computer-bridge/tool-defs.mjs +1 -1
  115. package/src/runtime/github/commands.mjs +4 -1
  116. package/src/runtime/github/contract.mjs +1 -1
  117. package/src/runtime/github/tool.mjs +2 -2
  118. package/src/runtime/media/adapters/antigravity-image.mjs +72 -0
  119. package/src/runtime/media/adapters/gemini-image.mjs +20 -11
  120. package/src/runtime/media/auth.mjs +12 -0
  121. package/src/runtime/media/catalog.mjs +30 -10
  122. package/src/runtime/media/jobs.mjs +4 -0
  123. package/src/runtime/media/lanes.mjs +40 -31
  124. package/src/runtime/memory/index.mjs +2 -9
  125. package/src/runtime/memory/lib/compact-handoff.mjs +26 -18
  126. package/src/runtime/memory/lib/memory-chunk-audit.mjs +41 -0
  127. package/src/runtime/memory/lib/memory-chunk-quality.mjs +388 -0
  128. package/src/runtime/memory/lib/memory-cycle1.mjs +95 -394
  129. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +29 -4
  130. package/src/runtime/memory/lib/memory-recall-store.mjs +8 -12
  131. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -11
  132. package/src/runtime/memory/lib/memory.mjs +2 -0
  133. package/src/runtime/memory/lib/query-handlers.mjs +98 -144
  134. package/src/runtime/memory/lib/query-ranking.mjs +23 -9
  135. package/src/runtime/memory/lib/recall-format.mjs +37 -27
  136. package/src/runtime/memory/lib/session-ingest-runtime.mjs +14 -8
  137. package/src/runtime/memory/lib/session-ingest.mjs +45 -84
  138. package/src/runtime/memory/lib/transcript-ingest.mjs +19 -21
  139. package/src/runtime/memory/tool-defs.mjs +2 -2
  140. package/src/runtime/office/authoring/pptx-author-session.mjs +3 -7
  141. package/src/runtime/office/core/office-actions-batch.mjs +2 -8
  142. package/src/runtime/office/core/office-actions-open.mjs +124 -0
  143. package/src/runtime/office/core/office-actions-read.mjs +127 -0
  144. package/src/runtime/office/core/office-core.mjs +80 -1
  145. package/src/runtime/office/core/office-sessions.mjs +116 -138
  146. package/src/runtime/office/index.mjs +18 -271
  147. package/src/runtime/office/pdf/pdf-analysis.mjs +2 -2
  148. package/src/runtime/office/pdf/pdf-limits.mjs +2 -0
  149. package/src/runtime/office/tool-defs.mjs +7 -6
  150. package/src/runtime/shared/agent-route-config.mjs +8 -8
  151. package/src/runtime/shared/child-spawn-gate.mjs +10 -13
  152. package/src/runtime/shared/config.mjs +2 -7
  153. package/src/runtime/shared/env.mjs +3 -3
  154. package/src/runtime/shared/err-text.mjs +1 -1
  155. package/src/runtime/shared/extension-scopes.mjs +3 -2
  156. package/src/runtime/shared/heap-cap.mjs +10 -6
  157. package/src/runtime/shared/llm/cost.mjs +35 -10
  158. package/src/runtime/shared/llm/usage-accounting.mjs +11 -1
  159. package/src/runtime/shared/llm/usage-context.mjs +6 -0
  160. package/src/runtime/shared/llm/usage-ledger-import.mjs +5 -0
  161. package/src/runtime/shared/llm/usage-ledger-repair.mjs +109 -0
  162. package/src/runtime/shared/llm/usage-ledger.mjs +59 -20
  163. package/src/runtime/shared/llm/usage-pricing-refresh.mjs +26 -0
  164. package/src/runtime/shared/llm/usage-rollup.mjs +17 -15
  165. package/src/runtime/shared/native-asset.mjs +3 -4
  166. package/src/runtime/shared/object.mjs +4 -0
  167. package/src/runtime/shared/pg-schema-db.mjs +21 -0
  168. package/src/runtime/shared/plugin-metadata.mjs +3 -1
  169. package/src/runtime/shared/resource-admission.mjs +1 -6
  170. package/src/runtime/shared/schedules-db.mjs +8 -24
  171. package/src/runtime/shared/schema-value-error.d.mts +2 -0
  172. package/src/runtime/shared/schema-value-error.mjs +68 -0
  173. package/src/runtime/shared/singleton-owner.mjs +11 -24
  174. package/src/runtime/shared/staged-update.mjs +1 -10
  175. package/src/runtime/shared/tool-card-model.mjs +8 -5
  176. package/src/runtime/shared/tool-execution-contract.mjs +1 -1
  177. package/src/runtime/shared/tool-surface.mjs +1 -5
  178. package/src/runtime/shared/user-data-guard.mjs +1 -4
  179. package/src/runtime/shared/webhooks-db.mjs +8 -24
  180. package/src/runtime/web-search/index.mjs +32 -8
  181. package/src/runtime/web-search/tool-defs.mjs +4 -4
  182. package/src/session-runtime/config-lifecycle.mjs +34 -0
  183. package/src/session-runtime/context-status.mjs +19 -0
  184. package/src/session-runtime/cwd-plugins.mjs +12 -29
  185. package/src/session-runtime/goal-tasks.mjs +2 -2
  186. package/src/session-runtime/goal-tool-defs.mjs +3 -2
  187. package/src/session-runtime/internal-tool-executor.mjs +7 -0
  188. package/src/session-runtime/lifecycle-api.mjs +5 -11
  189. package/src/session-runtime/notification-bus.mjs +41 -0
  190. package/src/session-runtime/prewarm.mjs +22 -0
  191. package/src/session-runtime/runtime-bootstrap.mjs +90 -0
  192. package/src/session-runtime/runtime-core.mjs +88 -202
  193. package/src/session-runtime/runtime-feature-gates.mjs +37 -0
  194. package/src/session-runtime/session-lifecycle.mjs +5 -5
  195. package/src/session-runtime/session-turn-api.mjs +1 -12
  196. package/src/session-runtime/setup-tool/executor.mjs +13 -5
  197. package/src/session-runtime/setup-tool/tool-defs.mjs +52 -46
  198. package/src/session-runtime/tool-defs.mjs +73 -4
  199. package/src/session-runtime/usage-stats-api.mjs +4 -1
  200. package/src/session-runtime/warmup-schedulers.mjs +8 -2
  201. package/src/session-runtime/workflow.mjs +14 -0
  202. package/src/standalone/channel-session-router.mjs +3 -1
  203. package/src/standalone/channel-worker.mjs +18 -9
  204. package/src/standalone/daemon-crash-capture.mjs +534 -0
  205. package/src/standalone/daemon-telemetry.mjs +175 -0
  206. package/src/standalone/daemon.mjs +31 -21
  207. package/src/standalone/session-client.mjs +31 -23
  208. package/src/standalone/usage-dashboard-model.mjs +2 -0
  209. package/src/standalone/usage-stats-hours.mjs +18 -11
  210. package/src/standalone/usage-stats-model.mjs +39 -28
  211. package/src/standalone/usage-stats-period.mjs +43 -45
  212. package/src/tui/app/use-transcript-window.mjs +1 -1
  213. package/src/tui/components/StatusLine.jsx +13 -42
  214. package/src/tui/dist/index.mjs +256 -239
  215. package/src/tui/session/session-api-ext.mjs +44 -41
  216. package/src/tui/session/session-api.mjs +4 -0
  217. package/src/tui/session/tool-card-results.mjs +25 -78
  218. package/src/tui/session/tool-result-status.mjs +94 -1
  219. package/src/tui/session/turn-aggregate-cards.mjs +17 -54
  220. package/src/ui/statusline-format.mjs +6 -26
  221. package/src/workflows/default/WORKFLOW.md +5 -0
@@ -7,7 +7,6 @@ import { performance } from 'node:perf_hooks';
7
7
  import { randomUUID } from 'node:crypto';
8
8
  import keychain from '../lib/keychain-cjs.cjs';
9
9
  import './hitch-profile.mjs';
10
- import { ensureStandaloneEnvironment } from '../standalone/seeds.mjs';
11
10
  import { createStandaloneAgent } from '../standalone/agent-tool.mjs';
12
11
  import { createStandaloneChannelWorker } from '../standalone/channel-worker.mjs';
13
12
  import { createStandaloneHookBus } from '../standalone/hook-bus.mjs';
@@ -20,6 +19,7 @@ import {
20
19
  channelNotificationModelContent,
21
20
  channelNotificationSessionId,
22
21
  } from '../runtime/shared/channel-notification-routing.mjs';
22
+ import { CHANNEL_NOTIFICATION_METHOD } from '../standalone/channel-session-router.mjs';
23
23
  import {
24
24
  normalizeAgentPermissionOrNone,
25
25
  readMarkdownDocument,
@@ -31,7 +31,6 @@ import {
31
31
  consumeOpenAICodexResetCredit,
32
32
  fetchOAuthUsageSnapshot,
33
33
  } from '../runtime/agent/orchestrator/providers/oauth-usage.mjs';
34
- import { hasActiveAutomation } from '../standalone/channel-admin.mjs';
35
34
  import { listRegisteredPlugins, pluginAdminStatus } from '../standalone/plugin-admin.mjs';
36
35
  import { clean, hasOwn } from './session-text.mjs';
37
36
  import { normalizeToolMode } from './effort.mjs';
@@ -47,16 +46,13 @@ import {
47
46
  autoClearIdleMsForProvider,
48
47
  autoClearProviderDefaults,
49
48
  normalizeCompactionConfig,
50
- moduleEnabled,
51
49
  setModuleEnabledInConfig,
52
- recapEnabled,
53
50
  setRecapEnabledInConfig,
54
- memoryToolsEnabled,
55
51
  setMemoryToolsEnabledInConfig,
56
52
  formatDurationMs,
57
53
  parseDurationMs,
58
54
  } from './config-helpers.mjs';
59
- import { builtinFeatureActive, featureDisallowedToolsFor, localGitToolsActive, withGrandfatheredBuiltins } from './builtin-features.mjs';
55
+ import { createRuntimeFeatureGates } from './runtime-feature-gates.mjs';
60
56
  import { outputStyleStatus as outputStyleStatusRaw } from './output-styles.mjs';
61
57
  import {
62
58
  countSkillFiles,
@@ -65,8 +61,6 @@ import {
65
61
  pluginMcpServerName,
66
62
  } from './plugin-mcp.mjs';
67
63
  import {
68
- WEB_SEARCH_DEFAULT_PROVIDER,
69
- WEB_SEARCH_DEFAULT_MODEL,
70
64
  workflowPresetId,
71
65
  createWorkflowHelpers,
72
66
  normalizeWebSearchProviderId,
@@ -76,13 +70,10 @@ import {
76
70
  normalizeWorkflowRoute,
77
71
  upsertWorkflowPreset,
78
72
  createWorkflowRouteHelpers,
73
+ webSearchRouteOrDefault,
79
74
  } from './workflow.mjs';
80
75
  import { applyDeferredToolSurface } from './tool-catalog.mjs';
81
- import {
82
- TOOL_SEARCH_TOOL,
83
- CWD_TOOL,
84
- SKILL_TOOL,
85
- } from './tool-defs.mjs';
76
+ import { collectStandaloneToolDefs } from './tool-defs.mjs';
86
77
  import {
87
78
  modelToolSchemaAllowlist,
88
79
  normalizeToolProfile,
@@ -93,17 +84,16 @@ import {
93
84
  providerModelCacheRow as providerModelCacheRowRaw,
94
85
  } from './model-recency.mjs';
95
86
  import { createNativeWebSearch } from './native-web-search.mjs';
96
- import { createConfigLifecycle } from './config-lifecycle.mjs';
87
+ import { createConfigLifecycle, resolveInitialConfigState } from './config-lifecycle.mjs';
97
88
  import { createQuickModelRows } from './quick-model-rows.mjs';
98
- import { createWarmupSchedulers } from './warmup-schedulers.mjs';
99
- import { createPrewarmSchedulers } from './prewarm.mjs';
100
89
  import { createMcpGlue } from './mcp-glue.mjs';
101
90
  import { createCwdPlugins } from './cwd-plugins.mjs';
102
91
  import { createSettingsApi } from './settings-api.mjs';
103
92
  import { createProviderModels } from './provider-models.mjs';
104
93
  import { createProviderUsage } from './provider-usage.mjs';
105
94
  import { envFlag } from '../runtime/shared/env.mjs';
106
- import { bootProfile, profiledImport } from './boot-profile.mjs';
95
+ import { bootProfile } from './boot-profile.mjs';
96
+ import { loadRuntimeModules, prepareStandaloneEnvironment } from './runtime-bootstrap.mjs';
107
97
  import { createProviderReadiness } from './provider-readiness.mjs';
108
98
  import { createLazyRuntimeModules } from './runtime-modules.mjs';
109
99
  import { closeNativeToolTransports, closePatchRuntimeIfLoaded, withTeardownDeadline } from './native-teardown.mjs';
@@ -111,14 +101,14 @@ import { createChannelConfigApi } from './channel-config-api.mjs';
111
101
  import { createMediaApi } from './media-api.mjs';
112
102
  import { createProviderAuthApi } from './provider-auth-api.mjs';
113
103
  import { createUsageStatsApi } from './usage-stats-api.mjs';
114
- import { createContextStatus } from './context-status.mjs';
104
+ import { contextStatusForSession, createContextStatus } from './context-status.mjs';
115
105
  import { createLifecycleApi } from './lifecycle-api.mjs';
116
106
  import { createResourceApi } from './resource-api.mjs';
117
107
  import { createModelRouteApi } from './model-route-api.mjs';
118
108
  import { createWorkflowAgentsApi } from './workflow-agents-api.mjs';
119
109
  import { createSelfUpdateController } from './self-update.mjs';
120
110
  import { createSkillsApi } from './skills-api.mjs';
121
- import { createNotificationBus } from './notification-bus.mjs';
111
+ import { createCompletionWakeScheduler, createNotificationBus } from './notification-bus.mjs';
122
112
  import { createToolSurface } from './tool-surface.mjs';
123
113
  import {
124
114
  LOCAL_PROVIDER_ID,
@@ -141,28 +131,19 @@ import { createHookPayload } from './hook-payload.mjs';
141
131
  import { createRoutedAgentTool } from './agent-tool-routing.mjs';
142
132
  import { createInternalToolExecutor } from './internal-tool-executor.mjs';
143
133
  import {
144
- RUNTIME,
145
- WEB_SEARCH_TOOL_DEFS,
146
- MEMORY_TOOL_DEFS,
147
- CHANNEL_TOOL_DEFS,
148
- CODE_GRAPH_TOOL_DEFS,
149
- STATUSLINE_SESSION_ROUTES,
150
134
  STANDALONE_ROOT,
151
135
  STANDALONE_DATA_DIR,
152
136
  } from './runtime-paths.mjs';
153
137
  // Desktop-app bridges: tiny fs/fetch clients, so a static import adds no
154
138
  // meaningful boot cost. The tools themselves are gated per session by the
155
- // sync bridge-availability probes (headless runs never see them); execution
156
- // lives in internal-tool-executor.mjs.
157
- import { browserBridgeAvailableSync } from '../runtime/browser-bridge/client.mjs';
139
+ // sync bridge-availability probes in runtime-feature-gates.mjs (headless runs
140
+ // never see them); execution lives in internal-tool-executor.mjs.
158
141
  import { TOOL_DEFS as BROWSER_BRIDGE_TOOL_DEFS } from '../runtime/browser-bridge/tool-defs.mjs';
159
142
  import {
160
- computerBridgeAvailableSync,
161
143
  deferComputerSessionRelease,
162
144
  endComputerExecution,
163
145
  } from '../runtime/computer-bridge/client.mjs';
164
146
  import { TOOL_DEFS as COMPUTER_BRIDGE_TOOL_DEFS } from '../runtime/computer-bridge/tool-defs.mjs';
165
- import { initializeOfficeTransactions } from '../runtime/office/index.mjs';
166
147
  import { TOOL_DEFS as OFFICE_TOOL_DEFS } from '../runtime/office/tool-defs.mjs';
167
148
  import { TOOL_DEFS as MEDIA_TOOL_DEFS } from '../runtime/media/tool-defs.mjs';
168
149
  import { SETUP_TOOL_DEFS } from './setup-tool/tool-defs.mjs';
@@ -228,19 +209,7 @@ export async function createMixdogSessionRuntime({
228
209
  // Last assistant text handed to the transcript writer (via onAssistantText),
229
210
  // so the post-turn final-content append can skip an exact duplicate.
230
211
  rt._lastAppendedAssistant = '';
231
- process.env.MIXDOG_QUIET_SESSION_LOG ??= '1';
232
- const standaloneStartedAt = performance.now();
233
- ensureStandaloneEnvironment({
234
- rootDir: STANDALONE_ROOT,
235
- dataDir: STANDALONE_DATA_DIR,
236
- });
237
- // Office journals exist only for cross-process crash recovery, so startup just
238
- // prunes expired ones in the background. Surfacing them as session context made
239
- // every new session (agents included) re-announce unrelated leftovers for the
240
- // full 30-day retention window; recovery stays reachable on demand through
241
- // office action=transactions / action=recover.
242
- initializeOfficeTransactions(STANDALONE_DATA_DIR).catch(() => {});
243
- bootProfile('standalone-env:ready', { ms: (performance.now() - standaloneStartedAt).toFixed(1) });
212
+ prepareStandaloneEnvironment();
244
213
  const {
245
214
  awaitKeychainPrewarm,
246
215
  invalidateProviderCaches,
@@ -248,7 +217,6 @@ export async function createMixdogSessionRuntime({
248
217
  modelMetaByRoute,
249
218
  providerModelCaches,
250
219
  providerUsageCaches,
251
- providerInitPromises,
252
220
  } = createProviderReadiness({
253
221
  rt,
254
222
  keychain,
@@ -261,8 +229,7 @@ export async function createMixdogSessionRuntime({
261
229
  }),
262
230
  });
263
231
 
264
- const importsStartedAt = performance.now();
265
- const [
232
+ const {
266
233
  cfgMod,
267
234
  sharedCfgMod,
268
235
  reg,
@@ -275,45 +242,21 @@ export async function createMixdogSessionRuntime({
275
242
  memoryToolDefs,
276
243
  channelToolDefs,
277
244
  codeGraphToolDefs,
278
- ] = await Promise.all([
279
- profiledImport('config', `${RUNTIME}/config.mjs`),
280
- profiledImport('shared-config', `${RUNTIME}/../../shared/config.mjs`),
281
- profiledImport('providers-registry', `${RUNTIME}/providers/registry.mjs`),
282
- profiledImport('mcp-client', `${RUNTIME}/mcp/client.mjs`),
283
- profiledImport('session-manager', `${RUNTIME}/session/manager.mjs`),
284
- profiledImport('context-collect', `${RUNTIME}/context/collect.mjs`),
285
- profiledImport('internal-tools', `${RUNTIME}/internal-tools.mjs`),
286
- profiledImport('status-routes', STATUSLINE_SESSION_ROUTES, { optional: true }),
287
- profiledImport('web-search-tool-defs', WEB_SEARCH_TOOL_DEFS, { optional: true }),
288
- profiledImport('memory-tool-defs', MEMORY_TOOL_DEFS, { optional: true }),
289
- profiledImport('channel-tool-defs', CHANNEL_TOOL_DEFS, { optional: true }),
290
- profiledImport('code-graph-tool-defs', CODE_GRAPH_TOOL_DEFS, { optional: true }),
291
- ]);
292
- bootProfile('imports:ready', { ms: (performance.now() - importsStartedAt).toFixed(1) });
293
- const pluginDataDir = cfgMod.getPluginData();
294
- // Re-wire the idle/tombstone sweep. startIdleCleanup() lost its caller in a
295
- // refactor, so closed-session tombstones were never deleted after their 24h
296
- // grace — the store grew unbounded (observed: 1.8k files / 114MB), which
297
- // made summary-index rebuilds and per-save index rewrites stall boot for
298
- // seconds. Timer is unref'd and first fires after CLEANUP_INITIAL_DELAY_MS
299
- // (5min), so this adds zero boot-path cost.
300
- try { mgr.startIdleCleanup?.(); } catch { /* cleanup is best-effort */ }
245
+ } = await loadRuntimeModules();
301
246
 
302
- // Memory ingest is always-on. `recap` gates only the background cycles;
303
- // `memoryTools` gates the model-facing memory/recall tool surface. Headless
304
- // runs override any toggle per process via MIXDOG_FEATURE_* env values.
305
- const recapEnabledFn = () => recapEnabled(rt.config, true);
306
- const memoryToolsEnabledFn = () => builtinFeatureActive(rt.config, 'memory');
307
- const webSearchEnabled = () => builtinFeatureActive(rt.config, 'webSearch');
308
- const gitToolsEnabledFn = () => localGitToolsActive(rt.config, rt.toolProfile);
309
- const officeToolsEnabledFn = () => builtinFeatureActive(rt.config, 'office');
310
- const localProviderEnabledFn = () => builtinFeatureActive(rt.config, 'localProvider');
311
- const mediaToolEnabledFn = () => builtinFeatureActive(rt.config, 'media');
312
- const channelsEnabled = () => moduleEnabled(rt.config, 'channels', true);
313
- const featureDisallowedTools = () => featureDisallowedToolsFor(rt.config, {
314
- browserAvailable: browserBridgeAvailableSync(),
315
- computerAvailable: computerBridgeAvailableSync(),
316
- toolProfile: rt.toolProfile,
247
+ const {
248
+ recapEnabledFn,
249
+ memoryToolsEnabledFn,
250
+ webSearchEnabled,
251
+ gitToolsEnabledFn,
252
+ officeToolsEnabledFn,
253
+ localProviderEnabledFn,
254
+ mediaToolEnabledFn,
255
+ channelsEnabled,
256
+ featureDisallowedTools,
257
+ } = createRuntimeFeatureGates({
258
+ getConfig: () => rt.config,
259
+ getToolProfile: () => rt.toolProfile,
317
260
  });
318
261
 
319
262
  const { getMemoryModule, getWebSearchModule, getCodeGraphModule } = createLazyRuntimeModules({ rt, cfgMod });
@@ -331,24 +274,23 @@ export async function createMixdogSessionRuntime({
331
274
  }
332
275
 
333
276
  const configStartedAt = performance.now();
334
- rt.config = withGrandfatheredBuiltins(initialConfig && typeof initialConfig === 'object'
335
- ? initialConfig
336
- : cfgMod.loadConfig({ secrets: false }));
277
+ ({
278
+ config: rt.config,
279
+ route: rt.route,
280
+ webSearchRoute: rt.webSearchRoute,
281
+ } = resolveInitialConfigState({
282
+ initialConfig,
283
+ loadConfig: () => cfgMod.loadConfig({ secrets: false }),
284
+ resolveRoute,
285
+ provider,
286
+ model,
287
+ effort,
288
+ fast,
289
+ modelParameters,
290
+ }));
337
291
  configureLocalProviderIdleTtl(rt.config.providers?.[LOCAL_PROVIDER_ID]?.idleTtlSeconds);
338
292
  setConfiguredShell(normalizeSystemShellConfig(rt.config.shell).command);
339
293
  rt.configHasSecrets = false;
340
- rt.route = resolveRoute(rt.config, { provider, model });
341
- if (effort !== undefined) rt.route = { ...rt.route, effort: effort || null };
342
- if (fast === true || fast === false) rt.route = { ...rt.route, fast };
343
- if (modelParameters && typeof modelParameters === 'object') {
344
- rt.route = { ...rt.route, modelParameters: { ...modelParameters } };
345
- }
346
- // Unset means the default "follow the Main Model" route, not "unconfigured".
347
- rt.webSearchRoute = normalizeWebSearchRouteConfig(rt.config.webSearchRoute)
348
- || normalizeWebSearchRouteConfig({
349
- provider: WEB_SEARCH_DEFAULT_PROVIDER,
350
- model: WEB_SEARCH_DEFAULT_MODEL,
351
- });
352
294
  bootProfile('config:ready', { ms: (performance.now() - configStartedAt).toFixed(1) });
353
295
  rt.mode = normalizeToolMode(toolMode);
354
296
  rt.session = null;
@@ -358,7 +300,6 @@ export async function createMixdogSessionRuntime({
358
300
  rt.reservedSessionId = null;
359
301
  rt.sessionCreatePromise = null;
360
302
  rt.currentCwd = cwd;
361
- rt.sessionNeedsCwdRefresh = false;
362
303
  rt.closeRequested = false;
363
304
  const warmupTimers = {
364
305
  providerSetupWarmupTimer: null,
@@ -482,46 +423,18 @@ export async function createMixdogSessionRuntime({
482
423
  getDataDir: () => cfgMod.getPluginData?.() || STANDALONE_DATA_DIR,
483
424
  emitNotification: (...a) => emitRuntimeNotification(...a),
484
425
  });
485
- const autoUpdateEnabled = () => selfUpdate.autoUpdateEnabled();
486
- const checkForUpdateInternal = (...a) => selfUpdate.checkForUpdate(...a);
487
- const runUpdateNowInternal = (...a) => selfUpdate.runUpdateNow();
488
426
  selfUpdate.startBootCheck();
489
427
 
490
428
  // Notification fan-out (listener broadcast + pending-queue mirroring of
491
429
  // terminal completions) lives in notification-bus.mjs.
492
430
  let sessionTurnApi = null;
493
431
  let goalRuntime = null;
494
- const completionWakeups = new Set();
495
- const wakeQueuedCompletion = ({ sessionId, executionId, enqueuedAt } = {}) => {
496
- const ownerSessionId = String(sessionId || '').trim();
497
- if (!ownerSessionId || completionWakeups.has(ownerSessionId)) return false;
498
- completionWakeups.add(ownerSessionId);
499
- setImmediate(async () => {
500
- const queuedAt = Number(enqueuedAt) || Date.now();
501
- try {
502
- const currentSessionId = String(rt.session?.id || rt.reservedSessionId || '').trim();
503
- if (currentSessionId !== ownerSessionId || !sessionTurnApi) return;
504
- const delayMs = Math.max(0, Date.now() - queuedAt);
505
- if (delayMs >= 1_000) {
506
- process.stderr.write(
507
- `[notification] delayed completion wake sessionId=${ownerSessionId}`
508
- + ` executionId=${executionId || 'unknown'} queuedMs=${delayMs}\n`,
509
- );
510
- }
511
- await sessionTurnApi.ask('', { submittedAt: queuedAt });
512
- } catch (err) {
513
- try {
514
- process.stderr.write(
515
- `[notification] completion wake failed sessionId=${ownerSessionId}`
516
- + ` executionId=${executionId || 'unknown'} err=${err?.message || err}\n`,
517
- );
518
- } catch {}
519
- } finally {
520
- completionWakeups.delete(ownerSessionId);
521
- }
522
- });
523
- return true;
524
- };
432
+ // Late-bound: the turn api is built near the end of this factory, while the
433
+ // notification bus must exist before it.
434
+ const wakeQueuedCompletion = createCompletionWakeScheduler({
435
+ getCurrentSessionId: () => rt.session?.id || rt.reservedSessionId || null,
436
+ getTurnApi: () => sessionTurnApi,
437
+ });
525
438
  const {
526
439
  emitRuntimeNotification,
527
440
  notifySession,
@@ -548,6 +461,19 @@ export async function createMixdogSessionRuntime({
548
461
  const adoptSession = (v) => {
549
462
  rt.session = v;
550
463
  if (v?.id) {
464
+ rt.desktopSession = v.desktopSession || null;
465
+ // Bind every adopted session, including a cold resume and a session
466
+ // materialized before ask(). The shared tool executor must never fall
467
+ // back to changing only a detached session object's cwd.
468
+ Object.defineProperty(v, '_applyResolvedCwdForCaller', {
469
+ value: (nextCwd) => {
470
+ if (rt.session?.id !== v.id) throw new Error('cwd: the calling session is no longer active');
471
+ return applyResolvedCwd(nextCwd, { persistProjectSelection: true });
472
+ },
473
+ enumerable: false,
474
+ configurable: true,
475
+ writable: true,
476
+ });
551
477
  rt.reservedSessionId = null;
552
478
  bindRuntimeNotificationSession(v.id);
553
479
  goalRuntime?.watchSession(v.id);
@@ -581,7 +507,6 @@ export async function createMixdogSessionRuntime({
581
507
  const {
582
508
  resolveCwdPath,
583
509
  applyResolvedCwd,
584
- refreshSessionForCwdIfNeeded,
585
510
  pluginsStatus,
586
511
  loadCoreMemoryContext,
587
512
  } = createCwdPlugins({
@@ -595,7 +520,6 @@ export async function createMixdogSessionRuntime({
595
520
  isCodeGraphPrewarmLazy: () => codeGraphPrewarmLazy,
596
521
  isCodeGraphFirstTurnPrewarmDone: () => rt.codeGraphFirstTurnPrewarmDone,
597
522
  getCodeGraphPrewarmDelayMs: () => codeGraphPrewarmDelayMs,
598
- setSessionNeedsCwdRefresh: (next) => { rt.sessionNeedsCwdRefresh = next; },
599
523
  connectConfiguredMcp,
600
524
  invalidatePreSessionToolSurface: (...a) => invalidatePreSessionToolSurface(...a),
601
525
  scheduleCodeGraphPrewarm: (...a) => scheduleCodeGraphPrewarm(...a),
@@ -671,7 +595,7 @@ export async function createMixdogSessionRuntime({
671
595
  // session-pinned channel-link restore for exactly the session that owns it.
672
596
  getSessionId: () => rt.session?.id || rt.reservedSessionId || null,
673
597
  onNotify: (msg) => {
674
- if (msg?.method !== 'notifications/claude/channel') return;
598
+ if (msg?.method !== CHANNEL_NOTIFICATION_METHOD) return;
675
599
  const params = msg?.params && typeof msg.params === 'object' ? msg.params : {};
676
600
  const meta = params.meta && typeof params.meta === 'object' ? params.meta : {};
677
601
  const content = channelNotificationModelContent(params);
@@ -682,31 +606,23 @@ export async function createMixdogSessionRuntime({
682
606
  });
683
607
  bootProfile('channels:worker-ready', { ms: (performance.now() - channelsStartedAt).toFixed(1) });
684
608
  const toolsStartedAt = performance.now();
685
- const webSearchRuntimeTools = (webSearchToolDefs?.TOOL_DEFS || [])
686
- .filter((tool) => ['web_search', 'web_fetch', 'local_fetch', 'image_fetch'].includes(tool?.name));
687
- const standaloneTools = [
688
- TOOL_SEARCH_TOOL,
689
- ...(envFlag('MIXDOG_DISABLE_SKILLS') ? [] : [SKILL_TOOL]),
690
- CWD_TOOL,
691
- ...webSearchRuntimeTools.filter((tool) => tool?.public !== false),
692
- ...(memoryToolDefs?.TOOL_DEFS || []).filter((tool) => tool?.name === 'recall' || tool?.name === 'memory'),
693
- ...(channelToolDefs?.TOOL_DEFS || []).filter((tool) => channels.isChannelTool(tool?.name)),
694
- ...(codeGraphToolDefs?.CODE_GRAPH_TOOL_DEFS || []).filter((tool) => tool?.name === 'code_graph'),
695
- ...BROWSER_BRIDGE_TOOL_DEFS.filter((tool) => tool?.name === 'browser' || tool?.name === 'browser_devtools'),
696
- ...COMPUTER_BRIDGE_TOOL_DEFS.filter((tool) => tool?.name === 'computer'),
697
- ...OFFICE_TOOL_DEFS.filter((tool) => tool?.name === 'office'),
698
- ...MEDIA_TOOL_DEFS.filter((tool) => tool?.name === 'media'),
699
- ...SETUP_TOOL_DEFS,
700
- ...goalRuntime.tools,
701
- ...agentTool.tools,
702
- ];
609
+ const { standaloneTools, internalToolDefs, agentToolNames } = collectStandaloneToolDefs({
610
+ webSearchToolDefs,
611
+ memoryToolDefs,
612
+ channelToolDefs,
613
+ codeGraphToolDefs,
614
+ browserToolDefs: BROWSER_BRIDGE_TOOL_DEFS,
615
+ computerToolDefs: COMPUTER_BRIDGE_TOOL_DEFS,
616
+ officeToolDefs: OFFICE_TOOL_DEFS,
617
+ mediaToolDefs: MEDIA_TOOL_DEFS,
618
+ setupToolDefs: SETUP_TOOL_DEFS,
619
+ goalTools: goalRuntime.tools,
620
+ agentTools: agentTool.tools,
621
+ isChannelTool: (name) => channels.isChannelTool(name),
622
+ skillToolEnabled: !envFlag('MIXDOG_DISABLE_SKILLS'),
623
+ });
703
624
  bootProfile('tools:ready', { ms: (performance.now() - toolsStartedAt).toFixed(1), count: standaloneTools.length });
704
625
 
705
- // Workflow-aware model surface: a pack that declares an EMPTY agents list
706
- // (Solo) must not advertise the agent tool at all — the model calling a
707
- // schema-visible tool that policy always rejects is a guaranteed error turn
708
- // (user-reported in Solo). Names derive from the live agent tool defs.
709
- const agentToolNames = new Set(agentTool.tools.map((tool) => String(tool?.name || '')).filter(Boolean));
710
626
  // Lead tool surface (workflow-gated agent tool, pre-session preview, deferred
711
627
  // replay) lives in tool-surface.mjs.
712
628
  const {
@@ -739,20 +655,10 @@ export async function createMixdogSessionRuntime({
739
655
  getMcpScopeId: () => rt.mcpScopeId,
740
656
  getMode: () => rt.mode,
741
657
  });
742
- const computeContextStatusForSession = (session) => {
743
- if (!session || typeof session !== 'object') return null;
744
- const { contextStatus } = createContextStatus({
745
- getSession: () => session,
746
- getRoute: () => ({
747
- provider: session.provider || '',
748
- model: session.model || '',
749
- contextWindow: session.contextWindow || null,
750
- }),
751
- getCurrentCwd: () => session.cwd || rt.currentCwd,
752
- getMode: () => rt.mode,
753
- });
754
- return contextStatus();
755
- };
658
+ const computeContextStatusForSession = (session) => contextStatusForSession(session, {
659
+ getMode: () => rt.mode,
660
+ fallbackCwd: rt.currentCwd,
661
+ });
756
662
  // The setup tool drives the same facade the settings UIs use. The facade is
757
663
  // the object this factory returns, so it is handed over by reference below
758
664
  // and read lazily on each call.
@@ -764,7 +670,7 @@ export async function createMixdogSessionRuntime({
764
670
  getSessionId: () => rt.session?.id || rt.reservedSessionId || null,
765
671
  });
766
672
  internalTools.setInternalToolsProvider({
767
- tools: [...standaloneTools, ...webSearchRuntimeTools.filter((tool) => tool?.public === false)],
673
+ tools: internalToolDefs,
768
674
  executor: createInternalToolExecutor({
769
675
  rt,
770
676
  channels,
@@ -966,7 +872,7 @@ export async function createMixdogSessionRuntime({
966
872
  scheduleCodeGraphPrewarm,
967
873
  scheduleToolRuntimeWarmup,
968
874
  scheduleSearchRuntimeWarmup,
969
- invokeChannelStart,
875
+ scheduleAutomationAutostart,
970
876
  scheduleChannelStart,
971
877
  refreshRouteEffort,
972
878
  routeHasModel,
@@ -976,6 +882,7 @@ export async function createMixdogSessionRuntime({
976
882
  remoteTranscript,
977
883
  } = createSessionLifecycle({
978
884
  rt,
885
+ adoptSession,
979
886
  collectProviderModels,
980
887
  ensureProvidersReady,
981
888
  lookupModelMeta,
@@ -1035,21 +942,7 @@ export async function createMixdogSessionRuntime({
1035
942
  scheduleProviderSetupWarmup();
1036
943
  scheduleModelCatalogWarmup();
1037
944
  scheduleStatuslineUsageWarmup();
1038
- // Automation decoupling (user decision): enabled schedules/webhooks boot
1039
- // the worker on their own — no messaging provider. The worker runs
1040
- // headless (scheduler/webhooks/voice only).
1041
- prewarmTimers.channelStartTimer = setTimeout(() => {
1042
- prewarmTimers.channelStartTimer = null;
1043
- if (rt.closeRequested) return;
1044
- void hasActiveAutomation()
1045
- .then((active) => {
1046
- if (!active || rt.closeRequested) return;
1047
- bootProfile('channels:automation-autostart');
1048
- void invokeChannelStart();
1049
- })
1050
- .catch(() => { /* automation probe is best-effort */ });
1051
- }, remoteAutoStartDelayMs);
1052
- prewarmTimers.channelStartTimer.unref?.();
945
+ scheduleAutomationAutostart(remoteAutoStartDelayMs);
1053
946
 
1054
947
  // Pure settings-delegate methods (onboarding status/skip, autoClear, profile,
1055
948
  // compaction, recap/memory, channels, systemShell, update settings).
@@ -1132,7 +1025,7 @@ export async function createMixdogSessionRuntime({
1132
1025
  localProviderEnabledFn,
1133
1026
  webSearchEnabled,
1134
1027
  channelsEnabled,
1135
- autoUpdateEnabled,
1028
+ autoUpdateEnabled: selfUpdate.autoUpdateEnabled,
1136
1029
  getUpdateCheckState: () => selfUpdate.getCheckState(),
1137
1030
  getUpdateProcessState: () => selfUpdate.getProcessState(),
1138
1031
  invalidateContextStatusCache: (...a) => invalidateContextStatusCache(...a),
@@ -1146,8 +1039,8 @@ export async function createMixdogSessionRuntime({
1146
1039
  prewarmTimers.channelStartTimer = null;
1147
1040
  }
1148
1041
  },
1149
- checkForUpdateInternal: (...a) => checkForUpdateInternal(...a),
1150
- runUpdateNowInternal: (...a) => runUpdateNowInternal(...a),
1042
+ checkForUpdateInternal: selfUpdate.checkForUpdate,
1043
+ runUpdateNowInternal: selfUpdate.runUpdateNow,
1151
1044
  reloadChannelsSoon: (...a) => reloadChannelsSoon(...a),
1152
1045
  ONBOARDING_VERSION,
1153
1046
  });
@@ -1203,7 +1096,6 @@ export async function createMixdogSessionRuntime({
1203
1096
  setCloseRequested: (v) => { rt.closeRequested = v; },
1204
1097
  getMemoryModPromise: () => rt.memoryModPromise,
1205
1098
  setMemoryModPromise: (v) => { rt.memoryModPromise = v; },
1206
- setSessionNeedsCwdRefresh: (v) => { rt.sessionNeedsCwdRefresh = v; },
1207
1099
  getReservedSessionId: () => rt.reservedSessionId,
1208
1100
  abortActiveTurns,
1209
1101
  hooks,
@@ -1344,7 +1236,6 @@ export async function createMixdogSessionRuntime({
1344
1236
  scheduleCodeGraphPrewarm,
1345
1237
  scheduleToolRuntimeWarmup,
1346
1238
  scheduleSearchRuntimeWarmup,
1347
- refreshSessionForCwdIfNeeded,
1348
1239
  createCurrentSession,
1349
1240
  ensureSessionTranscriptWriter,
1350
1241
  channels,
@@ -1426,12 +1317,7 @@ export async function createMixdogSessionRuntime({
1426
1317
  getAutoClear: () => settingsApi.getAutoClear(),
1427
1318
  getSystemShell: () => normalizeSystemShellConfig(rt.config.shell),
1428
1319
  getWebSearchRoute: () => {
1429
- rt.webSearchRoute = normalizeWebSearchRouteConfig(rt.config.webSearchRoute)
1430
- || normalizeWebSearchRouteConfig(rt.webSearchRoute)
1431
- || normalizeWebSearchRouteConfig({
1432
- provider: WEB_SEARCH_DEFAULT_PROVIDER,
1433
- model: WEB_SEARCH_DEFAULT_MODEL,
1434
- });
1320
+ rt.webSearchRoute = webSearchRouteOrDefault(rt.config.webSearchRoute, rt.webSearchRoute);
1435
1321
  return rt.webSearchRoute;
1436
1322
  },
1437
1323
  getWorkflow: () => {
@@ -0,0 +1,37 @@
1
+ // Model-facing feature activation for one session runtime. Every gate reads the
2
+ // LIVE config (a settings toggle must take effect without rebuilding the tool
3
+ // surface), so the factory takes getters rather than values.
4
+ //
5
+ // Key names mirror the dependency names of settings-api.mjs / the session-build
6
+ // deps, so the runtime can hand them straight through.
7
+ import {
8
+ builtinFeatureActive,
9
+ featureDisallowedToolsFor,
10
+ localGitToolsActive,
11
+ } from './builtin-features.mjs';
12
+ import { moduleEnabled, recapEnabled } from './config-helpers.mjs';
13
+ import { browserBridgeAvailableSync } from '../runtime/browser-bridge/client.mjs';
14
+ import { computerBridgeAvailableSync } from '../runtime/computer-bridge/client.mjs';
15
+
16
+ export function createRuntimeFeatureGates({ getConfig, getToolProfile }) {
17
+ return {
18
+ // Memory ingest is always-on. `recap` gates only the background cycles;
19
+ // `memoryTools` gates the model-facing memory/recall tool surface. Headless
20
+ // runs override any toggle per process via MIXDOG_FEATURE_* env values.
21
+ recapEnabledFn: () => recapEnabled(getConfig(), true),
22
+ memoryToolsEnabledFn: () => builtinFeatureActive(getConfig(), 'memory'),
23
+ webSearchEnabled: () => builtinFeatureActive(getConfig(), 'webSearch'),
24
+ gitToolsEnabledFn: () => localGitToolsActive(getConfig(), getToolProfile()),
25
+ officeToolsEnabledFn: () => builtinFeatureActive(getConfig(), 'office'),
26
+ localProviderEnabledFn: () => builtinFeatureActive(getConfig(), 'localProvider'),
27
+ mediaToolEnabledFn: () => builtinFeatureActive(getConfig(), 'media'),
28
+ channelsEnabled: () => moduleEnabled(getConfig(), 'channels', true),
29
+ // Browser/Computer activate on live desktop-bridge presence, so the probe
30
+ // runs per call instead of being captured at boot.
31
+ featureDisallowedTools: () => featureDisallowedToolsFor(getConfig(), {
32
+ browserAvailable: browserBridgeAvailableSync(),
33
+ computerAvailable: computerBridgeAvailableSync(),
34
+ toolProfile: getToolProfile(),
35
+ }),
36
+ };
37
+ }
@@ -96,6 +96,7 @@ export function resolveRouteContextState(
96
96
 
97
97
  export function createSessionLifecycle({
98
98
  rt,
99
+ adoptSession,
99
100
  collectProviderModels,
100
101
  ensureProvidersReady,
101
102
  lookupModelMeta,
@@ -227,7 +228,7 @@ export function createSessionLifecycle({
227
228
  if (rt.sessionCreatePromise) {
228
229
  return await runAbortable(signal, () => rt.sessionCreatePromise, 'Session creation aborted');
229
230
  }
230
- if (rt.session?.id && !rt.sessionNeedsCwdRefresh) {
231
+ if (rt.session?.id) {
231
232
  const liveSession = mgr.getSession(rt.session.id);
232
233
  if (liveSession && liveSession.closed !== true && liveSession.status !== 'closed') {
233
234
  rt.session = liveSession;
@@ -332,9 +333,8 @@ export function createSessionLifecycle({
332
333
  if (hasOwn(rt.route, 'effort') || rt.route.effectiveEffort) {
333
334
  sessionOpts.effort = rt.route.effectiveEffort || null;
334
335
  }
335
- rt.session = mgr.createSession(sessionOpts);
336
+ adoptSession(mgr.createSession(sessionOpts));
336
337
  rt.reservedSessionId = null;
337
- rt.sessionNeedsCwdRefresh = false;
338
338
  attachSessionHooks(rt.session, { hooks, hookCommonPayload, getCwd: () => rt.currentCwd });
339
339
  // Every-create MCP fold (NO blocking): seed the INITIAL provider-visible
340
340
  // surface (and native BP2 manifest) from MCP servers connected at create
@@ -471,8 +471,8 @@ export function createSessionLifecycle({
471
471
  scheduleCodeGraphPrewarm,
472
472
  scheduleToolRuntimeWarmup,
473
473
  scheduleSearchRuntimeWarmup,
474
- invokeChannelStart,
475
474
  scheduleChannelStart,
475
+ scheduleAutomationAutostart,
476
476
  } = createPrewarmSchedulers({
477
477
  timers: prewarmTimers,
478
478
  bootProfile,
@@ -515,8 +515,8 @@ export function createSessionLifecycle({
515
515
  scheduleCodeGraphPrewarm,
516
516
  scheduleToolRuntimeWarmup,
517
517
  scheduleSearchRuntimeWarmup,
518
- invokeChannelStart,
519
518
  scheduleChannelStart,
519
+ scheduleAutomationAutostart,
520
520
  refreshRouteEffort,
521
521
  routeHasModel,
522
522
  requireModelRoute,
@@ -47,7 +47,7 @@ export function createSessionTurnApi(deps) {
47
47
  getCodeGraphFirstTurnPrewarmDone, setCodeGraphFirstTurnPrewarmDone,
48
48
  getCloseRequested,
49
49
  getTranscriptWriter, getLastAppendedAssistant, setLastAppendedAssistant,
50
- scheduleCodeGraphPrewarm, scheduleToolRuntimeWarmup, scheduleSearchRuntimeWarmup, refreshSessionForCwdIfNeeded, createCurrentSession,
50
+ scheduleCodeGraphPrewarm, scheduleToolRuntimeWarmup, scheduleSearchRuntimeWarmup, createCurrentSession,
51
51
  ensureSessionTranscriptWriter, channels,
52
52
  hooks, hookCommonPayload, mgr, notifyFnForSession, subscribeRuntimeNotification, bootProfile,
53
53
  scheduleProviderWarmup, scheduleProviderModelWarmup, invalidateContextStatusCache,
@@ -206,7 +206,6 @@ export function createSessionTurnApi(deps) {
206
206
  try {
207
207
  await awaitTurn(() => awaitRoutePreparation?.());
208
208
  routeWaitMs = performance.now() - routeStartedAt;
209
- await awaitTurn(() => refreshSessionForCwdIfNeeded('cwd-change'));
210
209
  if (!getSession()?.id) {
211
210
  await awaitTurn(() => createCurrentSession('turn', { signal: turnSignal }));
212
211
  }
@@ -220,16 +219,6 @@ export function createSessionTurnApi(deps) {
220
219
  catch (error) { process.stderr.write(`mixdog: transcript-writer: appendUser failed: ${error?.message || error}\n`); }
221
220
  }
222
221
  session0 = getSession();
223
- // Internal tools are process-global, while each live session owns its
224
- // own Project. Give tool dispatch an owning-runtime callback so `cwd`
225
- // can update the caller instead of whichever runtime registered the
226
- // shared internal-tool executor most recently.
227
- Object.defineProperty(session0, '_applyResolvedCwdForCaller', {
228
- value: (nextCwd) => applyResolvedCwd(nextCwd, { persistProjectSelection: true }),
229
- enumerable: false,
230
- configurable: true,
231
- writable: true,
232
- });
233
222
  startTurnSnapshot(session0?.id);
234
223
  const firstTitleAfter = new Promise((resolve) => {
235
224
  releaseFirstTitle = () => {