@vellumai/assistant 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1068) hide show
  1. package/.dockerignore +27 -0
  2. package/.env.example +22 -0
  3. package/Dockerfile +99 -0
  4. package/Dockerfile.sandbox +5 -0
  5. package/README.md +248 -0
  6. package/bun.lock +1723 -0
  7. package/bunfig.toml +2 -0
  8. package/docs/skills.md +158 -0
  9. package/drizzle/0000_dizzy_maggott.sql +301 -0
  10. package/drizzle/meta/0000_snapshot.json +1999 -0
  11. package/drizzle/meta/_journal.json +13 -0
  12. package/drizzle.config.ts +7 -0
  13. package/eslint.config.mjs +17 -0
  14. package/hook-templates/debug-prompt-logger/hook.json +7 -0
  15. package/hook-templates/debug-prompt-logger/run.sh +68 -0
  16. package/knip.json +9 -0
  17. package/package.json +70 -0
  18. package/scripts/capture-x-graphql.ts +545 -0
  19. package/scripts/ipc/check-contract-inventory.ts +104 -0
  20. package/scripts/ipc/check-swift-decoder-drift.ts +166 -0
  21. package/scripts/ipc/generate-swift.ts +492 -0
  22. package/scripts/test-filesystem-tools.sh +48 -0
  23. package/scripts/test.sh +127 -0
  24. package/src/__tests__/__snapshots__/ipc-snapshot.test.ts.snap +2485 -0
  25. package/src/__tests__/account-registry.test.ts +245 -0
  26. package/src/__tests__/active-skill-tools.test.ts +378 -0
  27. package/src/__tests__/agent-heartbeat-service.test.ts +250 -0
  28. package/src/__tests__/agent-loop-thinking.test.ts +81 -0
  29. package/src/__tests__/agent-loop.test.ts +1135 -0
  30. package/src/__tests__/anthropic-provider.test.ts +778 -0
  31. package/src/__tests__/app-builder-tool-scripts.test.ts +290 -0
  32. package/src/__tests__/app-bundler.test.ts +292 -0
  33. package/src/__tests__/app-executors.test.ts +613 -0
  34. package/src/__tests__/app-git-history.test.ts +176 -0
  35. package/src/__tests__/app-git-service.test.ts +169 -0
  36. package/src/__tests__/app-open-proxy.test.ts +62 -0
  37. package/src/__tests__/asset-materialize-tool.test.ts +452 -0
  38. package/src/__tests__/asset-search-tool.test.ts +477 -0
  39. package/src/__tests__/assistant-attachment-directive.test.ts +401 -0
  40. package/src/__tests__/assistant-attachments.test.ts +437 -0
  41. package/src/__tests__/assistant-event-hub.test.ts +226 -0
  42. package/src/__tests__/assistant-event.test.ts +123 -0
  43. package/src/__tests__/assistant-events-sse-hardening.test.ts +315 -0
  44. package/src/__tests__/attachments-store.test.ts +476 -0
  45. package/src/__tests__/attachments.test.ts +134 -0
  46. package/src/__tests__/audit-log-rotation.test.ts +154 -0
  47. package/src/__tests__/browser-fill-credential.test.ts +309 -0
  48. package/src/__tests__/browser-manager.test.ts +203 -0
  49. package/src/__tests__/browser-runtime-check.test.ts +55 -0
  50. package/src/__tests__/browser-skill-baseline-tool-payload.test.ts +68 -0
  51. package/src/__tests__/browser-skill-endstate.test.ts +195 -0
  52. package/src/__tests__/bundle-scanner.test.ts +313 -0
  53. package/src/__tests__/call-bridge.test.ts +517 -0
  54. package/src/__tests__/call-constants.test.ts +40 -0
  55. package/src/__tests__/call-domain.test.ts +163 -0
  56. package/src/__tests__/call-orchestrator.test.ts +625 -0
  57. package/src/__tests__/call-recovery.test.ts +518 -0
  58. package/src/__tests__/call-routes-http.test.ts +699 -0
  59. package/src/__tests__/call-state-machine.test.ts +143 -0
  60. package/src/__tests__/call-state.test.ts +174 -0
  61. package/src/__tests__/call-store.test.ts +691 -0
  62. package/src/__tests__/channel-approval-routes.test.ts +2356 -0
  63. package/src/__tests__/channel-approval.test.ts +299 -0
  64. package/src/__tests__/channel-approvals.test.ts +521 -0
  65. package/src/__tests__/channel-delivery-store.test.ts +447 -0
  66. package/src/__tests__/channel-guardian.test.ts +1005 -0
  67. package/src/__tests__/checker.test.ts +3519 -0
  68. package/src/__tests__/clarification-resolver.test.ts +159 -0
  69. package/src/__tests__/classifier.test.ts +67 -0
  70. package/src/__tests__/claude-code-skill-regression.test.ts +127 -0
  71. package/src/__tests__/claude-code-tool-profiles.test.ts +88 -0
  72. package/src/__tests__/cli-discover.test.ts +85 -0
  73. package/src/__tests__/cli.test.ts +26 -0
  74. package/src/__tests__/clipboard.test.ts +80 -0
  75. package/src/__tests__/commit-guarantee.test.ts +335 -0
  76. package/src/__tests__/commit-message-enrichment-service.test.ts +550 -0
  77. package/src/__tests__/compaction.benchmark.test.ts +176 -0
  78. package/src/__tests__/computer-use-session-compaction.test.ts +132 -0
  79. package/src/__tests__/computer-use-session-lifecycle.test.ts +293 -0
  80. package/src/__tests__/computer-use-session-working-dir.test.ts +117 -0
  81. package/src/__tests__/computer-use-skill-baseline.test.ts +74 -0
  82. package/src/__tests__/computer-use-skill-endstate.test.ts +89 -0
  83. package/src/__tests__/computer-use-skill-lifecycle-cleanup.test.ts +217 -0
  84. package/src/__tests__/computer-use-skill-manifest-regression.test.ts +107 -0
  85. package/src/__tests__/computer-use-skill-proxy-bridge.test.ts +54 -0
  86. package/src/__tests__/computer-use-tools.test.ts +250 -0
  87. package/src/__tests__/config-schema.test.ts +1462 -0
  88. package/src/__tests__/conflict-intent-tokenization.test.ts +141 -0
  89. package/src/__tests__/conflict-policy.test.ts +121 -0
  90. package/src/__tests__/conflict-store.test.ts +332 -0
  91. package/src/__tests__/connection-policy.test.ts +102 -0
  92. package/src/__tests__/contacts-tools.test.ts +331 -0
  93. package/src/__tests__/context-memory-e2e.test.ts +434 -0
  94. package/src/__tests__/context-token-estimator.test.ts +135 -0
  95. package/src/__tests__/context-window-manager.test.ts +376 -0
  96. package/src/__tests__/contradiction-checker.test.ts +314 -0
  97. package/src/__tests__/conversation-store.test.ts +612 -0
  98. package/src/__tests__/credential-broker-browser-fill.test.ts +517 -0
  99. package/src/__tests__/credential-broker-server-use.test.ts +554 -0
  100. package/src/__tests__/credential-broker.test.ts +167 -0
  101. package/src/__tests__/credential-host-pattern-match.test.ts +104 -0
  102. package/src/__tests__/credential-metadata-store.test.ts +779 -0
  103. package/src/__tests__/credential-policy-validate.test.ts +121 -0
  104. package/src/__tests__/credential-resolve.test.ts +328 -0
  105. package/src/__tests__/credential-security-e2e.test.ts +352 -0
  106. package/src/__tests__/credential-security-invariants.test.ts +583 -0
  107. package/src/__tests__/credential-selection.test.ts +354 -0
  108. package/src/__tests__/credential-vault-unit.test.ts +780 -0
  109. package/src/__tests__/credential-vault.test.ts +852 -0
  110. package/src/__tests__/daemon-assistant-events.test.ts +164 -0
  111. package/src/__tests__/daemon-server-session-init.test.ts +522 -0
  112. package/src/__tests__/date-context.test.ts +373 -0
  113. package/src/__tests__/db-schedule-syntax-migration.test.ts +129 -0
  114. package/src/__tests__/delete-managed-skill-tool.test.ts +97 -0
  115. package/src/__tests__/diff.test.ts +121 -0
  116. package/src/__tests__/domain-normalize.test.ts +112 -0
  117. package/src/__tests__/domain-policy.test.ts +124 -0
  118. package/src/__tests__/doordash-client.test.ts +186 -0
  119. package/src/__tests__/doordash-session.test.ts +152 -0
  120. package/src/__tests__/dynamic-page-surface.test.ts +91 -0
  121. package/src/__tests__/dynamic-skill-workflow-prompt.test.ts +132 -0
  122. package/src/__tests__/edit-engine.test.ts +180 -0
  123. package/src/__tests__/elevenlabs-client.test.ts +271 -0
  124. package/src/__tests__/email-cli.test.ts +283 -0
  125. package/src/__tests__/encrypted-store.test.ts +332 -0
  126. package/src/__tests__/entity-extractor.test.ts +190 -0
  127. package/src/__tests__/ephemeral-permissions.test.ts +362 -0
  128. package/src/__tests__/evaluate-typescript-tool.test.ts +286 -0
  129. package/src/__tests__/event-bus.test.ts +222 -0
  130. package/src/__tests__/file-edit-tool.test.ts +122 -0
  131. package/src/__tests__/file-ops-service.test.ts +330 -0
  132. package/src/__tests__/file-read-tool.test.ts +75 -0
  133. package/src/__tests__/file-write-tool.test.ts +113 -0
  134. package/src/__tests__/filesystem-tools.test.ts +579 -0
  135. package/src/__tests__/fixtures/credential-security-fixtures.ts +181 -0
  136. package/src/__tests__/fixtures/media-reuse-fixtures.ts +126 -0
  137. package/src/__tests__/fixtures/mock-signup-server.ts +387 -0
  138. package/src/__tests__/fixtures/proxy-fixtures.ts +147 -0
  139. package/src/__tests__/followup-tools.test.ts +303 -0
  140. package/src/__tests__/forbidden-legacy-symbols.test.ts +71 -0
  141. package/src/__tests__/fuzzy-match-property.test.ts +216 -0
  142. package/src/__tests__/fuzzy-match.test.ts +138 -0
  143. package/src/__tests__/gateway-only-enforcement.test.ts +631 -0
  144. package/src/__tests__/gemini-image-service.test.ts +261 -0
  145. package/src/__tests__/gemini-provider.test.ts +651 -0
  146. package/src/__tests__/get-weather.test.ts +318 -0
  147. package/src/__tests__/gmail-integration.test.ts +73 -0
  148. package/src/__tests__/handlers-add-trust-rule-metadata.test.ts +202 -0
  149. package/src/__tests__/handlers-cu-observation-blob.test.ts +352 -0
  150. package/src/__tests__/handlers-ipc-blob-probe.test.ts +191 -0
  151. package/src/__tests__/handlers-slack-config.test.ts +200 -0
  152. package/src/__tests__/handlers-task-submit-slash.test.ts +38 -0
  153. package/src/__tests__/handlers-telegram-config.test.ts +968 -0
  154. package/src/__tests__/handlers-twilio-config.test.ts +659 -0
  155. package/src/__tests__/handlers-twitter-config.test.ts +858 -0
  156. package/src/__tests__/headless-browser-interactions.test.ts +536 -0
  157. package/src/__tests__/headless-browser-navigate.test.ts +211 -0
  158. package/src/__tests__/headless-browser-read-tools.test.ts +261 -0
  159. package/src/__tests__/headless-browser-snapshot.test.ts +185 -0
  160. package/src/__tests__/history-repair-observability.test.ts +56 -0
  161. package/src/__tests__/history-repair.test.ts +510 -0
  162. package/src/__tests__/home-base-bootstrap.test.ts +82 -0
  163. package/src/__tests__/hooks-blocking.test.ts +128 -0
  164. package/src/__tests__/hooks-cli.test.ts +144 -0
  165. package/src/__tests__/hooks-config.test.ts +93 -0
  166. package/src/__tests__/hooks-discovery.test.ts +199 -0
  167. package/src/__tests__/hooks-integration.test.ts +189 -0
  168. package/src/__tests__/hooks-manager.test.ts +187 -0
  169. package/src/__tests__/hooks-runner.test.ts +182 -0
  170. package/src/__tests__/hooks-settings.test.ts +154 -0
  171. package/src/__tests__/hooks-templates.test.ts +137 -0
  172. package/src/__tests__/hooks-ts-runner.test.ts +125 -0
  173. package/src/__tests__/hooks-watch.test.ts +100 -0
  174. package/src/__tests__/host-file-edit-tool.test.ts +228 -0
  175. package/src/__tests__/host-file-read-tool.test.ts +123 -0
  176. package/src/__tests__/host-file-write-tool.test.ts +136 -0
  177. package/src/__tests__/host-shell-tool.test.ts +562 -0
  178. package/src/__tests__/ingress-reconcile.test.ts +581 -0
  179. package/src/__tests__/ingress-url-consistency.test.ts +214 -0
  180. package/src/__tests__/intent-routing.test.ts +259 -0
  181. package/src/__tests__/ipc-blob-store.test.ts +315 -0
  182. package/src/__tests__/ipc-contract-inventory.test.ts +54 -0
  183. package/src/__tests__/ipc-contract.test.ts +74 -0
  184. package/src/__tests__/ipc-protocol.test.ts +113 -0
  185. package/src/__tests__/ipc-roundtrip.benchmark.test.ts +237 -0
  186. package/src/__tests__/ipc-snapshot.test.ts +1769 -0
  187. package/src/__tests__/ipc-validate.test.ts +407 -0
  188. package/src/__tests__/key-migration.test.ts +206 -0
  189. package/src/__tests__/keychain.test.ts +258 -0
  190. package/src/__tests__/llm-usage-store.test.ts +221 -0
  191. package/src/__tests__/managed-skill-lifecycle.test.ts +257 -0
  192. package/src/__tests__/managed-store.test.ts +608 -0
  193. package/src/__tests__/media-generate-image.test.ts +238 -0
  194. package/src/__tests__/media-reuse-story.e2e.test.ts +676 -0
  195. package/src/__tests__/media-visibility-policy.test.ts +141 -0
  196. package/src/__tests__/memory-context-benchmark.benchmark.test.ts +235 -0
  197. package/src/__tests__/memory-lifecycle-e2e.test.ts +481 -0
  198. package/src/__tests__/memory-query-builder.test.ts +59 -0
  199. package/src/__tests__/memory-recall-quality.test.ts +846 -0
  200. package/src/__tests__/memory-regressions.experimental.test.ts +538 -0
  201. package/src/__tests__/memory-regressions.test.ts +4435 -0
  202. package/src/__tests__/memory-retrieval-budget.test.ts +49 -0
  203. package/src/__tests__/memory-retrieval.benchmark.test.ts +430 -0
  204. package/src/__tests__/migration-cli-flows.test.ts +169 -0
  205. package/src/__tests__/migration-ordering.test.ts +249 -0
  206. package/src/__tests__/mock-signup-server.test.ts +528 -0
  207. package/src/__tests__/oauth-callback-registry.test.ts +92 -0
  208. package/src/__tests__/oauth2-gateway-transport.test.ts +285 -0
  209. package/src/__tests__/onboarding-starter-tasks.test.ts +176 -0
  210. package/src/__tests__/onboarding-template-contract.test.ts +58 -0
  211. package/src/__tests__/openai-provider.test.ts +753 -0
  212. package/src/__tests__/parallel-tool.benchmark.test.ts +294 -0
  213. package/src/__tests__/parser.test.ts +472 -0
  214. package/src/__tests__/path-classifier.test.ts +73 -0
  215. package/src/__tests__/path-policy.test.ts +435 -0
  216. package/src/__tests__/platform-move-helper.test.ts +99 -0
  217. package/src/__tests__/platform-socket-path.test.ts +52 -0
  218. package/src/__tests__/platform-workspace-migration.test.ts +1000 -0
  219. package/src/__tests__/platform.test.ts +131 -0
  220. package/src/__tests__/playbook-execution.test.ts +502 -0
  221. package/src/__tests__/playbook-tools.test.ts +340 -0
  222. package/src/__tests__/prebuilt-home-base-seed.test.ts +75 -0
  223. package/src/__tests__/pricing.test.ts +256 -0
  224. package/src/__tests__/profile-compiler.test.ts +374 -0
  225. package/src/__tests__/provider-commit-message-generator.test.ts +342 -0
  226. package/src/__tests__/provider-registry-ollama.test.ts +16 -0
  227. package/src/__tests__/provider-streaming.benchmark.test.ts +773 -0
  228. package/src/__tests__/proxy-approval-callback.test.ts +601 -0
  229. package/src/__tests__/public-ingress-urls.test.ts +256 -0
  230. package/src/__tests__/qdrant-manager.test.ts +267 -0
  231. package/src/__tests__/ratelimit.test.ts +297 -0
  232. package/src/__tests__/recurrence-engine-rruleset.test.ts +175 -0
  233. package/src/__tests__/recurrence-engine.test.ts +78 -0
  234. package/src/__tests__/recurrence-types.test.ts +79 -0
  235. package/src/__tests__/registry.test.ts +494 -0
  236. package/src/__tests__/relay-server.test.ts +688 -0
  237. package/src/__tests__/reminder-store.test.ts +223 -0
  238. package/src/__tests__/reminder.test.ts +229 -0
  239. package/src/__tests__/request-file-tool.test.ts +158 -0
  240. package/src/__tests__/run-orchestrator-assistant-events.test.ts +227 -0
  241. package/src/__tests__/run-orchestrator.test.ts +425 -0
  242. package/src/__tests__/runtime-attachment-metadata.test.ts +189 -0
  243. package/src/__tests__/runtime-events-sse-parity.test.ts +343 -0
  244. package/src/__tests__/runtime-events-sse.test.ts +162 -0
  245. package/src/__tests__/runtime-runs-http.test.ts +438 -0
  246. package/src/__tests__/runtime-runs.test.ts +260 -0
  247. package/src/__tests__/sandbox-diagnostics.test.ts +408 -0
  248. package/src/__tests__/sandbox-host-parity.test.ts +950 -0
  249. package/src/__tests__/scaffold-managed-skill-tool.test.ts +253 -0
  250. package/src/__tests__/schedule-store.test.ts +484 -0
  251. package/src/__tests__/schedule-tools.test.ts +783 -0
  252. package/src/__tests__/scheduler-recurrence.test.ts +430 -0
  253. package/src/__tests__/script-proxy-certs.test.ts +90 -0
  254. package/src/__tests__/script-proxy-connect-tunnel.test.ts +177 -0
  255. package/src/__tests__/script-proxy-decision-trace.test.ts +156 -0
  256. package/src/__tests__/script-proxy-http-forwarder.test.ts +281 -0
  257. package/src/__tests__/script-proxy-injection-runtime.test.ts +401 -0
  258. package/src/__tests__/script-proxy-mitm-handler.test.ts +407 -0
  259. package/src/__tests__/script-proxy-policy-runtime.test.ts +287 -0
  260. package/src/__tests__/script-proxy-policy.test.ts +310 -0
  261. package/src/__tests__/script-proxy-rewrite-specificity.test.ts +135 -0
  262. package/src/__tests__/script-proxy-router.test.ts +180 -0
  263. package/src/__tests__/script-proxy-session-manager.test.ts +382 -0
  264. package/src/__tests__/script-proxy-session-runtime.test.ts +113 -0
  265. package/src/__tests__/secret-allowlist.test.ts +230 -0
  266. package/src/__tests__/secret-ingress-handler.test.ts +110 -0
  267. package/src/__tests__/secret-onetime-send.test.ts +130 -0
  268. package/src/__tests__/secret-prompt-log-hygiene.test.ts +106 -0
  269. package/src/__tests__/secret-response-routing.test.ts +93 -0
  270. package/src/__tests__/secret-scanner-executor.test.ts +348 -0
  271. package/src/__tests__/secret-scanner.test.ts +900 -0
  272. package/src/__tests__/secure-keys.test.ts +323 -0
  273. package/src/__tests__/server-history-render.test.ts +431 -0
  274. package/src/__tests__/session-abort-tool-results.test.ts +240 -0
  275. package/src/__tests__/session-conflict-gate.test.ts +1136 -0
  276. package/src/__tests__/session-error.test.ts +369 -0
  277. package/src/__tests__/session-evictor.test.ts +188 -0
  278. package/src/__tests__/session-init.benchmark.test.ts +465 -0
  279. package/src/__tests__/session-load-history-repair.test.ts +222 -0
  280. package/src/__tests__/session-pre-run-repair.test.ts +213 -0
  281. package/src/__tests__/session-process-bridge.test.ts +242 -0
  282. package/src/__tests__/session-profile-injection.test.ts +444 -0
  283. package/src/__tests__/session-provider-retry-repair.test.ts +306 -0
  284. package/src/__tests__/session-queue.test.ts +1535 -0
  285. package/src/__tests__/session-runtime-assembly.test.ts +476 -0
  286. package/src/__tests__/session-runtime-workspace.test.ts +183 -0
  287. package/src/__tests__/session-skill-tools.test.ts +2431 -0
  288. package/src/__tests__/session-slash-known.test.ts +368 -0
  289. package/src/__tests__/session-slash-queue.test.ts +288 -0
  290. package/src/__tests__/session-slash-unknown.test.ts +271 -0
  291. package/src/__tests__/session-surfaces-task-progress.test.ts +104 -0
  292. package/src/__tests__/session-tool-setup-app-refresh.test.ts +473 -0
  293. package/src/__tests__/session-tool-setup-memory-scope.test.ts +140 -0
  294. package/src/__tests__/session-tool-setup-side-effect-flag.test.ts +140 -0
  295. package/src/__tests__/session-undo.test.ts +75 -0
  296. package/src/__tests__/session-workspace-cache-state.test.ts +246 -0
  297. package/src/__tests__/session-workspace-injection.test.ts +327 -0
  298. package/src/__tests__/session-workspace-tool-tracking.test.ts +240 -0
  299. package/src/__tests__/shared-filesystem-errors.test.ts +78 -0
  300. package/src/__tests__/shell-credential-ref.test.ts +187 -0
  301. package/src/__tests__/shell-identity.test.ts +256 -0
  302. package/src/__tests__/shell-parser-fuzz.test.ts +544 -0
  303. package/src/__tests__/shell-parser-property.test.ts +433 -0
  304. package/src/__tests__/shell-tool-proxy-mode.test.ts +272 -0
  305. package/src/__tests__/signup-e2e.test.ts +353 -0
  306. package/src/__tests__/size-guard.test.ts +117 -0
  307. package/src/__tests__/skill-include-graph.test.ts +303 -0
  308. package/src/__tests__/skill-load-tool.test.ts +409 -0
  309. package/src/__tests__/skill-projection.benchmark.test.ts +338 -0
  310. package/src/__tests__/skill-script-runner-host.test.ts +489 -0
  311. package/src/__tests__/skill-script-runner-sandbox.test.ts +349 -0
  312. package/src/__tests__/skill-script-runner.test.ts +159 -0
  313. package/src/__tests__/skill-tool-factory.test.ts +252 -0
  314. package/src/__tests__/skill-tool-manifest.test.ts +658 -0
  315. package/src/__tests__/skill-version-hash.test.ts +182 -0
  316. package/src/__tests__/skills.test.ts +680 -0
  317. package/src/__tests__/slash-commands-catalog.test.ts +86 -0
  318. package/src/__tests__/slash-commands-parser.test.ts +119 -0
  319. package/src/__tests__/slash-commands-resolver.test.ts +193 -0
  320. package/src/__tests__/slash-commands-rewrite.test.ts +39 -0
  321. package/src/__tests__/speaker-identification.test.ts +52 -0
  322. package/src/__tests__/starter-bundle.test.ts +136 -0
  323. package/src/__tests__/starter-task-flow.test.ts +143 -0
  324. package/src/__tests__/subagent-manager-notify.test.ts +404 -0
  325. package/src/__tests__/subagent-tools.test.ts +801 -0
  326. package/src/__tests__/subagent-types.test.ts +78 -0
  327. package/src/__tests__/swarm-orchestrator.test.ts +428 -0
  328. package/src/__tests__/swarm-plan-validator.test.ts +330 -0
  329. package/src/__tests__/swarm-recursion.test.ts +165 -0
  330. package/src/__tests__/swarm-router-planner.test.ts +208 -0
  331. package/src/__tests__/swarm-session-integration.test.ts +274 -0
  332. package/src/__tests__/swarm-tool.test.ts +145 -0
  333. package/src/__tests__/swarm-worker-backend.test.ts +129 -0
  334. package/src/__tests__/swarm-worker-runner.test.ts +272 -0
  335. package/src/__tests__/system-prompt.test.ts +439 -0
  336. package/src/__tests__/task-compiler.test.ts +284 -0
  337. package/src/__tests__/task-management-tools.test.ts +936 -0
  338. package/src/__tests__/task-runner.test.ts +216 -0
  339. package/src/__tests__/task-scheduler.test.ts +217 -0
  340. package/src/__tests__/task-tools.test.ts +595 -0
  341. package/src/__tests__/terminal-sandbox-docker.test.ts +1064 -0
  342. package/src/__tests__/terminal-sandbox.integration.test.ts +178 -0
  343. package/src/__tests__/terminal-sandbox.test.ts +202 -0
  344. package/src/__tests__/terminal-tools.test.ts +840 -0
  345. package/src/__tests__/test-support/browser-skill-harness.ts +90 -0
  346. package/src/__tests__/test-support/computer-use-skill-harness.ts +45 -0
  347. package/src/__tests__/tool-audit-listener.test.ts +113 -0
  348. package/src/__tests__/tool-domain-event-publisher.test.ts +253 -0
  349. package/src/__tests__/tool-execution-pipeline.benchmark.test.ts +500 -0
  350. package/src/__tests__/tool-executor-lifecycle-events.test.ts +516 -0
  351. package/src/__tests__/tool-executor-redaction.test.ts +289 -0
  352. package/src/__tests__/tool-executor-shell-integration.test.ts +301 -0
  353. package/src/__tests__/tool-executor.test.ts +1989 -0
  354. package/src/__tests__/tool-metrics-listener.test.ts +225 -0
  355. package/src/__tests__/tool-notification-listener.test.ts +49 -0
  356. package/src/__tests__/tool-permission-simulate-handler.test.ts +336 -0
  357. package/src/__tests__/tool-policy.test.ts +54 -0
  358. package/src/__tests__/tool-profiling-listener.test.ts +268 -0
  359. package/src/__tests__/tool-result-truncation.test.ts +217 -0
  360. package/src/__tests__/tool-trace-listener.test.ts +226 -0
  361. package/src/__tests__/top-level-renderer.test.ts +121 -0
  362. package/src/__tests__/top-level-scanner.test.ts +141 -0
  363. package/src/__tests__/trace-emitter.test.ts +173 -0
  364. package/src/__tests__/trust-store.test.ts +1605 -0
  365. package/src/__tests__/turn-commit.test.ts +554 -0
  366. package/src/__tests__/twilio-provider.test.ts +329 -0
  367. package/src/__tests__/twilio-routes-elevenlabs.test.ts +375 -0
  368. package/src/__tests__/twilio-routes-twiml.test.ts +127 -0
  369. package/src/__tests__/twilio-routes.test.ts +577 -0
  370. package/src/__tests__/twitter-auth-handler.test.ts +667 -0
  371. package/src/__tests__/twitter-cli-error-shaping.test.ts +208 -0
  372. package/src/__tests__/twitter-cli-routing.test.ts +252 -0
  373. package/src/__tests__/twitter-oauth-client.test.ts +209 -0
  374. package/src/__tests__/url-safety.test.ts +418 -0
  375. package/src/__tests__/view-image-tool.test.ts +217 -0
  376. package/src/__tests__/weather-skill-regression.test.ts +225 -0
  377. package/src/__tests__/web-fetch.test.ts +869 -0
  378. package/src/__tests__/web-search.test.ts +584 -0
  379. package/src/__tests__/workspace-git-service.test.ts +1153 -0
  380. package/src/__tests__/workspace-heartbeat-service.test.ts +486 -0
  381. package/src/__tests__/workspace-lifecycle.test.ts +292 -0
  382. package/src/__tests__/workspace-policy.test.ts +213 -0
  383. package/src/agent/attachments.ts +35 -0
  384. package/src/agent/loop.ts +500 -0
  385. package/src/agent/message-types.ts +17 -0
  386. package/src/agent-heartbeat/agent-heartbeat-service.ts +155 -0
  387. package/src/autonomy/autonomy-resolver.ts +60 -0
  388. package/src/autonomy/autonomy-store.ts +122 -0
  389. package/src/autonomy/disposition-mapper.ts +31 -0
  390. package/src/autonomy/index.ts +11 -0
  391. package/src/autonomy/types.ts +39 -0
  392. package/src/bundler/app-bundler.ts +295 -0
  393. package/src/bundler/bundle-scanner.ts +535 -0
  394. package/src/bundler/bundle-signer.ts +124 -0
  395. package/src/bundler/manifest.ts +21 -0
  396. package/src/bundler/signature-verifier.ts +184 -0
  397. package/src/calls/call-bridge.ts +168 -0
  398. package/src/calls/call-constants.ts +48 -0
  399. package/src/calls/call-domain.ts +430 -0
  400. package/src/calls/call-orchestrator.ts +498 -0
  401. package/src/calls/call-recovery.ts +207 -0
  402. package/src/calls/call-state-machine.ts +68 -0
  403. package/src/calls/call-state.ts +87 -0
  404. package/src/calls/call-store.ts +422 -0
  405. package/src/calls/elevenlabs-client.ts +97 -0
  406. package/src/calls/elevenlabs-config.ts +31 -0
  407. package/src/calls/relay-server.ts +390 -0
  408. package/src/calls/speaker-identification.ts +213 -0
  409. package/src/calls/twilio-config.ts +45 -0
  410. package/src/calls/twilio-provider.ts +263 -0
  411. package/src/calls/twilio-rest.ts +156 -0
  412. package/src/calls/twilio-routes.ts +311 -0
  413. package/src/calls/types.ts +39 -0
  414. package/src/calls/voice-provider.ts +14 -0
  415. package/src/calls/voice-quality.ts +114 -0
  416. package/src/cli/autonomy.ts +188 -0
  417. package/src/cli/config-commands.ts +334 -0
  418. package/src/cli/contacts.ts +149 -0
  419. package/src/cli/core-commands.ts +784 -0
  420. package/src/cli/doordash.ts +1055 -0
  421. package/src/cli/email-guardrails.ts +200 -0
  422. package/src/cli/email.ts +405 -0
  423. package/src/cli/ipc-client.ts +82 -0
  424. package/src/cli/main-screen.tsx +53 -0
  425. package/src/cli/map.ts +270 -0
  426. package/src/cli/twitter.ts +754 -0
  427. package/src/cli.ts +918 -0
  428. package/src/commands/__tests__/cc-command-registry.test.ts +319 -0
  429. package/src/commands/cc-command-registry.ts +209 -0
  430. package/src/config/bundled-skills/.gitkeep +0 -0
  431. package/src/config/bundled-skills/agentmail/SKILL.md +128 -0
  432. package/src/config/bundled-skills/agentmail/icon.svg +21 -0
  433. package/src/config/bundled-skills/app-builder/SKILL.md +1404 -0
  434. package/src/config/bundled-skills/app-builder/TOOLS.json +279 -0
  435. package/src/config/bundled-skills/app-builder/icon.svg +9 -0
  436. package/src/config/bundled-skills/app-builder/tools/app-create.ts +15 -0
  437. package/src/config/bundled-skills/app-builder/tools/app-delete.ts +10 -0
  438. package/src/config/bundled-skills/app-builder/tools/app-file-edit.ts +11 -0
  439. package/src/config/bundled-skills/app-builder/tools/app-file-list.ts +10 -0
  440. package/src/config/bundled-skills/app-builder/tools/app-file-read.ts +18 -0
  441. package/src/config/bundled-skills/app-builder/tools/app-file-write.ts +11 -0
  442. package/src/config/bundled-skills/app-builder/tools/app-list.ts +10 -0
  443. package/src/config/bundled-skills/app-builder/tools/app-query.ts +10 -0
  444. package/src/config/bundled-skills/app-builder/tools/app-update.ts +20 -0
  445. package/src/config/bundled-skills/browser/SKILL.md +28 -0
  446. package/src/config/bundled-skills/browser/TOOLS.json +234 -0
  447. package/src/config/bundled-skills/browser/tools/browser-click.ts +9 -0
  448. package/src/config/bundled-skills/browser/tools/browser-close.ts +9 -0
  449. package/src/config/bundled-skills/browser/tools/browser-extract.ts +9 -0
  450. package/src/config/bundled-skills/browser/tools/browser-fill-credential.ts +9 -0
  451. package/src/config/bundled-skills/browser/tools/browser-navigate.ts +9 -0
  452. package/src/config/bundled-skills/browser/tools/browser-press-key.ts +9 -0
  453. package/src/config/bundled-skills/browser/tools/browser-screenshot.ts +9 -0
  454. package/src/config/bundled-skills/browser/tools/browser-snapshot.ts +9 -0
  455. package/src/config/bundled-skills/browser/tools/browser-type.ts +9 -0
  456. package/src/config/bundled-skills/browser/tools/browser-wait-for.ts +9 -0
  457. package/src/config/bundled-skills/claude-code/SKILL.md +50 -0
  458. package/src/config/bundled-skills/claude-code/TOOLS.json +40 -0
  459. package/src/config/bundled-skills/claude-code/tools/claude-code.ts +9 -0
  460. package/src/config/bundled-skills/computer-use/SKILL.md +17 -0
  461. package/src/config/bundled-skills/computer-use/TOOLS.json +326 -0
  462. package/src/config/bundled-skills/computer-use/tools/computer-use-click.ts +9 -0
  463. package/src/config/bundled-skills/computer-use/tools/computer-use-done.ts +9 -0
  464. package/src/config/bundled-skills/computer-use/tools/computer-use-double-click.ts +9 -0
  465. package/src/config/bundled-skills/computer-use/tools/computer-use-drag.ts +9 -0
  466. package/src/config/bundled-skills/computer-use/tools/computer-use-key.ts +9 -0
  467. package/src/config/bundled-skills/computer-use/tools/computer-use-open-app.ts +9 -0
  468. package/src/config/bundled-skills/computer-use/tools/computer-use-request-control.ts +9 -0
  469. package/src/config/bundled-skills/computer-use/tools/computer-use-respond.ts +9 -0
  470. package/src/config/bundled-skills/computer-use/tools/computer-use-right-click.ts +9 -0
  471. package/src/config/bundled-skills/computer-use/tools/computer-use-run-applescript.ts +9 -0
  472. package/src/config/bundled-skills/computer-use/tools/computer-use-scroll.ts +9 -0
  473. package/src/config/bundled-skills/computer-use/tools/computer-use-type-text.ts +9 -0
  474. package/src/config/bundled-skills/computer-use/tools/computer-use-wait.ts +9 -0
  475. package/src/config/bundled-skills/contacts/SKILL.md +39 -0
  476. package/src/config/bundled-skills/contacts/TOOLS.json +122 -0
  477. package/src/config/bundled-skills/contacts/tools/contact-merge.ts +57 -0
  478. package/src/config/bundled-skills/contacts/tools/contact-search.ts +60 -0
  479. package/src/config/bundled-skills/contacts/tools/contact-upsert.ts +66 -0
  480. package/src/config/bundled-skills/document/SKILL.md +26 -0
  481. package/src/config/bundled-skills/document/TOOLS.json +53 -0
  482. package/src/config/bundled-skills/document/tools/document-create.ts +9 -0
  483. package/src/config/bundled-skills/document/tools/document-update.ts +9 -0
  484. package/src/config/bundled-skills/doordash/SKILL.md +163 -0
  485. package/src/config/bundled-skills/followups/SKILL.md +32 -0
  486. package/src/config/bundled-skills/followups/TOOLS.json +100 -0
  487. package/src/config/bundled-skills/followups/icon.svg +24 -0
  488. package/src/config/bundled-skills/followups/tools/followup-create.ts +9 -0
  489. package/src/config/bundled-skills/followups/tools/followup-list.ts +9 -0
  490. package/src/config/bundled-skills/followups/tools/followup-resolve.ts +9 -0
  491. package/src/config/bundled-skills/google-calendar/SKILL.md +51 -0
  492. package/src/config/bundled-skills/google-calendar/TOOLS.json +108 -0
  493. package/src/config/bundled-skills/google-calendar/calendar-client.ts +165 -0
  494. package/src/config/bundled-skills/google-calendar/tools/calendar-check-availability.ts +21 -0
  495. package/src/config/bundled-skills/google-calendar/tools/calendar-create-event.ts +42 -0
  496. package/src/config/bundled-skills/google-calendar/tools/calendar-get-event.ts +13 -0
  497. package/src/config/bundled-skills/google-calendar/tools/calendar-list-events.ts +30 -0
  498. package/src/config/bundled-skills/google-calendar/tools/calendar-rsvp.ts +41 -0
  499. package/src/config/bundled-skills/google-calendar/tools/shared.ts +18 -0
  500. package/src/config/bundled-skills/google-calendar/types.ts +97 -0
  501. package/src/config/bundled-skills/image-studio/SKILL.md +32 -0
  502. package/src/config/bundled-skills/image-studio/TOOLS.json +42 -0
  503. package/src/config/bundled-skills/image-studio/tools/media-generate-image.ts +115 -0
  504. package/src/config/bundled-skills/macos-automation/SKILL.md +66 -0
  505. package/src/config/bundled-skills/messaging/SKILL.md +153 -0
  506. package/src/config/bundled-skills/messaging/TOOLS.json +357 -0
  507. package/src/config/bundled-skills/messaging/tools/gmail-archive.ts +23 -0
  508. package/src/config/bundled-skills/messaging/tools/gmail-batch-archive.ts +23 -0
  509. package/src/config/bundled-skills/messaging/tools/gmail-batch-label.ts +25 -0
  510. package/src/config/bundled-skills/messaging/tools/gmail-draft.ts +26 -0
  511. package/src/config/bundled-skills/messaging/tools/gmail-label.ts +25 -0
  512. package/src/config/bundled-skills/messaging/tools/gmail-trash.ts +23 -0
  513. package/src/config/bundled-skills/messaging/tools/gmail-unsubscribe.ts +84 -0
  514. package/src/config/bundled-skills/messaging/tools/messaging-analyze-activity.ts +18 -0
  515. package/src/config/bundled-skills/messaging/tools/messaging-analyze-style.ts +125 -0
  516. package/src/config/bundled-skills/messaging/tools/messaging-auth-test.ts +16 -0
  517. package/src/config/bundled-skills/messaging/tools/messaging-draft.ts +49 -0
  518. package/src/config/bundled-skills/messaging/tools/messaging-list-conversations.ts +21 -0
  519. package/src/config/bundled-skills/messaging/tools/messaging-mark-read.ts +25 -0
  520. package/src/config/bundled-skills/messaging/tools/messaging-read.ts +28 -0
  521. package/src/config/bundled-skills/messaging/tools/messaging-reply.ts +32 -0
  522. package/src/config/bundled-skills/messaging/tools/messaging-search.ts +22 -0
  523. package/src/config/bundled-skills/messaging/tools/messaging-send.ts +31 -0
  524. package/src/config/bundled-skills/messaging/tools/shared.ts +76 -0
  525. package/src/config/bundled-skills/messaging/tools/slack-add-reaction.ts +25 -0
  526. package/src/config/bundled-skills/messaging/tools/slack-leave-channel.ts +23 -0
  527. package/src/config/bundled-skills/phone-calls/SKILL.md +533 -0
  528. package/src/config/bundled-skills/playbooks/SKILL.md +31 -0
  529. package/src/config/bundled-skills/playbooks/TOOLS.json +126 -0
  530. package/src/config/bundled-skills/playbooks/tools/playbook-create.ts +98 -0
  531. package/src/config/bundled-skills/playbooks/tools/playbook-delete.ts +54 -0
  532. package/src/config/bundled-skills/playbooks/tools/playbook-list.ts +76 -0
  533. package/src/config/bundled-skills/playbooks/tools/playbook-update.ts +113 -0
  534. package/src/config/bundled-skills/public-ingress/SKILL.md +200 -0
  535. package/src/config/bundled-skills/reminder/SKILL.md +20 -0
  536. package/src/config/bundled-skills/reminder/TOOLS.json +67 -0
  537. package/src/config/bundled-skills/reminder/tools/reminder-cancel.ts +9 -0
  538. package/src/config/bundled-skills/reminder/tools/reminder-create.ts +9 -0
  539. package/src/config/bundled-skills/reminder/tools/reminder-list.ts +9 -0
  540. package/src/config/bundled-skills/schedule/SKILL.md +74 -0
  541. package/src/config/bundled-skills/schedule/TOOLS.json +135 -0
  542. package/src/config/bundled-skills/schedule/tools/schedule-create.ts +9 -0
  543. package/src/config/bundled-skills/schedule/tools/schedule-delete.ts +9 -0
  544. package/src/config/bundled-skills/schedule/tools/schedule-list.ts +9 -0
  545. package/src/config/bundled-skills/schedule/tools/schedule-update.ts +9 -0
  546. package/src/config/bundled-skills/self-upgrade/SKILL.md +68 -0
  547. package/src/config/bundled-skills/start-the-day/SKILL.md +70 -0
  548. package/src/config/bundled-skills/start-the-day/icon.svg +13 -0
  549. package/src/config/bundled-skills/subagent/SKILL.md +25 -0
  550. package/src/config/bundled-skills/subagent/TOOLS.json +107 -0
  551. package/src/config/bundled-skills/subagent/tools/subagent-abort.ts +9 -0
  552. package/src/config/bundled-skills/subagent/tools/subagent-message.ts +9 -0
  553. package/src/config/bundled-skills/subagent/tools/subagent-read.ts +9 -0
  554. package/src/config/bundled-skills/subagent/tools/subagent-spawn.ts +9 -0
  555. package/src/config/bundled-skills/subagent/tools/subagent-status.ts +9 -0
  556. package/src/config/bundled-skills/tasks/SKILL.md +28 -0
  557. package/src/config/bundled-skills/tasks/TOOLS.json +281 -0
  558. package/src/config/bundled-skills/tasks/tools/task-delete.ts +9 -0
  559. package/src/config/bundled-skills/tasks/tools/task-list-add.ts +9 -0
  560. package/src/config/bundled-skills/tasks/tools/task-list-remove.ts +9 -0
  561. package/src/config/bundled-skills/tasks/tools/task-list-show.ts +9 -0
  562. package/src/config/bundled-skills/tasks/tools/task-list-update.ts +9 -0
  563. package/src/config/bundled-skills/tasks/tools/task-list.ts +9 -0
  564. package/src/config/bundled-skills/tasks/tools/task-queue-run.ts +9 -0
  565. package/src/config/bundled-skills/tasks/tools/task-run.ts +9 -0
  566. package/src/config/bundled-skills/tasks/tools/task-save.ts +9 -0
  567. package/src/config/bundled-skills/transcribe/SKILL.md +25 -0
  568. package/src/config/bundled-skills/transcribe/TOOLS.json +32 -0
  569. package/src/config/bundled-skills/transcribe/tools/transcribe-media.ts +370 -0
  570. package/src/config/bundled-skills/twitter/SKILL.md +220 -0
  571. package/src/config/bundled-skills/watcher/SKILL.md +27 -0
  572. package/src/config/bundled-skills/watcher/TOOLS.json +147 -0
  573. package/src/config/bundled-skills/watcher/tools/watcher-create.ts +9 -0
  574. package/src/config/bundled-skills/watcher/tools/watcher-delete.ts +9 -0
  575. package/src/config/bundled-skills/watcher/tools/watcher-digest.ts +9 -0
  576. package/src/config/bundled-skills/watcher/tools/watcher-list.ts +9 -0
  577. package/src/config/bundled-skills/watcher/tools/watcher-update.ts +9 -0
  578. package/src/config/bundled-skills/weather/SKILL.md +37 -0
  579. package/src/config/bundled-skills/weather/TOOLS.json +32 -0
  580. package/src/config/bundled-skills/weather/icon.svg +24 -0
  581. package/src/config/bundled-skills/weather/tools/get-weather.ts +9 -0
  582. package/src/config/computer-use-prompt.ts +97 -0
  583. package/src/config/defaults.ts +263 -0
  584. package/src/config/loader.ts +339 -0
  585. package/src/config/schema.ts +1436 -0
  586. package/src/config/skill-state.ts +95 -0
  587. package/src/config/skills.ts +972 -0
  588. package/src/config/system-prompt.ts +675 -0
  589. package/src/config/templates/BOOTSTRAP.md +70 -0
  590. package/src/config/templates/IDENTITY.md +25 -0
  591. package/src/config/templates/LOOKS.md +25 -0
  592. package/src/config/templates/SOUL.md +37 -0
  593. package/src/config/templates/USER.md +19 -0
  594. package/src/config/types.ts +42 -0
  595. package/src/config/vellum-skills/chatgpt-import/SKILL.md +24 -0
  596. package/src/config/vellum-skills/chatgpt-import/TOOLS.json +23 -0
  597. package/src/config/vellum-skills/chatgpt-import/tools/chatgpt-import.ts +284 -0
  598. package/src/config/vellum-skills/deploy-fullstack-vercel/SKILL.md +179 -0
  599. package/src/config/vellum-skills/document-writer/SKILL.md +195 -0
  600. package/src/config/vellum-skills/google-oauth-setup/SKILL.md +199 -0
  601. package/src/config/vellum-skills/slack-oauth-setup/SKILL.md +153 -0
  602. package/src/config/vellum-skills/telegram-setup/SKILL.md +143 -0
  603. package/src/config/vellum-skills/twilio-setup/SKILL.md +213 -0
  604. package/src/contacts/contact-store.ts +410 -0
  605. package/src/contacts/index.ts +11 -0
  606. package/src/contacts/types.ts +28 -0
  607. package/src/context/token-estimator.ts +108 -0
  608. package/src/context/tool-result-truncation.ts +128 -0
  609. package/src/context/window-manager.ts +531 -0
  610. package/src/daemon/assistant-attachments.ts +691 -0
  611. package/src/daemon/classifier.ts +110 -0
  612. package/src/daemon/computer-use-session.ts +903 -0
  613. package/src/daemon/connection-policy.ts +41 -0
  614. package/src/daemon/date-context.ts +136 -0
  615. package/src/daemon/handlers/apps.ts +530 -0
  616. package/src/daemon/handlers/browser.ts +54 -0
  617. package/src/daemon/handlers/computer-use.ts +187 -0
  618. package/src/daemon/handlers/config.ts +1517 -0
  619. package/src/daemon/handlers/diagnostics.ts +338 -0
  620. package/src/daemon/handlers/documents.ts +173 -0
  621. package/src/daemon/handlers/home-base.ts +78 -0
  622. package/src/daemon/handlers/identity.ts +127 -0
  623. package/src/daemon/handlers/index.ts +129 -0
  624. package/src/daemon/handlers/misc.ts +331 -0
  625. package/src/daemon/handlers/open-bundle-handler.ts +80 -0
  626. package/src/daemon/handlers/publish.ts +187 -0
  627. package/src/daemon/handlers/sessions.ts +555 -0
  628. package/src/daemon/handlers/shared.ts +570 -0
  629. package/src/daemon/handlers/signing.ts +37 -0
  630. package/src/daemon/handlers/skills.ts +486 -0
  631. package/src/daemon/handlers/subagents.ts +210 -0
  632. package/src/daemon/handlers/twitter-auth.ts +198 -0
  633. package/src/daemon/handlers/work-items.ts +632 -0
  634. package/src/daemon/handlers/workspace-files.ts +75 -0
  635. package/src/daemon/handlers.ts +17 -0
  636. package/src/daemon/history-repair.ts +214 -0
  637. package/src/daemon/ipc-blob-store.ts +231 -0
  638. package/src/daemon/ipc-contract-inventory.json +495 -0
  639. package/src/daemon/ipc-contract-inventory.ts +126 -0
  640. package/src/daemon/ipc-contract.ts +2551 -0
  641. package/src/daemon/ipc-protocol.ts +75 -0
  642. package/src/daemon/ipc-validate.ts +188 -0
  643. package/src/daemon/lifecycle.ts +582 -0
  644. package/src/daemon/main.ts +21 -0
  645. package/src/daemon/media-visibility-policy.ts +57 -0
  646. package/src/daemon/ride-shotgun-handler.ts +309 -0
  647. package/src/daemon/server.ts +1215 -0
  648. package/src/daemon/session-agent-loop.ts +922 -0
  649. package/src/daemon/session-attachments.ts +196 -0
  650. package/src/daemon/session-conflict-gate.ts +184 -0
  651. package/src/daemon/session-dynamic-profile.ts +63 -0
  652. package/src/daemon/session-error.ts +290 -0
  653. package/src/daemon/session-evictor.ts +196 -0
  654. package/src/daemon/session-history.ts +437 -0
  655. package/src/daemon/session-lifecycle.ts +147 -0
  656. package/src/daemon/session-media-retry.ts +147 -0
  657. package/src/daemon/session-memory.ts +212 -0
  658. package/src/daemon/session-messaging.ts +145 -0
  659. package/src/daemon/session-notifiers.ts +193 -0
  660. package/src/daemon/session-process.ts +323 -0
  661. package/src/daemon/session-queue-manager.ts +82 -0
  662. package/src/daemon/session-runtime-assembly.ts +447 -0
  663. package/src/daemon/session-skill-tools.ts +356 -0
  664. package/src/daemon/session-slash.ts +305 -0
  665. package/src/daemon/session-surfaces.ts +702 -0
  666. package/src/daemon/session-tool-setup.ts +523 -0
  667. package/src/daemon/session-usage.ts +72 -0
  668. package/src/daemon/session-workspace.ts +19 -0
  669. package/src/daemon/session.ts +400 -0
  670. package/src/daemon/tls-certs.ts +189 -0
  671. package/src/daemon/trace-emitter.ts +82 -0
  672. package/src/daemon/video-thumbnail.ts +62 -0
  673. package/src/daemon/watch-handler.ts +274 -0
  674. package/src/doordash/client.ts +999 -0
  675. package/src/doordash/queries.ts +1311 -0
  676. package/src/doordash/query-extractor.ts +93 -0
  677. package/src/doordash/session.ts +82 -0
  678. package/src/email/provider.ts +117 -0
  679. package/src/email/providers/agentmail.ts +317 -0
  680. package/src/email/providers/index.ts +58 -0
  681. package/src/email/service.ts +303 -0
  682. package/src/email/types.ts +126 -0
  683. package/src/events/bus.ts +157 -0
  684. package/src/events/domain-events.ts +83 -0
  685. package/src/events/index.ts +18 -0
  686. package/src/events/tool-audit-listener.ts +80 -0
  687. package/src/events/tool-domain-event-publisher.ts +111 -0
  688. package/src/events/tool-metrics-listener.ts +159 -0
  689. package/src/events/tool-notification-listener.ts +17 -0
  690. package/src/events/tool-profiling-listener.ts +158 -0
  691. package/src/events/tool-trace-listener.ts +75 -0
  692. package/src/export/formatter.ts +98 -0
  693. package/src/followups/followup-store.ts +168 -0
  694. package/src/followups/index.ts +10 -0
  695. package/src/followups/types.ts +29 -0
  696. package/src/gallery/default-gallery.ts +795 -0
  697. package/src/gallery/gallery-manifest.ts +24 -0
  698. package/src/home-base/app-link-store.ts +82 -0
  699. package/src/home-base/bootstrap.ts +68 -0
  700. package/src/home-base/prebuilt/index.html +662 -0
  701. package/src/home-base/prebuilt/seed-metadata.json +21 -0
  702. package/src/home-base/prebuilt/seed.ts +112 -0
  703. package/src/home-base/prebuilt-home-base-updater.ts +30 -0
  704. package/src/hooks/cli.ts +163 -0
  705. package/src/hooks/config.ts +88 -0
  706. package/src/hooks/discovery.ts +110 -0
  707. package/src/hooks/manager.ts +124 -0
  708. package/src/hooks/runner.ts +123 -0
  709. package/src/hooks/templates.ts +52 -0
  710. package/src/hooks/types.ts +72 -0
  711. package/src/inbound/public-ingress-urls.ts +123 -0
  712. package/src/index.ts +81 -0
  713. package/src/instrument.ts +60 -0
  714. package/src/logfire.ts +99 -0
  715. package/src/media/gemini-image-service.ts +136 -0
  716. package/src/memory/account-store.ts +108 -0
  717. package/src/memory/admin.ts +211 -0
  718. package/src/memory/app-git-service.ts +295 -0
  719. package/src/memory/app-store.ts +577 -0
  720. package/src/memory/attachments-store.ts +397 -0
  721. package/src/memory/channel-delivery-store.ts +353 -0
  722. package/src/memory/channel-guardian-store.ts +669 -0
  723. package/src/memory/checkpoints.ts +52 -0
  724. package/src/memory/clarification-resolver.ts +298 -0
  725. package/src/memory/conflict-intent.ts +157 -0
  726. package/src/memory/conflict-policy.ts +73 -0
  727. package/src/memory/conflict-store.ts +350 -0
  728. package/src/memory/contradiction-checker.ts +358 -0
  729. package/src/memory/conversation-key-store.ts +122 -0
  730. package/src/memory/conversation-store.ts +470 -0
  731. package/src/memory/db.ts +1991 -0
  732. package/src/memory/embedding-backend.ts +229 -0
  733. package/src/memory/embedding-gemini.ts +52 -0
  734. package/src/memory/embedding-local.ts +65 -0
  735. package/src/memory/embedding-ollama.ts +55 -0
  736. package/src/memory/embedding-openai.ts +25 -0
  737. package/src/memory/entity-extractor.ts +474 -0
  738. package/src/memory/external-conversation-store.ts +234 -0
  739. package/src/memory/fingerprint.ts +20 -0
  740. package/src/memory/indexer.ts +156 -0
  741. package/src/memory/items-extractor.ts +461 -0
  742. package/src/memory/job-handlers/backfill.ts +139 -0
  743. package/src/memory/job-handlers/cleanup.ts +58 -0
  744. package/src/memory/job-handlers/conflict.ts +141 -0
  745. package/src/memory/job-handlers/embedding.ts +61 -0
  746. package/src/memory/job-handlers/extraction.ts +123 -0
  747. package/src/memory/job-handlers/index-maintenance.ts +54 -0
  748. package/src/memory/job-handlers/summarization.ts +286 -0
  749. package/src/memory/job-utils.ts +170 -0
  750. package/src/memory/jobs-store.ts +401 -0
  751. package/src/memory/jobs-worker.ts +313 -0
  752. package/src/memory/llm-request-log-store.ts +45 -0
  753. package/src/memory/llm-usage-store.ts +60 -0
  754. package/src/memory/message-content.ts +54 -0
  755. package/src/memory/profile-compiler.ts +160 -0
  756. package/src/memory/published-pages-store.ts +137 -0
  757. package/src/memory/qdrant-client.ts +366 -0
  758. package/src/memory/qdrant-manager.ts +242 -0
  759. package/src/memory/query-builder.ts +45 -0
  760. package/src/memory/retrieval-budget.ts +30 -0
  761. package/src/memory/retriever.ts +653 -0
  762. package/src/memory/runs-store.ts +305 -0
  763. package/src/memory/schema.ts +677 -0
  764. package/src/memory/search/entity.ts +298 -0
  765. package/src/memory/search/formatting.ts +207 -0
  766. package/src/memory/search/lexical.ts +227 -0
  767. package/src/memory/search/ranking.ts +401 -0
  768. package/src/memory/search/semantic.ts +121 -0
  769. package/src/memory/search/types.ts +137 -0
  770. package/src/memory/segmenter.ts +68 -0
  771. package/src/memory/shared-app-links-store.ts +138 -0
  772. package/src/memory/tool-usage-store.ts +62 -0
  773. package/src/messaging/activity-analyzer.ts +76 -0
  774. package/src/messaging/draft-store.ts +88 -0
  775. package/src/messaging/index.ts +3 -0
  776. package/src/messaging/provider-types.ts +80 -0
  777. package/src/messaging/provider.ts +52 -0
  778. package/src/messaging/providers/gmail/adapter.ts +193 -0
  779. package/src/messaging/providers/gmail/client.ts +204 -0
  780. package/src/messaging/providers/gmail/types.ts +90 -0
  781. package/src/messaging/providers/slack/adapter.ts +202 -0
  782. package/src/messaging/providers/slack/client.ts +198 -0
  783. package/src/messaging/providers/slack/types.ts +119 -0
  784. package/src/messaging/providers/telegram-bot/adapter.ts +162 -0
  785. package/src/messaging/providers/telegram-bot/client.ts +104 -0
  786. package/src/messaging/providers/telegram-bot/types.ts +15 -0
  787. package/src/messaging/registry.ts +35 -0
  788. package/src/messaging/style-analyzer.ts +159 -0
  789. package/src/messaging/thread-summarizer.ts +306 -0
  790. package/src/messaging/triage-engine.ts +323 -0
  791. package/src/messaging/types.ts +55 -0
  792. package/src/permissions/checker.ts +640 -0
  793. package/src/permissions/defaults.ts +254 -0
  794. package/src/permissions/prompter.ts +98 -0
  795. package/src/permissions/secret-prompter.ts +114 -0
  796. package/src/permissions/shell-identity.ts +227 -0
  797. package/src/permissions/trust-store.ts +607 -0
  798. package/src/permissions/types.ts +43 -0
  799. package/src/permissions/workspace-policy.ts +114 -0
  800. package/src/playbooks/index.ts +2 -0
  801. package/src/playbooks/playbook-compiler.ts +90 -0
  802. package/src/playbooks/types.ts +55 -0
  803. package/src/providers/anthropic/client.ts +751 -0
  804. package/src/providers/failover.ts +129 -0
  805. package/src/providers/fireworks/client.ts +20 -0
  806. package/src/providers/gemini/client.ts +285 -0
  807. package/src/providers/ollama/client.ts +30 -0
  808. package/src/providers/openai/client.ts +337 -0
  809. package/src/providers/openrouter/client.ts +20 -0
  810. package/src/providers/ratelimit.ts +93 -0
  811. package/src/providers/registry.ts +146 -0
  812. package/src/providers/retry.ts +81 -0
  813. package/src/providers/stream-timeout.ts +38 -0
  814. package/src/providers/types.ts +109 -0
  815. package/src/runtime/assistant-event-hub.ts +157 -0
  816. package/src/runtime/assistant-event.ts +82 -0
  817. package/src/runtime/channel-approval-parser.ts +60 -0
  818. package/src/runtime/channel-approval-types.ts +73 -0
  819. package/src/runtime/channel-approvals.ts +206 -0
  820. package/src/runtime/channel-guardian-service.ts +212 -0
  821. package/src/runtime/gateway-client.ts +58 -0
  822. package/src/runtime/http-server.ts +1076 -0
  823. package/src/runtime/http-types.ts +66 -0
  824. package/src/runtime/routes/app-routes.ts +174 -0
  825. package/src/runtime/routes/attachment-routes.ts +133 -0
  826. package/src/runtime/routes/call-routes.ts +190 -0
  827. package/src/runtime/routes/channel-routes.ts +1404 -0
  828. package/src/runtime/routes/conversation-routes.ts +352 -0
  829. package/src/runtime/routes/events-routes.ts +148 -0
  830. package/src/runtime/routes/run-routes.ts +257 -0
  831. package/src/runtime/routes/secret-routes.ts +76 -0
  832. package/src/runtime/run-orchestrator.ts +330 -0
  833. package/src/schedule/recurrence-engine.ts +162 -0
  834. package/src/schedule/recurrence-types.ts +67 -0
  835. package/src/schedule/schedule-store.ts +506 -0
  836. package/src/schedule/scheduler.ts +171 -0
  837. package/src/security/encrypted-store.ts +238 -0
  838. package/src/security/keychain.ts +252 -0
  839. package/src/security/oauth-callback-registry.ts +66 -0
  840. package/src/security/oauth2.ts +274 -0
  841. package/src/security/redaction.ts +89 -0
  842. package/src/security/secret-allowlist.ts +164 -0
  843. package/src/security/secret-ingress.ts +57 -0
  844. package/src/security/secret-scanner.ts +550 -0
  845. package/src/security/secure-keys.ts +180 -0
  846. package/src/security/token-manager.ts +141 -0
  847. package/src/services/published-app-updater.ts +69 -0
  848. package/src/services/vercel-deploy.ts +73 -0
  849. package/src/skills/active-skill-tools.ts +81 -0
  850. package/src/skills/clawhub.ts +414 -0
  851. package/src/skills/include-graph.ts +146 -0
  852. package/src/skills/managed-store.ts +233 -0
  853. package/src/skills/path-classifier.ts +128 -0
  854. package/src/skills/slash-commands.ts +174 -0
  855. package/src/skills/tool-manifest.ts +165 -0
  856. package/src/skills/version-hash.ts +110 -0
  857. package/src/slack/slack-webhook.ts +61 -0
  858. package/src/subagent/index.ts +19 -0
  859. package/src/subagent/manager.ts +511 -0
  860. package/src/subagent/types.ts +69 -0
  861. package/src/swarm/backend-claude-code.ts +145 -0
  862. package/src/swarm/index.ts +44 -0
  863. package/src/swarm/limits.ts +37 -0
  864. package/src/swarm/orchestrator.ts +279 -0
  865. package/src/swarm/plan-validator.ts +151 -0
  866. package/src/swarm/router-planner.ts +100 -0
  867. package/src/swarm/router-prompts.ts +36 -0
  868. package/src/swarm/synthesizer.ts +62 -0
  869. package/src/swarm/types.ts +62 -0
  870. package/src/swarm/worker-backend.ts +121 -0
  871. package/src/swarm/worker-prompts.ts +79 -0
  872. package/src/swarm/worker-runner.ts +164 -0
  873. package/src/tasks/SPEC.md +139 -0
  874. package/src/tasks/candidate-store.ts +86 -0
  875. package/src/tasks/ephemeral-permissions.ts +48 -0
  876. package/src/tasks/task-compiler.ts +199 -0
  877. package/src/tasks/task-runner.ts +90 -0
  878. package/src/tasks/task-scheduler.ts +21 -0
  879. package/src/tasks/task-store.ts +127 -0
  880. package/src/tasks/tool-sanitizer.ts +36 -0
  881. package/src/tools/apps/definitions.ts +59 -0
  882. package/src/tools/apps/executors.ts +313 -0
  883. package/src/tools/apps/open-proxy.ts +43 -0
  884. package/src/tools/apps/registry.ts +16 -0
  885. package/src/tools/assets/materialize.ts +218 -0
  886. package/src/tools/assets/search.ts +361 -0
  887. package/src/tools/browser/__tests__/auth-cache.test.ts +219 -0
  888. package/src/tools/browser/__tests__/auth-detector.test.ts +362 -0
  889. package/src/tools/browser/__tests__/jit-auth.test.ts +189 -0
  890. package/src/tools/browser/api-map.ts +293 -0
  891. package/src/tools/browser/auth-cache.ts +149 -0
  892. package/src/tools/browser/auth-detector.ts +347 -0
  893. package/src/tools/browser/auto-navigate.ts +270 -0
  894. package/src/tools/browser/browser-execution.ts +980 -0
  895. package/src/tools/browser/browser-handoff.ts +79 -0
  896. package/src/tools/browser/browser-manager.ts +715 -0
  897. package/src/tools/browser/browser-screencast.ts +217 -0
  898. package/src/tools/browser/headless-browser.ts +450 -0
  899. package/src/tools/browser/jit-auth.ts +51 -0
  900. package/src/tools/browser/network-recorder.ts +349 -0
  901. package/src/tools/browser/network-recording-types.ts +49 -0
  902. package/src/tools/browser/recording-store.ts +49 -0
  903. package/src/tools/browser/runtime-check.ts +43 -0
  904. package/src/tools/browser/x-auto-navigate.ts +207 -0
  905. package/src/tools/calls/call-end.ts +67 -0
  906. package/src/tools/calls/call-start.ts +81 -0
  907. package/src/tools/calls/call-status.ts +81 -0
  908. package/src/tools/claude-code/claude-code.ts +428 -0
  909. package/src/tools/computer-use/definitions.ts +443 -0
  910. package/src/tools/computer-use/registry.ts +22 -0
  911. package/src/tools/computer-use/request-computer-control.ts +53 -0
  912. package/src/tools/computer-use/skill-proxy-bridge.ts +28 -0
  913. package/src/tools/credentials/account-registry.ts +127 -0
  914. package/src/tools/credentials/broker-types.ts +107 -0
  915. package/src/tools/credentials/broker.ts +372 -0
  916. package/src/tools/credentials/domain-policy.ts +51 -0
  917. package/src/tools/credentials/host-pattern-match.ts +60 -0
  918. package/src/tools/credentials/metadata-store.ts +335 -0
  919. package/src/tools/credentials/policy-types.ts +52 -0
  920. package/src/tools/credentials/policy-validate.ts +80 -0
  921. package/src/tools/credentials/resolve.ts +122 -0
  922. package/src/tools/credentials/selection.ts +159 -0
  923. package/src/tools/credentials/tool-policy.ts +25 -0
  924. package/src/tools/credentials/vault.ts +657 -0
  925. package/src/tools/document/document-tool.ts +92 -0
  926. package/src/tools/document/editor-template.ts +237 -0
  927. package/src/tools/execution-target.ts +21 -0
  928. package/src/tools/execution-timeout.ts +49 -0
  929. package/src/tools/executor.ts +815 -0
  930. package/src/tools/filesystem/edit.ts +127 -0
  931. package/src/tools/filesystem/fuzzy-match.ts +202 -0
  932. package/src/tools/filesystem/read.ts +71 -0
  933. package/src/tools/filesystem/view-image.ts +199 -0
  934. package/src/tools/filesystem/write.ts +79 -0
  935. package/src/tools/followups/followup_create.ts +76 -0
  936. package/src/tools/followups/followup_list.ts +60 -0
  937. package/src/tools/followups/followup_resolve.ts +56 -0
  938. package/src/tools/host-filesystem/edit.ts +125 -0
  939. package/src/tools/host-filesystem/read.ts +80 -0
  940. package/src/tools/host-filesystem/write.ts +76 -0
  941. package/src/tools/host-terminal/cli-discover.ts +180 -0
  942. package/src/tools/host-terminal/host-shell.ts +191 -0
  943. package/src/tools/memory/definitions.ts +69 -0
  944. package/src/tools/memory/handlers.ts +246 -0
  945. package/src/tools/memory/register.ts +66 -0
  946. package/src/tools/network/__tests__/web-search.test.ts +427 -0
  947. package/src/tools/network/domain-normalize.ts +85 -0
  948. package/src/tools/network/script-proxy/__tests__/logging.test.ts +248 -0
  949. package/src/tools/network/script-proxy/__tests__/policy.test.ts +234 -0
  950. package/src/tools/network/script-proxy/__tests__/router.test.ts +76 -0
  951. package/src/tools/network/script-proxy/certs.ts +237 -0
  952. package/src/tools/network/script-proxy/connect-tunnel.ts +82 -0
  953. package/src/tools/network/script-proxy/http-forwarder.ts +151 -0
  954. package/src/tools/network/script-proxy/index.ts +28 -0
  955. package/src/tools/network/script-proxy/logging.ts +196 -0
  956. package/src/tools/network/script-proxy/mitm-handler.ts +269 -0
  957. package/src/tools/network/script-proxy/policy.ts +152 -0
  958. package/src/tools/network/script-proxy/router.ts +60 -0
  959. package/src/tools/network/script-proxy/server.ts +136 -0
  960. package/src/tools/network/script-proxy/session-manager.ts +534 -0
  961. package/src/tools/network/script-proxy/types.ts +125 -0
  962. package/src/tools/network/url-safety.ts +227 -0
  963. package/src/tools/network/web-fetch.ts +713 -0
  964. package/src/tools/network/web-search.ts +296 -0
  965. package/src/tools/policy-context.ts +29 -0
  966. package/src/tools/registry.ts +295 -0
  967. package/src/tools/reminder/reminder-store.ts +148 -0
  968. package/src/tools/reminder/reminder.ts +80 -0
  969. package/src/tools/schedule/create.ts +81 -0
  970. package/src/tools/schedule/delete.ts +28 -0
  971. package/src/tools/schedule/list.ts +69 -0
  972. package/src/tools/schedule/update.ts +97 -0
  973. package/src/tools/shared/filesystem/edit-engine.ts +56 -0
  974. package/src/tools/shared/filesystem/errors.ts +85 -0
  975. package/src/tools/shared/filesystem/file-ops-service.ts +215 -0
  976. package/src/tools/shared/filesystem/format-diff.ts +35 -0
  977. package/src/tools/shared/filesystem/path-policy.ts +125 -0
  978. package/src/tools/shared/filesystem/size-guard.ts +41 -0
  979. package/src/tools/shared/filesystem/types.ts +80 -0
  980. package/src/tools/shared/shell-output.ts +52 -0
  981. package/src/tools/skills/delete-managed.ts +60 -0
  982. package/src/tools/skills/load.ts +139 -0
  983. package/src/tools/skills/sandbox-runner.ts +279 -0
  984. package/src/tools/skills/scaffold-managed.ts +150 -0
  985. package/src/tools/skills/script-contract.ts +6 -0
  986. package/src/tools/skills/skill-script-runner.ts +86 -0
  987. package/src/tools/skills/skill-tool-factory.ts +64 -0
  988. package/src/tools/skills/vellum-catalog.ts +217 -0
  989. package/src/tools/subagent/abort.ts +33 -0
  990. package/src/tools/subagent/message.ts +39 -0
  991. package/src/tools/subagent/read.ts +67 -0
  992. package/src/tools/subagent/spawn.ts +46 -0
  993. package/src/tools/subagent/status.ts +45 -0
  994. package/src/tools/swarm/delegate.ts +183 -0
  995. package/src/tools/system/request-permission.ts +98 -0
  996. package/src/tools/system/version.ts +43 -0
  997. package/src/tools/tasks/index.ts +27 -0
  998. package/src/tools/tasks/task-delete.ts +82 -0
  999. package/src/tools/tasks/task-list.ts +44 -0
  1000. package/src/tools/tasks/task-run.ts +97 -0
  1001. package/src/tools/tasks/task-save.ts +47 -0
  1002. package/src/tools/tasks/work-item-enqueue.ts +234 -0
  1003. package/src/tools/tasks/work-item-list.ts +55 -0
  1004. package/src/tools/tasks/work-item-remove.ts +60 -0
  1005. package/src/tools/tasks/work-item-run.ts +78 -0
  1006. package/src/tools/tasks/work-item-update.ts +114 -0
  1007. package/src/tools/terminal/backends/docker.ts +372 -0
  1008. package/src/tools/terminal/backends/native.ts +190 -0
  1009. package/src/tools/terminal/backends/types.ts +26 -0
  1010. package/src/tools/terminal/evaluate-typescript.ts +275 -0
  1011. package/src/tools/terminal/parser.ts +413 -0
  1012. package/src/tools/terminal/safe-env.ts +37 -0
  1013. package/src/tools/terminal/sandbox-diagnostics.ts +149 -0
  1014. package/src/tools/terminal/sandbox.ts +44 -0
  1015. package/src/tools/terminal/shell.ts +257 -0
  1016. package/src/tools/tool-manifest.ts +198 -0
  1017. package/src/tools/types.ts +176 -0
  1018. package/src/tools/ui-surface/definitions.ts +244 -0
  1019. package/src/tools/ui-surface/registry.ts +14 -0
  1020. package/src/tools/watch/screen-watch.ts +130 -0
  1021. package/src/tools/watch/watch-state.ts +119 -0
  1022. package/src/tools/watcher/create.ts +64 -0
  1023. package/src/tools/watcher/delete.ts +27 -0
  1024. package/src/tools/watcher/digest.ts +50 -0
  1025. package/src/tools/watcher/list.ts +60 -0
  1026. package/src/tools/watcher/update.ts +56 -0
  1027. package/src/tools/weather/service.ts +551 -0
  1028. package/src/twitter/client.ts +690 -0
  1029. package/src/twitter/oauth-client.ts +102 -0
  1030. package/src/twitter/router.ts +101 -0
  1031. package/src/twitter/session.ts +91 -0
  1032. package/src/usage/actors.ts +24 -0
  1033. package/src/usage/types.ts +37 -0
  1034. package/src/util/clipboard.ts +33 -0
  1035. package/src/util/content-id.ts +16 -0
  1036. package/src/util/debounce.ts +88 -0
  1037. package/src/util/diff.ts +181 -0
  1038. package/src/util/errors.ts +129 -0
  1039. package/src/util/logger.ts +243 -0
  1040. package/src/util/network-info.ts +47 -0
  1041. package/src/util/platform.ts +632 -0
  1042. package/src/util/pricing.ts +150 -0
  1043. package/src/util/promise-guard.ts +37 -0
  1044. package/src/util/retry.ts +98 -0
  1045. package/src/util/spinner.ts +51 -0
  1046. package/src/util/time.ts +16 -0
  1047. package/src/util/truncate.ts +6 -0
  1048. package/src/util/xml.ts +4 -0
  1049. package/src/version.ts +3 -0
  1050. package/src/watcher/constants.ts +11 -0
  1051. package/src/watcher/engine.ts +199 -0
  1052. package/src/watcher/provider-registry.ts +15 -0
  1053. package/src/watcher/provider-types.ts +48 -0
  1054. package/src/watcher/providers/gmail.ts +198 -0
  1055. package/src/watcher/providers/google-calendar.ts +228 -0
  1056. package/src/watcher/providers/slack.ts +129 -0
  1057. package/src/watcher/watcher-store.ts +419 -0
  1058. package/src/work-items/work-item-runner.ts +171 -0
  1059. package/src/work-items/work-item-store.ts +325 -0
  1060. package/src/workspace/commit-message-enrichment-service.ts +284 -0
  1061. package/src/workspace/commit-message-provider.ts +95 -0
  1062. package/src/workspace/git-service.ts +857 -0
  1063. package/src/workspace/heartbeat-service.ts +345 -0
  1064. package/src/workspace/provider-commit-message-generator.ts +285 -0
  1065. package/src/workspace/top-level-renderer.ts +19 -0
  1066. package/src/workspace/top-level-scanner.ts +41 -0
  1067. package/src/workspace/turn-commit.ts +175 -0
  1068. package/tsconfig.json +21 -0
@@ -0,0 +1,903 @@
1
+ /**
2
+ * Computer-use session orchestrator.
3
+ *
4
+ * Manages the observation -> infer -> action loop for computer-use tasks,
5
+ * bridging the macOS client (which captures screen state and executes actions)
6
+ * with the AgentLoop (which runs inference via the Anthropic API with CU tools).
7
+ */
8
+
9
+ import { v4 as uuid } from 'uuid';
10
+ import type { Provider, Message, ContentBlock, ToolDefinition } from '../providers/types.js';
11
+ import { INTERACTIVE_SURFACE_TYPES } from './ipc-protocol.js';
12
+ import type { ServerMessage, CuObservation, SurfaceType, SurfaceData, FileUploadSurfaceData, UiSurfaceShow } from './ipc-protocol.js';
13
+ import type { Tool, ToolExecutionResult } from '../tools/types.js';
14
+ import { AgentLoop } from '../agent/loop.js';
15
+ import { ToolExecutor } from '../tools/executor.js';
16
+ import { PermissionPrompter } from '../permissions/prompter.js';
17
+ import { SecretPrompter } from '../permissions/secret-prompter.js';
18
+ import type { UserDecision } from '../permissions/types.js';
19
+ import { allUiSurfaceTools } from '../tools/ui-surface/definitions.js';
20
+ import { allComputerUseTools } from '../tools/computer-use/definitions.js';
21
+ import { registerSkillTools } from '../tools/registry.js';
22
+ import { buildComputerUseSystemPrompt } from '../config/computer-use-prompt.js';
23
+ import { getSandboxWorkingDir } from '../util/platform.js';
24
+ import { getConfig } from '../config/loader.js';
25
+ import { projectSkillTools, resetSkillToolProjection, type SkillProjectionCache } from './session-skill-tools.js';
26
+ import { getLogger } from '../util/logger.js';
27
+
28
+ const log = getLogger('computer-use-session');
29
+
30
+ const MAX_STEPS = 50;
31
+ const SESSION_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes
32
+ const MAX_HISTORY_ENTRIES = 10;
33
+ const LOOP_DETECTION_WINDOW = 3;
34
+ const CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD = 2;
35
+
36
+ /** Number of most-recent AX tree snapshots to keep in conversation history. */
37
+ const MAX_AX_TREES_IN_HISTORY = 2;
38
+
39
+ /** Regex that matches the `<ax-tree>…</ax-tree>` markers injected by buildObservationResultContent. */
40
+ const AX_TREE_PATTERN = /<ax-tree>[\s\S]*?<\/ax-tree>/g;
41
+ const AX_TREE_PLACEHOLDER = '<ax_tree_omitted />';
42
+
43
+ type SessionState = 'idle' | 'awaiting_observation' | 'inferring' | 'complete' | 'error';
44
+
45
+ interface ActionRecord {
46
+ step: number;
47
+ toolName: string;
48
+ input: Record<string, unknown>;
49
+ reasoning?: string;
50
+ result?: string;
51
+ }
52
+
53
+ export class ComputerUseSession {
54
+ private readonly sessionId: string;
55
+ private readonly task: string;
56
+ private readonly screenWidth: number;
57
+ private readonly screenHeight: number;
58
+ private readonly provider: Provider;
59
+ private sendToClient: (msg: ServerMessage) => void;
60
+ private readonly interactionType: 'computer_use' | 'text_qa';
61
+ private readonly onTerminal?: (sessionId: string) => void;
62
+ private readonly preactivatedSkillIds: string[];
63
+ private readonly skillProjectionState = new Map<string, string>();
64
+ private readonly skillProjectionCache: SkillProjectionCache = {};
65
+
66
+ private state: SessionState = 'idle';
67
+ private stepCount = 0;
68
+ private actionHistory: ActionRecord[] = [];
69
+ private previousAXTree: string | undefined;
70
+ private consecutiveUnchangedSteps = 0;
71
+ private abortController: AbortController | null = null;
72
+ private sessionTimer: ReturnType<typeof setTimeout> | null = null;
73
+
74
+ private pendingObservation: {
75
+ resolve: (result: ToolExecutionResult) => void;
76
+ } | null = null;
77
+
78
+ private pendingSurfaceActions = new Map<string, {
79
+ resolve: (result: ToolExecutionResult) => void;
80
+ }>();
81
+ private surfaceState = new Map<string, { surfaceType: SurfaceType; data: SurfaceData }>();
82
+ private terminalNotified = false;
83
+ private prompter: PermissionPrompter | null = null;
84
+
85
+ // Tracks the agent loop promise so callers can await session completion
86
+ private loopPromise: Promise<void> | null = null;
87
+
88
+ constructor(
89
+ sessionId: string,
90
+ task: string,
91
+ screenWidth: number,
92
+ screenHeight: number,
93
+ provider: Provider,
94
+ sendToClient: (msg: ServerMessage) => void,
95
+ interactionType?: 'computer_use' | 'text_qa',
96
+ onTerminal?: (sessionId: string) => void,
97
+ preactivatedSkillIds?: string[],
98
+ ) {
99
+ this.sessionId = sessionId;
100
+ this.task = task;
101
+ this.screenWidth = screenWidth;
102
+ this.screenHeight = screenHeight;
103
+ this.provider = provider;
104
+ this.sendToClient = sendToClient;
105
+ this.interactionType = interactionType ?? 'computer_use';
106
+ this.onTerminal = onTerminal;
107
+ this.preactivatedSkillIds = preactivatedSkillIds ?? ['computer-use'];
108
+ }
109
+
110
+ // ---------------------------------------------------------------------------
111
+ // Public API
112
+ // ---------------------------------------------------------------------------
113
+
114
+ async handleObservation(obs: CuObservation): Promise<void> {
115
+ if (this.state === 'complete' || this.state === 'error') {
116
+ log.warn({ sessionId: this.sessionId, state: this.state }, 'Observation received after session ended');
117
+ return;
118
+ }
119
+
120
+ // Track consecutive unchanged steps
121
+ const hadPreviousAXTree = this.previousAXTree != null;
122
+ if (this.stepCount > 0) {
123
+ if (obs.axDiff == null && hadPreviousAXTree && obs.axTree != null) {
124
+ this.consecutiveUnchangedSteps++;
125
+ } else if (obs.axDiff != null) {
126
+ this.consecutiveUnchangedSteps = 0;
127
+ }
128
+ }
129
+
130
+ // Capture previous AX tree for next turn
131
+ if (obs.axTree != null) {
132
+ this.previousAXTree = obs.axTree;
133
+ }
134
+
135
+ if (this.state === 'awaiting_observation' && this.pendingObservation) {
136
+ // Resolve the pending proxy tool result with updated screen context
137
+ const content = this.buildObservationResultContent(obs, hadPreviousAXTree);
138
+ const result: ToolExecutionResult = obs.executionError
139
+ ? { content: `Action failed: ${obs.executionError}\n\n${content}`, isError: true }
140
+ : { content, isError: false };
141
+ this.state = 'inferring';
142
+ this.pendingObservation.resolve(result);
143
+ this.pendingObservation = null;
144
+ // The agent loop continues automatically after resolution
145
+ return;
146
+ }
147
+
148
+ // First observation — start the agent loop
149
+ this.state = 'inferring';
150
+ this.abortController = new AbortController();
151
+
152
+ // Safety net: abort the session if it runs longer than SESSION_TIMEOUT_MS
153
+ this.sessionTimer = setTimeout(() => {
154
+ log.warn({ sessionId: this.sessionId, timeoutMs: SESSION_TIMEOUT_MS }, 'Session timeout reached, aborting');
155
+ this.abort();
156
+ }, SESSION_TIMEOUT_MS);
157
+
158
+ const messages = this.buildMessages(obs, hadPreviousAXTree);
159
+ this.loopPromise = this.runAgentLoop(messages).catch((err) => {
160
+ // Catches errors from setup code (e.g. skill projection failures) that
161
+ // occur before runAgentLoop's internal try-catch takes over.
162
+ const message = err instanceof Error ? err.message : String(err);
163
+ log.error({ err, sessionId: this.sessionId }, 'Agent loop startup failed');
164
+ if (this.sessionTimer) {
165
+ clearTimeout(this.sessionTimer);
166
+ this.sessionTimer = null;
167
+ }
168
+ if (this.state !== 'complete' && this.state !== 'error') {
169
+ this.state = 'error';
170
+ this.sendToClient({
171
+ type: 'cu_error',
172
+ sessionId: this.sessionId,
173
+ message,
174
+ });
175
+ this.notifyTerminal();
176
+ }
177
+ });
178
+
179
+ await this.loopPromise;
180
+ }
181
+
182
+ abort(): void {
183
+ if (this.state === 'complete' || this.state === 'error') return;
184
+
185
+ log.info({ sessionId: this.sessionId }, 'Aborting computer-use session');
186
+ if (this.sessionTimer) {
187
+ clearTimeout(this.sessionTimer);
188
+ this.sessionTimer = null;
189
+ }
190
+ this.abortController?.abort();
191
+
192
+ // If waiting for an observation, resolve it as cancelled
193
+ if (this.pendingObservation) {
194
+ this.pendingObservation.resolve({ content: 'Session aborted', isError: true });
195
+ this.pendingObservation = null;
196
+ }
197
+
198
+ // Dispose prompter to clear pending permission timers and reject promises
199
+ this.prompter?.dispose();
200
+
201
+ // Resolve any pending surface actions
202
+ for (const [, pending] of this.pendingSurfaceActions) {
203
+ pending.resolve({ content: 'Session aborted', isError: true });
204
+ }
205
+ this.pendingSurfaceActions.clear();
206
+ this.surfaceState.clear();
207
+
208
+ this.state = 'error';
209
+ this.sendToClient({
210
+ type: 'cu_error',
211
+ sessionId: this.sessionId,
212
+ message: 'Session aborted by user',
213
+ });
214
+ this.notifyTerminal();
215
+ }
216
+
217
+ isComplete(): boolean {
218
+ return this.state === 'complete';
219
+ }
220
+
221
+ getState(): string {
222
+ return this.state;
223
+ }
224
+
225
+ /**
226
+ * Compute CU tool definitions from the bundled computer-use skill via
227
+ * skill projection. Returns null if projection fails so the caller can
228
+ * fall back to legacy hardcoded tool definitions.
229
+ */
230
+ private getProjectedCuToolDefinitions(): ToolDefinition[] | null {
231
+ if (this.preactivatedSkillIds.length === 0) {
232
+ log.warn('No preactivatedSkillIds configured, falling back to legacy CU tools');
233
+ return null;
234
+ }
235
+
236
+ try {
237
+ const projection = projectSkillTools([], {
238
+ preactivatedSkillIds: this.preactivatedSkillIds,
239
+ previouslyActiveSkillIds: this.skillProjectionState,
240
+ cache: this.skillProjectionCache,
241
+ });
242
+
243
+ if (projection.toolDefinitions.length === 0) {
244
+ log.warn(
245
+ { preactivatedSkillIds: this.preactivatedSkillIds },
246
+ 'Skill projection produced no tool definitions, falling back to legacy CU tools',
247
+ );
248
+ return null;
249
+ }
250
+
251
+ return projection.toolDefinitions;
252
+ } catch (err) {
253
+ log.warn({ err }, 'Skill projection failed, falling back to legacy CU tools');
254
+ return null;
255
+ }
256
+ }
257
+
258
+ handleSurfaceAction(surfaceId: string, actionId: string, data?: Record<string, unknown>): void {
259
+ const pending = this.pendingSurfaceActions.get(surfaceId);
260
+ if (!pending) {
261
+ log.warn({ surfaceId, actionId }, 'No pending surface action found');
262
+ return;
263
+ }
264
+ // selection_changed is a non-terminal state update — don't consume the
265
+ // pending entry. The selection state will be in the action button payload.
266
+ if (actionId === 'selection_changed') {
267
+ return;
268
+ }
269
+ this.pendingSurfaceActions.delete(surfaceId);
270
+ pending.resolve({
271
+ content: JSON.stringify({ actionId, data: data ?? {} }),
272
+ isError: false,
273
+ });
274
+ }
275
+
276
+ // ---------------------------------------------------------------------------
277
+ // Agent loop execution
278
+ // ---------------------------------------------------------------------------
279
+
280
+ private async runAgentLoop(messages: Message[]): Promise<void> {
281
+ const systemPrompt = buildComputerUseSystemPrompt(this.screenWidth, this.screenHeight);
282
+
283
+ let cuToolDefs = this.getProjectedCuToolDefinitions();
284
+ if (!cuToolDefs) {
285
+ // Fallback: register the legacy CU tools as skill-origin tools so
286
+ // ToolExecutor can resolve them via getTool(), but using the same
287
+ // ownerSkillId as the bundled computer-use skill. This avoids
288
+ // core-vs-skill collisions that would permanently block skill
289
+ // projection recovery on subsequent sessions.
290
+ const fallbackSkillId = this.preactivatedSkillIds[0] ?? 'computer-use';
291
+ const fallbackTools: Tool[] = allComputerUseTools.map((t) => ({
292
+ ...t,
293
+ origin: 'skill' as const,
294
+ ownerSkillId: fallbackSkillId,
295
+ ownerSkillBundled: true,
296
+ }));
297
+ registerSkillTools(fallbackTools);
298
+ // Track in the session map so resetSkillToolProjection cleans up
299
+ this.skillProjectionState.set(fallbackSkillId, 'fallback');
300
+ cuToolDefs = allComputerUseTools.map((t) => t.getDefinition());
301
+ }
302
+
303
+ const toolDefs: ToolDefinition[] = [
304
+ ...cuToolDefs,
305
+ ...allUiSurfaceTools
306
+ .filter((t) => t.name !== 'request_file')
307
+ .map((t) => t.getDefinition()),
308
+ ];
309
+
310
+ this.prompter = new PermissionPrompter(this.sendToClient);
311
+ const prompter = this.prompter;
312
+ const secretPrompter = new SecretPrompter(this.sendToClient);
313
+ const executor = new ToolExecutor(prompter);
314
+
315
+ const proxyResolver = async (
316
+ toolName: string,
317
+ input: Record<string, unknown>,
318
+ ): Promise<ToolExecutionResult> => {
319
+ // ── Surface tool proxying ──────────────────────────────────────
320
+ if (toolName === 'ui_show') {
321
+ const surfaceId = uuid();
322
+ const surfaceType = input.surface_type as SurfaceType;
323
+ const title = typeof input.title === 'string' ? input.title : undefined;
324
+ const data = input.data as SurfaceData;
325
+ const actions = input.actions as Array<{ id: string; label: string; style?: string }> | undefined;
326
+ // Interactive surfaces default to awaiting user action.
327
+ // Tables and lists only block when explicit action buttons are provided;
328
+ // selectionMode alone should not gate blocking because selection_changed
329
+ // fires on every click and would immediately resolve multi-select surfaces.
330
+ const hasActions = Array.isArray(actions) && actions.length > 0;
331
+ const isInteractive = surfaceType === 'list'
332
+ ? hasActions
333
+ : surfaceType === 'table'
334
+ ? hasActions
335
+ : INTERACTIVE_SURFACE_TYPES.includes(surfaceType);
336
+ const awaitAction = (input.await_action as boolean) ?? isInteractive;
337
+
338
+ // Track surface state for ui_update merging
339
+ this.surfaceState.set(surfaceId, { surfaceType, data });
340
+
341
+ this.sendToClient({
342
+ type: 'ui_surface_show',
343
+ sessionId: this.sessionId,
344
+ surfaceId,
345
+ surfaceType,
346
+ title,
347
+ data,
348
+ actions: actions?.map(a => ({ id: a.id, label: a.label, style: (a.style ?? 'secondary') as 'primary' | 'secondary' | 'destructive' })),
349
+ } as unknown as UiSurfaceShow);
350
+
351
+ if (awaitAction) {
352
+ return new Promise<ToolExecutionResult>((resolve) => {
353
+ this.pendingSurfaceActions.set(surfaceId, { resolve });
354
+ });
355
+ }
356
+ return { content: JSON.stringify({ surfaceId }), isError: false };
357
+ }
358
+
359
+ if (toolName === 'ui_update') {
360
+ const surfaceId = input.surface_id as string;
361
+ const patch = input.data as Record<string, unknown>;
362
+
363
+ // Merge the partial patch into the stored full surface data
364
+ const stored = this.surfaceState.get(surfaceId);
365
+ let mergedData: SurfaceData;
366
+ if (stored) {
367
+ mergedData = { ...stored.data, ...patch } as SurfaceData;
368
+ stored.data = mergedData;
369
+ } else {
370
+ mergedData = patch as unknown as SurfaceData;
371
+ }
372
+
373
+ this.sendToClient({
374
+ type: 'ui_surface_update',
375
+ sessionId: this.sessionId,
376
+ surfaceId,
377
+ data: mergedData,
378
+ });
379
+ return { content: 'Surface updated', isError: false };
380
+ }
381
+
382
+ if (toolName === 'ui_dismiss') {
383
+ const surfaceId = input.surface_id as string;
384
+ this.sendToClient({
385
+ type: 'ui_surface_dismiss',
386
+ sessionId: this.sessionId,
387
+ surfaceId,
388
+ });
389
+ this.pendingSurfaceActions.delete(surfaceId);
390
+ this.surfaceState.delete(surfaceId);
391
+ return { content: 'Surface dismissed', isError: false };
392
+ }
393
+
394
+ // ── File request proxying ──────────────────────────────────────
395
+ if (toolName === 'request_file') {
396
+ const surfaceId = uuid();
397
+ const prompt = typeof input.prompt === 'string' ? input.prompt : 'Please share a file';
398
+ const acceptedTypes = Array.isArray(input.accepted_types) ? input.accepted_types as string[] : undefined;
399
+ const maxFiles = typeof input.max_files === 'number' ? input.max_files : 1;
400
+
401
+ const data: FileUploadSurfaceData = {
402
+ prompt,
403
+ acceptedTypes,
404
+ maxFiles,
405
+ };
406
+
407
+ this.surfaceState.set(surfaceId, { surfaceType: 'file_upload', data });
408
+
409
+ this.sendToClient({
410
+ type: 'ui_surface_show',
411
+ sessionId: this.sessionId,
412
+ surfaceId,
413
+ surfaceType: 'file_upload',
414
+ title: 'File Request',
415
+ data,
416
+ } as UiSurfaceShow);
417
+
418
+ // Always await — file upload is interactive
419
+ return new Promise<ToolExecutionResult>((resolve) => {
420
+ this.pendingSurfaceActions.set(surfaceId, { resolve });
421
+ });
422
+ }
423
+
424
+ // ── Computer-use tool proxying ─────────────────────────────────
425
+ const reasoning = typeof input.reasoning === 'string' ? input.reasoning : undefined;
426
+
427
+ // Record action in history
428
+ this.actionHistory.push({
429
+ step: this.stepCount + 1,
430
+ toolName,
431
+ input,
432
+ reasoning,
433
+ });
434
+
435
+ // Check for terminal tools
436
+ if (toolName === 'computer_use_done' || toolName === 'computer_use_respond') {
437
+ const summary =
438
+ toolName === 'computer_use_done'
439
+ ? (typeof input.summary === 'string' ? input.summary : 'Task completed')
440
+ : (typeof input.answer === 'string' ? input.answer : 'No answer provided');
441
+
442
+ this.sendToClient({
443
+ type: 'cu_complete',
444
+ sessionId: this.sessionId,
445
+ summary,
446
+ stepCount: this.stepCount,
447
+ isResponse: toolName === 'computer_use_respond' ? true : undefined,
448
+ });
449
+ this.state = 'complete';
450
+ // Stop AgentLoop immediately so terminal tools cannot trigger extra provider calls.
451
+ this.abortController?.abort();
452
+ this.notifyTerminal();
453
+ return { content: 'Session complete', isError: false };
454
+ }
455
+
456
+ this.stepCount++;
457
+
458
+ // Enforce step limit — abort the loop so toolChoice:'any' can't force another turn
459
+ if (this.stepCount > MAX_STEPS) {
460
+ this.state = 'error';
461
+ this.sendToClient({
462
+ type: 'cu_error',
463
+ sessionId: this.sessionId,
464
+ message: `Step limit (${MAX_STEPS}) exceeded`,
465
+ });
466
+ this.abortController?.abort();
467
+ this.notifyTerminal();
468
+ return { content: `Step limit (${MAX_STEPS}) exceeded`, isError: true };
469
+ }
470
+
471
+ // Send action to client for execution
472
+ this.sendToClient({
473
+ type: 'cu_action',
474
+ sessionId: this.sessionId,
475
+ toolName,
476
+ input,
477
+ reasoning,
478
+ stepNumber: this.stepCount,
479
+ });
480
+
481
+ // Wait for next observation from client
482
+ this.state = 'awaiting_observation';
483
+ return new Promise<ToolExecutionResult>((resolve) => {
484
+ this.pendingObservation = { resolve };
485
+ });
486
+ };
487
+
488
+ // Build a set of tool names the CU session is allowed to execute.
489
+ // This prevents tools registered globally (e.g. computer_use_request_control)
490
+ // but not advertised to the CU model from executing during CU sessions.
491
+ const allowedToolNames = new Set(toolDefs.map((td) => td.name));
492
+
493
+ const toolExecutor = async (
494
+ name: string,
495
+ input: Record<string, unknown>,
496
+ ): Promise<ToolExecutionResult> => {
497
+ return executor.execute(name, input, {
498
+ workingDir: getSandboxWorkingDir(),
499
+ sessionId: this.sessionId,
500
+ conversationId: this.sessionId,
501
+ proxyToolResolver: proxyResolver,
502
+ allowedToolNames,
503
+ requestSecret: async (params) => {
504
+ return secretPrompter.prompt(
505
+ params.service, params.field, params.label,
506
+ params.description, params.placeholder,
507
+ this.sessionId,
508
+ params.purpose, params.allowedTools, params.allowedDomains,
509
+ );
510
+ },
511
+ });
512
+ };
513
+
514
+ // Wrap the provider so that old AX tree snapshots are stripped from
515
+ // conversation history before each API call, keeping only the most recent
516
+ // MAX_AX_TREES_IN_HISTORY entries. This prevents TTFT from growing
517
+ // linearly with step count.
518
+ const compactingProvider: Provider = {
519
+ name: this.provider.name,
520
+ sendMessage: (msgs, tools, sys, opts) => {
521
+ const compacted = ComputerUseSession.compactHistory(msgs);
522
+ return this.provider.sendMessage(compacted, tools, sys, opts);
523
+ },
524
+ };
525
+
526
+ const cuConfig = getConfig();
527
+ const agentLoop = new AgentLoop(
528
+ compactingProvider,
529
+ systemPrompt,
530
+ {
531
+ maxTokens: 4096,
532
+ maxInputTokens: cuConfig.contextWindow.maxInputTokens,
533
+ toolChoice: { type: 'any' },
534
+ // Allow MAX_STEPS non-terminal actions plus one terminal turn
535
+ // (computer_use_done/computer_use_respond), since AgentLoop caps tool turns globally.
536
+ maxToolUseTurns: MAX_STEPS + 1,
537
+ },
538
+ toolDefs,
539
+ toolExecutor,
540
+ );
541
+
542
+ try {
543
+ await agentLoop.run(
544
+ messages,
545
+ (event) => {
546
+ switch (event.type) {
547
+ case 'error':
548
+ log.error({ err: event.error, sessionId: this.sessionId }, 'Agent loop error');
549
+ if (this.state !== 'complete') {
550
+ this.state = 'error';
551
+ this.sendToClient({
552
+ type: 'cu_error',
553
+ sessionId: this.sessionId,
554
+ message: event.error.message,
555
+ });
556
+ this.notifyTerminal();
557
+ }
558
+ break;
559
+ case 'usage':
560
+ log.info({
561
+ sessionId: this.sessionId,
562
+ inputTokens: event.inputTokens,
563
+ outputTokens: event.outputTokens,
564
+ model: event.model,
565
+ }, 'Usage');
566
+ break;
567
+ // Other events (text_delta, thinking_delta, etc.) are not surfaced to the CU client
568
+ }
569
+ },
570
+ this.abortController?.signal,
571
+ );
572
+
573
+ // If the loop exits without completing, treat as error
574
+ if (this.state !== 'complete' && this.state !== 'error') {
575
+ this.state = 'error';
576
+ this.sendToClient({
577
+ type: 'cu_error',
578
+ sessionId: this.sessionId,
579
+ message: 'Agent loop ended unexpectedly',
580
+ });
581
+ this.notifyTerminal();
582
+ }
583
+ } catch (err) {
584
+ if (this.abortController?.signal.aborted) {
585
+ log.info({ sessionId: this.sessionId }, 'Agent loop aborted');
586
+ return;
587
+ }
588
+ const message = err instanceof Error ? err.message : String(err);
589
+ log.error({ err, sessionId: this.sessionId }, 'Agent loop failed');
590
+ if (this.state !== 'complete') {
591
+ this.state = 'error';
592
+ this.sendToClient({
593
+ type: 'cu_error',
594
+ sessionId: this.sessionId,
595
+ message,
596
+ });
597
+ this.notifyTerminal();
598
+ }
599
+ } finally {
600
+ // Always clean up skill projection state and session timer
601
+ resetSkillToolProjection(this.skillProjectionState);
602
+ if (this.sessionTimer) {
603
+ clearTimeout(this.sessionTimer);
604
+ this.sessionTimer = null;
605
+ }
606
+ }
607
+ }
608
+
609
+ private notifyTerminal(): void {
610
+ if (this.terminalNotified) return;
611
+ this.terminalNotified = true;
612
+ resetSkillToolProjection(this.skillProjectionState);
613
+ this.onTerminal?.(this.sessionId);
614
+ }
615
+
616
+ // ---------------------------------------------------------------------------
617
+ // History compaction — strip old AX tree snapshots from tool results
618
+ // ---------------------------------------------------------------------------
619
+
620
+ /**
621
+ * Returns a shallow copy of `messages` where all but the most recent
622
+ * `MAX_AX_TREES_IN_HISTORY` `<ax-tree>` blocks have been replaced with a
623
+ * short placeholder. This keeps the conversation context small so that
624
+ * TTFT does not grow linearly with step count.
625
+ */
626
+ static compactHistory(messages: Message[]): Message[] {
627
+ // Collect indices of user messages that contain an <ax-tree> block
628
+ const indicesWithAxTree: number[] = [];
629
+ for (let i = 0; i < messages.length; i++) {
630
+ const msg = messages[i];
631
+ if (msg.role !== 'user') continue;
632
+ for (const block of msg.content) {
633
+ if (
634
+ block.type === 'tool_result' &&
635
+ typeof block.content === 'string' &&
636
+ block.content.includes('<ax-tree>')
637
+ ) {
638
+ indicesWithAxTree.push(i);
639
+ break;
640
+ }
641
+ }
642
+ }
643
+
644
+ if (indicesWithAxTree.length <= MAX_AX_TREES_IN_HISTORY) {
645
+ return messages;
646
+ }
647
+
648
+ const toStrip = new Set(indicesWithAxTree.slice(0, -MAX_AX_TREES_IN_HISTORY));
649
+
650
+ return messages.map((msg, idx) => {
651
+ if (!toStrip.has(idx)) return msg;
652
+ return {
653
+ ...msg,
654
+ content: msg.content.map((block) => {
655
+ if (
656
+ block.type === 'tool_result' &&
657
+ typeof block.content === 'string' &&
658
+ block.content.includes('<ax-tree>')
659
+ ) {
660
+ return {
661
+ ...block,
662
+ content: block.content.replace(AX_TREE_PATTERN, AX_TREE_PLACEHOLDER),
663
+ };
664
+ }
665
+ return block;
666
+ }),
667
+ };
668
+ });
669
+ }
670
+
671
+ /**
672
+ * Escapes any literal `</ax-tree>` occurrences inside AX tree content so
673
+ * that the non-greedy compaction regex (`AX_TREE_PATTERN`) does not stop
674
+ * prematurely when the user happens to be viewing XML/HTML source that
675
+ * contains the closing tag. The escaped content does not need to be
676
+ * unescaped because compaction replaces the entire block with a placeholder.
677
+ */
678
+ static escapeAxTreeContent(content: string): string {
679
+ return content.replace(/<\/ax-tree>/gi, '&lt;/ax-tree&gt;');
680
+ }
681
+
682
+ // ---------------------------------------------------------------------------
683
+ // Build rich tool-result content from an observation so the model sees
684
+ // updated screen state on each turn (not just "Action executed").
685
+ // ---------------------------------------------------------------------------
686
+
687
+ private buildObservationResultContent(obs: CuObservation, hadPreviousAXTree: boolean): string {
688
+ const parts: string[] = [];
689
+
690
+ if (obs.executionResult) {
691
+ parts.push(obs.executionResult);
692
+ parts.push('');
693
+ }
694
+
695
+ // AX tree diff
696
+ if (obs.axDiff) {
697
+ parts.push(obs.axDiff);
698
+ parts.push('');
699
+ } else if (hadPreviousAXTree && obs.axTree != null) {
700
+ const lastAction = this.actionHistory[this.actionHistory.length - 1];
701
+ const wasWait = lastAction?.toolName === 'computer_use_wait';
702
+ if (this.consecutiveUnchangedSteps >= CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD) {
703
+ parts.push(
704
+ `WARNING: ${this.consecutiveUnchangedSteps} consecutive actions had NO VISIBLE EFFECT on the UI. You MUST try a completely different approach.`,
705
+ );
706
+ } else if (!wasWait) {
707
+ parts.push('Your last action had NO VISIBLE EFFECT on the UI. Try something different.');
708
+ }
709
+ parts.push('');
710
+ }
711
+
712
+ // Current screen state — wrapped in markers so compactHistory can strip old snapshots
713
+ if (obs.axTree) {
714
+ parts.push('<ax-tree>');
715
+ parts.push('CURRENT SCREEN STATE:');
716
+ parts.push(ComputerUseSession.escapeAxTreeContent(obs.axTree));
717
+ parts.push('</ax-tree>');
718
+ }
719
+
720
+ const screenshotMetadata = this.formatScreenshotMetadata(obs);
721
+ if (screenshotMetadata.length > 0) {
722
+ parts.push('');
723
+ parts.push(...screenshotMetadata);
724
+ }
725
+
726
+ return parts.join('\n').trim() || 'Action executed';
727
+ }
728
+
729
+ // ---------------------------------------------------------------------------
730
+ // Message building (replicates AnthropicProvider.buildMessages from Swift)
731
+ // ---------------------------------------------------------------------------
732
+
733
+ private buildMessages(obs: CuObservation, hadPreviousAXTree: boolean): Message[] {
734
+ const contentBlocks: ContentBlock[] = [];
735
+
736
+ // Screenshot image block
737
+ if (obs.screenshot) {
738
+ contentBlocks.push({
739
+ type: 'image',
740
+ source: {
741
+ type: 'base64',
742
+ media_type: 'image/jpeg',
743
+ data: obs.screenshot,
744
+ },
745
+ });
746
+ }
747
+
748
+ // Text block
749
+ const textParts: string[] = [];
750
+ const trimmedTask = this.task.trim();
751
+ if (trimmedTask) {
752
+ textParts.push(`TASK: ${trimmedTask}`);
753
+ } else {
754
+ textParts.push('TASK: No explicit task provided.');
755
+ }
756
+ textParts.push('');
757
+
758
+ // AX tree diff (compact summary of what changed)
759
+ if (obs.axDiff && this.actionHistory.length > 0) {
760
+ textParts.push(obs.axDiff);
761
+ textParts.push('');
762
+ } else if (hadPreviousAXTree && obs.axTree != null && this.actionHistory.length > 0) {
763
+ // AX tree unchanged — tell the model its action had no effect
764
+ const lastAction = this.actionHistory[this.actionHistory.length - 1];
765
+ const wasWait = lastAction?.toolName === 'computer_use_wait';
766
+ textParts.push('CHANGES SINCE LAST ACTION:');
767
+ if (this.consecutiveUnchangedSteps >= CONSECUTIVE_UNCHANGED_WARNING_THRESHOLD) {
768
+ textParts.push(
769
+ `WARNING: ${this.consecutiveUnchangedSteps} consecutive actions had NO VISIBLE EFFECT on the UI. You MUST try a completely different approach — do not repeat any of your recent actions.`,
770
+ );
771
+ } else if (!wasWait) {
772
+ const actionDesc = `${lastAction?.toolName ?? 'unknown'}`;
773
+ textParts.push(
774
+ `Your last action (${actionDesc}) had NO VISIBLE EFFECT on the UI. The screen is identical to the previous step. Do NOT repeat the same action — try something different.`,
775
+ );
776
+ } else {
777
+ textParts.push('No visible changes detected — the UI is identical to the previous step.');
778
+ }
779
+ textParts.push('');
780
+ }
781
+
782
+ // Current screen state
783
+ if (obs.axTree) {
784
+ textParts.push('CURRENT SCREEN STATE (accessibility tree of the focused window):');
785
+ textParts.push(obs.axTree);
786
+ textParts.push('');
787
+ textParts.push('Use element_id with the [ID] numbers shown above to target elements.');
788
+
789
+ // Secondary windows for cross-app awareness
790
+ if (obs.secondaryWindows) {
791
+ textParts.push('');
792
+ textParts.push(obs.secondaryWindows);
793
+ textParts.push('');
794
+ textParts.push(
795
+ "Note: The element [ID]s above are from other windows — you can reference them for context but can only interact with the focused window's elements.",
796
+ );
797
+ }
798
+
799
+ if (obs.screenshot) {
800
+ textParts.push('');
801
+ textParts.push(
802
+ 'A screenshot of the FULL SCREEN is also attached above. Use it to see content outside the focused window (e.g., reference documents, PDFs, other apps visible behind the current window).',
803
+ );
804
+ const screenshotMetadata = this.formatScreenshotMetadata(obs);
805
+ if (screenshotMetadata.length > 0) {
806
+ textParts.push(...screenshotMetadata);
807
+ }
808
+ }
809
+ } else if (obs.screenshot) {
810
+ textParts.push('CURRENT SCREEN STATE:');
811
+ textParts.push('See the screenshot above. No accessibility tree available — estimate coordinates from the image.');
812
+ const screenshotMetadata = this.formatScreenshotMetadata(obs);
813
+ if (screenshotMetadata.length > 0) {
814
+ textParts.push(...screenshotMetadata);
815
+ }
816
+ } else {
817
+ textParts.push('CURRENT SCREEN STATE:');
818
+ textParts.push('No screen data available.');
819
+ }
820
+
821
+ // Action history
822
+ if (this.actionHistory.length > 0) {
823
+ textParts.push('');
824
+ textParts.push('ACTIONS TAKEN SO FAR:');
825
+ let windowedHistory: ActionRecord[];
826
+ if (this.actionHistory.length > MAX_HISTORY_ENTRIES) {
827
+ textParts.push(
828
+ ` [... ${this.actionHistory.length - MAX_HISTORY_ENTRIES} earlier actions omitted]`,
829
+ );
830
+ windowedHistory = this.actionHistory.slice(-MAX_HISTORY_ENTRIES);
831
+ } else {
832
+ windowedHistory = this.actionHistory;
833
+ }
834
+ for (const record of windowedHistory) {
835
+ const result = record.result ?? 'executed';
836
+ textParts.push(` ${record.step}. ${record.toolName} → ${result}`);
837
+ }
838
+ }
839
+
840
+ // Loop detection warning
841
+ if (this.actionHistory.length >= LOOP_DETECTION_WINDOW) {
842
+ const recent = this.actionHistory.slice(-LOOP_DETECTION_WINDOW);
843
+ const allIdentical = recent.every(
844
+ (r) =>
845
+ r.toolName === recent[0].toolName &&
846
+ JSON.stringify(r.input) === JSON.stringify(recent[0].input),
847
+ );
848
+ if (allIdentical) {
849
+ textParts.push('');
850
+ textParts.push(
851
+ `WARNING: You have repeated the exact same action (${recent[0].toolName}) ${LOOP_DETECTION_WINDOW} times in a row. You MUST try a completely different approach or call computer_use_done with an explanation of why you are stuck.`,
852
+ );
853
+ }
854
+ }
855
+
856
+ // Prompt for next action
857
+ textParts.push('');
858
+ if (this.actionHistory.length === 0) {
859
+ textParts.push('This is the first action. Examine the screen state and decide what to do first.');
860
+ } else {
861
+ textParts.push('Decide the next action to take.');
862
+ }
863
+
864
+ contentBlocks.push({
865
+ type: 'text',
866
+ text: textParts.join('\n'),
867
+ });
868
+
869
+ return [{ role: 'user', content: contentBlocks }];
870
+ }
871
+
872
+ private formatScreenshotMetadata(obs: CuObservation): string[] {
873
+ if (!obs.screenshot) return [];
874
+
875
+ const lines: string[] = [];
876
+ if (obs.screenshotWidthPx != null && obs.screenshotHeightPx != null) {
877
+ lines.push(`Screenshot metadata: ${obs.screenshotWidthPx}x${obs.screenshotHeightPx} px`);
878
+ }
879
+ if (obs.screenWidthPt != null && obs.screenHeightPt != null) {
880
+ lines.push(`Screen metadata: ${obs.screenWidthPt}x${obs.screenHeightPt} pt`);
881
+ }
882
+ if (obs.coordinateOrigin) {
883
+ lines.push(`Coordinate origin: ${obs.coordinateOrigin}`);
884
+ }
885
+ if (obs.captureDisplayId != null) {
886
+ lines.push(`Capture display ID: ${obs.captureDisplayId}`);
887
+ }
888
+ return lines;
889
+ }
890
+
891
+ hasPendingConfirmation(requestId: string): boolean {
892
+ return this.prompter?.hasPendingRequest(requestId) ?? false;
893
+ }
894
+
895
+ handleConfirmationResponse(
896
+ requestId: string,
897
+ decision: UserDecision,
898
+ selectedPattern?: string,
899
+ selectedScope?: string,
900
+ ): void {
901
+ this.prompter?.resolveConfirmation(requestId, decision, selectedPattern, selectedScope);
902
+ }
903
+ }