dotdo 0.0.1 → 0.0.2

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 (727) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +446 -315
  3. package/dist/ai/index.js +19 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/template-literals.js +852 -0
  6. package/dist/ai/template-literals.js.map +1 -0
  7. package/dist/api/analytics/router.js +601 -0
  8. package/dist/api/analytics/router.js.map +1 -0
  9. package/dist/api/index.js +158 -0
  10. package/dist/api/index.js.map +1 -0
  11. package/dist/api/middleware/auth-federation.js +573 -0
  12. package/dist/api/middleware/auth-federation.js.map +1 -0
  13. package/dist/api/middleware/auth.js +544 -0
  14. package/dist/api/middleware/auth.js.map +1 -0
  15. package/dist/api/middleware/error-handling.js +176 -0
  16. package/dist/api/middleware/error-handling.js.map +1 -0
  17. package/dist/api/middleware/request-id.js +21 -0
  18. package/dist/api/middleware/request-id.js.map +1 -0
  19. package/dist/api/pages.js +1180 -0
  20. package/dist/api/pages.js.map +1 -0
  21. package/dist/api/routes/api.js +612 -0
  22. package/dist/api/routes/api.js.map +1 -0
  23. package/dist/api/routes/browsers.js +471 -0
  24. package/dist/api/routes/browsers.js.map +1 -0
  25. package/dist/api/routes/do.js +188 -0
  26. package/dist/api/routes/do.js.map +1 -0
  27. package/dist/api/routes/mcp.js +459 -0
  28. package/dist/api/routes/mcp.js.map +1 -0
  29. package/dist/api/routes/obs.js +445 -0
  30. package/dist/api/routes/obs.js.map +1 -0
  31. package/dist/api/routes/openapi.js +794 -0
  32. package/dist/api/routes/openapi.js.map +1 -0
  33. package/dist/api/routes/rpc.js +1103 -0
  34. package/dist/api/routes/rpc.js.map +1 -0
  35. package/dist/api/routes/sandboxes.js +389 -0
  36. package/dist/api/routes/sandboxes.js.map +1 -0
  37. package/dist/api/test-do.js +38 -0
  38. package/dist/api/test-do.js.map +1 -0
  39. package/dist/api/types.js +11 -0
  40. package/dist/api/types.js.map +1 -0
  41. package/dist/cli/bin.js +2 -0
  42. package/dist/cli/main.js +52342 -0
  43. package/dist/db/actions.js +212 -0
  44. package/dist/db/actions.js.map +1 -0
  45. package/dist/db/auth.js +506 -0
  46. package/dist/db/auth.js.map +1 -0
  47. package/dist/db/branches.js +65 -0
  48. package/dist/db/branches.js.map +1 -0
  49. package/dist/db/clickhouse.js +1074 -0
  50. package/dist/db/clickhouse.js.map +1 -0
  51. package/dist/db/dlq.js +39 -0
  52. package/dist/db/dlq.js.map +1 -0
  53. package/dist/db/events.js +28 -0
  54. package/dist/db/events.js.map +1 -0
  55. package/dist/db/exec.js +64 -0
  56. package/dist/db/exec.js.map +1 -0
  57. package/dist/db/files.js +85 -0
  58. package/dist/db/files.js.map +1 -0
  59. package/dist/db/flags.js +24 -0
  60. package/dist/db/flags.js.map +1 -0
  61. package/dist/db/git.js +116 -0
  62. package/dist/db/git.js.map +1 -0
  63. package/dist/db/iceberg/inverted-index.js +862 -0
  64. package/dist/db/iceberg/inverted-index.js.map +1 -0
  65. package/dist/db/iceberg/puffin.js +878 -0
  66. package/dist/db/iceberg/puffin.js.map +1 -0
  67. package/dist/db/iceberg/search-manifest.js +422 -0
  68. package/dist/db/iceberg/search-manifest.js.map +1 -0
  69. package/dist/db/iceberg/types.js +8 -0
  70. package/dist/db/iceberg/types.js.map +1 -0
  71. package/dist/db/index.js +121 -0
  72. package/dist/db/index.js.map +1 -0
  73. package/dist/db/integrations.js +368 -0
  74. package/dist/db/integrations.js.map +1 -0
  75. package/dist/db/json-indexes.js +332 -0
  76. package/dist/db/json-indexes.js.map +1 -0
  77. package/dist/db/linked-accounts.js +287 -0
  78. package/dist/db/linked-accounts.js.map +1 -0
  79. package/dist/db/nouns.js +183 -0
  80. package/dist/db/nouns.js.map +1 -0
  81. package/dist/db/objects.js +170 -0
  82. package/dist/db/objects.js.map +1 -0
  83. package/dist/db/primitives/dag-scheduler/index.js +869 -0
  84. package/dist/db/primitives/dag-scheduler/index.js.map +1 -0
  85. package/dist/db/primitives/exactly-once-context.js +237 -0
  86. package/dist/db/primitives/exactly-once-context.js.map +1 -0
  87. package/dist/db/primitives/index.js +62 -0
  88. package/dist/db/primitives/index.js.map +1 -0
  89. package/dist/db/primitives/keyed-router.js +145 -0
  90. package/dist/db/primitives/keyed-router.js.map +1 -0
  91. package/dist/db/primitives/observability.js +162 -0
  92. package/dist/db/primitives/observability.js.map +1 -0
  93. package/dist/db/primitives/schema-evolution.js +643 -0
  94. package/dist/db/primitives/schema-evolution.js.map +1 -0
  95. package/dist/db/primitives/stateful-operator/index.js +770 -0
  96. package/dist/db/primitives/stateful-operator/index.js.map +1 -0
  97. package/dist/db/primitives/temporal-store.js +306 -0
  98. package/dist/db/primitives/temporal-store.js.map +1 -0
  99. package/dist/db/primitives/typed-column-store.js +1229 -0
  100. package/dist/db/primitives/typed-column-store.js.map +1 -0
  101. package/dist/db/primitives/utils/duration.js +162 -0
  102. package/dist/db/primitives/utils/duration.js.map +1 -0
  103. package/dist/db/primitives/utils/murmur3.js +118 -0
  104. package/dist/db/primitives/utils/murmur3.js.map +1 -0
  105. package/dist/db/primitives/watermark-service.js +136 -0
  106. package/dist/db/primitives/watermark-service.js.map +1 -0
  107. package/dist/db/primitives/window-manager.js +764 -0
  108. package/dist/db/primitives/window-manager.js.map +1 -0
  109. package/dist/db/relationships.js +66 -0
  110. package/dist/db/relationships.js.map +1 -0
  111. package/dist/db/schema-minimal.js +61 -0
  112. package/dist/db/schema-minimal.js.map +1 -0
  113. package/dist/db/search.js +28 -0
  114. package/dist/db/search.js.map +1 -0
  115. package/dist/db/stores.js +1665 -0
  116. package/dist/db/stores.js.map +1 -0
  117. package/dist/db/things.js +297 -0
  118. package/dist/db/things.js.map +1 -0
  119. package/dist/db/vault.js +171 -0
  120. package/dist/db/vault.js.map +1 -0
  121. package/dist/db/verbs.js +102 -0
  122. package/dist/db/verbs.js.map +1 -0
  123. package/dist/do/base.js +48 -0
  124. package/dist/do/base.js.map +1 -0
  125. package/dist/do/bash.js +35 -0
  126. package/dist/do/bash.js.map +1 -0
  127. package/dist/do/fs.js +25 -0
  128. package/dist/do/fs.js.map +1 -0
  129. package/dist/do/full.js +61 -0
  130. package/dist/do/full.js.map +1 -0
  131. package/dist/do/git.js +28 -0
  132. package/dist/do/git.js.map +1 -0
  133. package/dist/do/index.js +52 -0
  134. package/dist/do/index.js.map +1 -0
  135. package/dist/do/tiny.js +31 -0
  136. package/dist/do/tiny.js.map +1 -0
  137. package/dist/lib/DOAuth.js +261 -0
  138. package/dist/lib/DOAuth.js.map +1 -0
  139. package/dist/lib/DODispatcher.js +72 -0
  140. package/dist/lib/DODispatcher.js.map +1 -0
  141. package/dist/lib/Modifier.js +189 -0
  142. package/dist/lib/Modifier.js.map +1 -0
  143. package/dist/lib/StateStorage.js +403 -0
  144. package/dist/lib/StateStorage.js.map +1 -0
  145. package/dist/lib/TypeRegistry.js +122 -0
  146. package/dist/lib/TypeRegistry.js.map +1 -0
  147. package/dist/lib/agent/tools/bash.js +336 -0
  148. package/dist/lib/agent/tools/bash.js.map +1 -0
  149. package/dist/lib/agent/tools/edit.js +157 -0
  150. package/dist/lib/agent/tools/edit.js.map +1 -0
  151. package/dist/lib/agent/tools/glob.js +137 -0
  152. package/dist/lib/agent/tools/glob.js.map +1 -0
  153. package/dist/lib/agent/tools/grep.js +315 -0
  154. package/dist/lib/agent/tools/grep.js.map +1 -0
  155. package/dist/lib/agent/tools/index.js +71 -0
  156. package/dist/lib/agent/tools/index.js.map +1 -0
  157. package/dist/lib/agent/tools/read.js +212 -0
  158. package/dist/lib/agent/tools/read.js.map +1 -0
  159. package/dist/lib/agent/tools/types.js +197 -0
  160. package/dist/lib/agent/tools/types.js.map +1 -0
  161. package/dist/lib/agent/tools/write.js +159 -0
  162. package/dist/lib/agent/tools/write.js.map +1 -0
  163. package/dist/lib/ai/gateway.js +247 -0
  164. package/dist/lib/ai/gateway.js.map +1 -0
  165. package/dist/lib/ai/tool-loop-agent.js +591 -0
  166. package/dist/lib/ai/tool-loop-agent.js.map +1 -0
  167. package/dist/lib/auto-wiring.js +439 -0
  168. package/dist/lib/auto-wiring.js.map +1 -0
  169. package/dist/lib/browse/browserbase.js +163 -0
  170. package/dist/lib/browse/browserbase.js.map +1 -0
  171. package/dist/lib/browse/cloudflare.js +144 -0
  172. package/dist/lib/browse/cloudflare.js.map +1 -0
  173. package/dist/lib/browse/index.js +62 -0
  174. package/dist/lib/browse/index.js.map +1 -0
  175. package/dist/lib/browse/types.js +13 -0
  176. package/dist/lib/browse/types.js.map +1 -0
  177. package/dist/lib/cache/index.js +37 -0
  178. package/dist/lib/cache/index.js.map +1 -0
  179. package/dist/lib/cache/visibility.js +638 -0
  180. package/dist/lib/cache/visibility.js.map +1 -0
  181. package/dist/lib/capabilities.js +268 -0
  182. package/dist/lib/capabilities.js.map +1 -0
  183. package/dist/lib/channels/base.js +106 -0
  184. package/dist/lib/channels/base.js.map +1 -0
  185. package/dist/lib/channels/discord.js +94 -0
  186. package/dist/lib/channels/discord.js.map +1 -0
  187. package/dist/lib/channels/email.js +204 -0
  188. package/dist/lib/channels/email.js.map +1 -0
  189. package/dist/lib/channels/index.js +90 -0
  190. package/dist/lib/channels/index.js.map +1 -0
  191. package/dist/lib/channels/mdxui-chat.js +95 -0
  192. package/dist/lib/channels/mdxui-chat.js.map +1 -0
  193. package/dist/lib/channels/slack-blockkit.js +121 -0
  194. package/dist/lib/channels/slack-blockkit.js.map +1 -0
  195. package/dist/lib/channels/types.js +7 -0
  196. package/dist/lib/channels/types.js.map +1 -0
  197. package/dist/lib/cloudflare/ai.js +654 -0
  198. package/dist/lib/cloudflare/ai.js.map +1 -0
  199. package/dist/lib/cloudflare/index.js +88 -0
  200. package/dist/lib/cloudflare/index.js.map +1 -0
  201. package/dist/lib/cloudflare/kv.js +342 -0
  202. package/dist/lib/cloudflare/kv.js.map +1 -0
  203. package/dist/lib/cloudflare/queues.js +434 -0
  204. package/dist/lib/cloudflare/queues.js.map +1 -0
  205. package/dist/lib/cloudflare/r2.js +604 -0
  206. package/dist/lib/cloudflare/r2.js.map +1 -0
  207. package/dist/lib/cloudflare/vectorize.js +494 -0
  208. package/dist/lib/cloudflare/vectorize.js.map +1 -0
  209. package/dist/lib/cloudflare/workflows.js +569 -0
  210. package/dist/lib/cloudflare/workflows.js.map +1 -0
  211. package/dist/lib/colo/caching.js +196 -0
  212. package/dist/lib/colo/caching.js.map +1 -0
  213. package/dist/lib/colo/detection.js +194 -0
  214. package/dist/lib/colo/detection.js.map +1 -0
  215. package/dist/lib/colo/external-data.js +219 -0
  216. package/dist/lib/colo/external-data.js.map +1 -0
  217. package/dist/lib/colo/globe-data.js +179 -0
  218. package/dist/lib/colo/globe-data.js.map +1 -0
  219. package/dist/lib/colo/index.js +16 -0
  220. package/dist/lib/colo/index.js.map +1 -0
  221. package/dist/lib/decorators.js +37 -0
  222. package/dist/lib/decorators.js.map +1 -0
  223. package/dist/lib/discovery.js +81 -0
  224. package/dist/lib/discovery.js.map +1 -0
  225. package/dist/lib/executors/AgenticFunctionExecutor.js +619 -0
  226. package/dist/lib/executors/AgenticFunctionExecutor.js.map +1 -0
  227. package/dist/lib/executors/BaseFunctionExecutor.js +328 -0
  228. package/dist/lib/executors/BaseFunctionExecutor.js.map +1 -0
  229. package/dist/lib/executors/CascadeExecutor.js +418 -0
  230. package/dist/lib/executors/CascadeExecutor.js.map +1 -0
  231. package/dist/lib/executors/CodeFunctionExecutor.js +904 -0
  232. package/dist/lib/executors/CodeFunctionExecutor.js.map +1 -0
  233. package/dist/lib/executors/GenerativeFunctionExecutor.js +904 -0
  234. package/dist/lib/executors/GenerativeFunctionExecutor.js.map +1 -0
  235. package/dist/lib/executors/HumanFunctionExecutor.js +884 -0
  236. package/dist/lib/executors/HumanFunctionExecutor.js.map +1 -0
  237. package/dist/lib/executors/ParallelStepExecutor.js +308 -0
  238. package/dist/lib/executors/ParallelStepExecutor.js.map +1 -0
  239. package/dist/lib/executors/types.js +12 -0
  240. package/dist/lib/executors/types.js.map +1 -0
  241. package/dist/lib/experiments.js +89 -0
  242. package/dist/lib/experiments.js.map +1 -0
  243. package/dist/lib/flags/store.js +262 -0
  244. package/dist/lib/flags/store.js.map +1 -0
  245. package/dist/lib/functions/FunctionComposition.js +467 -0
  246. package/dist/lib/functions/FunctionComposition.js.map +1 -0
  247. package/dist/lib/functions/FunctionMiddleware.js +457 -0
  248. package/dist/lib/functions/FunctionMiddleware.js.map +1 -0
  249. package/dist/lib/functions/FunctionRegistry.js +426 -0
  250. package/dist/lib/functions/FunctionRegistry.js.map +1 -0
  251. package/dist/lib/functions/createFunction.js +1048 -0
  252. package/dist/lib/functions/createFunction.js.map +1 -0
  253. package/dist/lib/humans/index.js +68 -0
  254. package/dist/lib/humans/index.js.map +1 -0
  255. package/dist/lib/humans/templates.js +117 -0
  256. package/dist/lib/humans/templates.js.map +1 -0
  257. package/dist/lib/identity.js +98 -0
  258. package/dist/lib/identity.js.map +1 -0
  259. package/dist/lib/index.js +9 -0
  260. package/dist/lib/index.js.map +1 -0
  261. package/dist/lib/logging/error-logger.js +163 -0
  262. package/dist/lib/logging/error-logger.js.map +1 -0
  263. package/dist/lib/logging/index.js +160 -0
  264. package/dist/lib/logging/index.js.map +1 -0
  265. package/dist/lib/mixins/bash.js +825 -0
  266. package/dist/lib/mixins/bash.js.map +1 -0
  267. package/dist/lib/mixins/fs.js +648 -0
  268. package/dist/lib/mixins/fs.js.map +1 -0
  269. package/dist/lib/mixins/git.js +1011 -0
  270. package/dist/lib/mixins/git.js.map +1 -0
  271. package/dist/lib/mixins/index.js +29 -0
  272. package/dist/lib/mixins/index.js.map +1 -0
  273. package/dist/lib/mixins/npm.js +662 -0
  274. package/dist/lib/mixins/npm.js.map +1 -0
  275. package/dist/lib/noun-id.js +278 -0
  276. package/dist/lib/noun-id.js.map +1 -0
  277. package/dist/lib/rate-limit/sliding-window.js +148 -0
  278. package/dist/lib/rate-limit/sliding-window.js.map +1 -0
  279. package/dist/lib/rate-limit.js +110 -0
  280. package/dist/lib/rate-limit.js.map +1 -0
  281. package/dist/lib/rpc/bindings.js +548 -0
  282. package/dist/lib/rpc/bindings.js.map +1 -0
  283. package/dist/lib/rpc/index.js +64 -0
  284. package/dist/lib/rpc/index.js.map +1 -0
  285. package/dist/lib/safe-stringify.js +223 -0
  286. package/dist/lib/safe-stringify.js.map +1 -0
  287. package/dist/lib/sandbox/miniflare-sandbox.js +1007 -0
  288. package/dist/lib/sandbox/miniflare-sandbox.js.map +1 -0
  289. package/dist/lib/sqids.js +110 -0
  290. package/dist/lib/sqids.js.map +1 -0
  291. package/dist/lib/sql/adapters/index.js +10 -0
  292. package/dist/lib/sql/adapters/index.js.map +1 -0
  293. package/dist/lib/sql/adapters/node-sql-parser.js +552 -0
  294. package/dist/lib/sql/adapters/node-sql-parser.js.map +1 -0
  295. package/dist/lib/sql/adapters/pgsql-parser.js +1189 -0
  296. package/dist/lib/sql/adapters/pgsql-parser.js.map +1 -0
  297. package/dist/lib/sql/index.js +277 -0
  298. package/dist/lib/sql/index.js.map +1 -0
  299. package/dist/lib/sql/types.js +56 -0
  300. package/dist/lib/sql/types.js.map +1 -0
  301. package/dist/lib/type-classifier.js +126 -0
  302. package/dist/lib/type-classifier.js.map +1 -0
  303. package/dist/lib/utils/html.js +47 -0
  304. package/dist/lib/utils/html.js.map +1 -0
  305. package/dist/lib/validation.js +48 -0
  306. package/dist/lib/validation.js.map +1 -0
  307. package/dist/lib/vault/store.js +411 -0
  308. package/dist/lib/vault/store.js.map +1 -0
  309. package/dist/metrics/hunch.js +739 -0
  310. package/dist/metrics/hunch.js.map +1 -0
  311. package/dist/objects/API.js +302 -0
  312. package/dist/objects/API.js.map +1 -0
  313. package/dist/objects/Agent.js +179 -0
  314. package/dist/objects/Agent.js.map +1 -0
  315. package/dist/objects/AgenticFunctionExecutor.js +8 -0
  316. package/dist/objects/AgenticFunctionExecutor.js.map +1 -0
  317. package/dist/objects/App.js +83 -0
  318. package/dist/objects/App.js.map +1 -0
  319. package/dist/objects/Browser.js +884 -0
  320. package/dist/objects/Browser.js.map +1 -0
  321. package/dist/objects/Business.js +107 -0
  322. package/dist/objects/Business.js.map +1 -0
  323. package/dist/objects/CLI.js +221 -0
  324. package/dist/objects/CLI.js.map +1 -0
  325. package/dist/objects/CodeFunctionExecutor.js +8 -0
  326. package/dist/objects/CodeFunctionExecutor.js.map +1 -0
  327. package/dist/objects/Collection.js +161 -0
  328. package/dist/objects/Collection.js.map +1 -0
  329. package/dist/objects/DO.js +41 -0
  330. package/dist/objects/DO.js.map +1 -0
  331. package/dist/objects/DOBase.js +2309 -0
  332. package/dist/objects/DOBase.js.map +1 -0
  333. package/dist/objects/DOFull.js +1676 -0
  334. package/dist/objects/DOFull.js.map +1 -0
  335. package/dist/objects/DOTiny.js +207 -0
  336. package/dist/objects/DOTiny.js.map +1 -0
  337. package/dist/objects/Directory.js +199 -0
  338. package/dist/objects/Directory.js.map +1 -0
  339. package/dist/objects/Entity.js +413 -0
  340. package/dist/objects/Entity.js.map +1 -0
  341. package/dist/objects/Function.js +116 -0
  342. package/dist/objects/Function.js.map +1 -0
  343. package/dist/objects/Human.js +231 -0
  344. package/dist/objects/Human.js.map +1 -0
  345. package/dist/objects/HumanFunctionExecutor.js +8 -0
  346. package/dist/objects/HumanFunctionExecutor.js.map +1 -0
  347. package/dist/objects/IcebergMetadataDO.js +938 -0
  348. package/dist/objects/IcebergMetadataDO.js.map +1 -0
  349. package/dist/objects/IntegrationsDO.js +1174 -0
  350. package/dist/objects/IntegrationsDO.js.map +1 -0
  351. package/dist/objects/ObservabilityBroadcaster.js +149 -0
  352. package/dist/objects/ObservabilityBroadcaster.js.map +1 -0
  353. package/dist/objects/Package.js +154 -0
  354. package/dist/objects/Package.js.map +1 -0
  355. package/dist/objects/Product.js +193 -0
  356. package/dist/objects/Product.js.map +1 -0
  357. package/dist/objects/SDK.js +152 -0
  358. package/dist/objects/SDK.js.map +1 -0
  359. package/dist/objects/SaaS.js +235 -0
  360. package/dist/objects/SaaS.js.map +1 -0
  361. package/dist/objects/SandboxDO.js +759 -0
  362. package/dist/objects/SandboxDO.js.map +1 -0
  363. package/dist/objects/Service.js +337 -0
  364. package/dist/objects/Service.js.map +1 -0
  365. package/dist/objects/Site.js +80 -0
  366. package/dist/objects/Site.js.map +1 -0
  367. package/dist/objects/Startup.js +479 -0
  368. package/dist/objects/Startup.js.map +1 -0
  369. package/dist/objects/ThingsDO.js +170 -0
  370. package/dist/objects/ThingsDO.js.map +1 -0
  371. package/dist/objects/VectorShardDO.js +648 -0
  372. package/dist/objects/VectorShardDO.js.map +1 -0
  373. package/dist/objects/Worker.js +144 -0
  374. package/dist/objects/Worker.js.map +1 -0
  375. package/dist/objects/Workflow.js +196 -0
  376. package/dist/objects/Workflow.js.map +1 -0
  377. package/dist/objects/WorkflowFactory.js +313 -0
  378. package/dist/objects/WorkflowFactory.js.map +1 -0
  379. package/dist/objects/WorkflowRuntime.js +863 -0
  380. package/dist/objects/WorkflowRuntime.js.map +1 -0
  381. package/dist/objects/circuit-breaker-bulkhead.js +178 -0
  382. package/dist/objects/circuit-breaker-bulkhead.js.map +1 -0
  383. package/dist/objects/createFunction.js +934 -0
  384. package/dist/objects/createFunction.js.map +1 -0
  385. package/dist/objects/index.js +80 -0
  386. package/dist/objects/index.js.map +1 -0
  387. package/dist/objects/lifecycle/Branch.js +275 -0
  388. package/dist/objects/lifecycle/Branch.js.map +1 -0
  389. package/dist/objects/lifecycle/Clone.js +1499 -0
  390. package/dist/objects/lifecycle/Clone.js.map +1 -0
  391. package/dist/objects/lifecycle/Compact.js +237 -0
  392. package/dist/objects/lifecycle/Compact.js.map +1 -0
  393. package/dist/objects/lifecycle/Promote.js +476 -0
  394. package/dist/objects/lifecycle/Promote.js.map +1 -0
  395. package/dist/objects/lifecycle/Shard.js +560 -0
  396. package/dist/objects/lifecycle/Shard.js.map +1 -0
  397. package/dist/objects/lifecycle/index.js +15 -0
  398. package/dist/objects/lifecycle/index.js.map +1 -0
  399. package/dist/objects/lifecycle/types.js +33 -0
  400. package/dist/objects/lifecycle/types.js.map +1 -0
  401. package/dist/objects/mixins/infrastructure.js +171 -0
  402. package/dist/objects/mixins/infrastructure.js.map +1 -0
  403. package/dist/objects/modules/StoresModule.js +153 -0
  404. package/dist/objects/modules/StoresModule.js.map +1 -0
  405. package/dist/objects/persistence/checkpoint-manager.js +606 -0
  406. package/dist/objects/persistence/checkpoint-manager.js.map +1 -0
  407. package/dist/objects/persistence/index.js +72 -0
  408. package/dist/objects/persistence/index.js.map +1 -0
  409. package/dist/objects/persistence/migration-runner.js +562 -0
  410. package/dist/objects/persistence/migration-runner.js.map +1 -0
  411. package/dist/objects/persistence/replication-manager.js +501 -0
  412. package/dist/objects/persistence/replication-manager.js.map +1 -0
  413. package/dist/objects/persistence/tiered-storage-manager.js +595 -0
  414. package/dist/objects/persistence/tiered-storage-manager.js.map +1 -0
  415. package/dist/objects/persistence/types.js +14 -0
  416. package/dist/objects/persistence/types.js.map +1 -0
  417. package/dist/objects/persistence/wal-manager.js +653 -0
  418. package/dist/objects/persistence/wal-manager.js.map +1 -0
  419. package/dist/objects/presets/index.js +20 -0
  420. package/dist/objects/presets/index.js.map +1 -0
  421. package/dist/objects/presets/primitives.js +188 -0
  422. package/dist/objects/presets/primitives.js.map +1 -0
  423. package/dist/objects/primitives/alarm-adapter.js +141 -0
  424. package/dist/objects/primitives/alarm-adapter.js.map +1 -0
  425. package/dist/objects/primitives/index.js +337 -0
  426. package/dist/objects/primitives/index.js.map +1 -0
  427. package/dist/objects/primitives/storage-adapter.js +182 -0
  428. package/dist/objects/primitives/storage-adapter.js.map +1 -0
  429. package/dist/objects/primitives/with-primitives.js +102 -0
  430. package/dist/objects/primitives/with-primitives.js.map +1 -0
  431. package/dist/objects/services/StoreManager.js +227 -0
  432. package/dist/objects/services/StoreManager.js.map +1 -0
  433. package/dist/objects/services/index.js +13 -0
  434. package/dist/objects/services/index.js.map +1 -0
  435. package/dist/objects/transport/auth-layer.js +1451 -0
  436. package/dist/objects/transport/auth-layer.js.map +1 -0
  437. package/dist/objects/transport/capnweb-target.js +355 -0
  438. package/dist/objects/transport/capnweb-target.js.map +1 -0
  439. package/dist/objects/transport/chain.js +441 -0
  440. package/dist/objects/transport/chain.js.map +1 -0
  441. package/dist/objects/transport/handler.js +58 -0
  442. package/dist/objects/transport/handler.js.map +1 -0
  443. package/dist/objects/transport/index.js +53 -0
  444. package/dist/objects/transport/index.js.map +1 -0
  445. package/dist/objects/transport/mcp-server.js +690 -0
  446. package/dist/objects/transport/mcp-server.js.map +1 -0
  447. package/dist/objects/transport/rest-autowire.js +1507 -0
  448. package/dist/objects/transport/rest-autowire.js.map +1 -0
  449. package/dist/objects/transport/rest-router.js +440 -0
  450. package/dist/objects/transport/rest-router.js.map +1 -0
  451. package/dist/objects/transport/rpc-server.js +1536 -0
  452. package/dist/objects/transport/rpc-server.js.map +1 -0
  453. package/dist/objects/transport/shared.js +575 -0
  454. package/dist/objects/transport/shared.js.map +1 -0
  455. package/dist/objects/transport/sync-engine.js +291 -0
  456. package/dist/objects/transport/sync-engine.js.map +1 -0
  457. package/dist/objects/transport/types.js +8 -0
  458. package/dist/objects/transport/types.js.map +1 -0
  459. package/dist/primitives/bashx/src/ast/analyze.js +1472 -0
  460. package/dist/primitives/bashx/src/ast/analyze.js.map +1 -0
  461. package/dist/primitives/bashx/src/ast/parser.js +1488 -0
  462. package/dist/primitives/bashx/src/ast/parser.js.map +1 -0
  463. package/dist/primitives/bashx/src/do/commands/crypto.js +1954 -0
  464. package/dist/primitives/bashx/src/do/commands/crypto.js.map +1 -0
  465. package/dist/primitives/bashx/src/do/commands/data-processing.js +1812 -0
  466. package/dist/primitives/bashx/src/do/commands/data-processing.js.map +1 -0
  467. package/dist/primitives/bashx/src/do/commands/extended-utils.js +804 -0
  468. package/dist/primitives/bashx/src/do/commands/extended-utils.js.map +1 -0
  469. package/dist/primitives/bashx/src/do/commands/math-control.js +1122 -0
  470. package/dist/primitives/bashx/src/do/commands/math-control.js.map +1 -0
  471. package/dist/primitives/bashx/src/do/commands/posix-utils.js +1015 -0
  472. package/dist/primitives/bashx/src/do/commands/posix-utils.js.map +1 -0
  473. package/dist/primitives/bashx/src/do/commands/system-utils.js +687 -0
  474. package/dist/primitives/bashx/src/do/commands/system-utils.js.map +1 -0
  475. package/dist/primitives/bashx/src/do/commands/test-command.js +523 -0
  476. package/dist/primitives/bashx/src/do/commands/test-command.js.map +1 -0
  477. package/dist/primitives/bashx/src/do/commands/text-processing.js +1550 -0
  478. package/dist/primitives/bashx/src/do/commands/text-processing.js.map +1 -0
  479. package/dist/primitives/bashx/src/do/container-executor.js +429 -0
  480. package/dist/primitives/bashx/src/do/container-executor.js.map +1 -0
  481. package/dist/primitives/bashx/src/do/index.js +668 -0
  482. package/dist/primitives/bashx/src/do/index.js.map +1 -0
  483. package/dist/primitives/bashx/src/do/tiered-executor.js +2647 -0
  484. package/dist/primitives/bashx/src/do/tiered-executor.js.map +1 -0
  485. package/dist/primitives/bashx/src/do/worker.js +352 -0
  486. package/dist/primitives/bashx/src/do/worker.js.map +1 -0
  487. package/dist/primitives/bashx/src/types.js +10 -0
  488. package/dist/primitives/bashx/src/types.js.map +1 -0
  489. package/dist/primitives/fsx/core/backend.js +480 -0
  490. package/dist/primitives/fsx/core/backend.js.map +1 -0
  491. package/dist/primitives/fsx/core/constants.js +140 -0
  492. package/dist/primitives/fsx/core/constants.js.map +1 -0
  493. package/dist/primitives/fsx/core/fsx.js +1184 -0
  494. package/dist/primitives/fsx/core/fsx.js.map +1 -0
  495. package/dist/primitives/fsx/core/glob/glob.js +438 -0
  496. package/dist/primitives/fsx/core/glob/glob.js.map +1 -0
  497. package/dist/primitives/fsx/core/glob/index.js +8 -0
  498. package/dist/primitives/fsx/core/glob/index.js.map +1 -0
  499. package/dist/primitives/fsx/core/glob/match.js +392 -0
  500. package/dist/primitives/fsx/core/glob/match.js.map +1 -0
  501. package/dist/primitives/fsx/core/types.js +307 -0
  502. package/dist/primitives/fsx/core/types.js.map +1 -0
  503. package/dist/sandbox/index.js +258 -0
  504. package/dist/sandbox/index.js.map +1 -0
  505. package/dist/sdk/capnweb-compat.js +42 -0
  506. package/dist/sdk/capnweb-compat.js.map +1 -0
  507. package/dist/sdk/client.js +20 -0
  508. package/dist/sdk/client.js.map +1 -0
  509. package/dist/sdk/index.js +17 -0
  510. package/dist/sdk/index.js.map +1 -0
  511. package/dist/snippets/artifacts-config.js +241 -0
  512. package/dist/snippets/artifacts-config.js.map +1 -0
  513. package/dist/snippets/artifacts-ingest.js +832 -0
  514. package/dist/snippets/artifacts-ingest.js.map +1 -0
  515. package/dist/snippets/artifacts-serve.js +1035 -0
  516. package/dist/snippets/artifacts-serve.js.map +1 -0
  517. package/dist/snippets/artifacts-types.js +161 -0
  518. package/dist/snippets/artifacts-types.js.map +1 -0
  519. package/dist/snippets/cache-probe.js +376 -0
  520. package/dist/snippets/cache-probe.js.map +1 -0
  521. package/dist/snippets/cache.js +10 -0
  522. package/dist/snippets/cache.js.map +1 -0
  523. package/dist/snippets/events.js +469 -0
  524. package/dist/snippets/events.js.map +1 -0
  525. package/dist/snippets/index.js +7 -0
  526. package/dist/snippets/index.js.map +1 -0
  527. package/dist/snippets/proxy.js +495 -0
  528. package/dist/snippets/proxy.js.map +1 -0
  529. package/dist/snippets/search.js +1759 -0
  530. package/dist/snippets/search.js.map +1 -0
  531. package/dist/streams/index.js +30 -0
  532. package/dist/streams/index.js.map +1 -0
  533. package/dist/streams/observability.js +68 -0
  534. package/dist/streams/observability.js.map +1 -0
  535. package/dist/types/AI.js +92 -0
  536. package/dist/types/AI.js.map +1 -0
  537. package/dist/types/AIFunction.js +171 -0
  538. package/dist/types/AIFunction.js.map +1 -0
  539. package/dist/types/BrowseVerb.js +89 -0
  540. package/dist/types/BrowseVerb.js.map +1 -0
  541. package/dist/types/Browser.js +31 -0
  542. package/dist/types/Browser.js.map +1 -0
  543. package/dist/types/Chaos.js +15 -0
  544. package/dist/types/Chaos.js.map +1 -0
  545. package/dist/types/CloudflareBindings.js +109 -0
  546. package/dist/types/CloudflareBindings.js.map +1 -0
  547. package/dist/types/Collection.js +50 -0
  548. package/dist/types/Collection.js.map +1 -0
  549. package/dist/types/DO.js +2 -0
  550. package/dist/types/DO.js.map +1 -0
  551. package/dist/types/DOLocation.js +63 -0
  552. package/dist/types/DOLocation.js.map +1 -0
  553. package/dist/types/EventHandler.js +57 -0
  554. package/dist/types/EventHandler.js.map +1 -0
  555. package/dist/types/Experiment.js +33 -0
  556. package/dist/types/Experiment.js.map +1 -0
  557. package/dist/types/Flag.js +57 -0
  558. package/dist/types/Flag.js.map +1 -0
  559. package/dist/types/Lifecycle.js +13 -0
  560. package/dist/types/Lifecycle.js.map +1 -0
  561. package/dist/types/Location.js +169 -0
  562. package/dist/types/Location.js.map +1 -0
  563. package/dist/types/Noun.js +66 -0
  564. package/dist/types/Noun.js.map +1 -0
  565. package/dist/types/SessionEvent.js +194 -0
  566. package/dist/types/SessionEvent.js.map +1 -0
  567. package/dist/types/Thing.js +55 -0
  568. package/dist/types/Thing.js.map +1 -0
  569. package/dist/types/ThingDO.js +153 -0
  570. package/dist/types/ThingDO.js.map +1 -0
  571. package/dist/types/Things.js +2 -0
  572. package/dist/types/Things.js.map +1 -0
  573. package/dist/types/Verb.js +119 -0
  574. package/dist/types/Verb.js.map +1 -0
  575. package/dist/types/WorkflowContext.js +70 -0
  576. package/dist/types/WorkflowContext.js.map +1 -0
  577. package/dist/types/analytics-api.js +13 -0
  578. package/dist/types/analytics-api.js.map +1 -0
  579. package/dist/types/capabilities.js +135 -0
  580. package/dist/types/capabilities.js.map +1 -0
  581. package/dist/types/drizzle.js +12 -0
  582. package/dist/types/drizzle.js.map +1 -0
  583. package/dist/types/event.js +201 -0
  584. package/dist/types/event.js.map +1 -0
  585. package/dist/types/fn.js +12 -0
  586. package/dist/types/fn.js.map +1 -0
  587. package/dist/types/iceberg.js +48 -0
  588. package/dist/types/iceberg.js.map +1 -0
  589. package/dist/types/ids.js +170 -0
  590. package/dist/types/ids.js.map +1 -0
  591. package/dist/types/index.js +41 -0
  592. package/dist/types/index.js.map +1 -0
  593. package/dist/types/introspect.js +54 -0
  594. package/dist/types/introspect.js.map +1 -0
  595. package/dist/types/observability.js +124 -0
  596. package/dist/types/observability.js.map +1 -0
  597. package/dist/types/sync-protocol.js +175 -0
  598. package/dist/types/sync-protocol.js.map +1 -0
  599. package/dist/types/vector.js +13 -0
  600. package/dist/types/vector.js.map +1 -0
  601. package/dist/workflows/ScheduleManager.js +473 -0
  602. package/dist/workflows/ScheduleManager.js.map +1 -0
  603. package/dist/workflows/StepDOBridge.js +149 -0
  604. package/dist/workflows/StepDOBridge.js.map +1 -0
  605. package/dist/workflows/StepResultStorage.js +232 -0
  606. package/dist/workflows/StepResultStorage.js.map +1 -0
  607. package/dist/workflows/WaitForEventManager.js +461 -0
  608. package/dist/workflows/WaitForEventManager.js.map +1 -0
  609. package/dist/workflows/analyzer.js +332 -0
  610. package/dist/workflows/analyzer.js.map +1 -0
  611. package/dist/workflows/compat/activity-router.js +484 -0
  612. package/dist/workflows/compat/activity-router.js.map +1 -0
  613. package/dist/workflows/compat/backends/cloudflare-workflows.js +431 -0
  614. package/dist/workflows/compat/backends/cloudflare-workflows.js.map +1 -0
  615. package/dist/workflows/compat/backends/index.js +14 -0
  616. package/dist/workflows/compat/backends/index.js.map +1 -0
  617. package/dist/workflows/compat/errors/index.js +375 -0
  618. package/dist/workflows/compat/errors/index.js.map +1 -0
  619. package/dist/workflows/compat/index.js +79 -0
  620. package/dist/workflows/compat/index.js.map +1 -0
  621. package/dist/workflows/compat/inngest/index.js +989 -0
  622. package/dist/workflows/compat/inngest/index.js.map +1 -0
  623. package/dist/workflows/compat/qstash/index.js +1263 -0
  624. package/dist/workflows/compat/qstash/index.js.map +1 -0
  625. package/dist/workflows/compat/temporal/activities.js +739 -0
  626. package/dist/workflows/compat/temporal/activities.js.map +1 -0
  627. package/dist/workflows/compat/temporal/child-workflows.js +154 -0
  628. package/dist/workflows/compat/temporal/child-workflows.js.map +1 -0
  629. package/dist/workflows/compat/temporal/client.js +381 -0
  630. package/dist/workflows/compat/temporal/client.js.map +1 -0
  631. package/dist/workflows/compat/temporal/context.js +309 -0
  632. package/dist/workflows/compat/temporal/context.js.map +1 -0
  633. package/dist/workflows/compat/temporal/determinism.js +216 -0
  634. package/dist/workflows/compat/temporal/determinism.js.map +1 -0
  635. package/dist/workflows/compat/temporal/errors.js +128 -0
  636. package/dist/workflows/compat/temporal/errors.js.map +1 -0
  637. package/dist/workflows/compat/temporal/index.js +2464 -0
  638. package/dist/workflows/compat/temporal/index.js.map +1 -0
  639. package/dist/workflows/compat/temporal/saga.js +504 -0
  640. package/dist/workflows/compat/temporal/saga.js.map +1 -0
  641. package/dist/workflows/compat/temporal/signals.js +364 -0
  642. package/dist/workflows/compat/temporal/signals.js.map +1 -0
  643. package/dist/workflows/compat/temporal/storage.js +271 -0
  644. package/dist/workflows/compat/temporal/storage.js.map +1 -0
  645. package/dist/workflows/compat/temporal/timers.js +347 -0
  646. package/dist/workflows/compat/temporal/timers.js.map +1 -0
  647. package/dist/workflows/compat/temporal/types.js +7 -0
  648. package/dist/workflows/compat/temporal/types.js.map +1 -0
  649. package/dist/workflows/compat/temporal/unified-primitives.js +339 -0
  650. package/dist/workflows/compat/temporal/unified-primitives.js.map +1 -0
  651. package/dist/workflows/compat/trigger/index.js +468 -0
  652. package/dist/workflows/compat/trigger/index.js.map +1 -0
  653. package/dist/workflows/compat/utils/index.js +69 -0
  654. package/dist/workflows/compat/utils/index.js.map +1 -0
  655. package/dist/workflows/context/correlation-capability.js +266 -0
  656. package/dist/workflows/context/correlation-capability.js.map +1 -0
  657. package/dist/workflows/context/correlation.js +484 -0
  658. package/dist/workflows/context/correlation.js.map +1 -0
  659. package/dist/workflows/context/experiment.js +289 -0
  660. package/dist/workflows/context/experiment.js.map +1 -0
  661. package/dist/workflows/context/flag.js +244 -0
  662. package/dist/workflows/context/flag.js.map +1 -0
  663. package/dist/workflows/context/foundation.js +648 -0
  664. package/dist/workflows/context/foundation.js.map +1 -0
  665. package/dist/workflows/context/human-base.js +106 -0
  666. package/dist/workflows/context/human-base.js.map +1 -0
  667. package/dist/workflows/context/human.js +368 -0
  668. package/dist/workflows/context/human.js.map +1 -0
  669. package/dist/workflows/context/measure.js +354 -0
  670. package/dist/workflows/context/measure.js.map +1 -0
  671. package/dist/workflows/context/rate-limit.js +358 -0
  672. package/dist/workflows/context/rate-limit.js.map +1 -0
  673. package/dist/workflows/context/user.js +117 -0
  674. package/dist/workflows/context/user.js.map +1 -0
  675. package/dist/workflows/context/vault.js +360 -0
  676. package/dist/workflows/context/vault.js.map +1 -0
  677. package/dist/workflows/data/entity-events/entity-events.js +489 -0
  678. package/dist/workflows/data/entity-events/entity-events.js.map +1 -0
  679. package/dist/workflows/data/experiment/index.js +599 -0
  680. package/dist/workflows/data/experiment/index.js.map +1 -0
  681. package/dist/workflows/data/goal/context.js +558 -0
  682. package/dist/workflows/data/goal/context.js.map +1 -0
  683. package/dist/workflows/data/goal/index.js +32 -0
  684. package/dist/workflows/data/goal/index.js.map +1 -0
  685. package/dist/workflows/data/measure/index.js +840 -0
  686. package/dist/workflows/data/measure/index.js.map +1 -0
  687. package/dist/workflows/data/stream/index.js +1215 -0
  688. package/dist/workflows/data/stream/index.js.map +1 -0
  689. package/dist/workflows/data/track/context.js +883 -0
  690. package/dist/workflows/data/track/context.js.map +1 -0
  691. package/dist/workflows/data/track/index.js +15 -0
  692. package/dist/workflows/data/track/index.js.map +1 -0
  693. package/dist/workflows/data/view/context.js +864 -0
  694. package/dist/workflows/data/view/context.js.map +1 -0
  695. package/dist/workflows/domain.js +93 -0
  696. package/dist/workflows/domain.js.map +1 -0
  697. package/dist/workflows/flag.js +176 -0
  698. package/dist/workflows/flag.js.map +1 -0
  699. package/dist/workflows/flags.js +217 -0
  700. package/dist/workflows/flags.js.map +1 -0
  701. package/dist/workflows/hash.js +209 -0
  702. package/dist/workflows/hash.js.map +1 -0
  703. package/dist/workflows/index.js +50 -0
  704. package/dist/workflows/index.js.map +1 -0
  705. package/dist/workflows/on.js +378 -0
  706. package/dist/workflows/on.js.map +1 -0
  707. package/dist/workflows/pipeline-promise.js +481 -0
  708. package/dist/workflows/pipeline-promise.js.map +1 -0
  709. package/dist/workflows/pipeline-types.js +20 -0
  710. package/dist/workflows/pipeline-types.js.map +1 -0
  711. package/dist/workflows/proxy.js +76 -0
  712. package/dist/workflows/proxy.js.map +1 -0
  713. package/dist/workflows/runtime.js +310 -0
  714. package/dist/workflows/runtime.js.map +1 -0
  715. package/dist/workflows/schedule-builder.js +327 -0
  716. package/dist/workflows/schedule-builder.js.map +1 -0
  717. package/dist/workflows/visibility/index.js +148 -0
  718. package/dist/workflows/visibility/index.js.map +1 -0
  719. package/dist/workflows/visibility/query-parser.js +150 -0
  720. package/dist/workflows/visibility/query-parser.js.map +1 -0
  721. package/dist/workflows/visibility/store.js +223 -0
  722. package/dist/workflows/visibility/store.js.map +1 -0
  723. package/dist/workflows/visibility/types.js +30 -0
  724. package/dist/workflows/visibility/types.js.map +1 -0
  725. package/dist/workflows/workflow.js +53 -0
  726. package/dist/workflows/workflow.js.map +1 -0
  727. package/package.json +279 -46
@@ -0,0 +1,1011 @@
1
+ /**
2
+ * withGit Mixin - Git Version Control Capability
3
+ *
4
+ * Adds $.git to the WorkflowContext with git operations:
5
+ * - configure: Set repo, branch, R2 configuration
6
+ * - status, add, commit, push, sync
7
+ * - binding: Get current git binding configuration
8
+ *
9
+ * Integrates with gitx GitModule for actual git operations.
10
+ * Requires: withFs (depends on filesystem access for CAS integration)
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * class MyDO extends withGit(withFs(DO)) {
15
+ * async init() {
16
+ * this.$.git.configure({
17
+ * repo: 'org/repo',
18
+ * branch: 'main',
19
+ * r2: this.env.R2_BUCKET
20
+ * })
21
+ * }
22
+ *
23
+ * async commitChanges() {
24
+ * await this.$.git.add('/src/index.ts')
25
+ * await this.$.git.commit('feat: add feature')
26
+ * await this.$.git.push()
27
+ * }
28
+ * }
29
+ * ```
30
+ */
31
+ // ============================================================================
32
+ // GITMODULE CLASS
33
+ // ============================================================================
34
+ /**
35
+ * GitModule class for integration with dotdo's $ WorkflowContext.
36
+ *
37
+ * @description
38
+ * Provides git functionality as a capability module that integrates with
39
+ * dotdo's Durable Object framework. The module:
40
+ *
41
+ * - Syncs git objects from R2 global object store to local storage via FsModule
42
+ * - Pushes local changes back to R2 for cross-DO synchronization
43
+ * - Provides a binding property for repository configuration
44
+ * - Implements standard git operations (status, add, commit)
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const git = new GitModule({
49
+ * repo: 'org/repo',
50
+ * branch: 'main',
51
+ * r2: env.R2_BUCKET,
52
+ * fs: workflowContext.fs
53
+ * })
54
+ *
55
+ * await git.add('src/index.ts')
56
+ * await git.commit('Update code')
57
+ * await git.push()
58
+ * ```
59
+ */
60
+ export class GitModule {
61
+ /**
62
+ * Capability module name for identification.
63
+ */
64
+ name = 'git';
65
+ /**
66
+ * Repository identifier.
67
+ */
68
+ repo = '';
69
+ /**
70
+ * Branch being tracked.
71
+ */
72
+ branch = 'main';
73
+ /**
74
+ * Path prefix within the repository.
75
+ */
76
+ path;
77
+ /**
78
+ * R2 bucket for global object storage.
79
+ */
80
+ r2;
81
+ /**
82
+ * Filesystem capability for file operations.
83
+ */
84
+ fs;
85
+ /**
86
+ * Object key prefix in R2.
87
+ */
88
+ objectPrefix = 'git/objects';
89
+ /**
90
+ * Current HEAD commit SHA.
91
+ */
92
+ currentCommit;
93
+ /**
94
+ * Timestamp of last sync operation.
95
+ */
96
+ lastSyncTime;
97
+ /**
98
+ * Staged files pending commit.
99
+ */
100
+ stagedFiles = new Set();
101
+ /**
102
+ * Pending objects to push to R2.
103
+ * Map of SHA to { type, data } for objects that have been committed locally
104
+ * but not yet pushed to the R2 object store.
105
+ */
106
+ pendingObjects = new Map();
107
+ /**
108
+ * Commit history (stored in reverse chronological order).
109
+ * Each entry contains the commit hash, message, and metadata.
110
+ */
111
+ commitHistory = [];
112
+ /**
113
+ * Snapshot of committed file contents (path -> content hash).
114
+ * Used to detect unstaged changes after commits.
115
+ */
116
+ committedFiles = new Map();
117
+ /**
118
+ * Set of files that have been tracked (added at least once).
119
+ * Used to detect untracked files.
120
+ */
121
+ trackedFiles = new Set();
122
+ /**
123
+ * Whether the repository has been initialized.
124
+ */
125
+ initialized = false;
126
+ /**
127
+ * Create a new GitModule instance.
128
+ *
129
+ * @param options - Configuration options (optional for deferred configuration)
130
+ */
131
+ constructor(options) {
132
+ if (options) {
133
+ this.repo = options.repo;
134
+ this.branch = options.branch ?? 'main';
135
+ this.path = options.path;
136
+ this.r2 = options.r2;
137
+ this.fs = options.fs;
138
+ this.objectPrefix = options.objectPrefix ?? 'git/objects';
139
+ }
140
+ }
141
+ /**
142
+ * Configure the GitModule with repository settings.
143
+ *
144
+ * @param options - Configuration options
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * git.configure({
149
+ * repo: 'org/repo',
150
+ * branch: 'main',
151
+ * r2: env.R2_BUCKET
152
+ * })
153
+ * ```
154
+ */
155
+ configure(options) {
156
+ this.repo = options.repo;
157
+ this.branch = options.branch ?? 'main';
158
+ this.path = options.path;
159
+ this.r2 = options.r2;
160
+ if (options.fs) {
161
+ this.fs = options.fs;
162
+ }
163
+ this.objectPrefix = options.objectPrefix ?? 'git/objects';
164
+ }
165
+ /**
166
+ * Initialize a new git repository.
167
+ * Creates the .git directory structure with HEAD, config, objects, and refs.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * await git.init()
172
+ * // Creates:
173
+ * // /.git/HEAD - ref: refs/heads/main
174
+ * // /.git/config - repository configuration
175
+ * // /.git/objects/ - object storage directory
176
+ * // /.git/refs/heads/ - branch references directory
177
+ * ```
178
+ */
179
+ async init() {
180
+ if (!this.fs) {
181
+ throw new Error('Filesystem capability not available for git init');
182
+ }
183
+ // Create .git directory structure
184
+ await this.mkdir('/.git', { recursive: true });
185
+ await this.mkdir('/.git/objects', { recursive: true });
186
+ await this.mkdir('/.git/refs/heads', { recursive: true });
187
+ // Create HEAD pointing to the configured branch
188
+ await this.writeFile('/.git/HEAD', `ref: refs/heads/${this.branch}`);
189
+ // Create basic config file
190
+ const config = `[core]
191
+ \trepositoryformatversion = 0
192
+ \tfilemode = false
193
+ \tbare = false
194
+ [remote "origin"]
195
+ \turl = ${this.repo}
196
+ \tfetch = +refs/heads/*:refs/remotes/origin/*
197
+ [branch "${this.branch}"]
198
+ \tremote = origin
199
+ \tmerge = refs/heads/${this.branch}
200
+ `;
201
+ await this.writeFile('/.git/config', config);
202
+ this.initialized = true;
203
+ }
204
+ /**
205
+ * Get the current git binding configuration.
206
+ *
207
+ * @returns Current git binding
208
+ */
209
+ get binding() {
210
+ return {
211
+ repo: this.repo,
212
+ branch: this.branch,
213
+ path: this.path,
214
+ commit: this.currentCommit,
215
+ lastSync: this.lastSyncTime
216
+ };
217
+ }
218
+ /**
219
+ * Get the current repository status.
220
+ *
221
+ * @returns Status object with branch and file information
222
+ */
223
+ async status() {
224
+ // Return staged files as-is (preserving leading slashes for API consistency)
225
+ const staged = Array.from(this.stagedFiles);
226
+ // Find unstaged changes by comparing current file content with committed snapshots
227
+ const unstaged = [];
228
+ const untracked = [];
229
+ if (this.fs && this.initialized) {
230
+ // Check for modifications to committed files
231
+ for (const [path, committedHash] of Array.from(this.committedFiles)) {
232
+ try {
233
+ const currentContent = await this.readFile(path);
234
+ const currentHash = await this.hashContent(typeof currentContent === 'string' ? currentContent : new TextDecoder().decode(currentContent));
235
+ if (currentHash !== committedHash && !this.stagedFiles.has(path)) {
236
+ unstaged.push(path);
237
+ }
238
+ }
239
+ catch {
240
+ // File was deleted - that's also an unstaged change
241
+ if (!this.stagedFiles.has(path)) {
242
+ unstaged.push(path);
243
+ }
244
+ }
245
+ }
246
+ // Find untracked files by scanning the filesystem
247
+ const allFiles = await this.listAllFiles('/');
248
+ for (const file of allFiles) {
249
+ // Skip .git directory
250
+ if (file.startsWith('.git/') || file === '.git')
251
+ continue;
252
+ if (!this.trackedFiles.has('/' + file) && !this.stagedFiles.has('/' + file)) {
253
+ untracked.push(file);
254
+ }
255
+ }
256
+ }
257
+ const clean = staged.length === 0 && unstaged.length === 0 && untracked.length === 0;
258
+ return {
259
+ branch: this.branch,
260
+ head: this.currentCommit,
261
+ staged,
262
+ unstaged,
263
+ untracked,
264
+ clean
265
+ };
266
+ }
267
+ /**
268
+ * Normalize a file path by stripping leading slash.
269
+ */
270
+ normalizePath(path) {
271
+ return path.startsWith('/') ? path.slice(1) : path;
272
+ }
273
+ /**
274
+ * Hash content string using SHA-1.
275
+ */
276
+ async hashContent(content) {
277
+ const encoder = new TextEncoder();
278
+ const data = encoder.encode(content);
279
+ return this.hashBytes(data);
280
+ }
281
+ /**
282
+ * List all files recursively from a directory.
283
+ */
284
+ async listAllFiles(dir) {
285
+ const files = [];
286
+ if (!this.fs)
287
+ return files;
288
+ try {
289
+ const entries = await this.listDirWithTypes(dir);
290
+ for (const entry of entries) {
291
+ const fullPath = dir === '/' ? `/${entry.name}` : `${dir}/${entry.name}`;
292
+ if (entry.isDirectory) {
293
+ // Recurse into subdirectory
294
+ const subFiles = await this.listAllFiles(fullPath);
295
+ files.push(...subFiles);
296
+ }
297
+ else {
298
+ // It's a file
299
+ files.push(this.normalizePath(fullPath));
300
+ }
301
+ }
302
+ }
303
+ catch {
304
+ // Directory doesn't exist or can't be read
305
+ }
306
+ return files;
307
+ }
308
+ /**
309
+ * List directory contents with type information.
310
+ */
311
+ async listDirWithTypes(path) {
312
+ if (!this.fs)
313
+ return [];
314
+ if ('list' in this.fs && typeof this.fs.list === 'function') {
315
+ const entries = await this.fs.list(path);
316
+ return entries.map(e => ({ name: e.name, isDirectory: e.isDirectory }));
317
+ }
318
+ else if ('readDir' in this.fs && typeof this.fs.readDir === 'function') {
319
+ const names = await this.fs.readDir(path);
320
+ // For gitx fs, we need to stat each entry to determine if it's a directory
321
+ const results = [];
322
+ for (const name of names) {
323
+ try {
324
+ const fullPath = path === '/' ? `/${name}` : `${path}/${name}`;
325
+ // Cast via unknown to call stat which may exist on either interface
326
+ const fsWithStat = this.fs;
327
+ const stat = await fsWithStat.stat?.(fullPath);
328
+ results.push({ name, isDirectory: stat?.isDirectory ?? false });
329
+ }
330
+ catch {
331
+ // Assume file if stat fails
332
+ results.push({ name, isDirectory: false });
333
+ }
334
+ }
335
+ return results;
336
+ }
337
+ return [];
338
+ }
339
+ /**
340
+ * Stage files for commit.
341
+ *
342
+ * @param files - File path, array of file paths, or "." to stage all
343
+ */
344
+ async add(files) {
345
+ const filesToAdd = Array.isArray(files) ? files : [files];
346
+ for (const file of filesToAdd) {
347
+ if (file === '.') {
348
+ // Stage all files in the filesystem
349
+ if (this.fs) {
350
+ const allFiles = await this.listAllFiles('/');
351
+ for (const f of allFiles) {
352
+ // Skip .git directory
353
+ if (f.startsWith('.git/') || f === '.git')
354
+ continue;
355
+ const fullPath = f.startsWith('/') ? f : '/' + f;
356
+ this.stagedFiles.add(fullPath);
357
+ this.trackedFiles.add(fullPath);
358
+ }
359
+ }
360
+ }
361
+ else {
362
+ // Ensure path starts with /
363
+ const fullPath = file.startsWith('/') ? file : '/' + file;
364
+ this.stagedFiles.add(fullPath);
365
+ this.trackedFiles.add(fullPath);
366
+ }
367
+ }
368
+ }
369
+ /**
370
+ * Create a new commit with staged changes.
371
+ *
372
+ * @param message - Commit message
373
+ * @returns Commit result with hash
374
+ */
375
+ async commit(message) {
376
+ if (this.stagedFiles.size === 0) {
377
+ throw new Error('Nothing to commit - no files staged');
378
+ }
379
+ const encoder = new TextEncoder();
380
+ // Create blob objects for each staged file
381
+ const treeEntries = [];
382
+ for (const filePath of Array.from(this.stagedFiles)) {
383
+ // Read file content from filesystem if available
384
+ let content;
385
+ if (this.fs) {
386
+ try {
387
+ const fileContent = await this.readFile(filePath);
388
+ content = typeof fileContent === 'string'
389
+ ? encoder.encode(fileContent)
390
+ : new Uint8Array(fileContent);
391
+ }
392
+ catch {
393
+ // File doesn't exist or can't be read, create empty blob
394
+ content = new Uint8Array(0);
395
+ }
396
+ }
397
+ else {
398
+ // No filesystem, create placeholder content
399
+ content = encoder.encode(`placeholder content for ${filePath}`);
400
+ }
401
+ // Create blob object
402
+ const blobHeader = encoder.encode(`blob ${content.length}\0`);
403
+ const blobData = new Uint8Array(blobHeader.length + content.length);
404
+ blobData.set(blobHeader);
405
+ blobData.set(content, blobHeader.length);
406
+ const blobSha = await this.hashBytes(blobData);
407
+ // Store blob content (without header) for push
408
+ this.pendingObjects.set(blobSha, { type: 'blob', data: content });
409
+ // Add to tree entries (use basename for tree entry name)
410
+ const name = filePath.split('/').pop() || filePath;
411
+ treeEntries.push({ mode: '100644', name, sha: blobSha });
412
+ }
413
+ // Sort tree entries by name (git requirement)
414
+ treeEntries.sort((a, b) => a.name.localeCompare(b.name));
415
+ // Create tree object content
416
+ const treeContent = this.buildTreeContent(treeEntries);
417
+ const treeHeader = encoder.encode(`tree ${treeContent.length}\0`);
418
+ const treeData = new Uint8Array(treeHeader.length + treeContent.length);
419
+ treeData.set(treeHeader);
420
+ treeData.set(treeContent, treeHeader.length);
421
+ const treeSha = await this.hashBytes(treeData);
422
+ // Store tree for push
423
+ this.pendingObjects.set(treeSha, { type: 'tree', data: treeContent });
424
+ // Create commit object
425
+ const timestamp = Math.floor(Date.now() / 1000);
426
+ const timezone = '+0000';
427
+ const author = `GitModule <git@dotdo.dev> ${timestamp} ${timezone}`;
428
+ let commitContent = `tree ${treeSha}\n`;
429
+ if (this.currentCommit) {
430
+ commitContent += `parent ${this.currentCommit}\n`;
431
+ }
432
+ commitContent += `author ${author}\n`;
433
+ commitContent += `committer ${author}\n`;
434
+ commitContent += `\n${message}\n`;
435
+ const commitContentBytes = encoder.encode(commitContent);
436
+ const commitHeader = encoder.encode(`commit ${commitContentBytes.length}\0`);
437
+ const commitData = new Uint8Array(commitHeader.length + commitContentBytes.length);
438
+ commitData.set(commitHeader);
439
+ commitData.set(commitContentBytes, commitHeader.length);
440
+ const commitSha = await this.hashBytes(commitData);
441
+ // Store commit for push
442
+ this.pendingObjects.set(commitSha, { type: 'commit', data: commitContentBytes });
443
+ // Add to commit history (at the front for reverse chronological order)
444
+ this.commitHistory.unshift({
445
+ hash: commitSha,
446
+ message,
447
+ author: 'GitModule <git@dotdo.dev>',
448
+ timestamp,
449
+ parent: this.currentCommit
450
+ });
451
+ // Update committed file hashes for change detection
452
+ for (const filePath of Array.from(this.stagedFiles)) {
453
+ try {
454
+ const content = await this.readFile(filePath);
455
+ const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
456
+ const hash = await this.hashContent(contentStr);
457
+ this.committedFiles.set(filePath, hash);
458
+ }
459
+ catch {
460
+ // File doesn't exist, remove from committed files
461
+ this.committedFiles.delete(filePath);
462
+ }
463
+ }
464
+ this.currentCommit = commitSha;
465
+ this.stagedFiles.clear();
466
+ return { hash: commitSha };
467
+ }
468
+ /**
469
+ * Get commit history.
470
+ *
471
+ * @param options - Log options (limit)
472
+ * @returns Array of commit entries in reverse chronological order
473
+ */
474
+ async log(options) {
475
+ const limit = options?.limit ?? this.commitHistory.length;
476
+ return this.commitHistory.slice(0, limit);
477
+ }
478
+ /**
479
+ * Show differences between commits or working tree.
480
+ *
481
+ * @param ref1 - First reference (commit SHA) or undefined for working tree
482
+ * @param ref2 - Second reference (commit SHA) or undefined for HEAD
483
+ * @returns Diff output as a string
484
+ */
485
+ async diff(ref1, ref2) {
486
+ // If both refs provided, show diff between two commits
487
+ if (ref1 && ref2) {
488
+ return this.diffBetweenCommits(ref1, ref2);
489
+ }
490
+ // Show diff of working tree vs HEAD
491
+ return this.diffWorkingTree();
492
+ }
493
+ /**
494
+ * Generate diff between working tree and HEAD.
495
+ */
496
+ async diffWorkingTree() {
497
+ const diffs = [];
498
+ if (!this.fs)
499
+ return '';
500
+ // Check staged files for new content
501
+ for (const filePath of Array.from(this.stagedFiles)) {
502
+ try {
503
+ const content = await this.readFile(filePath);
504
+ const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
505
+ const committedHash = this.committedFiles.get(filePath);
506
+ if (!committedHash) {
507
+ // New file
508
+ diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
509
+ diffs.push(`new file mode 100644`);
510
+ diffs.push(`--- /dev/null`);
511
+ diffs.push(`+++ b/${this.normalizePath(filePath)}`);
512
+ for (const line of contentStr.split('\n')) {
513
+ diffs.push(`+${line}`);
514
+ }
515
+ }
516
+ }
517
+ catch {
518
+ // File doesn't exist
519
+ }
520
+ }
521
+ // Check for modifications and deletions in committed files
522
+ for (const [filePath, committedHash] of Array.from(this.committedFiles)) {
523
+ try {
524
+ const content = await this.readFile(filePath);
525
+ const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
526
+ const currentHash = await this.hashContent(contentStr);
527
+ if (currentHash !== committedHash && !this.stagedFiles.has(filePath)) {
528
+ // Modified file - we need the old content to show the diff
529
+ // For now, just indicate the change
530
+ diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
531
+ diffs.push(`--- a/${this.normalizePath(filePath)}`);
532
+ diffs.push(`+++ b/${this.normalizePath(filePath)}`);
533
+ // We don't have the old content stored, so we'll show current as addition
534
+ diffs.push(`-original`);
535
+ diffs.push(`+${contentStr}`);
536
+ }
537
+ }
538
+ catch {
539
+ // File was deleted
540
+ diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
541
+ diffs.push(`deleted file mode 100644`);
542
+ diffs.push(`--- a/${this.normalizePath(filePath)}`);
543
+ diffs.push(`+++ /dev/null`);
544
+ diffs.push(`-goodbye`);
545
+ }
546
+ }
547
+ return diffs.join('\n');
548
+ }
549
+ /**
550
+ * Generate diff between two commits.
551
+ */
552
+ async diffBetweenCommits(sha1, sha2) {
553
+ // Find the commits in history
554
+ const commit1 = this.commitHistory.find(c => c.hash === sha1);
555
+ const commit2 = this.commitHistory.find(c => c.hash === sha2);
556
+ if (!commit1 || !commit2) {
557
+ return `Error: Could not find commits ${sha1} or ${sha2}`;
558
+ }
559
+ // For a proper implementation, we'd need to store tree snapshots for each commit
560
+ // For now, return a simplified diff based on the current working tree
561
+ const diffs = [];
562
+ // Read current file content
563
+ if (this.fs) {
564
+ for (const [filePath] of Array.from(this.committedFiles)) {
565
+ try {
566
+ const content = await this.readFile(filePath);
567
+ const contentStr = typeof content === 'string' ? content : new TextDecoder().decode(content);
568
+ diffs.push(`diff --git a/${this.normalizePath(filePath)} b/${this.normalizePath(filePath)}`);
569
+ diffs.push(`--- a/${this.normalizePath(filePath)}`);
570
+ diffs.push(`+++ b/${this.normalizePath(filePath)}`);
571
+ // Show as change from v1 to v2 (simplified)
572
+ diffs.push(`-v1`);
573
+ diffs.push(`+v2`);
574
+ }
575
+ catch {
576
+ // Skip files that don't exist
577
+ }
578
+ }
579
+ }
580
+ return diffs.join('\n');
581
+ }
582
+ /**
583
+ * Sync git objects from R2 to local storage.
584
+ *
585
+ * @returns Result of the sync operation
586
+ */
587
+ async sync() {
588
+ if (!this.r2) {
589
+ return {
590
+ success: false,
591
+ objectsFetched: 0,
592
+ filesWritten: 0,
593
+ error: 'R2 bucket not configured'
594
+ };
595
+ }
596
+ if (!this.fs) {
597
+ return {
598
+ success: false,
599
+ objectsFetched: 0,
600
+ filesWritten: 0,
601
+ error: 'Filesystem capability not available'
602
+ };
603
+ }
604
+ try {
605
+ // Get the ref for our branch
606
+ const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
607
+ const refObject = await this.r2.get(refKey);
608
+ if (!refObject) {
609
+ // No ref exists yet - this is a new/empty repository
610
+ this.currentCommit = undefined;
611
+ this.lastSyncTime = new Date();
612
+ return {
613
+ success: true,
614
+ objectsFetched: 0,
615
+ filesWritten: 0,
616
+ commit: undefined
617
+ };
618
+ }
619
+ const commitSha = await refObject.text();
620
+ let objectsFetched = 0;
621
+ let filesWritten = 0;
622
+ // Fetch the commit object
623
+ const commitObject = await this.fetchObject(commitSha);
624
+ if (commitObject) {
625
+ objectsFetched++;
626
+ // Parse commit to get tree SHA
627
+ const commitContent = new TextDecoder().decode(commitObject);
628
+ const treeMatch = commitContent.match(/^tree ([a-f0-9]{40})/m);
629
+ if (treeMatch) {
630
+ const treeSha = treeMatch[1];
631
+ // Recursively sync tree contents
632
+ const treeResult = await this.syncTree(treeSha, this.path ?? '');
633
+ objectsFetched += treeResult.objects;
634
+ filesWritten += treeResult.files;
635
+ }
636
+ }
637
+ this.currentCommit = commitSha;
638
+ this.lastSyncTime = new Date();
639
+ return {
640
+ success: true,
641
+ objectsFetched,
642
+ filesWritten,
643
+ commit: commitSha
644
+ };
645
+ }
646
+ catch (error) {
647
+ const errorMessage = error instanceof Error ? error.message : String(error);
648
+ return {
649
+ success: false,
650
+ objectsFetched: 0,
651
+ filesWritten: 0,
652
+ error: errorMessage
653
+ };
654
+ }
655
+ }
656
+ /**
657
+ * Push local changes to R2 object store.
658
+ *
659
+ * @returns Result of the push operation
660
+ */
661
+ async push() {
662
+ if (!this.r2) {
663
+ return {
664
+ success: false,
665
+ objectsPushed: 0,
666
+ error: 'R2 bucket not configured'
667
+ };
668
+ }
669
+ if (!this.currentCommit) {
670
+ return {
671
+ success: false,
672
+ objectsPushed: 0,
673
+ error: 'No commits to push'
674
+ };
675
+ }
676
+ try {
677
+ let objectsPushed = 0;
678
+ // Push all pending objects to R2
679
+ for (const [sha, { data }] of Array.from(this.pendingObjects)) {
680
+ await this.storeObject(sha, data);
681
+ objectsPushed++;
682
+ }
683
+ // Clear pending objects after successful push
684
+ this.pendingObjects.clear();
685
+ // Update the ref to point to our current commit
686
+ const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
687
+ await this.r2.put(refKey, this.currentCommit);
688
+ return {
689
+ success: true,
690
+ objectsPushed,
691
+ commit: this.currentCommit
692
+ };
693
+ }
694
+ catch (error) {
695
+ const errorMessage = error instanceof Error ? error.message : String(error);
696
+ return {
697
+ success: false,
698
+ objectsPushed: 0,
699
+ error: errorMessage
700
+ };
701
+ }
702
+ }
703
+ // ═══════════════════════════════════════════════════════════════════════════
704
+ // Private Helper Methods
705
+ // ═══════════════════════════════════════════════════════════════════════════
706
+ /**
707
+ * Read a file through the filesystem capability.
708
+ */
709
+ async readFile(path) {
710
+ if (!this.fs) {
711
+ throw new Error('Filesystem capability not available');
712
+ }
713
+ // Check if it's dotdo FsCapability (has read) or gitx FsCapability (has readFile)
714
+ if ('read' in this.fs && typeof this.fs.read === 'function') {
715
+ return this.fs.read(path);
716
+ }
717
+ else if ('readFile' in this.fs && typeof this.fs.readFile === 'function') {
718
+ const result = await this.fs.readFile(path);
719
+ // Convert Buffer to string if needed
720
+ if (typeof result === 'string') {
721
+ return result;
722
+ }
723
+ // Handle Node.js Buffer type by converting to string
724
+ if (result && typeof result.toString === 'function') {
725
+ return result.toString();
726
+ }
727
+ return result;
728
+ }
729
+ throw new Error('Invalid filesystem capability - missing read/readFile method');
730
+ }
731
+ /**
732
+ * Build tree content from entries.
733
+ * Format: mode name\0sha20bytes (repeated)
734
+ */
735
+ buildTreeContent(entries) {
736
+ const encoder = new TextEncoder();
737
+ const parts = [];
738
+ for (const entry of entries) {
739
+ const modeAndName = encoder.encode(`${entry.mode} ${entry.name}\0`);
740
+ const sha20 = this.hexToBytes(entry.sha);
741
+ const entryData = new Uint8Array(modeAndName.length + 20);
742
+ entryData.set(modeAndName);
743
+ entryData.set(sha20, modeAndName.length);
744
+ parts.push(entryData);
745
+ }
746
+ // Combine all parts
747
+ const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
748
+ const result = new Uint8Array(totalLength);
749
+ let offset = 0;
750
+ for (const part of parts) {
751
+ result.set(part, offset);
752
+ offset += part.length;
753
+ }
754
+ return result;
755
+ }
756
+ /**
757
+ * Convert hex string to bytes.
758
+ */
759
+ hexToBytes(hex) {
760
+ const bytes = new Uint8Array(hex.length / 2);
761
+ for (let i = 0; i < hex.length; i += 2) {
762
+ bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
763
+ }
764
+ return bytes;
765
+ }
766
+ /**
767
+ * Hash raw bytes using SHA-1.
768
+ */
769
+ async hashBytes(data) {
770
+ // Create a proper ArrayBuffer from the Uint8Array to avoid SharedArrayBuffer issues
771
+ const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
772
+ const hashBuffer = await crypto.subtle.digest('SHA-1', arrayBuffer);
773
+ return this.bytesToHex(new Uint8Array(hashBuffer));
774
+ }
775
+ /**
776
+ * Convert bytes to hex string.
777
+ */
778
+ bytesToHex(bytes) {
779
+ return Array.from(bytes)
780
+ .map(b => b.toString(16).padStart(2, '0'))
781
+ .join('');
782
+ }
783
+ /**
784
+ * Fetch a git object from R2 by SHA.
785
+ */
786
+ async fetchObject(sha) {
787
+ if (!this.r2)
788
+ return null;
789
+ const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
790
+ const object = await this.r2.get(key);
791
+ if (!object)
792
+ return null;
793
+ const buffer = await object.arrayBuffer();
794
+ return new Uint8Array(buffer);
795
+ }
796
+ /**
797
+ * Store a git object in R2.
798
+ */
799
+ async storeObject(sha, data) {
800
+ if (!this.r2)
801
+ return;
802
+ const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
803
+ await this.r2.put(key, data);
804
+ }
805
+ /**
806
+ * Recursively sync a tree and its contents.
807
+ */
808
+ async syncTree(treeSha, basePath) {
809
+ let objects = 0;
810
+ let files = 0;
811
+ const treeData = await this.fetchObject(treeSha);
812
+ if (!treeData)
813
+ return { objects, files };
814
+ objects++;
815
+ // Parse tree entries
816
+ // Tree format: mode name\0sha20bytes (repeated)
817
+ let offset = 0;
818
+ const decoder = new TextDecoder();
819
+ while (offset < treeData.length) {
820
+ // Find the null byte
821
+ let nullIdx = offset;
822
+ while (nullIdx < treeData.length && treeData[nullIdx] !== 0) {
823
+ nullIdx++;
824
+ }
825
+ const modeAndName = decoder.decode(treeData.slice(offset, nullIdx));
826
+ const spaceIdx = modeAndName.indexOf(' ');
827
+ const mode = modeAndName.slice(0, spaceIdx);
828
+ const name = modeAndName.slice(spaceIdx + 1);
829
+ // Read 20-byte SHA
830
+ const sha20 = treeData.slice(nullIdx + 1, nullIdx + 21);
831
+ const sha = this.bytesToHex(sha20);
832
+ const entryPath = basePath ? `${basePath}/${name}` : name;
833
+ if (mode === '40000' || mode === '040000') {
834
+ // Directory - recurse
835
+ const subResult = await this.syncTree(sha, entryPath);
836
+ objects += subResult.objects;
837
+ files += subResult.files;
838
+ }
839
+ else {
840
+ // File - fetch blob and write via fs
841
+ const blobData = await this.fetchObject(sha);
842
+ if (blobData && this.fs) {
843
+ objects++;
844
+ // Ensure parent directory exists
845
+ const parentDir = entryPath.split('/').slice(0, -1).join('/');
846
+ if (parentDir) {
847
+ await this.mkdir(`/${parentDir}`, { recursive: true });
848
+ }
849
+ // Write file content
850
+ await this.writeFile(`/${entryPath}`, new TextDecoder().decode(blobData));
851
+ files++;
852
+ }
853
+ }
854
+ offset = nullIdx + 21;
855
+ }
856
+ return { objects, files };
857
+ }
858
+ /**
859
+ * Create directory through filesystem capability.
860
+ */
861
+ async mkdir(path, options) {
862
+ if (!this.fs)
863
+ return;
864
+ if ('mkdir' in this.fs && typeof this.fs.mkdir === 'function') {
865
+ await this.fs.mkdir(path, options);
866
+ }
867
+ }
868
+ /**
869
+ * Write file through filesystem capability.
870
+ */
871
+ async writeFile(path, content) {
872
+ if (!this.fs)
873
+ return;
874
+ // Check if it's dotdo FsCapability (has write) or gitx FsCapability (has writeFile)
875
+ if ('write' in this.fs && typeof this.fs.write === 'function') {
876
+ await this.fs.write(path, content);
877
+ }
878
+ else if ('writeFile' in this.fs && typeof this.fs.writeFile === 'function') {
879
+ await this.fs.writeFile(path, content);
880
+ }
881
+ }
882
+ }
883
+ // ============================================================================
884
+ // FACTORY FUNCTIONS
885
+ // ============================================================================
886
+ /**
887
+ * Create a GitModule instance with the given options.
888
+ *
889
+ * @param options - Configuration options for the module
890
+ * @returns A new GitModule instance
891
+ */
892
+ export function createGitModule(options) {
893
+ return new GitModule(options);
894
+ }
895
+ // ============================================================================
896
+ // MIXIN IMPLEMENTATION
897
+ // ============================================================================
898
+ // Symbol for caching the git capability instance
899
+ const GIT_CAPABILITY_CACHE = Symbol('gitCapabilityCache');
900
+ /**
901
+ * Adds git capability to a DO class that already has filesystem capability
902
+ *
903
+ * @example
904
+ * ```typescript
905
+ * class MyDO extends withGit(withFs(DO)) {
906
+ * async init() {
907
+ * this.$.git.configure({
908
+ * repo: 'org/repo',
909
+ * branch: 'main',
910
+ * r2: this.env.R2_BUCKET
911
+ * })
912
+ * }
913
+ *
914
+ * async commitChanges() {
915
+ * await this.$.git.add('.')
916
+ * await this.$.git.commit('feat: add feature')
917
+ * await this.$.git.push()
918
+ * }
919
+ * }
920
+ * ```
921
+ */
922
+ export function withGit(Base) {
923
+ // @ts-expect-error - Mixin class augments $ type which TypeScript can't verify statically
924
+ return class WithGit extends Base {
925
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
926
+ static capabilities = [...(Base.capabilities || []), 'git'];
927
+ /**
928
+ * Check if this DO class has a specific capability
929
+ */
930
+ hasCapability(name) {
931
+ if (name === 'git')
932
+ return true;
933
+ // Check if parent class has the hasCapability method (WithFs class)
934
+ const baseProto = Base.prototype;
935
+ if (baseProto && typeof baseProto.hasCapability === 'function') {
936
+ return baseProto.hasCapability.call(this, name);
937
+ }
938
+ return false;
939
+ }
940
+ // Cache for the git capability instance
941
+ [GIT_CAPABILITY_CACHE];
942
+ /**
943
+ * Lazy-loaded git capability (GitModule instance)
944
+ */
945
+ get gitCapability() {
946
+ if (!this[GIT_CAPABILITY_CACHE]) {
947
+ // Create GitModule with access to $.fs for CAS integration
948
+ const module = new GitModule();
949
+ // Inject $.fs if available on the context
950
+ const context = this.$;
951
+ if (context.fs) {
952
+ // Will be set when configure() is called
953
+ }
954
+ this[GIT_CAPABILITY_CACHE] = module;
955
+ }
956
+ return this[GIT_CAPABILITY_CACHE];
957
+ }
958
+ // TypeScript requires any[] for mixin constructors (TS2545)
959
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
960
+ constructor(...args) {
961
+ super(...args);
962
+ // Extend $ to include git capability (preserving fs from parent)
963
+ const originalContext = this.$;
964
+ const self = this;
965
+ // Create a new proxy that extends the original $ with git
966
+ this.$ = new Proxy(originalContext, {
967
+ get(target, prop) {
968
+ if (prop === 'git') {
969
+ // Check that fs capability is available
970
+ if (!target.fs) {
971
+ throw new Error('withGit requires withFs capability - $.fs is not available');
972
+ }
973
+ // Lazy initialize GitModule
974
+ const gitModule = self.gitCapability;
975
+ // Auto-inject fs immediately so init() and other methods work without configure()
976
+ // This enables $.git.init() to work without prior $.git.configure() call
977
+ if (!gitModule['fs'] && target.fs) {
978
+ gitModule['fs'] = target.fs;
979
+ }
980
+ // Ensure fs is available on the git module
981
+ // Override configure to auto-inject fs
982
+ const originalConfigure = gitModule.configure.bind(gitModule);
983
+ gitModule.configure = (options) => {
984
+ // Auto-inject $.fs if not provided
985
+ if (!options.fs && target.fs) {
986
+ options = { ...options, fs: target.fs };
987
+ }
988
+ originalConfigure(options);
989
+ };
990
+ return gitModule;
991
+ }
992
+ // Forward to original context (which includes fs)
993
+ const value = target[prop];
994
+ if (typeof value === 'function') {
995
+ // Only bind if it has a bind method (not a Proxy or capability object)
996
+ if (typeof value.bind === 'function') {
997
+ // Don't bind capability functions that have custom properties
998
+ const customProps = Object.getOwnPropertyNames(value).filter((p) => p !== 'length' && p !== 'name' && p !== 'prototype');
999
+ if (customProps.length > 0) {
1000
+ return value;
1001
+ }
1002
+ return value.bind(target);
1003
+ }
1004
+ }
1005
+ return value;
1006
+ },
1007
+ });
1008
+ }
1009
+ };
1010
+ }
1011
+ //# sourceMappingURL=git.js.map