dotdo 0.0.1 → 0.1.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 (667) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +446 -315
  3. package/cli/README.md +238 -0
  4. package/cli/agent.ts +72 -0
  5. package/cli/bin.js +44 -0
  6. package/cli/bin.ts +38 -0
  7. package/cli/build.ts +157 -0
  8. package/cli/commands/auth/login.ts +14 -0
  9. package/cli/commands/auth/logout.ts +6 -0
  10. package/cli/commands/auth/whoami.ts +16 -0
  11. package/cli/commands/deploy-multi.ts +245 -0
  12. package/cli/commands/dev/deploy.ts +100 -0
  13. package/cli/commands/dev/dev.ts +95 -0
  14. package/cli/commands/dev/logs.ts +91 -0
  15. package/cli/commands/dev-local.ts +88 -0
  16. package/cli/commands/do-ops.ts +314 -0
  17. package/cli/commands/index.ts +100 -0
  18. package/cli/commands/init.ts +247 -0
  19. package/cli/commands/introspect/emitter.ts +315 -0
  20. package/cli/commands/introspect/index.ts +193 -0
  21. package/cli/commands/link.ts +598 -0
  22. package/cli/commands/snippets.ts +415 -0
  23. package/cli/commands/tunnel.ts +239 -0
  24. package/cli/device-auth.ts +289 -0
  25. package/cli/fallback.ts +12 -0
  26. package/cli/index.ts +121 -0
  27. package/cli/main.ts +246 -0
  28. package/cli/mcp-stdio.ts +790 -0
  29. package/cli/package.json +62 -0
  30. package/cli/runtime/do-registry.ts +193 -0
  31. package/cli/runtime/embedded-db.ts +344 -0
  32. package/cli/runtime/index.ts +9 -0
  33. package/cli/runtime/miniflare-adapter.ts +162 -0
  34. package/cli/sandbox.ts +82 -0
  35. package/cli/src/args.ts +174 -0
  36. package/cli/src/auth.ts +55 -0
  37. package/cli/src/commands/call.ts +84 -0
  38. package/cli/src/commands/charge.ts +96 -0
  39. package/cli/src/commands/config.ts +115 -0
  40. package/cli/src/commands/email.ts +112 -0
  41. package/cli/src/commands/llm.ts +115 -0
  42. package/cli/src/commands/queue.ts +134 -0
  43. package/cli/src/commands/text.ts +86 -0
  44. package/cli/src/config.ts +185 -0
  45. package/cli/src/output.ts +246 -0
  46. package/cli/src/rpc.ts +192 -0
  47. package/cli/utils/config.ts +282 -0
  48. package/cli/utils/detect.ts +73 -0
  49. package/cli/utils/index.ts +15 -0
  50. package/cli/utils/logger.ts +232 -0
  51. package/dist/ai/index.js +19 -0
  52. package/dist/ai/index.js.map +1 -0
  53. package/dist/ai/template-literals.js +852 -0
  54. package/dist/ai/template-literals.js.map +1 -0
  55. package/dist/api/middleware/auth-federation.js +573 -0
  56. package/dist/api/middleware/auth-federation.js.map +1 -0
  57. package/dist/api/middleware/auth.js +545 -0
  58. package/dist/api/middleware/auth.js.map +1 -0
  59. package/dist/db/actions.js +212 -0
  60. package/dist/db/actions.js.map +1 -0
  61. package/dist/db/auth.js +506 -0
  62. package/dist/db/auth.js.map +1 -0
  63. package/dist/db/branches.js +65 -0
  64. package/dist/db/branches.js.map +1 -0
  65. package/dist/db/clickhouse.js +1074 -0
  66. package/dist/db/clickhouse.js.map +1 -0
  67. package/dist/db/dlq.js +39 -0
  68. package/dist/db/dlq.js.map +1 -0
  69. package/dist/db/events.js +28 -0
  70. package/dist/db/events.js.map +1 -0
  71. package/dist/db/exec.js +64 -0
  72. package/dist/db/exec.js.map +1 -0
  73. package/dist/db/files.js +85 -0
  74. package/dist/db/files.js.map +1 -0
  75. package/dist/db/flags.js +24 -0
  76. package/dist/db/flags.js.map +1 -0
  77. package/dist/db/git.js +116 -0
  78. package/dist/db/git.js.map +1 -0
  79. package/dist/db/iceberg/inverted-index.js +862 -0
  80. package/dist/db/iceberg/inverted-index.js.map +1 -0
  81. package/dist/db/iceberg/puffin.js +878 -0
  82. package/dist/db/iceberg/puffin.js.map +1 -0
  83. package/dist/db/iceberg/search-manifest.js +422 -0
  84. package/dist/db/iceberg/search-manifest.js.map +1 -0
  85. package/dist/db/iceberg/types.js +8 -0
  86. package/dist/db/iceberg/types.js.map +1 -0
  87. package/dist/db/index.js +121 -0
  88. package/dist/db/index.js.map +1 -0
  89. package/dist/db/integrations.js +368 -0
  90. package/dist/db/integrations.js.map +1 -0
  91. package/dist/db/json-indexes.js +332 -0
  92. package/dist/db/json-indexes.js.map +1 -0
  93. package/dist/db/linked-accounts.js +287 -0
  94. package/dist/db/linked-accounts.js.map +1 -0
  95. package/dist/db/nouns.js +183 -0
  96. package/dist/db/nouns.js.map +1 -0
  97. package/dist/db/objects.js +170 -0
  98. package/dist/db/objects.js.map +1 -0
  99. package/dist/db/primitives/dag-scheduler/index.js +869 -0
  100. package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
  101. package/dist/db/primitives/exactly-once-context.js +237 -0
  102. package/dist/db/primitives/exactly-once-context.js.map +1 -0
  103. package/dist/db/primitives/index.js +62 -0
  104. package/dist/db/primitives/index.js.map +1 -0
  105. package/dist/db/primitives/keyed-router.js +145 -0
  106. package/dist/db/primitives/keyed-router.js.map +1 -0
  107. package/dist/db/primitives/observability.js +162 -0
  108. package/dist/db/primitives/observability.js.map +1 -0
  109. package/dist/db/primitives/schema-evolution.js +643 -0
  110. package/dist/db/primitives/schema-evolution.js.map +1 -0
  111. package/dist/db/primitives/stateful-operator/index.js +770 -0
  112. package/dist/db/primitives/stateful-operator/index.js.map +1 -0
  113. package/dist/db/primitives/temporal-store.js +306 -0
  114. package/dist/db/primitives/temporal-store.js.map +1 -0
  115. package/dist/db/primitives/typed-column-store.js +1229 -0
  116. package/dist/db/primitives/typed-column-store.js.map +1 -0
  117. package/dist/db/primitives/utils/duration.js +162 -0
  118. package/dist/db/primitives/utils/duration.js.map +1 -0
  119. package/dist/db/primitives/utils/murmur3.js +116 -0
  120. package/dist/db/primitives/utils/murmur3.js.map +1 -0
  121. package/dist/db/primitives/watermark-service.js +136 -0
  122. package/dist/db/primitives/watermark-service.js.map +1 -0
  123. package/dist/db/primitives/window-manager.js +764 -0
  124. package/dist/db/primitives/window-manager.js.map +1 -0
  125. package/dist/db/relationships.js +66 -0
  126. package/dist/db/relationships.js.map +1 -0
  127. package/dist/db/schema-minimal.js +61 -0
  128. package/dist/db/schema-minimal.js.map +1 -0
  129. package/dist/db/search.js +28 -0
  130. package/dist/db/search.js.map +1 -0
  131. package/dist/db/stores.js +1665 -0
  132. package/dist/db/stores.js.map +1 -0
  133. package/dist/db/things.js +297 -0
  134. package/dist/db/things.js.map +1 -0
  135. package/dist/db/vault.js +171 -0
  136. package/dist/db/vault.js.map +1 -0
  137. package/dist/db/verbs.js +102 -0
  138. package/dist/db/verbs.js.map +1 -0
  139. package/dist/do/base.js +48 -0
  140. package/dist/do/base.js.map +1 -0
  141. package/dist/do/tiny.js +31 -0
  142. package/dist/do/tiny.js.map +1 -0
  143. package/dist/lib/DOAuth.js +261 -0
  144. package/dist/lib/DOAuth.js.map +1 -0
  145. package/dist/lib/DODispatcher.js +72 -0
  146. package/dist/lib/DODispatcher.js.map +1 -0
  147. package/dist/lib/Modifier.js +189 -0
  148. package/dist/lib/Modifier.js.map +1 -0
  149. package/dist/lib/StateStorage.js +403 -0
  150. package/dist/lib/StateStorage.js.map +1 -0
  151. package/dist/lib/TypeRegistry.js +122 -0
  152. package/dist/lib/TypeRegistry.js.map +1 -0
  153. package/dist/lib/ai/gateway.js +247 -0
  154. package/dist/lib/ai/gateway.js.map +1 -0
  155. package/dist/lib/ai/tool-loop-agent.js +591 -0
  156. package/dist/lib/ai/tool-loop-agent.js.map +1 -0
  157. package/dist/lib/auto-wiring.js +439 -0
  158. package/dist/lib/auto-wiring.js.map +1 -0
  159. package/dist/lib/browse/browserbase.js +163 -0
  160. package/dist/lib/browse/browserbase.js.map +1 -0
  161. package/dist/lib/browse/cloudflare.js +144 -0
  162. package/dist/lib/browse/cloudflare.js.map +1 -0
  163. package/dist/lib/browse/index.js +62 -0
  164. package/dist/lib/browse/index.js.map +1 -0
  165. package/dist/lib/browse/types.js +13 -0
  166. package/dist/lib/browse/types.js.map +1 -0
  167. package/dist/lib/cache/index.js +37 -0
  168. package/dist/lib/cache/index.js.map +1 -0
  169. package/dist/lib/cache/visibility.js +638 -0
  170. package/dist/lib/cache/visibility.js.map +1 -0
  171. package/dist/lib/capabilities.js +268 -0
  172. package/dist/lib/capabilities.js.map +1 -0
  173. package/dist/lib/channels/base.js +106 -0
  174. package/dist/lib/channels/base.js.map +1 -0
  175. package/dist/lib/channels/discord.js +94 -0
  176. package/dist/lib/channels/discord.js.map +1 -0
  177. package/dist/lib/channels/email.js +204 -0
  178. package/dist/lib/channels/email.js.map +1 -0
  179. package/dist/lib/channels/index.js +90 -0
  180. package/dist/lib/channels/index.js.map +1 -0
  181. package/dist/lib/channels/mdxui-chat.js +95 -0
  182. package/dist/lib/channels/mdxui-chat.js.map +1 -0
  183. package/dist/lib/channels/slack-blockkit.js +121 -0
  184. package/dist/lib/channels/slack-blockkit.js.map +1 -0
  185. package/dist/lib/channels/types.js +7 -0
  186. package/dist/lib/channels/types.js.map +1 -0
  187. package/dist/lib/cloudflare/ai.js +654 -0
  188. package/dist/lib/cloudflare/ai.js.map +1 -0
  189. package/dist/lib/cloudflare/index.js +88 -0
  190. package/dist/lib/cloudflare/index.js.map +1 -0
  191. package/dist/lib/cloudflare/kv.js +342 -0
  192. package/dist/lib/cloudflare/kv.js.map +1 -0
  193. package/dist/lib/cloudflare/queues.js +434 -0
  194. package/dist/lib/cloudflare/queues.js.map +1 -0
  195. package/dist/lib/cloudflare/r2.js +604 -0
  196. package/dist/lib/cloudflare/r2.js.map +1 -0
  197. package/dist/lib/cloudflare/vectorize.js +494 -0
  198. package/dist/lib/cloudflare/vectorize.js.map +1 -0
  199. package/dist/lib/cloudflare/workflows.js +569 -0
  200. package/dist/lib/cloudflare/workflows.js.map +1 -0
  201. package/dist/lib/colo/caching.js +196 -0
  202. package/dist/lib/colo/caching.js.map +1 -0
  203. package/dist/lib/colo/detection.js +194 -0
  204. package/dist/lib/colo/detection.js.map +1 -0
  205. package/dist/lib/colo/external-data.js +219 -0
  206. package/dist/lib/colo/external-data.js.map +1 -0
  207. package/dist/lib/colo/globe-data.js +179 -0
  208. package/dist/lib/colo/globe-data.js.map +1 -0
  209. package/dist/lib/colo/index.js +16 -0
  210. package/dist/lib/colo/index.js.map +1 -0
  211. package/dist/lib/decorators.js +37 -0
  212. package/dist/lib/decorators.js.map +1 -0
  213. package/dist/lib/discovery.js +81 -0
  214. package/dist/lib/discovery.js.map +1 -0
  215. package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
  216. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
  217. package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
  218. package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
  219. package/dist/lib/executors/CascadeExecutor.js +418 -0
  220. package/dist/lib/executors/CascadeExecutor.js.map +1 -0
  221. package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
  222. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
  223. package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
  224. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
  225. package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
  226. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
  227. package/dist/lib/executors/ParallelStepExecutor.js +308 -0
  228. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
  229. package/dist/lib/executors/types.js +12 -0
  230. package/dist/lib/executors/types.js.map +1 -0
  231. package/dist/lib/experiments.js +89 -0
  232. package/dist/lib/experiments.js.map +1 -0
  233. package/dist/lib/flags/store.js +262 -0
  234. package/dist/lib/flags/store.js.map +1 -0
  235. package/dist/lib/functions/FunctionComposition.js +467 -0
  236. package/dist/lib/functions/FunctionComposition.js.map +1 -0
  237. package/dist/lib/functions/FunctionMiddleware.js +457 -0
  238. package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
  239. package/dist/lib/functions/FunctionRegistry.js +426 -0
  240. package/dist/lib/functions/FunctionRegistry.js.map +1 -0
  241. package/dist/lib/functions/createFunction.js +1048 -0
  242. package/dist/lib/functions/createFunction.js.map +1 -0
  243. package/dist/lib/humans/index.js +68 -0
  244. package/dist/lib/humans/index.js.map +1 -0
  245. package/dist/lib/humans/templates.js +117 -0
  246. package/dist/lib/humans/templates.js.map +1 -0
  247. package/dist/lib/identity.js +98 -0
  248. package/dist/lib/identity.js.map +1 -0
  249. package/dist/lib/index.js +9 -0
  250. package/dist/lib/index.js.map +1 -0
  251. package/dist/lib/logging/error-logger.js +163 -0
  252. package/dist/lib/logging/error-logger.js.map +1 -0
  253. package/dist/lib/logging/index.js +160 -0
  254. package/dist/lib/logging/index.js.map +1 -0
  255. package/dist/lib/mixins/bash.js +753 -0
  256. package/dist/lib/mixins/bash.js.map +1 -0
  257. package/dist/lib/mixins/fs.js +648 -0
  258. package/dist/lib/mixins/fs.js.map +1 -0
  259. package/dist/lib/mixins/git.js +1006 -0
  260. package/dist/lib/mixins/git.js.map +1 -0
  261. package/dist/lib/mixins/npm.js +662 -0
  262. package/dist/lib/mixins/npm.js.map +1 -0
  263. package/dist/lib/noun-id.js +278 -0
  264. package/dist/lib/noun-id.js.map +1 -0
  265. package/dist/lib/rate-limit/sliding-window.js +148 -0
  266. package/dist/lib/rate-limit/sliding-window.js.map +1 -0
  267. package/dist/lib/rate-limit.js +110 -0
  268. package/dist/lib/rate-limit.js.map +1 -0
  269. package/dist/lib/rpc/bindings.js +548 -0
  270. package/dist/lib/rpc/bindings.js.map +1 -0
  271. package/dist/lib/rpc/index.js +64 -0
  272. package/dist/lib/rpc/index.js.map +1 -0
  273. package/dist/lib/safe-stringify.js +223 -0
  274. package/dist/lib/safe-stringify.js.map +1 -0
  275. package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
  276. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
  277. package/dist/lib/sqids.js +110 -0
  278. package/dist/lib/sqids.js.map +1 -0
  279. package/dist/lib/sql/adapters/index.js +10 -0
  280. package/dist/lib/sql/adapters/index.js.map +1 -0
  281. package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
  282. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
  283. package/dist/lib/sql/adapters/pgsql-parser.js +1190 -0
  284. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
  285. package/dist/lib/sql/index.js +277 -0
  286. package/dist/lib/sql/index.js.map +1 -0
  287. package/dist/lib/sql/types.js +56 -0
  288. package/dist/lib/sql/types.js.map +1 -0
  289. package/dist/lib/type-classifier.js +126 -0
  290. package/dist/lib/type-classifier.js.map +1 -0
  291. package/dist/lib/utils/html.js +47 -0
  292. package/dist/lib/utils/html.js.map +1 -0
  293. package/dist/lib/validation.js +48 -0
  294. package/dist/lib/validation.js.map +1 -0
  295. package/dist/lib/vault/store.js +411 -0
  296. package/dist/lib/vault/store.js.map +1 -0
  297. package/dist/metrics/hunch.js +739 -0
  298. package/dist/metrics/hunch.js.map +1 -0
  299. package/dist/objects/API.js +302 -0
  300. package/dist/objects/API.js.map +1 -0
  301. package/dist/objects/Agent.js +179 -0
  302. package/dist/objects/Agent.js.map +1 -0
  303. package/dist/objects/AgenticFunctionExecutor.js +8 -0
  304. package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
  305. package/dist/objects/App.js +83 -0
  306. package/dist/objects/App.js.map +1 -0
  307. package/dist/objects/Browser.js +884 -0
  308. package/dist/objects/Browser.js.map +1 -0
  309. package/dist/objects/Business.js +107 -0
  310. package/dist/objects/Business.js.map +1 -0
  311. package/dist/objects/CLI.js +221 -0
  312. package/dist/objects/CLI.js.map +1 -0
  313. package/dist/objects/CodeFunctionExecutor.js +8 -0
  314. package/dist/objects/CodeFunctionExecutor.js.map +1 -0
  315. package/dist/objects/Collection.js +161 -0
  316. package/dist/objects/Collection.js.map +1 -0
  317. package/dist/objects/DO.js +41 -0
  318. package/dist/objects/DO.js.map +1 -0
  319. package/dist/objects/DOBase.js +2309 -0
  320. package/dist/objects/DOBase.js.map +1 -0
  321. package/dist/objects/DOCache.js +153 -0
  322. package/dist/objects/DOCache.js.map +1 -0
  323. package/dist/objects/DOFull.js +1676 -0
  324. package/dist/objects/DOFull.js.map +1 -0
  325. package/dist/objects/DOTiny.js +207 -0
  326. package/dist/objects/DOTiny.js.map +1 -0
  327. package/dist/objects/Directory.js +199 -0
  328. package/dist/objects/Directory.js.map +1 -0
  329. package/dist/objects/Entity.js +413 -0
  330. package/dist/objects/Entity.js.map +1 -0
  331. package/dist/objects/Function.js +116 -0
  332. package/dist/objects/Function.js.map +1 -0
  333. package/dist/objects/Human.js +231 -0
  334. package/dist/objects/Human.js.map +1 -0
  335. package/dist/objects/HumanFunctionExecutor.js +8 -0
  336. package/dist/objects/HumanFunctionExecutor.js.map +1 -0
  337. package/dist/objects/IcebergMetadataDO.js +938 -0
  338. package/dist/objects/IcebergMetadataDO.js.map +1 -0
  339. package/dist/objects/IntegrationsDO.js +1174 -0
  340. package/dist/objects/IntegrationsDO.js.map +1 -0
  341. package/dist/objects/ObservabilityBroadcaster.js +149 -0
  342. package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
  343. package/dist/objects/Package.js +154 -0
  344. package/dist/objects/Package.js.map +1 -0
  345. package/dist/objects/Product.js +193 -0
  346. package/dist/objects/Product.js.map +1 -0
  347. package/dist/objects/SDK.js +152 -0
  348. package/dist/objects/SDK.js.map +1 -0
  349. package/dist/objects/SaaS.js +235 -0
  350. package/dist/objects/SaaS.js.map +1 -0
  351. package/dist/objects/SandboxDO.js +759 -0
  352. package/dist/objects/SandboxDO.js.map +1 -0
  353. package/dist/objects/Service.js +337 -0
  354. package/dist/objects/Service.js.map +1 -0
  355. package/dist/objects/Site.js +80 -0
  356. package/dist/objects/Site.js.map +1 -0
  357. package/dist/objects/Startup.js +479 -0
  358. package/dist/objects/Startup.js.map +1 -0
  359. package/dist/objects/ThingsDO.js +170 -0
  360. package/dist/objects/ThingsDO.js.map +1 -0
  361. package/dist/objects/VectorShardDO.js +650 -0
  362. package/dist/objects/VectorShardDO.js.map +1 -0
  363. package/dist/objects/Worker.js +144 -0
  364. package/dist/objects/Worker.js.map +1 -0
  365. package/dist/objects/Workflow.js +196 -0
  366. package/dist/objects/Workflow.js.map +1 -0
  367. package/dist/objects/WorkflowFactory.js +313 -0
  368. package/dist/objects/WorkflowFactory.js.map +1 -0
  369. package/dist/objects/WorkflowRuntime.js +863 -0
  370. package/dist/objects/WorkflowRuntime.js.map +1 -0
  371. package/dist/objects/circuit-breaker-bulkhead.js +178 -0
  372. package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
  373. package/dist/objects/createFunction.js +934 -0
  374. package/dist/objects/createFunction.js.map +1 -0
  375. package/dist/objects/index.js +80 -0
  376. package/dist/objects/index.js.map +1 -0
  377. package/dist/objects/lifecycle/Branch.js +275 -0
  378. package/dist/objects/lifecycle/Branch.js.map +1 -0
  379. package/dist/objects/lifecycle/Clone.js +1499 -0
  380. package/dist/objects/lifecycle/Clone.js.map +1 -0
  381. package/dist/objects/lifecycle/Compact.js +237 -0
  382. package/dist/objects/lifecycle/Compact.js.map +1 -0
  383. package/dist/objects/lifecycle/Promote.js +476 -0
  384. package/dist/objects/lifecycle/Promote.js.map +1 -0
  385. package/dist/objects/lifecycle/Shard.js +560 -0
  386. package/dist/objects/lifecycle/Shard.js.map +1 -0
  387. package/dist/objects/lifecycle/index.js +15 -0
  388. package/dist/objects/lifecycle/index.js.map +1 -0
  389. package/dist/objects/lifecycle/types.js +33 -0
  390. package/dist/objects/lifecycle/types.js.map +1 -0
  391. package/dist/objects/mixins/infrastructure.js +171 -0
  392. package/dist/objects/mixins/infrastructure.js.map +1 -0
  393. package/dist/objects/modules/StoresModule.js +153 -0
  394. package/dist/objects/modules/StoresModule.js.map +1 -0
  395. package/dist/objects/persistence/checkpoint-manager.js +606 -0
  396. package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
  397. package/dist/objects/persistence/index.js +72 -0
  398. package/dist/objects/persistence/index.js.map +1 -0
  399. package/dist/objects/persistence/migration-runner.js +562 -0
  400. package/dist/objects/persistence/migration-runner.js.map +1 -0
  401. package/dist/objects/persistence/replication-manager.js +501 -0
  402. package/dist/objects/persistence/replication-manager.js.map +1 -0
  403. package/dist/objects/persistence/tiered-storage-manager.js +595 -0
  404. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
  405. package/dist/objects/persistence/types.js +14 -0
  406. package/dist/objects/persistence/types.js.map +1 -0
  407. package/dist/objects/persistence/wal-manager.js +653 -0
  408. package/dist/objects/persistence/wal-manager.js.map +1 -0
  409. package/dist/objects/presets/index.js +20 -0
  410. package/dist/objects/presets/index.js.map +1 -0
  411. package/dist/objects/presets/primitives.js +188 -0
  412. package/dist/objects/presets/primitives.js.map +1 -0
  413. package/dist/objects/primitives/alarm-adapter.js +141 -0
  414. package/dist/objects/primitives/alarm-adapter.js.map +1 -0
  415. package/dist/objects/primitives/index.js +337 -0
  416. package/dist/objects/primitives/index.js.map +1 -0
  417. package/dist/objects/primitives/storage-adapter.js +182 -0
  418. package/dist/objects/primitives/storage-adapter.js.map +1 -0
  419. package/dist/objects/primitives/with-primitives.js +102 -0
  420. package/dist/objects/primitives/with-primitives.js.map +1 -0
  421. package/dist/objects/services/StoreManager.js +227 -0
  422. package/dist/objects/services/StoreManager.js.map +1 -0
  423. package/dist/objects/services/index.js +13 -0
  424. package/dist/objects/services/index.js.map +1 -0
  425. package/dist/objects/transport/auth-layer.js +1451 -0
  426. package/dist/objects/transport/auth-layer.js.map +1 -0
  427. package/dist/objects/transport/capnweb-target.js +355 -0
  428. package/dist/objects/transport/capnweb-target.js.map +1 -0
  429. package/dist/objects/transport/chain.js +441 -0
  430. package/dist/objects/transport/chain.js.map +1 -0
  431. package/dist/objects/transport/handler.js +58 -0
  432. package/dist/objects/transport/handler.js.map +1 -0
  433. package/dist/objects/transport/index.js +53 -0
  434. package/dist/objects/transport/index.js.map +1 -0
  435. package/dist/objects/transport/mcp-server.js +691 -0
  436. package/dist/objects/transport/mcp-server.js.map +1 -0
  437. package/dist/objects/transport/rest-autowire.js +1508 -0
  438. package/dist/objects/transport/rest-autowire.js.map +1 -0
  439. package/dist/objects/transport/rest-router.js +440 -0
  440. package/dist/objects/transport/rest-router.js.map +1 -0
  441. package/dist/objects/transport/rpc-server.js +1539 -0
  442. package/dist/objects/transport/rpc-server.js.map +1 -0
  443. package/dist/objects/transport/shared.js +576 -0
  444. package/dist/objects/transport/shared.js.map +1 -0
  445. package/dist/objects/transport/sync-engine.js +291 -0
  446. package/dist/objects/transport/sync-engine.js.map +1 -0
  447. package/dist/objects/transport/types.js +8 -0
  448. package/dist/objects/transport/types.js.map +1 -0
  449. package/dist/sandbox/index.js +258 -0
  450. package/dist/sandbox/index.js.map +1 -0
  451. package/dist/snippets/artifacts-config.js +241 -0
  452. package/dist/snippets/artifacts-config.js.map +1 -0
  453. package/dist/snippets/artifacts-ingest.js +832 -0
  454. package/dist/snippets/artifacts-ingest.js.map +1 -0
  455. package/dist/snippets/artifacts-serve.js +1035 -0
  456. package/dist/snippets/artifacts-serve.js.map +1 -0
  457. package/dist/snippets/artifacts-types.js +161 -0
  458. package/dist/snippets/artifacts-types.js.map +1 -0
  459. package/dist/snippets/cache-probe.js +376 -0
  460. package/dist/snippets/cache-probe.js.map +1 -0
  461. package/dist/snippets/cache.js +10 -0
  462. package/dist/snippets/cache.js.map +1 -0
  463. package/dist/snippets/events.js +469 -0
  464. package/dist/snippets/events.js.map +1 -0
  465. package/dist/snippets/index.js +7 -0
  466. package/dist/snippets/index.js.map +1 -0
  467. package/dist/snippets/proxy.js +495 -0
  468. package/dist/snippets/proxy.js.map +1 -0
  469. package/dist/snippets/search.js +1759 -0
  470. package/dist/snippets/search.js.map +1 -0
  471. package/dist/streams/index.js +30 -0
  472. package/dist/streams/index.js.map +1 -0
  473. package/dist/streams/observability.js +68 -0
  474. package/dist/streams/observability.js.map +1 -0
  475. package/dist/types/AI.js +92 -0
  476. package/dist/types/AI.js.map +1 -0
  477. package/dist/types/AIFunction.js +171 -0
  478. package/dist/types/AIFunction.js.map +1 -0
  479. package/dist/types/BrowseVerb.js +89 -0
  480. package/dist/types/BrowseVerb.js.map +1 -0
  481. package/dist/types/Browser.js +31 -0
  482. package/dist/types/Browser.js.map +1 -0
  483. package/dist/types/Chaos.js +15 -0
  484. package/dist/types/Chaos.js.map +1 -0
  485. package/dist/types/CloudflareBindings.js +109 -0
  486. package/dist/types/CloudflareBindings.js.map +1 -0
  487. package/dist/types/Collection.js +50 -0
  488. package/dist/types/Collection.js.map +1 -0
  489. package/dist/types/DO.js +2 -0
  490. package/dist/types/DO.js.map +1 -0
  491. package/dist/types/DOLocation.js +63 -0
  492. package/dist/types/DOLocation.js.map +1 -0
  493. package/dist/types/EventHandler.js +57 -0
  494. package/dist/types/EventHandler.js.map +1 -0
  495. package/dist/types/Experiment.js +33 -0
  496. package/dist/types/Experiment.js.map +1 -0
  497. package/dist/types/Flag.js +57 -0
  498. package/dist/types/Flag.js.map +1 -0
  499. package/dist/types/Lifecycle.js +13 -0
  500. package/dist/types/Lifecycle.js.map +1 -0
  501. package/dist/types/Location.js +169 -0
  502. package/dist/types/Location.js.map +1 -0
  503. package/dist/types/Noun.js +66 -0
  504. package/dist/types/Noun.js.map +1 -0
  505. package/dist/types/SessionEvent.js +194 -0
  506. package/dist/types/SessionEvent.js.map +1 -0
  507. package/dist/types/Thing.js +55 -0
  508. package/dist/types/Thing.js.map +1 -0
  509. package/dist/types/ThingDO.js +153 -0
  510. package/dist/types/ThingDO.js.map +1 -0
  511. package/dist/types/Things.js +2 -0
  512. package/dist/types/Things.js.map +1 -0
  513. package/dist/types/Verb.js +119 -0
  514. package/dist/types/Verb.js.map +1 -0
  515. package/dist/types/WorkflowContext.js +70 -0
  516. package/dist/types/WorkflowContext.js.map +1 -0
  517. package/dist/types/analytics-api.js +13 -0
  518. package/dist/types/analytics-api.js.map +1 -0
  519. package/dist/types/capabilities.js +135 -0
  520. package/dist/types/capabilities.js.map +1 -0
  521. package/dist/types/drizzle.js +12 -0
  522. package/dist/types/drizzle.js.map +1 -0
  523. package/dist/types/event.js +201 -0
  524. package/dist/types/event.js.map +1 -0
  525. package/dist/types/fn.js +12 -0
  526. package/dist/types/fn.js.map +1 -0
  527. package/dist/types/iceberg.js +48 -0
  528. package/dist/types/iceberg.js.map +1 -0
  529. package/dist/types/ids.js +170 -0
  530. package/dist/types/ids.js.map +1 -0
  531. package/dist/types/index.js +41 -0
  532. package/dist/types/index.js.map +1 -0
  533. package/dist/types/introspect.js +54 -0
  534. package/dist/types/introspect.js.map +1 -0
  535. package/dist/types/observability.js +124 -0
  536. package/dist/types/observability.js.map +1 -0
  537. package/dist/types/sync-protocol.js +175 -0
  538. package/dist/types/sync-protocol.js.map +1 -0
  539. package/dist/types/vector.js +13 -0
  540. package/dist/types/vector.js.map +1 -0
  541. package/dist/workflows/ScheduleManager.js +473 -0
  542. package/dist/workflows/ScheduleManager.js.map +1 -0
  543. package/dist/workflows/StepDOBridge.js +149 -0
  544. package/dist/workflows/StepDOBridge.js.map +1 -0
  545. package/dist/workflows/StepResultStorage.js +232 -0
  546. package/dist/workflows/StepResultStorage.js.map +1 -0
  547. package/dist/workflows/WaitForEventManager.js +461 -0
  548. package/dist/workflows/WaitForEventManager.js.map +1 -0
  549. package/dist/workflows/analyzer.js +332 -0
  550. package/dist/workflows/analyzer.js.map +1 -0
  551. package/dist/workflows/compat/activity-router.js +484 -0
  552. package/dist/workflows/compat/activity-router.js.map +1 -0
  553. package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
  554. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
  555. package/dist/workflows/compat/backends/index.js +14 -0
  556. package/dist/workflows/compat/backends/index.js.map +1 -0
  557. package/dist/workflows/compat/errors/index.js +375 -0
  558. package/dist/workflows/compat/errors/index.js.map +1 -0
  559. package/dist/workflows/compat/index.js +79 -0
  560. package/dist/workflows/compat/index.js.map +1 -0
  561. package/dist/workflows/compat/inngest/index.js +989 -0
  562. package/dist/workflows/compat/inngest/index.js.map +1 -0
  563. package/dist/workflows/compat/qstash/index.js +1263 -0
  564. package/dist/workflows/compat/qstash/index.js.map +1 -0
  565. package/dist/workflows/compat/temporal/activities.js +739 -0
  566. package/dist/workflows/compat/temporal/activities.js.map +1 -0
  567. package/dist/workflows/compat/temporal/child-workflows.js +154 -0
  568. package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
  569. package/dist/workflows/compat/temporal/client.js +381 -0
  570. package/dist/workflows/compat/temporal/client.js.map +1 -0
  571. package/dist/workflows/compat/temporal/context.js +309 -0
  572. package/dist/workflows/compat/temporal/context.js.map +1 -0
  573. package/dist/workflows/compat/temporal/determinism.js +216 -0
  574. package/dist/workflows/compat/temporal/determinism.js.map +1 -0
  575. package/dist/workflows/compat/temporal/errors.js +128 -0
  576. package/dist/workflows/compat/temporal/errors.js.map +1 -0
  577. package/dist/workflows/compat/temporal/index.js +2464 -0
  578. package/dist/workflows/compat/temporal/index.js.map +1 -0
  579. package/dist/workflows/compat/temporal/saga.js +504 -0
  580. package/dist/workflows/compat/temporal/saga.js.map +1 -0
  581. package/dist/workflows/compat/temporal/signals.js +364 -0
  582. package/dist/workflows/compat/temporal/signals.js.map +1 -0
  583. package/dist/workflows/compat/temporal/storage.js +271 -0
  584. package/dist/workflows/compat/temporal/storage.js.map +1 -0
  585. package/dist/workflows/compat/temporal/timers.js +347 -0
  586. package/dist/workflows/compat/temporal/timers.js.map +1 -0
  587. package/dist/workflows/compat/temporal/types.js +7 -0
  588. package/dist/workflows/compat/temporal/types.js.map +1 -0
  589. package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
  590. package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
  591. package/dist/workflows/compat/trigger/index.js +468 -0
  592. package/dist/workflows/compat/trigger/index.js.map +1 -0
  593. package/dist/workflows/compat/utils/index.js +69 -0
  594. package/dist/workflows/compat/utils/index.js.map +1 -0
  595. package/dist/workflows/context/correlation-capability.js +266 -0
  596. package/dist/workflows/context/correlation-capability.js.map +1 -0
  597. package/dist/workflows/context/correlation.js +484 -0
  598. package/dist/workflows/context/correlation.js.map +1 -0
  599. package/dist/workflows/context/experiment.js +289 -0
  600. package/dist/workflows/context/experiment.js.map +1 -0
  601. package/dist/workflows/context/flag.js +244 -0
  602. package/dist/workflows/context/flag.js.map +1 -0
  603. package/dist/workflows/context/foundation.js +648 -0
  604. package/dist/workflows/context/foundation.js.map +1 -0
  605. package/dist/workflows/context/human-base.js +106 -0
  606. package/dist/workflows/context/human-base.js.map +1 -0
  607. package/dist/workflows/context/human.js +368 -0
  608. package/dist/workflows/context/human.js.map +1 -0
  609. package/dist/workflows/context/measure.js +354 -0
  610. package/dist/workflows/context/measure.js.map +1 -0
  611. package/dist/workflows/context/rate-limit.js +358 -0
  612. package/dist/workflows/context/rate-limit.js.map +1 -0
  613. package/dist/workflows/context/user.js +117 -0
  614. package/dist/workflows/context/user.js.map +1 -0
  615. package/dist/workflows/context/vault.js +360 -0
  616. package/dist/workflows/context/vault.js.map +1 -0
  617. package/dist/workflows/data/entity-events/entity-events.js +489 -0
  618. package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
  619. package/dist/workflows/data/experiment/index.js +599 -0
  620. package/dist/workflows/data/experiment/index.js.map +1 -0
  621. package/dist/workflows/data/goal/context.js +558 -0
  622. package/dist/workflows/data/goal/context.js.map +1 -0
  623. package/dist/workflows/data/goal/index.js +32 -0
  624. package/dist/workflows/data/goal/index.js.map +1 -0
  625. package/dist/workflows/data/measure/index.js +840 -0
  626. package/dist/workflows/data/measure/index.js.map +1 -0
  627. package/dist/workflows/data/stream/index.js +1149 -0
  628. package/dist/workflows/data/stream/index.js.map +1 -0
  629. package/dist/workflows/data/track/context.js +883 -0
  630. package/dist/workflows/data/track/context.js.map +1 -0
  631. package/dist/workflows/data/track/index.js +15 -0
  632. package/dist/workflows/data/track/index.js.map +1 -0
  633. package/dist/workflows/data/view/context.js +864 -0
  634. package/dist/workflows/data/view/context.js.map +1 -0
  635. package/dist/workflows/domain.js +93 -0
  636. package/dist/workflows/domain.js.map +1 -0
  637. package/dist/workflows/flag.js +176 -0
  638. package/dist/workflows/flag.js.map +1 -0
  639. package/dist/workflows/flags.js +217 -0
  640. package/dist/workflows/flags.js.map +1 -0
  641. package/dist/workflows/hash.js +209 -0
  642. package/dist/workflows/hash.js.map +1 -0
  643. package/dist/workflows/index.js +50 -0
  644. package/dist/workflows/index.js.map +1 -0
  645. package/dist/workflows/on.js +378 -0
  646. package/dist/workflows/on.js.map +1 -0
  647. package/dist/workflows/pipeline-promise.js +481 -0
  648. package/dist/workflows/pipeline-promise.js.map +1 -0
  649. package/dist/workflows/pipeline-types.js +20 -0
  650. package/dist/workflows/pipeline-types.js.map +1 -0
  651. package/dist/workflows/proxy.js +76 -0
  652. package/dist/workflows/proxy.js.map +1 -0
  653. package/dist/workflows/runtime.js +310 -0
  654. package/dist/workflows/runtime.js.map +1 -0
  655. package/dist/workflows/schedule-builder.js +327 -0
  656. package/dist/workflows/schedule-builder.js.map +1 -0
  657. package/dist/workflows/visibility/index.js +146 -0
  658. package/dist/workflows/visibility/index.js.map +1 -0
  659. package/dist/workflows/visibility/query-parser.js +150 -0
  660. package/dist/workflows/visibility/query-parser.js.map +1 -0
  661. package/dist/workflows/visibility/store.js +223 -0
  662. package/dist/workflows/visibility/store.js.map +1 -0
  663. package/dist/workflows/visibility/types.js +30 -0
  664. package/dist/workflows/visibility/types.js.map +1 -0
  665. package/dist/workflows/workflow.js +53 -0
  666. package/dist/workflows/workflow.js.map +1 -0
  667. package/package.json +294 -46
@@ -0,0 +1,759 @@
1
+ /**
2
+ * SandboxDO - Durable Object for code execution sandboxes
3
+ *
4
+ * Provides HTTP routes for interacting with Cloudflare Sandbox:
5
+ * - POST /create - Create sandbox session
6
+ * - POST /exec - Execute command
7
+ * - POST /exec/stream - Execute command with SSE streaming
8
+ * - POST /file/write - Write file
9
+ * - GET /file/read - Read file
10
+ * - POST /port/expose - Expose port
11
+ * - GET /ports - List exposed ports
12
+ * - GET /state - Get session state
13
+ * - POST /destroy - Destroy sandbox
14
+ * - GET /terminal - WebSocket terminal upgrade
15
+ *
16
+ * Terminal WebSocket Protocol:
17
+ * Client -> Server:
18
+ * { type: 'input', data: string } - Send input to stdin
19
+ * { type: 'resize', cols: number, rows: number } - Resize terminal
20
+ * { type: 'execute', command: string } - Execute command
21
+ * Server -> Client:
22
+ * { type: 'output', data: string } - stdout output
23
+ * { type: 'error', data: string } - stderr output (with ANSI codes)
24
+ * { type: 'exit', code: number } - Process exit
25
+ * { type: 'connected', sessionId: string } - Connection established
26
+ */
27
+ import { Hono } from 'hono';
28
+ import { DO } from './DO';
29
+ import { getSandbox, } from '../sandbox';
30
+ // ============================================================================
31
+ // Ring Buffer for Output Preservation (64KB max)
32
+ // ============================================================================
33
+ /**
34
+ * Ring buffer that preserves last 64KB of output for reconnection
35
+ */
36
+ class RingBuffer {
37
+ buffer = [];
38
+ totalSize = 0;
39
+ maxSize;
40
+ constructor(maxSize = 64 * 1024) {
41
+ this.maxSize = maxSize;
42
+ }
43
+ push(data) {
44
+ this.buffer.push(data);
45
+ this.totalSize += data.length;
46
+ // Evict oldest entries if over size limit
47
+ while (this.totalSize > this.maxSize && this.buffer.length > 0) {
48
+ const removed = this.buffer.shift();
49
+ this.totalSize -= removed.length;
50
+ }
51
+ }
52
+ getAll() {
53
+ return this.buffer.join('');
54
+ }
55
+ clear() {
56
+ this.buffer = [];
57
+ this.totalSize = 0;
58
+ }
59
+ get size() {
60
+ return this.totalSize;
61
+ }
62
+ }
63
+ // ============================================================================
64
+ // SandboxDO Class
65
+ // ============================================================================
66
+ export class SandboxDO extends DO {
67
+ static $type = 'Sandbox';
68
+ sandbox = null;
69
+ legacySessionId = null;
70
+ legacyCreatedAt = null;
71
+ legacySessionStatus = 'idle';
72
+ // New session state for lifecycle API
73
+ session = null;
74
+ // Terminal WebSocket state
75
+ terminalSessions = new Map();
76
+ app;
77
+ constructor(ctx, env) {
78
+ super(ctx, env);
79
+ this.app = this.createRoutes();
80
+ // Load persisted session on construction
81
+ this.loadSession();
82
+ }
83
+ // --------------------------------------------------------------------------
84
+ // New Session Lifecycle API (TDD)
85
+ // --------------------------------------------------------------------------
86
+ /**
87
+ * Create a new sandbox session
88
+ */
89
+ async create(options) {
90
+ // Check if Sandbox namespace is configured
91
+ if (!this.env.Sandbox) {
92
+ throw new Error('Sandbox namespace not configured');
93
+ }
94
+ // Check if session already exists
95
+ if (this.session && this.session.status !== 'stopped') {
96
+ throw new Error('Session already exists');
97
+ }
98
+ const { sandboxId, config = {} } = options;
99
+ const now = new Date();
100
+ // Create the underlying sandbox
101
+ this.sandbox = getSandbox(this.env.Sandbox, sandboxId, 'sandbox.do', {
102
+ sleepAfter: config.sleepAfter ?? '10m',
103
+ keepAlive: config.keepAlive ?? false,
104
+ normalizeId: config.normalizeId ?? true,
105
+ });
106
+ // Create session state
107
+ this.session = {
108
+ status: 'running',
109
+ sandboxId,
110
+ config,
111
+ createdAt: now,
112
+ lastActivityAt: now,
113
+ };
114
+ // Update legacy fields for backward compatibility
115
+ this.legacySessionId = sandboxId;
116
+ this.legacyCreatedAt = now.toISOString();
117
+ this.legacySessionStatus = 'running';
118
+ // Persist to storage
119
+ await this.persistSession();
120
+ // Schedule timeout alarm if configured
121
+ if (config.timeoutMs) {
122
+ await this.scheduleTimeout(config.timeoutMs);
123
+ }
124
+ // Emit lifecycle event
125
+ await this.emitEvent('sandbox.created', {
126
+ sandboxId,
127
+ config,
128
+ });
129
+ return this.session;
130
+ }
131
+ /**
132
+ * Destroy the sandbox session
133
+ */
134
+ async destroy() {
135
+ if (!this.session || !this.sandbox) {
136
+ throw new Error('No active session');
137
+ }
138
+ const { sandboxId } = this.session;
139
+ // Destroy the underlying sandbox
140
+ await this.sandbox.destroy();
141
+ // Update session status
142
+ this.session.status = 'stopped';
143
+ // Emit lifecycle event
144
+ await this.emitEvent('sandbox.destroyed', { sandboxId });
145
+ // Clear session from storage
146
+ await this.ctx.storage.delete('session');
147
+ // Cancel any scheduled alarms
148
+ await this.ctx.storage.deleteAlarm();
149
+ // Clear in-memory state
150
+ this.session = null;
151
+ this.sandbox = null;
152
+ this.legacySessionId = null;
153
+ this.legacySessionStatus = 'stopped';
154
+ }
155
+ /**
156
+ * Get the current session state
157
+ */
158
+ async getState() {
159
+ // Try to load from storage if not in memory
160
+ if (!this.session) {
161
+ await this.loadSession();
162
+ }
163
+ return this.session;
164
+ }
165
+ /**
166
+ * Execute a command in the sandbox
167
+ */
168
+ async exec(command) {
169
+ if (!this.session || !this.sandbox) {
170
+ throw new Error('No active session');
171
+ }
172
+ try {
173
+ // Execute the command
174
+ const result = await this.sandbox.exec(command);
175
+ // Update activity timestamp
176
+ await this.updateActivity();
177
+ return result;
178
+ }
179
+ catch (error) {
180
+ // Update session to error state
181
+ this.session.status = 'error';
182
+ this.session.error = error instanceof Error ? error.message : 'Unknown error';
183
+ await this.persistSession();
184
+ // Emit error event
185
+ await this.emitEvent('sandbox.error', {
186
+ sandboxId: this.session.sandboxId,
187
+ error: this.session.error,
188
+ });
189
+ throw error;
190
+ }
191
+ }
192
+ /**
193
+ * Handle DO alarm - checks for session timeout
194
+ */
195
+ async alarm() {
196
+ // Call parent alarm handler first
197
+ await super.alarm();
198
+ if (!this.session) {
199
+ return;
200
+ }
201
+ const config = this.session.config;
202
+ const timeoutMs = config.timeoutMs;
203
+ if (!timeoutMs) {
204
+ return;
205
+ }
206
+ // Check if session has timed out
207
+ const now = Date.now();
208
+ const lastActivity = new Date(this.session.lastActivityAt).getTime();
209
+ const elapsed = now - lastActivity;
210
+ if (elapsed >= timeoutMs) {
211
+ // Session has timed out - emit event and destroy
212
+ await this.emitEvent('sandbox.timeout', {
213
+ sandboxId: this.session.sandboxId,
214
+ elapsed,
215
+ timeoutMs,
216
+ });
217
+ await this.destroy();
218
+ }
219
+ else {
220
+ // Reschedule alarm for remaining time
221
+ const remaining = timeoutMs - elapsed;
222
+ await this.scheduleTimeout(remaining);
223
+ }
224
+ }
225
+ // --------------------------------------------------------------------------
226
+ // Private Session Helpers
227
+ // --------------------------------------------------------------------------
228
+ /**
229
+ * Load session state from storage
230
+ */
231
+ async loadSession() {
232
+ const stored = await this.ctx.storage.get('session');
233
+ if (stored) {
234
+ this.session = stored;
235
+ // Update legacy fields for backward compatibility
236
+ this.legacySessionId = stored.sandboxId;
237
+ this.legacyCreatedAt = new Date(stored.createdAt).toISOString();
238
+ this.legacySessionStatus = stored.status === 'error' ? 'stopped' : stored.status;
239
+ // Recreate sandbox instance if session is running
240
+ if (stored.status === 'running' && this.env.Sandbox) {
241
+ this.sandbox = getSandbox(this.env.Sandbox, stored.sandboxId, 'sandbox.do', stored.config);
242
+ }
243
+ }
244
+ }
245
+ /**
246
+ * Persist session state to storage
247
+ */
248
+ async persistSession() {
249
+ if (this.session) {
250
+ await this.ctx.storage.put('session', this.session);
251
+ }
252
+ }
253
+ /**
254
+ * Update last activity timestamp and reschedule timeout
255
+ */
256
+ async updateActivity() {
257
+ if (!this.session) {
258
+ return;
259
+ }
260
+ this.session.lastActivityAt = new Date();
261
+ await this.persistSession();
262
+ // Reschedule timeout if configured
263
+ if (this.session.config.timeoutMs) {
264
+ await this.scheduleTimeout(this.session.config.timeoutMs);
265
+ }
266
+ }
267
+ /**
268
+ * Schedule a timeout alarm
269
+ */
270
+ async scheduleTimeout(ms) {
271
+ const scheduledTime = Date.now() + ms;
272
+ await this.ctx.storage.setAlarm(scheduledTime);
273
+ }
274
+ // --------------------------------------------------------------------------
275
+ // Routes
276
+ // --------------------------------------------------------------------------
277
+ createRoutes() {
278
+ const app = new Hono();
279
+ // Error handler middleware
280
+ app.onError((err, c) => {
281
+ console.error('SandboxDO error:', err);
282
+ return c.json({ error: err.message || 'Internal server error' }, 500);
283
+ });
284
+ // Helper function to safely get JSON body
285
+ const getJsonBody = async (c) => {
286
+ try {
287
+ const contentType = c.req.header('content-type');
288
+ if (contentType?.includes('application/json')) {
289
+ return await c.req.json();
290
+ }
291
+ return {};
292
+ }
293
+ catch {
294
+ return {};
295
+ }
296
+ };
297
+ // GET /health - Health check
298
+ app.get('/health', (c) => {
299
+ return c.json({ status: 'ok', ns: this.ns, type: this.$type });
300
+ });
301
+ // --------------------------------------------------------------------------
302
+ // New Session Lifecycle Routes
303
+ // --------------------------------------------------------------------------
304
+ // POST /session - Create sandbox session (new API)
305
+ app.post('/session', async (c) => {
306
+ try {
307
+ const body = await getJsonBody(c);
308
+ // Use provided sandboxId or generate one
309
+ const options = {
310
+ sandboxId: body.sandboxId || crypto.randomUUID(),
311
+ config: body.config,
312
+ };
313
+ const result = await this.create(options);
314
+ return c.json(result, 201);
315
+ }
316
+ catch (err) {
317
+ const message = err instanceof Error ? err.message : 'Failed to create session';
318
+ return c.json({ error: message }, 400);
319
+ }
320
+ });
321
+ // DELETE /session - Destroy sandbox session (new API)
322
+ app.delete('/session', async (c) => {
323
+ try {
324
+ await this.destroy();
325
+ return c.json({ success: true });
326
+ }
327
+ catch (err) {
328
+ const message = err instanceof Error ? err.message : 'Failed to destroy session';
329
+ return c.json({ error: message }, 400);
330
+ }
331
+ });
332
+ // GET /session/state - Get session state (new API)
333
+ app.get('/session/state', async (c) => {
334
+ const state = await this.getState();
335
+ if (!state) {
336
+ return c.json({ error: 'No active session' }, 404);
337
+ }
338
+ return c.json(state);
339
+ });
340
+ // --------------------------------------------------------------------------
341
+ // Legacy Routes (backward compatibility)
342
+ // --------------------------------------------------------------------------
343
+ // POST /create - Create sandbox session (legacy)
344
+ app.post('/create', async (c) => {
345
+ if (this.sandbox !== null) {
346
+ return c.json({ error: 'Session already exists' }, 409);
347
+ }
348
+ const body = await getJsonBody(c);
349
+ const config = {
350
+ sleepAfter: body.sleepAfter,
351
+ keepAlive: body.keepAlive,
352
+ };
353
+ try {
354
+ const sandboxId = crypto.randomUUID();
355
+ const hostname = new URL(c.req.url).hostname;
356
+ this.sandbox = getSandbox(this.env.Sandbox, sandboxId, hostname, config);
357
+ this.legacySessionId = sandboxId;
358
+ this.legacyCreatedAt = new Date().toISOString();
359
+ this.legacySessionStatus = 'running';
360
+ // Also create new session state
361
+ this.session = {
362
+ status: 'running',
363
+ sandboxId,
364
+ config,
365
+ createdAt: new Date(),
366
+ lastActivityAt: new Date(),
367
+ };
368
+ await this.persistSession();
369
+ return c.json({
370
+ sessionId: sandboxId,
371
+ status: 'created',
372
+ });
373
+ }
374
+ catch (err) {
375
+ this.sandbox = null;
376
+ this.legacySessionId = null;
377
+ throw err;
378
+ }
379
+ });
380
+ // POST /exec - Execute command (uses new API internally)
381
+ app.post('/exec', async (c) => {
382
+ if (!this.sandbox) {
383
+ return c.json({ error: 'No active session' }, 400);
384
+ }
385
+ const body = await getJsonBody(c);
386
+ if (!body.command) {
387
+ return c.json({ error: 'Missing required field: command' }, 400);
388
+ }
389
+ try {
390
+ const result = await this.exec(body.command);
391
+ return c.json(result);
392
+ }
393
+ catch (err) {
394
+ const message = err instanceof Error ? err.message : 'Execution failed';
395
+ return c.json({ error: message }, 500);
396
+ }
397
+ });
398
+ // POST /exec/stream - Execute command with streaming
399
+ app.post('/exec/stream', async (c) => {
400
+ if (!this.sandbox) {
401
+ return c.json({ error: 'No active session' }, 400);
402
+ }
403
+ const body = await getJsonBody(c);
404
+ if (!body.command) {
405
+ return c.json({ error: 'Missing required field: command' }, 400);
406
+ }
407
+ try {
408
+ const stream = await this.sandbox.execStream(body.command);
409
+ return new Response(new ReadableStream({
410
+ async start(controller) {
411
+ const encoder = new TextEncoder();
412
+ try {
413
+ for await (const event of stream) {
414
+ const sseData = `data: ${JSON.stringify(event)}\n\n`;
415
+ controller.enqueue(encoder.encode(sseData));
416
+ }
417
+ controller.close();
418
+ }
419
+ catch (err) {
420
+ controller.error(err);
421
+ }
422
+ },
423
+ }), {
424
+ headers: {
425
+ 'Content-Type': 'text/event-stream',
426
+ 'Cache-Control': 'no-cache',
427
+ Connection: 'keep-alive',
428
+ },
429
+ });
430
+ }
431
+ catch (err) {
432
+ throw err;
433
+ }
434
+ });
435
+ // POST /file/write - Write file
436
+ app.post('/file/write', async (c) => {
437
+ if (!this.sandbox) {
438
+ return c.json({ error: 'No active session' }, 400);
439
+ }
440
+ const body = await getJsonBody(c);
441
+ if (!body.path) {
442
+ return c.json({ error: 'Missing required field: path' }, 400);
443
+ }
444
+ if (body.content === undefined || body.content === null) {
445
+ return c.json({ error: 'Missing required field: content' }, 400);
446
+ }
447
+ try {
448
+ await this.sandbox.writeFile(body.path, body.content, {
449
+ encoding: body.encoding || 'utf-8',
450
+ });
451
+ return c.json({ success: true });
452
+ }
453
+ catch (err) {
454
+ throw err;
455
+ }
456
+ });
457
+ // GET /file/read - Read file
458
+ app.get('/file/read', async (c) => {
459
+ if (!this.sandbox) {
460
+ return c.json({ error: 'No active session' }, 400);
461
+ }
462
+ const path = c.req.query('path');
463
+ if (!path) {
464
+ return c.json({ error: 'Missing required query parameter: path' }, 400);
465
+ }
466
+ try {
467
+ const result = await this.sandbox.readFile(path);
468
+ return c.json(result);
469
+ }
470
+ catch (err) {
471
+ if (err instanceof Error && err.message.includes('not found')) {
472
+ return c.json({ error: 'File not found' }, 404);
473
+ }
474
+ throw err;
475
+ }
476
+ });
477
+ // POST /port/expose - Expose port
478
+ app.post('/port/expose', async (c) => {
479
+ if (!this.sandbox) {
480
+ return c.json({ error: 'No active session' }, 400);
481
+ }
482
+ const body = await getJsonBody(c);
483
+ if (body.port === undefined || body.port === null) {
484
+ return c.json({ error: 'Missing required field: port' }, 400);
485
+ }
486
+ if (typeof body.port !== 'number' || body.port < 1 || body.port > 65535) {
487
+ return c.json({ error: 'Invalid port number' }, 400);
488
+ }
489
+ try {
490
+ const result = await this.sandbox.exposePort(body.port, {
491
+ name: body.name,
492
+ });
493
+ return c.json(result);
494
+ }
495
+ catch (err) {
496
+ throw err;
497
+ }
498
+ });
499
+ // GET /ports - List exposed ports
500
+ app.get('/ports', async (c) => {
501
+ if (!this.sandbox) {
502
+ return c.json({ error: 'No active session' }, 400);
503
+ }
504
+ try {
505
+ const ports = await this.sandbox.getExposedPorts();
506
+ return c.json(ports);
507
+ }
508
+ catch (err) {
509
+ throw err;
510
+ }
511
+ });
512
+ // GET /state - Get session state (legacy)
513
+ app.get('/state', async (c) => {
514
+ const state = {
515
+ status: this.legacySessionStatus,
516
+ exposedPorts: [],
517
+ createdAt: this.legacyCreatedAt || '',
518
+ };
519
+ if (this.sandbox && this.legacySessionStatus === 'running') {
520
+ try {
521
+ state.exposedPorts = await this.sandbox.getExposedPorts();
522
+ }
523
+ catch {
524
+ // Ignore errors getting ports
525
+ }
526
+ }
527
+ return c.json(state);
528
+ });
529
+ // POST /destroy - Destroy sandbox (legacy)
530
+ app.post('/destroy', async (c) => {
531
+ if (!this.sandbox) {
532
+ return c.json({ error: 'No active session' }, 400);
533
+ }
534
+ try {
535
+ await this.sandbox.destroy();
536
+ this.sandbox = null;
537
+ this.legacySessionId = null;
538
+ this.legacySessionStatus = 'stopped';
539
+ this.session = null;
540
+ await this.ctx.storage.delete('session');
541
+ return c.json({ success: true });
542
+ }
543
+ catch (err) {
544
+ throw err;
545
+ }
546
+ });
547
+ // GET /terminal - WebSocket upgrade
548
+ // Note: WebSocket upgrade is handled in fetch() method, not via Hono
549
+ app.get('/terminal', async (c) => {
550
+ if (!this.sandbox) {
551
+ return c.json({ error: 'No active session' }, 400);
552
+ }
553
+ const upgradeHeader = c.req.header('Upgrade');
554
+ if (!upgradeHeader || upgradeHeader.toLowerCase() !== 'websocket') {
555
+ return c.json({ error: 'WebSocket upgrade required' }, 426);
556
+ }
557
+ // WebSocket handling is done in fetch() method before routing to Hono
558
+ // This should not be reached for valid WebSocket requests
559
+ return c.json({ error: 'WebSocket upgrade required' }, 426);
560
+ });
561
+ // Method not allowed handler for known routes
562
+ app.all('/create', (c) => c.json({ error: 'Method not allowed' }, 405));
563
+ app.all('/exec', (c) => c.json({ error: 'Method not allowed' }, 405));
564
+ app.all('/exec/stream', (c) => c.json({ error: 'Method not allowed' }, 405));
565
+ app.all('/file/write', (c) => c.json({ error: 'Method not allowed' }, 405));
566
+ app.all('/file/read', (c) => c.json({ error: 'Method not allowed' }, 405));
567
+ app.all('/port/expose', (c) => c.json({ error: 'Method not allowed' }, 405));
568
+ app.all('/ports', (c) => c.json({ error: 'Method not allowed' }, 405));
569
+ app.all('/destroy', (c) => c.json({ error: 'Method not allowed' }, 405));
570
+ app.all('/terminal', (c) => c.json({ error: 'Method not allowed' }, 405));
571
+ // 404 handler
572
+ app.notFound((c) => c.json({ error: 'Not found' }, 404));
573
+ return app;
574
+ }
575
+ // --------------------------------------------------------------------------
576
+ // Fetch Handler
577
+ // --------------------------------------------------------------------------
578
+ async fetch(request) {
579
+ // Check for WebSocket upgrade on /terminal path
580
+ const url = new URL(request.url);
581
+ if (url.pathname === '/terminal' && request.headers.get('Upgrade')?.toLowerCase() === 'websocket') {
582
+ return this.handleTerminalWebSocket(request);
583
+ }
584
+ return this.app.fetch(request, this.env);
585
+ }
586
+ // --------------------------------------------------------------------------
587
+ // Terminal WebSocket Handling
588
+ // --------------------------------------------------------------------------
589
+ /**
590
+ * Handle WebSocket upgrade for terminal connections
591
+ */
592
+ handleTerminalWebSocket(request) {
593
+ if (!this.sandbox) {
594
+ return new Response(JSON.stringify({ error: 'No active session' }), {
595
+ status: 400,
596
+ headers: { 'Content-Type': 'application/json' },
597
+ });
598
+ }
599
+ // Create WebSocket pair
600
+ const pair = new WebSocketPair();
601
+ const [client, server] = Object.values(pair);
602
+ // Accept the server socket
603
+ server.accept();
604
+ // Generate terminal session ID
605
+ const terminalSessionId = crypto.randomUUID();
606
+ // Get initial dimensions from query params
607
+ const url = new URL(request.url);
608
+ const cols = parseInt(url.searchParams.get('cols') || '80', 10);
609
+ const rows = parseInt(url.searchParams.get('rows') || '24', 10);
610
+ // Create terminal session
611
+ const session = {
612
+ sessionId: terminalSessionId,
613
+ clients: new Set([server]),
614
+ outputBuffer: new RingBuffer(64 * 1024), // 64KB buffer
615
+ cols: Math.max(1, cols),
616
+ rows: Math.max(1, rows),
617
+ };
618
+ this.terminalSessions.set(terminalSessionId, session);
619
+ // Send connected message
620
+ server.send(JSON.stringify({
621
+ type: 'connected',
622
+ sessionId: terminalSessionId,
623
+ }));
624
+ // Send buffered output for reconnection (if any)
625
+ const bufferedOutput = session.outputBuffer.getAll();
626
+ if (bufferedOutput) {
627
+ server.send(JSON.stringify({
628
+ type: 'output',
629
+ data: bufferedOutput,
630
+ }));
631
+ }
632
+ // Handle incoming messages
633
+ server.addEventListener('message', async (event) => {
634
+ try {
635
+ const msg = JSON.parse(event.data);
636
+ await this.handleTerminalMessage(session, server, msg);
637
+ }
638
+ catch (e) {
639
+ server.send(JSON.stringify({
640
+ type: 'error',
641
+ data: `\x1b[31mError: ${e.message}\x1b[0m`,
642
+ }));
643
+ }
644
+ });
645
+ // Handle close
646
+ server.addEventListener('close', () => {
647
+ session.clients.delete(server);
648
+ // Don't destroy session on disconnect - keep for reconnection
649
+ });
650
+ // Handle error
651
+ server.addEventListener('error', () => {
652
+ session.clients.delete(server);
653
+ });
654
+ // Return WebSocket upgrade response (Cloudflare Workers specific)
655
+ return new Response(null, {
656
+ status: 101,
657
+ webSocket: client,
658
+ });
659
+ }
660
+ /**
661
+ * Handle incoming terminal WebSocket message
662
+ */
663
+ async handleTerminalMessage(session, client, msg) {
664
+ switch (msg.type) {
665
+ case 'input':
666
+ // Input is handled by exec/execStream
667
+ // In a full PTY implementation, this would go to stdin
668
+ break;
669
+ case 'execute':
670
+ if (msg.command) {
671
+ await this.executeTerminalCommand(session, msg.command);
672
+ }
673
+ break;
674
+ case 'resize':
675
+ if (msg.cols && msg.rows && msg.cols > 0 && msg.rows > 0) {
676
+ session.cols = msg.cols;
677
+ session.rows = msg.rows;
678
+ // In real implementation, would send SIGWINCH to process
679
+ }
680
+ break;
681
+ }
682
+ }
683
+ /**
684
+ * Execute a command in the sandbox and stream output to terminal clients
685
+ */
686
+ async executeTerminalCommand(session, command) {
687
+ if (!this.sandbox) {
688
+ this.broadcastToTerminal(session, {
689
+ type: 'error',
690
+ data: '\x1b[31mNo active sandbox session\x1b[0m',
691
+ });
692
+ return;
693
+ }
694
+ try {
695
+ // Use execStream for streaming output
696
+ const stream = await this.sandbox.execStream(command);
697
+ for await (const event of stream) {
698
+ let message;
699
+ switch (event.type) {
700
+ case 'stdout':
701
+ message = { type: 'output', data: event.data };
702
+ // Buffer output for reconnection
703
+ if (event.data) {
704
+ session.outputBuffer.push(event.data);
705
+ }
706
+ break;
707
+ case 'stderr':
708
+ // Include ANSI color codes for errors (red)
709
+ const errorData = `\x1b[31m${event.data}\x1b[0m`;
710
+ message = { type: 'error', data: errorData };
711
+ // Buffer error output too
712
+ if (event.data) {
713
+ session.outputBuffer.push(errorData);
714
+ }
715
+ break;
716
+ case 'complete':
717
+ message = { type: 'exit', code: event.exitCode ?? 0 };
718
+ break;
719
+ case 'error':
720
+ const errMessage = `\x1b[31m${event.message}\x1b[0m`;
721
+ message = { type: 'error', data: errMessage };
722
+ break;
723
+ default:
724
+ continue;
725
+ }
726
+ // Broadcast to all connected clients
727
+ this.broadcastToTerminal(session, message);
728
+ }
729
+ }
730
+ catch (error) {
731
+ this.broadcastToTerminal(session, {
732
+ type: 'error',
733
+ data: `\x1b[31mExecution error: ${error.message}\x1b[0m`,
734
+ });
735
+ }
736
+ }
737
+ /**
738
+ * Broadcast message to all clients in a terminal session
739
+ */
740
+ broadcastToTerminal(session, message) {
741
+ const data = JSON.stringify(message);
742
+ for (const client of session.clients) {
743
+ try {
744
+ client.send(data);
745
+ }
746
+ catch {
747
+ // Client disconnected, will be removed on close event
748
+ }
749
+ }
750
+ }
751
+ /**
752
+ * Get terminal session by ID (for testing)
753
+ */
754
+ getTerminalSession(sessionId) {
755
+ return this.terminalSessions.get(sessionId);
756
+ }
757
+ }
758
+ export default SandboxDO;
759
+ //# sourceMappingURL=SandboxDO.js.map