@bubblebrain-ai/bubble 0.0.63 → 0.0.65

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 (912) hide show
  1. package/README.md +437 -11
  2. package/dist/agent/abort-errors.d.ts +18 -0
  3. package/dist/agent/abort-errors.js +51 -0
  4. package/dist/agent/budget-ledger.d.ts +20 -0
  5. package/dist/agent/budget-ledger.js +45 -0
  6. package/dist/agent/categories.d.ts +100 -0
  7. package/dist/agent/categories.js +203 -0
  8. package/dist/agent/change-tracker.d.ts +40 -0
  9. package/dist/agent/change-tracker.js +89 -0
  10. package/dist/agent/child-runner.d.ts +64 -0
  11. package/dist/agent/child-runner.js +405 -0
  12. package/dist/agent/input-controller.d.ts +14 -0
  13. package/dist/agent/input-controller.js +43 -0
  14. package/dist/agent/internal-reminder-sanitizer.d.ts +25 -0
  15. package/dist/agent/internal-reminder-sanitizer.js +297 -0
  16. package/dist/agent/profiles.d.ts +76 -0
  17. package/dist/agent/profiles.js +526 -0
  18. package/dist/agent/provider-fingerprint.d.ts +6 -0
  19. package/dist/agent/provider-fingerprint.js +89 -0
  20. package/dist/agent/resident-history.d.ts +7 -0
  21. package/dist/agent/resident-history.js +61 -0
  22. package/dist/agent/result-integrator.d.ts +22 -0
  23. package/dist/agent/result-integrator.js +50 -0
  24. package/dist/agent/routing-catalog.d.ts +131 -0
  25. package/dist/agent/routing-catalog.js +260 -0
  26. package/dist/agent/structured-output.d.ts +37 -0
  27. package/dist/agent/structured-output.js +193 -0
  28. package/dist/agent/subagent/router.d.ts +65 -0
  29. package/dist/agent/subagent/router.js +203 -0
  30. package/dist/agent/subagent/runtime.d.ts +235 -0
  31. package/dist/agent/subagent/runtime.js +835 -0
  32. package/dist/agent/subagent-control.d.ts +100 -0
  33. package/dist/agent/subagent-control.js +70 -0
  34. package/dist/agent/subagent-lifecycle-reminder.d.ts +3 -0
  35. package/dist/agent/subagent-lifecycle-reminder.js +112 -0
  36. package/dist/agent/subagent-route-format.d.ts +8 -0
  37. package/dist/agent/subagent-route-format.js +18 -0
  38. package/dist/agent/subagent-scheduler.d.ts +105 -0
  39. package/dist/agent/subagent-scheduler.js +287 -0
  40. package/dist/agent/subagent-store.d.ts +57 -0
  41. package/dist/agent/subagent-store.js +180 -0
  42. package/dist/agent/subagent-summary.d.ts +30 -0
  43. package/dist/agent/subagent-summary.js +74 -0
  44. package/dist/agent/subagent-wait-guidance.d.ts +2 -0
  45. package/dist/agent/subagent-wait-guidance.js +8 -0
  46. package/dist/agent/subtask-policy.d.ts +13 -0
  47. package/dist/agent/subtask-policy.js +56 -0
  48. package/dist/agent/task-lifecycle-reminder.d.ts +26 -0
  49. package/dist/agent/task-lifecycle-reminder.js +59 -0
  50. package/dist/agent/tool-intent.d.ts +45 -0
  51. package/dist/agent/tool-intent.js +318 -0
  52. package/dist/agent/tool-visibility.d.ts +10 -0
  53. package/dist/agent/tool-visibility.js +6 -0
  54. package/dist/agent/transcript-helpers.d.ts +20 -0
  55. package/dist/agent/transcript-helpers.js +63 -0
  56. package/dist/agent/update-queue.d.ts +13 -0
  57. package/dist/agent/update-queue.js +69 -0
  58. package/dist/agent/workflow/control.d.ts +60 -0
  59. package/dist/agent/workflow/control.js +62 -0
  60. package/dist/agent/workflow/errors.d.ts +16 -0
  61. package/dist/agent/workflow/errors.js +24 -0
  62. package/dist/agent/workflow/runs.d.ts +73 -0
  63. package/dist/agent/workflow/runs.js +160 -0
  64. package/dist/agent/workflow/runtime.d.ts +88 -0
  65. package/dist/agent/workflow/runtime.js +319 -0
  66. package/dist/agent/worktree.d.ts +29 -0
  67. package/dist/agent/worktree.js +73 -0
  68. package/dist/agent.d.ts +460 -0
  69. package/dist/agent.js +2210 -0
  70. package/dist/anthropic-thinking.d.ts +4 -0
  71. package/dist/anthropic-thinking.js +11 -0
  72. package/dist/approval/controller.d.ts +71 -0
  73. package/dist/approval/controller.js +286 -0
  74. package/dist/approval/danger.d.ts +13 -0
  75. package/dist/approval/danger.js +55 -0
  76. package/dist/approval/diff-hunks.d.ts +12 -0
  77. package/dist/approval/diff-hunks.js +32 -0
  78. package/dist/approval/protected-paths.d.ts +1 -0
  79. package/dist/approval/protected-paths.js +35 -0
  80. package/dist/approval/session-cache.d.ts +21 -0
  81. package/dist/approval/session-cache.js +38 -0
  82. package/dist/approval/tool-helper.d.ts +14 -0
  83. package/dist/approval/tool-helper.js +47 -0
  84. package/dist/approval/types.d.ts +146 -0
  85. package/dist/approval/types.js +8 -0
  86. package/dist/bin.d.ts +2 -0
  87. package/dist/bin.js +3 -0
  88. package/dist/bubble-home.d.ts +8 -0
  89. package/dist/bubble-home.js +19 -0
  90. package/dist/checkpoints.d.ts +57 -0
  91. package/dist/checkpoints.js +0 -0
  92. package/dist/cli.d.ts +37 -0
  93. package/dist/cli.js +175 -0
  94. package/dist/clipboard.d.ts +14 -0
  95. package/dist/clipboard.js +132 -0
  96. package/dist/config.d.ts +96 -0
  97. package/dist/config.js +287 -0
  98. package/dist/context/budget.d.ts +28 -0
  99. package/dist/context/budget.js +130 -0
  100. package/dist/context/checkpoint.d.ts +18 -0
  101. package/dist/context/checkpoint.js +117 -0
  102. package/dist/context/compact-llm.d.ts +25 -0
  103. package/dist/context/compact-llm.js +175 -0
  104. package/dist/context/compact.d.ts +124 -0
  105. package/dist/context/compact.js +635 -0
  106. package/dist/context/compaction-files.d.ts +44 -0
  107. package/dist/context/compaction-files.js +148 -0
  108. package/dist/context/llm-compactor.d.ts +53 -0
  109. package/dist/context/llm-compactor.js +424 -0
  110. package/dist/context/overflow.d.ts +9 -0
  111. package/dist/context/overflow.js +50 -0
  112. package/dist/context/projector.d.ts +34 -0
  113. package/dist/context/projector.js +251 -0
  114. package/dist/context/prune.d.ts +26 -0
  115. package/dist/context/prune.js +171 -0
  116. package/dist/context/session-write-lock.d.ts +20 -0
  117. package/dist/context/session-write-lock.js +162 -0
  118. package/dist/context/token-estimator.d.ts +14 -0
  119. package/dist/context/token-estimator.js +106 -0
  120. package/dist/context/tool-images.d.ts +3 -0
  121. package/dist/context/tool-images.js +35 -0
  122. package/dist/context/tool-output-truncate.d.ts +24 -0
  123. package/dist/context/tool-output-truncate.js +181 -0
  124. package/dist/context/usage.d.ts +34 -0
  125. package/dist/context/usage.js +230 -0
  126. package/dist/debug-trace.d.ts +27 -0
  127. package/dist/debug-trace.js +401 -0
  128. package/dist/diff-stats.d.ts +5 -0
  129. package/dist/diff-stats.js +21 -0
  130. package/dist/external-runtime/grok-acp.d.ts +56 -0
  131. package/dist/external-runtime/grok-acp.js +386 -0
  132. package/dist/external-runtime/grok-binary.d.ts +25 -0
  133. package/dist/external-runtime/grok-binary.js +108 -0
  134. package/dist/external-runtime/grok-errors.d.ts +7 -0
  135. package/dist/external-runtime/grok-errors.js +15 -0
  136. package/dist/external-runtime/grok-input-policy.d.ts +58 -0
  137. package/dist/external-runtime/grok-input-policy.js +52 -0
  138. package/dist/external-runtime/grok-ndjson.d.ts +14 -0
  139. package/dist/external-runtime/grok-ndjson.js +193 -0
  140. package/dist/external-runtime/grok-network.d.ts +15 -0
  141. package/dist/external-runtime/grok-network.js +81 -0
  142. package/dist/external-runtime/grok-preflight.d.ts +28 -0
  143. package/dist/external-runtime/grok-preflight.js +194 -0
  144. package/dist/external-runtime/grok-process.d.ts +26 -0
  145. package/dist/external-runtime/grok-process.js +184 -0
  146. package/dist/external-runtime/grok-profile.d.ts +32 -0
  147. package/dist/external-runtime/grok-profile.js +419 -0
  148. package/dist/external-runtime/grok-provider.d.ts +31 -0
  149. package/dist/external-runtime/grok-provider.js +41 -0
  150. package/dist/external-runtime/grok-runtime.d.ts +91 -0
  151. package/dist/external-runtime/grok-runtime.js +882 -0
  152. package/dist/external-runtime/index.d.ts +13 -0
  153. package/dist/external-runtime/index.js +13 -0
  154. package/dist/external-runtime/session-policy.d.ts +11 -0
  155. package/dist/external-runtime/session-policy.js +30 -0
  156. package/dist/external-runtime/types.d.ts +65 -0
  157. package/dist/external-runtime/types.js +1 -0
  158. package/dist/feedback/collect.d.ts +7 -0
  159. package/dist/feedback/collect.js +119 -0
  160. package/dist/feedback/config.d.ts +14 -0
  161. package/dist/feedback/config.js +16 -0
  162. package/dist/feedback/redact.d.ts +1 -0
  163. package/dist/feedback/redact.js +25 -0
  164. package/dist/feedback/submit.d.ts +6 -0
  165. package/dist/feedback/submit.js +43 -0
  166. package/dist/feedback/types.d.ts +22 -0
  167. package/dist/feedback/types.js +1 -0
  168. package/dist/feishu/agent-host/approval-card.d.ts +11 -0
  169. package/dist/feishu/agent-host/approval-card.js +85 -0
  170. package/dist/feishu/agent-host/approval-ui.d.ts +59 -0
  171. package/dist/feishu/agent-host/approval-ui.js +214 -0
  172. package/dist/feishu/agent-host/run-driver.d.ts +51 -0
  173. package/dist/feishu/agent-host/run-driver.js +397 -0
  174. package/dist/feishu/agent-host/runtime-deps.d.ts +33 -0
  175. package/dist/feishu/agent-host/runtime-deps.js +8 -0
  176. package/dist/feishu/card/budget.d.ts +40 -0
  177. package/dist/feishu/card/budget.js +134 -0
  178. package/dist/feishu/card/renderer.d.ts +29 -0
  179. package/dist/feishu/card/renderer.js +245 -0
  180. package/dist/feishu/card/run-state-types.d.ts +49 -0
  181. package/dist/feishu/card/run-state-types.js +15 -0
  182. package/dist/feishu/card/run-state.d.ts +21 -0
  183. package/dist/feishu/card/run-state.js +223 -0
  184. package/dist/feishu/channel/channel.d.ts +52 -0
  185. package/dist/feishu/channel/channel.js +74 -0
  186. package/dist/feishu/config.d.ts +24 -0
  187. package/dist/feishu/config.js +97 -0
  188. package/dist/feishu/format.d.ts +6 -0
  189. package/dist/feishu/format.js +14 -0
  190. package/dist/feishu/index.d.ts +4 -0
  191. package/dist/feishu/index.js +4 -0
  192. package/dist/feishu/logger.d.ts +31 -0
  193. package/dist/feishu/logger.js +62 -0
  194. package/dist/feishu/paths.d.ts +12 -0
  195. package/dist/feishu/paths.js +38 -0
  196. package/dist/feishu/process-registry.d.ts +29 -0
  197. package/dist/feishu/process-registry.js +90 -0
  198. package/dist/feishu/router/commands.d.ts +38 -0
  199. package/dist/feishu/router/commands.js +286 -0
  200. package/dist/feishu/router/event-router.d.ts +40 -0
  201. package/dist/feishu/router/event-router.js +208 -0
  202. package/dist/feishu/router/whitelist.d.ts +23 -0
  203. package/dist/feishu/router/whitelist.js +20 -0
  204. package/dist/feishu/runtime/active-runs.d.ts +32 -0
  205. package/dist/feishu/runtime/active-runs.js +84 -0
  206. package/dist/feishu/runtime/pending-queue.d.ts +36 -0
  207. package/dist/feishu/runtime/pending-queue.js +98 -0
  208. package/dist/feishu/runtime/process-pool.d.ts +29 -0
  209. package/dist/feishu/runtime/process-pool.js +49 -0
  210. package/dist/feishu/schema.d.ts +17 -0
  211. package/dist/feishu/schema.js +252 -0
  212. package/dist/feishu/scope/scope-registry.d.ts +39 -0
  213. package/dist/feishu/scope/scope-registry.js +148 -0
  214. package/dist/feishu/scope/session-binder.d.ts +44 -0
  215. package/dist/feishu/scope/session-binder.js +100 -0
  216. package/dist/feishu/scope/session-store.d.ts +24 -0
  217. package/dist/feishu/scope/session-store.js +73 -0
  218. package/dist/feishu/secrets.d.ts +37 -0
  219. package/dist/feishu/secrets.js +129 -0
  220. package/dist/feishu/serve.d.ts +12 -0
  221. package/dist/feishu/serve.js +302 -0
  222. package/dist/feishu/types.d.ts +75 -0
  223. package/dist/feishu/types.js +23 -0
  224. package/dist/feishu/wizard.d.ts +24 -0
  225. package/dist/feishu/wizard.js +121 -0
  226. package/dist/goal/command.d.ts +20 -0
  227. package/dist/goal/command.js +76 -0
  228. package/dist/goal/engine.d.ts +33 -0
  229. package/dist/goal/engine.js +65 -0
  230. package/dist/goal/format.d.ts +18 -0
  231. package/dist/goal/format.js +112 -0
  232. package/dist/goal/prompts.d.ts +13 -0
  233. package/dist/goal/prompts.js +84 -0
  234. package/dist/goal/store.d.ts +64 -0
  235. package/dist/goal/store.js +174 -0
  236. package/dist/goal/tools.d.ts +13 -0
  237. package/dist/goal/tools.js +67 -0
  238. package/dist/goal/usage.d.ts +2 -0
  239. package/dist/goal/usage.js +3 -0
  240. package/dist/hooks/config.d.ts +9 -0
  241. package/dist/hooks/config.js +278 -0
  242. package/dist/hooks/controller.d.ts +24 -0
  243. package/dist/hooks/controller.js +254 -0
  244. package/dist/hooks/index.d.ts +6 -0
  245. package/dist/hooks/index.js +4 -0
  246. package/dist/hooks/log.d.ts +14 -0
  247. package/dist/hooks/log.js +54 -0
  248. package/dist/hooks/runner.d.ts +5 -0
  249. package/dist/hooks/runner.js +225 -0
  250. package/dist/hooks/trust.d.ts +37 -0
  251. package/dist/hooks/trust.js +143 -0
  252. package/dist/hooks/types.d.ts +173 -0
  253. package/dist/hooks/types.js +46 -0
  254. package/dist/loop/engine.d.ts +29 -0
  255. package/dist/loop/engine.js +63 -0
  256. package/dist/lsp/config.d.ts +18 -0
  257. package/dist/lsp/config.js +58 -0
  258. package/dist/lsp/diagnostics.d.ts +24 -0
  259. package/dist/lsp/diagnostics.js +103 -0
  260. package/dist/lsp/index.d.ts +3 -0
  261. package/dist/lsp/index.js +3 -0
  262. package/dist/lsp/service.d.ts +97 -0
  263. package/dist/lsp/service.js +815 -0
  264. package/dist/main.d.ts +5 -0
  265. package/dist/main.js +984 -0
  266. package/dist/mcp/client.d.ts +68 -0
  267. package/dist/mcp/client.js +177 -0
  268. package/dist/mcp/config.d.ts +30 -0
  269. package/dist/mcp/config.js +144 -0
  270. package/dist/mcp/manager.d.ts +67 -0
  271. package/dist/mcp/manager.js +328 -0
  272. package/dist/mcp/name.d.ts +26 -0
  273. package/dist/mcp/name.js +40 -0
  274. package/dist/mcp/transports.d.ts +54 -0
  275. package/dist/mcp/transports.js +267 -0
  276. package/dist/mcp/types.d.ts +111 -0
  277. package/dist/mcp/types.js +14 -0
  278. package/dist/memory/db.d.ts +65 -0
  279. package/dist/memory/db.js +332 -0
  280. package/dist/memory/index.d.ts +10 -0
  281. package/dist/memory/index.js +10 -0
  282. package/dist/memory/paths.d.ts +18 -0
  283. package/dist/memory/paths.js +38 -0
  284. package/dist/memory/phase1.d.ts +23 -0
  285. package/dist/memory/phase1.js +292 -0
  286. package/dist/memory/phase2.d.ts +19 -0
  287. package/dist/memory/phase2.js +119 -0
  288. package/dist/memory/prompts.d.ts +19 -0
  289. package/dist/memory/prompts.js +104 -0
  290. package/dist/memory/reset.d.ts +1 -0
  291. package/dist/memory/reset.js +13 -0
  292. package/dist/memory/session-policy.d.ts +25 -0
  293. package/dist/memory/session-policy.js +55 -0
  294. package/dist/memory/start.d.ts +24 -0
  295. package/dist/memory/start.js +50 -0
  296. package/dist/memory/storage.d.ts +11 -0
  297. package/dist/memory/storage.js +95 -0
  298. package/dist/memory/store.d.ts +43 -0
  299. package/dist/memory/store.js +193 -0
  300. package/dist/memory/usage.d.ts +1 -0
  301. package/dist/memory/usage.js +38 -0
  302. package/dist/model-catalog.d.ts +65 -0
  303. package/dist/model-catalog.js +399 -0
  304. package/dist/model-config.d.ts +40 -0
  305. package/dist/model-config.js +74 -0
  306. package/dist/model-data.generated.d.ts +16 -0
  307. package/dist/model-data.generated.js +275 -0
  308. package/dist/model-pricing.d.ts +54 -0
  309. package/dist/model-pricing.js +256 -0
  310. package/dist/model-selection.d.ts +7 -0
  311. package/dist/model-selection.js +18 -0
  312. package/dist/network/chatgpt-transport.d.ts +16 -0
  313. package/dist/network/chatgpt-transport.js +232 -0
  314. package/dist/network/errors.d.ts +47 -0
  315. package/dist/network/errors.js +48 -0
  316. package/dist/network/provider-transport-log.d.ts +12 -0
  317. package/dist/network/provider-transport-log.js +32 -0
  318. package/dist/network/provider-transport.d.ts +37 -0
  319. package/dist/network/provider-transport.js +256 -0
  320. package/dist/network/retry.d.ts +34 -0
  321. package/dist/network/retry.js +97 -0
  322. package/dist/network/system-proxy.d.ts +18 -0
  323. package/dist/network/system-proxy.js +175 -0
  324. package/dist/oauth/grok.d.ts +26 -0
  325. package/dist/oauth/grok.js +251 -0
  326. package/dist/oauth/index.d.ts +4 -0
  327. package/dist/oauth/index.js +3 -0
  328. package/dist/oauth/openai-codex.d.ts +15 -0
  329. package/dist/oauth/openai-codex.js +193 -0
  330. package/dist/oauth/refresh-control.d.ts +12 -0
  331. package/dist/oauth/refresh-control.js +42 -0
  332. package/dist/oauth/storage.d.ts +88 -0
  333. package/dist/oauth/storage.js +357 -0
  334. package/dist/oauth/types.d.ts +15 -0
  335. package/dist/oauth/types.js +1 -0
  336. package/dist/orchestrator/default-hooks.d.ts +22 -0
  337. package/dist/orchestrator/default-hooks.js +127 -0
  338. package/dist/orchestrator/hooks.d.ts +69 -0
  339. package/dist/orchestrator/hooks.js +52 -0
  340. package/dist/permission/mode.d.ts +19 -0
  341. package/dist/permission/mode.js +16 -0
  342. package/dist/permissions/rule.d.ts +42 -0
  343. package/dist/permissions/rule.js +293 -0
  344. package/dist/permissions/settings.d.ts +97 -0
  345. package/dist/permissions/settings.js +289 -0
  346. package/dist/permissions/shell-command.d.ts +36 -0
  347. package/dist/permissions/shell-command.js +226 -0
  348. package/dist/permissions/trust-prompt.d.ts +10 -0
  349. package/dist/permissions/trust-prompt.js +34 -0
  350. package/dist/permissions/trust.d.ts +26 -0
  351. package/dist/permissions/trust.js +113 -0
  352. package/dist/permissions/types.d.ts +61 -0
  353. package/dist/permissions/types.js +14 -0
  354. package/dist/print-output.d.ts +98 -0
  355. package/dist/print-output.js +117 -0
  356. package/dist/prompt/compose.d.ts +19 -0
  357. package/dist/prompt/compose.js +110 -0
  358. package/dist/prompt/delegation.d.ts +14 -0
  359. package/dist/prompt/delegation.js +100 -0
  360. package/dist/prompt/environment.d.ts +12 -0
  361. package/dist/prompt/environment.js +55 -0
  362. package/dist/prompt/provider-prompts/anthropic.d.ts +1 -0
  363. package/dist/prompt/provider-prompts/anthropic.js +5 -0
  364. package/dist/prompt/provider-prompts/codex.d.ts +1 -0
  365. package/dist/prompt/provider-prompts/codex.js +5 -0
  366. package/dist/prompt/provider-prompts/deepseek.d.ts +1 -0
  367. package/dist/prompt/provider-prompts/deepseek.js +7 -0
  368. package/dist/prompt/provider-prompts/default.d.ts +1 -0
  369. package/dist/prompt/provider-prompts/default.js +6 -0
  370. package/dist/prompt/provider-prompts/gemini.d.ts +1 -0
  371. package/dist/prompt/provider-prompts/gemini.js +5 -0
  372. package/dist/prompt/provider-prompts/glm.d.ts +1 -0
  373. package/dist/prompt/provider-prompts/glm.js +7 -0
  374. package/dist/prompt/provider-prompts/gpt.d.ts +1 -0
  375. package/dist/prompt/provider-prompts/gpt.js +5 -0
  376. package/dist/prompt/provider-prompts/kimi.d.ts +1 -0
  377. package/dist/prompt/provider-prompts/kimi.js +8 -0
  378. package/dist/prompt/reminders.d.ts +33 -0
  379. package/dist/prompt/reminders.js +135 -0
  380. package/dist/prompt/routing.d.ts +14 -0
  381. package/dist/prompt/routing.js +71 -0
  382. package/dist/prompt/runtime.d.ts +12 -0
  383. package/dist/prompt/runtime.js +40 -0
  384. package/dist/prompt/task-reminders.d.ts +12 -0
  385. package/dist/prompt/task-reminders.js +64 -0
  386. package/dist/provider-ai-sdk.d.ts +59 -0
  387. package/dist/provider-ai-sdk.js +584 -0
  388. package/dist/provider-anthropic.d.ts +126 -0
  389. package/dist/provider-anthropic.js +940 -0
  390. package/dist/provider-ark-responses.d.ts +29 -0
  391. package/dist/provider-ark-responses.js +518 -0
  392. package/dist/provider-artifacts.d.ts +7 -0
  393. package/dist/provider-artifacts.js +60 -0
  394. package/dist/provider-error-record.d.ts +43 -0
  395. package/dist/provider-error-record.js +213 -0
  396. package/dist/provider-grok.d.ts +50 -0
  397. package/dist/provider-grok.js +110 -0
  398. package/dist/provider-model-policy.d.ts +16 -0
  399. package/dist/provider-model-policy.js +33 -0
  400. package/dist/provider-openai-codex.d.ts +66 -0
  401. package/dist/provider-openai-codex.js +781 -0
  402. package/dist/provider-registry.d.ts +197 -0
  403. package/dist/provider-registry.js +1194 -0
  404. package/dist/provider-transform.d.ts +12 -0
  405. package/dist/provider-transform.js +293 -0
  406. package/dist/provider-zen-errors.d.ts +9 -0
  407. package/dist/provider-zen-errors.js +36 -0
  408. package/dist/provider.d.ts +85 -0
  409. package/dist/provider.js +925 -0
  410. package/dist/question/controller.d.ts +22 -0
  411. package/dist/question/controller.js +98 -0
  412. package/dist/question/index.d.ts +2 -0
  413. package/dist/question/index.js +2 -0
  414. package/dist/question/normalize.d.ts +6 -0
  415. package/dist/question/normalize.js +11 -0
  416. package/dist/question/types.d.ts +42 -0
  417. package/dist/question/types.js +6 -0
  418. package/dist/reasoning-debug.d.ts +7 -0
  419. package/dist/reasoning-debug.js +33 -0
  420. package/dist/rewind.d.ts +20 -0
  421. package/dist/rewind.js +29 -0
  422. package/dist/sdk/index.d.ts +319 -0
  423. package/dist/sdk/index.js +1068 -0
  424. package/dist/sdk/replay-event-log.d.ts +26 -0
  425. package/dist/sdk/replay-event-log.js +122 -0
  426. package/dist/sdk/session-turn-coordinator.d.ts +45 -0
  427. package/dist/sdk/session-turn-coordinator.js +227 -0
  428. package/dist/session-context-fence.d.ts +16 -0
  429. package/dist/session-context-fence.js +26 -0
  430. package/dist/session-log.d.ts +25 -0
  431. package/dist/session-log.js +444 -0
  432. package/dist/session-title.d.ts +16 -0
  433. package/dist/session-title.js +131 -0
  434. package/dist/session-types.d.ts +86 -0
  435. package/dist/session-types.js +1 -0
  436. package/dist/session.d.ts +135 -0
  437. package/dist/session.js +664 -0
  438. package/dist/skills/discovery.d.ts +12 -0
  439. package/dist/skills/discovery.js +166 -0
  440. package/dist/skills/format.d.ts +32 -0
  441. package/dist/skills/format.js +68 -0
  442. package/dist/skills/frontmatter.d.ts +5 -0
  443. package/dist/skills/frontmatter.js +60 -0
  444. package/dist/skills/invocation.d.ts +8 -0
  445. package/dist/skills/invocation.js +33 -0
  446. package/dist/skills/registry.d.ts +28 -0
  447. package/dist/skills/registry.js +79 -0
  448. package/dist/skills/types.d.ts +34 -0
  449. package/dist/skills/types.js +1 -0
  450. package/dist/slash-commands/commands.d.ts +10 -0
  451. package/dist/slash-commands/commands.js +1251 -0
  452. package/dist/slash-commands/feishu.d.ts +17 -0
  453. package/dist/slash-commands/feishu.js +400 -0
  454. package/dist/slash-commands/index.d.ts +4 -0
  455. package/dist/slash-commands/index.js +8 -0
  456. package/dist/slash-commands/registry.d.ts +32 -0
  457. package/dist/slash-commands/registry.js +73 -0
  458. package/dist/slash-commands/types.d.ts +109 -0
  459. package/dist/slash-commands/types.js +1 -0
  460. package/dist/slash-commands/unified.d.ts +38 -0
  461. package/dist/slash-commands/unified.js +38 -0
  462. package/dist/stats/usage.d.ts +59 -0
  463. package/dist/stats/usage.js +485 -0
  464. package/dist/stream-json.d.ts +13 -0
  465. package/dist/stream-json.js +74 -0
  466. package/dist/system-prompt.d.ts +40 -0
  467. package/dist/system-prompt.js +7 -0
  468. package/dist/tasks/manager.d.ts +145 -0
  469. package/dist/tasks/manager.js +634 -0
  470. package/dist/tasks/process-utils.d.ts +10 -0
  471. package/dist/tasks/process-utils.js +49 -0
  472. package/dist/tasks/promotion.d.ts +17 -0
  473. package/dist/tasks/promotion.js +30 -0
  474. package/dist/tasks/wake.d.ts +53 -0
  475. package/dist/tasks/wake.js +125 -0
  476. package/dist/text-display.d.ts +3 -0
  477. package/dist/text-display.js +25 -0
  478. package/dist/tools/agent-lifecycle.d.ts +30 -0
  479. package/dist/tools/agent-lifecycle.js +790 -0
  480. package/dist/tools/bash.d.ts +23 -0
  481. package/dist/tools/bash.js +443 -0
  482. package/dist/tools/child-tools.d.ts +41 -0
  483. package/dist/tools/child-tools.js +122 -0
  484. package/dist/tools/edit-apply.d.ts +25 -0
  485. package/dist/tools/edit-apply.js +274 -0
  486. package/dist/tools/edit.d.ts +18 -0
  487. package/dist/tools/edit.js +200 -0
  488. package/dist/tools/exa-mcp.d.ts +3 -0
  489. package/dist/tools/exa-mcp.js +74 -0
  490. package/dist/tools/exit-plan-mode.d.ts +22 -0
  491. package/dist/tools/exit-plan-mode.js +79 -0
  492. package/dist/tools/file-mutation-queue.d.ts +2 -0
  493. package/dist/tools/file-mutation-queue.js +43 -0
  494. package/dist/tools/file-state.d.ts +48 -0
  495. package/dist/tools/file-state.js +76 -0
  496. package/dist/tools/grep.d.ts +9 -0
  497. package/dist/tools/grep.js +387 -0
  498. package/dist/tools/index.d.ts +63 -0
  499. package/dist/tools/index.js +76 -0
  500. package/dist/tools/ls.d.ts +3 -0
  501. package/dist/tools/ls.js +85 -0
  502. package/dist/tools/lsp.d.ts +4 -0
  503. package/dist/tools/lsp.js +95 -0
  504. package/dist/tools/memory.d.ts +8 -0
  505. package/dist/tools/memory.js +77 -0
  506. package/dist/tools/path-utils.d.ts +8 -0
  507. package/dist/tools/path-utils.js +53 -0
  508. package/dist/tools/prompt-metadata.d.ts +3 -0
  509. package/dist/tools/prompt-metadata.js +17 -0
  510. package/dist/tools/question.d.ts +3 -0
  511. package/dist/tools/question.js +177 -0
  512. package/dist/tools/read.d.ts +8 -0
  513. package/dist/tools/read.js +309 -0
  514. package/dist/tools/sensitive-paths.d.ts +11 -0
  515. package/dist/tools/sensitive-paths.js +106 -0
  516. package/dist/tools/server-manager.d.ts +6 -0
  517. package/dist/tools/server-manager.js +6 -0
  518. package/dist/tools/server.d.ts +6 -0
  519. package/dist/tools/server.js +249 -0
  520. package/dist/tools/skill-search.d.ts +10 -0
  521. package/dist/tools/skill-search.js +134 -0
  522. package/dist/tools/skill.d.ts +7 -0
  523. package/dist/tools/skill.js +81 -0
  524. package/dist/tools/task-tools.d.ts +10 -0
  525. package/dist/tools/task-tools.js +133 -0
  526. package/dist/tools/tool-search.d.ts +23 -0
  527. package/dist/tools/tool-search.js +145 -0
  528. package/dist/tools/web-fetch.d.ts +6 -0
  529. package/dist/tools/web-fetch.js +76 -0
  530. package/dist/tools/web-search.d.ts +5 -0
  531. package/dist/tools/web-search.js +50 -0
  532. package/dist/tools/write.d.ts +10 -0
  533. package/dist/tools/write.js +155 -0
  534. package/dist/tui/animation-clock.d.ts +14 -0
  535. package/dist/tui/animation-clock.js +34 -0
  536. package/dist/tui/app.d.ts +176 -0
  537. package/dist/tui/app.js +1659 -0
  538. package/dist/tui/components/approval-dialog.d.ts +43 -0
  539. package/dist/tui/components/approval-dialog.js +212 -0
  540. package/dist/tui/components/bottom-sheet.d.ts +9 -0
  541. package/dist/tui/components/bottom-sheet.js +32 -0
  542. package/dist/tui/components/context-info.d.ts +54 -0
  543. package/dist/tui/components/context-info.js +388 -0
  544. package/dist/tui/components/feedback-dialog.d.ts +56 -0
  545. package/dist/tui/components/feedback-dialog.js +262 -0
  546. package/dist/tui/components/feishu-setup-dialog.d.ts +65 -0
  547. package/dist/tui/components/feishu-setup-dialog.js +332 -0
  548. package/dist/tui/components/image-preview.d.ts +32 -0
  549. package/dist/tui/components/image-preview.js +130 -0
  550. package/dist/tui/components/plan-dialog.d.ts +34 -0
  551. package/dist/tui/components/plan-dialog.js +196 -0
  552. package/dist/tui/components/provider-key-input.d.ts +18 -0
  553. package/dist/tui/components/provider-key-input.js +49 -0
  554. package/dist/tui/components/question-dialog.d.ts +25 -0
  555. package/dist/tui/components/question-dialog.js +263 -0
  556. package/dist/tui/components/responsive-transcript.d.ts +31 -0
  557. package/dist/tui/components/responsive-transcript.js +77 -0
  558. package/dist/tui/components/rewind-picker.d.ts +62 -0
  559. package/dist/tui/components/rewind-picker.js +317 -0
  560. package/dist/tui/components/session-picker.d.ts +49 -0
  561. package/dist/tui/components/session-picker.js +303 -0
  562. package/dist/tui/components/skills-panel.d.ts +63 -0
  563. package/dist/tui/components/skills-panel.js +582 -0
  564. package/dist/tui/components/stats-panel.d.ts +40 -0
  565. package/dist/tui/components/stats-panel.js +301 -0
  566. package/dist/tui/components/streaming-message.d.ts +69 -0
  567. package/dist/tui/components/streaming-message.js +398 -0
  568. package/dist/tui/components/subagent-inspector.d.ts +28 -0
  569. package/dist/tui/components/subagent-inspector.js +127 -0
  570. package/dist/tui/components/task-inspector.d.ts +26 -0
  571. package/dist/tui/components/task-inspector.js +70 -0
  572. package/dist/tui/components/tasks-pane.d.ts +126 -0
  573. package/dist/tui/components/tasks-pane.js +566 -0
  574. package/dist/tui/components/transcript.d.ts +103 -0
  575. package/dist/tui/components/transcript.js +858 -0
  576. package/dist/tui/components/welcome.d.ts +20 -0
  577. package/dist/tui/components/welcome.js +133 -0
  578. package/dist/tui/components/workflow-inspector.d.ts +30 -0
  579. package/dist/tui/components/workflow-inspector.js +136 -0
  580. package/dist/tui/composer-autocomplete.d.ts +76 -0
  581. package/dist/tui/composer-autocomplete.js +465 -0
  582. package/dist/tui/composer-style.d.ts +7 -0
  583. package/dist/tui/composer-style.js +29 -0
  584. package/dist/tui/controller/agent-event-reducer.d.ts +75 -0
  585. package/dist/tui/controller/agent-event-reducer.js +239 -0
  586. package/dist/tui/controller/composer-controller.d.ts +95 -0
  587. package/dist/tui/controller/composer-controller.js +502 -0
  588. package/dist/tui/controller/controller.d.ts +199 -0
  589. package/dist/tui/controller/controller.js +1034 -0
  590. package/dist/tui/controller/effects.d.ts +71 -0
  591. package/dist/tui/controller/effects.js +1 -0
  592. package/dist/tui/controller/goal-runtime-controller.d.ts +47 -0
  593. package/dist/tui/controller/goal-runtime-controller.js +202 -0
  594. package/dist/tui/controller/input-queue-machine.d.ts +71 -0
  595. package/dist/tui/controller/input-queue-machine.js +121 -0
  596. package/dist/tui/controller/intents.d.ts +56 -0
  597. package/dist/tui/controller/intents.js +6 -0
  598. package/dist/tui/controller/overlay-controller.d.ts +64 -0
  599. package/dist/tui/controller/overlay-controller.js +129 -0
  600. package/dist/tui/controller/ports.d.ts +57 -0
  601. package/dist/tui/controller/ports.js +9 -0
  602. package/dist/tui/controller/session-transition.d.ts +54 -0
  603. package/dist/tui/controller/session-transition.js +68 -0
  604. package/dist/tui/controller/state.d.ts +14 -0
  605. package/dist/tui/controller/state.js +36 -0
  606. package/dist/tui/controller/task-runtime-controller.d.ts +66 -0
  607. package/dist/tui/controller/task-runtime-controller.js +158 -0
  608. package/dist/tui/detect-theme.d.ts +4 -0
  609. package/dist/tui/detect-theme.js +116 -0
  610. package/dist/tui/display-history.d.ts +64 -0
  611. package/dist/tui/display-history.js +283 -0
  612. package/dist/tui/display-sanitizer.d.ts +3 -0
  613. package/dist/tui/display-sanitizer.js +38 -0
  614. package/dist/tui/edit-diff.d.ts +11 -0
  615. package/dist/tui/edit-diff.js +57 -0
  616. package/dist/tui/file-mentions.d.ts +29 -0
  617. package/dist/tui/file-mentions.js +174 -0
  618. package/dist/tui/footer.d.ts +37 -0
  619. package/dist/tui/footer.js +80 -0
  620. package/dist/tui/formatting/edit-diff.d.ts +11 -0
  621. package/dist/tui/formatting/edit-diff.js +52 -0
  622. package/dist/tui/formatting/summary.d.ts +43 -0
  623. package/dist/tui/formatting/summary.js +150 -0
  624. package/dist/tui/fullscreen.d.ts +48 -0
  625. package/dist/tui/fullscreen.js +256 -0
  626. package/dist/tui/image-display.d.ts +23 -0
  627. package/dist/tui/image-display.js +92 -0
  628. package/dist/tui/image-paste.d.ts +113 -0
  629. package/dist/tui/image-paste.js +565 -0
  630. package/dist/tui/input-history.d.ts +47 -0
  631. package/dist/tui/input-history.js +250 -0
  632. package/dist/tui/markdown-style.d.ts +5 -0
  633. package/dist/tui/markdown-style.js +23 -0
  634. package/dist/tui/model/composer-buffer.d.ts +55 -0
  635. package/dist/tui/model/composer-buffer.js +317 -0
  636. package/dist/tui/model/composer-types.d.ts +17 -0
  637. package/dist/tui/model/composer-types.js +1 -0
  638. package/dist/tui/model/display-history.d.ts +78 -0
  639. package/dist/tui/model/display-history.js +124 -0
  640. package/dist/tui/model/display-reconstruct.d.ts +3 -0
  641. package/dist/tui/model/display-reconstruct.js +130 -0
  642. package/dist/tui/model/file-mentions.d.ts +31 -0
  643. package/dist/tui/model/file-mentions.js +178 -0
  644. package/dist/tui/model/image-attachment.d.ts +15 -0
  645. package/dist/tui/model/image-attachment.js +1 -0
  646. package/dist/tui/model/image-paste.d.ts +119 -0
  647. package/dist/tui/model/image-paste.js +610 -0
  648. package/dist/tui/model/input-history.d.ts +1 -0
  649. package/dist/tui/model/input-history.js +1 -0
  650. package/dist/tui/model/input-queue.d.ts +12 -0
  651. package/dist/tui/model/input-queue.js +17 -0
  652. package/dist/tui/model/key-events.d.ts +9 -0
  653. package/dist/tui/model/key-events.js +8 -0
  654. package/dist/tui/model/paste-operation-tracker.d.ts +13 -0
  655. package/dist/tui/model/paste-operation-tracker.js +25 -0
  656. package/dist/tui/model/recent-activity.d.ts +8 -0
  657. package/dist/tui/model/recent-activity.js +71 -0
  658. package/dist/tui/model/subagent-view.d.ts +87 -0
  659. package/dist/tui/model/subagent-view.js +336 -0
  660. package/dist/tui/model/submit-dedupe.d.ts +5 -0
  661. package/dist/tui/model/submit-dedupe.js +25 -0
  662. package/dist/tui/model/sync-output.d.ts +17 -0
  663. package/dist/tui/model/sync-output.js +35 -0
  664. package/dist/tui/model/task-lifecycle.d.ts +57 -0
  665. package/dist/tui/model/task-lifecycle.js +124 -0
  666. package/dist/tui/model/terminal-env.d.ts +15 -0
  667. package/dist/tui/model/terminal-env.js +22 -0
  668. package/dist/tui/model/terminal-mouse.d.ts +28 -0
  669. package/dist/tui/model/terminal-mouse.js +82 -0
  670. package/dist/tui/model/theme-style.d.ts +10 -0
  671. package/dist/tui/model/theme-style.js +79 -0
  672. package/dist/tui/model/theme.d.ts +72 -0
  673. package/dist/tui/model/theme.js +121 -0
  674. package/dist/tui/model/trace-groups.d.ts +45 -0
  675. package/dist/tui/model/trace-groups.js +558 -0
  676. package/dist/tui/model/trace-interaction.d.ts +63 -0
  677. package/dist/tui/model/trace-interaction.js +87 -0
  678. package/dist/tui/model/width.d.ts +18 -0
  679. package/dist/tui/model/width.js +130 -0
  680. package/dist/tui/model-picker-data.d.ts +9 -0
  681. package/dist/tui/model-picker-data.js +39 -0
  682. package/dist/tui/model-switch.d.ts +49 -0
  683. package/dist/tui/model-switch.js +67 -0
  684. package/dist/tui/paste-placeholder.d.ts +11 -0
  685. package/dist/tui/paste-placeholder.js +52 -0
  686. package/dist/tui/recent-activity.d.ts +8 -0
  687. package/dist/tui/recent-activity.js +71 -0
  688. package/dist/tui/run-session-picker.d.ts +9 -0
  689. package/dist/tui/run-session-picker.js +64 -0
  690. package/dist/tui/run.d.ts +72 -0
  691. package/dist/tui/run.js +139 -0
  692. package/dist/tui/session-display.d.ts +6 -0
  693. package/dist/tui/session-display.js +12 -0
  694. package/dist/tui/session-picker-data.d.ts +18 -0
  695. package/dist/tui/session-picker-data.js +21 -0
  696. package/dist/tui/terminal/multiplexer.d.ts +5 -0
  697. package/dist/tui/terminal/multiplexer.js +14 -0
  698. package/dist/tui/testing/fake-agent.d.ts +24 -0
  699. package/dist/tui/testing/fake-agent.js +22 -0
  700. package/dist/tui/testing/spy-host.d.ts +21 -0
  701. package/dist/tui/testing/spy-host.js +55 -0
  702. package/dist/tui/trace-groups.d.ts +43 -0
  703. package/dist/tui/trace-groups.js +554 -0
  704. package/dist/tui/wordmark.d.ts +18 -0
  705. package/dist/tui/wordmark.js +208 -0
  706. package/dist/types.d.ts +503 -0
  707. package/dist/types.js +4 -0
  708. package/dist/update/index.d.ts +61 -0
  709. package/dist/update/index.js +267 -0
  710. package/dist/variant/thinking-level.d.ts +5 -0
  711. package/dist/variant/thinking-level.js +26 -0
  712. package/dist/variant/variant-resolver.d.ts +28 -0
  713. package/dist/variant/variant-resolver.js +62 -0
  714. package/node_modules/@bubblebrain-ai/pi-tui/LICENSE +21 -0
  715. package/node_modules/@bubblebrain-ai/pi-tui/README.md +854 -0
  716. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts +26 -0
  717. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.d.ts.map +1 -0
  718. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js +121 -0
  719. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/alt-screen-search.js.map +1 -0
  720. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts +86 -0
  721. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.d.ts.map +1 -0
  722. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js +649 -0
  723. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/autocomplete.js.map +1 -0
  724. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts +13 -0
  725. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.d.ts.map +1 -0
  726. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js +36 -0
  727. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/alt-screen-flash.js.map +1 -0
  728. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts +22 -0
  729. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.d.ts.map +1 -0
  730. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js +99 -0
  731. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/box.js.map +1 -0
  732. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts +22 -0
  733. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.d.ts.map +1 -0
  734. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js +36 -0
  735. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/cancellable-loader.js.map +1 -0
  736. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts +330 -0
  737. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.d.ts.map +1 -0
  738. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js +2344 -0
  739. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/editor.js.map +1 -0
  740. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts +7 -0
  741. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.d.ts.map +1 -0
  742. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js +43 -0
  743. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/h-stack.js.map +1 -0
  744. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts +28 -0
  745. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.d.ts.map +1 -0
  746. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js +82 -0
  747. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/image.js.map +1 -0
  748. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts +48 -0
  749. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.d.ts.map +1 -0
  750. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js +390 -0
  751. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/input.js.map +1 -0
  752. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts +31 -0
  753. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.d.ts.map +1 -0
  754. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js +67 -0
  755. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/loader.js.map +1 -0
  756. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts +103 -0
  757. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.d.ts.map +1 -0
  758. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js +797 -0
  759. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/markdown.js.map +1 -0
  760. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts +56 -0
  761. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.d.ts.map +1 -0
  762. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js +179 -0
  763. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/scroll-view.js.map +1 -0
  764. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts +53 -0
  765. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.d.ts.map +1 -0
  766. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js +175 -0
  767. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/select-list.js.map +1 -0
  768. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts +50 -0
  769. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.d.ts.map +1 -0
  770. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js +174 -0
  771. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/settings-list.js.map +1 -0
  772. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts +12 -0
  773. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.d.ts.map +1 -0
  774. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js +22 -0
  775. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/spacer.js.map +1 -0
  776. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts +32 -0
  777. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.d.ts.map +1 -0
  778. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js +109 -0
  779. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/stack.js.map +1 -0
  780. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts +19 -0
  781. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.d.ts.map +1 -0
  782. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js +81 -0
  783. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/text.js.map +1 -0
  784. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts +13 -0
  785. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.d.ts.map +1 -0
  786. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js +48 -0
  787. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/truncated-text.js.map +1 -0
  788. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts +8 -0
  789. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.d.ts.map +1 -0
  790. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js +26 -0
  791. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/components/v-stack.js.map +1 -0
  792. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts +39 -0
  793. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.d.ts.map +1 -0
  794. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js +2 -0
  795. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/editor-component.js.map +1 -0
  796. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts +16 -0
  797. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.d.ts.map +1 -0
  798. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js +110 -0
  799. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/fuzzy.js.map +1 -0
  800. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts +31 -0
  801. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.d.ts.map +1 -0
  802. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js +42 -0
  803. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/index.js.map +1 -0
  804. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts +273 -0
  805. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.d.ts.map +1 -0
  806. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js +231 -0
  807. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keybindings.js.map +1 -0
  808. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts +184 -0
  809. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.d.ts.map +1 -0
  810. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js +1174 -0
  811. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/keys.js.map +1 -0
  812. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts +28 -0
  813. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.d.ts.map +1 -0
  814. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js +46 -0
  815. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/kill-ring.js.map +1 -0
  816. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts +10 -0
  817. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.d.ts.map +1 -0
  818. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js +1268 -0
  819. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/latex.js.map +1 -0
  820. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts +40 -0
  821. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.d.ts.map +1 -0
  822. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js +6 -0
  823. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout-node.js.map +1 -0
  824. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts +42 -0
  825. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.d.ts.map +1 -0
  826. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js +335 -0
  827. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/layout.js.map +1 -0
  828. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts +3 -0
  829. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.d.ts.map +1 -0
  830. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js +60 -0
  831. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/native-modifiers.js.map +1 -0
  832. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts +56 -0
  833. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.d.ts.map +1 -0
  834. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js +363 -0
  835. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/stdin-buffer.js.map +1 -0
  836. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts +10 -0
  837. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.d.ts.map +1 -0
  838. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js +59 -0
  839. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-colors.js.map +1 -0
  840. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts +116 -0
  841. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.d.ts.map +1 -0
  842. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js +518 -0
  843. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal-image.js.map +1 -0
  844. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts +142 -0
  845. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.d.ts.map +1 -0
  846. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js +544 -0
  847. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/terminal.js.map +1 -0
  848. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts +11 -0
  849. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.d.ts.map +1 -0
  850. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js +11 -0
  851. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/testing.js.map +1 -0
  852. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts +141 -0
  853. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.d.ts.map +1 -0
  854. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js +1340 -0
  855. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-alt-screen.js.map +1 -0
  856. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts +39 -0
  857. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.d.ts.map +1 -0
  858. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js +536 -0
  859. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui-main-screen.js.map +1 -0
  860. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts +340 -0
  861. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.d.ts.map +1 -0
  862. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js +1020 -0
  863. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/tui.js.map +1 -0
  864. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts +17 -0
  865. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.d.ts.map +1 -0
  866. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js +27 -0
  867. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/undo-stack.js.map +1 -0
  868. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts +96 -0
  869. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.d.ts.map +1 -0
  870. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js +1193 -0
  871. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/utils.js.map +1 -0
  872. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts +25 -0
  873. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.d.ts.map +1 -0
  874. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js +96 -0
  875. package/node_modules/@bubblebrain-ai/pi-tui/dist/src/word-navigation.js.map +1 -0
  876. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts +73 -0
  877. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.d.ts.map +1 -0
  878. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js +188 -0
  879. package/node_modules/@bubblebrain-ai/pi-tui/dist/test/virtual-terminal.js.map +1 -0
  880. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/README.md +20 -0
  881. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/build.sh +62 -0
  882. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-arm64/darwin-modifiers.node +0 -0
  883. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/prebuilds/darwin-x64/darwin-modifiers.node +0 -0
  884. package/node_modules/@bubblebrain-ai/pi-tui/native/darwin/src/darwin-modifiers.c +70 -0
  885. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/README.md +22 -0
  886. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/build.mjs +229 -0
  887. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-arm64/win32-console-mode.node +0 -0
  888. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/prebuilds/win32-x64/win32-console-mode.node +0 -0
  889. package/node_modules/@bubblebrain-ai/pi-tui/native/win32/src/win32-console-mode.c +119 -0
  890. package/node_modules/@bubblebrain-ai/pi-tui/package.json +66 -0
  891. package/node_modules/get-east-asian-width/index.d.ts +60 -0
  892. package/node_modules/get-east-asian-width/index.js +30 -0
  893. package/node_modules/get-east-asian-width/license +9 -0
  894. package/node_modules/get-east-asian-width/lookup-data.js +21 -0
  895. package/node_modules/get-east-asian-width/lookup.js +138 -0
  896. package/node_modules/get-east-asian-width/package.json +71 -0
  897. package/node_modules/get-east-asian-width/readme.md +65 -0
  898. package/node_modules/get-east-asian-width/utilities.js +24 -0
  899. package/node_modules/marked/LICENSE +44 -0
  900. package/node_modules/marked/README.md +115 -0
  901. package/node_modules/marked/bin/main.js +284 -0
  902. package/node_modules/marked/bin/marked.js +16 -0
  903. package/node_modules/marked/lib/marked.d.ts +760 -0
  904. package/node_modules/marked/lib/marked.esm.js +77 -0
  905. package/node_modules/marked/lib/marked.esm.js.map +7 -0
  906. package/node_modules/marked/lib/marked.umd.js +79 -0
  907. package/node_modules/marked/lib/marked.umd.js.map +7 -0
  908. package/node_modules/marked/man/marked.1 +113 -0
  909. package/node_modules/marked/man/marked.1.md +93 -0
  910. package/node_modules/marked/package.json +103 -0
  911. package/package.json +96 -17
  912. package/bin/bubble.js +0 -39
@@ -0,0 +1,1068 @@
1
+ /**
2
+ * Bubble SDK — the programmatic embedding surface for external hosts.
3
+ *
4
+ * Two layers:
5
+ * 1. `BubbleSdk` — a high-level facade that owns config/provider resolution and
6
+ * assembles a full agent turn (tools, approvals, questions, plan mode, MCP,
7
+ * skills, hooks, session persistence) behind a single `runTurn()` async
8
+ * iterator of `AgentEvent`s. This is what a host like an Electron app should
9
+ * consume: wire the three interaction callbacks (approval / question / plan)
10
+ * to its own UI and map the event stream to its own message format.
11
+ * 2. Curated re-exports of the underlying building blocks, for hosts that need
12
+ * to assemble a custom loop the facade doesn't cover.
13
+ *
14
+ * Runs under plain Node (>=20); nothing here touches the TUI layer.
15
+ */
16
+ import os from "node:os";
17
+ import { rmSync } from "node:fs";
18
+ import { randomUUID } from "node:crypto";
19
+ import { Agent, AgentAbortError } from "../agent.js";
20
+ import { AgentRunInputQueue } from "../agent/input-controller.js";
21
+ import { SessionTurnCoordinator, } from "./session-turn-coordinator.js";
22
+ import { ReplayEventLog } from "./replay-event-log.js";
23
+ import { SessionManager } from "../session.js";
24
+ import { isPermissionModeReminder } from "../prompt/reminders.js";
25
+ import { PermissionAwareApprovalController } from "../approval/controller.js";
26
+ import { BashAllowlist } from "../approval/session-cache.js";
27
+ import { SettingsManager } from "../permissions/settings.js";
28
+ import { isRepoConfigTrusted, mergedRepoCapabilities, readRepoSettings, trustRepoConfig, } from "../permissions/trust.js";
29
+ import { createAllTools, buildToolPromptOptions } from "../tools/index.js";
30
+ import { buildSystemPrompt } from "../system-prompt.js";
31
+ import { FileStateTracker } from "../tools/file-state.js";
32
+ import { BudgetLedger } from "../agent/budget-ledger.js";
33
+ import { UserConfig } from "../config.js";
34
+ import { ProviderRegistry, encodeModel, decodeModel, displayModel } from "../provider-registry.js";
35
+ import { createProviderInstance } from "../provider.js";
36
+ import { getDefaultThinkingLevel } from "../variant/variant-resolver.js";
37
+ import { QuestionController } from "../question/controller.js";
38
+ import { assertProviderModelAllowed } from "../provider-model-policy.js";
39
+ import { SkillRegistry } from "../skills/registry.js";
40
+ import { parseSkillInvocation } from "../skills/invocation.js";
41
+ import { GoalStore } from "../goal/store.js";
42
+ import { McpManager, gateMcpTools } from "../mcp/manager.js";
43
+ import { loadMcpConfig } from "../mcp/config.js";
44
+ import { ExternalHookController } from "../hooks/controller.js";
45
+ import { buildMemoryPrompt } from "../memory/store.js";
46
+ import { calculateUsageCost } from "../model-pricing.js";
47
+ import { purgeUnsafeMemorySources } from "../memory/session-policy.js";
48
+ import { recordMemoryCitations } from "../memory/usage.js";
49
+ // ── Facade ─────────────────────────────────────────────────────────────────
50
+ export class BubbleSdk {
51
+ userConfig = new UserConfig();
52
+ registry = new ProviderRegistry(this.userConfig);
53
+ defaultCwd;
54
+ mcpEnabled;
55
+ sessionEventRetention;
56
+ cwdBySession = new Map();
57
+ bashAllowlists = new Map();
58
+ sessionGrants = new Map();
59
+ turnCoordinator = new SessionTurnCoordinator();
60
+ turnRuntimes = new Map();
61
+ lastTurnOptions = new Map();
62
+ mcpToolsByCwd = new Map();
63
+ mcpManagersByCwd = new Map();
64
+ /** Folders whose trust question was already put to the host. */
65
+ projectTrustAsked = new Set();
66
+ inputIdNonce = randomUUID().slice(0, 6);
67
+ nextTurnInputPrefix = 0;
68
+ nextDetachedInputId = 0;
69
+ /** id -> {cwd,file} rebuilt from disk so sessions survive host restarts. */
70
+ sessionIndex = new Map();
71
+ constructor(options = {}) {
72
+ this.defaultCwd = options.defaultCwd || process.env.BUBBLE_CWD || os.homedir();
73
+ this.mcpEnabled = options.mcp !== false;
74
+ this.sessionEventRetention = options.sessionEventRetention ?? Infinity;
75
+ if (this.sessionEventRetention !== Infinity && (!Number.isSafeInteger(this.sessionEventRetention) || this.sessionEventRetention < 1)) {
76
+ throw new Error('sessionEventRetention must be a positive integer');
77
+ }
78
+ }
79
+ // ── Sessions ─────────────────────────────────────────────────────────────
80
+ listSessions() {
81
+ const sessions = SessionManager.listAllSessions().filter((session) => !this.turnCoordinator.isDeleted(session.name));
82
+ this.sessionIndex = new Map(sessions.map((s) => [s.name, { cwd: s.cwd ?? s.cwdLabel ?? this.defaultCwd, file: s.file }]));
83
+ return sessions;
84
+ }
85
+ createSession(options = {}) {
86
+ const cwd = options.cwd || this.defaultCwd;
87
+ const id = options.id || `sdk-${Date.now().toString(36)}-${randomUUID().slice(0, 8)}`;
88
+ this.turnCoordinator.revive(id);
89
+ SessionManager.create(cwd, sessionFileName(id));
90
+ processSessionLocations.set(id, cwd);
91
+ this.cwdBySession.set(id, cwd);
92
+ return { id, cwd };
93
+ }
94
+ openSession(sessionId) {
95
+ const resolved = this.resolveSession(sessionId);
96
+ if (!resolved)
97
+ throw new Error(`Unknown session: ${sessionId}`);
98
+ const ownerKey = resolved.manager.getSessionFile();
99
+ const eventLog = sessionEventLogFor(ownerKey, this.sessionEventRetention);
100
+ const closed = new AbortController();
101
+ return {
102
+ id: sessionId,
103
+ cwd: resolved.cwd,
104
+ get latestSequence() { return eventLog.length; },
105
+ get events() { return eventLog.iterate({ signal: closed.signal }); },
106
+ eventsFrom: (afterSequence) => eventLog.iterate({
107
+ from: Math.max(0, afterSequence),
108
+ signal: closed.signal,
109
+ }),
110
+ send: (options) => this.runTurn(sessionId, options),
111
+ steer: (content) => this.steer(sessionId, content),
112
+ stop: (options) => this.stop(sessionId, options),
113
+ close: () => closed.abort(),
114
+ };
115
+ }
116
+ getHistory(sessionId) {
117
+ if (this.turnCoordinator.isDeleted(sessionId))
118
+ return [];
119
+ return this.resolveSession(sessionId)?.manager.getMessages() ?? [];
120
+ }
121
+ /** Preserve an accepted desktop input cancelled before runTurn was admitted. */
122
+ recordInterruptedInput(sessionId, prompt) {
123
+ const owner = this.ownerForSession(sessionId);
124
+ if (owner && owner !== this)
125
+ return owner.recordInterruptedInput(sessionId, prompt);
126
+ if (this.turnCoordinator.isDeleted(sessionId) || this.getSessionRunState(sessionId).active) {
127
+ throw new Error(`Cannot record interrupted input while session is active or deleted: ${sessionId}`);
128
+ }
129
+ const resolved = this.resolveSession(sessionId);
130
+ if (!resolved)
131
+ throw new Error(`Unknown session: ${sessionId}`);
132
+ this.persistInterruptedInput(resolved, prompt);
133
+ }
134
+ persistInterruptedInput(resolved, prompt) {
135
+ const session = resolved.manager;
136
+ session.getMessages();
137
+ const revision = session.getRevision();
138
+ session.updateMetadata({ cwd: resolved.cwd });
139
+ session.appendMessage({ role: "user", content: prompt }, revision);
140
+ session.appendMessage({
141
+ role: "assistant",
142
+ content: "[Interrupted by user before execution started.]",
143
+ error: { name: "MessageAbortedError", message: "Turn stopped during initialization.", aborted: true },
144
+ }, session.getRevision());
145
+ }
146
+ async deleteSession(sessionId) {
147
+ const owner = this.ownerForSession(sessionId);
148
+ if (owner && owner !== this)
149
+ return owner.deleteSession(sessionId);
150
+ const resolved = this.resolveSession(sessionId);
151
+ for (const runtime of this.runtimesForSession(sessionId))
152
+ runtime.inputController.closePendingInputs();
153
+ await this.turnCoordinator.delete(sessionId);
154
+ if (resolved)
155
+ rmSync(resolved.manager.getSessionFile(), { force: true });
156
+ this.cwdBySession.delete(sessionId);
157
+ this.bashAllowlists.delete(sessionId);
158
+ this.sessionGrants.delete(sessionId);
159
+ this.lastTurnOptions.delete(sessionId);
160
+ this.sessionIndex.delete(sessionId);
161
+ processSessionLocations.delete(sessionId);
162
+ if (resolved) {
163
+ releaseSessionEventLog(resolved.manager.getSessionFile());
164
+ releaseProcessOwner(resolved.manager.getSessionFile(), this);
165
+ }
166
+ }
167
+ /** Interrupt the active turn. Queued turns survive unless cancelQueued is true. */
168
+ stop(sessionId, options = {}) {
169
+ const owner = this.ownerForSession(sessionId);
170
+ if (owner && owner !== this)
171
+ return owner.stop(sessionId, options);
172
+ const current = this.turnCoordinator.getCurrent(sessionId);
173
+ const runtime = current ? this.turnRuntimes.get(current.id) : undefined;
174
+ runtime?.inputController.closePendingInputs();
175
+ // A reserved turn can release its slot synchronously when cancelled.
176
+ // Clear the queue first so cancellation cannot promote an unwanted input.
177
+ const queued = options.cancelQueued ? this.turnCoordinator.clearQueue(sessionId) : 0;
178
+ return queued + this.turnCoordinator.stopCurrent(sessionId);
179
+ }
180
+ /** Stop and wait for persistence, cleanup, and terminal event publication. */
181
+ async stopAndWait(sessionId, options = {}) {
182
+ const owner = this.ownerForSession(sessionId);
183
+ if (owner && owner !== this)
184
+ return owner.stopAndWait(sessionId, options);
185
+ const current = this.turnCoordinator.getCurrent(sessionId);
186
+ const stopping = this.runtimesForSession(sessionId).filter(runtime => options.cancelQueued || runtime.reservation.id === current?.id);
187
+ const stopped = this.stop(sessionId, options);
188
+ await Promise.all(stopping.map(runtime => runtime.finished));
189
+ return stopped;
190
+ }
191
+ /** Cancel queued turns without interrupting the turn that owns the session slot. */
192
+ clearQueue(sessionId) {
193
+ const owner = this.ownerForSession(sessionId);
194
+ if (owner && owner !== this)
195
+ return owner.clearQueue(sessionId);
196
+ return this.turnCoordinator.clearQueue(sessionId);
197
+ }
198
+ getSessionRunState(sessionId) {
199
+ const owner = this.ownerForSession(sessionId);
200
+ if (owner && owner !== this)
201
+ return owner.getSessionRunState(sessionId);
202
+ const state = this.turnCoordinator.getState(sessionId);
203
+ const current = this.turnCoordinator.getCurrent(sessionId);
204
+ const runtime = current ? this.turnRuntimes.get(current.id) : undefined;
205
+ return {
206
+ active: state.active,
207
+ queuedTurns: state.queued,
208
+ pendingSteers: runtime?.outcomes.size ?? 0,
209
+ phase: state.phase,
210
+ };
211
+ }
212
+ /**
213
+ * Add text to the turn that currently owns the session slot. Every accepted
214
+ * input exposes an outcome promise, independent of event-stream consumption.
215
+ */
216
+ steer(sessionId, content) {
217
+ if (this.turnCoordinator.isDeleted(sessionId)) {
218
+ return { accepted: false, disposition: "rejected", reason: "session_deleted" };
219
+ }
220
+ const owner = this.ownerForSession(sessionId);
221
+ if (owner && owner !== this)
222
+ return owner.steer(sessionId, content);
223
+ const resolved = this.resolveSession(sessionId);
224
+ if (!resolved) {
225
+ return { accepted: false, disposition: "rejected", reason: "unknown_session" };
226
+ }
227
+ const current = this.turnCoordinator.getCurrent(sessionId);
228
+ const runtime = current ? this.turnRuntimes.get(current.id) : undefined;
229
+ if (runtime) {
230
+ const input = runtime.inputController.tryEnqueue(content);
231
+ if (input) {
232
+ const pending = pendingSteerOutcome(input);
233
+ runtime.outcomes.set(input.id, pending);
234
+ return { accepted: true, disposition: "steered", input, outcome: pending.promise };
235
+ }
236
+ }
237
+ return this.queueDetachedInput(sessionId, content, resolved);
238
+ }
239
+ enqueueTurn(sessionId, options) {
240
+ return this.runTurn(sessionId, options);
241
+ }
242
+ queueTurn(sessionId, options) {
243
+ return this.enqueueTurn(sessionId, options);
244
+ }
245
+ // ── Discovery (composer pickers) ─────────────────────────────────────────
246
+ listSkills(cwd, skillPaths = []) {
247
+ const registry = new SkillRegistry({
248
+ cwd: cwd || this.defaultCwd,
249
+ skillPaths: [...this.userConfig.getSkillPaths(), ...skillPaths],
250
+ disabledSkills: this.userConfig.getDisabledSkills(),
251
+ });
252
+ return registry.summaries();
253
+ }
254
+ /**
255
+ * Ask the host once per folder (onProjectTrust) before this turn loads the
256
+ * repository's allow rules, MCP servers and LSP servers. Trusting restarts
257
+ * the folder's MCP servers so newly trusted ones are available right away.
258
+ */
259
+ async resolveProjectTrust(cwd, options, signal) {
260
+ if (!options.onProjectTrust || this.projectTrustAsked.has(cwd))
261
+ return;
262
+ // Read once: what gets trusted is exactly what the host was shown.
263
+ const raw = readRepoSettings(cwd);
264
+ if (isRepoConfigTrusted(cwd, raw))
265
+ return;
266
+ this.projectTrustAsked.add(cwd);
267
+ const trusted = await awaitWithAbort(options.onProjectTrust({ cwd, pending: mergedRepoCapabilities(raw) }), signal);
268
+ if (!trusted)
269
+ return;
270
+ trustRepoConfig(cwd, raw);
271
+ const manager = this.mcpManagersByCwd.get(cwd);
272
+ this.mcpManagersByCwd.delete(cwd);
273
+ this.mcpToolsByCwd.delete(cwd);
274
+ await (await manager?.catch(() => null))?.shutdown().catch(() => undefined);
275
+ }
276
+ /** Configured providers + default model, for a host's model picker. */
277
+ getModelConfig() {
278
+ const configured = this.registry.getConfigured().filter((p) => p.enabled);
279
+ return {
280
+ defaultProviderId: this.registry.getDefault()?.id ?? "",
281
+ defaultModel: this.userConfig.getDefaultModel() ?? "",
282
+ providers: configured.map((p) => ({ id: p.id, baseURL: p.baseURL, hasApiKey: Boolean(p.apiKey) })),
283
+ };
284
+ }
285
+ // ── The turn ─────────────────────────────────────────────────────────────
286
+ /**
287
+ * Reserve and start a session turn immediately. Execution is driven by the
288
+ * SDK's own pump, not by consumption of the returned iterator: the iterator
289
+ * is a replay subscription, so a host may drop it (or reconnect later via
290
+ * `openSession`) without stalling or cancelling the turn. Cancel with
291
+ * `stop()`, the options signal, or `deleteSession()`.
292
+ */
293
+ runTurn(sessionId, options) {
294
+ const resolved = this.resolveSession(sessionId);
295
+ if (!resolved)
296
+ throw new Error(`Unknown session: ${sessionId}`);
297
+ const ownerKey = resolved.manager.getSessionFile();
298
+ const owner = processSessionOwners.get(ownerKey);
299
+ if (owner && owner !== this)
300
+ return owner.runTurn(sessionId, options);
301
+ claimProcessOwner(ownerKey, this);
302
+ try {
303
+ const runtime = this.startOwnedTurn(sessionId, options, resolved, ownerKey);
304
+ return runtime.events.iterate();
305
+ }
306
+ catch (error) {
307
+ // A synchronous reserve() failure (e.g. pre-aborted signal) must not
308
+ // leave this SDK pinned as process owner of a session it never ran.
309
+ if (!this.turnCoordinator.getState(sessionId).active) {
310
+ releaseProcessOwner(ownerKey, this);
311
+ }
312
+ throw error;
313
+ }
314
+ }
315
+ startOwnedTurn(sessionId, options, resolved, ownerKey) {
316
+ const reservation = this.turnCoordinator.reserve(sessionId, options.signal);
317
+ const runtime = {
318
+ sessionId,
319
+ ownerKey,
320
+ reservation,
321
+ inputController: new AgentRunInputQueue(`sdk-turn-${this.inputIdNonce}-${++this.nextTurnInputPrefix}`),
322
+ outcomes: new Map(),
323
+ options,
324
+ events: new ReplayEventLog(),
325
+ started: reservation.phase !== "queued",
326
+ inputRecorded: false,
327
+ finished: Promise.resolve(),
328
+ };
329
+ this.lastTurnOptions.set(sessionId, inheritableTurnOptions(options));
330
+ this.turnRuntimes.set(reservation.id, runtime);
331
+ runtime.finished = this.pumpTurn(runtime, resolved);
332
+ return runtime;
333
+ }
334
+ async pumpTurn(runtime, resolved) {
335
+ let failure;
336
+ let completedEvent;
337
+ try {
338
+ for await (const event of this.runReservedTurn(runtime, runtime.options, resolved)) {
339
+ runtime.events.append(event);
340
+ // Publish success after the pump's finally releases its slot.
341
+ // A host can then distinguish idle from an automatically queued steer.
342
+ if (event.type === "agent_end")
343
+ completedEvent = event;
344
+ else
345
+ this.publishSessionEvent(runtime, event);
346
+ }
347
+ }
348
+ catch (error) {
349
+ failure = error;
350
+ // Setup can fail before runReservedTurn installs its own cleanup.
351
+ for (const event of this.rejectOutstandingSteers(runtime, runtime.reservation.signal.aborted ? "turn_cancelled" : "turn_failed")) {
352
+ runtime.events.append(event);
353
+ this.publishSessionEvent(runtime, event);
354
+ }
355
+ // Desktop users already submitted this input. Even if setup was
356
+ // interrupted before Agent.run appended it, keep it for a later resume.
357
+ // Cancelled queued inputs never owned the turn and must stay discarded.
358
+ if (runtime.options.preserveInterruptedInput && runtime.started && !runtime.inputRecorded
359
+ && runtime.reservation.signal.aborted && !this.turnCoordinator.isDeleted(runtime.sessionId)) {
360
+ try {
361
+ this.persistInterruptedInput(resolved, runtime.options.prompt);
362
+ }
363
+ catch (persistError) {
364
+ failure = persistError;
365
+ }
366
+ }
367
+ }
368
+ finally {
369
+ runtime.inputController.closePendingInputs();
370
+ // Release only after the interrupted input is durable. Keep the runtime
371
+ // discoverable until the terminal event is published for stopAndWait.
372
+ runtime.reservation.finish();
373
+ if (failure !== undefined) {
374
+ // The session-level log never closes per turn, so replay subscribers
375
+ // need an explicit terminal record — otherwise a failed turn is
376
+ // indistinguishable from one that is still running.
377
+ this.publishSessionEvent(runtime, { type: "turn_end", willContinue: false }, {
378
+ kind: failure instanceof AgentAbortError || runtime.reservation.signal.aborted
379
+ ? "cancelled"
380
+ : "failed",
381
+ message: failure instanceof Error ? failure.message : String(failure),
382
+ });
383
+ }
384
+ else {
385
+ this.publishSessionEvent(runtime, completedEvent ?? { type: "agent_end" }, { kind: "completed" });
386
+ }
387
+ runtime.events.close(failure);
388
+ if (this.turnRuntimes.get(runtime.reservation.id) === runtime) {
389
+ this.turnRuntimes.delete(runtime.reservation.id);
390
+ }
391
+ if (!this.turnCoordinator.getState(runtime.sessionId).active) {
392
+ releaseProcessOwner(runtime.ownerKey, this);
393
+ }
394
+ }
395
+ }
396
+ async *runReservedTurn(runtime, options, resolved) {
397
+ const { sessionId, reservation, inputController } = runtime;
398
+ const { manager: session, cwd } = resolved;
399
+ const mode = options.mode ?? "default";
400
+ const planExitMode = options.planExitMode === "bypassPermissions" ? "bypassPermissions" : "default";
401
+ const abortSignal = reservation.signal;
402
+ await reservation.waitForStart();
403
+ runtime.started = true;
404
+ let agentRef;
405
+ let streamCompleted = false;
406
+ const hookController = new ExternalHookController({ cwd, sessionId });
407
+ await this.resolveProjectTrust(cwd, options, abortSignal);
408
+ // Same allow/deny rules as the TUI (user, project and local settings;
409
+ // repository allow rules only once trusted). Deny rules bind even under
410
+ // bypassPermissions.
411
+ const ruleSet = new SettingsManager(cwd).getMerged().ruleSet;
412
+ // Settles as reject the moment the turn aborts, so a tool blocked on a
413
+ // host approval (or question) can never hang the abort path.
414
+ const abortedDecision = new Promise((resolve) => {
415
+ const decide = () => resolve({ action: "reject", feedback: "Turn aborted" });
416
+ if (abortSignal.aborted)
417
+ decide();
418
+ else
419
+ abortSignal.addEventListener("abort", decide, { once: true });
420
+ });
421
+ const approvalController = new PermissionAwareApprovalController({
422
+ getMode: () => agentRef?.mode ?? mode,
423
+ handlerRef: {
424
+ current: (req) => options.onApproval
425
+ ? Promise.race([options.onApproval(req), abortedDecision])
426
+ : Promise.resolve({
427
+ action: "reject",
428
+ feedback: "Host provided no approval handler",
429
+ }),
430
+ },
431
+ bashAllowlist: this.bashAllowlistFor(sessionId),
432
+ sessionGrants: this.sessionGrantsFor(sessionId),
433
+ cwd,
434
+ // Read once per turn: edits to settings files apply from the next turn.
435
+ getRuleSet: () => ruleSet,
436
+ externalHooks: hookController,
437
+ });
438
+ const fileStateTracker = new FileStateTracker(cwd);
439
+ const planController = {
440
+ getMode: () => agentRef?.mode ?? mode,
441
+ requestApproval: async (plan) => {
442
+ const approved = options.onPlanApproval
443
+ ? await awaitWithAbort(options.onPlanApproval(plan), abortSignal)
444
+ : false;
445
+ // exit_plan_mode applies getExitMode() itself on approval.
446
+ return approved
447
+ ? { action: "approve", plan }
448
+ : { action: "reject", reason: "Plan rejected by host" };
449
+ },
450
+ setMode: (m) => agentRef?.setMode(m),
451
+ getExitMode: () => planExitMode,
452
+ };
453
+ const questionController = new QuestionController();
454
+ const unsubscribeQuestions = questionController.subscribe((event) => {
455
+ if (event.type !== "asked")
456
+ return;
457
+ const request = event.request;
458
+ if (!options.onQuestion) {
459
+ questionController.reject(request.id);
460
+ return;
461
+ }
462
+ options.onQuestion(request).then((answers) => answers ? questionController.reply(request.id, answers) : questionController.reject(request.id), () => questionController.reject(request.id));
463
+ });
464
+ abortSignal.addEventListener("abort", () => questionController.rejectAll(), { once: true });
465
+ try {
466
+ const skillRegistry = new SkillRegistry({
467
+ cwd,
468
+ skillPaths: [...this.userConfig.getSkillPaths(), ...(options.skillPaths ?? [])],
469
+ disabledSkills: this.userConfig.getDisabledSkills(),
470
+ });
471
+ const tools = createAllTools(cwd, skillRegistry, {
472
+ approvalController,
473
+ fileStateTracker,
474
+ planController,
475
+ questionController,
476
+ goalStore: new GoalStore(),
477
+ checkpoints: () => session.getCheckpoints(),
478
+ });
479
+ tools.push(...gateMcpTools(await awaitWithAbort(this.mcpToolsFor(cwd), abortSignal), approvalController));
480
+ const hostTools = options.hostTools ?? [];
481
+ const registered = new Set(tools.map(tool => tool.name));
482
+ for (const tool of hostTools) {
483
+ if (registered.has(tool.name))
484
+ throw new Error(`Duplicate host tool: ${tool.name}`);
485
+ registered.add(tool.name);
486
+ const guarded = {
487
+ ...tool,
488
+ execute: async (args, ctx) => {
489
+ throwAbortSignal(abortSignal);
490
+ return tool.execute(args, { ...ctx, abortSignal });
491
+ },
492
+ cloneForChild: () => ({ ...tool, enabled: () => false, execute: async () => ({ content: "Host capability is not available to this child.", isError: true }) }),
493
+ };
494
+ tools.push(...(tool.readOnly ? [guarded] : gateMcpTools([guarded], approvalController)));
495
+ }
496
+ throwAbortSignal(abortSignal);
497
+ const promptCacheKey = session.getOrCreatePromptCacheKey();
498
+ if (!this.turnCoordinator.isDeleted(sessionId)) {
499
+ session.updateMetadata({ cwd }); // recoverable by cwd after host restart
500
+ }
501
+ const { provider, providerId, model } = this.resolveProvider(promptCacheKey, options.model);
502
+ const thinkingLevel = options.thinkingLevel ??
503
+ this.userConfig.getDefaultThinkingLevel() ??
504
+ getDefaultThinkingLevel(providerId, decodeModel(model).modelId);
505
+ // Same ordering as the TUI: the provenance gate must run before memories
506
+ // enter the system prompt.
507
+ purgeUnsafeMemorySources(cwd);
508
+ const memoryPrompt = buildMemoryPrompt(cwd);
509
+ const builtSystemPrompt = buildSystemPrompt({
510
+ agentName: "Bubble",
511
+ skills: skillRegistry.summaries(),
512
+ skillCatalogChars: this.userConfig.getSkillCatalogChars(),
513
+ configuredProvider: providerId || "none",
514
+ configuredModel: model ? displayModel(model) : "none",
515
+ configuredModelId: model || "none",
516
+ thinkingLevel,
517
+ mode,
518
+ workingDir: cwd,
519
+ ...buildToolPromptOptions(tools.filter((t) => !t.deferred)),
520
+ memoryPrompt,
521
+ });
522
+ const systemPrompt = options.appendSystemPrompt
523
+ ? `${builtSystemPrompt}\n\n${options.appendSystemPrompt.trim()}`
524
+ : builtSystemPrompt;
525
+ // Host-driven mode changes (picker, /plan, leaving plan) go into the log
526
+ // as markers, so the rebuilt history states the mode where it changed —
527
+ // after any older tool result that claimed a different mode.
528
+ if (latestRecordedMode(session) !== mode && !this.turnCoordinator.isDeleted(sessionId)) {
529
+ session.appendMarker("mode_switch", mode);
530
+ }
531
+ const history = session.getMessages();
532
+ let contextRevision = session.getRevision();
533
+ // The constructor's leading context minus its mode reminder: the history
534
+ // carries the mode timeline itself (session-log toMessages).
535
+ let leadingContext = [];
536
+ // A fence rejection means the durable log diverged from this turn's
537
+ // resident snapshot (a foreign append or clear landed mid-flight). Refuse
538
+ // the write, then roll the resident transcript back to the file's truth so
539
+ // the rejected message does not linger and later writes are not wedged
540
+ // behind the stale revision.
541
+ const persistFenced = (write) => {
542
+ try {
543
+ write();
544
+ }
545
+ catch (error) {
546
+ // Any refused write (fence rejection, busy lock, I/O) leaves the agent's
547
+ // already-pushed message unpersisted. getMessages() refreshes, so read
548
+ // the history first and adopt the revision of that same snapshot.
549
+ try {
550
+ const reloaded = session.getMessages();
551
+ contextRevision = session.getRevision();
552
+ agent.messages = [...leadingContext, ...reloaded];
553
+ }
554
+ catch { /* surface the original write failure */ }
555
+ throw error;
556
+ }
557
+ };
558
+ const agent = new Agent({
559
+ provider,
560
+ providerId,
561
+ model,
562
+ sessionID: session.getSessionFile(),
563
+ tools,
564
+ systemPrompt,
565
+ temperature: 0.2,
566
+ thinkingLevel,
567
+ mode,
568
+ budgetLedger: new BudgetLedger(),
569
+ fileStateTracker,
570
+ skills: skillRegistry.summaries(),
571
+ skillCatalogChars: this.userConfig.getSkillCatalogChars(),
572
+ memoryPrompt,
573
+ externalHooks: hookController,
574
+ // Cross-provider subagent routes (spawn_agent with "provider:model")
575
+ // need a factory; without one the child blocks with
576
+ // "no provider factory is configured". Default mirrors the TUI's
577
+ // createProviderForRoute (OAuth prepare + configured+enabled+keyed
578
+ // profile lookup); hosts may override per turn.
579
+ providerFactory: options.providerFactory ?? this.defaultProviderFactory(),
580
+ onMessageAppend: (message) => {
581
+ if (message.role === "system" || message.role === "meta")
582
+ return;
583
+ if (this.turnCoordinator.isDeleted(sessionId))
584
+ return;
585
+ if (message.role === "user")
586
+ runtime.inputRecorded = true;
587
+ persistFenced(() => {
588
+ session.appendMessage(message, contextRevision);
589
+ contextRevision = session.getRevision();
590
+ });
591
+ if (message.role === "assistant")
592
+ recordMemoryCitations(cwd, message.content);
593
+ },
594
+ onProviderError: (error) => {
595
+ if (this.turnCoordinator.isDeleted(sessionId))
596
+ return;
597
+ persistFenced(() => session.appendProviderError(error, contextRevision));
598
+ },
599
+ getContextRevision: () => contextRevision,
600
+ onContextCheckpoint: (checkpoint) => {
601
+ if (this.turnCoordinator.isDeleted(sessionId))
602
+ throw new Error("Session deleted before context commit");
603
+ persistFenced(() => {
604
+ session.commitContextCheckpoint(checkpoint, contextRevision);
605
+ contextRevision = session.getRevision();
606
+ });
607
+ },
608
+ onModeUpdate: (m) => {
609
+ if (!this.turnCoordinator.isDeleted(sessionId)) {
610
+ persistFenced(() => {
611
+ session.appendMarker("mode_switch", m, contextRevision);
612
+ contextRevision = session.getRevision();
613
+ });
614
+ }
615
+ },
616
+ });
617
+ agentRef = agent;
618
+ leadingContext = agent.messages.filter((message) => !(message.role === "meta" && isPermissionModeReminder(message.content)));
619
+ if (history.length > 0) {
620
+ // Leading context (system prompt + deferred-tools reminder, never
621
+ // persisted) stays ahead of the history, at the same position every
622
+ // turn, so the provider's prefix cache covers the previous turn. The
623
+ // mode reminder comes from the history's own mode markers instead, so
624
+ // it is ordered after anything older that mentioned a mode.
625
+ agent.messages = [...leadingContext, ...history];
626
+ }
627
+ reservation.markActive();
628
+ options.onStart?.({
629
+ providerId,
630
+ model,
631
+ thinkingLevel,
632
+ mode,
633
+ tools: tools.map((t) => t.name),
634
+ skills: skillRegistry.summaries().map((s) => s.name),
635
+ });
636
+ // Match the TUI: a leading "/<skill-name> <task>" becomes an explicit
637
+ // load-this-skill instruction, so invocation never depends on the model
638
+ // recognizing the slash syntax on its own.
639
+ const prompt = rewriteSkillInvocationPrompt(options.prompt, skillRegistry);
640
+ const bareModelId = decodeModel(model).modelId;
641
+ for await (const event of agent.run(prompt, cwd, {
642
+ abortSignal,
643
+ inputController,
644
+ })) {
645
+ const sdkEvent = this.handleSteerEvent(runtime, event, resolved);
646
+ yield attachTurnCost(sdkEvent, providerId, bareModelId);
647
+ }
648
+ streamCompleted = true;
649
+ for (const event of this.rejectOutstandingSteers(runtime, "no_continuation", resolved))
650
+ yield event;
651
+ }
652
+ catch (error) {
653
+ const reason = abortSignal.aborted ? "turn_cancelled" : "turn_failed";
654
+ for (const event of this.rejectOutstandingSteers(runtime, reason))
655
+ yield event;
656
+ throw error;
657
+ }
658
+ finally {
659
+ inputController.closePendingInputs();
660
+ this.rejectOutstandingSteers(runtime, streamCompleted ? "no_continuation" : abortSignal.aborted ? "turn_cancelled" : "turn_failed", streamCompleted ? resolved : undefined);
661
+ unsubscribeQuestions();
662
+ questionController.rejectAll();
663
+ }
664
+ }
665
+ // ── Internals ────────────────────────────────────────────────────────────
666
+ runtimesForSession(sessionId) {
667
+ return [...this.turnRuntimes.values()].filter((runtime) => runtime.sessionId === sessionId);
668
+ }
669
+ settleSteerFromEvent(runtime, event) {
670
+ if (event.type !== "input_applied" && event.type !== "input_rejected")
671
+ return;
672
+ const pending = runtime.outcomes.get(event.id);
673
+ if (!pending)
674
+ return;
675
+ runtime.outcomes.delete(event.id);
676
+ pending.resolve(event);
677
+ }
678
+ handleSteerEvent(runtime, event, resolved) {
679
+ if (event.type === "input_rejected" && event.reason === "no_continuation") {
680
+ const pending = runtime.outcomes.get(event.id);
681
+ if (pending)
682
+ return this.queuePendingSteer(runtime, pending, resolved, event);
683
+ }
684
+ this.settleSteerFromEvent(runtime, event);
685
+ return event;
686
+ }
687
+ rejectOutstandingSteers(runtime, reason, resolved) {
688
+ runtime.inputController.closePendingInputs();
689
+ const events = [];
690
+ for (const [id, pending] of runtime.outcomes) {
691
+ const event = {
692
+ type: "input_rejected",
693
+ id,
694
+ content: pending.input.content,
695
+ reason,
696
+ target: "next_turn",
697
+ };
698
+ runtime.outcomes.delete(id);
699
+ if (reason === "no_continuation" && resolved) {
700
+ events.push(this.queuePendingSteer(runtime, pending, resolved, event));
701
+ }
702
+ else {
703
+ pending.resolve(event);
704
+ events.push(event);
705
+ }
706
+ }
707
+ return events;
708
+ }
709
+ queuePendingSteer(runtime, pending, resolved, rejected) {
710
+ try {
711
+ const queuedRuntime = this.startOwnedTurn(runtime.sessionId, { ...inheritableTurnOptions(runtime.options), prompt: pending.input.content }, resolved, runtime.ownerKey);
712
+ const queued = {
713
+ type: "input_queued",
714
+ id: pending.input.id,
715
+ content: pending.input.content,
716
+ turnId: queuedRuntime.reservation.id,
717
+ target: "next_turn",
718
+ };
719
+ // The follow-up turn's own subscribers also see the queue marker; the
720
+ // session-level log already gets it once via this turn's yielded event.
721
+ queuedRuntime.events.append(queued);
722
+ runtime.outcomes.delete(pending.input.id);
723
+ pending.resolve(queued);
724
+ return queued;
725
+ }
726
+ catch {
727
+ runtime.outcomes.delete(pending.input.id);
728
+ pending.resolve(rejected);
729
+ return rejected;
730
+ }
731
+ }
732
+ queueDetachedInput(sessionId, content, resolved) {
733
+ const ownerKey = resolved.manager.getSessionFile();
734
+ try {
735
+ claimProcessOwner(ownerKey, this);
736
+ const input = {
737
+ id: `sdk-steer-${this.inputIdNonce}-${++this.nextDetachedInputId}`,
738
+ content,
739
+ submittedAt: Date.now(),
740
+ };
741
+ const runtime = this.startOwnedTurn(sessionId, { ...(this.lastTurnOptions.get(sessionId) ?? {}), prompt: content }, resolved, ownerKey);
742
+ const queued = {
743
+ type: "input_queued",
744
+ id: input.id,
745
+ content,
746
+ turnId: runtime.reservation.id,
747
+ target: "next_turn",
748
+ };
749
+ runtime.events.append(queued);
750
+ this.publishSessionEvent(runtime, queued);
751
+ return {
752
+ accepted: true,
753
+ disposition: "queued",
754
+ input,
755
+ turnId: runtime.reservation.id,
756
+ outcome: Promise.resolve(queued),
757
+ };
758
+ }
759
+ catch {
760
+ releaseProcessOwner(ownerKey, this);
761
+ return { accepted: false, disposition: "rejected", reason: "ownership_conflict" };
762
+ }
763
+ }
764
+ publishSessionEvent(runtime, event, terminal) {
765
+ const log = sessionEventLogFor(runtime.ownerKey, this.sessionEventRetention);
766
+ log.append({
767
+ sequence: log.length + 1,
768
+ sessionId: runtime.sessionId,
769
+ turnId: runtime.reservation.id,
770
+ event,
771
+ ...(terminal ? { terminal } : {}),
772
+ });
773
+ }
774
+ ownerForSession(sessionId) {
775
+ const resolved = this.resolveSession(sessionId);
776
+ return resolved ? processSessionOwners.get(resolved.manager.getSessionFile()) : undefined;
777
+ }
778
+ bashAllowlistFor(sessionId) {
779
+ let allowlist = this.bashAllowlists.get(sessionId);
780
+ if (!allowlist) {
781
+ allowlist = new BashAllowlist();
782
+ this.bashAllowlists.set(sessionId, allowlist);
783
+ }
784
+ return allowlist;
785
+ }
786
+ sessionGrantsFor(sessionId) {
787
+ let grants = this.sessionGrants.get(sessionId);
788
+ if (!grants) {
789
+ grants = new Set();
790
+ this.sessionGrants.set(sessionId, grants);
791
+ }
792
+ return grants;
793
+ }
794
+ /**
795
+ * Default cross-provider subagent factory over this SDK instance's own
796
+ * registry — the same semantics as the TUI's createProviderForRoute. The
797
+ * registry is reloaded first so a key added after construction works.
798
+ */
799
+ defaultProviderFactory() {
800
+ return async (route) => {
801
+ const providerId = route.providerId;
802
+ if (!providerId) {
803
+ throw new Error(`Subagent route for model "${route.model}" did not include a provider.`);
804
+ }
805
+ // getConfigured() reads config.json from disk every call, so keys
806
+ // added after SDK construction are picked up without a reload call.
807
+ const target = this.registry.getConfigured().find((item) => item.id === providerId);
808
+ if (target?.authType === "oauth") {
809
+ await this.registry.prepareProvider(providerId);
810
+ }
811
+ if (!target?.enabled || !target.apiKey) {
812
+ throw new Error(`Subagent route requires provider "${providerId}", but it is not configured or has no active credentials.`);
813
+ }
814
+ return createProviderInstance({
815
+ providerId,
816
+ apiKey: target.apiKey,
817
+ baseURL: target.baseURL,
818
+ protocol: target.protocol,
819
+ headers: target.headers,
820
+ openAICodexAuth: this.registry.createOpenAICodexAuthAdapter(providerId),
821
+ grokAuth: this.registry.createGrokAuthAdapter(providerId),
822
+ });
823
+ };
824
+ }
825
+ /**
826
+ * MCP servers are started lazily, once per cwd, and restarted only when the
827
+ * repository's settings get trusted (resolveProjectTrust).
828
+ */
829
+ mcpToolsFor(cwd) {
830
+ if (!this.mcpEnabled)
831
+ return Promise.resolve([]);
832
+ let cached = this.mcpToolsByCwd.get(cwd);
833
+ if (!cached) {
834
+ const managerPromise = (async () => {
835
+ const loaded = loadMcpConfig({ cwd });
836
+ if (loaded.servers.length === 0)
837
+ return null;
838
+ const manager = new McpManager({ servers: loaded.servers });
839
+ await manager.start();
840
+ return manager;
841
+ })().catch(() => null);
842
+ this.mcpManagersByCwd.set(cwd, managerPromise);
843
+ cached = managerPromise.then((manager) => manager?.getToolEntries() ?? []);
844
+ this.mcpToolsByCwd.set(cwd, cached);
845
+ }
846
+ return cached;
847
+ }
848
+ resolveSession(sessionId) {
849
+ if (this.turnCoordinator.isDeleted(sessionId))
850
+ return undefined;
851
+ const memCwd = this.cwdBySession.get(sessionId);
852
+ if (memCwd) {
853
+ // create() only resolves the path and loads iff the file exists, so this
854
+ // covers both fresh (lazily persisted, not yet on disk) and resumed sessions.
855
+ return { manager: SessionManager.create(memCwd, sessionFileName(sessionId)), cwd: memCwd };
856
+ }
857
+ if (this.sessionIndex.size === 0)
858
+ this.listSessions();
859
+ const entry = this.sessionIndex.get(sessionId);
860
+ if (!entry) {
861
+ // A session created in this process but not yet persisted to disk is
862
+ // still resolvable (and routable) for other SDK instances.
863
+ const registeredCwd = processSessionLocations.get(sessionId);
864
+ if (!registeredCwd)
865
+ return undefined;
866
+ this.cwdBySession.set(sessionId, registeredCwd);
867
+ return {
868
+ manager: SessionManager.create(registeredCwd, sessionFileName(sessionId)),
869
+ cwd: registeredCwd,
870
+ };
871
+ }
872
+ // The disk entry supersedes the pre-persistence registry entry.
873
+ processSessionLocations.delete(sessionId);
874
+ this.cwdBySession.set(sessionId, entry.cwd);
875
+ return { manager: new SessionManager(entry.file), cwd: entry.cwd };
876
+ }
877
+ resolveProvider(promptCacheKey, explicitModel) {
878
+ const configuredModel = explicitModel || this.userConfig.getDefaultModel();
879
+ const defaultProvider = this.registry.getDefault();
880
+ const fallbackProviderId = defaultProvider?.id ?? "";
881
+ const normalized = configuredModel
882
+ ? configuredModel.includes(":")
883
+ ? configuredModel
884
+ : fallbackProviderId
885
+ ? encodeModel(fallbackProviderId, configuredModel)
886
+ : ""
887
+ : "";
888
+ const { providerId: effId, modelId: effModelId } = normalized
889
+ ? decodeModel(normalized)
890
+ : { providerId: undefined, modelId: "" };
891
+ const activeProviderId = effId || fallbackProviderId;
892
+ if (effModelId)
893
+ assertProviderModelAllowed(activeProviderId, effModelId);
894
+ const target = this.registry.getConfigured().find((p) => p.id === activeProviderId) || defaultProvider;
895
+ if (!target?.apiKey) {
896
+ throw new Error("No provider with an API key configured — run the Bubble CLI once to set one up");
897
+ }
898
+ const activeModel = effModelId ? encodeModel(activeProviderId, effModelId) : "";
899
+ const provider = createProviderInstance({
900
+ providerId: activeProviderId,
901
+ apiKey: target.apiKey,
902
+ baseURL: target.baseURL,
903
+ promptCacheKey,
904
+ protocol: target.protocol,
905
+ headers: target.headers,
906
+ // Main SDK turns need the same per-request OAuth renewal as the TUI
907
+ // and child provider factory, including calls after a long-running tool.
908
+ openAICodexAuth: this.registry.createOpenAICodexAuthAdapter(activeProviderId),
909
+ grokAuth: this.registry.createGrokAuthAdapter(activeProviderId),
910
+ });
911
+ return { provider, providerId: activeProviderId, model: activeModel };
912
+ }
913
+ }
914
+ /**
915
+ * Process-local ownership routes every producer to one SDK runner. Hosts that
916
+ * run multiple OS processes still need a broker or distributed per-session
917
+ * lease; two processes cannot safely share a local JSONL transcript directly.
918
+ */
919
+ const processSessionOwners = new Map();
920
+ const sessionEventLogs = new Map();
921
+ /** sessionId -> cwd for sessions created in this process but not yet on disk. */
922
+ const processSessionLocations = new Map();
923
+ function claimProcessOwner(ownerKey, sdk) {
924
+ const existing = processSessionOwners.get(ownerKey);
925
+ if (existing && existing !== sdk) {
926
+ throw new Error(`SDK session is owned by another runner: ${ownerKey}`);
927
+ }
928
+ processSessionOwners.set(ownerKey, sdk);
929
+ }
930
+ function releaseProcessOwner(ownerKey, sdk) {
931
+ if (processSessionOwners.get(ownerKey) === sdk)
932
+ processSessionOwners.delete(ownerKey);
933
+ }
934
+ function sessionEventLogFor(ownerKey, retention = Infinity) {
935
+ let log = sessionEventLogs.get(ownerKey);
936
+ if (!log) {
937
+ log = new ReplayEventLog(retention);
938
+ sessionEventLogs.set(ownerKey, log);
939
+ }
940
+ return log;
941
+ }
942
+ /** End live iterators and drop the buffered events of a deleted session. */
943
+ function releaseSessionEventLog(ownerKey) {
944
+ const log = sessionEventLogs.get(ownerKey);
945
+ if (!log)
946
+ return;
947
+ log.close();
948
+ sessionEventLogs.delete(ownerKey);
949
+ }
950
+ function inheritableTurnOptions(options) {
951
+ const { prompt: _prompt, signal: _signal, ...inherited } = options;
952
+ return inherited;
953
+ }
954
+ function sessionFileName(sessionId) {
955
+ return sessionId.endsWith(".jsonl") ? sessionId : `${sessionId}.jsonl`;
956
+ }
957
+ function pendingSteerOutcome(input) {
958
+ let resolve;
959
+ const promise = new Promise((done) => {
960
+ resolve = done;
961
+ });
962
+ return { input, promise, resolve };
963
+ }
964
+ function throwAbortSignal(signal) {
965
+ if (!signal.aborted)
966
+ return;
967
+ if (signal.reason instanceof Error)
968
+ throw signal.reason;
969
+ throw new AgentAbortError(typeof signal.reason === "string" ? signal.reason : "SDK turn cancelled.");
970
+ }
971
+ /** The mode the session log last recorded ("default" before any switch). */
972
+ function latestRecordedMode(session) {
973
+ const entries = session.getEntries();
974
+ for (let index = entries.length - 1; index >= 0; index--) {
975
+ const entry = entries[index];
976
+ if (entry.type === "marker" && entry.kind === "mode_switch"
977
+ && (entry.value === "default" || entry.value === "plan" || entry.value === "bypassPermissions")) {
978
+ return entry.value;
979
+ }
980
+ }
981
+ return "default";
982
+ }
983
+ function awaitWithAbort(promise, signal) {
984
+ if (signal.aborted) {
985
+ try {
986
+ throwAbortSignal(signal);
987
+ }
988
+ catch (error) {
989
+ return Promise.reject(error);
990
+ }
991
+ }
992
+ return new Promise((resolve, reject) => {
993
+ const onAbort = () => {
994
+ cleanup();
995
+ try {
996
+ throwAbortSignal(signal);
997
+ }
998
+ catch (error) {
999
+ reject(error);
1000
+ }
1001
+ };
1002
+ const cleanup = () => signal.removeEventListener("abort", onAbort);
1003
+ signal.addEventListener("abort", onAbort, { once: true });
1004
+ promise.then((value) => {
1005
+ cleanup();
1006
+ resolve(value);
1007
+ }, (error) => {
1008
+ cleanup();
1009
+ reject(error);
1010
+ });
1011
+ });
1012
+ }
1013
+ /**
1014
+ * Attach a `cost` field to turn_end events that carry usage, priced via the
1015
+ * static pricing table. Pricing is an accounting concern, so it rides along
1016
+ * here in the SDK rather than in the agent core. Multi-step turns emit several
1017
+ * turn_end events; each cost covers only that step's usage, so hosts sum them.
1018
+ * Events for unpriced models (or without usage) pass through untouched.
1019
+ */
1020
+ export function attachTurnCost(event, providerId, modelId, at = new Date()) {
1021
+ if (event.type !== "turn_end" || !event.usage)
1022
+ return event;
1023
+ const cost = calculateUsageCost(providerId, modelId, event.usage, at);
1024
+ return cost ? { ...event, cost } : event;
1025
+ }
1026
+ /**
1027
+ * If the prompt (or its first text part) is a "/<skill-name> <task>" skill
1028
+ * invocation, rewrite it into the same explicit execution prompt the TUI
1029
+ * sends. Non-matching prompts pass through untouched.
1030
+ */
1031
+ export function rewriteSkillInvocationPrompt(prompt, registry) {
1032
+ if (typeof prompt === "string") {
1033
+ return parseSkillInvocation(prompt, registry)?.actualPrompt ?? prompt;
1034
+ }
1035
+ const index = prompt.findIndex((part) => part.type === "text");
1036
+ if (index === -1)
1037
+ return prompt;
1038
+ const part = prompt[index];
1039
+ const rewritten = parseSkillInvocation(part.text, registry)?.actualPrompt;
1040
+ if (!rewritten)
1041
+ return prompt;
1042
+ const next = prompt.slice();
1043
+ next[index] = { ...part, text: rewritten };
1044
+ return next;
1045
+ }
1046
+ // ── Building blocks (escape hatch for custom hosts) ────────────────────────
1047
+ export { Agent, AgentAbortError } from "../agent.js";
1048
+ export { AgentRunInputQueue } from "../agent/input-controller.js";
1049
+ export { SessionManager, getSessionsDir, } from "../session.js";
1050
+ export { PermissionAwareApprovalController } from "../approval/controller.js";
1051
+ export { BashAllowlist } from "../approval/session-cache.js";
1052
+ export { createAllTools, buildToolPromptOptions } from "../tools/index.js";
1053
+ export { buildSystemPrompt } from "../system-prompt.js";
1054
+ export { FileStateTracker } from "../tools/file-state.js";
1055
+ export { BudgetLedger } from "../agent/budget-ledger.js";
1056
+ export { UserConfig } from "../config.js";
1057
+ export { ProviderRegistry, encodeModel, decodeModel, displayModel, } from "../provider-registry.js";
1058
+ export { createProviderInstance } from "../provider.js";
1059
+ export { getDefaultThinkingLevel } from "../variant/variant-resolver.js";
1060
+ export { QuestionController, QuestionRejectedError, } from "../question/controller.js";
1061
+ export { SkillRegistry } from "../skills/registry.js";
1062
+ export { parseSkillInvocation } from "../skills/invocation.js";
1063
+ export { GoalStore } from "../goal/store.js";
1064
+ export { McpManager } from "../mcp/manager.js";
1065
+ export { loadMcpConfig } from "../mcp/config.js";
1066
+ export { ExternalHookController } from "../hooks/controller.js";
1067
+ export { calculateUsageCost, getModelPricing, } from "../model-pricing.js";
1068
+ export { registry as slashCommandRegistry } from "../slash-commands/index.js";