@sayknow-cli/coding-agent 0.3.15 → 0.4.0

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 (1474) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/package.json +133 -116
  3. package/scripts/build-sdk-package-smoke.ts +132 -0
  4. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  5. package/scripts/compile-args.ts +5 -2
  6. package/scripts/g005-daemon-smoke.ts +4 -5
  7. package/scripts/g011-daemon-path-smoke.ts +5 -5
  8. package/scripts/generate-hotkeys-docs.ts +74 -0
  9. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  10. package/scripts/generate-sdk-operation-inventory.ts +914 -0
  11. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  12. package/scripts/manifest-schema.ts +124 -0
  13. package/scripts/run-test-manifest.ts +153 -0
  14. package/scripts/run-threat-model-check.ts +217 -0
  15. package/scripts/verify-skc-sdk-canonicalization.ts +3647 -0
  16. package/scripts/verify-skc-sdk-rename.ts +90 -0
  17. package/src/append-only-mode.ts +1 -1
  18. package/src/async/job-manager.ts +455 -69
  19. package/src/cli/args.ts +43 -12
  20. package/src/cli/auth-gateway-cli.ts +2 -2
  21. package/src/cli/config-cli.ts +77 -3
  22. package/src/cli/daemon-cli.ts +63 -14
  23. package/src/cli/launch-disposition.ts +42 -0
  24. package/src/cli/list-models.ts +1 -1
  25. package/src/cli/notify-cli.ts +373 -283
  26. package/src/cli/session-picker.ts +20 -3
  27. package/src/cli/setup-cli.ts +1 -1
  28. package/src/cli/worktree-cli.ts +9 -287
  29. package/src/cli.ts +31 -11
  30. package/src/commands/config.ts +1 -1
  31. package/src/commands/daemon.ts +50 -6
  32. package/src/commands/gc.ts +11 -1
  33. package/src/commands/harness.ts +127 -142
  34. package/src/commands/launch.ts +11 -6
  35. package/src/commands/mcp-serve.ts +97 -13
  36. package/src/commands/mcp.ts +2 -2
  37. package/src/commands/notify.ts +44 -7
  38. package/src/commands/sdk.ts +453 -0
  39. package/src/commands/ultragoal.ts +4 -1
  40. package/src/commands/worktree.ts +10 -53
  41. package/src/commit/agentic/agent.ts +1 -0
  42. package/src/config/atomic-yaml-patch.ts +490 -0
  43. package/src/config/file-lock.ts +105 -43
  44. package/src/config/keybindings.ts +64 -20
  45. package/src/config/model-auth.ts +9 -0
  46. package/src/config/model-bindings-applier.ts +139 -0
  47. package/src/config/model-discovery-manager.ts +224 -0
  48. package/src/config/model-equivalence.ts +66 -0
  49. package/src/config/model-profile-activation.ts +233 -86
  50. package/src/config/model-profiles.ts +52 -49
  51. package/src/config/model-registry.ts +5 -4
  52. package/src/config/model-resolver.ts +487 -410
  53. package/src/config/model-selector-value.ts +50 -0
  54. package/src/config/models-config-schema.ts +17 -23
  55. package/src/config/settings-schema.ts +372 -21
  56. package/src/config/settings.ts +1120 -182
  57. package/src/coordinator-mcp/model-preset.ts +74 -20
  58. package/src/coordinator-mcp/policy.ts +76 -11
  59. package/src/coordinator-mcp/question-gate-codec.ts +274 -0
  60. package/src/coordinator-mcp/question-state.ts +778 -0
  61. package/src/coordinator-mcp/server.ts +3120 -3111
  62. package/src/daemon/builtin.ts +8 -5
  63. package/src/daemon/control-types.ts +1 -1
  64. package/src/daemon/runtime.ts +2 -2
  65. package/src/debug/index.ts +1 -1
  66. package/src/defaults/skc/skills/team/SKILL.md +27 -13
  67. package/src/defaults/skc/skills/ultragoal/SKILL.md +0 -2
  68. package/src/discovery/helpers.ts +1 -50
  69. package/src/discovery/mcp-json.ts +327 -20
  70. package/src/edit/index.ts +64 -0
  71. package/src/eval/js/shared/runtime.ts +1 -1
  72. package/src/eval/py/env.ts +26 -0
  73. package/src/eval/py/index.ts +2 -2
  74. package/src/eval/py/kernel.ts +5 -3
  75. package/src/export/html/template.generated.ts +1 -1
  76. package/src/export/html/template.js +52 -18
  77. package/src/extensibility/custom-tools/types.ts +1 -1
  78. package/src/extensibility/extensions/compact-handler.ts +3 -3
  79. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  80. package/src/extensibility/extensions/loader.ts +77 -5
  81. package/src/extensibility/extensions/runner.ts +124 -7
  82. package/src/extensibility/extensions/types.ts +215 -18
  83. package/src/extensibility/hooks/runner.ts +2 -2
  84. package/src/extensibility/hooks/types.ts +1 -1
  85. package/src/extensibility/plugins/marketplace/manager.ts +94 -10
  86. package/src/extensibility/runtime-skill-discovery.ts +33 -13
  87. package/src/extensibility/shared-events.ts +2 -0
  88. package/src/extensibility/skc-plugins/installer.ts +16 -16
  89. package/src/extensibility/slash-commands.ts +3 -3
  90. package/src/goals/continuation-timeout-guard.ts +79 -0
  91. package/src/goals/runtime.ts +7 -5
  92. package/src/goals/state.ts +18 -0
  93. package/src/harness-control-plane/lifecycle-reconciliation.ts +64 -0
  94. package/src/harness-control-plane/operate.ts +9 -9
  95. package/src/harness-control-plane/owner.ts +341 -41
  96. package/src/harness-control-plane/phase-rollup.ts +4 -7
  97. package/src/harness-control-plane/receipt-ingest.ts +5 -0
  98. package/src/harness-control-plane/receipt-spool.ts +51 -7
  99. package/src/harness-control-plane/receipts.ts +0 -1
  100. package/src/harness-control-plane/sdk-transport.ts +395 -0
  101. package/src/harness-control-plane/session-lease.ts +12 -130
  102. package/src/harness-control-plane/session-transport.ts +94 -0
  103. package/src/harness-control-plane/types.ts +1 -1
  104. package/src/hindsight/backend.ts +26 -27
  105. package/src/hindsight/client.ts +65 -2
  106. package/src/hindsight/state.ts +101 -32
  107. package/src/hooks/skill-state.ts +17 -11
  108. package/src/i18n/messages/en.ts +1 -0
  109. package/src/internal-urls/agent-protocol.ts +76 -5
  110. package/src/internal-urls/docs-index.generated.ts +44 -37
  111. package/src/internal-urls/local-protocol.ts +420 -18
  112. package/src/lsp/client.ts +43 -7
  113. package/src/lsp/config.ts +145 -26
  114. package/src/lsp/index.ts +7 -91
  115. package/src/lsp/lspmux.ts +39 -10
  116. package/src/lsp/path-trust.ts +81 -0
  117. package/src/main.ts +451 -236
  118. package/src/memories/index.ts +1 -0
  119. package/src/memories/storage.ts +6 -2
  120. package/src/modes/DESIGN.md +258 -0
  121. package/src/modes/acp/acp-agent.ts +1236 -2612
  122. package/src/modes/acp/acp-client-bridge.ts +2 -20
  123. package/src/modes/acp/acp-event-mapper.ts +18 -2
  124. package/src/modes/acp/acp-mode.ts +8 -36
  125. package/src/modes/acp/permission-mode.ts +25 -0
  126. package/src/modes/acp/startup-options.ts +6 -0
  127. package/src/modes/action-registry.ts +165 -0
  128. package/src/modes/bridge/bridge-mode.ts +6 -4
  129. package/src/modes/components/agent-dashboard.ts +37 -17
  130. package/src/modes/components/ansi-display-validator.ts +54 -0
  131. package/src/modes/components/chrome.ts +40 -0
  132. package/src/modes/components/command-palette.ts +168 -0
  133. package/src/modes/components/custom-editor.ts +105 -33
  134. package/src/modes/components/custom-provider-wizard.ts +77 -15
  135. package/src/modes/components/index.ts +2 -1
  136. package/src/modes/components/model-selector.ts +93 -35
  137. package/src/modes/components/notifications-settings-editor.ts +1403 -0
  138. package/src/modes/components/pet-capability.ts +115 -0
  139. package/src/modes/components/pet-selector.ts +15 -23
  140. package/src/modes/components/plan-preview-overlay.ts +295 -0
  141. package/src/modes/components/queue-mode-selector.ts +10 -27
  142. package/src/modes/components/queue-pane.ts +79 -0
  143. package/src/modes/components/read-tool-group.ts +13 -0
  144. package/src/modes/components/sayknow-pet-widget.ts +169 -20
  145. package/src/modes/components/session-observer-overlay.ts +213 -775
  146. package/src/modes/components/sessions-dashboard.ts +181 -0
  147. package/src/modes/components/settings-selector.ts +89 -12
  148. package/src/modes/components/show-images-selector.ts +10 -24
  149. package/src/modes/components/status-line/types.ts +1 -1
  150. package/src/modes/components/status-line.ts +1 -969
  151. package/src/modes/components/tasks-pane.ts +73 -0
  152. package/src/modes/components/theme-selector.ts +11 -31
  153. package/src/modes/components/tool-execution.ts +22 -0
  154. package/src/modes/components/tool-status-header.ts +1056 -0
  155. package/src/modes/components/tool-transcript-format.ts +393 -0
  156. package/src/modes/components/transcript-viewer-overlay.ts +446 -0
  157. package/src/modes/components/welcome.ts +4 -4
  158. package/src/modes/controllers/btw-controller.ts +1 -0
  159. package/src/modes/controllers/command-controller.ts +25 -17
  160. package/src/modes/controllers/event-controller.ts +14 -18
  161. package/src/modes/controllers/extension-ui-controller.ts +441 -37
  162. package/src/modes/controllers/goal-mode-controller.ts +493 -0
  163. package/src/modes/controllers/input-controller.ts +889 -263
  164. package/src/modes/controllers/mode-gate.ts +24 -0
  165. package/src/modes/controllers/plan-mode-controller.ts +519 -0
  166. package/src/modes/controllers/runtime-mcp-command-controller.ts +3 -0
  167. package/src/modes/controllers/selector-controller.ts +957 -54
  168. package/src/modes/controllers/stt-controller.ts +125 -0
  169. package/src/modes/index.ts +0 -22
  170. package/src/modes/interactive-mode.ts +376 -1130
  171. package/src/modes/jobs-observer.ts +3 -0
  172. package/src/modes/prompt-action-autocomplete.ts +7 -0
  173. package/src/modes/rpc/rpc-mode.ts +3 -1
  174. package/src/modes/runtime-init.ts +320 -6
  175. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  176. package/src/modes/shared/agent-wire/command-dispatch.ts +3 -1
  177. package/src/modes/shared/agent-wire/deep-interview-gate.ts +65 -111
  178. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  179. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  180. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  181. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1331 -89
  182. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +19 -17
  183. package/src/modes/shared/agent-wire/workflow-gate-types.ts +407 -0
  184. package/src/modes/tasks-aggregator.ts +199 -0
  185. package/src/modes/transcript-item-registry.ts +229 -0
  186. package/src/modes/types.ts +63 -21
  187. package/src/modes/utils/ui-helpers.ts +17 -9
  188. package/src/notifications/index.ts +8 -2
  189. package/src/plan-mode/approved-plan.ts +3 -1
  190. package/src/prompts/agent-fragments/ralplan-persistence.md +6 -0
  191. package/src/prompts/agent-fragments/restricted-bash.md +1 -0
  192. package/src/prompts/agents/architect.md +3 -8
  193. package/src/prompts/agents/critic.md +3 -8
  194. package/src/prompts/agents/executor.md +3 -0
  195. package/src/prompts/agents/planner.md +4 -12
  196. package/src/prompts/system/custom-system-prompt.md +2 -24
  197. package/src/prompts/system/plan-mode-approved.md +8 -0
  198. package/src/prompts/system/system-prompt.md +18 -94
  199. package/src/prompts/tools/bash.md +4 -4
  200. package/src/prompts/tools/browser.md +15 -52
  201. package/src/prompts/tools/find.md +2 -2
  202. package/src/prompts/tools/hashline.md +13 -55
  203. package/src/prompts/tools/lsp.md +3 -3
  204. package/src/prompts/tools/read.md +3 -6
  205. package/src/prompts/tools/search-tool-bm25.md +0 -2
  206. package/src/prompts/tools/search.md +2 -4
  207. package/src/prompts/tools/skill-discovery.md +1 -2
  208. package/src/prompts/tools/task.md +1 -1
  209. package/src/runtime-mcp/client.ts +94 -19
  210. package/src/runtime-mcp/config.ts +27 -15
  211. package/src/runtime-mcp/discoverable-tool-metadata.ts +16 -13
  212. package/src/runtime-mcp/manager.ts +359 -106
  213. package/src/runtime-mcp/oauth-discovery.ts +116 -26
  214. package/src/runtime-mcp/oauth-flow.ts +42 -12
  215. package/src/runtime-mcp/transports/http.ts +49 -19
  216. package/src/runtime-mcp/transports/stdio.ts +47 -28
  217. package/src/runtime-mcp/types.ts +10 -0
  218. package/src/sdk/acp/adapter.ts +418 -0
  219. package/src/sdk/acp/index.ts +2 -0
  220. package/src/sdk/broker/broker.ts +877 -0
  221. package/src/sdk/broker/discovery.ts +238 -0
  222. package/src/sdk/broker/ensure.ts +393 -0
  223. package/src/sdk/broker/identity.ts +42 -0
  224. package/src/sdk/broker/index.ts +8 -0
  225. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  226. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  227. package/src/sdk/broker/internal.ts +10 -0
  228. package/src/sdk/broker/lifecycle-codec.ts +11 -0
  229. package/src/sdk/broker/lifecycle-ledger.ts +583 -0
  230. package/src/sdk/broker/lifecycle.ts +3413 -0
  231. package/src/sdk/broker/process-incarnation.ts +151 -0
  232. package/src/sdk/broker/runtime.ts +164 -0
  233. package/src/sdk/broker/session-index.ts +678 -0
  234. package/src/sdk/broker/state-version.ts +47 -0
  235. package/src/sdk/broker/transport.ts +125 -0
  236. package/src/sdk/bus/attachment-registry.ts +23 -0
  237. package/src/sdk/bus/chat-adapters.ts +147 -0
  238. package/src/sdk/bus/chat-command-policy.ts +107 -0
  239. package/src/sdk/bus/chat-daemon-cli.ts +278 -0
  240. package/src/sdk/bus/chat-daemon-control.ts +1101 -0
  241. package/src/sdk/bus/chat-daemon-runtime.ts +527 -0
  242. package/src/sdk/bus/chat-effect-journal.ts +363 -0
  243. package/src/sdk/bus/config-commands.ts +192 -0
  244. package/src/sdk/bus/config.ts +568 -0
  245. package/src/sdk/bus/conversation-store.ts +367 -0
  246. package/src/sdk/bus/daemon-paths.ts +34 -0
  247. package/src/sdk/bus/discord-conversation.ts +85 -0
  248. package/src/sdk/bus/discord-daemon.ts +2292 -0
  249. package/src/sdk/bus/discord-live-provider.ts +521 -0
  250. package/src/sdk/bus/discord-provider.ts +56 -0
  251. package/src/sdk/bus/engine.ts +100 -0
  252. package/src/sdk/bus/helpers.ts +135 -0
  253. package/src/sdk/bus/html-format.ts +518 -0
  254. package/src/sdk/bus/index.ts +4961 -0
  255. package/src/sdk/bus/lifecycle-commands.ts +291 -0
  256. package/src/sdk/bus/lifecycle-control-runtime.ts +1409 -0
  257. package/src/sdk/bus/lifecycle-orchestrator.ts +458 -0
  258. package/src/sdk/bus/managed-daemon.ts +163 -0
  259. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  260. package/src/sdk/bus/natives-augment.d.ts +63 -0
  261. package/src/sdk/bus/notification-orchestration.ts +535 -0
  262. package/src/sdk/bus/notification-service.ts +1174 -0
  263. package/src/sdk/bus/operator-runtime.ts +171 -0
  264. package/src/sdk/bus/rate-limit-pool.ts +276 -0
  265. package/src/sdk/bus/recent-activity.ts +279 -0
  266. package/src/sdk/bus/reply-sent-store.ts +134 -0
  267. package/src/sdk/bus/rich-document.ts +258 -0
  268. package/src/sdk/bus/rich-draft.ts +107 -0
  269. package/src/sdk/bus/rich-render.ts +135 -0
  270. package/src/sdk/bus/session-control.ts +439 -0
  271. package/src/sdk/bus/slack-conversation.ts +74 -0
  272. package/src/sdk/bus/slack-daemon.ts +2144 -0
  273. package/src/sdk/bus/slack-live-provider.ts +380 -0
  274. package/src/sdk/bus/slack-provider.ts +76 -0
  275. package/src/sdk/bus/telegram-cli.ts +194 -0
  276. package/src/sdk/bus/telegram-daemon-cli.ts +292 -0
  277. package/src/sdk/bus/telegram-daemon-contract.ts +27 -0
  278. package/src/sdk/bus/telegram-daemon-control.ts +642 -0
  279. package/src/sdk/bus/telegram-daemon.ts +6675 -0
  280. package/src/sdk/bus/telegram-reference.ts +436 -0
  281. package/src/sdk/bus/telegram-setup.ts +663 -0
  282. package/src/sdk/bus/threaded-inbound.ts +141 -0
  283. package/src/sdk/bus/threaded-render.ts +294 -0
  284. package/src/sdk/bus/topic-registry.ts +364 -0
  285. package/src/sdk/cli/index.ts +1 -0
  286. package/src/sdk/cli/session-cli.ts +275 -0
  287. package/src/sdk/client/client.ts +1 -0
  288. package/src/sdk/client/discovery.ts +108 -0
  289. package/src/sdk/client/index.ts +2 -0
  290. package/src/sdk/host/control/dispatch.ts +388 -0
  291. package/src/sdk/host/control/index.ts +10 -0
  292. package/src/sdk/host/control/operations.ts +68 -0
  293. package/src/sdk/host/events.ts +91 -0
  294. package/src/sdk/host/host.ts +338 -0
  295. package/src/sdk/host/index.ts +4 -0
  296. package/src/sdk/host/query/cursor.ts +189 -0
  297. package/src/sdk/host/query/handlers.ts +531 -0
  298. package/src/sdk/host/query/index.ts +3 -0
  299. package/src/sdk/host/query/revision-store.ts +1149 -0
  300. package/src/sdk/host/reverse-leases.ts +325 -0
  301. package/src/sdk/host/types.ts +29 -0
  302. package/src/sdk/index.ts +14 -0
  303. package/src/sdk/lifecycle-session.ts +39 -0
  304. package/src/sdk/mcp/index.ts +1 -0
  305. package/src/sdk/mcp/server.ts +332 -0
  306. package/src/sdk/models.ts +168 -0
  307. package/src/sdk/protocol/adapter-validation.ts +48 -0
  308. package/src/sdk/protocol/operation-inventory.generated.json +4719 -0
  309. package/src/sdk/protocol/operation-registry.ts +312 -0
  310. package/src/sdk/session-directory.ts +141 -0
  311. package/src/sdk/session.ts +2869 -0
  312. package/src/sdk/startup-capability.ts +189 -0
  313. package/src/secrets/index.ts +53 -10
  314. package/src/secrets/obfuscator.ts +21 -18
  315. package/src/secrets/regex.ts +2 -0
  316. package/src/session/agent-session.ts +5602 -2138
  317. package/src/session/agent-storage.ts +18 -0
  318. package/src/session/artifacts.ts +188 -23
  319. package/src/session/cache-economics.ts +25 -8
  320. package/src/session/context-estimation.ts +7 -2
  321. package/src/session/default-model-selection.ts +93 -0
  322. package/src/session/fallback-chain-controller.ts +186 -0
  323. package/src/session/internal/managed-session-scope.ts +2402 -0
  324. package/src/session/internal/managed-session-storage.ts +1559 -0
  325. package/src/session/messages.ts +91 -2
  326. package/src/session/session-manager-internal.ts +33 -0
  327. package/src/session/session-manager.ts +2578 -392
  328. package/src/session/session-storage.ts +550 -40
  329. package/src/session/streaming-output.ts +6 -0
  330. package/src/session/volatile-context-pruning.ts +78 -0
  331. package/src/session/yield-queue.ts +20 -0
  332. package/src/setup/credential-auto-import.ts +291 -35
  333. package/src/setup/hermes/templates/operator-instructions.v1.md +4 -6
  334. package/src/setup/provider-onboarding.ts +36 -61
  335. package/src/setup/provider-presets.json +5 -0
  336. package/src/skc-runtime/deep-interview-recorder.ts +70 -3
  337. package/src/skc-runtime/deep-interview-state.ts +441 -5
  338. package/src/skc-runtime/gc-render.ts +19 -1
  339. package/src/skc-runtime/gc-runtime.ts +68 -3
  340. package/src/skc-runtime/goal-mode-request.ts +55 -8
  341. package/src/skc-runtime/launch-worktree.ts +5 -5
  342. package/src/skc-runtime/linux-proc.ts +71 -0
  343. package/src/skc-runtime/managed-owner-admission.ts +352 -0
  344. package/src/skc-runtime/managed-owner-supervisor.ts +162 -0
  345. package/src/skc-runtime/psmux-detect.ts +82 -4
  346. package/src/skc-runtime/ralplan-runtime.ts +74 -90
  347. package/src/skc-runtime/session-resolution.ts +18 -3
  348. package/src/skc-runtime/session-state-sidecar.ts +47 -138
  349. package/src/skc-runtime/state-argv.ts +292 -0
  350. package/src/skc-runtime/state-migrations.ts +1 -1
  351. package/src/skc-runtime/state-runtime.ts +387 -451
  352. package/src/skc-runtime/state-writer.ts +36 -40
  353. package/src/skc-runtime/team-launch.ts +319 -0
  354. package/src/skc-runtime/team-notify.ts +326 -0
  355. package/src/skc-runtime/team-runtime.ts +8 -2
  356. package/src/skc-runtime/team-store.ts +828 -0
  357. package/src/skc-runtime/team-workers.ts +962 -0
  358. package/src/skc-runtime/tmux-owner-isolation-cli.ts +55 -28
  359. package/src/skc-runtime/tmux-owner-isolation.ts +136 -11
  360. package/src/skc-runtime/tmux-sessions.ts +23 -34
  361. package/src/skc-runtime/ultragoal-change-set.ts +172 -0
  362. package/src/skc-runtime/ultragoal-evidence.ts +874 -0
  363. package/src/skc-runtime/ultragoal-guard.ts +136 -18
  364. package/src/skc-runtime/ultragoal-owner-loss-recovery.ts +328 -0
  365. package/src/skc-runtime/ultragoal-pipeline.ts +306 -0
  366. package/src/skc-runtime/ultragoal-receipt-freshness.ts +102 -1
  367. package/src/skc-runtime/ultragoal-runtime.ts +325 -1322
  368. package/src/skc-runtime/windows-powershell-command.ts +58 -0
  369. package/src/skc-runtime/workflow-cli-common.ts +30 -0
  370. package/src/skc-runtime/workflow-manifest.generated.json +58 -0
  371. package/src/skc-runtime/workflow-manifest.ts +18 -0
  372. package/src/skill-state/active-state.ts +3 -13
  373. package/src/skill-state/workflow-mutation-guard.ts +661 -0
  374. package/src/skill-state/workflow-state-contract.ts +6 -41
  375. package/src/slash-commands/builtin-registry.ts +115 -41
  376. package/src/system-prompt.ts +37 -44
  377. package/src/task/agents.ts +19 -1
  378. package/src/task/executor.ts +223 -45
  379. package/src/task/index.ts +124 -56
  380. package/src/thinking.ts +21 -6
  381. package/src/tool-discovery/tool-index.ts +20 -134
  382. package/src/tools/ask-answer-registry.ts +16 -2
  383. package/src/tools/ast-edit.ts +1 -1
  384. package/src/tools/bash-allowed-prefixes.ts +79 -29
  385. package/src/tools/bash-skill-urls.ts +14 -3
  386. package/src/tools/bash.ts +40 -2
  387. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  388. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  389. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  390. package/src/tools/browser/dead-tab-recovery.ts +78 -0
  391. package/src/tools/browser/launch.ts +127 -20
  392. package/src/tools/browser/profile-discovery.ts +63 -0
  393. package/src/tools/browser/profile-posture.ts +59 -0
  394. package/src/tools/browser/profile-reuse.ts +102 -0
  395. package/src/tools/browser/profile-warmup.ts +109 -0
  396. package/src/tools/browser/readable.ts +1 -1
  397. package/src/tools/browser/registry.ts +87 -11
  398. package/src/tools/browser/screenshot-format.ts +34 -0
  399. package/src/tools/browser/tab-protocol.ts +4 -0
  400. package/src/tools/browser/tab-supervisor.ts +392 -142
  401. package/src/tools/browser/tab-worker-entry.ts +33 -14
  402. package/src/tools/browser/tab-worker-path-resolver.ts +67 -0
  403. package/src/tools/browser/tab-worker-smoke.ts +87 -0
  404. package/src/tools/browser/tab-worker.ts +8 -6
  405. package/src/tools/browser.ts +6 -0
  406. package/src/tools/computer.ts +10 -3
  407. package/src/tools/cron.ts +30 -16
  408. package/src/tools/fetch.ts +11 -4
  409. package/src/tools/index.ts +88 -32
  410. package/src/tools/output-meta.ts +19 -7
  411. package/src/tools/path-utils.ts +42 -35
  412. package/src/tools/plan-mode-guard.ts +1 -0
  413. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  414. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  415. package/src/tools/read.ts +226 -65
  416. package/src/tools/resource-gc.ts +125 -36
  417. package/src/tools/search-tool-bm25.ts +11 -74
  418. package/src/tools/sqlite-reader.ts +3 -2
  419. package/src/tools/subagent-render.ts +19 -8
  420. package/src/tools/subagent.ts +129 -34
  421. package/src/tools/telegram-send.ts +2 -2
  422. package/src/utils/event-bus.ts +9 -4
  423. package/src/utils/file-mentions.ts +4 -4
  424. package/src/utils/image-loading.ts +85 -34
  425. package/src/utils/image-resize.ts +16 -9
  426. package/src/utils/pasted-image-loading.ts +514 -0
  427. package/src/utils/pasted-image-path.ts +223 -98
  428. package/src/web/scrapers/html-to-markdown.ts +68 -0
  429. package/src/web/scrapers/readthedocs.ts +1 -1
  430. package/src/web/scrapers/types.ts +1 -68
  431. package/src/web/search/index.ts +3 -3
  432. package/src/web/search/providers/openai-compatible.ts +76 -23
  433. package/dist/types/append-only-mode.d.ts +0 -31
  434. package/dist/types/async/index.d.ts +0 -2
  435. package/dist/types/async/job-manager.d.ts +0 -328
  436. package/dist/types/async/support.d.ts +0 -2
  437. package/dist/types/autoresearch/dashboard.d.ts +0 -4
  438. package/dist/types/autoresearch/git.d.ts +0 -36
  439. package/dist/types/autoresearch/helpers.d.ts +0 -24
  440. package/dist/types/autoresearch/index.d.ts +0 -2
  441. package/dist/types/autoresearch/state.d.ts +0 -17
  442. package/dist/types/autoresearch/storage.d.ts +0 -142
  443. package/dist/types/autoresearch/tools/init-experiment.d.ts +0 -31
  444. package/dist/types/autoresearch/tools/log-experiment.d.ts +0 -23
  445. package/dist/types/autoresearch/tools/run-experiment.d.ts +0 -8
  446. package/dist/types/autoresearch/tools/update-notes.d.ts +0 -12
  447. package/dist/types/autoresearch/types.d.ts +0 -154
  448. package/dist/types/build-metadata.d.ts +0 -7
  449. package/dist/types/capability/context-file.d.ts +0 -17
  450. package/dist/types/capability/extension-module.d.ts +0 -15
  451. package/dist/types/capability/extension.d.ts +0 -28
  452. package/dist/types/capability/fs.d.ts +0 -20
  453. package/dist/types/capability/hook.d.ts +0 -19
  454. package/dist/types/capability/index.d.ts +0 -80
  455. package/dist/types/capability/instruction.d.ts +0 -17
  456. package/dist/types/capability/mcp.d.ts +0 -49
  457. package/dist/types/capability/prompt.d.ts +0 -15
  458. package/dist/types/capability/rule.d.ts +0 -69
  459. package/dist/types/capability/settings.d.ts +0 -15
  460. package/dist/types/capability/skill.d.ts +0 -36
  461. package/dist/types/capability/slash-command.d.ts +0 -17
  462. package/dist/types/capability/ssh.d.ts +0 -23
  463. package/dist/types/capability/system-prompt.d.ts +0 -15
  464. package/dist/types/capability/tool.d.ts +0 -19
  465. package/dist/types/capability/types.d.ts +0 -154
  466. package/dist/types/cli/agents-cli.d.ts +0 -12
  467. package/dist/types/cli/args.d.ts +0 -57
  468. package/dist/types/cli/auth-broker-cli.d.ts +0 -25
  469. package/dist/types/cli/auth-gateway-cli.d.ts +0 -18
  470. package/dist/types/cli/classify-install-target.d.ts +0 -8
  471. package/dist/types/cli/commands/init-xdg.d.ts +0 -1
  472. package/dist/types/cli/completion-cli.d.ts +0 -41
  473. package/dist/types/cli/config-cli.d.ts +0 -23
  474. package/dist/types/cli/daemon-cli.d.ts +0 -27
  475. package/dist/types/cli/fast-help.d.ts +0 -1
  476. package/dist/types/cli/file-processor.d.ts +0 -11
  477. package/dist/types/cli/fixture-report.d.ts +0 -20
  478. package/dist/types/cli/fixture-report.test.d.ts +0 -1
  479. package/dist/types/cli/grep-cli.d.ts +0 -17
  480. package/dist/types/cli/initial-message.d.ts +0 -17
  481. package/dist/types/cli/list-models.d.ts +0 -36
  482. package/dist/types/cli/local-provider-smoke.d.ts +0 -59
  483. package/dist/types/cli/malloc-env-guard.d.ts +0 -65
  484. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  485. package/dist/types/cli/mcp-cli.d.ts +0 -25
  486. package/dist/types/cli/migrate-cli.d.ts +0 -20
  487. package/dist/types/cli/nofile-limit.d.ts +0 -11
  488. package/dist/types/cli/notify-cli.d.ts +0 -39
  489. package/dist/types/cli/plugin-cli.d.ts +0 -34
  490. package/dist/types/cli/read-cli.d.ts +0 -4
  491. package/dist/types/cli/session-picker.d.ts +0 -4
  492. package/dist/types/cli/setup-cli.d.ts +0 -73
  493. package/dist/types/cli/shell-cli.d.ts +0 -8
  494. package/dist/types/cli/skills-cli.d.ts +0 -9
  495. package/dist/types/cli/ssh-cli.d.ts +0 -21
  496. package/dist/types/cli/stats-cli.d.ts +0 -17
  497. package/dist/types/cli/telegram-cli.d.ts +0 -13
  498. package/dist/types/cli/update-cli.d.ts +0 -108
  499. package/dist/types/cli/web-search-cli.d.ts +0 -32
  500. package/dist/types/cli/worktree-cli.d.ts +0 -26
  501. package/dist/types/cli.d.ts +0 -140
  502. package/dist/types/commands/acp.d.ts +0 -12
  503. package/dist/types/commands/agents.d.ts +0 -34
  504. package/dist/types/commands/auth-broker.d.ts +0 -54
  505. package/dist/types/commands/auth-gateway.d.ts +0 -32
  506. package/dist/types/commands/codex-native-hook.d.ts +0 -6
  507. package/dist/types/commands/commit.d.ts +0 -27
  508. package/dist/types/commands/completion.d.ts +0 -29
  509. package/dist/types/commands/config.d.ts +0 -33
  510. package/dist/types/commands/contribution-prep.d.ts +0 -18
  511. package/dist/types/commands/coordinator.d.ts +0 -19
  512. package/dist/types/commands/daemon.d.ts +0 -45
  513. package/dist/types/commands/deep-interview.d.ts +0 -54
  514. package/dist/types/commands/gc.d.ts +0 -26
  515. package/dist/types/commands/grep.d.ts +0 -42
  516. package/dist/types/commands/harness.d.ts +0 -43
  517. package/dist/types/commands/launch.d.ts +0 -131
  518. package/dist/types/commands/local-provider.d.ts +0 -34
  519. package/dist/types/commands/mcp-serve.d.ts +0 -24
  520. package/dist/types/commands/mcp.d.ts +0 -70
  521. package/dist/types/commands/migrate.d.ts +0 -33
  522. package/dist/types/commands/notify.d.ts +0 -47
  523. package/dist/types/commands/plugin.d.ts +0 -58
  524. package/dist/types/commands/ralplan.d.ts +0 -7
  525. package/dist/types/commands/read.d.ts +0 -15
  526. package/dist/types/commands/rlm.d.ts +0 -10
  527. package/dist/types/commands/session.d.ts +0 -30
  528. package/dist/types/commands/setup.d.ts +0 -105
  529. package/dist/types/commands/shell.d.ts +0 -21
  530. package/dist/types/commands/skills.d.ts +0 -26
  531. package/dist/types/commands/ssh.d.ts +0 -48
  532. package/dist/types/commands/state.d.ts +0 -7
  533. package/dist/types/commands/stats.d.ts +0 -25
  534. package/dist/types/commands/team.d.ts +0 -24
  535. package/dist/types/commands/telegram.d.ts +0 -22
  536. package/dist/types/commands/ultragoal.d.ts +0 -8
  537. package/dist/types/commands/update.d.ts +0 -20
  538. package/dist/types/commands/web-search.d.ts +0 -87
  539. package/dist/types/commands/worktree.d.ts +0 -34
  540. package/dist/types/commit/agentic/agent.d.ts +0 -31
  541. package/dist/types/commit/agentic/fallback.d.ts +0 -5
  542. package/dist/types/commit/agentic/index.d.ts +0 -2
  543. package/dist/types/commit/agentic/state.d.ts +0 -58
  544. package/dist/types/commit/agentic/tools/analyze-file.d.ts +0 -19
  545. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +0 -10
  546. package/dist/types/commit/agentic/tools/git-hunk.d.ts +0 -9
  547. package/dist/types/commit/agentic/tools/git-overview.d.ts +0 -9
  548. package/dist/types/commit/agentic/tools/index.d.ts +0 -16
  549. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +0 -28
  550. package/dist/types/commit/agentic/tools/propose-commit.d.ts +0 -36
  551. package/dist/types/commit/agentic/tools/recent-commits.d.ts +0 -7
  552. package/dist/types/commit/agentic/tools/schemas.d.ts +0 -27
  553. package/dist/types/commit/agentic/tools/split-commit.d.ts +0 -53
  554. package/dist/types/commit/agentic/topo-sort.d.ts +0 -4
  555. package/dist/types/commit/agentic/trivial.d.ts +0 -7
  556. package/dist/types/commit/agentic/validation.d.ts +0 -20
  557. package/dist/types/commit/analysis/conventional.d.ts +0 -22
  558. package/dist/types/commit/analysis/index.d.ts +0 -4
  559. package/dist/types/commit/analysis/scope.d.ts +0 -6
  560. package/dist/types/commit/analysis/summary.d.ts +0 -19
  561. package/dist/types/commit/analysis/validation.d.ts +0 -8
  562. package/dist/types/commit/changelog/detect.d.ts +0 -2
  563. package/dist/types/commit/changelog/generate.d.ts +0 -30
  564. package/dist/types/commit/changelog/index.d.ts +0 -30
  565. package/dist/types/commit/changelog/parse.d.ts +0 -2
  566. package/dist/types/commit/cli.d.ts +0 -3
  567. package/dist/types/commit/git/diff.d.ts +0 -5
  568. package/dist/types/commit/index.d.ts +0 -4
  569. package/dist/types/commit/map-reduce/index.d.ts +0 -28
  570. package/dist/types/commit/map-reduce/map-phase.d.ts +0 -17
  571. package/dist/types/commit/map-reduce/reduce-phase.d.ts +0 -13
  572. package/dist/types/commit/map-reduce/utils.d.ts +0 -2
  573. package/dist/types/commit/message.d.ts +0 -2
  574. package/dist/types/commit/model-selection.d.ts +0 -15
  575. package/dist/types/commit/pipeline.d.ts +0 -5
  576. package/dist/types/commit/shared-llm.d.ts +0 -54
  577. package/dist/types/commit/types.d.ts +0 -78
  578. package/dist/types/commit/utils/exclusions.d.ts +0 -4
  579. package/dist/types/commit/utils.d.ts +0 -20
  580. package/dist/types/config/config-file.d.ts +0 -58
  581. package/dist/types/config/file-lock-gc.d.ts +0 -5
  582. package/dist/types/config/file-lock.d.ts +0 -36
  583. package/dist/types/config/keybindings.d.ts +0 -364
  584. package/dist/types/config/model-equivalence.d.ts +0 -24
  585. package/dist/types/config/model-profile-activation.d.ts +0 -65
  586. package/dist/types/config/model-profiles.d.ts +0 -39
  587. package/dist/types/config/model-registry.d.ts +0 -473
  588. package/dist/types/config/model-resolver.d.ts +0 -217
  589. package/dist/types/config/models-config-schema.d.ts +0 -700
  590. package/dist/types/config/prompt-templates.d.ts +0 -32
  591. package/dist/types/config/resolve-config-value.d.ts +0 -17
  592. package/dist/types/config/settings-schema.d.ts +0 -4223
  593. package/dist/types/config/settings.d.ts +0 -158
  594. package/dist/types/config/skill-settings-defaults.d.ts +0 -14
  595. package/dist/types/config/telegram-autostart.d.ts +0 -14
  596. package/dist/types/config/telegram-env-bridge.d.ts +0 -18
  597. package/dist/types/config.d.ts +0 -66
  598. package/dist/types/coordinator/contract.d.ts +0 -4
  599. package/dist/types/coordinator-mcp/model-preset.d.ts +0 -45
  600. package/dist/types/coordinator-mcp/policy.d.ts +0 -27
  601. package/dist/types/coordinator-mcp/safety.d.ts +0 -26
  602. package/dist/types/coordinator-mcp/server.d.ts +0 -139
  603. package/dist/types/coordinator-mcp/session-reaper.d.ts +0 -53
  604. package/dist/types/cursor.d.ts +0 -24
  605. package/dist/types/daemon/builtin.d.ts +0 -20
  606. package/dist/types/daemon/control-types.d.ts +0 -67
  607. package/dist/types/daemon/operator-contract.d.ts +0 -47
  608. package/dist/types/daemon/runtime.d.ts +0 -25
  609. package/dist/types/dap/client.d.ts +0 -39
  610. package/dist/types/dap/config.d.ts +0 -6
  611. package/dist/types/dap/index.d.ts +0 -4
  612. package/dist/types/dap/session.d.ts +0 -108
  613. package/dist/types/dap/types.d.ts +0 -524
  614. package/dist/types/debug/crash-diagnostics.d.ts +0 -45
  615. package/dist/types/debug/index.d.ts +0 -15
  616. package/dist/types/debug/log-formatting.d.ts +0 -4
  617. package/dist/types/debug/log-viewer.d.ts +0 -68
  618. package/dist/types/debug/profiler.d.ts +0 -24
  619. package/dist/types/debug/raw-sse-buffer.d.ts +0 -44
  620. package/dist/types/debug/raw-sse.d.ts +0 -16
  621. package/dist/types/debug/report-bundle.d.ts +0 -55
  622. package/dist/types/debug/runtime-gauges.d.ts +0 -6
  623. package/dist/types/debug/system-info.d.ts +0 -26
  624. package/dist/types/deep-interview/plaintext-gate-guard.d.ts +0 -11
  625. package/dist/types/deep-interview/render-middleware.d.ts +0 -6
  626. package/dist/types/defaults/skc/extensions/grok-build/index.d.ts +0 -1
  627. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/index.d.ts +0 -1
  628. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/models/catalog.d.ts +0 -29
  629. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/payload/sanitize.d.ts +0 -27
  630. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/billing.d.ts +0 -8
  631. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/register.d.ts +0 -5
  632. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/stream.d.ts +0 -10
  633. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/provider/usage.d.ts +0 -2
  634. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/shared/base-url.d.ts +0 -2
  635. package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/shared/errors.d.ts +0 -38
  636. package/dist/types/defaults/skc-defaults.d.ts +0 -64
  637. package/dist/types/defaults/skc-grok-cli.d.ts +0 -5
  638. package/dist/types/discovery/agents-md.d.ts +0 -1
  639. package/dist/types/discovery/agents.d.ts +0 -12
  640. package/dist/types/discovery/builtin.d.ts +0 -1
  641. package/dist/types/discovery/claude-plugins.d.ts +0 -1
  642. package/dist/types/discovery/claude.d.ts +0 -1
  643. package/dist/types/discovery/cline.d.ts +0 -1
  644. package/dist/types/discovery/codex.d.ts +0 -1
  645. package/dist/types/discovery/cursor.d.ts +0 -19
  646. package/dist/types/discovery/gemini.d.ts +0 -1
  647. package/dist/types/discovery/github.d.ts +0 -1
  648. package/dist/types/discovery/helpers.d.ts +0 -271
  649. package/dist/types/discovery/index.d.ts +0 -48
  650. package/dist/types/discovery/mcp-json.d.ts +0 -1
  651. package/dist/types/discovery/opencode.d.ts +0 -1
  652. package/dist/types/discovery/plugin-dir-roots.d.ts +0 -15
  653. package/dist/types/discovery/ssh.d.ts +0 -1
  654. package/dist/types/discovery/substitute-plugin-root.d.ts +0 -1
  655. package/dist/types/discovery/vscode.d.ts +0 -1
  656. package/dist/types/discovery/windsurf.d.ts +0 -15
  657. package/dist/types/edit/apply-patch/index.d.ts +0 -35
  658. package/dist/types/edit/apply-patch/parser.d.ts +0 -34
  659. package/dist/types/edit/diff.d.ts +0 -75
  660. package/dist/types/edit/file-read-cache.d.ts +0 -25
  661. package/dist/types/edit/index.d.ts +0 -58
  662. package/dist/types/edit/modes/apply-patch.d.ts +0 -24
  663. package/dist/types/edit/modes/patch.d.ts +0 -99
  664. package/dist/types/edit/modes/replace.d.ts +0 -149
  665. package/dist/types/edit/normalize.d.ts +0 -43
  666. package/dist/types/edit/notebook.d.ts +0 -26
  667. package/dist/types/edit/read-file.d.ts +0 -8
  668. package/dist/types/edit/renderer.d.ts +0 -110
  669. package/dist/types/edit/streaming.d.ts +0 -66
  670. package/dist/types/eval/backend.d.ts +0 -40
  671. package/dist/types/eval/index.d.ts +0 -4
  672. package/dist/types/eval/js/context-manager.d.ts +0 -27
  673. package/dist/types/eval/js/executor.d.ts +0 -29
  674. package/dist/types/eval/js/index.d.ts +0 -10
  675. package/dist/types/eval/js/shared/helpers.d.ts +0 -38
  676. package/dist/types/eval/js/shared/indirect-eval.d.ts +0 -14
  677. package/dist/types/eval/js/shared/prelude.d.ts +0 -1
  678. package/dist/types/eval/js/shared/rewrite-imports.d.ts +0 -6
  679. package/dist/types/eval/js/shared/runtime.d.ts +0 -47
  680. package/dist/types/eval/js/shared/types.d.ts +0 -24
  681. package/dist/types/eval/js/tool-bridge.d.ts +0 -18
  682. package/dist/types/eval/js/worker-core.d.ts +0 -5
  683. package/dist/types/eval/js/worker-entry.d.ts +0 -1
  684. package/dist/types/eval/js/worker-protocol.d.ts +0 -77
  685. package/dist/types/eval/py/display.d.ts +0 -25
  686. package/dist/types/eval/py/executor.d.ts +0 -88
  687. package/dist/types/eval/py/index.d.ts +0 -10
  688. package/dist/types/eval/py/kernel.d.ts +0 -65
  689. package/dist/types/eval/py/prelude.d.ts +0 -1
  690. package/dist/types/eval/py/runtime.d.ts +0 -29
  691. package/dist/types/eval/py/tool-bridge.d.ts +0 -20
  692. package/dist/types/eval/types.d.ts +0 -52
  693. package/dist/types/exa/factory.d.ts +0 -13
  694. package/dist/types/exa/index.d.ts +0 -20
  695. package/dist/types/exa/mcp-client.d.ts +0 -45
  696. package/dist/types/exa/render.d.ts +0 -19
  697. package/dist/types/exa/researcher.d.ts +0 -9
  698. package/dist/types/exa/search.d.ts +0 -9
  699. package/dist/types/exa/types.d.ts +0 -155
  700. package/dist/types/exa/websets.d.ts +0 -9
  701. package/dist/types/exec/bash-executor.d.ts +0 -64
  702. package/dist/types/exec/exec.d.ts +0 -25
  703. package/dist/types/exec/idle-timeout-watchdog.d.ts +0 -18
  704. package/dist/types/exec/non-interactive-env.d.ts +0 -1
  705. package/dist/types/export/custom-share.d.ts +0 -20
  706. package/dist/types/export/html/index.d.ts +0 -10
  707. package/dist/types/export/html/template.generated.d.ts +0 -1
  708. package/dist/types/export/html/template.macro.d.ts +0 -5
  709. package/dist/types/export/ttsr.d.ts +0 -55
  710. package/dist/types/extensibility/custom-commands/bundled/ci-green/index.d.ts +0 -9
  711. package/dist/types/extensibility/custom-commands/index.d.ts +0 -2
  712. package/dist/types/extensibility/custom-commands/loader.d.ts +0 -29
  713. package/dist/types/extensibility/custom-commands/types.d.ts +0 -106
  714. package/dist/types/extensibility/custom-tools/index.d.ts +0 -6
  715. package/dist/types/extensibility/custom-tools/loader.d.ts +0 -69
  716. package/dist/types/extensibility/custom-tools/types.d.ts +0 -229
  717. package/dist/types/extensibility/custom-tools/wrapper.d.ts +0 -24
  718. package/dist/types/extensibility/extensions/compact-handler.d.ts +0 -26
  719. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +0 -29
  720. package/dist/types/extensibility/extensions/index.d.ts +0 -9
  721. package/dist/types/extensibility/extensions/loader.d.ts +0 -43
  722. package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +0 -35
  723. package/dist/types/extensibility/extensions/runner.d.ts +0 -135
  724. package/dist/types/extensibility/extensions/types.d.ts +0 -920
  725. package/dist/types/extensibility/extensions/wrapper.d.ts +0 -55
  726. package/dist/types/extensibility/hooks/index.d.ts +0 -5
  727. package/dist/types/extensibility/hooks/loader.d.ts +0 -89
  728. package/dist/types/extensibility/hooks/runner.d.ts +0 -126
  729. package/dist/types/extensibility/hooks/tool-wrapper.d.ts +0 -25
  730. package/dist/types/extensibility/hooks/types.d.ts +0 -431
  731. package/dist/types/extensibility/plugins/doctor.d.ts +0 -3
  732. package/dist/types/extensibility/plugins/git-url.d.ts +0 -34
  733. package/dist/types/extensibility/plugins/index.d.ts +0 -8
  734. package/dist/types/extensibility/plugins/installer.d.ts +0 -5
  735. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +0 -2
  736. package/dist/types/extensibility/plugins/loader.d.ts +0 -31
  737. package/dist/types/extensibility/plugins/manager.d.ts +0 -65
  738. package/dist/types/extensibility/plugins/marketplace/cache.d.ts +0 -41
  739. package/dist/types/extensibility/plugins/marketplace/fetcher.d.ts +0 -48
  740. package/dist/types/extensibility/plugins/marketplace/index.d.ts +0 -6
  741. package/dist/types/extensibility/plugins/marketplace/manager.d.ts +0 -57
  742. package/dist/types/extensibility/plugins/marketplace/registry.d.ts +0 -34
  743. package/dist/types/extensibility/plugins/marketplace/source-resolver.d.ts +0 -28
  744. package/dist/types/extensibility/plugins/marketplace/types.d.ts +0 -130
  745. package/dist/types/extensibility/plugins/parser.d.ts +0 -52
  746. package/dist/types/extensibility/plugins/security-scanner.d.ts +0 -31
  747. package/dist/types/extensibility/plugins/types.d.ts +0 -149
  748. package/dist/types/extensibility/runtime-skill-discovery.d.ts +0 -20
  749. package/dist/types/extensibility/shared-events.d.ts +0 -281
  750. package/dist/types/extensibility/skc-plugins/activation.d.ts +0 -14
  751. package/dist/types/extensibility/skc-plugins/compiler.d.ts +0 -19
  752. package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +0 -29
  753. package/dist/types/extensibility/skc-plugins/index.d.ts +0 -18
  754. package/dist/types/extensibility/skc-plugins/injection.d.ts +0 -40
  755. package/dist/types/extensibility/skc-plugins/installer.d.ts +0 -13
  756. package/dist/types/extensibility/skc-plugins/loader.d.ts +0 -3
  757. package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +0 -26
  758. package/dist/types/extensibility/skc-plugins/observability.d.ts +0 -27
  759. package/dist/types/extensibility/skc-plugins/paths.d.ts +0 -8
  760. package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +0 -16
  761. package/dist/types/extensibility/skc-plugins/registry.d.ts +0 -32
  762. package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +0 -64
  763. package/dist/types/extensibility/skc-plugins/schema.d.ts +0 -3
  764. package/dist/types/extensibility/skc-plugins/session-validation.d.ts +0 -42
  765. package/dist/types/extensibility/skc-plugins/state.d.ts +0 -9
  766. package/dist/types/extensibility/skc-plugins/tools.d.ts +0 -8
  767. package/dist/types/extensibility/skc-plugins/types.d.ts +0 -220
  768. package/dist/types/extensibility/skc-plugins/validation.d.ts +0 -11
  769. package/dist/types/extensibility/skills.d.ts +0 -82
  770. package/dist/types/extensibility/slash-commands.d.ts +0 -48
  771. package/dist/types/extensibility/tool-proxy.d.ts +0 -4
  772. package/dist/types/extensibility/typebox.d.ts +0 -155
  773. package/dist/types/extensibility/utils.d.ts +0 -12
  774. package/dist/types/goals/index.d.ts +0 -3
  775. package/dist/types/goals/runtime.d.ts +0 -63
  776. package/dist/types/goals/state.d.ts +0 -32
  777. package/dist/types/goals/tools/goal-tool.d.ts +0 -62
  778. package/dist/types/harness-control-plane/classifier.d.ts +0 -13
  779. package/dist/types/harness-control-plane/control-endpoint.d.ts +0 -31
  780. package/dist/types/harness-control-plane/finalize.d.ts +0 -60
  781. package/dist/types/harness-control-plane/gc-adapter.d.ts +0 -3
  782. package/dist/types/harness-control-plane/operate.d.ts +0 -35
  783. package/dist/types/harness-control-plane/owner.d.ts +0 -53
  784. package/dist/types/harness-control-plane/phase-rollup.d.ts +0 -23
  785. package/dist/types/harness-control-plane/preserve.d.ts +0 -19
  786. package/dist/types/harness-control-plane/receipt-ingest.d.ts +0 -19
  787. package/dist/types/harness-control-plane/receipt-spool.d.ts +0 -19
  788. package/dist/types/harness-control-plane/receipts.d.ts +0 -149
  789. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  790. package/dist/types/harness-control-plane/seams.d.ts +0 -21
  791. package/dist/types/harness-control-plane/session-lease.d.ts +0 -65
  792. package/dist/types/harness-control-plane/state-machine.d.ts +0 -24
  793. package/dist/types/harness-control-plane/storage.d.ts +0 -81
  794. package/dist/types/harness-control-plane/types.d.ts +0 -187
  795. package/dist/types/hashline/anchors.d.ts +0 -20
  796. package/dist/types/hashline/apply.d.ts +0 -14
  797. package/dist/types/hashline/constants.d.ts +0 -19
  798. package/dist/types/hashline/diff-preview.d.ts +0 -2
  799. package/dist/types/hashline/diff.d.ts +0 -17
  800. package/dist/types/hashline/execute.d.ts +0 -4
  801. package/dist/types/hashline/hash.d.ts +0 -123
  802. package/dist/types/hashline/index.d.ts +0 -13
  803. package/dist/types/hashline/input.d.ts +0 -11
  804. package/dist/types/hashline/parser.d.ts +0 -7
  805. package/dist/types/hashline/prefixes.d.ts +0 -7
  806. package/dist/types/hashline/recovery.d.ts +0 -27
  807. package/dist/types/hashline/stream.d.ts +0 -2
  808. package/dist/types/hashline/types.d.ts +0 -77
  809. package/dist/types/hindsight/backend.d.ts +0 -13
  810. package/dist/types/hindsight/bank.d.ts +0 -54
  811. package/dist/types/hindsight/client.d.ts +0 -224
  812. package/dist/types/hindsight/config.d.ts +0 -51
  813. package/dist/types/hindsight/content.d.ts +0 -70
  814. package/dist/types/hindsight/index.d.ts +0 -8
  815. package/dist/types/hindsight/mental-models.d.ts +0 -125
  816. package/dist/types/hindsight/state.d.ts +0 -99
  817. package/dist/types/hindsight/transcript.d.ts +0 -28
  818. package/dist/types/hooks/codex-native-hooks-config.d.ts +0 -29
  819. package/dist/types/hooks/native-skill-hook.d.ts +0 -28
  820. package/dist/types/hooks/skill-keywords.d.ts +0 -18
  821. package/dist/types/hooks/skill-state.d.ts +0 -93
  822. package/dist/types/i18n/index.d.ts +0 -38
  823. package/dist/types/i18n/messages/de.d.ts +0 -2
  824. package/dist/types/i18n/messages/de.messages.d.ts +0 -1
  825. package/dist/types/i18n/messages/de.settings.d.ts +0 -1
  826. package/dist/types/i18n/messages/en.d.ts +0 -81
  827. package/dist/types/i18n/messages/es.d.ts +0 -2
  828. package/dist/types/i18n/messages/es.messages.d.ts +0 -1
  829. package/dist/types/i18n/messages/es.settings.d.ts +0 -1
  830. package/dist/types/i18n/messages/fr.d.ts +0 -2
  831. package/dist/types/i18n/messages/fr.messages.d.ts +0 -1
  832. package/dist/types/i18n/messages/fr.settings.d.ts +0 -1
  833. package/dist/types/i18n/messages/ja.d.ts +0 -2
  834. package/dist/types/i18n/messages/ja.messages.d.ts +0 -1
  835. package/dist/types/i18n/messages/ja.settings.d.ts +0 -1
  836. package/dist/types/i18n/messages/ko.d.ts +0 -2
  837. package/dist/types/i18n/messages/ko.messages.d.ts +0 -1
  838. package/dist/types/i18n/messages/ko.settings.d.ts +0 -1
  839. package/dist/types/i18n/messages/zh.d.ts +0 -2
  840. package/dist/types/i18n/messages/zh.messages.d.ts +0 -1
  841. package/dist/types/i18n/messages/zh.settings.d.ts +0 -1
  842. package/dist/types/index.d.ts +0 -33
  843. package/dist/types/internal-urls/agent-protocol.d.ts +0 -12
  844. package/dist/types/internal-urls/artifact-protocol.d.ts +0 -6
  845. package/dist/types/internal-urls/docs-index.generated.d.ts +0 -2
  846. package/dist/types/internal-urls/index.d.ts +0 -20
  847. package/dist/types/internal-urls/issue-pr-protocol.d.ts +0 -17
  848. package/dist/types/internal-urls/json-query.d.ts +0 -30
  849. package/dist/types/internal-urls/local-protocol.d.ts +0 -43
  850. package/dist/types/internal-urls/mcp-protocol.d.ts +0 -12
  851. package/dist/types/internal-urls/memory-protocol.d.ts +0 -23
  852. package/dist/types/internal-urls/parse.d.ts +0 -19
  853. package/dist/types/internal-urls/registry-helpers.d.ts +0 -11
  854. package/dist/types/internal-urls/router.d.ts +0 -14
  855. package/dist/types/internal-urls/rule-protocol.d.ts +0 -6
  856. package/dist/types/internal-urls/skc-protocol.d.ts +0 -12
  857. package/dist/types/internal-urls/skill-protocol.d.ts +0 -13
  858. package/dist/types/internal-urls/types.d.ts +0 -109
  859. package/dist/types/lsp/client.d.ts +0 -66
  860. package/dist/types/lsp/clients/biome-client.d.ts +0 -16
  861. package/dist/types/lsp/clients/index.d.ts +0 -19
  862. package/dist/types/lsp/clients/lsp-linter-client.d.ts +0 -16
  863. package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -20
  864. package/dist/types/lsp/config.d.ts +0 -65
  865. package/dist/types/lsp/edits.d.ts +0 -23
  866. package/dist/types/lsp/index.d.ts +0 -130
  867. package/dist/types/lsp/lspmux.d.ts +0 -58
  868. package/dist/types/lsp/render.d.ts +0 -32
  869. package/dist/types/lsp/startup-events.d.ts +0 -12
  870. package/dist/types/lsp/types.d.ts +0 -306
  871. package/dist/types/lsp/utils.d.ts +0 -108
  872. package/dist/types/main.d.ts +0 -139
  873. package/dist/types/memories/index.d.ts +0 -28
  874. package/dist/types/memories/storage.d.ts +0 -110
  875. package/dist/types/memory-backend/index.d.ts +0 -4
  876. package/dist/types/memory-backend/local-backend.d.ts +0 -9
  877. package/dist/types/memory-backend/off-backend.d.ts +0 -7
  878. package/dist/types/memory-backend/resolve.d.ts +0 -15
  879. package/dist/types/memory-backend/types.d.ts +0 -61
  880. package/dist/types/migrate/action-planner.d.ts +0 -11
  881. package/dist/types/migrate/adapters/claude-code.d.ts +0 -2
  882. package/dist/types/migrate/adapters/codex.d.ts +0 -5
  883. package/dist/types/migrate/adapters/index.d.ts +0 -45
  884. package/dist/types/migrate/adapters/opencode.d.ts +0 -2
  885. package/dist/types/migrate/executor.d.ts +0 -2
  886. package/dist/types/migrate/mcp-mapper.d.ts +0 -20
  887. package/dist/types/migrate/report.d.ts +0 -18
  888. package/dist/types/migrate/skill-normalizer.d.ts +0 -27
  889. package/dist/types/migrate/types.d.ts +0 -126
  890. package/dist/types/modes/acp/acp-agent.d.ts +0 -78
  891. package/dist/types/modes/acp/acp-client-bridge.d.ts +0 -9
  892. package/dist/types/modes/acp/acp-event-mapper.d.ts +0 -36
  893. package/dist/types/modes/acp/acp-mode.d.ts +0 -17
  894. package/dist/types/modes/acp/index.d.ts +0 -2
  895. package/dist/types/modes/acp/terminal-auth.d.ts +0 -6
  896. package/dist/types/modes/bridge/auth.d.ts +0 -12
  897. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  898. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  899. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  900. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  901. package/dist/types/modes/components/agent-dashboard.d.ts +0 -21
  902. package/dist/types/modes/components/assistant-message.d.ts +0 -20
  903. package/dist/types/modes/components/bash-execution.d.ts +0 -29
  904. package/dist/types/modes/components/bordered-loader.d.ts +0 -11
  905. package/dist/types/modes/components/branch-summary-message.d.ts +0 -13
  906. package/dist/types/modes/components/btw-panel.d.ts +0 -16
  907. package/dist/types/modes/components/compaction-summary-message.d.ts +0 -13
  908. package/dist/types/modes/components/countdown-timer.d.ts +0 -14
  909. package/dist/types/modes/components/custom-editor.d.ts +0 -69
  910. package/dist/types/modes/components/custom-message.d.ts +0 -15
  911. package/dist/types/modes/components/custom-model-preset-wizard.d.ts +0 -12
  912. package/dist/types/modes/components/custom-provider-wizard.d.ts +0 -10
  913. package/dist/types/modes/components/diff.d.ts +0 -11
  914. package/dist/types/modes/components/dynamic-border.d.ts +0 -14
  915. package/dist/types/modes/components/eval-execution.d.ts +0 -23
  916. package/dist/types/modes/components/execution-shared.d.ts +0 -46
  917. package/dist/types/modes/components/extensions/extension-dashboard.d.ts +0 -26
  918. package/dist/types/modes/components/extensions/extension-list.d.ts +0 -39
  919. package/dist/types/modes/components/extensions/index.d.ts +0 -8
  920. package/dist/types/modes/components/extensions/inspector-panel.d.ts +0 -8
  921. package/dist/types/modes/components/extensions/state-manager.d.ts +0 -50
  922. package/dist/types/modes/components/extensions/types.d.ts +0 -151
  923. package/dist/types/modes/components/footer.d.ts +0 -30
  924. package/dist/types/modes/components/history-search.d.ts +0 -7
  925. package/dist/types/modes/components/hook-editor.d.ts +0 -18
  926. package/dist/types/modes/components/hook-input.d.ts +0 -15
  927. package/dist/types/modes/components/hook-message.d.ts +0 -15
  928. package/dist/types/modes/components/hook-selector.d.ts +0 -59
  929. package/dist/types/modes/components/index.d.ts +0 -35
  930. package/dist/types/modes/components/irc-sidebar.d.ts +0 -32
  931. package/dist/types/modes/components/jobs-overlay-model.d.ts +0 -31
  932. package/dist/types/modes/components/jobs-overlay.d.ts +0 -30
  933. package/dist/types/modes/components/keybinding-hints.d.ts +0 -40
  934. package/dist/types/modes/components/login-dialog.d.ts +0 -32
  935. package/dist/types/modes/components/message-frame.d.ts +0 -42
  936. package/dist/types/modes/components/model-selector.d.ts +0 -60
  937. package/dist/types/modes/components/oauth-selector.d.ts +0 -17
  938. package/dist/types/modes/components/pet-selector.d.ts +0 -11
  939. package/dist/types/modes/components/plugin-selector.d.ts +0 -26
  940. package/dist/types/modes/components/plugin-settings.d.ts +0 -66
  941. package/dist/types/modes/components/provider-onboarding-selector.d.ts +0 -7
  942. package/dist/types/modes/components/queue-mode-selector.d.ts +0 -9
  943. package/dist/types/modes/components/queued-message-selector.d.ts +0 -12
  944. package/dist/types/modes/components/read-tool-group.d.ts +0 -30
  945. package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +0 -26
  946. package/dist/types/modes/components/sayknow-pet-widget.d.ts +0 -59
  947. package/dist/types/modes/components/session-observer-overlay.d.ts +0 -11
  948. package/dist/types/modes/components/session-selector.d.ts +0 -43
  949. package/dist/types/modes/components/settings-defs.d.ts +0 -50
  950. package/dist/types/modes/components/settings-selector.d.ts +0 -64
  951. package/dist/types/modes/components/show-images-selector.d.ts +0 -9
  952. package/dist/types/modes/components/skill-hud/render.d.ts +0 -2
  953. package/dist/types/modes/components/skill-message.d.ts +0 -10
  954. package/dist/types/modes/components/status-line/context-thresholds.d.ts +0 -4
  955. package/dist/types/modes/components/status-line/git-utils.d.ts +0 -28
  956. package/dist/types/modes/components/status-line/index.d.ts +0 -4
  957. package/dist/types/modes/components/status-line/presets.d.ts +0 -3
  958. package/dist/types/modes/components/status-line/segments.d.ts +0 -5
  959. package/dist/types/modes/components/status-line/separators.d.ts +0 -3
  960. package/dist/types/modes/components/status-line/token-rate.d.ts +0 -10
  961. package/dist/types/modes/components/status-line/types.d.ts +0 -83
  962. package/dist/types/modes/components/status-line.d.ts +0 -94
  963. package/dist/types/modes/components/theme-selector.d.ts +0 -10
  964. package/dist/types/modes/components/thinking-selector.d.ts +0 -15
  965. package/dist/types/modes/components/todo-reminder.d.ts +0 -13
  966. package/dist/types/modes/components/tool-execution.d.ts +0 -55
  967. package/dist/types/modes/components/tree-selector.d.ts +0 -31
  968. package/dist/types/modes/components/ttsr-notification.d.ts +0 -13
  969. package/dist/types/modes/components/two-column-body.d.ts +0 -9
  970. package/dist/types/modes/components/user-message-selector.d.ts +0 -28
  971. package/dist/types/modes/components/user-message.d.ts +0 -8
  972. package/dist/types/modes/components/visual-truncate.d.ts +0 -19
  973. package/dist/types/modes/components/welcome.d.ts +0 -46
  974. package/dist/types/modes/controllers/btw-controller.d.ts +0 -10
  975. package/dist/types/modes/controllers/command-controller-shared.d.ts +0 -47
  976. package/dist/types/modes/controllers/command-controller.d.ts +0 -40
  977. package/dist/types/modes/controllers/event-controller.d.ts +0 -21
  978. package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -80
  979. package/dist/types/modes/controllers/input-controller.d.ts +0 -42
  980. package/dist/types/modes/controllers/runtime-mcp-command-controller.d.ts +0 -10
  981. package/dist/types/modes/controllers/selector-controller.d.ts +0 -68
  982. package/dist/types/modes/controllers/ssh-command-controller.d.ts +0 -10
  983. package/dist/types/modes/controllers/todo-command-controller.d.ts +0 -7
  984. package/dist/types/modes/emoji-autocomplete.d.ts +0 -16
  985. package/dist/types/modes/index.d.ts +0 -10
  986. package/dist/types/modes/interactive-mode.d.ts +0 -297
  987. package/dist/types/modes/irc-observation-ledger.d.ts +0 -22
  988. package/dist/types/modes/jobs-observer.d.ts +0 -57
  989. package/dist/types/modes/oauth-manual-input.d.ts +0 -8
  990. package/dist/types/modes/print-mode.d.ts +0 -44
  991. package/dist/types/modes/prompt-action-autocomplete.d.ts +0 -50
  992. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  993. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  994. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  995. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  996. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  997. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  998. package/dist/types/modes/runtime-init.d.ts +0 -21
  999. package/dist/types/modes/session-observer-registry.d.ts +0 -26
  1000. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +0 -57
  1001. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  1002. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  1003. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  1004. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +0 -102
  1005. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +0 -103
  1006. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +0 -60
  1007. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +0 -37
  1008. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  1009. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  1010. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  1011. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  1012. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  1013. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  1014. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  1015. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  1016. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  1017. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  1018. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  1019. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  1020. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  1021. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +0 -154
  1022. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +0 -39
  1023. package/dist/types/modes/shared.d.ts +0 -15
  1024. package/dist/types/modes/slash-command-visibility.d.ts +0 -1
  1025. package/dist/types/modes/theme/defaults/index.d.ts +0 -652
  1026. package/dist/types/modes/theme/mermaid-cache.d.ts +0 -9
  1027. package/dist/types/modes/theme/shimmer.d.ts +0 -38
  1028. package/dist/types/modes/theme/theme.d.ts +0 -275
  1029. package/dist/types/modes/tmux-scroll.d.ts +0 -18
  1030. package/dist/types/modes/types.d.ts +0 -318
  1031. package/dist/types/modes/utils/abort-message.d.ts +0 -4
  1032. package/dist/types/modes/utils/context-usage.d.ts +0 -36
  1033. package/dist/types/modes/utils/hotkeys-markdown.d.ts +0 -5
  1034. package/dist/types/modes/utils/injected-user-submission.d.ts +0 -52
  1035. package/dist/types/modes/utils/irc-message.d.ts +0 -38
  1036. package/dist/types/modes/utils/keybinding-matchers.d.ts +0 -10
  1037. package/dist/types/modes/utils/terminal-bell.d.ts +0 -3
  1038. package/dist/types/modes/utils/tools-markdown.d.ts +0 -5
  1039. package/dist/types/modes/utils/ui-helpers.d.ts +0 -75
  1040. package/dist/types/notifications/attachment-registry.d.ts +0 -17
  1041. package/dist/types/notifications/chat-adapters.d.ts +0 -9
  1042. package/dist/types/notifications/config-commands.d.ts +0 -64
  1043. package/dist/types/notifications/config.d.ts +0 -132
  1044. package/dist/types/notifications/daemon-paths.d.ts +0 -17
  1045. package/dist/types/notifications/engine.d.ts +0 -59
  1046. package/dist/types/notifications/helpers.d.ts +0 -55
  1047. package/dist/types/notifications/html-format.d.ts +0 -75
  1048. package/dist/types/notifications/index.d.ts +0 -219
  1049. package/dist/types/notifications/lifecycle-commands.d.ts +0 -69
  1050. package/dist/types/notifications/lifecycle-control-runtime.d.ts +0 -107
  1051. package/dist/types/notifications/lifecycle-orchestrator.d.ts +0 -144
  1052. package/dist/types/notifications/managed-daemon.d.ts +0 -48
  1053. package/dist/types/notifications/notification-service.d.ts +0 -144
  1054. package/dist/types/notifications/operator-runtime.d.ts +0 -52
  1055. package/dist/types/notifications/rate-limit-pool.d.ts +0 -113
  1056. package/dist/types/notifications/recent-activity.d.ts +0 -39
  1057. package/dist/types/notifications/reply-sent-store.d.ts +0 -53
  1058. package/dist/types/notifications/rich-draft.d.ts +0 -68
  1059. package/dist/types/notifications/rich-render.d.ts +0 -90
  1060. package/dist/types/notifications/telegram-cli.d.ts +0 -19
  1061. package/dist/types/notifications/telegram-daemon-cli.d.ts +0 -28
  1062. package/dist/types/notifications/telegram-daemon-control.d.ts +0 -70
  1063. package/dist/types/notifications/telegram-daemon.d.ts +0 -558
  1064. package/dist/types/notifications/telegram-reference.d.ts +0 -136
  1065. package/dist/types/notifications/threaded-inbound.d.ts +0 -77
  1066. package/dist/types/notifications/threaded-render.d.ts +0 -88
  1067. package/dist/types/notifications/topic-registry.d.ts +0 -89
  1068. package/dist/types/plan-mode/approved-plan.d.ts +0 -49
  1069. package/dist/types/plan-mode/state.d.ts +0 -6
  1070. package/dist/types/registry/agent-registry.d.ts +0 -64
  1071. package/dist/types/reminders/star-reminder.d.ts +0 -115
  1072. package/dist/types/research-plan/index.d.ts +0 -1
  1073. package/dist/types/research-plan/ledger.d.ts +0 -33
  1074. package/dist/types/rlm/artifacts.d.ts +0 -9
  1075. package/dist/types/rlm/complete-research-tool.d.ts +0 -35
  1076. package/dist/types/rlm/data-context.d.ts +0 -6
  1077. package/dist/types/rlm/index.d.ts +0 -47
  1078. package/dist/types/rlm/notebook.d.ts +0 -12
  1079. package/dist/types/rlm/preset.d.ts +0 -23
  1080. package/dist/types/rlm/python-tool.d.ts +0 -16
  1081. package/dist/types/rlm/report.d.ts +0 -14
  1082. package/dist/types/rlm/types.d.ts +0 -37
  1083. package/dist/types/runtime/process-lifecycle.d.ts +0 -108
  1084. package/dist/types/runtime-api-key.d.ts +0 -7
  1085. package/dist/types/runtime-credential-selector.d.ts +0 -7
  1086. package/dist/types/runtime-mcp/client.d.ts +0 -74
  1087. package/dist/types/runtime-mcp/config-writer.d.ts +0 -89
  1088. package/dist/types/runtime-mcp/config.d.ts +0 -77
  1089. package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +0 -7
  1090. package/dist/types/runtime-mcp/index.d.ts +0 -18
  1091. package/dist/types/runtime-mcp/json-rpc.d.ts +0 -22
  1092. package/dist/types/runtime-mcp/loader.d.ts +0 -45
  1093. package/dist/types/runtime-mcp/manager.d.ts +0 -195
  1094. package/dist/types/runtime-mcp/oauth-discovery.d.ts +0 -40
  1095. package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -59
  1096. package/dist/types/runtime-mcp/render.d.ts +0 -25
  1097. package/dist/types/runtime-mcp/smithery-auth.d.ts +0 -16
  1098. package/dist/types/runtime-mcp/smithery-connect.d.ts +0 -38
  1099. package/dist/types/runtime-mcp/smithery-registry.d.ts +0 -51
  1100. package/dist/types/runtime-mcp/tool-bridge.d.ts +0 -86
  1101. package/dist/types/runtime-mcp/tool-cache.d.ts +0 -8
  1102. package/dist/types/runtime-mcp/transports/http.d.ts +0 -36
  1103. package/dist/types/runtime-mcp/transports/index.d.ts +0 -5
  1104. package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -29
  1105. package/dist/types/runtime-mcp/types.d.ts +0 -349
  1106. package/dist/types/sdk.d.ts +0 -256
  1107. package/dist/types/secrets/index.d.ts +0 -9
  1108. package/dist/types/secrets/obfuscator.d.ts +0 -23
  1109. package/dist/types/secrets/regex.d.ts +0 -2
  1110. package/dist/types/session/agent-session.d.ts +0 -1238
  1111. package/dist/types/session/agent-storage.d.ts +0 -101
  1112. package/dist/types/session/artifacts.d.ts +0 -64
  1113. package/dist/types/session/auth-broker-config.d.ts +0 -13
  1114. package/dist/types/session/auth-storage.d.ts +0 -6
  1115. package/dist/types/session/blob-store.d.ts +0 -160
  1116. package/dist/types/session/cache-economics.d.ts +0 -79
  1117. package/dist/types/session/client-bridge.d.ts +0 -88
  1118. package/dist/types/session/context-estimation.d.ts +0 -31
  1119. package/dist/types/session/contribution-prep.d.ts +0 -47
  1120. package/dist/types/session/file-mention-pruning.d.ts +0 -8
  1121. package/dist/types/session/history-storage.d.ts +0 -16
  1122. package/dist/types/session/messages.d.ts +0 -169
  1123. package/dist/types/session/provider-safety-stop.d.ts +0 -5
  1124. package/dist/types/session/session-dump-format.d.ts +0 -22
  1125. package/dist/types/session/session-manager.d.ts +0 -781
  1126. package/dist/types/session/session-storage.d.ts +0 -230
  1127. package/dist/types/session/streaming-output.d.ts +0 -209
  1128. package/dist/types/session/tool-choice-queue.d.ts +0 -84
  1129. package/dist/types/session/yield-queue.d.ts +0 -24
  1130. package/dist/types/setup/credential-auto-import.d.ts +0 -63
  1131. package/dist/types/setup/credential-import.d.ts +0 -82
  1132. package/dist/types/setup/hermes-setup.d.ts +0 -78
  1133. package/dist/types/setup/host-plugin-setup.d.ts +0 -39
  1134. package/dist/types/setup/model-onboarding-guidance.d.ts +0 -9
  1135. package/dist/types/setup/provider-onboarding.d.ts +0 -52
  1136. package/dist/types/skc-runtime/cli-write-receipt.d.ts +0 -24
  1137. package/dist/types/skc-runtime/deep-interview-ambiguity.d.ts +0 -39
  1138. package/dist/types/skc-runtime/deep-interview-recorder.d.ts +0 -114
  1139. package/dist/types/skc-runtime/deep-interview-runtime.d.ts +0 -36
  1140. package/dist/types/skc-runtime/deep-interview-state.d.ts +0 -127
  1141. package/dist/types/skc-runtime/gc-render.d.ts +0 -6
  1142. package/dist/types/skc-runtime/gc-runtime.d.ts +0 -134
  1143. package/dist/types/skc-runtime/goal-mode-request.d.ts +0 -53
  1144. package/dist/types/skc-runtime/launch-tmux.d.ts +0 -78
  1145. package/dist/types/skc-runtime/launch-worktree.d.ts +0 -46
  1146. package/dist/types/skc-runtime/ledger-event-renderer.d.ts +0 -68
  1147. package/dist/types/skc-runtime/psmux-detect.d.ts +0 -78
  1148. package/dist/types/skc-runtime/ralplan-runtime.d.ts +0 -26
  1149. package/dist/types/skc-runtime/restricted-role-agent-bash.d.ts +0 -3
  1150. package/dist/types/skc-runtime/session-layout.d.ts +0 -59
  1151. package/dist/types/skc-runtime/session-resolution.d.ts +0 -47
  1152. package/dist/types/skc-runtime/session-state-sidecar.d.ts +0 -70
  1153. package/dist/types/skc-runtime/state-graph.d.ts +0 -4
  1154. package/dist/types/skc-runtime/state-migrations.d.ts +0 -33
  1155. package/dist/types/skc-runtime/state-renderer.d.ts +0 -70
  1156. package/dist/types/skc-runtime/state-runtime.d.ts +0 -38
  1157. package/dist/types/skc-runtime/state-schema.d.ts +0 -319
  1158. package/dist/types/skc-runtime/state-validation.d.ts +0 -6
  1159. package/dist/types/skc-runtime/state-writer.d.ts +0 -244
  1160. package/dist/types/skc-runtime/team-gc.d.ts +0 -7
  1161. package/dist/types/skc-runtime/team-runtime.d.ts +0 -355
  1162. package/dist/types/skc-runtime/tmux-common.d.ts +0 -111
  1163. package/dist/types/skc-runtime/tmux-gc.d.ts +0 -7
  1164. package/dist/types/skc-runtime/tmux-owner-isolation-cli.d.ts +0 -5
  1165. package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +0 -309
  1166. package/dist/types/skc-runtime/tmux-sessions.d.ts +0 -94
  1167. package/dist/types/skc-runtime/ultragoal-guard.d.ts +0 -93
  1168. package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +0 -42
  1169. package/dist/types/skc-runtime/ultragoal-runtime.d.ts +0 -410
  1170. package/dist/types/skc-runtime/workflow-command-ref.d.ts +0 -43
  1171. package/dist/types/skc-runtime/workflow-manifest.d.ts +0 -54
  1172. package/dist/types/skill-state/active-state.d.ts +0 -126
  1173. package/dist/types/skill-state/canonical-skills.d.ts +0 -3
  1174. package/dist/types/skill-state/deep-interview-mutation-guard.d.ts +0 -38
  1175. package/dist/types/skill-state/initial-phase.d.ts +0 -12
  1176. package/dist/types/skill-state/workflow-hud.d.ts +0 -83
  1177. package/dist/types/skill-state/workflow-state-contract.d.ts +0 -57
  1178. package/dist/types/skill-state/workflow-state-version.d.ts +0 -3
  1179. package/dist/types/slash-commands/acp-builtins.d.ts +0 -18
  1180. package/dist/types/slash-commands/builtin-registry.d.ts +0 -24
  1181. package/dist/types/slash-commands/helpers/context-report.d.ts +0 -7
  1182. package/dist/types/slash-commands/helpers/fast-status-report.d.ts +0 -82
  1183. package/dist/types/slash-commands/helpers/format.d.ts +0 -10
  1184. package/dist/types/slash-commands/helpers/mcp.d.ts +0 -3
  1185. package/dist/types/slash-commands/helpers/parse.d.ts +0 -33
  1186. package/dist/types/slash-commands/helpers/ssh.d.ts +0 -3
  1187. package/dist/types/slash-commands/helpers/todo.d.ts +0 -3
  1188. package/dist/types/slash-commands/helpers/usage-report.d.ts +0 -7
  1189. package/dist/types/slash-commands/types.d.ts +0 -120
  1190. package/dist/types/ssh/config-writer.d.ts +0 -49
  1191. package/dist/types/ssh/connection-manager.d.ts +0 -33
  1192. package/dist/types/ssh/ssh-executor.d.ts +0 -37
  1193. package/dist/types/ssh/sshfs-mount.d.ts +0 -6
  1194. package/dist/types/ssh/utils.d.ts +0 -2
  1195. package/dist/types/stt/downloader.d.ts +0 -9
  1196. package/dist/types/stt/index.d.ts +0 -3
  1197. package/dist/types/stt/recorder.d.ts +0 -13
  1198. package/dist/types/stt/setup.d.ts +0 -18
  1199. package/dist/types/stt/stt-controller.d.ts +0 -16
  1200. package/dist/types/stt/transcriber.d.ts +0 -16
  1201. package/dist/types/system-prompt.d.ts +0 -118
  1202. package/dist/types/task/agents.d.ts +0 -28
  1203. package/dist/types/task/commands.d.ts +0 -35
  1204. package/dist/types/task/discovery.d.ts +0 -19
  1205. package/dist/types/task/executor.d.ts +0 -127
  1206. package/dist/types/task/fork-context-advisory.d.ts +0 -13
  1207. package/dist/types/task/fork-context-budget.d.ts +0 -7
  1208. package/dist/types/task/id.d.ts +0 -7
  1209. package/dist/types/task/index.d.ts +0 -43
  1210. package/dist/types/task/name-generator.d.ts +0 -16
  1211. package/dist/types/task/output-manager.d.ts +0 -36
  1212. package/dist/types/task/parallel.d.ts +0 -34
  1213. package/dist/types/task/receipt.d.ts +0 -89
  1214. package/dist/types/task/render.d.ts +0 -28
  1215. package/dist/types/task/roi-reconciliation.d.ts +0 -27
  1216. package/dist/types/task/simple-mode.d.ts +0 -8
  1217. package/dist/types/task/skc-command.d.ts +0 -7
  1218. package/dist/types/task/spawn-gate.d.ts +0 -29
  1219. package/dist/types/task/subprocess-tool-registry.d.ts +0 -72
  1220. package/dist/types/task/token-log.d.ts +0 -30
  1221. package/dist/types/task/token-log.test.d.ts +0 -1
  1222. package/dist/types/task/types.d.ts +0 -516
  1223. package/dist/types/task/worktree.d.ts +0 -94
  1224. package/dist/types/thinking-metadata.d.ts +0 -16
  1225. package/dist/types/thinking.d.ts +0 -22
  1226. package/dist/types/tool-discovery/tool-index.d.ts +0 -112
  1227. package/dist/types/tools/archive-reader.d.ts +0 -40
  1228. package/dist/types/tools/ask-answer-registry.d.ts +0 -18
  1229. package/dist/types/tools/ask.d.ts +0 -123
  1230. package/dist/types/tools/ast-edit.d.ts +0 -77
  1231. package/dist/types/tools/ast-grep.d.ts +0 -69
  1232. package/dist/types/tools/auto-generated-guard.d.ts +0 -17
  1233. package/dist/types/tools/bash-allowed-prefixes.d.ts +0 -10
  1234. package/dist/types/tools/bash-command-fixup.d.ts +0 -11
  1235. package/dist/types/tools/bash-interactive.d.ts +0 -16
  1236. package/dist/types/tools/bash-interceptor.d.ts +0 -24
  1237. package/dist/types/tools/bash-pty-selection.d.ts +0 -7
  1238. package/dist/types/tools/bash-skill-urls.d.ts +0 -31
  1239. package/dist/types/tools/bash.d.ts +0 -157
  1240. package/dist/types/tools/bisect.d.ts +0 -81
  1241. package/dist/types/tools/browser/actions.d.ts +0 -54
  1242. package/dist/types/tools/browser/attach.d.ts +0 -50
  1243. package/dist/types/tools/browser/launch.d.ts +0 -62
  1244. package/dist/types/tools/browser/readable.d.ts +0 -17
  1245. package/dist/types/tools/browser/registry.d.ts +0 -57
  1246. package/dist/types/tools/browser/render.d.ts +0 -53
  1247. package/dist/types/tools/browser/tab-protocol.d.ts +0 -144
  1248. package/dist/types/tools/browser/tab-supervisor.d.ts +0 -109
  1249. package/dist/types/tools/browser/tab-worker-entry.d.ts +0 -1
  1250. package/dist/types/tools/browser/tab-worker.d.ts +0 -19
  1251. package/dist/types/tools/browser.d.ts +0 -211
  1252. package/dist/types/tools/calculator.d.ts +0 -76
  1253. package/dist/types/tools/checkpoint.d.ts +0 -63
  1254. package/dist/types/tools/composer-bash-policy.d.ts +0 -14
  1255. package/dist/types/tools/computer/render.d.ts +0 -17
  1256. package/dist/types/tools/computer-gc.d.ts +0 -23
  1257. package/dist/types/tools/computer.d.ts +0 -465
  1258. package/dist/types/tools/conflict-detect.d.ts +0 -205
  1259. package/dist/types/tools/context.d.ts +0 -19
  1260. package/dist/types/tools/cron.d.ts +0 -91
  1261. package/dist/types/tools/debug.d.ts +0 -209
  1262. package/dist/types/tools/eval.d.ts +0 -108
  1263. package/dist/types/tools/fetch.d.ts +0 -84
  1264. package/dist/types/tools/file-recorder.d.ts +0 -13
  1265. package/dist/types/tools/find.d.ts +0 -95
  1266. package/dist/types/tools/fs-cache-invalidation.d.ts +0 -15
  1267. package/dist/types/tools/gh-format.d.ts +0 -6
  1268. package/dist/types/tools/gh-renderer.d.ts +0 -25
  1269. package/dist/types/tools/gh.d.ts +0 -356
  1270. package/dist/types/tools/github-cache.d.ts +0 -103
  1271. package/dist/types/tools/grouped-file-output.d.ts +0 -36
  1272. package/dist/types/tools/hindsight-recall.d.ts +0 -21
  1273. package/dist/types/tools/hindsight-reflect.d.ts +0 -23
  1274. package/dist/types/tools/hindsight-retain.d.ts +0 -27
  1275. package/dist/types/tools/image-gen.d.ts +0 -79
  1276. package/dist/types/tools/index.d.ts +0 -371
  1277. package/dist/types/tools/irc.d.ts +0 -79
  1278. package/dist/types/tools/job.d.ts +0 -78
  1279. package/dist/types/tools/json-tree.d.ts +0 -23
  1280. package/dist/types/tools/jtd-to-json-schema.d.ts +0 -29
  1281. package/dist/types/tools/jtd-to-typescript.d.ts +0 -26
  1282. package/dist/types/tools/jtd-utils.d.ts +0 -42
  1283. package/dist/types/tools/list-limit.d.ts +0 -12
  1284. package/dist/types/tools/match-line-format.d.ts +0 -11
  1285. package/dist/types/tools/monitor.d.ts +0 -54
  1286. package/dist/types/tools/output-meta.d.ts +0 -204
  1287. package/dist/types/tools/path-utils.d.ts +0 -147
  1288. package/dist/types/tools/plan-mode-guard.d.ts +0 -18
  1289. package/dist/types/tools/read.d.ts +0 -85
  1290. package/dist/types/tools/recipe/index.d.ts +0 -45
  1291. package/dist/types/tools/recipe/render.d.ts +0 -36
  1292. package/dist/types/tools/recipe/runner.d.ts +0 -60
  1293. package/dist/types/tools/recipe/runners/cargo.d.ts +0 -16
  1294. package/dist/types/tools/recipe/runners/index.d.ts +0 -2
  1295. package/dist/types/tools/recipe/runners/just.d.ts +0 -2
  1296. package/dist/types/tools/recipe/runners/make.d.ts +0 -2
  1297. package/dist/types/tools/recipe/runners/pkg.d.ts +0 -2
  1298. package/dist/types/tools/recipe/runners/task.d.ts +0 -2
  1299. package/dist/types/tools/render-mermaid.d.ts +0 -37
  1300. package/dist/types/tools/render-utils.d.ts +0 -158
  1301. package/dist/types/tools/renderers.d.ts +0 -26
  1302. package/dist/types/tools/resolve.d.ts +0 -80
  1303. package/dist/types/tools/resource-gc.d.ts +0 -54
  1304. package/dist/types/tools/review.d.ts +0 -63
  1305. package/dist/types/tools/search-tool-bm25.d.ts +0 -65
  1306. package/dist/types/tools/search.d.ts +0 -93
  1307. package/dist/types/tools/skill-discovery.d.ts +0 -40
  1308. package/dist/types/tools/skill.d.ts +0 -48
  1309. package/dist/types/tools/sqlite-reader.d.ts +0 -94
  1310. package/dist/types/tools/ssh.d.ts +0 -67
  1311. package/dist/types/tools/subagent-render.d.ts +0 -31
  1312. package/dist/types/tools/subagent.d.ts +0 -117
  1313. package/dist/types/tools/telegram-send.d.ts +0 -39
  1314. package/dist/types/tools/todo-write.d.ts +0 -120
  1315. package/dist/types/tools/tool-errors.d.ts +0 -33
  1316. package/dist/types/tools/tool-result.d.ts +0 -30
  1317. package/dist/types/tools/tool-timeouts.d.ts +0 -56
  1318. package/dist/types/tools/ultragoal-ask-guard.d.ts +0 -12
  1319. package/dist/types/tools/vim.d.ts +0 -58
  1320. package/dist/types/tools/write.d.ts +0 -59
  1321. package/dist/types/tools/yield.d.ts +0 -25
  1322. package/dist/types/tui/code-cell.d.ts +0 -32
  1323. package/dist/types/tui/file-list.d.ts +0 -22
  1324. package/dist/types/tui/hyperlink.d.ts +0 -42
  1325. package/dist/types/tui/index.d.ts +0 -11
  1326. package/dist/types/tui/output-block.d.ts +0 -28
  1327. package/dist/types/tui/status-line.d.ts +0 -18
  1328. package/dist/types/tui/tree-list.d.ts +0 -19
  1329. package/dist/types/tui/types.d.ts +0 -13
  1330. package/dist/types/tui/utils.d.ts +0 -36
  1331. package/dist/types/utils/changelog.d.ts +0 -37
  1332. package/dist/types/utils/clipboard.d.ts +0 -22
  1333. package/dist/types/utils/cmux-workspace.d.ts +0 -52
  1334. package/dist/types/utils/command-args.d.ts +0 -9
  1335. package/dist/types/utils/commit-message-generator.d.ts +0 -7
  1336. package/dist/types/utils/edit-mode.d.ts +0 -13
  1337. package/dist/types/utils/event-bus.d.ts +0 -6
  1338. package/dist/types/utils/external-editor.d.ts +0 -19
  1339. package/dist/types/utils/file-display-mode.d.ts +0 -27
  1340. package/dist/types/utils/file-mentions.d.ts +0 -25
  1341. package/dist/types/utils/git.d.ts +0 -393
  1342. package/dist/types/utils/image-loading.d.ts +0 -26
  1343. package/dist/types/utils/image-resize.d.ts +0 -39
  1344. package/dist/types/utils/lang-from-path.d.ts +0 -8
  1345. package/dist/types/utils/linkedom.d.ts +0 -4
  1346. package/dist/types/utils/markit.d.ts +0 -7
  1347. package/dist/types/utils/open.d.ts +0 -2
  1348. package/dist/types/utils/pasted-image-path.d.ts +0 -32
  1349. package/dist/types/utils/session-color.d.ts +0 -10
  1350. package/dist/types/utils/shell-snapshot.d.ts +0 -5
  1351. package/dist/types/utils/sixel.d.ts +0 -21
  1352. package/dist/types/utils/title-generator.d.ts +0 -31
  1353. package/dist/types/utils/tool-choice.d.ts +0 -20
  1354. package/dist/types/utils/tools-manager.d.ts +0 -9
  1355. package/dist/types/vim/buffer.d.ts +0 -41
  1356. package/dist/types/vim/commands.d.ts +0 -6
  1357. package/dist/types/vim/engine.d.ts +0 -47
  1358. package/dist/types/vim/parser.d.ts +0 -3
  1359. package/dist/types/vim/render.d.ts +0 -25
  1360. package/dist/types/vim/types.d.ts +0 -182
  1361. package/dist/types/web/insane/bridge.d.ts +0 -103
  1362. package/dist/types/web/insane/url-guard.d.ts +0 -25
  1363. package/dist/types/web/kagi.d.ts +0 -23
  1364. package/dist/types/web/parallel.d.ts +0 -58
  1365. package/dist/types/web/scrapers/artifacthub.d.ts +0 -6
  1366. package/dist/types/web/scrapers/arxiv.d.ts +0 -5
  1367. package/dist/types/web/scrapers/aur.d.ts +0 -5
  1368. package/dist/types/web/scrapers/biorxiv.d.ts +0 -5
  1369. package/dist/types/web/scrapers/bluesky.d.ts +0 -5
  1370. package/dist/types/web/scrapers/brew.d.ts +0 -5
  1371. package/dist/types/web/scrapers/cheatsh.d.ts +0 -8
  1372. package/dist/types/web/scrapers/chocolatey.d.ts +0 -5
  1373. package/dist/types/web/scrapers/choosealicense.d.ts +0 -2
  1374. package/dist/types/web/scrapers/cisa-kev.d.ts +0 -5
  1375. package/dist/types/web/scrapers/clojars.d.ts +0 -5
  1376. package/dist/types/web/scrapers/coingecko.d.ts +0 -5
  1377. package/dist/types/web/scrapers/crates-io.d.ts +0 -5
  1378. package/dist/types/web/scrapers/crossref.d.ts +0 -2
  1379. package/dist/types/web/scrapers/devto.d.ts +0 -5
  1380. package/dist/types/web/scrapers/discogs.d.ts +0 -8
  1381. package/dist/types/web/scrapers/discourse.d.ts +0 -5
  1382. package/dist/types/web/scrapers/dockerhub.d.ts +0 -5
  1383. package/dist/types/web/scrapers/docs-rs.d.ts +0 -2
  1384. package/dist/types/web/scrapers/fdroid.d.ts +0 -5
  1385. package/dist/types/web/scrapers/firefox-addons.d.ts +0 -2
  1386. package/dist/types/web/scrapers/flathub.d.ts +0 -2
  1387. package/dist/types/web/scrapers/github-gist.d.ts +0 -5
  1388. package/dist/types/web/scrapers/github.d.ts +0 -12
  1389. package/dist/types/web/scrapers/gitlab.d.ts +0 -5
  1390. package/dist/types/web/scrapers/go-pkg.d.ts +0 -5
  1391. package/dist/types/web/scrapers/hackage.d.ts +0 -5
  1392. package/dist/types/web/scrapers/hackernews.d.ts +0 -2
  1393. package/dist/types/web/scrapers/hex.d.ts +0 -5
  1394. package/dist/types/web/scrapers/huggingface.d.ts +0 -2
  1395. package/dist/types/web/scrapers/iacr.d.ts +0 -5
  1396. package/dist/types/web/scrapers/index.d.ts +0 -84
  1397. package/dist/types/web/scrapers/jetbrains-marketplace.d.ts +0 -2
  1398. package/dist/types/web/scrapers/lemmy.d.ts +0 -2
  1399. package/dist/types/web/scrapers/lobsters.d.ts +0 -5
  1400. package/dist/types/web/scrapers/mastodon.d.ts +0 -5
  1401. package/dist/types/web/scrapers/maven.d.ts +0 -6
  1402. package/dist/types/web/scrapers/mdn.d.ts +0 -2
  1403. package/dist/types/web/scrapers/metacpan.d.ts +0 -5
  1404. package/dist/types/web/scrapers/musicbrainz.d.ts +0 -5
  1405. package/dist/types/web/scrapers/npm.d.ts +0 -5
  1406. package/dist/types/web/scrapers/nuget.d.ts +0 -5
  1407. package/dist/types/web/scrapers/nvd.d.ts +0 -5
  1408. package/dist/types/web/scrapers/ollama.d.ts +0 -2
  1409. package/dist/types/web/scrapers/open-vsx.d.ts +0 -5
  1410. package/dist/types/web/scrapers/opencorporates.d.ts +0 -5
  1411. package/dist/types/web/scrapers/openlibrary.d.ts +0 -5
  1412. package/dist/types/web/scrapers/orcid.d.ts +0 -5
  1413. package/dist/types/web/scrapers/osv.d.ts +0 -5
  1414. package/dist/types/web/scrapers/packagist.d.ts +0 -5
  1415. package/dist/types/web/scrapers/pub-dev.d.ts +0 -5
  1416. package/dist/types/web/scrapers/pubmed.d.ts +0 -5
  1417. package/dist/types/web/scrapers/pypi.d.ts +0 -5
  1418. package/dist/types/web/scrapers/rawg.d.ts +0 -2
  1419. package/dist/types/web/scrapers/readthedocs.d.ts +0 -2
  1420. package/dist/types/web/scrapers/reddit.d.ts +0 -5
  1421. package/dist/types/web/scrapers/repology.d.ts +0 -5
  1422. package/dist/types/web/scrapers/rfc.d.ts +0 -5
  1423. package/dist/types/web/scrapers/rubygems.d.ts +0 -5
  1424. package/dist/types/web/scrapers/searchcode.d.ts +0 -2
  1425. package/dist/types/web/scrapers/sec-edgar.d.ts +0 -5
  1426. package/dist/types/web/scrapers/semantic-scholar.d.ts +0 -2
  1427. package/dist/types/web/scrapers/snapcraft.d.ts +0 -2
  1428. package/dist/types/web/scrapers/sourcegraph.d.ts +0 -2
  1429. package/dist/types/web/scrapers/spdx.d.ts +0 -5
  1430. package/dist/types/web/scrapers/spotify.d.ts +0 -8
  1431. package/dist/types/web/scrapers/stackoverflow.d.ts +0 -6
  1432. package/dist/types/web/scrapers/terraform.d.ts +0 -5
  1433. package/dist/types/web/scrapers/tldr.d.ts +0 -7
  1434. package/dist/types/web/scrapers/twitter.d.ts +0 -5
  1435. package/dist/types/web/scrapers/types.d.ts +0 -83
  1436. package/dist/types/web/scrapers/utils.d.ts +0 -32
  1437. package/dist/types/web/scrapers/vimeo.d.ts +0 -5
  1438. package/dist/types/web/scrapers/vscode-marketplace.d.ts +0 -5
  1439. package/dist/types/web/scrapers/w3c.d.ts +0 -2
  1440. package/dist/types/web/scrapers/wikidata.d.ts +0 -5
  1441. package/dist/types/web/scrapers/wikipedia.d.ts +0 -5
  1442. package/dist/types/web/scrapers/youtube.d.ts +0 -13
  1443. package/dist/types/web/search/index.d.ts +0 -118
  1444. package/dist/types/web/search/provider.d.ts +0 -55
  1445. package/dist/types/web/search/providers/anthropic.d.ts +0 -32
  1446. package/dist/types/web/search/providers/base.d.ts +0 -90
  1447. package/dist/types/web/search/providers/brave.d.ts +0 -27
  1448. package/dist/types/web/search/providers/codex.d.ts +0 -35
  1449. package/dist/types/web/search/providers/duckduckgo.d.ts +0 -57
  1450. package/dist/types/web/search/providers/exa.d.ts +0 -52
  1451. package/dist/types/web/search/providers/gemini.d.ts +0 -57
  1452. package/dist/types/web/search/providers/insane.d.ts +0 -53
  1453. package/dist/types/web/search/providers/jina.d.ts +0 -26
  1454. package/dist/types/web/search/providers/kagi.d.ts +0 -24
  1455. package/dist/types/web/search/providers/kimi.d.ts +0 -27
  1456. package/dist/types/web/search/providers/openai-compatible.d.ts +0 -9
  1457. package/dist/types/web/search/providers/parallel.d.ts +0 -15
  1458. package/dist/types/web/search/providers/perplexity.d.ts +0 -38
  1459. package/dist/types/web/search/providers/searxng.d.ts +0 -44
  1460. package/dist/types/web/search/providers/synthetic.d.ts +0 -21
  1461. package/dist/types/web/search/providers/tavily.d.ts +0 -29
  1462. package/dist/types/web/search/providers/text-citations.d.ts +0 -23
  1463. package/dist/types/web/search/providers/utils.d.ts +0 -88
  1464. package/dist/types/web/search/providers/xai.d.ts +0 -64
  1465. package/dist/types/web/search/providers/zai.d.ts +0 -28
  1466. package/dist/types/web/search/render.d.ts +0 -36
  1467. package/dist/types/web/search/types.d.ts +0 -372
  1468. package/dist/types/web/search/utils.d.ts +0 -4
  1469. package/dist/types/workflow/workflow-intent-diff.d.ts +0 -25
  1470. package/dist/types/workflow/workflow-intent-report-consumer.d.ts +0 -50
  1471. package/dist/types/workflow/workflow-intent-report-schema.d.ts +0 -2
  1472. package/dist/types/workflow/workflow-intent-report.d.ts +0 -48
  1473. package/dist/types/workspace-tree.d.ts +0 -42
  1474. package/src/sdk.ts +0 -2623
@@ -7,10 +7,9 @@
7
7
  * const enabled = settings.get("compaction.enabled"); // sync read
8
8
  * settings.set("theme.dark", "red-octopus"); // sync write, saves in background
9
9
  *
10
- * For tests:
10
+ * For tests, `Settings.isolated()` seeds explicit user/global settings:
11
11
  * const isolated = Settings.isolated({ "compaction.enabled": false });
12
12
  */
13
-
14
13
  import * as fs from "node:fs";
15
14
  import * as os from "node:os";
16
15
  import * as path from "node:path";
@@ -30,16 +29,35 @@ import type { ModelRole } from "../config/model-registry";
30
29
  import { loadCapability } from "../discovery";
31
30
  import { type LanguagePref, setLanguage } from "../i18n";
32
31
  import { isLightTheme, setAutoThemeMapping, setColorBlindMode, setSymbolPreset } from "../modes/theme/theme";
32
+ import {
33
+ type NotificationSettingsReader,
34
+ type NotificationSettingsSnapshot,
35
+ parseNotificationSettingsSnapshot,
36
+ } from "../sdk/bus/config";
33
37
  import { AgentStorage } from "../session/agent-storage";
34
38
  import { type EditMode, normalizeEditMode } from "../utils/edit-mode";
35
- import { withFileLock } from "./file-lock";
39
+ import {
40
+ type AtomicYamlPatch,
41
+ applyAtomicYamlPatches,
42
+ applyAtomicYamlPatchesWithCurrent,
43
+ atomicYamlPathHash,
44
+ type CasReceipt,
45
+ deleteByPath,
46
+ reserveAtomicYamlUpdateSlot,
47
+ setByPath,
48
+ } from "./atomic-yaml-patch";
49
+ import { isModelSelectorValue, type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
50
+
36
51
  import {
37
52
  type BashInterceptorRule,
53
+ CONFIG_SCHEMA_VERSION,
38
54
  type GroupPrefix,
39
55
  type GroupTypeMap,
40
56
  getDefault,
57
+ reconcileSettingsSchema,
41
58
  SETTINGS_SCHEMA,
42
59
  type SettingPath,
60
+ type SettingsSchemaReport,
43
61
  type SettingValue,
44
62
  } from "./settings-schema";
45
63
 
@@ -58,10 +76,38 @@ export interface RawSettings {
58
76
 
59
77
  type SettingsPatch = {
60
78
  readonly path: string;
61
- readonly value: unknown;
79
+ readonly value: unknown | undefined;
62
80
  readonly generation: number;
81
+ readonly revision: number;
82
+ readonly modelRole?: string;
83
+ readonly legacyFallbackMigration?: boolean;
84
+ };
85
+
86
+ type PendingSaveSlot = {
87
+ captured: boolean;
88
+ released: boolean;
89
+ release: () => void;
90
+ wait: Promise<void>;
91
+ };
92
+
93
+ type DurableBatchRevision = {
94
+ patch: AtomicYamlPatch;
95
+ previousRevision: number | undefined;
96
+ revision: number;
97
+ };
98
+ type NotificationValidationState = {
99
+ malformedConfigRoot: boolean;
100
+ invalidNotificationConfiguration: boolean;
101
+ generation: number;
102
+ };
103
+ type NotificationValidationRestoreGuard = {
104
+ readonly state: NotificationValidationState;
105
+ restoreGeneration: number | undefined;
63
106
  };
64
107
 
108
+ export type SettingsAtomicPatch = { path: SettingPath; op: "set"; value: unknown } | { path: SettingPath; op: "unset" };
109
+ export type SettingsAtomicReceipt = CasReceipt;
110
+
65
111
  export interface SettingsOptions {
66
112
  /** Current working directory for project settings discovery */
67
113
  cwd?: string;
@@ -73,6 +119,49 @@ export interface SettingsOptions {
73
119
  overrides?: Partial<Record<SettingPath, unknown>>;
74
120
  }
75
121
 
122
+ function summarizeSettingsOptions(options: SettingsOptions | null): {
123
+ optionKeys: string[];
124
+ overrideKeys: string[];
125
+ } {
126
+ if (!options) return { optionKeys: [], overrideKeys: [] };
127
+ return {
128
+ optionKeys: Object.keys(options).sort(),
129
+ overrideKeys: Object.keys(options.overrides ?? {}).sort(),
130
+ };
131
+ }
132
+
133
+ /** Additional layer setup for {@link Settings.isolated}. */
134
+ export interface IsolatedSettingsOptions {
135
+ /** Initial runtime overrides. Notification paths are rejected. */
136
+ overrides?: Partial<Record<SettingPath, unknown>>;
137
+ }
138
+
139
+ /** Raised when an ephemeral override attempts to change global-only notification settings. */
140
+ export class NotificationSettingsOverrideError extends Error {
141
+ constructor(readonly path: SettingPath) {
142
+ super(`Runtime overrides are not allowed for global notification setting ${path}.`);
143
+ this.name = "NotificationSettingsOverrideError";
144
+ }
145
+ }
146
+
147
+ const LOCAL_NOTIFICATION_SETTING_KEYS = new Set(["terminalBell", "bellOnComplete", "bellOnApproval", "bellOnAsk"]);
148
+ const LOCAL_NOTIFICATION_SETTING_PATHS = new Set(
149
+ [...LOCAL_NOTIFICATION_SETTING_KEYS].map(key => `notifications.${key}`),
150
+ );
151
+
152
+ function isNotificationSettingsPath(path: string): boolean {
153
+ return (
154
+ (path === "notifications" || path.startsWith("notifications.")) && !LOCAL_NOTIFICATION_SETTING_PATHS.has(path)
155
+ );
156
+ }
157
+
158
+ function isAtomicSettingsPath(path: string): boolean {
159
+ return (
160
+ Object.hasOwn(SETTINGS_SCHEMA, path) ||
161
+ (path.startsWith("modelRoles.") && path.split(".").every(segment => segment.length > 0))
162
+ );
163
+ }
164
+
76
165
  // ═══════════════════════════════════════════════════════════════════════════
77
166
  // Path Utilities
78
167
  // ═══════════════════════════════════════════════════════════════════════════
@@ -91,22 +180,6 @@ function getByPath(obj: RawSettings, segments: string[]): unknown {
91
180
  return current;
92
181
  }
93
182
 
94
- /**
95
- * Set a nested value in an object by path segments.
96
- * Creates intermediate objects as needed.
97
- */
98
- function setByPath(obj: RawSettings, segments: string[], value: unknown): void {
99
- let current = obj;
100
- for (let i = 0; i < segments.length - 1; i++) {
101
- const segment = segments[i];
102
- if (!(segment in current) || typeof current[segment] !== "object" || current[segment] === null) {
103
- current[segment] = {};
104
- }
105
- current = current[segment] as RawSettings;
106
- }
107
- current[segments[segments.length - 1]] = value;
108
- }
109
-
110
183
  const PATH_SCOPED_ARRAY_SETTINGS = new Set<SettingPath>(["enabledModels", "disabledProviders"]);
111
184
  const LEGACY_THEME_NAME_REPLACEMENTS = {
112
185
  dark: "blue-octopus",
@@ -145,18 +218,45 @@ function stringArrayFromUnknown(value: unknown): string[] {
145
218
  return [];
146
219
  }
147
220
 
148
- function shallowStringRecord(value: unknown): Record<string, string> {
149
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
221
+ function normalizeSessionDirectoryMigration(raw: RawSettings): void {
222
+ const session = rawSettingsRecord(raw.session);
223
+ if (!session) return;
224
+ if (session.directoryMigration !== "copy-retain" && session.directoryMigration !== "disabled") {
225
+ delete session.directoryMigration;
226
+ }
227
+ }
150
228
 
151
- const result: Record<string, string> = {};
152
- for (const [key, item] of Object.entries(value)) {
153
- if (typeof item === "string") {
154
- result[key] = item;
155
- }
229
+ function rawSettingsRecord(value: unknown): RawSettings | undefined {
230
+ if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
231
+ return value as RawSettings;
232
+ }
233
+
234
+ function shallowModelSelectorRecord(value: unknown): Record<string, ModelSelectorValue> {
235
+ const record = rawSettingsRecord(value);
236
+ if (!record) return {};
237
+
238
+ const result: Record<string, ModelSelectorValue> = {};
239
+ for (const [key, item] of Object.entries(record)) {
240
+ if (isModelSelectorValue(item)) result[key] = Array.isArray(item) ? [...item] : item;
156
241
  }
157
242
  return result;
158
243
  }
159
244
 
245
+ function legacyFallbackChains(value: unknown): Record<string, unknown> {
246
+ return value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : {};
247
+ }
248
+
249
+ function hasOwnModelRole(source: RawSettings, role: string): boolean {
250
+ const roles = getByPath(source, ["modelRoles"]);
251
+ return !!roles && typeof roles === "object" && !Array.isArray(roles) && Object.hasOwn(roles, role);
252
+ }
253
+
254
+ function selectorChain(value: unknown): string[] {
255
+ if (typeof value === "string") return normalizeModelSelectorValue(value);
256
+ if (!Array.isArray(value) || !value.every(item => typeof item === "string")) return [];
257
+ return normalizeModelSelectorValue(value);
258
+ }
259
+
160
260
  function resolvePathScopedStringArray(settingPath: SettingPath, value: unknown, cwd: string): string[] | undefined {
161
261
  if (!PATH_SCOPED_ARRAY_SETTINGS.has(settingPath) || !Array.isArray(value)) return undefined;
162
262
 
@@ -195,11 +295,46 @@ function resolvePathScopedStringArray(settingPath: SettingPath, value: unknown,
195
295
  return resolved;
196
296
  }
197
297
 
298
+ function setRawModelRole(
299
+ raw: RawSettings,
300
+ role: string,
301
+ modelId: ModelSelectorValue | undefined,
302
+ removeContainerWhenEmpty = false,
303
+ ): void {
304
+ const roles = { ...rawSettingsRecord(raw.modelRoles) };
305
+ if (modelId === undefined) {
306
+ delete roles[role];
307
+ if (removeContainerWhenEmpty && Object.keys(roles).length === 0) {
308
+ delete raw.modelRoles;
309
+ } else {
310
+ raw.modelRoles = roles;
311
+ }
312
+ return;
313
+ }
314
+ raw.modelRoles = { ...roles, [role]: modelId };
315
+ }
316
+
317
+ function settingsPatchKey(patch: SettingsPatch): string {
318
+ return patch.modelRole ? `modelRoles.${patch.modelRole}` : patch.path;
319
+ }
320
+
321
+ function applySettingsPatch(raw: RawSettings, patch: SettingsPatch): void {
322
+ if (patch.modelRole) {
323
+ setRawModelRole(raw, patch.modelRole, patch.value as ModelSelectorValue | undefined);
324
+ return;
325
+ }
326
+ if (patch.value === undefined) {
327
+ deleteByPath(raw, patch.path.split("."));
328
+ return;
329
+ }
330
+ setByPath(raw, patch.path.split("."), patch.value);
331
+ }
332
+
198
333
  // ═══════════════════════════════════════════════════════════════════════════
199
334
  // Settings Class
200
335
  // ═══════════════════════════════════════════════════════════════════════════
201
336
 
202
- export class Settings {
337
+ export class Settings implements NotificationSettingsReader {
203
338
  #configPath: string | null;
204
339
  #cwd: string;
205
340
  #agentDir: string;
@@ -207,6 +342,13 @@ export class Settings {
207
342
 
208
343
  /** Global settings from config.yml */
209
344
  #global: RawSettings = {};
345
+ /**
346
+ * Raw notification syntax retained across schema reconciliation so notification
347
+ * validation matches the lightweight config reader until each leaf is repaired.
348
+ */
349
+ #rawNotificationConfig: RawSettings | undefined = {};
350
+ /** Raw notification syntax from the last durable config read, before local replay. */
351
+ #durableRawNotificationConfig: RawSettings | undefined = {};
210
352
  /** Project settings from .Anthropic model/settings.yml etc */
211
353
  #project: RawSettings = {};
212
354
  /** Runtime overrides (not persisted) */
@@ -217,11 +359,25 @@ export class Settings {
217
359
  /** Latest dirty patch for each path, owned by its generation. */
218
360
  #modified = new Map<string, SettingsPatch>();
219
361
  #nextGeneration = 0;
220
-
221
- /** Pending save (debounced) */
362
+ #pathRevisions = new Map<string, number>();
363
+ #nextRevision = 0;
364
+ /** Pending debounced ordinary save; its queue slot is reserved immediately. */
222
365
  #saveTimer?: NodeJS.Timeout;
223
- #saveTail: Promise<void> = Promise.resolve();
224
- #globalModelRoleTail: Promise<void> = Promise.resolve();
366
+ #savePromise?: Promise<void>;
367
+ #pendingSaveSlot?: PendingSaveSlot;
368
+
369
+ /** Legacy fallback migration warnings emitted once per settings instance. */
370
+ #legacyFallbackMigrationWarnings = 0;
371
+ #legacyFallbackMigrationGlobalFingerprint: string | undefined;
372
+ #schemaReport: SettingsSchemaReport = { issues: [], valid: true };
373
+ #schemaMigrationPending = false;
374
+ /** A newer config schema must never be rewritten by legacy migrations. */
375
+ #futureSchemaVersion = false;
376
+ #hasMalformedConfigRoot = false;
377
+ #hasInvalidNotificationConfiguration = false;
378
+ #notificationValidationGeneration = 0;
379
+ /** Notification subtree fingerprint from the last raw durable config read. */
380
+ #durableNotificationFingerprint: string | undefined;
225
381
 
226
382
  /** Whether to persist changes */
227
383
  #persist: boolean;
@@ -234,9 +390,11 @@ export class Settings {
234
390
 
235
391
  if (options.overrides) {
236
392
  for (const [key, value] of Object.entries(options.overrides)) {
237
- setByPath(this.#overrides, key.split("."), value);
393
+ if (isNotificationSettingsPath(key)) throw new NotificationSettingsOverrideError(key as SettingPath);
394
+ setByPath(this.#overrides, key.split("."), structuredClone(value));
238
395
  }
239
396
  }
397
+ normalizeSessionDirectoryMigration(this.#overrides);
240
398
  }
241
399
 
242
400
  // ─────────────────────────────────────────────────────────────────────────
@@ -248,8 +406,17 @@ export class Settings {
248
406
  * Call once at startup before accessing `settings`.
249
407
  */
250
408
  static init(options: SettingsOptions = {}): Promise<Settings> {
251
- if (globalInstancePromise) return globalInstancePromise;
409
+ if (globalInstancePromise) {
410
+ if (JSON.stringify(options) !== JSON.stringify(globalInitOptions)) {
411
+ logger.warn("Settings.init called again with different options; reusing existing settings instance", {
412
+ initialOptions: summarizeSettingsOptions(globalInitOptions),
413
+ requestedOptions: summarizeSettingsOptions(options),
414
+ });
415
+ }
416
+ return globalInstancePromise;
417
+ }
252
418
 
419
+ globalInitOptions = structuredClone(options);
253
420
  const instance = new Settings(options);
254
421
  const promise = instance.#load();
255
422
  globalInstancePromise = promise;
@@ -268,12 +435,30 @@ export class Settings {
268
435
  }
269
436
 
270
437
  /**
271
- * Create an isolated instance for testing.
438
+ * Load settings for an explicit workspace without changing the global singleton.
439
+ * Managed-session policy resolution must be bound to the workspace being opened.
440
+ */
441
+ static loadForScope(options: { cwd: string; agentDir?: string }): Promise<Settings> {
442
+ const instance = new Settings(options);
443
+ return instance.#load();
444
+ }
445
+
446
+ /**
447
+ * Create an isolated instance for testing with explicit user/global settings.
272
448
  * Does not affect the global singleton.
273
449
  */
274
- static isolated(overrides: Partial<Record<SettingPath, unknown>> = {}): Settings {
275
- const instance = new Settings({ inMemory: true, overrides });
450
+ static isolated(
451
+ globalSettings: Partial<Record<SettingPath, unknown>> = {},
452
+ options: IsolatedSettingsOptions = {},
453
+ ): Settings {
454
+ const instance = new Settings({ inMemory: true, overrides: options.overrides });
455
+ for (const [key, value] of Object.entries(globalSettings)) {
456
+ setByPath(instance.#global, key.split("."), structuredClone(value));
457
+ }
458
+ normalizeSessionDirectoryMigration(instance.#global);
459
+
276
460
  instance.#rebuildMerged();
461
+ instance.#captureRawNotificationConfig(instance.#global);
277
462
  return instance;
278
463
  }
279
464
 
@@ -317,32 +502,271 @@ export class Settings {
317
502
  return value === undefined ? undefined : (value as SettingValue<P>);
318
503
  }
319
504
 
505
+ /**
506
+ * Read the remote-notification settings from the user/global layer only.
507
+ * Schema defaults are applied per path; project settings and runtime overrides
508
+ * are deliberately excluded from this trust boundary.
509
+ */
510
+ getNotificationSettingsSnapshot(): NotificationSettingsSnapshot {
511
+ return parseNotificationSettingsSnapshot(
512
+ this.#hasMalformedConfigRoot || this.#hasInvalidNotificationConfiguration ? null : this.#global,
513
+ );
514
+ }
515
+
320
516
  /** Check whether a setting is present in loaded settings/overrides rather than coming from schema defaults. */
321
517
  has(path: SettingPath): boolean {
322
518
  return getByPath(this.#merged, path.split(".")) !== undefined;
323
519
  }
324
520
 
521
+ /** Diagnostics from schema reconciliation during the most recent load. */
522
+ getSchemaReport(): SettingsSchemaReport {
523
+ return structuredClone(this.#schemaReport);
524
+ }
525
+
325
526
  /**
326
527
  * Set a setting value (sync).
327
- * Updates global settings and queues a background save.
328
- * Triggers hooks for settings that have side effects.
528
+ * Updates global settings and reserves its background persistence slot before
529
+ * returning, so later durable batches cannot overtake this mutation.
329
530
  */
330
- set<P extends SettingPath>(path: P, value: SettingValue<P>): void {
531
+ set<P extends SettingPath>(path: P, value: SettingValue<P> | undefined): void {
532
+ if (value === undefined) {
533
+ this.unset(path);
534
+ return;
535
+ }
536
+ this.#set(path, value, true);
537
+ }
538
+
539
+ #set<P extends SettingPath>(path: P, value: SettingValue<P>, _defaultModelRoleMayHaveChanged: boolean): void {
331
540
  const prev = this.get(path);
541
+ const clonedValue = structuredClone(value);
332
542
  const patch: SettingsPatch = {
333
543
  path,
334
- value: structuredClone(value),
544
+ value: clonedValue,
335
545
  generation: ++this.#nextGeneration,
546
+ revision: ++this.#nextRevision,
336
547
  };
337
- setByPath(this.#global, path.split("."), structuredClone(patch.value));
548
+ setByPath(this.#global, path.split("."), structuredClone(clonedValue));
549
+ this.#applyNotificationMutationToRaw(path, clonedValue);
550
+ this.#pathRevisions.set(path, patch.revision);
338
551
  this.#modified.set(path, patch);
552
+
339
553
  this.#rebuildMerged();
554
+ this.#revalidateNotificationSettingsAfterMutation([path]);
340
555
  this.#queueSave();
341
556
 
342
- // Trigger hook if exists
343
557
  const hook = SETTING_HOOKS[path];
344
- if (hook) {
345
- hook(value, prev);
558
+ if (hook) hook(value, prev);
559
+ }
560
+
561
+ /**
562
+ * Delete a global setting (sync), rather than serializing an ambiguous YAML
563
+ * `undefined` value. Defaults/project settings become visible immediately.
564
+ */
565
+ unset<P extends SettingPath>(path: P): void {
566
+ const prev = this.get(path);
567
+ const patch: SettingsPatch = {
568
+ path,
569
+ value: undefined,
570
+ generation: ++this.#nextGeneration,
571
+ revision: ++this.#nextRevision,
572
+ };
573
+ deleteByPath(this.#global, path.split("."));
574
+ this.#applyNotificationMutationToRaw(path, undefined);
575
+ this.#pathRevisions.set(path, patch.revision);
576
+ this.#modified.set(path, patch);
577
+ this.#rebuildMerged();
578
+ this.#revalidateNotificationSettingsAfterMutation([path]);
579
+ this.#queueSave();
580
+
581
+ const hook = SETTING_HOOKS[path];
582
+ if (hook) hook(this.get(path), prev);
583
+ }
584
+
585
+ /**
586
+ * Persist a tagged batch as one atomic YAML replacement. Unlike ordinary
587
+ * {@link set}, canonical state and hooks change only after the rename succeeds.
588
+ */
589
+ async commitAtomicBatch(patches: readonly SettingsAtomicPatch[]): Promise<CasReceipt> {
590
+ if (!this.#persist || !this.#configPath) {
591
+ const notificationValidationGuard = this.#notificationValidationRestoreGuard();
592
+ const changes = new Map<string, { before: unknown; beforeHash: string; afterHash: string }>();
593
+ for (const patch of patches) {
594
+ if (!isAtomicSettingsPath(patch.path)) {
595
+ throw new Error(`Unknown setting path for atomic batch: ${patch.path}`);
596
+ }
597
+ if (patch.op === "set" && patch.value === undefined) {
598
+ throw new TypeError(`Settings set patch for ${patch.path} cannot carry undefined; use unset instead.`);
599
+ }
600
+ if (!changes.has(patch.path)) {
601
+ changes.set(patch.path, {
602
+ before: structuredClone(getByPath(this.#global, patch.path.split("."))),
603
+ beforeHash: atomicYamlPathHash(this.#global, patch.path),
604
+ afterHash: "",
605
+ });
606
+ }
607
+ }
608
+ for (const patch of patches) {
609
+ if (patch.op === "set") {
610
+ setByPath(this.#global, patch.path.split("."), structuredClone(patch.value));
611
+ this.#applyNotificationMutationToRaw(patch.path, patch.value);
612
+ } else {
613
+ deleteByPath(this.#global, patch.path.split("."));
614
+ this.#applyNotificationMutationToRaw(patch.path, undefined);
615
+ }
616
+ }
617
+ for (const [patchPath, change] of changes) {
618
+ change.afterHash = atomicYamlPathHash(this.#global, patchPath);
619
+ }
620
+ this.#rebuildMerged();
621
+ this.#revalidateNotificationSettingsAfterMutation(patches.map(patch => patch.path));
622
+ this.#recordNotificationValidationBatchApply(
623
+ notificationValidationGuard,
624
+ patches.map(patch => patch.path),
625
+ );
626
+ let discarded = false;
627
+ let receipt: CasReceipt;
628
+ receipt = {
629
+ revisions: [],
630
+ discard: () => {
631
+ discarded = true;
632
+ },
633
+ restore: async () => {
634
+ if (discarded) return { status: "discarded" } as const;
635
+ const conflicts = [...changes].flatMap(([patchPath, change]) =>
636
+ atomicYamlPathHash(this.#global, patchPath) === change.afterHash ? [] : [patchPath],
637
+ );
638
+ if (conflicts.length > 0) return { status: "conflict", paths: conflicts } as const;
639
+ const restoreNotificationValidationState = this.#canRestoreNotificationValidationState(
640
+ notificationValidationGuard,
641
+ changes.keys(),
642
+ );
643
+ for (const [patchPath, change] of changes) {
644
+ if (change.beforeHash === atomicYamlPathHash({}, patchPath)) {
645
+ deleteByPath(this.#global, patchPath.split("."));
646
+ this.#applyNotificationMutationToRaw(patchPath, undefined);
647
+ } else {
648
+ setByPath(this.#global, patchPath.split("."), structuredClone(change.before));
649
+ this.#applyNotificationMutationToRaw(patchPath, change.before);
650
+ }
651
+ }
652
+ const modelRoles = rawSettingsRecord(this.#global.modelRoles);
653
+ if (changes.has("modelRoles.default") && modelRoles && Object.keys(modelRoles).length === 0) {
654
+ delete this.#global.modelRoles;
655
+ }
656
+ this.#rebuildMerged();
657
+ this.#revalidateNotificationSettingsAfterMutation(changes.keys());
658
+ if (restoreNotificationValidationState) {
659
+ this.#restoreNotificationValidationState(notificationValidationGuard.state);
660
+ }
661
+ return { status: "restored", receipt } as const;
662
+ },
663
+ };
664
+ return receipt;
665
+ }
666
+
667
+ const durablePatches: AtomicYamlPatch[] = patches.map(patch => {
668
+ if (!isAtomicSettingsPath(patch.path)) {
669
+ throw new Error(`Unknown setting path for atomic batch: ${patch.path}`);
670
+ }
671
+ if (patch.op === "unset") return { path: patch.path, op: "unset" };
672
+ if (patch.value === undefined) {
673
+ throw new TypeError(`Settings set patch for ${patch.path} cannot carry undefined; use unset instead.`);
674
+ }
675
+ return { path: patch.path, op: "set", value: structuredClone(patch.value) };
676
+ });
677
+
678
+ // A durable batch is a causal barrier: close the earlier ordinary debounce
679
+ // inside its already-reserved slot before queueing this batch.
680
+ this.#releasePendingSaveSlot();
681
+ const notificationValidationGuard = this.#notificationValidationRestoreGuard();
682
+
683
+ const revisions = durablePatches.map(patch => ({
684
+ patch,
685
+ revision: ++this.#nextRevision,
686
+ previousRevision: this.#pathRevisions.get(patch.path),
687
+ }));
688
+ for (const entry of revisions) this.#pathRevisions.set(entry.patch.path, entry.revision);
689
+
690
+ try {
691
+ const receipt = await applyAtomicYamlPatches(this.#configPath, durablePatches, {
692
+ validateRoot: (root, currentPatches) =>
693
+ this.#rejectAtomicNotificationRepairForMalformedRoot(currentPatches, root),
694
+ onRestored: restoredPatches =>
695
+ this.#applyRestoredDurableBatch(revisions, restoredPatches, notificationValidationGuard),
696
+ });
697
+ const appliedNotificationMutation = this.#applyDurableBatch(revisions);
698
+ this.#recordNotificationValidationBatchApply(notificationValidationGuard, appliedNotificationMutation);
699
+ return receipt;
700
+ } catch (error) {
701
+ for (const entry of revisions) {
702
+ if (this.#pathRevisions.get(entry.patch.path) === entry.revision) {
703
+ if (entry.previousRevision === undefined) this.#pathRevisions.delete(entry.patch.path);
704
+ else this.#pathRevisions.set(entry.patch.path, entry.previousRevision);
705
+ }
706
+ }
707
+ if (this.#modified.size > 0 && !this.#pendingSaveSlot) this.#queueSave();
708
+ throw error;
709
+ }
710
+ }
711
+
712
+ /** Build a durable batch from the current on-disk YAML under the shared queue and file lock. */
713
+ async commitAtomicBatchWithCurrent(
714
+ buildPatches: (
715
+ current: Readonly<RawSettings>,
716
+ ) => Promise<readonly SettingsAtomicPatch[]> | readonly SettingsAtomicPatch[],
717
+ ): Promise<CasReceipt> {
718
+ if (!this.#persist || !this.#configPath) {
719
+ const patches = await buildPatches(structuredClone(this.#global));
720
+ return this.commitAtomicBatch(patches);
721
+ }
722
+
723
+ this.#releasePendingSaveSlot();
724
+ let revisions: DurableBatchRevision[] = [];
725
+ const notificationValidationGuard = this.#notificationValidationRestoreGuard();
726
+ try {
727
+ const receipt = await applyAtomicYamlPatchesWithCurrent(
728
+ this.#configPath,
729
+ async current => {
730
+ const patches = await buildPatches(structuredClone(current));
731
+ const durablePatches: AtomicYamlPatch[] = patches.map(patch => {
732
+ if (!isAtomicSettingsPath(patch.path)) {
733
+ throw new Error(`Unknown setting path for atomic batch: ${patch.path}`);
734
+ }
735
+ if (patch.op === "unset") return { path: patch.path, op: "unset" };
736
+ if (patch.value === undefined) {
737
+ throw new TypeError(
738
+ `Settings set patch for ${patch.path} cannot carry undefined; use unset instead.`,
739
+ );
740
+ }
741
+ return { path: patch.path, op: "set", value: structuredClone(patch.value) };
742
+ });
743
+ revisions = durablePatches.map(patch => ({
744
+ patch,
745
+ revision: ++this.#nextRevision,
746
+ previousRevision: this.#pathRevisions.get(patch.path),
747
+ }));
748
+ for (const entry of revisions) this.#pathRevisions.set(entry.patch.path, entry.revision);
749
+ return durablePatches;
750
+ },
751
+ {
752
+ validateRoot: (root, currentPatches) =>
753
+ this.#rejectAtomicNotificationRepairForMalformedRoot(currentPatches, root),
754
+ onRestored: restoredPatches =>
755
+ this.#applyRestoredDurableBatch(revisions, restoredPatches, notificationValidationGuard),
756
+ },
757
+ );
758
+ const appliedNotificationMutation = this.#applyDurableBatch(revisions);
759
+ this.#recordNotificationValidationBatchApply(notificationValidationGuard, appliedNotificationMutation);
760
+ return receipt;
761
+ } catch (error) {
762
+ for (const entry of revisions) {
763
+ if (this.#pathRevisions.get(entry.patch.path) === entry.revision) {
764
+ if (entry.previousRevision === undefined) this.#pathRevisions.delete(entry.patch.path);
765
+ else this.#pathRevisions.set(entry.patch.path, entry.previousRevision);
766
+ }
767
+ }
768
+ if (this.#modified.size > 0 && !this.#pendingSaveSlot) this.#queueSave();
769
+ throw error;
346
770
  }
347
771
  }
348
772
 
@@ -350,8 +774,9 @@ export class Settings {
350
774
  * Apply runtime overrides (not persisted).
351
775
  */
352
776
  override<P extends SettingPath>(path: P, value: SettingValue<P>): void {
353
- const segments = path.split(".");
354
- setByPath(this.#overrides, segments, value);
777
+ if (isNotificationSettingsPath(path)) throw new NotificationSettingsOverrideError(path);
778
+ const clonedValue = structuredClone(value);
779
+ setByPath(this.#overrides, path.split("."), clonedValue);
355
780
  this.#rebuildMerged();
356
781
  }
357
782
 
@@ -370,45 +795,61 @@ export class Settings {
370
795
  this.#rebuildMerged();
371
796
  }
372
797
 
373
- /**
374
- * Flush any pending saves to disk.
375
- * Call before exit to ensure all changes are persisted.
376
- */
798
+ /** Flush a reserved debounced save without allowing it to be overtaken. */
377
799
  async flush(): Promise<void> {
378
- if (this.#saveTimer) {
379
- clearTimeout(this.#saveTimer);
380
- this.#saveTimer = undefined;
800
+ this.#releasePendingSaveSlot();
801
+ if (this.#modified.size > 0 && !this.#pendingSaveSlot) this.#queueSave();
802
+ this.#releasePendingSaveSlot();
803
+ const observedSave = this.#savePromise;
804
+ try {
805
+ await observedSave;
806
+ } catch {
807
+ // Historical flush() behavior logs background failures but does not reject.
381
808
  }
382
- const save = this.#modified.size > 0 ? this.#saveNow() : this.#saveTail;
383
- await save;
809
+ // A failed predecessor may settle just before a new mutation observes its
810
+ // still-reserved slot. Explicit flush owns one fresh attempt for remaining
811
+ // dirty patches instead of leaving them stranded or retrying forever.
812
+ if (this.#modified.size > 0 && this.#savePromise === observedSave) {
813
+ if (!this.#pendingSaveSlot) this.#queueSave();
814
+ this.#releasePendingSaveSlot();
815
+ try {
816
+ await this.#savePromise;
817
+ } catch {
818
+ // Keep dirty state for a later explicit flush or mutation.
819
+ }
820
+ }
821
+ await this.#refreshDurableSettings();
384
822
  }
385
823
 
386
- /**
387
- * Like {@link flush}, but rejects if the durable save fails instead of
388
- * swallowing the error. Use where the caller must confirm persistence before
389
- * reporting success (e.g. the Telegram `/rich` toggle). In-memory instances
390
- * ({@link isolated}) short-circuit in {@link #saveNow} and never throw.
391
- */
824
+ /** Like {@link flush}, but reports a durable save failure to the caller. */
392
825
  async flushOrThrow(): Promise<void> {
393
- if (this.#saveTimer) {
394
- clearTimeout(this.#saveTimer);
395
- this.#saveTimer = undefined;
396
- }
397
- const save = this.#modified.size > 0 ? this.#saveNow({ throwOnError: true }) : this.#saveTail;
398
- await save;
826
+ this.#releasePendingSaveSlot();
827
+ if (this.#modified.size > 0 && !this.#pendingSaveSlot) this.#queueSave();
828
+ this.#releasePendingSaveSlot();
829
+ await this.#savePromise;
830
+ await this.#refreshDurableSettings();
399
831
  }
400
832
 
401
833
  async cloneForCwd(cwd: string): Promise<Settings> {
834
+ // A clone shares the same config queue. Settle an already-reserved local
835
+ // debounce before the clone can enqueue a durable selector, preventing it
836
+ // from waiting behind a slot only this instance can open.
837
+ await this.flush();
402
838
  const cloned = new Settings({
403
839
  cwd,
404
840
  agentDir: this.#agentDir,
405
841
  inMemory: !this.#persist,
406
842
  });
407
843
  cloned.#storage = this.#storage;
844
+ cloned.#futureSchemaVersion = this.#futureSchemaVersion;
845
+
408
846
  cloned.#global = structuredClone(this.#global);
847
+ cloned.#rawNotificationConfig = structuredClone(this.#rawNotificationConfig);
848
+ cloned.#durableRawNotificationConfig = structuredClone(this.#durableRawNotificationConfig);
849
+ cloned.#durableNotificationFingerprint = this.#durableNotificationFingerprint;
409
850
  cloned.#project = this.#persist ? await cloned.#loadProjectSettings() : structuredClone(this.#project);
410
851
  cloned.#overrides = structuredClone(this.#overrides);
411
- cloned.#rebuildMerged();
852
+ await cloned.#normalizeAfterLoad();
412
853
  cloned.#fireAllHooks();
413
854
  return cloned;
414
855
  }
@@ -484,7 +925,7 @@ export class Settings {
484
925
  /**
485
926
  * Set a model role (helper for modelRoles record).
486
927
  */
487
- setModelRole(role: ModelRole | string, modelId: string): void {
928
+ setModelRole(role: ModelRole | string, modelId: ModelSelectorValue): void {
488
929
  const runtimeOverrides = getByPath(this.#overrides, ["modelRoles"]);
489
930
  const updateRuntimeOverride =
490
931
  !!runtimeOverrides &&
@@ -495,51 +936,51 @@ export class Settings {
495
936
  this.setGlobalModelRole(role, modelId);
496
937
 
497
938
  if (updateRuntimeOverride) {
498
- this.override("modelRoles", { ...shallowStringRecord(runtimeOverrides), [role]: modelId });
939
+ this.override("modelRoles", { ...shallowModelSelectorRecord(runtimeOverrides), [role]: modelId });
499
940
  }
500
941
  }
501
942
 
502
- setGlobalModelRole(role: ModelRole | string, modelId: string | undefined): void {
503
- const current = shallowStringRecord(getByPath(this.#global, ["modelRoles"]));
504
- if (modelId === undefined) {
505
- const { [role]: _removed, ...remaining } = current;
506
- this.set("modelRoles", remaining);
507
- return;
508
- }
509
- this.set("modelRoles", { ...current, [role]: modelId });
943
+ setGlobalModelRole(role: ModelRole | string, modelId: ModelSelectorValue | undefined): void {
944
+ const revision = ++this.#nextRevision;
945
+ const patch: SettingsPatch = {
946
+ path: "modelRoles",
947
+ value: modelId,
948
+ generation: ++this.#nextGeneration,
949
+ revision,
950
+ modelRole: role,
951
+ };
952
+ setRawModelRole(this.#global, role, modelId);
953
+ this.#pathRevisions.set("modelRoles", revision);
954
+ this.#modified.set(settingsPatchKey(patch), patch);
955
+ this.#rebuildMerged();
956
+ this.#queueSave();
510
957
  }
511
958
 
512
- setGlobalModelRoleAndFlush(role: ModelRole | string, modelId: string | undefined): Promise<void> {
513
- const transaction = this.#globalModelRoleTail.then(async () => {
514
- const hadModelRoles = Object.hasOwn(this.#global, "modelRoles");
515
- const previousModelRoles = structuredClone(this.#global.modelRoles);
516
- const previousPatch = this.#modified.get("modelRoles");
517
- this.setGlobalModelRole(role, modelId);
518
- const generation = this.#modified.get("modelRoles")?.generation;
519
- if (this.#saveTimer) {
520
- clearTimeout(this.#saveTimer);
521
- this.#saveTimer = undefined;
522
- }
523
- const save = this.#saveNow({ throwOnError: true });
524
- try {
525
- await save;
526
- } catch (error) {
527
- const currentPatch = this.#modified.get("modelRoles");
528
- if (currentPatch?.generation === generation) {
529
- if (hadModelRoles) this.#global.modelRoles = previousModelRoles;
530
- else delete this.#global.modelRoles;
531
- if (previousPatch) this.#modified.set("modelRoles", previousPatch);
532
- else this.#modified.delete("modelRoles");
533
- this.#rebuildMerged();
534
- }
535
- throw error;
536
- }
959
+ async setGlobalModelRoleAndFlush(
960
+ role: ModelRole | string,
961
+ modelId: ModelSelectorValue | undefined,
962
+ ): Promise<CasReceipt> {
963
+ return this.commitAtomicBatchWithCurrent(current => {
964
+ const roles = rawSettingsRecord(current.modelRoles) ?? {};
965
+ const next = { ...roles };
966
+ if (modelId === undefined) delete next[role];
967
+ else next[role] = modelId;
968
+ return [{ path: "modelRoles", op: "set", value: next }];
537
969
  });
538
- this.#globalModelRoleTail = transaction.then(
539
- () => undefined,
540
- () => undefined,
541
- );
542
- return transaction;
970
+ }
971
+
972
+ async restoreGlobalDefaultModelRoleIfCurrent(commit: CasReceipt): Promise<boolean> {
973
+ return (await commit.restore()).status === "restored";
974
+ }
975
+
976
+ #replaceGlobalWithDurable(current: RawSettings): void {
977
+ this.#global = current;
978
+ for (const patch of this.#pendingPatchesInGenerationOrder()) {
979
+ applySettingsPatch(this.#global, { ...patch, value: structuredClone(patch.value) });
980
+ this.#applyNotificationMutationToRaw(patch.path, patch.value);
981
+ }
982
+ this.#rebuildMerged();
983
+ this.#recomputeNotificationValidationFromRaw();
543
984
  }
544
985
  /**
545
986
  * Set an agent model override while keeping any live runtime override aligned.
@@ -548,8 +989,8 @@ export class Settings {
548
989
  * session. A user-selected role assignment must win immediately in that same
549
990
  * session, but only the explicit agent change should be persisted.
550
991
  */
551
- setAgentModelOverride(agentName: string, modelId: string): void {
552
- const current = shallowStringRecord(getByPath(this.#global, ["task", "agentModelOverrides"]));
992
+ setAgentModelOverride(agentName: string, modelId: ModelSelectorValue): void {
993
+ const current = shallowModelSelectorRecord(getByPath(this.#global, ["task", "agentModelOverrides"]));
553
994
  const runtimeOverrides = getByPath(this.#overrides, ["task", "agentModelOverrides"]);
554
995
  const updateRuntimeOverride =
555
996
  !!runtimeOverrides && typeof runtimeOverrides === "object" && !Array.isArray(runtimeOverrides);
@@ -558,7 +999,7 @@ export class Settings {
558
999
 
559
1000
  if (updateRuntimeOverride) {
560
1001
  this.override("task.agentModelOverrides", {
561
- ...shallowStringRecord(runtimeOverrides),
1002
+ ...shallowModelSelectorRecord(runtimeOverrides),
562
1003
  [agentName]: modelId,
563
1004
  });
564
1005
  }
@@ -567,7 +1008,7 @@ export class Settings {
567
1008
  /**
568
1009
  * Get a model role (helper for modelRoles record).
569
1010
  */
570
- getModelRole(role: ModelRole | string): string | undefined {
1011
+ getModelRole(role: ModelRole | string): ModelSelectorValue | undefined {
571
1012
  const roles = this.get("modelRoles");
572
1013
  return roles[role];
573
1014
  }
@@ -575,19 +1016,17 @@ export class Settings {
575
1016
  /**
576
1017
  * Get all model roles (helper for modelRoles record).
577
1018
  */
578
- getModelRoles(): ReadOnlyDict<string> {
1019
+ getModelRoles(): Readonly<Record<string, ModelSelectorValue>> {
579
1020
  return { ...this.get("modelRoles") };
580
1021
  }
581
1022
 
582
1023
  /*
583
1024
  * Override model roles (helper for modelRoles record).
584
1025
  */
585
- overrideModelRoles(roles: ReadOnlyDict<string>): void {
586
- const next = shallowStringRecord(getByPath(this.#overrides, ["modelRoles"]));
1026
+ overrideModelRoles(roles: Readonly<Record<string, ModelSelectorValue>>): void {
1027
+ const next = shallowModelSelectorRecord(getByPath(this.#overrides, ["modelRoles"]));
587
1028
  for (const [role, modelId] of Object.entries(roles)) {
588
- if (modelId) {
589
- next[role] = modelId;
590
- }
1029
+ if (modelId) next[role] = Array.isArray(modelId) ? [...modelId] : modelId;
591
1030
  }
592
1031
  this.override("modelRoles", next);
593
1032
  }
@@ -611,32 +1050,83 @@ export class Settings {
611
1050
  // #loadYaml then reads; migration's db fallback needs #storage opened.
612
1051
  const projectPromise = this.#loadProjectSettings();
613
1052
 
614
- if (this.#persist) {
615
- this.#storage = await AgentStorage.open(getAgentDbPath(this.#agentDir));
616
- await this.#migrateFromLegacy();
617
- this.#global = await this.#loadYaml(this.#configPath!);
618
- }
1053
+ try {
1054
+ if (this.#persist) {
1055
+ this.#storage = await AgentStorage.open(getAgentDbPath(this.#agentDir));
1056
+ await this.#migrateFromLegacy();
1057
+ this.#global = await this.#loadYaml(this.#configPath!);
1058
+ }
1059
+ if (this.#schemaMigrationPending)
1060
+ this.#recordLegacyFallbackMigrationPatch("configSchemaVersion", CONFIG_SCHEMA_VERSION);
619
1061
 
620
- this.#project = await projectPromise;
1062
+ this.#project = await projectPromise;
621
1063
 
622
- // Build merged view (global → project → overrides; project wins over global)
623
- this.#rebuildMerged();
624
- this.#fireAllHooks();
625
- return this;
1064
+ await this.#normalizeAfterLoad();
1065
+ if (this.#schemaReport.issues.length > 0) {
1066
+ logger.warn("Settings: schema reconciliation found configuration issues", {
1067
+ issues: this.#schemaReport.issues.map(issue => `${issue.kind}:${issue.path}`),
1068
+ });
1069
+ }
1070
+ return this;
1071
+ } catch (error) {
1072
+ this.#storage?.close();
1073
+ throw error;
1074
+ }
626
1075
  }
627
1076
 
628
1077
  async #loadYaml(filePath: string): Promise<RawSettings> {
1078
+ this.#hasMalformedConfigRoot = false;
1079
+ this.#hasInvalidNotificationConfiguration = false;
1080
+ this.#captureRawNotificationConfig({});
629
1081
  try {
630
1082
  const content = await Bun.file(filePath).text();
631
1083
  const parsed = YAML.parse(content);
1084
+ if (parsed === undefined) return {};
632
1085
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1086
+ this.#hasMalformedConfigRoot = true;
1087
+ this.#captureRawNotificationConfig(undefined);
633
1088
  return {};
634
1089
  }
635
- return this.#migrateRawSettings(parsed as RawSettings);
1090
+ const parsedRaw = parsed as RawSettings;
1091
+ if (filePath === this.#configPath) this.#captureRawNotificationConfig(parsedRaw);
1092
+ if (filePath === this.#configPath) {
1093
+ try {
1094
+ parseNotificationSettingsSnapshot(parsedRaw);
1095
+ } catch (error) {
1096
+ if (!(error instanceof Error) || error.message !== "skc_notify_daemon_invalid_configuration")
1097
+ throw error;
1098
+ this.#hasInvalidNotificationConfiguration = true;
1099
+ }
1100
+ }
1101
+ this.#futureSchemaVersion =
1102
+ filePath === this.#configPath &&
1103
+ typeof parsedRaw.configSchemaVersion === "number" &&
1104
+ parsedRaw.configSchemaVersion > CONFIG_SCHEMA_VERSION;
1105
+
1106
+ const configSchemaVersion = parsedRaw.configSchemaVersion;
1107
+ if (
1108
+ filePath === this.#configPath &&
1109
+ (typeof configSchemaVersion !== "number" || configSchemaVersion < CONFIG_SCHEMA_VERSION)
1110
+ ) {
1111
+ this.#schemaMigrationPending = true;
1112
+ }
1113
+ const migrated = this.#migrateRawSettings(parsedRaw);
1114
+ const reconciled = reconcileSettingsSchema(migrated);
1115
+ if (typeof configSchemaVersion === "number" && configSchemaVersion > CONFIG_SCHEMA_VERSION) {
1116
+ reconciled.report.issues.push({
1117
+ path: "configSchemaVersion",
1118
+ kind: "pending-migration",
1119
+ detail: `Configuration requires schema version ${configSchemaVersion}.`,
1120
+ });
1121
+ }
1122
+ this.#schemaReport = reconciled.report;
1123
+ return reconciled.settings;
636
1124
  } catch (error) {
637
- if (isEnoent(error)) return {};
638
- logger.warn("Settings: failed to load", { path: filePath, error: String(error) });
639
- return {};
1125
+ if (isEnoent(error)) {
1126
+ this.#captureRawNotificationConfig({});
1127
+ return {};
1128
+ }
1129
+ throw error;
640
1130
  }
641
1131
  }
642
1132
 
@@ -645,9 +1135,14 @@ export class Settings {
645
1135
  const result = await loadCapability(settingsCapability.id, { cwd: this.#cwd });
646
1136
  let merged: RawSettings = {};
647
1137
  for (const item of result.items as SettingsCapabilityItem[]) {
648
- if (item.level === "project") {
649
- merged = this.#deepMerge(merged, item.data as RawSettings);
1138
+ if (item.level !== "project") continue;
1139
+ const { settings, rejectedNotifications } = this.#stripProjectNotificationSettings(
1140
+ item.data as RawSettings,
1141
+ );
1142
+ if (rejectedNotifications) {
1143
+ logger.warn("Settings: ignoring project notification settings", { path: item.path });
650
1144
  }
1145
+ merged = this.#deepMerge(merged, settings);
651
1146
  }
652
1147
  return this.#migrateRawSettings(merged);
653
1148
  } catch {
@@ -655,6 +1150,150 @@ export class Settings {
655
1150
  }
656
1151
  }
657
1152
 
1153
+ async #normalizeAfterLoad(): Promise<void> {
1154
+ this.#sanitizeModelSelectorRecords();
1155
+ this.#rebuildMerged();
1156
+ if (!this.#futureSchemaVersion) {
1157
+ this.#legacyFallbackMigrationGlobalFingerprint = YAML.stringify(this.#global, null, 2);
1158
+ this.#migrateRetryFallbackChains();
1159
+ if (
1160
+ !this.#modified.has("modelRoles") &&
1161
+ ![...this.#modified.keys()].some(path => path.startsWith("retry.fallback"))
1162
+ ) {
1163
+ this.#legacyFallbackMigrationGlobalFingerprint = undefined;
1164
+ }
1165
+ }
1166
+ await this.flush();
1167
+ this.#sanitizeModelSelectorRecords();
1168
+ this.#rebuildMerged();
1169
+ this.#fireAllHooks();
1170
+ }
1171
+
1172
+ #sanitizeModelSelectorRecords(): void {
1173
+ for (const source of [this.#global, this.#project, this.#overrides]) {
1174
+ for (const pathSegments of [["modelRoles"], ["task", "agentModelOverrides"]]) {
1175
+ const raw = getByPath(source, pathSegments);
1176
+ if (raw === undefined) continue;
1177
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
1178
+ logger.warn("Settings: replaced malformed model selector record", { path: pathSegments.join(".") });
1179
+ setByPath(source, pathSegments, {});
1180
+ continue;
1181
+ }
1182
+ const sanitized = shallowModelSelectorRecord(raw);
1183
+ if (Object.keys(sanitized).length !== Object.keys(raw).length) {
1184
+ logger.warn("Settings: dropped invalid model selector values", {
1185
+ path: pathSegments.join("."),
1186
+ dropped: Object.keys(raw).filter(key => !(key in sanitized)),
1187
+ });
1188
+ }
1189
+ setByPath(source, pathSegments, sanitized);
1190
+ }
1191
+ }
1192
+ }
1193
+
1194
+ #migrateRetryFallbackChains(): void {
1195
+ const globalChains = legacyFallbackChains(getByPath(this.#global, ["retry", "fallbackChains"]));
1196
+ const projectChains = legacyFallbackChains(getByPath(this.#project, ["retry", "fallbackChains"]));
1197
+ const overrideChains = legacyFallbackChains(getByPath(this.#overrides, ["retry", "fallbackChains"]));
1198
+ const roles = new Set([
1199
+ ...Object.keys(globalChains),
1200
+ ...Object.keys(projectChains),
1201
+ ...Object.keys(overrideChains),
1202
+ ]);
1203
+ const retainedGlobalChains: Record<string, unknown> = {};
1204
+ const effectiveRoles = shallowModelSelectorRecord(getByPath(this.#merged, ["modelRoles"]));
1205
+ for (const role of roles) {
1206
+ const source = Object.hasOwn(overrideChains, role)
1207
+ ? "override"
1208
+ : Object.hasOwn(projectChains, role)
1209
+ ? "project"
1210
+ : "global";
1211
+ const tailValue =
1212
+ source === "override"
1213
+ ? overrideChains[role]
1214
+ : source === "project"
1215
+ ? projectChains[role]
1216
+ : globalChains[role];
1217
+ const primary = selectorChain(effectiveRoles[role]);
1218
+ const tail = selectorChain(tailValue);
1219
+ const chain = [...new Set([...primary, ...tail])];
1220
+ if (primary.length === 0 || tail.length === 0) {
1221
+ this.#warnLegacyFallbackMigration(
1222
+ `retry.fallbackChains.${role} could not be migrated because it lacks a valid primary selector or tail.`,
1223
+ );
1224
+ continue;
1225
+ }
1226
+ const target =
1227
+ source === "override" || hasOwnModelRole(this.#overrides, role)
1228
+ ? this.#overrides
1229
+ : source === "project" || hasOwnModelRole(this.#project, role)
1230
+ ? this.#project
1231
+ : this.#global;
1232
+ const targetRoles = shallowModelSelectorRecord(getByPath(target, ["modelRoles"]));
1233
+ setByPath(target, ["modelRoles"], { ...targetRoles, [role]: chain });
1234
+ if (target === this.#global) {
1235
+ this.#recordLegacyFallbackMigrationPatch("modelRoles", getByPath(this.#global, ["modelRoles"]));
1236
+ }
1237
+ if (target !== this.#global && Object.hasOwn(globalChains, role))
1238
+ retainedGlobalChains[role] = globalChains[role];
1239
+ if (source === "project") {
1240
+ this.#warnLegacyFallbackMigration(
1241
+ `retry.fallbackChains.${role} is project-owned and was migrated in memory only.`,
1242
+ );
1243
+ }
1244
+ }
1245
+ for (const source of [this.#project, this.#overrides]) {
1246
+ deleteByPath(source, ["retry", "fallbackChains"]);
1247
+ deleteByPath(source, ["retry", "fallbackRevertPolicy"]);
1248
+ }
1249
+ if (Object.keys(retainedGlobalChains).length > 0) {
1250
+ setByPath(this.#global, ["retry", "fallbackChains"], retainedGlobalChains);
1251
+ this.#recordLegacyFallbackMigrationPatch("retry.fallbackChains", retainedGlobalChains);
1252
+ } else if (getByPath(this.#global, ["retry", "fallbackChains"]) !== undefined) {
1253
+ deleteByPath(this.#global, ["retry", "fallbackChains"]);
1254
+ this.#recordLegacyFallbackMigrationPatch("retry.fallbackChains", undefined);
1255
+ }
1256
+ if (
1257
+ Object.keys(retainedGlobalChains).length === 0 &&
1258
+ getByPath(this.#global, ["retry", "fallbackRevertPolicy"]) !== undefined
1259
+ ) {
1260
+ deleteByPath(this.#global, ["retry", "fallbackRevertPolicy"]);
1261
+ this.#recordLegacyFallbackMigrationPatch("retry.fallbackRevertPolicy", undefined);
1262
+ }
1263
+ if (
1264
+ Object.keys(retainedGlobalChains).length === 0 &&
1265
+ this.#global.retry !== undefined &&
1266
+ Object.keys(rawSettingsRecord(this.#global.retry) ?? {}).length === 0
1267
+ ) {
1268
+ delete this.#global.retry;
1269
+ this.#recordLegacyFallbackMigrationPatch("retry", undefined);
1270
+ }
1271
+ this.#rebuildMerged();
1272
+ }
1273
+
1274
+ #recordLegacyFallbackMigrationPatch(path: string, value: unknown): void {
1275
+ const existing = this.#modified.get(path);
1276
+ if (existing && !existing.legacyFallbackMigration) {
1277
+ this.#modified.set(path, { ...existing, value: structuredClone(value) });
1278
+ return;
1279
+ }
1280
+ const revision = ++this.#nextRevision;
1281
+ this.#pathRevisions.set(path, revision);
1282
+ this.#modified.set(path, {
1283
+ path,
1284
+ value: structuredClone(value),
1285
+ generation: ++this.#nextGeneration,
1286
+ revision,
1287
+ legacyFallbackMigration: true,
1288
+ });
1289
+ }
1290
+
1291
+ #warnLegacyFallbackMigration(message: string): void {
1292
+ if (this.#legacyFallbackMigrationWarnings >= 10) return;
1293
+ this.#legacyFallbackMigrationWarnings++;
1294
+ logger.warn(`Settings: ${message}`);
1295
+ }
1296
+
658
1297
  async #migrateFromLegacy(): Promise<void> {
659
1298
  if (!this.#configPath) return;
660
1299
 
@@ -691,10 +1330,17 @@ export class Settings {
691
1330
  }
692
1331
  } catch {}
693
1332
 
694
- // 3. Write merged settings
1333
+ // 3. Write merged settings through the shared atomic YAML pipeline.
695
1334
  if (migrated && Object.keys(settings).length > 0) {
696
1335
  try {
697
- await Bun.write(this.#configPath, YAML.stringify(settings, null, 2));
1336
+ await applyAtomicYamlPatches(
1337
+ this.#configPath,
1338
+ Object.entries(settings).map(([settingPath, value]) => ({
1339
+ path: settingPath,
1340
+ op: "set" as const,
1341
+ value,
1342
+ })),
1343
+ );
698
1344
  logger.debug("Settings: migrated to config.yml", { path: this.#configPath });
699
1345
  } catch {}
700
1346
  }
@@ -719,20 +1365,23 @@ export class Settings {
719
1365
  return isLightTheme(name, this.#agentDir) ? "light" : "dark";
720
1366
  }
721
1367
 
722
- /** Apply schema migrations to raw settings */
1368
+ /** Apply registered schema migrations once, using configSchemaVersion as the durable marker. */
723
1369
  #migrateRawSettings(raw: RawSettings): RawSettings {
1370
+ const configuredVersion = raw.configSchemaVersion;
1371
+ if (configuredVersion === CONFIG_SCHEMA_VERSION) return raw;
1372
+ if (typeof configuredVersion === "number" && configuredVersion > CONFIG_SCHEMA_VERSION) return raw;
1373
+
1374
+ // Migration registry v0 -> v1.
724
1375
  // queueMode -> steeringMode
1376
+ normalizeSessionDirectoryMigration(raw);
725
1377
  if ("queueMode" in raw && !("steeringMode" in raw)) {
726
1378
  raw.steeringMode = raw.queueMode;
727
1379
  delete raw.queueMode;
728
1380
  }
729
-
730
- // ask.timeout: ms -> seconds (if value > 1000, it's old ms format)
1381
+ // ask.timeout: v0 stored milliseconds; v1 stores seconds.
731
1382
  if (raw.ask && typeof (raw.ask as Record<string, unknown>).timeout === "number") {
732
1383
  const oldValue = (raw.ask as Record<string, unknown>).timeout as number;
733
- if (oldValue > 1000) {
734
- (raw.ask as Record<string, unknown>).timeout = Math.round(oldValue / 1000);
735
- }
1384
+ if (oldValue > 1000) (raw.ask as Record<string, unknown>).timeout = Math.round(oldValue / 1000);
736
1385
  }
737
1386
 
738
1387
  // Migrate old flat "theme" string to nested theme.dark/theme.light
@@ -861,6 +1510,8 @@ export class Settings {
861
1510
  }
862
1511
  }
863
1512
 
1513
+ raw.configSchemaVersion = CONFIG_SCHEMA_VERSION;
1514
+
864
1515
  return raw;
865
1516
  }
866
1517
 
@@ -871,65 +1522,321 @@ export class Settings {
871
1522
  #queueSave(): void {
872
1523
  if (!this.#persist || !this.#configPath) return;
873
1524
 
1525
+ const currentSlot = this.#pendingSaveSlot;
1526
+ if (currentSlot && !currentSlot.captured && !currentSlot.released) {
1527
+ this.#armSaveTimer(currentSlot);
1528
+ return;
1529
+ }
1530
+
1531
+ let release!: () => void;
1532
+ const slot: PendingSaveSlot = {
1533
+ captured: false,
1534
+ released: false,
1535
+ release: () => release(),
1536
+ wait: new Promise<void>(resolve => {
1537
+ release = resolve;
1538
+ }),
1539
+ };
1540
+ this.#pendingSaveSlot = slot;
1541
+
1542
+ let captured: SettingsPatch[] = [];
1543
+ let durableBeforeWrite: RawSettings | undefined;
1544
+ const save = reserveAtomicYamlUpdateSlot(this.#configPath, async () => {
1545
+ await slot.wait;
1546
+ slot.captured = true;
1547
+ if (this.#pendingSaveSlot === slot) this.#pendingSaveSlot = undefined;
1548
+ captured = this.#pendingPatchesInGenerationOrder();
1549
+ return {
1550
+ apply: current => {
1551
+ this.#migrateRawSettings(current);
1552
+ const migrationFingerprint = this.#legacyFallbackMigrationGlobalFingerprint;
1553
+ this.#legacyFallbackMigrationGlobalFingerprint = undefined;
1554
+ if (migrationFingerprint !== undefined && YAML.stringify(current, null, 2) !== migrationFingerprint) {
1555
+ this.#global = structuredClone(current);
1556
+ this.#rebuildMerged();
1557
+ if (getByPath(current, ["retry", "fallbackChains"]) !== undefined) {
1558
+ this.#migrateRetryFallbackChains();
1559
+ captured = this.#pendingPatchesInGenerationOrder();
1560
+ } else {
1561
+ for (const patch of captured) {
1562
+ if (!patch.legacyFallbackMigration) continue;
1563
+ const key = settingsPatchKey(patch);
1564
+ if (this.#modified.get(key)?.generation === patch.generation) this.#modified.delete(key);
1565
+ }
1566
+ captured = captured.filter(patch => !patch.legacyFallbackMigration);
1567
+ }
1568
+ }
1569
+ this.#fenceNotificationValidationForExternalDurableDelta(current, captured);
1570
+ durableBeforeWrite = structuredClone(current);
1571
+ for (const patch of captured) applySettingsPatch(current, patch);
1572
+ return { shouldWrite: captured.length > 0 };
1573
+ },
1574
+ shouldWrite: result => result.shouldWrite,
1575
+ committed: current => {
1576
+ for (const patch of captured) {
1577
+ const key = settingsPatchKey(patch);
1578
+ if (this.#modified.get(key)?.generation === patch.generation) this.#modified.delete(key);
1579
+ }
1580
+ this.#global = current;
1581
+ this.#captureRawNotificationConfig(current);
1582
+ for (const patch of this.#pendingPatchesInGenerationOrder()) {
1583
+ applySettingsPatch(this.#global, { ...patch, value: structuredClone(patch.value) });
1584
+ this.#applyNotificationMutationToRaw(patch.path, patch.value);
1585
+ }
1586
+ this.#rebuildMerged();
1587
+ this.#recomputeNotificationValidationFromRaw();
1588
+ },
1589
+ };
1590
+ }).then(() => undefined);
1591
+ this.#savePromise = save;
1592
+ void save.catch(error => {
1593
+ logger.warn("Settings: background save failed", { error: String(error) });
1594
+ for (const patch of captured) {
1595
+ const key = settingsPatchKey(patch);
1596
+ if (this.#modified.get(key)?.generation === patch.generation) this.#modified.set(key, patch);
1597
+ }
1598
+ if (durableBeforeWrite) {
1599
+ this.#global = durableBeforeWrite;
1600
+ this.#captureRawNotificationConfig(durableBeforeWrite);
1601
+ for (const patch of this.#pendingPatchesInGenerationOrder()) {
1602
+ applySettingsPatch(this.#global, { ...patch, value: structuredClone(patch.value) });
1603
+ this.#applyNotificationMutationToRaw(patch.path, patch.value);
1604
+ }
1605
+ this.#rebuildMerged();
1606
+ this.#recomputeNotificationValidationFromRaw();
1607
+ }
1608
+ });
1609
+ this.#armSaveTimer(slot);
1610
+ }
1611
+
1612
+ #armSaveTimer(slot: PendingSaveSlot): void {
874
1613
  if (this.#saveTimer) clearTimeout(this.#saveTimer);
875
1614
  this.#saveTimer = setTimeout(() => {
876
1615
  this.#saveTimer = undefined;
877
- void this.#saveNow();
1616
+ if (slot.released) return;
1617
+ slot.released = true;
1618
+ slot.release();
878
1619
  }, 100);
879
1620
  }
880
1621
 
881
- async #saveNow(options: { throwOnError?: boolean } = {}): Promise<void> {
882
- if (!this.#persist || !this.#configPath || this.#modified.size === 0) return;
883
-
884
- const configPath = this.#configPath;
885
- const patches = [...this.#modified.values()];
1622
+ #pendingPatchesInGenerationOrder(): SettingsPatch[] {
1623
+ return [...this.#modified.values()].sort((left, right) => left.generation - right.generation);
1624
+ }
1625
+ #releasePendingSaveSlot(): void {
1626
+ if (this.#saveTimer) {
1627
+ clearTimeout(this.#saveTimer);
1628
+ this.#saveTimer = undefined;
1629
+ }
1630
+ const slot = this.#pendingSaveSlot;
1631
+ if (!slot || slot.released) return;
1632
+ slot.released = true;
1633
+ slot.release();
1634
+ }
886
1635
 
887
- const save = this.#saveTail.then(() =>
888
- withFileLock(configPath, async () => {
889
- const current = await this.#loadYaml(configPath);
890
- for (const patch of patches) {
891
- setByPath(current, patch.path.split("."), patch.value);
892
- }
893
- await Bun.write(configPath, YAML.stringify(current, null, 2));
894
- for (const patch of patches) {
895
- if (this.#modified.get(patch.path)?.generation === patch.generation) {
896
- this.#modified.delete(patch.path);
897
- }
898
- }
899
- this.#global = current;
900
- for (const patch of this.#modified.values()) {
901
- setByPath(this.#global, patch.path.split("."), structuredClone(patch.value));
902
- }
903
- }),
1636
+ #applyDurableBatch(revisions: readonly DurableBatchRevision[]): boolean {
1637
+ return this.#applyDurablePatches(
1638
+ revisions,
1639
+ revisions.map(entry => entry.patch),
1640
+ true,
904
1641
  );
905
- this.#saveTail = save.then(
906
- () => undefined,
907
- () => undefined,
1642
+ }
1643
+
1644
+ #applyRestoredDurableBatch(
1645
+ revisions: readonly DurableBatchRevision[],
1646
+ restoredPatches: readonly AtomicYamlPatch[],
1647
+ notificationValidationGuard: NotificationValidationRestoreGuard,
1648
+ ): void {
1649
+ const restoreNotificationValidationState = this.#canRestoreNotificationValidationState(
1650
+ notificationValidationGuard,
1651
+ restoredPatches.map(patch => patch.path),
908
1652
  );
1653
+ if (this.#applyDurablePatches(revisions, restoredPatches, false) && restoreNotificationValidationState) {
1654
+ this.#restoreNotificationValidationState(notificationValidationGuard.state);
1655
+ }
1656
+ }
909
1657
 
910
- try {
911
- await save;
912
- } catch (error) {
913
- logger.warn("Settings: save failed", { error: String(error) });
914
- for (const patch of patches) {
915
- const currentPatch = this.#modified.get(patch.path);
916
- if (currentPatch?.generation === patch.generation) {
917
- this.#modified.set(patch.path, patch);
918
- }
1658
+ #applyDurablePatches(
1659
+ revisions: readonly DurableBatchRevision[],
1660
+ patches: readonly AtomicYamlPatch[],
1661
+ clearStagedMutations: boolean,
1662
+ ): boolean {
1663
+ const revisionsByPath = new Map<string, DurableBatchRevision>();
1664
+ for (const entry of revisions) revisionsByPath.set(entry.patch.path, entry);
1665
+ const finalPatches = new Map<string, AtomicYamlPatch>();
1666
+ for (const patch of patches) finalPatches.set(patch.path, patch);
1667
+ const applicable = [...finalPatches.values()].filter(patch => {
1668
+ const revision = revisionsByPath.get(patch.path);
1669
+ return revision !== undefined && this.#pathRevisions.get(patch.path) === revision.revision;
1670
+ });
1671
+ if (applicable.length === 0) return false;
1672
+
1673
+ const previous = new Map<string, unknown>();
1674
+ for (const patch of applicable) {
1675
+ const settingPath = patch.path;
1676
+ const revision = revisionsByPath.get(patch.path)!;
1677
+ previous.set(settingPath, getByPath(this.#global, settingPath.split(".")));
1678
+ if (patch.op === "set") {
1679
+ setByPath(this.#global, settingPath.split("."), structuredClone(patch.value));
1680
+ this.#applyNotificationMutationToRaw(settingPath, patch.value);
1681
+ } else {
1682
+ deleteByPath(this.#global, settingPath.split("."));
1683
+ this.#applyNotificationMutationToRaw(settingPath, undefined);
919
1684
  }
920
- if (options.throwOnError) {
921
- this.#rebuildMerged();
922
- throw error;
1685
+ if (clearStagedMutations) {
1686
+ for (const [key, staged] of this.#modified) {
1687
+ if (staged.path === settingPath && staged.revision <= revision.revision) {
1688
+ this.#modified.delete(key);
1689
+ }
1690
+ }
923
1691
  }
924
1692
  }
925
-
1693
+ for (const patch of applicable) this.#applyDurableNotificationMutation(patch);
1694
+ const modelRoles = rawSettingsRecord(this.#global.modelRoles);
1695
+ if (
1696
+ applicable.some(patch => patch.path === "modelRoles.default" && patch.op === "unset") &&
1697
+ modelRoles &&
1698
+ Object.keys(modelRoles).length === 0
1699
+ ) {
1700
+ delete this.#global.modelRoles;
1701
+ }
926
1702
  this.#rebuildMerged();
1703
+ this.#revalidateNotificationSettingsAfterMutation(applicable.map(patch => patch.path));
1704
+ for (const patch of applicable) {
1705
+ const settingPath = patch.path as SettingPath;
1706
+ const hook = SETTING_HOOKS[settingPath];
1707
+ if (hook) hook(this.get(settingPath), previous.get(settingPath)!);
1708
+ }
1709
+ return applicable.some(patch => isNotificationSettingsPath(patch.path));
1710
+ }
1711
+
1712
+ async #refreshDurableSettings(): Promise<void> {
1713
+ if (!this.#persist || !this.#configPath) return;
1714
+ const previousFingerprint = this.#durableNotificationFingerprint;
1715
+ const current = await this.#loadYaml(this.#configPath);
1716
+ if (previousFingerprint !== this.#durableNotificationFingerprint) this.#notificationValidationGeneration++;
1717
+ this.#replaceGlobalWithDurable(current);
927
1718
  }
928
1719
 
929
1720
  // ─────────────────────────────────────────────────────────────────────────
930
1721
  // Utilities
931
1722
  // ─────────────────────────────────────────────────────────────────────────
932
1723
 
1724
+ #notificationValidationRestoreGuard(): NotificationValidationRestoreGuard {
1725
+ return {
1726
+ state: this.#notificationValidationState(),
1727
+ restoreGeneration: undefined,
1728
+ };
1729
+ }
1730
+ #notificationValidationState(): NotificationValidationState {
1731
+ return {
1732
+ malformedConfigRoot: this.#hasMalformedConfigRoot,
1733
+ invalidNotificationConfiguration: this.#hasInvalidNotificationConfiguration,
1734
+ generation: this.#notificationValidationGeneration,
1735
+ };
1736
+ }
1737
+ #recordNotificationValidationBatchApply(
1738
+ guard: NotificationValidationRestoreGuard,
1739
+ pathsOrAppliedNotificationMutation: Iterable<string> | boolean,
1740
+ ): void {
1741
+ const appliedNotificationMutation =
1742
+ typeof pathsOrAppliedNotificationMutation === "boolean"
1743
+ ? pathsOrAppliedNotificationMutation
1744
+ : [...pathsOrAppliedNotificationMutation].some(isNotificationSettingsPath);
1745
+ if (appliedNotificationMutation && this.#notificationValidationGeneration === guard.state.generation + 1) {
1746
+ guard.restoreGeneration = this.#notificationValidationGeneration;
1747
+ }
1748
+ }
1749
+ #canRestoreNotificationValidationState(guard: NotificationValidationRestoreGuard, paths: Iterable<string>): boolean {
1750
+ return (
1751
+ [...paths].some(isNotificationSettingsPath) &&
1752
+ guard.restoreGeneration !== undefined &&
1753
+ this.#notificationValidationGeneration === guard.restoreGeneration
1754
+ );
1755
+ }
1756
+ #restoreNotificationValidationState(state: NotificationValidationState): void {
1757
+ this.#hasMalformedConfigRoot = state.malformedConfigRoot;
1758
+ this.#hasInvalidNotificationConfiguration = state.invalidNotificationConfiguration;
1759
+ }
1760
+ #rejectAtomicNotificationRepairForMalformedRoot(patches: readonly AtomicYamlPatch[], root: unknown): void {
1761
+ if (
1762
+ root !== undefined &&
1763
+ !rawSettingsRecord(root) &&
1764
+ patches.some(patch => isNotificationSettingsPath(patch.path))
1765
+ ) {
1766
+ throw new Error("Cannot atomically repair notification settings while config.yml has a malformed root.");
1767
+ }
1768
+ }
1769
+
1770
+ #captureRawNotificationConfig(raw: RawSettings | undefined): void {
1771
+ this.#rawNotificationConfig = raw === undefined ? undefined : structuredClone(raw);
1772
+ this.#durableRawNotificationConfig = raw === undefined ? undefined : structuredClone(raw);
1773
+ this.#durableNotificationFingerprint =
1774
+ raw === undefined ? "malformed-root" : YAML.stringify(getByPath(raw, ["notifications"]), null, 2);
1775
+ }
1776
+ #applyNotificationMutationToRaw(path: string, value: unknown | undefined): void {
1777
+ if (!isNotificationSettingsPath(path)) return;
1778
+ if (!this.#rawNotificationConfig) this.#rawNotificationConfig = {};
1779
+ if (value === undefined) deleteByPath(this.#rawNotificationConfig, path.split("."));
1780
+ else setByPath(this.#rawNotificationConfig, path.split("."), structuredClone(value));
1781
+ }
1782
+ #applyDurableNotificationMutation(patch: AtomicYamlPatch): void {
1783
+ if (!isNotificationSettingsPath(patch.path)) return;
1784
+ if (!this.#durableRawNotificationConfig) this.#durableRawNotificationConfig = {};
1785
+ if (patch.op === "unset") deleteByPath(this.#durableRawNotificationConfig, patch.path.split("."));
1786
+ else setByPath(this.#durableRawNotificationConfig, patch.path.split("."), structuredClone(patch.value));
1787
+ this.#durableNotificationFingerprint = YAML.stringify(
1788
+ getByPath(this.#durableRawNotificationConfig, ["notifications"]),
1789
+ null,
1790
+ 2,
1791
+ );
1792
+ }
1793
+ #fenceNotificationValidationForExternalDurableDelta(current: RawSettings, captured: readonly SettingsPatch[]): void {
1794
+ const expected = structuredClone(this.#durableRawNotificationConfig);
1795
+ for (const patch of captured) {
1796
+ if (!isNotificationSettingsPath(patch.path)) continue;
1797
+ if (!expected) break;
1798
+ if (patch.value === undefined) deleteByPath(expected, patch.path.split("."));
1799
+ else setByPath(expected, patch.path.split("."), structuredClone(patch.value));
1800
+ }
1801
+ const expectedFingerprint =
1802
+ expected === undefined ? "malformed-root" : YAML.stringify(getByPath(expected, ["notifications"]), null, 2);
1803
+ const currentFingerprint = YAML.stringify(getByPath(current, ["notifications"]), null, 2);
1804
+ if (expectedFingerprint !== currentFingerprint) this.#notificationValidationGeneration++;
1805
+ }
1806
+ #recomputeNotificationValidationFromRaw(): void {
1807
+ if (this.#rawNotificationConfig === undefined) {
1808
+ this.#hasMalformedConfigRoot = true;
1809
+ this.#hasInvalidNotificationConfiguration = false;
1810
+ return;
1811
+ }
1812
+ try {
1813
+ parseNotificationSettingsSnapshot(this.#rawNotificationConfig);
1814
+ this.#hasMalformedConfigRoot = false;
1815
+ this.#hasInvalidNotificationConfiguration = false;
1816
+ } catch (error) {
1817
+ if (error instanceof Error && error.message === "skc_notify_daemon_invalid_configuration") {
1818
+ this.#hasMalformedConfigRoot = false;
1819
+ this.#hasInvalidNotificationConfiguration = true;
1820
+ return;
1821
+ }
1822
+ throw error;
1823
+ }
1824
+ }
1825
+ #revalidateNotificationSettingsAfterMutation(paths: Iterable<string>): void {
1826
+ if (![...paths].some(isNotificationSettingsPath)) return;
1827
+ this.#notificationValidationGeneration++;
1828
+ try {
1829
+ parseNotificationSettingsSnapshot(this.#rawNotificationConfig);
1830
+ this.#hasMalformedConfigRoot = false;
1831
+ this.#hasInvalidNotificationConfiguration = false;
1832
+ } catch (error) {
1833
+ if (error instanceof Error && error.message === "skc_notify_daemon_invalid_configuration") {
1834
+ this.#hasInvalidNotificationConfiguration = true;
1835
+ return;
1836
+ }
1837
+ throw error;
1838
+ }
1839
+ }
933
1840
  #rebuildMerged(): void {
934
1841
  this.#merged = this.#deepMerge(this.#deepMerge({}, this.#global), this.#project);
935
1842
  this.#merged = this.#deepMerge(this.#merged, this.#overrides);
@@ -945,6 +1852,34 @@ export class Settings {
945
1852
  }
946
1853
  }
947
1854
 
1855
+ #stripProjectNotificationSettings(settings: RawSettings): {
1856
+ settings: RawSettings;
1857
+ rejectedNotifications: boolean;
1858
+ } {
1859
+ let rejectedNotifications = false;
1860
+ const sanitized: RawSettings = {};
1861
+ for (const [key, value] of Object.entries(settings)) {
1862
+ if (key === "notifications" && value && typeof value === "object" && !Array.isArray(value)) {
1863
+ const localNotifications: Record<string, unknown> = {};
1864
+ for (const [notificationKey, notificationValue] of Object.entries(value)) {
1865
+ if (LOCAL_NOTIFICATION_SETTING_KEYS.has(notificationKey)) {
1866
+ localNotifications[notificationKey] = notificationValue;
1867
+ } else {
1868
+ rejectedNotifications = true;
1869
+ }
1870
+ }
1871
+ if (Object.keys(localNotifications).length > 0) sanitized[key] = localNotifications;
1872
+ continue;
1873
+ }
1874
+ if (isNotificationSettingsPath(key)) {
1875
+ rejectedNotifications = true;
1876
+ continue;
1877
+ }
1878
+ sanitized[key] = value;
1879
+ }
1880
+ return { settings: sanitized, rejectedNotifications };
1881
+ }
1882
+
948
1883
  #deepMerge(base: RawSettings, overrides: RawSettings): RawSettings {
949
1884
  const result = { ...base };
950
1885
  for (const key of Object.keys(overrides)) {
@@ -1038,6 +1973,7 @@ export function onAppendOnlyModeChanged(cb: (value: string) => void): () => void
1038
1973
 
1039
1974
  let globalInstance: Settings | null = null;
1040
1975
  let globalInstancePromise: Promise<Settings> | null = null;
1976
+ let globalInitOptions: SettingsOptions | null = null;
1041
1977
 
1042
1978
  export function isSettingsInitialized(): boolean {
1043
1979
  return globalInstance !== null;
@@ -1048,8 +1984,10 @@ export function isSettingsInitialized(): boolean {
1048
1984
  * @internal
1049
1985
  */
1050
1986
  export function resetSettingsForTest(): void {
1987
+ globalInstance?.getStorage()?.close();
1051
1988
  globalInstance = null;
1052
1989
  globalInstancePromise = null;
1990
+ globalInitOptions = null;
1053
1991
  }
1054
1992
 
1055
1993
  /**