@sayknow-cli/coding-agent 0.3.16 → 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 +127 -110
  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
@@ -0,0 +1,2869 @@
1
+ import * as path from "node:path";
2
+ import {
3
+ Agent,
4
+ type AgentEvent,
5
+ type AgentMessage,
6
+ type AgentTelemetryConfig,
7
+ type AgentTool,
8
+ type AppendOnlyContextManager,
9
+ INTENT_FIELD,
10
+ ThinkingLevel,
11
+ } from "@sayknow-cli/agent-core";
12
+ import {
13
+ type Api,
14
+ type AssistantMessage,
15
+ type AuthCredentialSelector,
16
+ type CredentialDisabledEvent,
17
+ type Message,
18
+ type Model,
19
+ type ProviderSessionState,
20
+ type SimpleStreamOptions,
21
+ streamSimple,
22
+ type ToolResultMessage,
23
+ } from "@sayknow-cli/ai";
24
+ import {
25
+ getOpenAICodexTransportDetails,
26
+ prewarmOpenAICodexResponses,
27
+ } from "@sayknow-cli/ai/providers/openai-codex-responses";
28
+ import type { Component } from "@sayknow-cli/tui";
29
+ import {
30
+ $flag,
31
+ getAgentDbPath,
32
+ getAgentDir,
33
+ getProjectDir,
34
+ logger,
35
+ postmortem,
36
+ prompt,
37
+ Snowflake,
38
+ } from "@sayknow-cli/utils";
39
+ import {
40
+ createAppendOnlyContextManager,
41
+ providerSupportsAppendOnlyAuto,
42
+ resolveAppendOnlyMode,
43
+ } from "../append-only-mode";
44
+ import { type AsyncJob, AsyncJobManager, isBackgroundJobSupportEnabled, jobElapsedMs } from "../async";
45
+ import { loadCapability } from "../capability";
46
+ import { type Rule, ruleCapability, setActiveRules } from "../capability/rule";
47
+ import { kNoAuth, ModelRegistry } from "../config/model-registry";
48
+ import {
49
+ formatModelString,
50
+ defaultModelPerProvider,
51
+ parseModelPattern,
52
+ resolveAllowedModels,
53
+ resolveModelChainWithAuth,
54
+ resolveModelRoleValue,
55
+ type ScopedModelSelection,
56
+ } from "../config/model-resolver";
57
+ import { loadPromptTemplates as loadPromptTemplatesInternal, type PromptTemplate } from "../config/prompt-templates";
58
+ import { Settings, type SkillsSettings } from "../config/settings";
59
+ import { CursorExecHandlers } from "../cursor";
60
+ import type { BashRestrictionProfile } from "../tools/bash-allowed-prefixes";
61
+ import "../discovery";
62
+ import { resolveConfigValue } from "../config/resolve-config-value";
63
+ import { getEmbeddedDefaultSkcSkills } from "../defaults/skc-defaults";
64
+ import { BUNDLED_GROK_BUILD_EXTENSION_ID, getBundledGrokBuildExtensionFactory } from "../defaults/skc-grok-cli";
65
+ import { initializeWithSettings } from "../discovery";
66
+ import { disposeAllVmContexts, disposeVmContextsByOwner } from "../eval/js/context-manager";
67
+ import { disposeAllKernelSessions, disposeKernelSessionsByOwner } from "../eval/py/executor";
68
+ import { TtsrManager } from "../export/ttsr";
69
+ import type { CustomCommandsLoadResult, LoadedCustomCommand } from "../extensibility/custom-commands";
70
+ import type { CustomTool, CustomToolContext, CustomToolSessionEvent } from "../extensibility/custom-tools/types";
71
+ import { CustomToolAdapter } from "../extensibility/custom-tools/wrapper";
72
+ import {
73
+ type ExtensionContext,
74
+ type ExtensionFactory,
75
+ ExtensionRunner,
76
+ ExtensionToolWrapper,
77
+ type ExtensionUIContext,
78
+ type LoadExtensionsResult,
79
+ loadExtensionFromFactory,
80
+ type ToolDefinition,
81
+ wrapRegisteredTools,
82
+ } from "../extensibility/extensions";
83
+ import { ExtensionRuntime } from "../extensibility/extensions/loader";
84
+ import { type ConstrainedPluginHook, loadConstrainedPluginHooks } from "../extensibility/skc-plugins/constrained-hooks";
85
+ import { resolveCurrentPhaseForParent } from "../extensibility/skc-plugins/injection";
86
+ import {
87
+ buildPluginMcpConfigs,
88
+ loadAlwaysOnPluginTools,
89
+ renderAlwaysOnSystemAppendices,
90
+ } from "../extensibility/skc-plugins/runtime-adapters";
91
+ import { loadActiveSubskillTools } from "../extensibility/skc-plugins/tools";
92
+ import { loadSkills, type Skill, type SkillWarning, setActiveSkills } from "../extensibility/skills";
93
+ import type { FileSlashCommand } from "../extensibility/slash-commands";
94
+ import type { HindsightSessionState } from "../hindsight/state";
95
+ import { initializeLocalRoot, LocalProtocolHandler, type LocalProtocolOptions } from "../internal-urls";
96
+ import { resolveMemoryBackend } from "../memory-backend";
97
+ import asyncResultTemplate from "../prompts/tools/async-result.md" with { type: "text" };
98
+ import { AgentRegistry, MAIN_AGENT_ID } from "../registry/agent-registry";
99
+ import { MCPManager } from "../runtime-mcp";
100
+ import { createNotificationsExtension } from "../sdk/bus";
101
+ import {
102
+ getNotificationConfig,
103
+ isNotificationHostEligible,
104
+ type NotificationConfig,
105
+ SPAWN_PROVENANCE_ENV,
106
+ shouldRegisterNotificationsExtension,
107
+ } from "../sdk/bus/config";
108
+ import { NotificationSessionController } from "../sdk/bus/session-control";
109
+ import { shouldHostSdk } from "../sdk/host";
110
+ import {
111
+ collectEnvSecrets,
112
+ createSecretObfuscator,
113
+ deobfuscateSessionContext,
114
+ loadSecrets,
115
+ obfuscateMessages,
116
+ type SecretObfuscator,
117
+ } from "../secrets";
118
+ import { AgentSession, type ForkContextSeed } from "../session/agent-session";
119
+ import { resolveAuthBrokerConfig } from "../session/auth-broker-config";
120
+ import { AuthBrokerClient, AuthStorage, RemoteAuthCredentialStore } from "../session/auth-storage";
121
+ import { type CustomMessage, convertToLlm } from "../session/messages";
122
+ import { createReadonlySessionManager, SessionManager } from "../session/session-manager";
123
+ import { formatNoModelsAvailableFallback } from "../setup/model-onboarding-guidance";
124
+ import { closeAllConnections } from "../ssh/connection-manager";
125
+ import { unmountAll } from "../ssh/sshfs-mount";
126
+ import {
127
+ type BuildSystemPromptResult,
128
+ buildSystemPrompt as buildSystemPromptInternal,
129
+ buildSystemPromptToolMetadata,
130
+ loadProjectContextFiles as loadContextFilesInternal,
131
+ } from "../system-prompt";
132
+ import { AgentOutputManager } from "../task/output-manager";
133
+ import { parseThinkingLevel, resolveThinkingLevelForModel, toReasoningEffort } from "../thinking";
134
+ import { isMCPBridgeTool, selectRestorableDiscoveredBuiltinToolNames } from "../tool-discovery/tool-index";
135
+ import {
136
+ applyConfiguredSearchTimeout,
137
+ BashTool,
138
+ BUILTIN_TOOLS,
139
+ computeEssentialBuiltinNames,
140
+ createTools,
141
+ discoverStartupLspServers,
142
+ EditTool,
143
+ EvalTool,
144
+ FindTool,
145
+ getConfiguredSearchProviderPreference,
146
+ getSearchTools,
147
+ HIDDEN_TOOLS,
148
+ isConfigurableSearchProviderId,
149
+ type LspStartupServerInfo,
150
+ loadSshTool,
151
+ ReadTool,
152
+ ResolveTool,
153
+ SearchTool,
154
+ setPreferredImageProvider,
155
+ setPreferredSearchProvider,
156
+ setSearchFallbackProviders,
157
+ type Tool,
158
+ type ToolSession,
159
+ WebSearchTool,
160
+ WriteTool,
161
+ } from "../tools";
162
+ import { ToolContextStore } from "../tools/context";
163
+ import { getImageGenTools } from "../tools/image-gen";
164
+ import { wrapToolWithMetaNotice } from "../tools/output-meta";
165
+ import { guardToolForUltragoalAsk } from "../tools/ultragoal-ask-guard";
166
+ import { EventBus } from "../utils/event-bus";
167
+ import { buildNamedToolChoice, buildNamedToolChoiceResult } from "../utils/tool-choice";
168
+ import { buildWorkspaceTree, type WorkspaceTree } from "../workspace-tree";
169
+ import {
170
+ attachLifecycleStartupCapability,
171
+ lifecycleStartupCapabilityOption,
172
+ type SdkStartupCapability,
173
+ } from "./startup-capability";
174
+
175
+ type AsyncResultEntry = {
176
+ jobId: string;
177
+ result: string;
178
+ job: AsyncJob | undefined;
179
+ durationMs: number | undefined;
180
+ };
181
+
182
+ type AsyncResultJobDetails = {
183
+ jobId: string;
184
+ type?: "bash" | "task";
185
+ label?: string;
186
+ durationMs?: number;
187
+ };
188
+
189
+ type AsyncResultDetails = {
190
+ jobs: AsyncResultJobDetails[];
191
+ };
192
+
193
+ type McpNotificationEntry = {
194
+ serverName: string;
195
+ uri: string;
196
+ };
197
+
198
+ function buildAsyncResultBatchMessage(entries: AsyncResultEntry[]): CustomMessage<AsyncResultDetails> | null {
199
+ if (entries.length === 0) return null;
200
+ const jobs = entries.map(entry => ({
201
+ jobId: entry.jobId,
202
+ result: entry.result,
203
+ type: entry.job?.type,
204
+ label: entry.job?.label,
205
+ durationMs: entry.durationMs,
206
+ }));
207
+ const details: AsyncResultDetails = {
208
+ jobs: jobs.map(job => ({
209
+ jobId: job.jobId,
210
+ type: job.type,
211
+ label: job.label,
212
+ durationMs: job.durationMs,
213
+ })),
214
+ };
215
+ return {
216
+ role: "custom",
217
+ customType: "async-result",
218
+ content: prompt.render(asyncResultTemplate, {
219
+ multiple: jobs.length > 1,
220
+ jobs,
221
+ }),
222
+ display: true,
223
+ attribution: "agent",
224
+ details,
225
+ timestamp: Date.now(),
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Reconcile a resumed transcript that ends on an unpaired tool call.
231
+ *
232
+ * When a subagent finishes by calling `yield` (or any turn is torn down right
233
+ * after a tool executes), the terminating abort can land before the tool
234
+ * result is persisted, leaving the saved session ending on an assistant
235
+ * `toolCall` with no matching `toolResult`. Replaying that history verbatim on
236
+ * resume produces an invalid provider request (a tool_use not followed by a
237
+ * tool_result) and the resumed turn fails immediately. Synthesize a placeholder
238
+ * result for any such trailing unpaired tool call so a resumed session always
239
+ * starts from a valid, paired history. No-op for well-formed transcripts.
240
+ */
241
+ export function reconcileTrailingToolCalls(messages: AgentMessage[]): AgentMessage[] {
242
+ let lastAssistantIdx = -1;
243
+ for (let i = messages.length - 1; i >= 0; i--) {
244
+ if (messages[i].role === "assistant") {
245
+ lastAssistantIdx = i;
246
+ break;
247
+ }
248
+ }
249
+ if (lastAssistantIdx === -1) return messages;
250
+ const lastAssistant = messages[lastAssistantIdx] as AssistantMessage;
251
+ const toolCalls = lastAssistant.content.filter(
252
+ (part): part is Extract<AssistantMessage["content"][number], { type: "toolCall" }> => part.type === "toolCall",
253
+ );
254
+ if (toolCalls.length === 0) return messages;
255
+ const satisfied = new Set<string>();
256
+ for (let i = lastAssistantIdx + 1; i < messages.length; i++) {
257
+ const message = messages[i];
258
+ if (message.role === "toolResult") satisfied.add(message.toolCallId);
259
+ }
260
+ const missing = toolCalls.filter(toolCall => !satisfied.has(toolCall.id));
261
+ if (missing.length === 0) return messages;
262
+ const now = Date.now();
263
+ const synthesized: ToolResultMessage[] = missing.map(toolCall => ({
264
+ role: "toolResult",
265
+ toolCallId: toolCall.id,
266
+ toolName: toolCall.name,
267
+ content: [
268
+ {
269
+ type: "text",
270
+ text: "Tool result was not persisted before the previous turn ended; synthesized on resume to keep tool_use/tool_result pairing valid.",
271
+ },
272
+ ],
273
+ details: {},
274
+ isError: false,
275
+ timestamp: now,
276
+ }));
277
+ return [...messages, ...synthesized];
278
+ }
279
+
280
+ function buildMcpNotificationBatchMessage(entries: McpNotificationEntry[]): AgentMessage | null {
281
+ const resources: McpNotificationEntry[] = [];
282
+ const seen = new Set<string>();
283
+ for (const entry of entries) {
284
+ const key = `${entry.serverName}\0${entry.uri}`;
285
+ if (seen.has(key)) continue;
286
+ seen.add(key);
287
+ resources.push(entry);
288
+ }
289
+ if (resources.length === 0) return null;
290
+ const lines = [`[MCP notification] ${resources.length} resource(s) updated:`];
291
+ for (const resource of resources) {
292
+ lines.push(`- server="${resource.serverName}" uri=${resource.uri}`);
293
+ }
294
+ lines.push('Use read(path="mcp://<uri>") to inspect if relevant.');
295
+ return {
296
+ role: "user",
297
+ content: [{ type: "text", text: lines.join("\n") }],
298
+ attribution: "agent",
299
+ timestamp: Date.now(),
300
+ };
301
+ }
302
+
303
+ function sanitizeRosterLabel(value: string): string {
304
+ const normalized = value
305
+ .replace(/[\p{Cc}]/gu, " ")
306
+ .replace(/\s+/g, " ")
307
+ .trim();
308
+ return normalized.length > 48 ? `${normalized.slice(0, 47)}…` : normalized;
309
+ }
310
+
311
+ function humanizeAgentTaskId(id: string): string {
312
+ return id
313
+ .replace(/([a-z\d])([A-Z])/g, "$1 $2")
314
+ .replace(/[-_]+/g, " ")
315
+ .trim();
316
+ }
317
+
318
+ function resolveAgentRosterLabel(label: string | undefined, agentId: string, displayName: string): string {
319
+ return (
320
+ sanitizeRosterLabel(label ?? "") ||
321
+ sanitizeRosterLabel(humanizeAgentTaskId(agentId)) ||
322
+ sanitizeRosterLabel(displayName)
323
+ );
324
+ }
325
+ // Types
326
+ export interface CreateAgentSessionOptions {
327
+ /** Working directory for project-local discovery. Default: getProjectDir() */
328
+ cwd?: string;
329
+ /** Global config directory. Default: ~/.skc/agent */
330
+ agentDir?: string;
331
+ /** Spawns to allow. Default: "*" */
332
+ spawns?: string;
333
+
334
+ /** Auth storage for credentials. Default: discoverAuthStorage(agentDir) */
335
+ authStorage?: AuthStorage;
336
+ /** Model registry. Default: discoverModels(authStorage, agentDir) */
337
+ modelRegistry?: ModelRegistry;
338
+
339
+ /** Model to use. Default: from settings, else first available */
340
+ model?: Model;
341
+ /** Raw model pattern string (e.g. from --model CLI flag) to resolve after extensions load.
342
+ * Used when model lookup is deferred because extension-provided models aren't registered yet. */
343
+ modelPattern?: string;
344
+ /** Thinking selector. Default: from settings, else unset */
345
+ thinkingLevel?: ThinkingLevel;
346
+ /** Runtime substitution metadata for the initial model_change session event. */
347
+ modelSubstitution?: { requestedModel: Model; reason: string };
348
+ /** Models available for cycling (Alt+N in interactive mode) */
349
+ scopedModels?: ScopedModelSelection[];
350
+
351
+ /** System prompt blocks. Array replaces default, function receives default blocks and returns final blocks. */
352
+ systemPrompt?: string[] | ((defaultPrompt: string[]) => string[]);
353
+ /** Optional provider-facing session identifier for prompt caches and sticky auth selection.
354
+ * Keeps persisted session files isolated while reusing provider-side caches. */
355
+ providerSessionId?: string;
356
+ /** Runtime credential selector for multi-account auth pools. */
357
+ credentialSelector?: { provider?: string; selector: AuthCredentialSelector; raw: string };
358
+
359
+ /** Custom tools to register (in addition to built-in tools). Accepts both CustomTool and ToolDefinition. */
360
+ customTools?: (CustomTool | ToolDefinition)[];
361
+ /** Explicit parent/phase used to load active SKC sub-skill tools for this session. */
362
+ skcSubskillToolContext?: { parent: string; phase: string; sessionId?: string; cwd?: string };
363
+ /** Inline extensions (merged with discovery). */
364
+ extensions?: ExtensionFactory[];
365
+ /** Additional extension paths to load (merged with discovery). */
366
+ additionalExtensionPaths?: string[];
367
+ /** Disable extension discovery (explicit paths still load). */
368
+ disableExtensionDiscovery?: boolean;
369
+ /**
370
+ * Pre-loaded extensions (skips file discovery).
371
+ * @internal Used by CLI when extensions are loaded early to parse custom flags.
372
+ */
373
+ preloadedExtensions?: LoadExtensionsResult;
374
+
375
+ /** Shared event bus for tool/extension communication. Default: creates new bus. */
376
+ eventBus?: EventBus;
377
+
378
+ /** Skills. Default: bundled SKC defaults, plus filesystem skills when enabled */
379
+ skills?: Skill[];
380
+ /** Rules. Default: discovered from multiple locations */
381
+ rules?: Rule[];
382
+ /** Context files (AGENTS.md content). Default: discovered walking up from cwd */
383
+ contextFiles?: Array<{ path: string; content: string }>;
384
+ /** Pre-built workspace tree (skips re-scanning; passed by parents to subagents). */
385
+ workspaceTree?: WorkspaceTree;
386
+ /** Prompt templates. Default: discovered from cwd/.skc/prompts/ + agentDir/prompts/ */
387
+ promptTemplates?: PromptTemplate[];
388
+ /** File-based slash commands. Default: discovered from commands/ directories */
389
+ slashCommands?: FileSlashCommand[];
390
+
391
+ /** @deprecated MCP runtime discovery is quarantined and ignored. */
392
+ enableMCP?: boolean;
393
+ /** Existing MCP manager to reuse (skips discovery, propagates to toolSession).
394
+ * Mutually exclusive with mcpConfigPath. */
395
+ mcpManager?: MCPManager;
396
+ /** Load MCP tools for a top-level session only from this caller-owned absolute config file path.
397
+ * Mutually exclusive with mcpManager. */
398
+ mcpConfigPath?: string;
399
+
400
+ /** Enable LSP integration (tool, formatting, diagnostics, warmup). Default: true */
401
+ enableLsp?: boolean;
402
+ /** Skip Python kernel availability check and prelude warmup */
403
+ skipPythonPreflight?: boolean;
404
+ /** Tool names explicitly requested (enables disabled-by-default tools) */
405
+ toolNames?: string[];
406
+
407
+ /** Output schema for structured completion (subagents) */
408
+ outputSchema?: unknown;
409
+ /** Whether to include the yield tool by default */
410
+ requireYieldTool?: boolean;
411
+ /** Task recursion depth (for subagent sessions). Default: 0 */
412
+ taskDepth?: number;
413
+ /** Current role-agent type/name for nested task sessions. */
414
+ currentAgentType?: string;
415
+ /** Parent Hindsight state to alias for subagent private memory backend compatibility. */
416
+ parentHindsightSessionState?: HindsightSessionState;
417
+ /** Pre-allocated agent identity for IRC routing. Default: "0-Main" for top-level, parentTaskPrefix-derived for sub. */
418
+ agentId?: string;
419
+ /** Display name for the agent in IRC. Default: "main" or "sub". */
420
+ agentDisplayName?: string;
421
+ /** Compact task label for hidden IRC roster reminders. */
422
+ agentRosterLabel?: string;
423
+ /** Optional restricted bash command prefixes for read-only role agents. */
424
+ bashAllowedPrefixes?: string[];
425
+ /** Restriction policy paired with bashAllowedPrefixes. */
426
+ bashRestrictionProfile?: BashRestrictionProfile;
427
+ /** Optional per-session restriction for goal tool operations. */
428
+ goalToolAllowedOps?: readonly ("create" | "get" | "complete" | "resume" | "drop" | "pause")[];
429
+ /** Optional per-session allowlist for tools exposed through search_tool_bm25. */
430
+ discoverableToolAllowedNames?: readonly string[];
431
+ /** Optional shared agent registry for IRC routing. Default: AgentRegistry.global(). */
432
+ agentRegistry?: AgentRegistry;
433
+ /** Parent task ID prefix for nested artifact naming (e.g., "6-Extensions") */
434
+ parentTaskPrefix?: string;
435
+
436
+ /** Session manager. Default: session stored under the configured agentDir sessions root */
437
+ sessionManager?: SessionManager;
438
+
439
+ /** Override local:// protocol options for subagent local:// sharing. Default: uses the session's own artifacts dir and session ID. */
440
+ localProtocolOptions?: LocalProtocolOptions;
441
+
442
+ /** Settings instance. Default: Settings.init({ cwd, agentDir }) */
443
+ settings?: Settings;
444
+
445
+ /** Whether UI is available (enables interactive tools like ask). Default: false */
446
+ hasUI?: boolean;
447
+ /** Whether this host mode can own a notification session endpoint. Default: true. */
448
+ notificationHostModeSupported?: boolean;
449
+ /** Whether this host mode can own the root SDK endpoint. Default: true. */
450
+ sdkHostModeSupported?: boolean;
451
+ /** Override configured Discord/Slack daemon readiness, primarily for embedded hosts and deterministic tests. */
452
+ ensureNotificationProviderDaemon?: (provider: "discord" | "slack", settings: Settings) => Promise<unknown>;
453
+
454
+ /**
455
+ * Opt-in OpenTelemetry instrumentation forwarded to the underlying Agent.
456
+ * Passing `{}` enables the loop's GenAI-semantic-convention spans. See
457
+ * {@link AgentTelemetryConfig} for the full surface (hooks, content capture,
458
+ * cost estimator, agent identity).
459
+ *
460
+ * Safe to enable without an OTEL SDK registered in the host: the
461
+ * `@opentelemetry/api` package returns a no-op tracer in that case.
462
+ */
463
+ telemetry?: AgentTelemetryConfig;
464
+ /** Optional fork-context seed used to initialize a child session before its first prompt. */
465
+ forkContextSeed?: ForkContextSeed;
466
+ /** Optional provider state override. Fork-context children should omit this by default. */
467
+ providerSessionState?: Map<string, ProviderSessionState>;
468
+ /** Cooperative pause checkpoint passed through to Agent. */
469
+ shouldPause?: () => boolean;
470
+ }
471
+
472
+ /** Result from createAgentSession */
473
+ export interface CreateAgentSessionResult {
474
+ /** The created session */
475
+ session: AgentSession;
476
+ /** Extensions result (loaded extensions + runtime) */
477
+ extensionsResult: LoadExtensionsResult;
478
+ /** Update tool UI context (interactive mode) */
479
+ setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
480
+ /** MCP manager for server lifecycle management (undefined if MCP disabled or an exact tools-only config is session-owned) */
481
+ mcpManager?: MCPManager;
482
+ /** Warning if session was restored with a different model than saved */
483
+ modelFallbackMessage?: string;
484
+ /** LSP servers configured for lazy startup in interactive mode */
485
+ lspServers?: LspStartupServerInfo[];
486
+ /** Shared event bus for tool/extension communication */
487
+ eventBus: EventBus;
488
+ }
489
+
490
+ // Re-exports
491
+
492
+ export type { PromptTemplate } from "../config/prompt-templates";
493
+ export { Settings, type SkillsSettings } from "../config/settings";
494
+ export type { CustomCommand, CustomCommandFactory } from "../extensibility/custom-commands/types";
495
+ export type { CustomTool, CustomToolFactory } from "../extensibility/custom-tools/types";
496
+ export type * from "../extensibility/extensions";
497
+ export type { Skill } from "../extensibility/skills";
498
+ export type { FileSlashCommand } from "../extensibility/slash-commands";
499
+ export type { Tool } from "../tools";
500
+ export { buildDirectoryTree, buildWorkspaceTree, type DirectoryTree, type WorkspaceTree } from "../workspace-tree";
501
+
502
+ export {
503
+ // Individual tool classes (for custom usage)
504
+ BashTool,
505
+ // Tool classes and factories
506
+ BUILTIN_TOOLS,
507
+ createTools,
508
+ EditTool,
509
+ EvalTool,
510
+ FindTool,
511
+ HIDDEN_TOOLS,
512
+ loadSshTool,
513
+ ReadTool,
514
+ ResolveTool,
515
+ SearchTool,
516
+ type ToolSession,
517
+ WebSearchTool,
518
+ WriteTool,
519
+ };
520
+
521
+ // Helper Functions
522
+
523
+ function getDefaultAgentDir(): string {
524
+ return getAgentDir();
525
+ }
526
+
527
+ // Discovery Functions
528
+
529
+ /**
530
+ * Create an AuthStorage instance.
531
+ *
532
+ * Default: local SQLite store at `<agentDir>/agent.db`.
533
+ *
534
+ * Broker mode: when `SKC_AUTH_BROKER_URL` is set, credentials are pulled from
535
+ * a remote auth-broker over the wire. Refresh tokens never leave the broker;
536
+ * the client receives access tokens with `refresh = "__remote__"` and calls
537
+ * back into the broker through the {@link AuthStorageOptions.refreshOAuthCredential}
538
+ * override to re-mint access tokens when needed.
539
+ */
540
+ export async function discoverAuthStorage(agentDir: string = getDefaultAgentDir()): Promise<AuthStorage> {
541
+ const brokerConfig = await resolveAuthBrokerConfig();
542
+ const credentialRankingMode = resolveCredentialRankingMode();
543
+ if (brokerConfig) {
544
+ const client = new AuthBrokerClient({ url: brokerConfig.url, token: brokerConfig.token });
545
+ const initialResult = await client.fetchSnapshot();
546
+ if (initialResult.status !== 200) throw new Error("Auth broker returned no initial snapshot");
547
+ const store = new RemoteAuthCredentialStore({ client, initialSnapshot: initialResult.snapshot });
548
+ // Refresh + usage hooks live on RemoteAuthCredentialStore; AuthStorage
549
+ // discovers them automatically when no explicit option overrides them.
550
+ const storage = new AuthStorage(store, {
551
+ configValueResolver: resolveConfigValue,
552
+ sourceLabel: `broker ${brokerConfig.url}`,
553
+ credentialRankingMode,
554
+ });
555
+ try {
556
+ await storage.reload();
557
+ } catch (error) {
558
+ try {
559
+ storage.close();
560
+ } catch {
561
+ // Preserve the initial reload failure.
562
+ }
563
+ throw error;
564
+ }
565
+ return storage;
566
+ }
567
+ const dbPath = getAgentDbPath(agentDir);
568
+ const storage = await AuthStorage.create(dbPath, {
569
+ configValueResolver: resolveConfigValue,
570
+ sourceLabel: `local ${dbPath}`,
571
+ credentialRankingMode,
572
+ });
573
+ try {
574
+ await storage.reload();
575
+ } catch (error) {
576
+ try {
577
+ storage.close();
578
+ } catch {
579
+ // Preserve the initial reload failure.
580
+ }
581
+ throw error;
582
+ }
583
+ return storage;
584
+ }
585
+
586
+ /**
587
+ * Opt-in multi-account credential ranking mode, read from the
588
+ * `SKC_CREDENTIAL_RANKING_MODE` env var. Unset/unknown → `undefined`, leaving
589
+ * {@link AuthStorage}'s default (`balanced`) untouched. `earliest-reset`
590
+ * switches to earliest-expiry-first selection so soon-to-reset tumbling-window
591
+ * quota is drained before it is lost.
592
+ */
593
+ function resolveCredentialRankingMode(): "balanced" | "earliest-reset" | undefined {
594
+ const raw = process.env.SKC_CREDENTIAL_RANKING_MODE?.trim();
595
+ if (raw === "balanced" || raw === "earliest-reset") return raw;
596
+ return undefined;
597
+ }
598
+
599
+ /**
600
+ * Discover extensions from cwd.
601
+ */
602
+ export async function discoverExtensions(_cwd?: string): Promise<LoadExtensionsResult> {
603
+ return { extensions: [], errors: [], runtime: new ExtensionRuntime() };
604
+ }
605
+
606
+ /**
607
+ * Discover skills from cwd and agentDir.
608
+ */
609
+ export async function discoverSkills(
610
+ _cwd?: string,
611
+ _agentDir?: string,
612
+ _settings?: SkillsSettings,
613
+ ): Promise<{ skills: Skill[]; warnings: SkillWarning[] }> {
614
+ return { skills: [], warnings: [] };
615
+ }
616
+
617
+ /**
618
+ * Discover context files (AGENTS.md) walking up from cwd.
619
+ * Returns files sorted by depth (farther from cwd first, so closer files appear last/more prominent).
620
+ */
621
+ export async function discoverContextFiles(
622
+ cwd?: string,
623
+ _agentDir?: string,
624
+ ): Promise<Array<{ path: string; content: string; depth?: number }>> {
625
+ return await loadContextFilesInternal({
626
+ cwd: cwd ?? getProjectDir(),
627
+ });
628
+ }
629
+
630
+ /**
631
+ * Discover prompt templates from cwd and agentDir.
632
+ */
633
+ export async function discoverPromptTemplates(cwd?: string, agentDir?: string): Promise<PromptTemplate[]> {
634
+ return await loadPromptTemplatesInternal({
635
+ cwd: cwd ?? getProjectDir(),
636
+ agentDir: agentDir ?? getDefaultAgentDir(),
637
+ });
638
+ }
639
+
640
+ /**
641
+ * Discover file-based slash commands from commands/ directories.
642
+ */
643
+ export async function discoverSlashCommands(_cwd?: string): Promise<FileSlashCommand[]> {
644
+ return [];
645
+ }
646
+
647
+ /**
648
+ * Discover custom commands (TypeScript slash commands) from cwd and agentDir.
649
+ */
650
+ export async function discoverCustomTSCommands(_cwd?: string, _agentDir?: string): Promise<CustomCommandsLoadResult> {
651
+ return { commands: [], errors: [] };
652
+ }
653
+
654
+ // API Key Helpers
655
+
656
+ // System Prompt
657
+
658
+ export interface BuildSystemPromptOptions {
659
+ tools?: Tool[];
660
+ skills?: Skill[];
661
+ contextFiles?: Array<{ path: string; content: string }>;
662
+ cwd?: string;
663
+ appendPrompt?: string;
664
+ repeatToolDescriptions?: boolean;
665
+ }
666
+
667
+ /**
668
+ * Build the default provider-facing system prompt blocks.
669
+ *
670
+ * The returned `systemPrompt` preserves the stable harness prompt and dynamic project context
671
+ * as separate entries so providers can cache prompt prefixes without concatenating blocks.
672
+ */
673
+ export async function buildSystemPrompt(options: BuildSystemPromptOptions = {}): Promise<BuildSystemPromptResult> {
674
+ return await buildSystemPromptInternal({
675
+ cwd: options.cwd,
676
+ skills: options.skills,
677
+ contextFiles: options.contextFiles,
678
+ appendSystemPrompt: options.appendPrompt,
679
+ repeatToolDescriptions: options.repeatToolDescriptions,
680
+ });
681
+ }
682
+
683
+ // Internal Helpers
684
+
685
+ function createCustomToolContext(ctx: ExtensionContext): CustomToolContext {
686
+ return {
687
+ sessionManager: ctx.sessionManager,
688
+ modelRegistry: ctx.modelRegistry,
689
+ model: ctx.model,
690
+ isIdle: ctx.isIdle,
691
+ hasQueuedMessages: ctx.hasPendingMessages,
692
+ abort: ctx.abort,
693
+ };
694
+ }
695
+
696
+ function isCustomTool(tool: CustomTool | ToolDefinition): tool is CustomTool {
697
+ // To distinguish, we mark converted tools with a hidden symbol property.
698
+ // If the tool doesn't have this marker, it's a CustomTool that needs conversion.
699
+ return !(tool as any).__isToolDefinition;
700
+ }
701
+
702
+ const TOOL_DEFINITION_MARKER = Symbol("__isToolDefinition");
703
+
704
+ let sshCleanupRegistered = false;
705
+
706
+ async function cleanupSshResources(): Promise<void> {
707
+ const results = await Promise.allSettled([closeAllConnections(), unmountAll()]);
708
+ for (const result of results) {
709
+ if (result.status === "rejected") {
710
+ logger.warn("SSH cleanup failed", { error: String(result.reason) });
711
+ }
712
+ }
713
+ }
714
+
715
+ function registerSshCleanup(): void {
716
+ if (sshCleanupRegistered) return;
717
+ sshCleanupRegistered = true;
718
+ postmortem.register("ssh-cleanup", cleanupSshResources);
719
+ }
720
+
721
+ let pythonCleanupRegistered = false;
722
+
723
+ function registerPythonCleanup(): void {
724
+ if (pythonCleanupRegistered) return;
725
+ pythonCleanupRegistered = true;
726
+ postmortem.register("python-cleanup", disposeAllKernelSessions);
727
+ }
728
+
729
+ let jsVmCleanupRegistered = false;
730
+
731
+ function registerJsVmCleanup(): void {
732
+ if (jsVmCleanupRegistered) return;
733
+ jsVmCleanupRegistered = true;
734
+ postmortem.register("js-vm-cleanup", disposeAllVmContexts);
735
+ }
736
+
737
+ /*
738
+ * Append-only context-mode resolution + manager construction live in
739
+ * ./append-only-mode so the initial build, the runtime model/setting-change
740
+ * path, and the status UI share one implementation. Re-exported for importers/tests.
741
+ */
742
+ export { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode };
743
+
744
+ function customToolToDefinition(tool: CustomTool): ToolDefinition {
745
+ const definition: ToolDefinition & { [TOOL_DEFINITION_MARKER]: true } = {
746
+ name: tool.name,
747
+ label: tool.label,
748
+ description: tool.description,
749
+ parameters: tool.parameters,
750
+ concurrency: tool.concurrency,
751
+ hidden: tool.hidden,
752
+ deferrable: tool.deferrable,
753
+ mcpServerName: tool.mcpServerName,
754
+ mcpToolName: tool.mcpToolName,
755
+ execute: (toolCallId, params, signal, onUpdate, ctx) =>
756
+ tool.execute(toolCallId, params, onUpdate, createCustomToolContext(ctx), signal),
757
+ onSession: tool.onSession ? (event, ctx) => tool.onSession?.(event, createCustomToolContext(ctx)) : undefined,
758
+ renderCall: tool.renderCall,
759
+ renderResult: tool.renderResult
760
+ ? (result, options, theme): Component => {
761
+ const component = tool.renderResult?.(
762
+ result,
763
+ { expanded: options.expanded, isPartial: options.isPartial, spinnerFrame: options.spinnerFrame },
764
+ theme,
765
+ );
766
+ // Return empty component if undefined to match Component type requirement
767
+ return component ?? ({ render: () => [] } as unknown as Component);
768
+ }
769
+ : undefined,
770
+ [TOOL_DEFINITION_MARKER]: true,
771
+ };
772
+ return definition;
773
+ }
774
+
775
+ function createCustomToolsExtension(tools: CustomTool[]): ExtensionFactory {
776
+ return api => {
777
+ for (const tool of tools) {
778
+ api.registerTool(customToolToDefinition(tool));
779
+ }
780
+
781
+ const runOnSession = async (event: CustomToolSessionEvent, ctx: ExtensionContext) => {
782
+ for (const tool of tools) {
783
+ if (!tool.onSession) continue;
784
+ try {
785
+ await tool.onSession(event, createCustomToolContext(ctx));
786
+ } catch (err) {
787
+ logger.warn("Custom tool onSession error", { tool: tool.name, error: String(err) });
788
+ }
789
+ }
790
+ };
791
+
792
+ api.on("session_start", async (_event, ctx) =>
793
+ runOnSession({ reason: "start", previousSessionFile: undefined }, ctx),
794
+ );
795
+ api.on("session_switch", async (event, ctx) =>
796
+ runOnSession({ reason: "switch", previousSessionFile: event.previousSessionFile }, ctx),
797
+ );
798
+ api.on("session_branch", async (event, ctx) =>
799
+ runOnSession({ reason: "branch", previousSessionFile: event.previousSessionFile }, ctx),
800
+ );
801
+ api.on("session_tree", async (_event, ctx) =>
802
+ runOnSession({ reason: "tree", previousSessionFile: undefined }, ctx),
803
+ );
804
+ api.on("session_shutdown", async (_event, ctx) =>
805
+ runOnSession({ reason: "shutdown", previousSessionFile: undefined }, ctx),
806
+ );
807
+ api.on("auto_compaction_start", async (event, ctx) =>
808
+ runOnSession({ reason: "auto_compaction_start", trigger: event.reason, action: event.action }, ctx),
809
+ );
810
+ api.on("auto_compaction_end", async (event, ctx) =>
811
+ runOnSession(
812
+ {
813
+ reason: "auto_compaction_end",
814
+ action: event.action,
815
+ result: event.result,
816
+ aborted: event.aborted,
817
+ willRetry: event.willRetry,
818
+ errorMessage: event.errorMessage,
819
+ },
820
+ ctx,
821
+ ),
822
+ );
823
+ api.on("auto_retry_start", async (event, ctx) =>
824
+ runOnSession(
825
+ {
826
+ reason: "auto_retry_start",
827
+ attempt: event.attempt,
828
+ maxAttempts: event.maxAttempts,
829
+ unbounded: event.unbounded,
830
+ delayMs: event.delayMs,
831
+ errorMessage: event.errorMessage,
832
+ },
833
+ ctx,
834
+ ),
835
+ );
836
+ api.on("auto_retry_end", async (event, ctx) =>
837
+ runOnSession(
838
+ {
839
+ reason: "auto_retry_end",
840
+ success: event.success,
841
+ attempt: event.attempt,
842
+ finalError: event.finalError,
843
+ },
844
+ ctx,
845
+ ),
846
+ );
847
+ api.on("ttsr_triggered", async (event, ctx) =>
848
+ runOnSession({ reason: "ttsr_triggered", rules: event.rules }, ctx),
849
+ );
850
+ api.on("todo_reminder", async (event, ctx) =>
851
+ runOnSession(
852
+ {
853
+ reason: "todo_reminder",
854
+ todos: event.todos,
855
+ attempt: event.attempt,
856
+ maxAttempts: event.maxAttempts,
857
+ },
858
+ ctx,
859
+ ),
860
+ );
861
+ };
862
+ }
863
+
864
+ export function createPluginHooksExtension(hooks: ConstrainedPluginHook[]): ExtensionFactory {
865
+ return api => {
866
+ for (const hook of hooks) {
867
+ // Constrained plugin hooks register exactly their declared event handler
868
+ // through the standard extension API; the loader already denied every
869
+ // session-mutation/command/exec capability at load time. At execution we
870
+ // additionally enforce the declared `target`: a tool-scoped hook only
871
+ // fires for its declared tool, never for arbitrary tool events.
872
+ const target = hook.target;
873
+ const handler = target
874
+ ? (event: { toolName?: string; tool?: { name?: string }; name?: string }, ...rest: unknown[]) => {
875
+ const toolName = event?.toolName ?? event?.tool?.name ?? event?.name;
876
+ if (toolName !== target) return undefined;
877
+ return (hook.handler as (...a: unknown[]) => unknown)(event, ...rest);
878
+ }
879
+ : hook.handler;
880
+ (api.on as (event: string, handler: (...args: unknown[]) => unknown) => void)(hook.event, handler);
881
+ }
882
+ };
883
+ }
884
+
885
+ // Factory
886
+
887
+ /**
888
+ * Build LoadedCustomCommand entries for all MCP prompts across connected servers.
889
+ * These are re-created whenever prompts change (setOnPromptsChanged callback).
890
+ */
891
+ function buildMCPPromptCommands(manager: MCPManager): LoadedCustomCommand[] {
892
+ const commands: LoadedCustomCommand[] = [];
893
+ for (const serverName of manager.getConnectedServers()) {
894
+ const prompts = manager.getServerPrompts(serverName);
895
+ if (!prompts?.length) continue;
896
+ for (const prompt of prompts) {
897
+ const commandName = `${serverName}:${prompt.name}`;
898
+ commands.push({
899
+ path: `mcp:${commandName}`,
900
+ resolvedPath: `mcp:${commandName}`,
901
+ source: "bundled",
902
+ command: {
903
+ name: commandName,
904
+ description: prompt.description ?? `MCP prompt from ${serverName}`,
905
+ async execute(args: string[]) {
906
+ const promptArgs: Record<string, string> = {};
907
+ for (const arg of args) {
908
+ const eqIdx = arg.indexOf("=");
909
+ if (eqIdx > 0) {
910
+ promptArgs[arg.slice(0, eqIdx)] = arg.slice(eqIdx + 1);
911
+ }
912
+ }
913
+ const result = await manager.executePrompt(serverName, prompt.name, promptArgs);
914
+ if (!result) return "";
915
+ const parts: string[] = [];
916
+ for (const msg of result.messages) {
917
+ const contentItems = Array.isArray(msg.content) ? msg.content : [msg.content];
918
+ for (const item of contentItems) {
919
+ if (item.type === "text") {
920
+ parts.push(item.text);
921
+ } else if (item.type === "resource") {
922
+ const resource = item.resource;
923
+ if (resource.text) parts.push(resource.text);
924
+ }
925
+ }
926
+ }
927
+ return parts.join("\n\n");
928
+ },
929
+ },
930
+ });
931
+ }
932
+ }
933
+ return commands;
934
+ }
935
+ /**
936
+ * Create an AgentSession with the specified options.
937
+ *
938
+ * @example
939
+ * ```typescript
940
+ * // Minimal - uses defaults
941
+ * const { session } = await createAgentSession();
942
+ *
943
+ * // With explicit model
944
+ * import { getModel } from '@sayknow-cli/ai';
945
+ * const { session } = await createAgentSession({
946
+ * model: getModel('anthropic', 'Anthropic model-opus-4-5'),
947
+ * thinkingLevel: 'high',
948
+ * });
949
+ *
950
+ * // Continue previous session
951
+ * const { session, modelFallbackMessage } = await createAgentSession({
952
+ * continueSession: true,
953
+ * });
954
+ *
955
+ * // Full control
956
+ * const { session } = await createAgentSession({
957
+ * model: myModel,
958
+ * getApiKey: async () => Bun.env.MY_KEY,
959
+ * systemPrompt: ['You are helpful.'],
960
+ * tools: codingTools({ cwd: getProjectDir() }),
961
+ * skills: [],
962
+ * sessionManager: SessionManager.inMemory(),
963
+ * });
964
+ * ```
965
+ */
966
+
967
+ function withEmbeddedDefaultSkcSkills(skills: Skill[]): Skill[] {
968
+ const byName = new Map(skills.map(skill => [skill.name, skill]));
969
+ for (const defaultSkill of getEmbeddedDefaultSkcSkills()) {
970
+ if (!byName.has(defaultSkill.name)) {
971
+ byName.set(defaultSkill.name, defaultSkill);
972
+ }
973
+ }
974
+ return [...byName.values()];
975
+ }
976
+
977
+ export function resolveIntentTracingEnabled(intentTracingSetting: boolean | undefined, hasUI: boolean): boolean {
978
+ return (!!intentTracingSetting || $flag("PI_INTENT_TRACING")) && hasUI;
979
+ }
980
+
981
+ const MCP_CONFIG_PATH_AND_MANAGER_ERROR = "mcpConfigPath and mcpManager are mutually exclusive";
982
+ const MCP_CONFIG_PATH_ABSOLUTE_ERROR = "mcpConfigPath requires an absolute path";
983
+ const MCP_TOOLS_ONLY_MANAGER_SUBSESSION_ERROR = "tools-only MCP managers cannot be reused in sub-sessions";
984
+ const MCP_CONFIG_PATH_SUBSESSION_ERROR = "mcpConfigPath cannot be used in sub-sessions";
985
+ const MAX_EXACT_MCP_TOOL_COLLISION_NAMES = 10;
986
+ const MAX_EXACT_MCP_TOOL_NAME_LENGTH = 100;
987
+ const pluginMcpManagerServers = new WeakMap<MCPManager, ReadonlySet<string>>();
988
+
989
+ class ExactMcpToolNameCollisionError extends Error {
990
+ constructor(toolNames: Iterable<string>) {
991
+ const names = [...new Set(toolNames)]
992
+ .sort()
993
+ .slice(0, MAX_EXACT_MCP_TOOL_COLLISION_NAMES)
994
+ .map(name => name.slice(0, MAX_EXACT_MCP_TOOL_NAME_LENGTH));
995
+ super(`Exact MCP tool name collision: ${names.join(", ")}`);
996
+ }
997
+ }
998
+
999
+ function findExactMcpToolNameCollisions(
1000
+ exactMcpToolNames: readonly string[],
1001
+ catalogToolNames: Iterable<string>,
1002
+ ): string[] {
1003
+ const exactMcpToolNameCounts = new Map<string, number>();
1004
+ for (const toolName of exactMcpToolNames) {
1005
+ exactMcpToolNameCounts.set(toolName, (exactMcpToolNameCounts.get(toolName) ?? 0) + 1);
1006
+ }
1007
+ const catalogToolNameCounts = new Map<string, number>();
1008
+ for (const toolName of catalogToolNames) {
1009
+ catalogToolNameCounts.set(toolName, (catalogToolNameCounts.get(toolName) ?? 0) + 1);
1010
+ }
1011
+ const collisions: string[] = [];
1012
+ for (const [toolName, exactMcpToolNameCount] of exactMcpToolNameCounts) {
1013
+ if (exactMcpToolNameCount > 1 || (catalogToolNameCounts.get(toolName) ?? 0) > 1) {
1014
+ collisions.push(toolName);
1015
+ }
1016
+ }
1017
+ return collisions;
1018
+ }
1019
+
1020
+ export async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {
1021
+ const lifecycleStartupCapability = (
1022
+ options as CreateAgentSessionOptions & { [lifecycleStartupCapabilityOption]?: SdkStartupCapability }
1023
+ )[lifecycleStartupCapabilityOption];
1024
+ const isCanonicalSubSession =
1025
+ (options.taskDepth ?? 0) > 0 || Boolean(options.parentTaskPrefix) || Boolean(options.currentAgentType);
1026
+ if (isCanonicalSubSession && options.mcpConfigPath !== undefined) {
1027
+ throw new Error(MCP_CONFIG_PATH_SUBSESSION_ERROR);
1028
+ }
1029
+ if (options.mcpConfigPath !== undefined && options.mcpManager !== undefined) {
1030
+ throw new Error(MCP_CONFIG_PATH_AND_MANAGER_ERROR);
1031
+ }
1032
+ if (options.mcpConfigPath !== undefined && !path.isAbsolute(options.mcpConfigPath)) {
1033
+ throw new Error(MCP_CONFIG_PATH_ABSOLUTE_ERROR);
1034
+ }
1035
+ if (isCanonicalSubSession && options.mcpManager?.isToolsOnly()) {
1036
+ throw new Error(MCP_TOOLS_ONLY_MANAGER_SUBSESSION_ERROR);
1037
+ }
1038
+ const cwd = options.cwd ?? getProjectDir();
1039
+ const agentDir = options.agentDir ?? getDefaultAgentDir();
1040
+ const eventBus = options.eventBus ?? new EventBus();
1041
+
1042
+ registerSshCleanup();
1043
+ registerPythonCleanup();
1044
+ registerJsVmCleanup();
1045
+
1046
+ // Pin authStorage to modelRegistry.authStorage: ModelRegistry.getApiKey() routes refresh
1047
+ // failures through that instance, so any divergent storage handed to the bridge / mcpManager
1048
+ // / session would silently miss credential_disabled events.
1049
+ const ownsAuthStorage = options.modelRegistry === undefined && options.authStorage === undefined;
1050
+ const modelRegistry =
1051
+ options.modelRegistry ??
1052
+ new ModelRegistry(options.authStorage ?? (await logger.time("discoverModels", discoverAuthStorage, agentDir)));
1053
+ const authStorage = modelRegistry.authStorage;
1054
+ if (options.authStorage && options.authStorage !== authStorage) {
1055
+ throw new Error(
1056
+ "options.authStorage and options.modelRegistry.authStorage must be the same instance when both are provided",
1057
+ );
1058
+ }
1059
+ let agent: Agent;
1060
+ let session!: AgentSession;
1061
+ let hasSession = false;
1062
+ let hasRegistered = false;
1063
+ let cleanupOwnedMcpManager: (() => Promise<void>) | undefined;
1064
+ const agentRegistry = options.agentRegistry ?? AgentRegistry.global();
1065
+ const resolvedAgentId = options.agentId ?? options.parentTaskPrefix ?? MAIN_AGENT_ID;
1066
+ const resolvedAgentDisplayName = options.agentDisplayName ?? (isCanonicalSubSession ? "sub" : "main");
1067
+ const resolvedAgentRosterLabel = resolveAgentRosterLabel(
1068
+ options.agentRosterLabel,
1069
+ resolvedAgentId,
1070
+ resolvedAgentDisplayName,
1071
+ );
1072
+ const evalKernelOwnerId = `agent-session:${Snowflake.next()}`;
1073
+ let disposeLocalProtocolOverride: (() => void) | undefined;
1074
+ let localProtocolOverrideReleased = false;
1075
+ const releaseLocalProtocolOverride = (): void => {
1076
+ if (localProtocolOverrideReleased) return;
1077
+ localProtocolOverrideReleased = true;
1078
+ disposeLocalProtocolOverride?.();
1079
+ };
1080
+ const enableLsp = options.enableLsp ?? true;
1081
+ let authStorageClosed = false;
1082
+ const closeOwnedAuthStorage = (): void => {
1083
+ if (!ownsAuthStorage || authStorageClosed) return;
1084
+ authStorageClosed = true;
1085
+ authStorage.close();
1086
+ };
1087
+ let unsubscribeCredentialDisabled: (() => void) | undefined;
1088
+ const releaseCredentialDisabledSubscription = (): void => {
1089
+ const unsubscribe = unsubscribeCredentialDisabled;
1090
+ unsubscribeCredentialDisabled = undefined;
1091
+ unsubscribe?.();
1092
+ };
1093
+
1094
+ try {
1095
+ // Subscribe before any getApiKey() call so startup model probes can't fire a
1096
+ // credential_disabled event past us. An embedder's constructor handler makes the
1097
+ // listener set non-empty from construction, which defeats AuthStorage's no-listener
1098
+ // buffer — so we can't rely on it to catch startup events for the extension runner.
1099
+ const startupCredentialDisabledEvents: CredentialDisabledEvent[] = [];
1100
+ let credentialDisabledTarget: ExtensionRunner | undefined;
1101
+ unsubscribeCredentialDisabled = authStorage.onCredentialDisabled(event => {
1102
+ if (credentialDisabledTarget) {
1103
+ // Discard return: any handler error is routed through runner.onError listeners.
1104
+ void credentialDisabledTarget.emitCredentialDisabled(event);
1105
+ } else {
1106
+ startupCredentialDisabledEvents.push(event);
1107
+ }
1108
+ });
1109
+ let runtimeCredentialSelectorInstalled = false;
1110
+ const installRuntimeCredentialSelector = (provider: string): void => {
1111
+ if (!options.credentialSelector || runtimeCredentialSelectorInstalled) return;
1112
+ authStorage.setRuntimeCredentialSelector(provider, options.credentialSelector.selector);
1113
+ runtimeCredentialSelectorInstalled = true;
1114
+ };
1115
+ const earlyCredentialSelectorProvider = options.credentialSelector?.provider ?? options.model?.provider;
1116
+ if (earlyCredentialSelectorProvider) {
1117
+ installRuntimeCredentialSelector(earlyCredentialSelectorProvider);
1118
+ }
1119
+ const settings = options.settings ?? (await logger.time("settings", Settings.init, { cwd, agentDir }));
1120
+ modelRegistry.applyConfiguredModelBindings(settings);
1121
+ logger.time("initializeWithSettings", initializeWithSettings, settings);
1122
+ const canRefreshModelsBeforeCredentialSelector =
1123
+ !options.credentialSelector || runtimeCredentialSelectorInstalled || options.modelRegistry !== undefined;
1124
+ if (!options.modelRegistry && canRefreshModelsBeforeCredentialSelector) {
1125
+ modelRegistry.refreshInBackground();
1126
+ }
1127
+ // Kick off workspace tree discovery early. The native workspace scan returns
1128
+ // both the rendered-tree input and the AGENTS.md directory-context index, so
1129
+ // startup does not perform a second recursive filesystem search. Subagents
1130
+ // inherit the parent's resolved values via options.
1131
+ const STARTUP_SCAN_DEADLINE_MS = 5000;
1132
+ const workspaceTreePromise: Promise<WorkspaceTree> = options.workspaceTree
1133
+ ? Promise.resolve(options.workspaceTree)
1134
+ : logger.time("buildWorkspaceTree", () => buildWorkspaceTree(cwd, { timeoutMs: STARTUP_SCAN_DEADLINE_MS }));
1135
+ workspaceTreePromise.catch(() => {});
1136
+
1137
+ // Independent discoveries that depend only on cwd/agentDir — kicked off in parallel and awaited
1138
+ // at their respective consumer sites. Their work can overlap with model resolution, secret loading,
1139
+ // session-context build, tool creation, MCP discovery, and extension discovery.
1140
+ const contextFilesPromise = options.contextFiles
1141
+ ? Promise.resolve(options.contextFiles)
1142
+ : logger.time("discoverContextFiles", discoverContextFiles, cwd, agentDir);
1143
+ contextFilesPromise.catch(() => {});
1144
+ const promptTemplatesPromise = options.promptTemplates
1145
+ ? Promise.resolve(options.promptTemplates)
1146
+ : logger.time("discoverPromptTemplates", discoverPromptTemplates, cwd, agentDir);
1147
+ promptTemplatesPromise.catch(() => {});
1148
+ const slashCommandsPromise = options.slashCommands ? Promise.resolve(options.slashCommands) : Promise.resolve([]);
1149
+ slashCommandsPromise.catch(() => {});
1150
+
1151
+ // Initialize provider preferences from settings
1152
+ const webSearchProvider = getConfiguredSearchProviderPreference(settings);
1153
+ setPreferredSearchProvider(webSearchProvider);
1154
+ const webSearchFallback = settings.get("web_search.fallback");
1155
+ if (Array.isArray(webSearchFallback)) {
1156
+ setSearchFallbackProviders(
1157
+ webSearchFallback.filter(value => typeof value === "string" && isConfigurableSearchProviderId(value)),
1158
+ );
1159
+ }
1160
+ applyConfiguredSearchTimeout(settings);
1161
+
1162
+ const imageProvider = settings.get("providers.image");
1163
+ if (
1164
+ imageProvider === "auto" ||
1165
+ imageProvider === "openai" ||
1166
+ imageProvider === "gemini" ||
1167
+ imageProvider === "openrouter" ||
1168
+ imageProvider === "antigravity"
1169
+ ) {
1170
+ setPreferredImageProvider(imageProvider);
1171
+ }
1172
+
1173
+ const sessionManager =
1174
+ options.sessionManager ??
1175
+ (await logger.time("sessionManager", async () => {
1176
+ return SessionManager.create(cwd, SessionManager.managedDestination(cwd, agentDir));
1177
+ }));
1178
+ const logicalSessionId = sessionManager.getSessionId();
1179
+ const providerSessionId = options.providerSessionId ?? options.forkContextSeed?.cacheIdentity ?? logicalSessionId;
1180
+ const modelApiKeyAvailability = new Map<string, boolean>();
1181
+ const getModelAvailabilityKey = (candidate: Model): string =>
1182
+ `${candidate.provider}\u0000${candidate.baseUrl ?? ""}`;
1183
+ const hasModelApiKey = async (candidate: Model): Promise<boolean> => {
1184
+ const availabilityKey = getModelAvailabilityKey(candidate);
1185
+ const cached = modelApiKeyAvailability.get(availabilityKey);
1186
+ if (cached !== undefined) {
1187
+ return cached;
1188
+ }
1189
+
1190
+ const credentialSelector =
1191
+ options.credentialSelector && !runtimeCredentialSelectorInstalled
1192
+ ? options.credentialSelector.provider === undefined ||
1193
+ options.credentialSelector.provider === candidate.provider
1194
+ ? options.credentialSelector.selector
1195
+ : undefined
1196
+ : undefined;
1197
+ if (options.credentialSelector?.provider && options.credentialSelector.provider !== candidate.provider) {
1198
+ modelApiKeyAvailability.set(availabilityKey, false);
1199
+ return false;
1200
+ }
1201
+ const key = await modelRegistry
1202
+ .getApiKey(candidate, providerSessionId, { credentialSelector })
1203
+ .catch(error => {
1204
+ if (credentialSelector) {
1205
+ logger.debug("Credential selector did not match model availability candidate", {
1206
+ provider: candidate.provider,
1207
+ model: candidate.id,
1208
+ error: error instanceof Error ? error.message : String(error),
1209
+ });
1210
+ return undefined;
1211
+ }
1212
+ throw error;
1213
+ });
1214
+ const hasKey = Boolean(key) && (!credentialSelector || key !== kNoAuth);
1215
+ modelApiKeyAvailability.set(availabilityKey, hasKey);
1216
+ return hasKey;
1217
+ };
1218
+
1219
+ // Load and create secret obfuscator early so resumed session state and prompt warnings
1220
+ // reflect actual loaded secrets, not just the setting toggle.
1221
+ let obfuscator: SecretObfuscator | undefined;
1222
+ if (settings.get("secrets.enabled")) {
1223
+ const fileEntries = await logger.time("loadSecrets", loadSecrets, cwd, agentDir);
1224
+ const envEntries = collectEnvSecrets();
1225
+ const allEntries = [...envEntries, ...fileEntries];
1226
+ if (allEntries.length > 0) {
1227
+ obfuscator = createSecretObfuscator(allEntries);
1228
+ }
1229
+ }
1230
+ const secretsEnabled = obfuscator?.hasSecrets() === true;
1231
+
1232
+ // Check if session has existing data to restore
1233
+ const existingSession = logger.time("loadSessionContext", () =>
1234
+ deobfuscateSessionContext(sessionManager.buildSessionContext(), obfuscator),
1235
+ );
1236
+ const existingBranch = logger.time("getSessionBranch", () => sessionManager.getBranch());
1237
+ const hasExistingSession = existingBranch.length > 0;
1238
+ const hasThinkingEntry = existingBranch.some(entry => entry.type === "thinking_level_change");
1239
+ const hasServiceTierEntry = existingBranch.some(entry => entry.type === "service_tier_change");
1240
+
1241
+ const hasExplicitModel = options.model !== undefined || options.modelPattern !== undefined;
1242
+ const modelMatchPreferences = {
1243
+ usageOrder: settings.getStorage()?.getModelUsageOrder(),
1244
+ };
1245
+ const allowedModels = await logger.time("resolveAllowedModels", () =>
1246
+ resolveAllowedModels(modelRegistry, settings, modelMatchPreferences),
1247
+ );
1248
+ const defaultRoleSpec = logger.time("resolveDefaultModelRole", () =>
1249
+ resolveModelRoleValue(settings.getModelRole("default"), allowedModels, {
1250
+ settings,
1251
+ matchPreferences: modelMatchPreferences,
1252
+ modelRegistry,
1253
+ }),
1254
+ );
1255
+ let model = options.model;
1256
+ let modelFallbackMessage: string | undefined;
1257
+ const persistedDefaultChain = existingSession.configuredModelChains.default?.entries;
1258
+ const defaultModelEntries =
1259
+ persistedDefaultChain && persistedDefaultChain.length > 0
1260
+ ? persistedDefaultChain
1261
+ : existingSession.models.default
1262
+ ? [existingSession.models.default]
1263
+ : [];
1264
+ // If session has data, restore its configured default chain rather than the
1265
+ // scalar runtime model, which may be a stale fallback from the prior run.
1266
+ if (!hasExplicitModel && !model && hasExistingSession && defaultModelEntries.length > 0) {
1267
+ await logger.time("restoreSessionModel", async () => {
1268
+ const restoredDefaultResolution = await resolveModelChainWithAuth(
1269
+ defaultModelEntries,
1270
+ modelRegistry,
1271
+ settings,
1272
+ providerSessionId,
1273
+ { managedFallback: defaultModelEntries.length > 1 },
1274
+ );
1275
+ model = restoredDefaultResolution.model;
1276
+ if (!model) modelFallbackMessage = `Could not restore model ${defaultModelEntries.join(" -> ")}`;
1277
+ });
1278
+ }
1279
+
1280
+ // If still no model, try settings default.
1281
+ // Skip settings fallback when an explicit model was requested.
1282
+ if (!hasExplicitModel && !model && defaultRoleSpec.model) {
1283
+ const settingsDefaultModel = defaultRoleSpec.model;
1284
+ logger.time("resolveSettingsDefaultModel", () => {
1285
+ // defaultRoleSpec.model already comes from modelRegistry.getAvailable(),
1286
+ // so re-validating auth here just repeats the expensive lookup path.
1287
+ model = settingsDefaultModel;
1288
+ });
1289
+ }
1290
+
1291
+ const taskDepth = options.taskDepth ?? 0;
1292
+
1293
+ let thinkingLevel = options.thinkingLevel;
1294
+ const hasExplicitDefaultThinkingLevel = settings.has("defaultThinkingLevel");
1295
+ let thinkingLevelFromSchemaDefault = false;
1296
+
1297
+ // If session has data and includes a thinking entry, restore an explicit session
1298
+ // override. A persisted inherit marker deliberately re-enters the normal
1299
+ // default-role/global/model resolution path instead of resolving to `undefined`.
1300
+ const restoredThinkingLevel =
1301
+ hasExistingSession && hasThinkingEntry ? parseThinkingLevel(existingSession.thinkingLevel) : undefined;
1302
+ if (thinkingLevel === undefined && restoredThinkingLevel !== ThinkingLevel.Inherit) {
1303
+ thinkingLevel = restoredThinkingLevel;
1304
+ }
1305
+
1306
+ if (thinkingLevel === undefined && !hasExplicitModel && defaultRoleSpec.explicitThinkingLevel) {
1307
+ thinkingLevel = defaultRoleSpec.thinkingLevel;
1308
+ }
1309
+
1310
+ // An explicit user/project default should win over the model's bundled
1311
+ // defaultLevel. The schema default is only a final fallback so model metadata
1312
+ // can keep driving first-run behavior until the user chooses "Set as default".
1313
+ if (thinkingLevel === undefined && hasExplicitDefaultThinkingLevel) {
1314
+ thinkingLevel = settings.get("defaultThinkingLevel");
1315
+ }
1316
+
1317
+ if (thinkingLevel === undefined && model?.thinking?.defaultLevel !== undefined) {
1318
+ thinkingLevel = model.thinking.defaultLevel;
1319
+ }
1320
+
1321
+ if (thinkingLevel === undefined) {
1322
+ thinkingLevel = settings.get("defaultThinkingLevel");
1323
+ thinkingLevelFromSchemaDefault = true;
1324
+ }
1325
+ if (model) {
1326
+ const resolvedModel = model;
1327
+ thinkingLevel = logger.time("resolveThinkingLevelForModel", () =>
1328
+ resolveThinkingLevelForModel(resolvedModel, thinkingLevel),
1329
+ );
1330
+ // Fire-and-forget TLS+H2 handshake to the model's host so it overlaps
1331
+ // with the rest of session setup (extension/skill load, tool registry,
1332
+ // system prompt build). Without this, the first `fetch(...)` pays the
1333
+ // full handshake serially — 100–300 ms transcontinental for
1334
+ // api.anthropic.com from a residential IP. Every session frontend benefits
1335
+ // (interactive, print, SDK, ACP).
1336
+ preconnectModelHost(model.baseUrl);
1337
+ }
1338
+
1339
+ let skills: Skill[];
1340
+ let skillWarnings: SkillWarning[];
1341
+ if (options.skills !== undefined) {
1342
+ // The four public SKC workflow skills are a product invariant, not
1343
+ // ordinary filesystem-discovered skills. Keep them available even for
1344
+ // explicit SDK skill lists so startup and command routing survive
1345
+ // accidental `.skc` deletion or overzealous caller filtering.
1346
+ skills = withEmbeddedDefaultSkcSkills(options.skills);
1347
+ skillWarnings = [];
1348
+ } else if (settings.get("skills.enabled")) {
1349
+ const skillsResult = await logger.time("loadSkills", loadSkills, {
1350
+ ...settings.getGroup("skills"),
1351
+ cwd,
1352
+ disabledExtensions: settings.get("disabledExtensions"),
1353
+ });
1354
+ skills = withEmbeddedDefaultSkcSkills(skillsResult.skills);
1355
+ skillWarnings = skillsResult.warnings;
1356
+ } else {
1357
+ // SKC's four public workflow skills are bundled into the binary so the
1358
+ // default workflow surface survives accidental .skc deletion. Arbitrary
1359
+ // filesystem skill discovery remains gated by skills.enabled above.
1360
+ skills = getEmbeddedDefaultSkcSkills();
1361
+ skillWarnings = [];
1362
+ }
1363
+
1364
+ // Discover rules and bucket them in one pass to avoid repeated scans over large rule sets.
1365
+ const { ttsrManager, rulebookRules, alwaysApplyRules } = await logger.time("discoverTtsrRules", async () => {
1366
+ const ttsrSettings = settings.getGroup("ttsr");
1367
+ const ttsrManager = new TtsrManager(ttsrSettings);
1368
+ const rulesResult =
1369
+ options.rules !== undefined
1370
+ ? { items: options.rules, warnings: undefined }
1371
+ : await loadCapability<Rule>(ruleCapability.id, { cwd });
1372
+ const rulebookRules: Rule[] = [];
1373
+ const alwaysApplyRules: Rule[] = [];
1374
+ for (const rule of rulesResult.items) {
1375
+ const isTtsrRule = rule.condition && rule.condition.length > 0 ? ttsrManager.addRule(rule) : false;
1376
+ if (isTtsrRule) {
1377
+ continue;
1378
+ }
1379
+ if (rule.alwaysApply === true) {
1380
+ alwaysApplyRules.push(rule);
1381
+ continue;
1382
+ }
1383
+ if (rule.description) {
1384
+ rulebookRules.push(rule);
1385
+ }
1386
+ }
1387
+ if (ttsrManager.getSettings().enabled !== false) {
1388
+ if ((existingSession.ttsrMessageCount ?? 0) > 0) {
1389
+ ttsrManager.restoreMessageCount(existingSession.ttsrMessageCount ?? 0);
1390
+ }
1391
+ if (existingSession.injectedTtsrRuleRecords && existingSession.injectedTtsrRuleRecords.length > 0) {
1392
+ ttsrManager.restoreInjected(existingSession.injectedTtsrRuleRecords);
1393
+ } else if (existingSession.injectedTtsrRules.length > 0) {
1394
+ ttsrManager.restoreInjected(existingSession.injectedTtsrRules);
1395
+ }
1396
+ }
1397
+ return { ttsrManager, rulebookRules, alwaysApplyRules };
1398
+ });
1399
+
1400
+ // Resolve contextFiles up-front (it's needed before tool creation). The
1401
+ // workspace tree scan is slow on large repos and we MUST NOT block startup on
1402
+ // it. On timeout we forward `undefined` to ToolSession; buildSystemPromptInternal
1403
+ // will re-race the same promise through its own withDeadline path. Background
1404
+ // work continues so caches still warm.
1405
+ const raceWithDeadline = async <T>(name: string, work: Promise<T>): Promise<T | undefined> => {
1406
+ let timedOut = false;
1407
+ const result = await Promise.race([
1408
+ work,
1409
+ Bun.sleep(STARTUP_SCAN_DEADLINE_MS).then(() => {
1410
+ timedOut = true;
1411
+ return undefined;
1412
+ }),
1413
+ ]);
1414
+ if (timedOut) {
1415
+ logger.warn("Startup scan exceeded deadline; deferring to system prompt fallback", {
1416
+ name,
1417
+ timeoutMs: STARTUP_SCAN_DEADLINE_MS,
1418
+ cwd,
1419
+ });
1420
+ }
1421
+ return result;
1422
+ };
1423
+ const [contextFiles, resolvedWorkspaceTree] = await Promise.all([
1424
+ contextFilesPromise,
1425
+ raceWithDeadline("buildWorkspaceTree", workspaceTreePromise),
1426
+ ]);
1427
+
1428
+ const backgroundJobsEnabled = isBackgroundJobSupportEnabled(settings);
1429
+ const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ?? 100));
1430
+ const ASYNC_INLINE_RESULT_MAX_CHARS = 12_000;
1431
+ const ASYNC_PREVIEW_MAX_CHARS = 4_000;
1432
+ const formatAsyncResultForFollowUp = async (result: string): Promise<string> => {
1433
+ if (result.length <= ASYNC_INLINE_RESULT_MAX_CHARS) {
1434
+ return result;
1435
+ }
1436
+
1437
+ const preview = `${result.slice(0, ASYNC_PREVIEW_MAX_CHARS)}\n\n[Output truncated. Showing first ${ASYNC_PREVIEW_MAX_CHARS.toLocaleString()} characters.]`;
1438
+ try {
1439
+ const { path: artifactPath, id: artifactId } = await sessionManager.allocateArtifactPath("async");
1440
+ if (artifactPath && artifactId) {
1441
+ await Bun.write(artifactPath, result);
1442
+ return `${preview}\nFull output: artifact://${artifactId}`;
1443
+ }
1444
+ } catch (error) {
1445
+ logger.warn("Failed to persist async follow-up artifact", {
1446
+ error: error instanceof Error ? error.message : String(error),
1447
+ });
1448
+ }
1449
+
1450
+ return preview;
1451
+ };
1452
+ // Only top-level sessions own an AsyncJobManager. Subagents reach the
1453
+ // parent's manager via `AsyncJobManager.instance()` (set below), so creating
1454
+ // a second instance here just to leave it orphaned wastes a constructor and
1455
+ // risks accidental disposal of the parent's manager on subagent teardown.
1456
+ const asyncJobManager =
1457
+ backgroundJobsEnabled && !options.parentTaskPrefix
1458
+ ? new AsyncJobManager({
1459
+ maxRunningJobs: asyncMaxJobs,
1460
+ onJobComplete: async (jobId, result, job) => {
1461
+ if (!session || asyncJobManager!.isDeliverySuppressed(jobId)) return;
1462
+ const formattedResult = await formatAsyncResultForFollowUp(result);
1463
+ if (asyncJobManager!.isDeliverySuppressed(jobId)) return;
1464
+
1465
+ const durationMs = job ? jobElapsedMs(job) : undefined;
1466
+ session.yieldQueue.enqueue<AsyncResultEntry>("async-result", {
1467
+ jobId,
1468
+ result: formattedResult,
1469
+ job,
1470
+ durationMs,
1471
+ });
1472
+ },
1473
+ })
1474
+ : undefined;
1475
+
1476
+ let promptMetadataModel: Model | undefined;
1477
+ const getActiveModelString = (): string | undefined => {
1478
+ const activeModel = promptMetadataModel ?? agent?.state.model;
1479
+ if (activeModel) return formatModelString(activeModel);
1480
+ if (model) return formatModelString(model);
1481
+ return undefined;
1482
+ };
1483
+ const toolSession: ToolSession = {
1484
+ get cwd() {
1485
+ return sessionManager.getCwd();
1486
+ },
1487
+ hasUI: options.hasUI ?? false,
1488
+ workflowGateEligible: true,
1489
+ enableLsp,
1490
+ get hasEditTool() {
1491
+ const requestedToolNames = options.toolNames
1492
+ ? [...new Set(options.toolNames.map(name => name.toLowerCase()))]
1493
+ : undefined;
1494
+ return !requestedToolNames || requestedToolNames.includes("edit");
1495
+ },
1496
+ skipPythonPreflight: options.skipPythonPreflight,
1497
+ contextFiles,
1498
+ workspaceTree: resolvedWorkspaceTree,
1499
+ skills,
1500
+ eventBus,
1501
+ outputSchema: options.outputSchema,
1502
+ requireYieldTool: options.requireYieldTool,
1503
+ taskDepth: options.taskDepth ?? 0,
1504
+ currentAgentType: options.currentAgentType,
1505
+ getSessionFile: () => sessionManager.getSessionFile() ?? null,
1506
+ getEvalKernelOwnerId: () => evalKernelOwnerId,
1507
+ assertEvalExecutionAllowed: () => session?.assertEvalExecutionAllowed(),
1508
+ trackEvalExecution: (execution, abortController) =>
1509
+ session ? session.trackEvalExecution(execution, abortController) : execution,
1510
+ getSessionId: () => sessionManager.getSessionId?.() ?? null,
1511
+ isManagedSessionDestination: () => sessionManager.isManagedDestination(),
1512
+ getActiveSkillState: () => session?.getActiveSkillState(),
1513
+ getActiveSkillPhase: () => session?.getActiveSkillPhase(),
1514
+ getHindsightSessionState: () => session?.getHindsightSessionState(),
1515
+ get model() {
1516
+ return agent?.state.model ?? model;
1517
+ },
1518
+ get serviceTier() {
1519
+ // Live parent service-tier intent (e.g. runtime `/fast on|off`), inherited
1520
+ // by `inherit` subagents. Only fall back to the startup tier when there is
1521
+ // no live agent yet — never `??`, or an intentional `/fast off`
1522
+ // (serviceTier === undefined) would be resurrected to the startup value.
1523
+ return agent ? agent.serviceTier : initialServiceTier;
1524
+ },
1525
+ getAgentId: () => resolvedAgentId,
1526
+ bashAllowedPrefixes: options.bashAllowedPrefixes,
1527
+ bashRestrictionProfile: options.bashRestrictionProfile,
1528
+ goalToolAllowedOps: options.goalToolAllowedOps,
1529
+ discoverableToolAllowedNames: options.discoverableToolAllowedNames,
1530
+ getToolByName: name => session?.getToolByName(name),
1531
+ agentRegistry,
1532
+ getSessionSpawns: () => options.spawns ?? "*",
1533
+ getModelString: () => (hasExplicitModel && model ? formatModelString(model) : undefined),
1534
+ getActiveModelString,
1535
+ getPlanModeState: () => session?.getPlanModeState(),
1536
+ getGoalModeState: () => session?.getGoalModeState(),
1537
+ getWorkflowGateEmitter: () => session?.getWorkflowGateEmitter(),
1538
+ getAskAnswerSource: () => session?.getAskAnswerSource(),
1539
+ getGoalRuntime: () => session?.goalRuntime,
1540
+ getClientBridge: () => session?.clientBridge,
1541
+ getCompactContext: () => session.formatCompactContext(),
1542
+ getTodoPhases: () => session.getTodoPhases(),
1543
+ setTodoPhases: phases => session.setTodoPhases(phases),
1544
+ // Generic tool discovery (unified — covers built-in + MCP + extension)
1545
+ isToolDiscoveryEnabled: () => session.isToolDiscoveryEnabled(),
1546
+ getDiscoverableTools: filter => session.getDiscoverableTools(filter),
1547
+ getDiscoverableToolSearchIndex: () => session.getDiscoverableToolSearchIndex(),
1548
+ getSelectedDiscoveredToolNames: () => session.getSelectedDiscoveredToolNames(),
1549
+ activateDiscoveredTools: toolNames => session.activateDiscoveredTools(toolNames),
1550
+ getCheckpointState: () => session.getCheckpointState(),
1551
+ setCheckpointState: state => session.setCheckpointState(state ?? undefined),
1552
+ getToolChoiceQueue: () => session.toolChoiceQueue,
1553
+ buildToolChoice: name => {
1554
+ const m = session.model;
1555
+ return m ? buildNamedToolChoice(name, m) : undefined;
1556
+ },
1557
+ buildToolChoiceResult: name => buildNamedToolChoiceResult(name, session.model),
1558
+ steer: msg =>
1559
+ session.agent.steer({
1560
+ role: "custom",
1561
+ customType: msg.customType,
1562
+ content: msg.content,
1563
+ display: false,
1564
+ details: msg.details,
1565
+ attribution: "agent",
1566
+ timestamp: Date.now(),
1567
+ }),
1568
+ sendCustomMessage: (msg, opts) => session.sendCustomMessage(msg, opts),
1569
+ purgeQueuedCustomMessages: predicate => session.purgeQueuedCustomMessages(predicate),
1570
+ peekQueueInvoker: () => session.peekQueueInvoker(),
1571
+ peekStandingResolveHandler: () => session.peekStandingResolveHandler(),
1572
+ setStandingResolveHandler: handler => session.setStandingResolveHandler(handler),
1573
+ allocateOutputArtifact: async toolType => {
1574
+ try {
1575
+ return await sessionManager.allocateArtifactPath(toolType);
1576
+ } catch {
1577
+ return {};
1578
+ }
1579
+ },
1580
+ getArtifactManager: () => sessionManager.getArtifactManager(),
1581
+ settings,
1582
+ authStorage,
1583
+ modelRegistry,
1584
+ getTelemetry: () => agent?.telemetry,
1585
+ buildForkContextSeed: forkOptions => session.buildForkContextSeed(forkOptions),
1586
+ };
1587
+
1588
+ // Wire process-wide internal URL singletons owned by their real classes.
1589
+ // Top-level sessions install the active snapshots; subagents inherit them.
1590
+ // Artifact and agent-output URLs resolve via `AgentRegistry.global()` —
1591
+ // the protocol handlers walk each ref's `sessionManager.getArtifactsDir()`,
1592
+ // which collapses to the parent's dir for subagents (they adopt the
1593
+ // parent's ArtifactManager) so one lookup hits everything.
1594
+ const getArtifactsDir = () => sessionManager.getArtifactsDir();
1595
+ if (!options.parentTaskPrefix) {
1596
+ setActiveSkills(skills);
1597
+ setActiveRules([...rulebookRules, ...alwaysApplyRules]);
1598
+ if (asyncJobManager) AsyncJobManager.setInstance(asyncJobManager);
1599
+ }
1600
+ if (options.localProtocolOptions) {
1601
+ await initializeLocalRoot(options.localProtocolOptions);
1602
+ disposeLocalProtocolOverride = LocalProtocolHandler.installOverride(options.localProtocolOptions);
1603
+ }
1604
+ toolSession.getArtifactsDir = getArtifactsDir;
1605
+ toolSession.agentOutputManager = new AgentOutputManager(
1606
+ getArtifactsDir,
1607
+ options.parentTaskPrefix ? { parentPrefix: options.parentTaskPrefix } : undefined,
1608
+ );
1609
+
1610
+ // Create built-in tools (already wrapped with meta notice formatting)
1611
+ const builtinTools = await logger.time("createAllTools", createTools, toolSession, options.toolNames);
1612
+
1613
+ // MCP runtime discovery is quarantined for the SKC surface. A top-level
1614
+ // session may load only a caller-supplied exact config; project and user
1615
+ // MCP configs are never discovered here. Existing managers remain available
1616
+ // for legacy in-process callers, and plugin-bundle managers are created
1617
+ // below after `customTools` is populated.
1618
+ let mcpManager: MCPManager | undefined = options.mcpManager;
1619
+ let ownsMcpManager = false;
1620
+ const explicitMcpConfigPath = !isCanonicalSubSession && !options.mcpManager ? options.mcpConfigPath : undefined;
1621
+ const customTools: CustomTool[] = [];
1622
+ const exactMcpToolNames: string[] = [];
1623
+ const pluginMcpToolNames: string[] = [];
1624
+
1625
+ // Add image tools when the active model or configured image providers can generate images.
1626
+ const imageGenTools = await logger.time("getImageGenTools", () => getImageGenTools(modelRegistry, model));
1627
+ if (imageGenTools.length > 0) {
1628
+ customTools.push(...(imageGenTools as unknown as CustomTool[]));
1629
+ }
1630
+
1631
+ // Add web search tools
1632
+ if (options.toolNames?.includes("web_search")) {
1633
+ customTools.push(...getSearchTools());
1634
+ }
1635
+
1636
+ const getReservedSubskillToolNames = () => [
1637
+ ...new Set([
1638
+ ...builtinTools.map(tool => tool.name),
1639
+ ...(options.toolNames?.map(name => name.toLowerCase()) ?? []),
1640
+ ...(options.customTools?.map(tool => (isCustomTool(tool) ? tool.name : tool.name)) ?? []),
1641
+ ...customTools.map(tool => tool.name),
1642
+ ]),
1643
+ ];
1644
+
1645
+ const skcSubskillToolContext = options.skcSubskillToolContext;
1646
+ if (skcSubskillToolContext?.parent.trim() && skcSubskillToolContext.phase.trim()) {
1647
+ const pluginTools = await loadActiveSubskillTools({
1648
+ cwd: skcSubskillToolContext.cwd ?? cwd,
1649
+ sessionId: skcSubskillToolContext.sessionId ?? logicalSessionId,
1650
+ parent: skcSubskillToolContext.parent,
1651
+ phase: skcSubskillToolContext.phase,
1652
+ reservedToolNames: getReservedSubskillToolNames(),
1653
+ });
1654
+ if (pluginTools.length > 0) {
1655
+ customTools.push(...pluginTools);
1656
+ }
1657
+ } else {
1658
+ for (const skill of skills) {
1659
+ const phase = await resolveCurrentPhaseForParent({
1660
+ cwd,
1661
+ sessionId: logicalSessionId,
1662
+ parent: skill.name,
1663
+ });
1664
+ const pluginTools = await loadActiveSubskillTools({
1665
+ cwd,
1666
+ sessionId: logicalSessionId,
1667
+ parent: skill.name,
1668
+ phase,
1669
+ reservedToolNames: getReservedSubskillToolNames(),
1670
+ });
1671
+ if (pluginTools.length > 0) {
1672
+ customTools.push(...pluginTools);
1673
+ }
1674
+ }
1675
+ }
1676
+
1677
+ // Always-on SKC plugin bundle tools (validated registry surfaces). This is
1678
+ // additive and a no-op when no plugins are installed for the cwd. Surfaces
1679
+ // are hash-verified and collision-checked; declared names are authoritative.
1680
+ try {
1681
+ const pluginToolResult = await loadAlwaysOnPluginTools({
1682
+ cwd,
1683
+ reservedToolNames: [...getReservedSubskillToolNames(), ...customTools.map(tool => tool.name)],
1684
+ });
1685
+ if (pluginToolResult.tools.length > 0) customTools.push(...pluginToolResult.tools);
1686
+ for (const q of pluginToolResult.quarantine) {
1687
+ logger.warn("Quarantined SKC plugin surface", { plugin: q.plugin, surface: q.surfaceId, code: q.code });
1688
+ }
1689
+ } catch (error) {
1690
+ logger.warn("Failed to load always-on SKC plugin tools", { error });
1691
+ }
1692
+
1693
+ const preExactCustomToolNames = customTools.map(tool => tool.name);
1694
+ if (explicitMcpConfigPath !== undefined) {
1695
+ const owned = new MCPManager(cwd, null, { toolsOnly: true });
1696
+ owned.setAuthStorage(authStorage);
1697
+ mcpManager = owned;
1698
+ ownsMcpManager = true;
1699
+ cleanupOwnedMcpManager = () => owned.disconnectAll();
1700
+ const result = await owned.discoverAndConnect({ configPath: explicitMcpConfigPath });
1701
+ const resultTools = result.tools as CustomTool[];
1702
+ exactMcpToolNames.push(...resultTools.map(tool => tool.name));
1703
+ customTools.push(...resultTools);
1704
+ if (result.errors.size > 0 || result.tools.length === 0) {
1705
+ logger.warn("MCP tools could not be loaded.");
1706
+ }
1707
+ } else if (!mcpManager && !isCanonicalSubSession) {
1708
+ // Always-on SKC plugin-bundle MCP servers. Top-level sessions own a manager
1709
+ // and connect the validated servers; subagents inherit the parent's manager
1710
+ // via options.mcpManager and never spawn their own (prevents duplicate
1711
+ // processes and leaks). Per the plugin product contract, connected MCP tools
1712
+ // are surfaced as always-on tools rather than gated behind MCP selection.
1713
+ try {
1714
+ const { configs, quarantine } = await buildPluginMcpConfigs({ cwd });
1715
+ for (const q of quarantine) {
1716
+ logger.warn("Quarantined SKC plugin MCP", { plugin: q.plugin, surface: q.surfaceId, code: q.code });
1717
+ }
1718
+ if (Object.keys(configs).length > 0) {
1719
+ const owned = new MCPManager(cwd);
1720
+ try {
1721
+ const sources = Object.fromEntries(
1722
+ Object.keys(configs).map(name => [
1723
+ name,
1724
+ { provider: "skc-plugins", providerName: "SKC plugin bundle", level: "project" as const },
1725
+ ]),
1726
+ );
1727
+ const result = await owned.connectServers(configs, sources as never);
1728
+ for (const [server, err] of result.errors) {
1729
+ logger.warn("SKC plugin MCP connect failed", { path: `mcp:${server}`, error: err });
1730
+ }
1731
+ if (result.connectedServers.length > 0) {
1732
+ mcpManager = owned;
1733
+ ownsMcpManager = true;
1734
+ customTools.push(...(result.tools as CustomTool[]));
1735
+ pluginMcpManagerServers.set(owned, new Set(result.connectedServers));
1736
+ owned.sealConnectionSet();
1737
+ pluginMcpToolNames.push(...result.tools.map(tool => tool.name));
1738
+ } else {
1739
+ await owned.disconnectAll().catch(() => {});
1740
+ }
1741
+ } catch (error) {
1742
+ // Avoid leaking partially-started server processes on failure.
1743
+ await owned.disconnectAll().catch(() => {});
1744
+ throw error;
1745
+ }
1746
+ }
1747
+ } catch (error) {
1748
+ logger.warn("Failed to wire SKC plugin MCP servers", { error });
1749
+ }
1750
+ } else if (isCanonicalSubSession) {
1751
+ // Subagent: inherit the parent's always-on plugin MCP tools WITHOUT
1752
+ // owning the manager (no connect, no callbacks, no disposal). The
1753
+ // top-level session installed its manager as the process-global
1754
+ // instance; reading getTools() surfaces the same always-on tools so the
1755
+ // product decision holds for subagent sessions too.
1756
+ const singleton = MCPManager.instance();
1757
+ const inherited = mcpManager ?? (singleton?.isToolsOnly() ? undefined : singleton);
1758
+ if (inherited) {
1759
+ try {
1760
+ const inheritedTools = inherited.getTools();
1761
+ if (inheritedTools.length > 0) customTools.push(...(inheritedTools as CustomTool[]));
1762
+ const pluginServers = pluginMcpManagerServers.get(inherited);
1763
+ if (pluginServers) {
1764
+ pluginMcpToolNames.push(
1765
+ ...inheritedTools
1766
+ .filter(tool => tool.mcpServerName !== undefined && pluginServers.has(tool.mcpServerName))
1767
+ .map(tool => tool.name),
1768
+ );
1769
+ }
1770
+ } catch (error) {
1771
+ logger.warn("Failed to inherit MCP tools in subagent", { error });
1772
+ }
1773
+ }
1774
+ }
1775
+ // Exact-config managers are session-local. Plugin managers keep their
1776
+ // existing top-level singleton behavior for bundled runtime surfaces.
1777
+ if (mcpManager && !mcpManager.isToolsOnly() && !isCanonicalSubSession && explicitMcpConfigPath === undefined) {
1778
+ MCPManager.setInstance(mcpManager);
1779
+ }
1780
+
1781
+ // Custom tool and extension discovery is quarantined from the public SKC utility surface.
1782
+ // Explicit SDK extension factories are still honored; callers use them to
1783
+ // register in-process tools/providers without enabling filesystem discovery.
1784
+ const inlineExtensions: ExtensionFactory[] = [...(options.extensions ?? [])];
1785
+ if (customTools.length > 0) {
1786
+ inlineExtensions.push(createCustomToolsExtension(customTools));
1787
+ }
1788
+
1789
+ // Always-on constrained plugin hooks (validated registry surfaces). Additive
1790
+ // and a no-op without installed plugins; the loader denies all dangerous APIs.
1791
+ try {
1792
+ const pluginHookResult = await loadConstrainedPluginHooks({ cwd });
1793
+ if (pluginHookResult.hooks.length > 0) {
1794
+ inlineExtensions.push(createPluginHooksExtension(pluginHookResult.hooks));
1795
+ }
1796
+ for (const q of pluginHookResult.quarantine) {
1797
+ logger.warn("Quarantined SKC plugin hook", { plugin: q.plugin, surface: q.surfaceId, code: q.code });
1798
+ }
1799
+ } catch (error) {
1800
+ logger.warn("Failed to load constrained SKC plugin hooks", { error });
1801
+ }
1802
+ let notificationCfg: NotificationConfig | undefined;
1803
+ try {
1804
+ notificationCfg = getNotificationConfig(settings);
1805
+ } catch {
1806
+ notificationCfg = undefined;
1807
+ }
1808
+ const isTopLevelSdkSession = !isCanonicalSubSession;
1809
+ // Consume the SKC spawn-provenance marker: read it once, then remove it
1810
+ // from this process's env so it is never re-inherited by children this
1811
+ // session later spawns (marker is per-spawn, not dynastic — each SKC child
1812
+ // spawn site sets it explicitly). Suppression under `sessionScope=primary`
1813
+ // keeps auto-spawned children (team workers, harness owners) silent while
1814
+ // explicit SDK session opt-in (SKC_NOTIFICATIONS=1) still wins.
1815
+ const spawnProvenance = process.env[SPAWN_PROVENANCE_ENV];
1816
+ const spawnedBySkc = typeof spawnProvenance === "string" && spawnProvenance.trim().length > 0;
1817
+ delete process.env[SPAWN_PROVENANCE_ENV];
1818
+ const notificationHostEligible = isNotificationHostEligible({
1819
+ env: process.env,
1820
+ hostModeSupported: options.notificationHostModeSupported ?? true,
1821
+ taskDepth,
1822
+ parentTaskPrefix: options.parentTaskPrefix,
1823
+ currentAgentType: options.currentAgentType,
1824
+ sessionScope: notificationCfg?.sessionScope,
1825
+ spawnedBySkc,
1826
+ });
1827
+ const notificationSessionController = new NotificationSessionController({
1828
+ eligible: notificationHostEligible,
1829
+ getConfig: () => getNotificationConfig(settings),
1830
+ });
1831
+ if (
1832
+ lifecycleStartupCapability ||
1833
+ shouldRegisterNotificationsExtension({
1834
+ env: process.env,
1835
+ cfg: notificationCfg,
1836
+ taskDepth,
1837
+ parentTaskPrefix: options.parentTaskPrefix,
1838
+ currentAgentType: options.currentAgentType,
1839
+ spawnedBySkc,
1840
+ }) ||
1841
+ (shouldHostSdk(notificationCfg, isTopLevelSdkSession) && (options.sdkHostModeSupported ?? true))
1842
+ ) {
1843
+ inlineExtensions.push(async api => {
1844
+ try {
1845
+ if (lifecycleStartupCapability) attachLifecycleStartupCapability(api, lifecycleStartupCapability);
1846
+ if (lifecycleStartupCapability && process.env.SKC_SDK_TEST_FACTORY_FAILURE === cwd)
1847
+ throw new Error(process.env.SKC_SDK_TEST_FACTORY_SECRET ?? "Lifecycle factory test failure.");
1848
+ createNotificationsExtension(api, {
1849
+ settings,
1850
+ controller: notificationSessionController,
1851
+ spawnedBySkc,
1852
+ sdkHostModeSupported: options.sdkHostModeSupported,
1853
+ ensureProviderDaemon: options.ensureNotificationProviderDaemon,
1854
+ runEphemeralTurn: async (promptText, signal) => {
1855
+ if (!session) throw new Error("Ephemeral turns are unavailable.");
1856
+ const { replyText } = await session.runEphemeralTurn({ promptText, signal });
1857
+ return { replyText };
1858
+ },
1859
+ });
1860
+ } catch (error) {
1861
+ lifecycleStartupCapability?.settleFailure(
1862
+ lifecycleStartupCapability.normalizeFailure("registration", "factory_absent", error),
1863
+ );
1864
+ throw error;
1865
+ }
1866
+ });
1867
+ }
1868
+
1869
+ // Extension/module discovery is quarantined; retain only the private
1870
+ // runtime needed for bundled product extensions, explicitly supplied SDK
1871
+ // extension factories, and custom tools. Filesystem extension paths remain
1872
+ // ignored here even when options.additionalExtensionPaths is supplied.
1873
+ const extensionsResult: LoadExtensionsResult = options.preloadedExtensions ?? {
1874
+ extensions: [],
1875
+ errors: [],
1876
+ runtime: new ExtensionRuntime(),
1877
+ };
1878
+
1879
+ if (!extensionsResult.extensions.some(extension => extension.path === BUNDLED_GROK_BUILD_EXTENSION_ID)) {
1880
+ const bundledGrokExtension = await loadExtensionFromFactory(
1881
+ getBundledGrokBuildExtensionFactory(),
1882
+ cwd,
1883
+ eventBus,
1884
+ extensionsResult.runtime,
1885
+ BUNDLED_GROK_BUILD_EXTENSION_ID,
1886
+ );
1887
+ extensionsResult.extensions.push(bundledGrokExtension);
1888
+ }
1889
+
1890
+ // Load inline extensions from factories
1891
+ if (inlineExtensions.length > 0) {
1892
+ for (let i = 0; i < inlineExtensions.length; i++) {
1893
+ const factory = inlineExtensions[i];
1894
+ const loaded = await loadExtensionFromFactory(
1895
+ factory,
1896
+ cwd,
1897
+ eventBus,
1898
+ extensionsResult.runtime,
1899
+ `<inline-${i}>`,
1900
+ );
1901
+ extensionsResult.extensions.push(loaded);
1902
+ }
1903
+ }
1904
+
1905
+ // Process provider registrations queued during extension loading.
1906
+ // This must happen before the runner is created so that models registered by
1907
+ // extensions are available for model selection on session resume / fallback.
1908
+ const activeExtensionSources = extensionsResult.extensions.map(extension => extension.path);
1909
+ modelRegistry.syncExtensionSources(activeExtensionSources);
1910
+ for (const sourceId of new Set(activeExtensionSources)) {
1911
+ modelRegistry.clearSourceRegistrations(sourceId);
1912
+ }
1913
+ if (extensionsResult.runtime.pendingProviderRegistrations.length > 0) {
1914
+ for (const { name, config, sourceId } of extensionsResult.runtime.pendingProviderRegistrations) {
1915
+ modelRegistry.registerProvider(name, config, sourceId);
1916
+ }
1917
+ extensionsResult.runtime.pendingProviderRegistrations = [];
1918
+ }
1919
+
1920
+ // Resolve deferred --model pattern now that extension models are registered.
1921
+ if (!model && options.modelPattern) {
1922
+ const availableModels = modelRegistry.getAll();
1923
+ const matchPreferences = {
1924
+ usageOrder: settings.getStorage()?.getModelUsageOrder(),
1925
+ };
1926
+ const { model: resolved } = parseModelPattern(options.modelPattern, availableModels, matchPreferences, {
1927
+ modelRegistry,
1928
+ });
1929
+ if (resolved) {
1930
+ model = resolved;
1931
+ modelFallbackMessage = undefined;
1932
+ if (thinkingLevelFromSchemaDefault && resolved.thinking?.defaultLevel !== undefined) {
1933
+ thinkingLevel = resolved.thinking.defaultLevel;
1934
+ thinkingLevelFromSchemaDefault = false;
1935
+ }
1936
+ thinkingLevel = resolveThinkingLevelForModel(resolved, thinkingLevel);
1937
+ } else {
1938
+ modelFallbackMessage = `Model "${options.modelPattern}" not found`;
1939
+ }
1940
+ }
1941
+
1942
+ // Fall back to first available model with a valid API key, honoring the
1943
+ // path-scoped `enabledModels` allow-list when configured. Skip when the
1944
+ // user explicitly requested a model via --model that wasn't found.
1945
+ if (!model && !options.modelPattern) {
1946
+ // Re-resolve the allowed set: extension factories above may have
1947
+ // registered providers/models that weren't visible at startup.
1948
+ const fallbackCandidates = await resolveAllowedModels(modelRegistry, settings, modelMatchPreferences);
1949
+ // resolveAllowedModels returns getAvailable() in static-catalog order
1950
+ // when no `enabledModels` allow-list is set — and the catalog happens to
1951
+ // list the years-old `claude-3-5-sonnet-20240620` ("Sonnet 3.5") before
1952
+ // modern models. Picking the first valid-key candidate verbatim therefore
1953
+ // cold-starts an authenticated user on an ancient model, ignoring the one
1954
+ // they actually used last. Order the fallback the way the model selector
1955
+ // does: most-recently-used first, then each provider's curated default
1956
+ // (e.g. anthropic → claude-sonnet-4-6), then catalog order.
1957
+ const mruIndex = new Map((modelMatchPreferences.usageOrder ?? []).map((key, i) => [key, i]));
1958
+ const fallbackRank = (candidate: Model<Api>): number => {
1959
+ const mru = mruIndex.get(formatModelString(candidate));
1960
+ if (mru !== undefined) return mru;
1961
+ if (defaultModelPerProvider[candidate.provider as keyof typeof defaultModelPerProvider] === candidate.id) {
1962
+ return Number.MAX_SAFE_INTEGER - 1;
1963
+ }
1964
+ return Number.MAX_SAFE_INTEGER;
1965
+ };
1966
+ const orderedFallback = fallbackCandidates
1967
+ .map((candidate, index) => ({ candidate, index }))
1968
+ .sort((a, b) => fallbackRank(a.candidate) - fallbackRank(b.candidate) || a.index - b.index)
1969
+ .map(entry => entry.candidate);
1970
+ for (const candidate of orderedFallback) {
1971
+ if (await hasModelApiKey(candidate)) {
1972
+ model = candidate;
1973
+ break;
1974
+ }
1975
+ }
1976
+ if (model) {
1977
+ if (modelFallbackMessage) {
1978
+ modelFallbackMessage += `. Using ${model.provider}/${model.id}`;
1979
+ }
1980
+ } else {
1981
+ const patterns = settings.get("enabledModels");
1982
+ modelFallbackMessage =
1983
+ patterns && patterns.length > 0
1984
+ ? `No model available matching enabledModels (${patterns.join(", ")}) with usable credentials. ${formatNoModelsAvailableFallback()}`
1985
+ : formatNoModelsAvailableFallback();
1986
+ }
1987
+ }
1988
+
1989
+ if (options.credentialSelector && !runtimeCredentialSelectorInstalled) {
1990
+ const credentialProvider = options.credentialSelector.provider ?? model?.provider;
1991
+ if (!credentialProvider) {
1992
+ throw new Error(
1993
+ `--credential ${options.credentialSelector.raw} requires a resolved model or an explicit provider prefix`,
1994
+ );
1995
+ }
1996
+ installRuntimeCredentialSelector(credentialProvider);
1997
+ if (!options.modelRegistry && !canRefreshModelsBeforeCredentialSelector) {
1998
+ modelRegistry.refreshInBackground();
1999
+ }
2000
+ }
2001
+ const customCommandsResult: CustomCommandsLoadResult = { commands: [], errors: [] };
2002
+
2003
+ let extensionRunner: ExtensionRunner | undefined;
2004
+ if (extensionsResult.extensions.length > 0) {
2005
+ extensionRunner = new ExtensionRunner(
2006
+ extensionsResult.extensions,
2007
+ extensionsResult.runtime,
2008
+ cwd,
2009
+ sessionManager,
2010
+ modelRegistry,
2011
+ {
2012
+ kind: isCanonicalSubSession ? "sub" : "main",
2013
+ taskDepth,
2014
+ ...(options.parentTaskPrefix ? { parentTaskPrefix: options.parentTaskPrefix } : {}),
2015
+ ...(options.currentAgentType ? { currentAgentType: options.currentAgentType } : {}),
2016
+ },
2017
+ );
2018
+ }
2019
+
2020
+ if (extensionRunner) {
2021
+ credentialDisabledTarget = extensionRunner;
2022
+ for (const event of startupCredentialDisabledEvents.splice(0)) {
2023
+ // Discard return: any handler error is routed through runner.onError listeners.
2024
+ void extensionRunner.emitCredentialDisabled(event);
2025
+ }
2026
+ } else {
2027
+ // No runner to forward to; release our subscription. The embedder's own
2028
+ // onCredentialDisabled (if any) keeps firing through its own subscription.
2029
+ startupCredentialDisabledEvents.length = 0;
2030
+ releaseCredentialDisabledSubscription();
2031
+ }
2032
+
2033
+ const getSessionContext = () => ({
2034
+ sessionManager: createReadonlySessionManager(sessionManager),
2035
+ modelRegistry,
2036
+ model: agent.state.model,
2037
+ isIdle: () => !session.isStreaming,
2038
+ hasQueuedMessages: () => session.queuedMessageCount > 0,
2039
+ abort: () => {
2040
+ session.abort();
2041
+ },
2042
+ settings,
2043
+ });
2044
+ const toolContextStore = new ToolContextStore(getSessionContext);
2045
+
2046
+ const registeredTools = extensionRunner?.getAllRegisteredTools() ?? [];
2047
+ let wrappedExtensionTools: Tool[];
2048
+
2049
+ if (extensionRunner) {
2050
+ // With extension runner: convert CustomTools to ToolDefinitions and wrap all together
2051
+ const allCustomTools = [
2052
+ ...registeredTools,
2053
+ ...(options.customTools?.map(tool => {
2054
+ const definition = isCustomTool(tool) ? customToolToDefinition(tool) : tool;
2055
+ return { definition, extensionPath: "<sdk>" };
2056
+ }) ?? []),
2057
+ ];
2058
+ wrappedExtensionTools = wrapRegisteredTools(allCustomTools, extensionRunner);
2059
+ } else {
2060
+ // Without extension runner: wrap CustomTools directly with CustomToolAdapter
2061
+ // ToolDefinition items require ExtensionContext and cannot be used without a runner
2062
+ const customToolContext = (): CustomToolContext => ({
2063
+ sessionManager: createReadonlySessionManager(sessionManager),
2064
+ modelRegistry,
2065
+ model: agent?.state.model,
2066
+ isIdle: () => !session?.isStreaming,
2067
+ hasQueuedMessages: () => (session?.queuedMessageCount ?? 0) > 0,
2068
+ abort: () => session?.abort(),
2069
+ settings,
2070
+ });
2071
+ wrappedExtensionTools = (options.customTools ?? [])
2072
+ .filter(isCustomTool)
2073
+ .map(tool => CustomToolAdapter.wrap(tool, customToolContext));
2074
+ }
2075
+
2076
+ // All built-in tools are active (conditional tools like git/ask return null from factory if disabled)
2077
+ const toolRegistry = new Map<string, Tool>();
2078
+ let builtinCandidateTools = [...builtinTools];
2079
+ for (const tool of builtinTools) {
2080
+ toolRegistry.set(tool.name, tool);
2081
+ }
2082
+ const goalStateToolNames = ["goal"] as const;
2083
+ if (settings.get("goal.enabled")) {
2084
+ for (const name of goalStateToolNames) {
2085
+ if (toolRegistry.has(name)) continue;
2086
+ const goalStateTool = await logger.time(`createTools:${name}:session`, BUILTIN_TOOLS[name], toolSession);
2087
+ if (goalStateTool) {
2088
+ const wrappedGoalStateTool = wrapToolWithMetaNotice(goalStateTool);
2089
+ builtinCandidateTools.push(wrappedGoalStateTool);
2090
+ toolRegistry.set(wrappedGoalStateTool.name, wrappedGoalStateTool);
2091
+ }
2092
+ }
2093
+ }
2094
+ for (const tool of wrappedExtensionTools) {
2095
+ toolRegistry.set(tool.name, tool);
2096
+ }
2097
+ if (extensionRunner) {
2098
+ for (const tool of toolRegistry.values()) {
2099
+ toolRegistry.set(tool.name, new ExtensionToolWrapper(tool, extensionRunner));
2100
+ }
2101
+ }
2102
+ if (model?.provider === "cursor") {
2103
+ toolRegistry.delete("edit");
2104
+ builtinCandidateTools = builtinCandidateTools.filter(tool => tool.name !== "edit");
2105
+ }
2106
+
2107
+ const hasDeferrableTools = Array.from(toolRegistry.values()).some(tool => tool.deferrable === true);
2108
+ if (!hasDeferrableTools) {
2109
+ toolRegistry.delete("resolve");
2110
+ } else if (!toolRegistry.has("resolve")) {
2111
+ const resolveTool = await logger.time("createTools:resolve:session", HIDDEN_TOOLS.resolve, toolSession);
2112
+ if (resolveTool) {
2113
+ const wrappedResolveTool = wrapToolWithMetaNotice(resolveTool);
2114
+ builtinCandidateTools.push(wrappedResolveTool);
2115
+ toolRegistry.set(wrappedResolveTool.name, wrappedResolveTool);
2116
+ }
2117
+ }
2118
+ // Exact-config MCP tools cannot claim a name already represented by the final candidate catalog.
2119
+ // Other catalog collisions retain their legacy override behavior.
2120
+ if (exactMcpToolNames.length > 0) {
2121
+ const catalogToolNames = [
2122
+ ...builtinCandidateTools.map(tool => tool.name),
2123
+ ...preExactCustomToolNames,
2124
+ ...wrappedExtensionTools.map(tool => tool.name),
2125
+ ];
2126
+ const collidingToolNames = findExactMcpToolNameCollisions(exactMcpToolNames, catalogToolNames);
2127
+ if (collidingToolNames.length > 0) {
2128
+ throw new ExactMcpToolNameCollisionError(collidingToolNames);
2129
+ }
2130
+ }
2131
+
2132
+ const reloadSshTool = async (): Promise<AgentTool | null> => {
2133
+ if (!requestedToolNameSet.has("ssh")) return null;
2134
+ const sshTool = (await loadSshTool({
2135
+ ...toolSession,
2136
+ cwd: sessionManager.getCwd(),
2137
+ })) as unknown as AgentTool | null;
2138
+ if (!sshTool) return null;
2139
+ const wrapped = wrapToolWithMetaNotice(sshTool);
2140
+ return (extensionRunner ? new ExtensionToolWrapper(wrapped, extensionRunner) : wrapped) as AgentTool;
2141
+ };
2142
+
2143
+ let cursorEventEmitter: ((event: AgentEvent) => void) | undefined;
2144
+ const cursorExecHandlers = new CursorExecHandlers({
2145
+ cwd,
2146
+ tools: toolRegistry,
2147
+ getToolContext: () => toolContextStore.getContext(),
2148
+ emitEvent: event => cursorEventEmitter?.(event),
2149
+ createEventEmitter: () => agent.createExternalEventEmitterForCurrentRun(),
2150
+ });
2151
+
2152
+ const repeatToolDescriptions = settings.get("repeatToolDescriptions");
2153
+ const eagerTasks = settings.get("task.eager");
2154
+ const intentTracingEnabled = resolveIntentTracingEnabled(
2155
+ settings.get("tools.intentTracing"),
2156
+ options.hasUI ?? false,
2157
+ );
2158
+ const intentField = intentTracingEnabled ? INTENT_FIELD : undefined;
2159
+ const rebuildSystemPrompt = async (
2160
+ toolNames: string[],
2161
+ tools: Map<string, AgentTool>,
2162
+ candidateModel?: Model,
2163
+ ): Promise<BuildSystemPromptResult> => {
2164
+ toolContextStore.setToolNames(toolNames);
2165
+ const promptTools = (() => {
2166
+ const previousPromptMetadataModel = promptMetadataModel;
2167
+ promptMetadataModel = candidateModel;
2168
+ try {
2169
+ return buildSystemPromptToolMetadata(tools);
2170
+ } finally {
2171
+ promptMetadataModel = previousPromptMetadataModel;
2172
+ }
2173
+ })();
2174
+ const memoryInstructions = await resolveMemoryBackend(settings).buildDeveloperInstructions(
2175
+ agentDir,
2176
+ settings,
2177
+ session,
2178
+ );
2179
+
2180
+ const appendPrompt: string | undefined = memoryInstructions ?? undefined;
2181
+ let pluginSystemAppendices = "";
2182
+ try {
2183
+ pluginSystemAppendices = await renderAlwaysOnSystemAppendices({ cwd });
2184
+ } catch (error) {
2185
+ logger.warn("Failed to render SKC plugin system appendices", { error });
2186
+ }
2187
+ const defaultPrompt = await buildSystemPromptInternal({
2188
+ cwd,
2189
+ skills,
2190
+ contextFiles,
2191
+ tools: promptTools,
2192
+ toolNames,
2193
+ rules: rulebookRules,
2194
+ alwaysApplyRules,
2195
+ skillsSettings: settings.getGroup("skills"),
2196
+ appendSystemPrompt: appendPrompt,
2197
+ pluginAppendices: pluginSystemAppendices,
2198
+ repeatToolDescriptions,
2199
+ intentField,
2200
+ toolDiscoveryActive: effectiveDiscoveryMode === "all" || mcpDiscoveryEnabled,
2201
+ eagerTasks,
2202
+ secretsEnabled,
2203
+ workspaceTree: workspaceTreePromise,
2204
+ subagent: options.parentTaskPrefix !== undefined,
2205
+ });
2206
+
2207
+ if (options.systemPrompt === undefined) {
2208
+ return defaultPrompt;
2209
+ }
2210
+ if (Array.isArray(options.systemPrompt)) {
2211
+ return { systemPrompt: options.systemPrompt };
2212
+ }
2213
+ return {
2214
+ systemPrompt: options.systemPrompt(defaultPrompt.systemPrompt),
2215
+ };
2216
+ };
2217
+
2218
+ const toolNamesFromRegistry = Array.from(toolRegistry.keys());
2219
+ const hasExplicitToolNames = options.toolNames !== undefined;
2220
+ const requestedToolNames = hasExplicitToolNames
2221
+ ? [
2222
+ ...new Set([
2223
+ ...options.toolNames!.map(name => name.toLowerCase()),
2224
+ ...(settings.get("goal.enabled") ? ["goal"] : []),
2225
+ ]),
2226
+ ]
2227
+ : toolNamesFromRegistry;
2228
+ const normalizedRequested = requestedToolNames.filter(name => toolRegistry.has(name));
2229
+ const explicitRequestedToolNames = hasExplicitToolNames ? normalizedRequested : [];
2230
+ const requestedToolNameSet = new Set(normalizedRequested);
2231
+ // Normalize the user-facing mcp.discoveryMode alias once at session construction.
2232
+ const toolsDiscoveryModeSetting = settings.get("tools.discoveryMode");
2233
+ const effectiveDiscoveryMode: "off" | "mcp-only" | "all" =
2234
+ toolsDiscoveryModeSetting !== "off"
2235
+ ? (toolsDiscoveryModeSetting as "mcp-only" | "all")
2236
+ : settings.get("mcp.discoveryMode") || explicitMcpConfigPath !== undefined
2237
+ ? "mcp-only"
2238
+ : "off";
2239
+ const mcpDiscoveryEnabled = effectiveDiscoveryMode !== "off";
2240
+ const defaultInactiveToolNames = new Set(
2241
+ registeredTools.filter(tool => tool.definition.defaultInactive).map(tool => tool.definition.name),
2242
+ );
2243
+ const requestedActiveToolNames = normalizedRequested;
2244
+ const initialRequestedActiveToolNames = options.toolNames
2245
+ ? requestedActiveToolNames
2246
+ : requestedActiveToolNames.filter(name => !defaultInactiveToolNames.has(name));
2247
+ const discoverableMCPToolNames = new Set<string>();
2248
+ const explicitlyRequestedMCPToolNames: string[] = [];
2249
+ const discoveryDefaultServerToolNames: string[] = [];
2250
+ let initialSelectedMCPToolNames: string[] = [];
2251
+ let defaultSelectedMCPToolNames: string[] = [];
2252
+ let initialBaselineDiscoveredBuiltinToolNames: string[] = [];
2253
+ let initialSelectedDiscoveredBuiltinToolNames: string[] = [];
2254
+ let hasExplicitMCPToolSelection = false;
2255
+ let hasExplicitDiscoveredBuiltinToolSelection = false;
2256
+ let explicitlyRequestedDiscoveredBuiltinToolNames: string[] = [];
2257
+ if (mcpDiscoveryEnabled) {
2258
+ const defaultServerNames = new Set(settings.get("mcp.discoveryDefaultServers") ?? []);
2259
+ for (const tool of toolRegistry.values()) {
2260
+ if (!isMCPBridgeTool(tool)) continue;
2261
+ discoverableMCPToolNames.add(tool.name);
2262
+ if (explicitRequestedToolNames.includes(tool.name)) {
2263
+ explicitlyRequestedMCPToolNames.push(tool.name);
2264
+ }
2265
+ const serverName = (tool as AgentTool & { mcpServerName?: string }).mcpServerName;
2266
+ if (serverName && defaultServerNames.has(serverName)) {
2267
+ discoveryDefaultServerToolNames.push(tool.name);
2268
+ }
2269
+ }
2270
+ }
2271
+ const mandatoryMCPToolNameSet = new Set(pluginMcpToolNames);
2272
+ const selectableExplicitMCPToolNames = explicitlyRequestedMCPToolNames.filter(
2273
+ name => !mandatoryMCPToolNameSet.has(name),
2274
+ );
2275
+ let initialToolNames = [...initialRequestedActiveToolNames];
2276
+ if (mcpDiscoveryEnabled) {
2277
+ const restoredSelectedMCPToolNames = existingSession.selectedMCPToolNames.filter(
2278
+ name => toolRegistry.has(name) && !mandatoryMCPToolNameSet.has(name),
2279
+ );
2280
+ if (
2281
+ existingSession.hasPersistedMCPToolSelection &&
2282
+ restoredSelectedMCPToolNames.length !== existingSession.selectedMCPToolNames.length
2283
+ ) {
2284
+ sessionManager.appendMCPToolSelection(restoredSelectedMCPToolNames);
2285
+ }
2286
+ defaultSelectedMCPToolNames = [
2287
+ ...new Set([
2288
+ ...discoveryDefaultServerToolNames,
2289
+ ...(explicitMcpConfigPath !== undefined ? exactMcpToolNames : []),
2290
+ ]),
2291
+ ];
2292
+ hasExplicitMCPToolSelection =
2293
+ hasExplicitToolNames && (options.toolNames!.length === 0 || selectableExplicitMCPToolNames.length > 0);
2294
+ initialSelectedMCPToolNames = existingSession.hasPersistedMCPToolSelection
2295
+ ? restoredSelectedMCPToolNames
2296
+ : hasExplicitMCPToolSelection
2297
+ ? selectableExplicitMCPToolNames
2298
+ : defaultSelectedMCPToolNames;
2299
+ initialToolNames = [
2300
+ ...new Set([
2301
+ ...initialRequestedActiveToolNames.filter(name => !discoverableMCPToolNames.has(name)),
2302
+ ...initialSelectedMCPToolNames,
2303
+ ]),
2304
+ ];
2305
+ }
2306
+
2307
+ // Custom, extension-registered, and plugin-bundle MCP tools are always
2308
+ // included regardless of the caller's built-in tool filter. Plugin MCPs
2309
+ // remain always-on even when generic MCP discovery is disabled.
2310
+ const alwaysInclude: string[] = [
2311
+ ...(options.customTools?.map(t => (isCustomTool(t) ? t.name : t.name)) ?? []),
2312
+ ...registeredTools.filter(t => !t.definition.defaultInactive).map(t => t.definition.name),
2313
+ ...pluginMcpToolNames,
2314
+ ];
2315
+ const pluginMcpToolNameSet = new Set(pluginMcpToolNames);
2316
+ for (const name of alwaysInclude) {
2317
+ if (mcpDiscoveryEnabled && discoverableMCPToolNames.has(name) && !pluginMcpToolNameSet.has(name)) {
2318
+ continue;
2319
+ }
2320
+ if (toolRegistry.has(name) && !initialToolNames.includes(name)) {
2321
+ initialToolNames.push(name);
2322
+ }
2323
+ }
2324
+
2325
+ // When tools.discoveryMode === "all", hide non-essential built-in discoverable tools
2326
+ // from the initial set unless they were explicitly requested or restored from persistence.
2327
+ // The model finds them via search_tool_bm25 and activates them on demand.
2328
+ if (effectiveDiscoveryMode === "all") {
2329
+ const essentialBuiltinNames = new Set(computeEssentialBuiltinNames(settings));
2330
+ const allowedDiscoveredBuiltinNames = options.discoverableToolAllowedNames
2331
+ ? new Set(options.discoverableToolAllowedNames.map(name => name.toLowerCase()))
2332
+ : undefined;
2333
+ const baselineInitialToolNames = initialToolNames.filter(name => {
2334
+ const tool = toolRegistry.get(name);
2335
+ if (!tool?.loadMode) return true; // not a built-in — leave MCP/custom/extension to existing logic
2336
+ if (tool.loadMode === "essential") return true;
2337
+ return essentialBuiltinNames.has(name);
2338
+ });
2339
+ explicitlyRequestedDiscoveredBuiltinToolNames = selectRestorableDiscoveredBuiltinToolNames(
2340
+ explicitRequestedToolNames,
2341
+ toolRegistry,
2342
+ allowedDiscoveredBuiltinNames,
2343
+ ).filter(name => !essentialBuiltinNames.has(name));
2344
+ const requestedDiscoveredBuiltinToolNameSet = new Set(explicitlyRequestedDiscoveredBuiltinToolNames);
2345
+ initialBaselineDiscoveredBuiltinToolNames = selectRestorableDiscoveredBuiltinToolNames(
2346
+ baselineInitialToolNames.filter(name => !requestedDiscoveredBuiltinToolNameSet.has(name)),
2347
+ toolRegistry,
2348
+ allowedDiscoveredBuiltinNames,
2349
+ );
2350
+ const restoredDiscoveredNames = selectRestorableDiscoveredBuiltinToolNames(
2351
+ existingSession.selectedDiscoveredBuiltinToolNames ?? [],
2352
+ toolRegistry,
2353
+ allowedDiscoveredBuiltinNames,
2354
+ essentialBuiltinNames,
2355
+ );
2356
+ initialSelectedDiscoveredBuiltinToolNames = existingSession.hasPersistedDiscoveredBuiltinToolSelection
2357
+ ? restoredDiscoveredNames
2358
+ : explicitlyRequestedDiscoveredBuiltinToolNames;
2359
+ initialToolNames = [...new Set([...baselineInitialToolNames, ...initialSelectedDiscoveredBuiltinToolNames])];
2360
+ hasExplicitDiscoveredBuiltinToolSelection =
2361
+ hasExplicitToolNames &&
2362
+ (options.toolNames!.length === 0 || explicitlyRequestedDiscoveredBuiltinToolNames.length > 0);
2363
+ }
2364
+
2365
+ // Pre-register in the global agent registry BEFORE building the system prompt,
2366
+ // so that subagents launched in the same parallel batch can see each other in
2367
+ // their initial `# IRC Peers` block (rendered inside `rebuildSystemPrompt`).
2368
+ // The session reference is attached after construction below.
2369
+ agentRegistry.register({
2370
+ id: resolvedAgentId,
2371
+ displayName: resolvedAgentDisplayName,
2372
+ rosterLabel: resolvedAgentRosterLabel,
2373
+ kind: isCanonicalSubSession ? "sub" : "main",
2374
+ parentId: options.parentTaskPrefix,
2375
+ session: null,
2376
+ sessionFile: sessionManager.getSessionFile() ?? null,
2377
+ status: "running",
2378
+ });
2379
+ hasRegistered = true;
2380
+
2381
+ const { systemPrompt } = await logger.time(
2382
+ "buildSystemPrompt",
2383
+ rebuildSystemPrompt,
2384
+ initialToolNames,
2385
+ toolRegistry,
2386
+ );
2387
+
2388
+ const promptTemplates = await promptTemplatesPromise;
2389
+ toolSession.promptTemplates = promptTemplates;
2390
+
2391
+ const slashCommands = await slashCommandsPromise;
2392
+
2393
+ // Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)
2394
+ const convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {
2395
+ const converted = convertToLlm(messages);
2396
+ // Check setting dynamically so mid-session changes take effect
2397
+ if (!settings.get("images.blockImages")) {
2398
+ return converted;
2399
+ }
2400
+ // Filter out ImageContent from all messages, replacing with text placeholder
2401
+ return converted.map(msg => {
2402
+ if (msg.role === "user" || msg.role === "toolResult") {
2403
+ const content = msg.content;
2404
+ if (Array.isArray(content)) {
2405
+ const hasImages = content.some(c => c.type === "image");
2406
+ if (hasImages) {
2407
+ const filteredContent = content
2408
+ .map(c =>
2409
+ c.type === "image" ? { type: "text" as const, text: "Image reading is disabled." } : c,
2410
+ )
2411
+ .filter((c, i, arr) => {
2412
+ // Dedupe consecutive "Image reading is disabled." texts
2413
+ if (!(c.type === "text" && c.text === "Image reading is disabled." && i > 0)) return true;
2414
+ const prev = arr[i - 1];
2415
+ return !(prev.type === "text" && prev.text === "Image reading is disabled.");
2416
+ });
2417
+ return { ...msg, content: filteredContent };
2418
+ }
2419
+ }
2420
+ }
2421
+ return msg;
2422
+ });
2423
+ };
2424
+
2425
+ // Final convertToLlm: chain block-images filter with secret obfuscation
2426
+ const convertToLlmFinal = (messages: AgentMessage[]): Message[] => {
2427
+ const converted = convertToLlmWithBlockImages(messages);
2428
+ if (!obfuscator?.hasSecrets()) return converted;
2429
+ return obfuscateMessages(obfuscator, converted);
2430
+ };
2431
+ const transformContext = async (messages: AgentMessage[], _signal?: AbortSignal) => {
2432
+ // External Agent events dispatch listeners without awaiting them. The
2433
+ // session-owned barrier makes any pre-admission artifact transformation
2434
+ // visible before this provider context is normalized.
2435
+ await session?.awaitPendingContextTransformations();
2436
+ return extensionRunner ? await extensionRunner.emitContext(messages) : messages;
2437
+ };
2438
+ const onPayload = extensionRunner
2439
+ ? async (payload: unknown, _model?: Model) => {
2440
+ return await extensionRunner.emitBeforeProviderRequest(payload);
2441
+ }
2442
+ : undefined;
2443
+ const onResponse: SimpleStreamOptions["onResponse"] | undefined = extensionRunner
2444
+ ? async (response, model) => {
2445
+ await extensionRunner.emitAfterProviderResponse(response, model);
2446
+ }
2447
+ : undefined;
2448
+
2449
+ const setToolUIContext = (uiContext: ExtensionUIContext, hasUI: boolean) => {
2450
+ toolContextStore.setUIContext(uiContext, hasUI);
2451
+ };
2452
+
2453
+ const initialTools = initialToolNames
2454
+ .map(name => toolRegistry.get(name))
2455
+ .filter((tool): tool is AgentTool => tool !== undefined)
2456
+ // AgentSession tool wrapping is not installed until after Agent construction.
2457
+ .map(tool =>
2458
+ guardToolForUltragoalAsk(
2459
+ tool,
2460
+ () => sessionManager.getCwd(),
2461
+ () => ({
2462
+ activeSkillState: session?.getActiveSkillState(),
2463
+ sessionId: sessionManager.getSessionId?.() ?? null,
2464
+ }),
2465
+ ),
2466
+ );
2467
+
2468
+ const openaiWebsocketSetting = settings.get("providers.openaiWebsockets") ?? "off";
2469
+ const preferOpenAICodexWebsockets =
2470
+ openaiWebsocketSetting === "on" ? true : openaiWebsocketSetting === "off" ? false : undefined;
2471
+ const serviceTierSetting = settings.get("serviceTier");
2472
+ const retrySettings = settings.getGroup("retry");
2473
+
2474
+ const initialServiceTier = hasServiceTierEntry
2475
+ ? existingSession.serviceTier
2476
+ : serviceTierSetting === "none"
2477
+ ? undefined
2478
+ : serviceTierSetting;
2479
+
2480
+ const appendOnlyContext =
2481
+ model && resolveAppendOnlyMode(settings.get("provider.appendOnlyContext"), model.provider)
2482
+ ? createAppendOnlyContextManager(model.provider)
2483
+ : undefined;
2484
+ if (appendOnlyContext && options.forkContextSeed && !hasExistingSession) {
2485
+ if (options.forkContextSeed.appendOnlyPrefixSnapshot) {
2486
+ (
2487
+ appendOnlyContext.prefix as typeof appendOnlyContext.prefix & {
2488
+ importSnapshot(
2489
+ snapshot: NonNullable<ForkContextSeed["appendOnlyPrefixSnapshot"]>,
2490
+ options: { intentTracing: boolean },
2491
+ ): void;
2492
+ }
2493
+ ).importSnapshot(options.forkContextSeed.appendOnlyPrefixSnapshot, { intentTracing: !!intentField });
2494
+ }
2495
+ (
2496
+ appendOnlyContext as AppendOnlyContextManager & {
2497
+ seedNormalizedMessages(messages: readonly Message[]): void;
2498
+ }
2499
+ ).seedNormalizedMessages(options.forkContextSeed.messages);
2500
+ }
2501
+
2502
+ agent = new Agent({
2503
+ initialState: {
2504
+ systemPrompt,
2505
+ model,
2506
+ thinkingLevel: toReasoningEffort(thinkingLevel),
2507
+ tools: initialTools,
2508
+ ...(options.forkContextSeed && !hasExistingSession
2509
+ ? { messages: options.forkContextSeed.agentMessages }
2510
+ : {}),
2511
+ },
2512
+ convertToLlm: convertToLlmFinal,
2513
+ onPayload,
2514
+ onResponse,
2515
+ sessionId: logicalSessionId,
2516
+ providerSessionId,
2517
+ transformContext,
2518
+ steeringMode: settings.get("steeringMode") ?? "one-at-a-time",
2519
+ followUpMode: settings.get("followUpMode") ?? "one-at-a-time",
2520
+ interruptMode: settings.get("interruptMode") ?? "immediate",
2521
+ thinkingBudgets: settings.getGroup("thinkingBudgets"),
2522
+ temperature: settings.get("temperature") >= 0 ? settings.get("temperature") : undefined,
2523
+ topP: settings.get("topP") >= 0 ? settings.get("topP") : undefined,
2524
+ topK: settings.get("topK") >= 0 ? settings.get("topK") : undefined,
2525
+ minP: settings.get("minP") >= 0 ? settings.get("minP") : undefined,
2526
+ presencePenalty: settings.get("presencePenalty") >= 0 ? settings.get("presencePenalty") : undefined,
2527
+ repetitionPenalty: settings.get("repetitionPenalty") >= 0 ? settings.get("repetitionPenalty") : undefined,
2528
+ serviceTier: initialServiceTier,
2529
+ hideThinkingSummary: settings.get("hideThinkingBlock"),
2530
+ maxRetryDelayMs: retrySettings.maxDelayMs,
2531
+ requestMaxRetries: retrySettings.requestMaxRetries,
2532
+ streamMaxRetries: retrySettings.streamMaxRetries,
2533
+ kimiApiFormat: settings.get("providers.kimiApiFormat") ?? "anthropic",
2534
+ shouldPause: options.shouldPause,
2535
+ preferWebsockets: preferOpenAICodexWebsockets,
2536
+ getToolContext: tc => toolContextStore.getContext(tc),
2537
+ getApiKey: async provider => {
2538
+ // Read agent.sessionId at call time so credential selection stays aligned
2539
+ // with metadataResolver after /new, fork, resume, or branch switches.
2540
+ const key = await modelRegistry.getApiKeyForProvider(provider, agent.providerSessionId ?? agent.sessionId);
2541
+ if (!key) {
2542
+ throw new Error(`No API key found for provider "${provider}"`);
2543
+ }
2544
+ return key;
2545
+ },
2546
+ getAuthCredentialType: provider =>
2547
+ modelRegistry.getSessionCredentialType(provider, agent.providerSessionId ?? agent.sessionId),
2548
+ streamFn: (streamModel, context, streamOptions) =>
2549
+ streamSimple(streamModel, context, {
2550
+ ...streamOptions,
2551
+ onAuthError: async (provider, oldKey, error) => {
2552
+ await modelRegistry.authStorage.invalidateCredentialMatching(provider, oldKey, {
2553
+ signal: streamOptions?.signal,
2554
+ sessionId: agent.sessionId,
2555
+ });
2556
+ logger.debug("Retrying provider request after credential invalidation", {
2557
+ provider,
2558
+ error: error instanceof Error ? error.message : String(error),
2559
+ });
2560
+ return modelRegistry.getApiKeyForProvider(provider, agent.sessionId);
2561
+ },
2562
+ }),
2563
+ cursorExecHandlers,
2564
+ transformToolCallArguments: (args, _toolName) => {
2565
+ let result = args;
2566
+ const maxTimeout = settings.get("tools.maxTimeout");
2567
+ if (maxTimeout > 0 && typeof result.timeout === "number") {
2568
+ result = { ...result, timeout: Math.min(result.timeout, maxTimeout) };
2569
+ }
2570
+ if (obfuscator?.hasSecrets()) {
2571
+ result = obfuscator.deobfuscateObject(result);
2572
+ }
2573
+ return result;
2574
+ },
2575
+ onToolChoiceIncapability: event => {
2576
+ const droppedLabel = session?.toolChoiceQueue.degradeInFlight(event.reason);
2577
+ logger.debug("Dropped in-flight tool choice after runtime incapability", {
2578
+ droppedLabel,
2579
+ api: event.api,
2580
+ provider: event.provider,
2581
+ model: event.model,
2582
+ requestedLevel: event.requestedLevel,
2583
+ resolvedLevel: event.resolvedLevel,
2584
+ reason: event.reason,
2585
+ registryKey: event.registryKey,
2586
+ });
2587
+ },
2588
+ intentTracing: !!intentField,
2589
+ getToolChoice: () => session?.nextToolChoice(),
2590
+ telemetry: options.telemetry,
2591
+ appendOnlyContext,
2592
+ });
2593
+
2594
+ cursorEventEmitter = event => agent.emitExternalEvent(event);
2595
+
2596
+ // Restore messages if session has existing data
2597
+ if (hasExistingSession) {
2598
+ agent.replaceMessages(reconcileTrailingToolCalls(existingSession.messages));
2599
+ } else {
2600
+ // Save initial model, thinking level, and service tier for new sessions so they can be restored on resume.
2601
+ if (model) {
2602
+ const substitution = options.modelSubstitution;
2603
+ sessionManager.appendModelChange(
2604
+ `${model.provider}/${model.id}`,
2605
+ undefined,
2606
+ substitution
2607
+ ? {
2608
+ previousModel: `${substitution.requestedModel.provider}/${substitution.requestedModel.id}`,
2609
+ reason: substitution.reason,
2610
+ thinkingLevel: thinkingLevel ?? null,
2611
+ }
2612
+ : undefined,
2613
+ );
2614
+ }
2615
+ sessionManager.appendThinkingLevelChange(options.thinkingLevel ?? ThinkingLevel.Inherit);
2616
+ if (initialServiceTier) {
2617
+ sessionManager.appendServiceTierChange(initialServiceTier);
2618
+ }
2619
+ }
2620
+
2621
+ session = new AgentSession({
2622
+ agent,
2623
+ thinkingLevel,
2624
+ sessionManager,
2625
+ settings,
2626
+ notificationSessionController,
2627
+ evalKernelOwnerId,
2628
+ // Defined only for top-level sessions (creation is gated above).
2629
+ // AgentSession uses this to decide whether it may dispose the global
2630
+ // AsyncJobManager on teardown; subagents inherit the parent's and
2631
+ // **MUST NOT** tear it down.
2632
+ ownedAsyncJobManager: asyncJobManager,
2633
+ // Only an MCP manager owned by this session is torn down on dispose;
2634
+ // subagents and callers that merely observe a manager must not (see
2635
+ // AgentSession.dispose).
2636
+ ownedMcpManager: ownsMcpManager ? mcpManager : undefined,
2637
+ scopedModels: options.scopedModels,
2638
+ promptTemplates,
2639
+ slashCommands,
2640
+ extensionRunner,
2641
+ customCommands: customCommandsResult.commands,
2642
+ skills,
2643
+ skillWarnings,
2644
+ skillsSettings: settings.getGroup("skills"),
2645
+ modelRegistry,
2646
+ taskDepth,
2647
+ toolRegistry,
2648
+ workflowGateToolSession: toolSession,
2649
+ transformContext,
2650
+ onPayload,
2651
+ onResponse,
2652
+ convertToLlm: convertToLlmFinal,
2653
+ rebuildSystemPrompt,
2654
+ getMcpServerInstructions:
2655
+ explicitMcpConfigPath === undefined && mcpManager ? () => mcpManager.getServerInstructions() : undefined,
2656
+ workspaceTree: resolvedWorkspaceTree,
2657
+ reloadSshTool,
2658
+ requestedToolNames: requestedToolNameSet,
2659
+ discoverableToolAllowedNames: options.discoverableToolAllowedNames,
2660
+ mcpDiscoveryEnabled,
2661
+ discoveryMode: effectiveDiscoveryMode,
2662
+ initialSelectedMCPToolNames,
2663
+ initialMCPToolSelectionIsExplicit: hasExplicitMCPToolSelection,
2664
+ initialDiscoveredBuiltinToolSelectionIsExplicit: hasExplicitDiscoveredBuiltinToolSelection,
2665
+ initialSelectedDiscoveredBuiltinToolNames,
2666
+ initialBaselineDiscoveredBuiltinToolNames,
2667
+ defaultSelectedMCPToolNames,
2668
+ mandatoryMCPToolNames: pluginMcpToolNames,
2669
+ persistInitialMCPToolSelection: !hasExistingSession && hasExplicitMCPToolSelection,
2670
+ persistInitialDiscoveredBuiltinToolSelection: !hasExistingSession && hasExplicitDiscoveredBuiltinToolSelection,
2671
+ initialPersistedMCPToolNames: selectableExplicitMCPToolNames,
2672
+ initialPersistedDiscoveredBuiltinToolNames: explicitlyRequestedDiscoveredBuiltinToolNames,
2673
+ defaultSelectedMCPServerNames: settings.get("mcp.discoveryDefaultServers") ?? [],
2674
+ ttsrManager,
2675
+ obfuscator,
2676
+ agentId: resolvedAgentId,
2677
+ agentRegistry,
2678
+ providerSessionId: options.providerSessionId,
2679
+ providerCacheSessionId: providerSessionId,
2680
+ forkContextSeed: options.forkContextSeed,
2681
+ providerSessionState: options.providerSessionState,
2682
+ });
2683
+ hasSession = true;
2684
+ if (asyncJobManager) {
2685
+ session.yieldQueue.register<AsyncResultEntry>("async-result", {
2686
+ isStale: entry => asyncJobManager.isDeliverySuppressed(entry.jobId),
2687
+ build: buildAsyncResultBatchMessage,
2688
+ });
2689
+ }
2690
+ session.yieldQueue.register<McpNotificationEntry>("mcp-notification", {
2691
+ build: buildMcpNotificationBatchMessage,
2692
+ });
2693
+
2694
+ // Attach the live session to the pre-registered ref so peers can route IRC
2695
+ // messages here. Refresh sessionFile in case it was unavailable at pre-register
2696
+ // time. The dispose wrapper below unregisters on teardown.
2697
+ agentRegistry.attachSession(resolvedAgentId, session, sessionManager.getSessionFile() ?? null);
2698
+ {
2699
+ const originalDispose = session.dispose.bind(session);
2700
+ session.dispose = async () => {
2701
+ try {
2702
+ await originalDispose();
2703
+ } finally {
2704
+ try {
2705
+ agentRegistry.unregister(resolvedAgentId);
2706
+ releaseCredentialDisabledSubscription();
2707
+ releaseLocalProtocolOverride();
2708
+ } finally {
2709
+ closeOwnedAuthStorage();
2710
+ }
2711
+ }
2712
+ };
2713
+ }
2714
+
2715
+ if (model?.api === "openai-codex-responses") {
2716
+ const codexModel = model;
2717
+ const codexTransport = getOpenAICodexTransportDetails(codexModel, {
2718
+ sessionId: providerSessionId,
2719
+ baseUrl: codexModel.baseUrl,
2720
+ preferWebsockets: preferOpenAICodexWebsockets,
2721
+ providerSessionState: session.providerSessionState,
2722
+ });
2723
+ if (codexTransport.websocketPreferred) {
2724
+ void (async () => {
2725
+ try {
2726
+ const codexPrewarmApiKey = await modelRegistry.getApiKey(codexModel, providerSessionId);
2727
+ if (!codexPrewarmApiKey) return;
2728
+ await logger.time("prewarmOpenAICodexResponses", prewarmOpenAICodexResponses, codexModel, {
2729
+ apiKey: codexPrewarmApiKey,
2730
+ sessionId: providerSessionId,
2731
+ preferWebsockets: preferOpenAICodexWebsockets,
2732
+ providerSessionState: session.providerSessionState,
2733
+ });
2734
+ } catch (error) {
2735
+ const errorMessage = error instanceof Error ? error.message : String(error);
2736
+ logger.debug("Codex websocket prewarm failed", {
2737
+ error: errorMessage,
2738
+ provider: codexModel.provider,
2739
+ model: codexModel.id,
2740
+ });
2741
+ }
2742
+ })();
2743
+ }
2744
+ }
2745
+
2746
+ // Discover configured LSP servers for the interactive status display without starting them.
2747
+ // LSP-backed write operations create clients on demand through `getOrCreateClient`.
2748
+ const lspServers =
2749
+ enableLsp && options.hasUI && settings.get("lsp.diagnosticsOnWrite")
2750
+ ? discoverStartupLspServers(cwd)
2751
+ : undefined;
2752
+
2753
+ logger.time("startMemoryStartupTask", () =>
2754
+ Promise.resolve(
2755
+ resolveMemoryBackend(settings).start({
2756
+ session,
2757
+ settings,
2758
+ modelRegistry,
2759
+ agentDir,
2760
+ taskDepth,
2761
+ parentHindsightSessionState: options.parentHindsightSessionState,
2762
+ }),
2763
+ ),
2764
+ );
2765
+
2766
+ // Exact-config managers do not receive reactive callbacks; their tools are
2767
+ // registered once in the session-owned catalog.
2768
+ if (mcpManager && !options.mcpManager && explicitMcpConfigPath === undefined) {
2769
+ // The owned plugin-bundle manager surfaces its tools as always-on custom
2770
+ // tools (registered above), so it must NOT drive refreshMCPTools — that
2771
+ // path strips MCP bridge tools and re-gates them behind MCP selection,
2772
+ // which would deactivate the always-on plugin tools. Reactive tool
2773
+ // updates remain wired only for externally supplied managers.
2774
+ // The owned manager is disconnected by AgentSession.dispose via
2775
+ // ownedMcpManager; only externally supplied managers wire reactive
2776
+ // refreshMCPTools (the owned always-on path must not, or it would
2777
+ // deactivate the plugin tools).
2778
+ if (!ownsMcpManager) {
2779
+ mcpManager.setOnToolsChanged(tools => {
2780
+ void session.refreshMCPTools(tools);
2781
+ });
2782
+ }
2783
+ // Wire prompt refresh → rebuild MCP prompt slash commands
2784
+ mcpManager.setOnPromptsChanged(serverName => {
2785
+ const promptCommands = buildMCPPromptCommands(mcpManager);
2786
+ session.setMCPPromptCommands(promptCommands);
2787
+ logger.debug("MCP prompt commands refreshed", { path: `mcp:${serverName}` });
2788
+ });
2789
+ const notificationDebounceTimers = new Map<string, Timer>();
2790
+ const clearDebounceTimers = () => {
2791
+ for (const timer of notificationDebounceTimers.values()) clearTimeout(timer);
2792
+ notificationDebounceTimers.clear();
2793
+ };
2794
+ postmortem.register("mcp-notification-cleanup", clearDebounceTimers);
2795
+ mcpManager.setOnResourcesChanged((serverName, uri) => {
2796
+ logger.debug("MCP resources changed", { path: `mcp:${serverName}`, uri });
2797
+ if (!settings.get("mcp.notifications")) return;
2798
+ const debounceMs = settings.get("mcp.notificationDebounceMs");
2799
+ const key = `${serverName}:${uri}`;
2800
+ const existing = notificationDebounceTimers.get(key);
2801
+ if (existing) clearTimeout(existing);
2802
+ notificationDebounceTimers.set(
2803
+ key,
2804
+ setTimeout(() => {
2805
+ notificationDebounceTimers.delete(key);
2806
+ // Re-check: user may have disabled notifications during the debounce window
2807
+ if (!settings.get("mcp.notifications")) return;
2808
+ session.yieldQueue.enqueue<McpNotificationEntry>("mcp-notification", { serverName, uri });
2809
+ }, debounceMs),
2810
+ );
2811
+ });
2812
+ }
2813
+
2814
+ // Constructor-time workflow-gate tool restoration is deferred by one
2815
+ // microtask (the ToolSession closure needs `session` assigned). Await it
2816
+ // so a resumed canonical workflow session returns with `ask` resident.
2817
+ await session.workflowGateToolRestoration;
2818
+ return {
2819
+ session,
2820
+ extensionsResult,
2821
+ setToolUIContext,
2822
+ mcpManager: ownsMcpManager && mcpManager?.isToolsOnly() ? undefined : mcpManager,
2823
+ modelFallbackMessage,
2824
+ lspServers,
2825
+ eventBus,
2826
+ };
2827
+ } catch (error) {
2828
+ // Release the subscription if the throw happened after install but before the
2829
+ // dispose-wrap took ownership.
2830
+ releaseCredentialDisabledSubscription();
2831
+ try {
2832
+ if (hasSession) {
2833
+ await session.dispose();
2834
+ } else {
2835
+ if (hasRegistered) agentRegistry.unregister(resolvedAgentId);
2836
+ await cleanupOwnedMcpManager?.();
2837
+ await disposeKernelSessionsByOwner(evalKernelOwnerId);
2838
+ await disposeVmContextsByOwner(evalKernelOwnerId);
2839
+ }
2840
+ } catch {
2841
+ logger.warn("Failed to clean up createAgentSession resources after startup error");
2842
+ } finally {
2843
+ releaseLocalProtocolOverride();
2844
+ try {
2845
+ closeOwnedAuthStorage();
2846
+ } catch {
2847
+ logger.warn("Failed to close owned auth storage after startup error");
2848
+ }
2849
+ }
2850
+ throw error;
2851
+ }
2852
+ }
2853
+
2854
+ /**
2855
+ * Best-effort preconnect to the model's API host. Bun's `fetch.preconnect`
2856
+ * primes DNS + TCP + TLS + H2 so the first real request reuses the warm
2857
+ * connection. Errors are swallowed: preconnect is an optimization, never a
2858
+ * hard dependency.
2859
+ */
2860
+ function preconnectModelHost(baseUrl: string | undefined): void {
2861
+ if (!baseUrl) return;
2862
+ const preconnect = (globalThis.fetch as typeof fetch & { preconnect?: (url: string) => void }).preconnect;
2863
+ if (typeof preconnect !== "function") return;
2864
+ try {
2865
+ preconnect(baseUrl);
2866
+ } catch {
2867
+ // Best effort.
2868
+ }
2869
+ }