gitx.do 0.1.0 → 0.1.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 (344) hide show
  1. package/README.md +40 -353
  2. package/dist/do/logger.d.ts +50 -0
  3. package/dist/do/logger.d.ts.map +1 -0
  4. package/dist/do/logger.js +122 -0
  5. package/dist/do/logger.js.map +1 -0
  6. package/dist/{durable-object → do}/schema.d.ts +3 -3
  7. package/dist/do/schema.d.ts.map +1 -0
  8. package/dist/{durable-object → do}/schema.js +4 -3
  9. package/dist/do/schema.js.map +1 -0
  10. package/dist/do/types.d.ts +267 -0
  11. package/dist/do/types.d.ts.map +1 -0
  12. package/dist/do/types.js +62 -0
  13. package/dist/do/types.js.map +1 -0
  14. package/dist/index.d.ts +15 -415
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +31 -483
  17. package/dist/index.js.map +1 -1
  18. package/package.json +13 -21
  19. package/dist/cli/commands/add.d.ts +0 -174
  20. package/dist/cli/commands/add.d.ts.map +0 -1
  21. package/dist/cli/commands/add.js +0 -131
  22. package/dist/cli/commands/add.js.map +0 -1
  23. package/dist/cli/commands/blame.d.ts +0 -259
  24. package/dist/cli/commands/blame.d.ts.map +0 -1
  25. package/dist/cli/commands/blame.js +0 -609
  26. package/dist/cli/commands/blame.js.map +0 -1
  27. package/dist/cli/commands/branch.d.ts +0 -249
  28. package/dist/cli/commands/branch.d.ts.map +0 -1
  29. package/dist/cli/commands/branch.js +0 -693
  30. package/dist/cli/commands/branch.js.map +0 -1
  31. package/dist/cli/commands/commit.d.ts +0 -182
  32. package/dist/cli/commands/commit.d.ts.map +0 -1
  33. package/dist/cli/commands/commit.js +0 -437
  34. package/dist/cli/commands/commit.js.map +0 -1
  35. package/dist/cli/commands/diff.d.ts +0 -464
  36. package/dist/cli/commands/diff.d.ts.map +0 -1
  37. package/dist/cli/commands/diff.js +0 -958
  38. package/dist/cli/commands/diff.js.map +0 -1
  39. package/dist/cli/commands/log.d.ts +0 -239
  40. package/dist/cli/commands/log.d.ts.map +0 -1
  41. package/dist/cli/commands/log.js +0 -535
  42. package/dist/cli/commands/log.js.map +0 -1
  43. package/dist/cli/commands/merge.d.ts +0 -106
  44. package/dist/cli/commands/merge.d.ts.map +0 -1
  45. package/dist/cli/commands/merge.js +0 -55
  46. package/dist/cli/commands/merge.js.map +0 -1
  47. package/dist/cli/commands/review.d.ts +0 -457
  48. package/dist/cli/commands/review.d.ts.map +0 -1
  49. package/dist/cli/commands/review.js +0 -533
  50. package/dist/cli/commands/review.js.map +0 -1
  51. package/dist/cli/commands/status.d.ts +0 -269
  52. package/dist/cli/commands/status.d.ts.map +0 -1
  53. package/dist/cli/commands/status.js +0 -493
  54. package/dist/cli/commands/status.js.map +0 -1
  55. package/dist/cli/commands/web.d.ts +0 -199
  56. package/dist/cli/commands/web.d.ts.map +0 -1
  57. package/dist/cli/commands/web.js +0 -696
  58. package/dist/cli/commands/web.js.map +0 -1
  59. package/dist/cli/fs-adapter.d.ts +0 -656
  60. package/dist/cli/fs-adapter.d.ts.map +0 -1
  61. package/dist/cli/fs-adapter.js +0 -1179
  62. package/dist/cli/fs-adapter.js.map +0 -1
  63. package/dist/cli/fsx-cli-adapter.d.ts +0 -359
  64. package/dist/cli/fsx-cli-adapter.d.ts.map +0 -1
  65. package/dist/cli/fsx-cli-adapter.js +0 -619
  66. package/dist/cli/fsx-cli-adapter.js.map +0 -1
  67. package/dist/cli/index.d.ts +0 -387
  68. package/dist/cli/index.d.ts.map +0 -1
  69. package/dist/cli/index.js +0 -523
  70. package/dist/cli/index.js.map +0 -1
  71. package/dist/cli/ui/components/DiffView.d.ts +0 -7
  72. package/dist/cli/ui/components/DiffView.d.ts.map +0 -1
  73. package/dist/cli/ui/components/DiffView.js +0 -11
  74. package/dist/cli/ui/components/DiffView.js.map +0 -1
  75. package/dist/cli/ui/components/ErrorDisplay.d.ts +0 -6
  76. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +0 -1
  77. package/dist/cli/ui/components/ErrorDisplay.js +0 -11
  78. package/dist/cli/ui/components/ErrorDisplay.js.map +0 -1
  79. package/dist/cli/ui/components/FuzzySearch.d.ts +0 -9
  80. package/dist/cli/ui/components/FuzzySearch.d.ts.map +0 -1
  81. package/dist/cli/ui/components/FuzzySearch.js +0 -12
  82. package/dist/cli/ui/components/FuzzySearch.js.map +0 -1
  83. package/dist/cli/ui/components/LoadingSpinner.d.ts +0 -6
  84. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +0 -1
  85. package/dist/cli/ui/components/LoadingSpinner.js +0 -10
  86. package/dist/cli/ui/components/LoadingSpinner.js.map +0 -1
  87. package/dist/cli/ui/components/NavigationList.d.ts +0 -9
  88. package/dist/cli/ui/components/NavigationList.d.ts.map +0 -1
  89. package/dist/cli/ui/components/NavigationList.js +0 -11
  90. package/dist/cli/ui/components/NavigationList.js.map +0 -1
  91. package/dist/cli/ui/components/ScrollableContent.d.ts +0 -8
  92. package/dist/cli/ui/components/ScrollableContent.d.ts.map +0 -1
  93. package/dist/cli/ui/components/ScrollableContent.js +0 -11
  94. package/dist/cli/ui/components/ScrollableContent.js.map +0 -1
  95. package/dist/cli/ui/components/index.d.ts +0 -7
  96. package/dist/cli/ui/components/index.d.ts.map +0 -1
  97. package/dist/cli/ui/components/index.js +0 -9
  98. package/dist/cli/ui/components/index.js.map +0 -1
  99. package/dist/cli/ui/terminal-ui.d.ts +0 -52
  100. package/dist/cli/ui/terminal-ui.d.ts.map +0 -1
  101. package/dist/cli/ui/terminal-ui.js +0 -121
  102. package/dist/cli/ui/terminal-ui.js.map +0 -1
  103. package/dist/do/BashModule.d.ts +0 -871
  104. package/dist/do/BashModule.d.ts.map +0 -1
  105. package/dist/do/BashModule.js +0 -1143
  106. package/dist/do/BashModule.js.map +0 -1
  107. package/dist/do/FsModule.d.ts +0 -601
  108. package/dist/do/FsModule.d.ts.map +0 -1
  109. package/dist/do/FsModule.js +0 -1120
  110. package/dist/do/FsModule.js.map +0 -1
  111. package/dist/do/GitModule.d.ts +0 -635
  112. package/dist/do/GitModule.d.ts.map +0 -1
  113. package/dist/do/GitModule.js +0 -781
  114. package/dist/do/GitModule.js.map +0 -1
  115. package/dist/do/GitRepoDO.d.ts +0 -281
  116. package/dist/do/GitRepoDO.d.ts.map +0 -1
  117. package/dist/do/GitRepoDO.js +0 -479
  118. package/dist/do/GitRepoDO.js.map +0 -1
  119. package/dist/do/bash-ast.d.ts +0 -246
  120. package/dist/do/bash-ast.d.ts.map +0 -1
  121. package/dist/do/bash-ast.js +0 -888
  122. package/dist/do/bash-ast.js.map +0 -1
  123. package/dist/do/container-executor.d.ts +0 -491
  124. package/dist/do/container-executor.d.ts.map +0 -1
  125. package/dist/do/container-executor.js +0 -730
  126. package/dist/do/container-executor.js.map +0 -1
  127. package/dist/do/index.d.ts +0 -53
  128. package/dist/do/index.d.ts.map +0 -1
  129. package/dist/do/index.js +0 -91
  130. package/dist/do/index.js.map +0 -1
  131. package/dist/do/tiered-storage.d.ts +0 -403
  132. package/dist/do/tiered-storage.d.ts.map +0 -1
  133. package/dist/do/tiered-storage.js +0 -689
  134. package/dist/do/tiered-storage.js.map +0 -1
  135. package/dist/do/withBash.d.ts +0 -231
  136. package/dist/do/withBash.d.ts.map +0 -1
  137. package/dist/do/withBash.js +0 -244
  138. package/dist/do/withBash.js.map +0 -1
  139. package/dist/do/withFs.d.ts +0 -237
  140. package/dist/do/withFs.d.ts.map +0 -1
  141. package/dist/do/withFs.js +0 -387
  142. package/dist/do/withFs.js.map +0 -1
  143. package/dist/do/withGit.d.ts +0 -180
  144. package/dist/do/withGit.d.ts.map +0 -1
  145. package/dist/do/withGit.js +0 -271
  146. package/dist/do/withGit.js.map +0 -1
  147. package/dist/durable-object/object-store.d.ts +0 -633
  148. package/dist/durable-object/object-store.d.ts.map +0 -1
  149. package/dist/durable-object/object-store.js +0 -1161
  150. package/dist/durable-object/object-store.js.map +0 -1
  151. package/dist/durable-object/schema.d.ts.map +0 -1
  152. package/dist/durable-object/schema.js.map +0 -1
  153. package/dist/durable-object/wal.d.ts +0 -416
  154. package/dist/durable-object/wal.d.ts.map +0 -1
  155. package/dist/durable-object/wal.js +0 -445
  156. package/dist/durable-object/wal.js.map +0 -1
  157. package/dist/mcp/adapter.d.ts +0 -772
  158. package/dist/mcp/adapter.d.ts.map +0 -1
  159. package/dist/mcp/adapter.js +0 -895
  160. package/dist/mcp/adapter.js.map +0 -1
  161. package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -22
  162. package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
  163. package/dist/mcp/sandbox/miniflare-evaluator.js +0 -140
  164. package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
  165. package/dist/mcp/sandbox/object-store-proxy.d.ts +0 -32
  166. package/dist/mcp/sandbox/object-store-proxy.d.ts.map +0 -1
  167. package/dist/mcp/sandbox/object-store-proxy.js +0 -30
  168. package/dist/mcp/sandbox/object-store-proxy.js.map +0 -1
  169. package/dist/mcp/sandbox/template.d.ts +0 -17
  170. package/dist/mcp/sandbox/template.d.ts.map +0 -1
  171. package/dist/mcp/sandbox/template.js +0 -71
  172. package/dist/mcp/sandbox/template.js.map +0 -1
  173. package/dist/mcp/sandbox.d.ts +0 -764
  174. package/dist/mcp/sandbox.d.ts.map +0 -1
  175. package/dist/mcp/sandbox.js +0 -1362
  176. package/dist/mcp/sandbox.js.map +0 -1
  177. package/dist/mcp/sdk-adapter.d.ts +0 -835
  178. package/dist/mcp/sdk-adapter.d.ts.map +0 -1
  179. package/dist/mcp/sdk-adapter.js +0 -974
  180. package/dist/mcp/sdk-adapter.js.map +0 -1
  181. package/dist/mcp/tools/do.d.ts +0 -32
  182. package/dist/mcp/tools/do.d.ts.map +0 -1
  183. package/dist/mcp/tools/do.js +0 -115
  184. package/dist/mcp/tools/do.js.map +0 -1
  185. package/dist/mcp/tools.d.ts +0 -548
  186. package/dist/mcp/tools.d.ts.map +0 -1
  187. package/dist/mcp/tools.js +0 -1934
  188. package/dist/mcp/tools.js.map +0 -1
  189. package/dist/ops/blame.d.ts +0 -551
  190. package/dist/ops/blame.d.ts.map +0 -1
  191. package/dist/ops/blame.js +0 -1037
  192. package/dist/ops/blame.js.map +0 -1
  193. package/dist/ops/branch.d.ts +0 -766
  194. package/dist/ops/branch.d.ts.map +0 -1
  195. package/dist/ops/branch.js +0 -950
  196. package/dist/ops/branch.js.map +0 -1
  197. package/dist/ops/commit-traversal.d.ts +0 -349
  198. package/dist/ops/commit-traversal.d.ts.map +0 -1
  199. package/dist/ops/commit-traversal.js +0 -821
  200. package/dist/ops/commit-traversal.js.map +0 -1
  201. package/dist/ops/commit.d.ts +0 -555
  202. package/dist/ops/commit.d.ts.map +0 -1
  203. package/dist/ops/commit.js +0 -826
  204. package/dist/ops/commit.js.map +0 -1
  205. package/dist/ops/merge-base.d.ts +0 -397
  206. package/dist/ops/merge-base.d.ts.map +0 -1
  207. package/dist/ops/merge-base.js +0 -691
  208. package/dist/ops/merge-base.js.map +0 -1
  209. package/dist/ops/merge.d.ts +0 -855
  210. package/dist/ops/merge.d.ts.map +0 -1
  211. package/dist/ops/merge.js +0 -1551
  212. package/dist/ops/merge.js.map +0 -1
  213. package/dist/ops/tag.d.ts +0 -247
  214. package/dist/ops/tag.d.ts.map +0 -1
  215. package/dist/ops/tag.js +0 -649
  216. package/dist/ops/tag.js.map +0 -1
  217. package/dist/ops/tree-builder.d.ts +0 -178
  218. package/dist/ops/tree-builder.d.ts.map +0 -1
  219. package/dist/ops/tree-builder.js +0 -271
  220. package/dist/ops/tree-builder.js.map +0 -1
  221. package/dist/ops/tree-diff.d.ts +0 -291
  222. package/dist/ops/tree-diff.d.ts.map +0 -1
  223. package/dist/ops/tree-diff.js +0 -705
  224. package/dist/ops/tree-diff.js.map +0 -1
  225. package/dist/pack/delta.d.ts +0 -248
  226. package/dist/pack/delta.d.ts.map +0 -1
  227. package/dist/pack/delta.js +0 -736
  228. package/dist/pack/delta.js.map +0 -1
  229. package/dist/pack/format.d.ts +0 -446
  230. package/dist/pack/format.d.ts.map +0 -1
  231. package/dist/pack/format.js +0 -572
  232. package/dist/pack/format.js.map +0 -1
  233. package/dist/pack/full-generation.d.ts +0 -612
  234. package/dist/pack/full-generation.d.ts.map +0 -1
  235. package/dist/pack/full-generation.js +0 -1378
  236. package/dist/pack/full-generation.js.map +0 -1
  237. package/dist/pack/generation.d.ts +0 -441
  238. package/dist/pack/generation.d.ts.map +0 -1
  239. package/dist/pack/generation.js +0 -707
  240. package/dist/pack/generation.js.map +0 -1
  241. package/dist/pack/index.d.ts +0 -502
  242. package/dist/pack/index.d.ts.map +0 -1
  243. package/dist/pack/index.js +0 -833
  244. package/dist/pack/index.js.map +0 -1
  245. package/dist/refs/branch.d.ts +0 -668
  246. package/dist/refs/branch.d.ts.map +0 -1
  247. package/dist/refs/branch.js +0 -897
  248. package/dist/refs/branch.js.map +0 -1
  249. package/dist/refs/storage.d.ts +0 -833
  250. package/dist/refs/storage.d.ts.map +0 -1
  251. package/dist/refs/storage.js +0 -1023
  252. package/dist/refs/storage.js.map +0 -1
  253. package/dist/refs/tag.d.ts +0 -860
  254. package/dist/refs/tag.d.ts.map +0 -1
  255. package/dist/refs/tag.js +0 -996
  256. package/dist/refs/tag.js.map +0 -1
  257. package/dist/storage/backend.d.ts +0 -425
  258. package/dist/storage/backend.d.ts.map +0 -1
  259. package/dist/storage/backend.js +0 -41
  260. package/dist/storage/backend.js.map +0 -1
  261. package/dist/storage/fsx-adapter.d.ts +0 -204
  262. package/dist/storage/fsx-adapter.d.ts.map +0 -1
  263. package/dist/storage/fsx-adapter.js +0 -470
  264. package/dist/storage/fsx-adapter.js.map +0 -1
  265. package/dist/storage/lru-cache.d.ts +0 -691
  266. package/dist/storage/lru-cache.d.ts.map +0 -1
  267. package/dist/storage/lru-cache.js +0 -813
  268. package/dist/storage/lru-cache.js.map +0 -1
  269. package/dist/storage/object-index.d.ts +0 -585
  270. package/dist/storage/object-index.d.ts.map +0 -1
  271. package/dist/storage/object-index.js +0 -532
  272. package/dist/storage/object-index.js.map +0 -1
  273. package/dist/storage/r2-pack.d.ts +0 -1257
  274. package/dist/storage/r2-pack.d.ts.map +0 -1
  275. package/dist/storage/r2-pack.js +0 -1770
  276. package/dist/storage/r2-pack.js.map +0 -1
  277. package/dist/tiered/cdc-pipeline.d.ts +0 -1888
  278. package/dist/tiered/cdc-pipeline.d.ts.map +0 -1
  279. package/dist/tiered/cdc-pipeline.js +0 -1880
  280. package/dist/tiered/cdc-pipeline.js.map +0 -1
  281. package/dist/tiered/migration.d.ts +0 -1104
  282. package/dist/tiered/migration.d.ts.map +0 -1
  283. package/dist/tiered/migration.js +0 -1214
  284. package/dist/tiered/migration.js.map +0 -1
  285. package/dist/tiered/parquet-writer.d.ts +0 -1145
  286. package/dist/tiered/parquet-writer.d.ts.map +0 -1
  287. package/dist/tiered/parquet-writer.js +0 -1183
  288. package/dist/tiered/parquet-writer.js.map +0 -1
  289. package/dist/tiered/read-path.d.ts +0 -835
  290. package/dist/tiered/read-path.d.ts.map +0 -1
  291. package/dist/tiered/read-path.js +0 -487
  292. package/dist/tiered/read-path.js.map +0 -1
  293. package/dist/types/capability.d.ts +0 -1385
  294. package/dist/types/capability.d.ts.map +0 -1
  295. package/dist/types/capability.js +0 -36
  296. package/dist/types/capability.js.map +0 -1
  297. package/dist/types/index.d.ts +0 -13
  298. package/dist/types/index.d.ts.map +0 -1
  299. package/dist/types/index.js +0 -18
  300. package/dist/types/index.js.map +0 -1
  301. package/dist/types/objects.d.ts +0 -692
  302. package/dist/types/objects.d.ts.map +0 -1
  303. package/dist/types/objects.js +0 -837
  304. package/dist/types/objects.js.map +0 -1
  305. package/dist/types/storage.d.ts +0 -603
  306. package/dist/types/storage.d.ts.map +0 -1
  307. package/dist/types/storage.js +0 -191
  308. package/dist/types/storage.js.map +0 -1
  309. package/dist/types/worker-loader.d.ts +0 -60
  310. package/dist/types/worker-loader.d.ts.map +0 -1
  311. package/dist/types/worker-loader.js +0 -62
  312. package/dist/types/worker-loader.js.map +0 -1
  313. package/dist/utils/hash.d.ts +0 -197
  314. package/dist/utils/hash.d.ts.map +0 -1
  315. package/dist/utils/hash.js +0 -268
  316. package/dist/utils/hash.js.map +0 -1
  317. package/dist/utils/sha1.d.ts +0 -290
  318. package/dist/utils/sha1.d.ts.map +0 -1
  319. package/dist/utils/sha1.js +0 -582
  320. package/dist/utils/sha1.js.map +0 -1
  321. package/dist/wire/capabilities.d.ts +0 -1044
  322. package/dist/wire/capabilities.d.ts.map +0 -1
  323. package/dist/wire/capabilities.js +0 -941
  324. package/dist/wire/capabilities.js.map +0 -1
  325. package/dist/wire/path-security.d.ts +0 -157
  326. package/dist/wire/path-security.d.ts.map +0 -1
  327. package/dist/wire/path-security.js +0 -307
  328. package/dist/wire/path-security.js.map +0 -1
  329. package/dist/wire/pkt-line.d.ts +0 -345
  330. package/dist/wire/pkt-line.d.ts.map +0 -1
  331. package/dist/wire/pkt-line.js +0 -381
  332. package/dist/wire/pkt-line.js.map +0 -1
  333. package/dist/wire/receive-pack.d.ts +0 -1059
  334. package/dist/wire/receive-pack.d.ts.map +0 -1
  335. package/dist/wire/receive-pack.js +0 -1414
  336. package/dist/wire/receive-pack.js.map +0 -1
  337. package/dist/wire/smart-http.d.ts +0 -799
  338. package/dist/wire/smart-http.d.ts.map +0 -1
  339. package/dist/wire/smart-http.js +0 -945
  340. package/dist/wire/smart-http.js.map +0 -1
  341. package/dist/wire/upload-pack.d.ts +0 -727
  342. package/dist/wire/upload-pack.d.ts.map +0 -1
  343. package/dist/wire/upload-pack.js +0 -1138
  344. package/dist/wire/upload-pack.js.map +0 -1
@@ -1,781 +0,0 @@
1
- /**
2
- * @fileoverview GitModule for Durable Object Integration
3
- *
4
- * This module provides a GitModule class that integrates with dotdo's $ WorkflowContext,
5
- * providing $.git.sync(), $.git.push(), and $.git.binding functionality.
6
- *
7
- * The module depends on FsModule for file operations and uses R2 as the
8
- * global git object store for cross-DO synchronization.
9
- *
10
- * @module do/GitModule
11
- *
12
- * @example
13
- * ```typescript
14
- * import { GitModule } from 'gitx.do/do'
15
- *
16
- * class MyDO extends DO {
17
- * git = new GitModule(this.$, {
18
- * repo: 'org/repo',
19
- * branch: 'main',
20
- * r2: this.env.R2_BUCKET
21
- * })
22
- *
23
- * async syncRepository() {
24
- * await this.git.sync()
25
- * const status = await this.git.status()
26
- * console.log(`On branch ${status.branch}`)
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
- * // In a Durable Object
49
- * class MyDO extends DO {
50
- * private git: GitModule
51
- *
52
- * constructor(state: DurableObjectState, env: Env) {
53
- * super(state, env)
54
- * this.git = new GitModule({
55
- * repo: 'my-org/my-repo',
56
- * branch: 'main',
57
- * r2: env.GIT_OBJECTS,
58
- * fs: this.$.fs
59
- * })
60
- * }
61
- *
62
- * async fetch(request: Request) {
63
- * // Sync from R2
64
- * await this.git.sync()
65
- *
66
- * // Make changes via $.fs
67
- * await this.$.fs.writeFile('/src/index.ts', 'new code')
68
- *
69
- * // Stage and commit
70
- * await this.git.add('src/index.ts')
71
- * await this.git.commit('Update code')
72
- *
73
- * // Push to R2
74
- * await this.git.push()
75
- *
76
- * return new Response('OK')
77
- * }
78
- * }
79
- * ```
80
- */
81
- export class GitModule {
82
- /**
83
- * Capability module name for identification.
84
- */
85
- name = 'git';
86
- /**
87
- * Repository identifier.
88
- */
89
- repo;
90
- /**
91
- * Branch being tracked.
92
- */
93
- branch;
94
- /**
95
- * Path prefix within the repository.
96
- */
97
- path;
98
- /**
99
- * R2 bucket for global object storage.
100
- */
101
- r2;
102
- /**
103
- * Filesystem capability for file operations.
104
- */
105
- fs;
106
- /**
107
- * Object key prefix in R2.
108
- */
109
- objectPrefix;
110
- /**
111
- * Database storage for persistence.
112
- */
113
- storage;
114
- /**
115
- * Database row ID for this repository binding.
116
- */
117
- repoId;
118
- /**
119
- * Current HEAD commit SHA.
120
- */
121
- currentCommit;
122
- /**
123
- * Timestamp of last sync operation.
124
- */
125
- lastSyncTime;
126
- /**
127
- * Staged files pending commit.
128
- */
129
- stagedFiles = new Set();
130
- /**
131
- * Pending objects to push to R2.
132
- * Map of SHA to { type, data } for objects that have been committed locally
133
- * but not yet pushed to the R2 object store.
134
- */
135
- pendingObjects = new Map();
136
- /**
137
- * Create a new GitModule instance.
138
- *
139
- * @param options - Configuration options
140
- *
141
- * @example
142
- * ```typescript
143
- * const git = new GitModule({
144
- * repo: 'org/repo',
145
- * branch: 'main',
146
- * r2: env.R2_BUCKET,
147
- * fs: workflowContext.fs
148
- * })
149
- * ```
150
- */
151
- constructor(options) {
152
- this.repo = options.repo;
153
- this.branch = options.branch ?? 'main';
154
- this.path = options.path;
155
- this.r2 = options.r2;
156
- this.fs = options.fs;
157
- this.objectPrefix = options.objectPrefix ?? 'git/objects';
158
- this.storage = options.storage;
159
- }
160
- /**
161
- * Get the current git binding configuration.
162
- *
163
- * @description
164
- * Returns the binding information connecting this module to a git repository.
165
- * This includes the repository, branch, path, current commit, and last sync time.
166
- *
167
- * @returns Current git binding
168
- *
169
- * @example
170
- * ```typescript
171
- * const binding = git.binding
172
- * console.log(`Repo: ${binding.repo}`)
173
- * console.log(`Branch: ${binding.branch}`)
174
- * console.log(`Commit: ${binding.commit ?? 'not synced'}`)
175
- * ```
176
- */
177
- get binding() {
178
- return {
179
- repo: this.repo,
180
- branch: this.branch,
181
- path: this.path,
182
- commit: this.currentCommit,
183
- lastSync: this.lastSyncTime
184
- };
185
- }
186
- /**
187
- * Optional initialization hook.
188
- * Called when the module is first loaded.
189
- * When storage is provided, loads or creates the repository binding from the database.
190
- */
191
- async initialize() {
192
- if (!this.storage)
193
- return;
194
- // Try to load existing repository binding
195
- const existingRows = this.storage.sql.exec('SELECT id, commit, last_sync FROM git WHERE repo = ?', this.repo).toArray();
196
- if (existingRows.length > 0) {
197
- // Load existing state
198
- const row = existingRows[0];
199
- this.repoId = row.id;
200
- this.currentCommit = row.commit ?? undefined;
201
- this.lastSyncTime = row.last_sync ? new Date(row.last_sync) : undefined;
202
- // Load staged files from git_content table
203
- const stagedRows = this.storage.sql.exec('SELECT path FROM git_content WHERE repo_id = ? AND status = ?', this.repoId, 'staged').toArray();
204
- for (const staged of stagedRows) {
205
- this.stagedFiles.add(staged.path);
206
- }
207
- }
208
- else {
209
- // Create new repository binding
210
- const now = Date.now();
211
- this.storage.sql.exec(`INSERT INTO git (repo, path, branch, object_prefix, created_at, updated_at)
212
- VALUES (?, ?, ?, ?, ?, ?)`, this.repo, this.path ?? null, this.branch, this.objectPrefix, now, now);
213
- // Get the inserted row ID
214
- const insertedRows = this.storage.sql.exec('SELECT id FROM git WHERE repo = ?', this.repo).toArray();
215
- if (insertedRows.length > 0) {
216
- this.repoId = insertedRows[0].id;
217
- // Create the branch record
218
- this.storage.sql.exec(`INSERT INTO git_branches (repo_id, name, tracking, created_at, updated_at)
219
- VALUES (?, ?, 1, ?, ?)`, this.repoId, this.branch, now, now);
220
- }
221
- }
222
- }
223
- /**
224
- * Optional cleanup hook.
225
- * Called when the capability is unloaded.
226
- */
227
- async dispose() {
228
- // Cleanup logic if needed
229
- this.stagedFiles.clear();
230
- }
231
- /**
232
- * Sync git objects from R2 to local storage via FsModule.
233
- *
234
- * @description
235
- * Fetches git objects from the R2 global object store and writes them
236
- * to the local filesystem via the FsModule. This syncs the DO's local
237
- * state with the shared repository state.
238
- *
239
- * @returns Result of the sync operation
240
- *
241
- * @example
242
- * ```typescript
243
- * const result = await git.sync()
244
- * if (result.success) {
245
- * console.log(`Synced ${result.objectsFetched} objects`)
246
- * console.log(`Now at commit ${result.commit}`)
247
- * } else {
248
- * console.error(`Sync failed: ${result.error}`)
249
- * }
250
- * ```
251
- */
252
- async sync() {
253
- if (!this.r2) {
254
- return {
255
- success: false,
256
- objectsFetched: 0,
257
- filesWritten: 0,
258
- error: 'R2 bucket not configured'
259
- };
260
- }
261
- if (!this.fs) {
262
- return {
263
- success: false,
264
- objectsFetched: 0,
265
- filesWritten: 0,
266
- error: 'Filesystem capability not available'
267
- };
268
- }
269
- try {
270
- // Get the ref for our branch
271
- const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
272
- const refObject = await this.r2.get(refKey);
273
- if (!refObject) {
274
- // No ref exists yet - this is a new/empty repository
275
- this.currentCommit = undefined;
276
- this.lastSyncTime = new Date();
277
- // Persist sync state to database even for empty repos
278
- await this.persistSyncState();
279
- return {
280
- success: true,
281
- objectsFetched: 0,
282
- filesWritten: 0,
283
- commit: undefined
284
- };
285
- }
286
- const commitSha = await refObject.text();
287
- let objectsFetched = 0;
288
- let filesWritten = 0;
289
- // Fetch the commit object
290
- const commitObject = await this.fetchObject(commitSha);
291
- if (commitObject) {
292
- objectsFetched++;
293
- // Parse commit to get tree SHA
294
- const commitContent = new TextDecoder().decode(commitObject);
295
- const treeMatch = commitContent.match(/^tree ([a-f0-9]{40})/m);
296
- if (treeMatch) {
297
- const treeSha = treeMatch[1];
298
- // Recursively sync tree contents
299
- const treeResult = await this.syncTree(treeSha, this.path ?? '');
300
- objectsFetched += treeResult.objects;
301
- filesWritten += treeResult.files;
302
- }
303
- }
304
- this.currentCommit = commitSha;
305
- this.lastSyncTime = new Date();
306
- // Persist sync state to database
307
- await this.persistSyncState();
308
- return {
309
- success: true,
310
- objectsFetched,
311
- filesWritten,
312
- commit: commitSha
313
- };
314
- }
315
- catch (error) {
316
- const errorMessage = error instanceof Error ? error.message : String(error);
317
- return {
318
- success: false,
319
- objectsFetched: 0,
320
- filesWritten: 0,
321
- error: errorMessage
322
- };
323
- }
324
- }
325
- /**
326
- * Push local changes to R2 object store.
327
- *
328
- * @description
329
- * Writes local git objects to the R2 global object store for
330
- * cross-DO synchronization. This makes local changes available
331
- * to other DOs that sync from the same repository.
332
- *
333
- * @returns Result of the push operation
334
- *
335
- * @example
336
- * ```typescript
337
- * // Make changes and commit
338
- * await git.add('src/index.ts')
339
- * await git.commit('Update code')
340
- *
341
- * // Push to R2
342
- * const result = await git.push()
343
- * if (result.success) {
344
- * console.log(`Pushed ${result.objectsPushed} objects`)
345
- * }
346
- * ```
347
- */
348
- async push() {
349
- if (!this.r2) {
350
- return {
351
- success: false,
352
- objectsPushed: 0,
353
- error: 'R2 bucket not configured'
354
- };
355
- }
356
- if (!this.currentCommit) {
357
- return {
358
- success: false,
359
- objectsPushed: 0,
360
- error: 'No commits to push'
361
- };
362
- }
363
- try {
364
- let objectsPushed = 0;
365
- // Push all pending objects to R2
366
- for (const [sha, { data }] of this.pendingObjects) {
367
- await this.storeObject(sha, data);
368
- objectsPushed++;
369
- }
370
- // Clear pending objects after successful push
371
- this.pendingObjects.clear();
372
- // Update the ref to point to our current commit
373
- const refKey = `${this.objectPrefix}/refs/heads/${this.branch}`;
374
- await this.r2.put(refKey, this.currentCommit);
375
- return {
376
- success: true,
377
- objectsPushed,
378
- commit: this.currentCommit
379
- };
380
- }
381
- catch (error) {
382
- const errorMessage = error instanceof Error ? error.message : String(error);
383
- return {
384
- success: false,
385
- objectsPushed: 0,
386
- error: errorMessage
387
- };
388
- }
389
- }
390
- /**
391
- * Get the current repository status.
392
- *
393
- * @description
394
- * Returns information about the current branch, HEAD commit,
395
- * and staged/unstaged files.
396
- *
397
- * @returns Status object with branch and file information
398
- *
399
- * @example
400
- * ```typescript
401
- * const status = await git.status()
402
- * console.log(`On branch ${status.branch}`)
403
- * if (status.staged.length > 0) {
404
- * console.log(`${status.staged.length} files staged`)
405
- * }
406
- * ```
407
- */
408
- async status() {
409
- return {
410
- branch: this.branch,
411
- head: this.currentCommit,
412
- staged: Array.from(this.stagedFiles),
413
- unstaged: [], // Would need working tree comparison
414
- clean: this.stagedFiles.size === 0
415
- };
416
- }
417
- /**
418
- * Stage files for commit.
419
- *
420
- * @description
421
- * Adds files to the staging area for the next commit.
422
- *
423
- * @param files - File path or array of file paths to stage
424
- *
425
- * @example
426
- * ```typescript
427
- * await git.add('src/index.ts')
428
- * await git.add(['src/a.ts', 'src/b.ts'])
429
- * ```
430
- */
431
- async add(files) {
432
- const filesToAdd = Array.isArray(files) ? files : [files];
433
- for (const file of filesToAdd) {
434
- this.stagedFiles.add(file);
435
- // Persist staged file to database
436
- await this.persistStagedFile(file);
437
- }
438
- }
439
- /**
440
- * Create a new commit with staged changes.
441
- *
442
- * @description
443
- * Creates a commit object with the currently staged changes.
444
- * Returns the commit hash.
445
- *
446
- * @param message - Commit message
447
- * @returns Commit hash or object with hash
448
- *
449
- * @example
450
- * ```typescript
451
- * await git.add('src/index.ts')
452
- * const result = await git.commit('Update code')
453
- * console.log(`Created commit: ${result}`)
454
- * ```
455
- */
456
- async commit(message) {
457
- if (this.stagedFiles.size === 0) {
458
- throw new Error('Nothing to commit - no files staged');
459
- }
460
- const encoder = new TextEncoder();
461
- // Create blob objects for each staged file
462
- const treeEntries = [];
463
- for (const filePath of this.stagedFiles) {
464
- // Read file content from filesystem if available
465
- let content;
466
- if (this.fs) {
467
- try {
468
- const fileContent = await this.fs.readFile(filePath);
469
- content = typeof fileContent === 'string'
470
- ? encoder.encode(fileContent)
471
- : new Uint8Array(fileContent);
472
- }
473
- catch {
474
- // File doesn't exist or can't be read, create empty blob
475
- content = new Uint8Array(0);
476
- }
477
- }
478
- else {
479
- // No filesystem, create placeholder content
480
- content = encoder.encode(`placeholder content for ${filePath}`);
481
- }
482
- // Create blob object
483
- const blobHeader = encoder.encode(`blob ${content.length}\0`);
484
- const blobData = new Uint8Array(blobHeader.length + content.length);
485
- blobData.set(blobHeader);
486
- blobData.set(content, blobHeader.length);
487
- const blobSha = await this.hashBytes(blobData);
488
- // Store blob content (without header) for push
489
- this.pendingObjects.set(blobSha, { type: 'blob', data: content });
490
- // Add to tree entries (use basename for tree entry name)
491
- const name = filePath.split('/').pop() || filePath;
492
- treeEntries.push({ mode: '100644', name, sha: blobSha });
493
- }
494
- // Sort tree entries by name (git requirement)
495
- treeEntries.sort((a, b) => a.name.localeCompare(b.name));
496
- // Create tree object content
497
- const treeContent = this.buildTreeContent(treeEntries);
498
- const treeHeader = encoder.encode(`tree ${treeContent.length}\0`);
499
- const treeData = new Uint8Array(treeHeader.length + treeContent.length);
500
- treeData.set(treeHeader);
501
- treeData.set(treeContent, treeHeader.length);
502
- const treeSha = await this.hashBytes(treeData);
503
- // Store tree for push
504
- this.pendingObjects.set(treeSha, { type: 'tree', data: treeContent });
505
- // Create commit object
506
- const timestamp = Math.floor(Date.now() / 1000);
507
- const timezone = '+0000';
508
- const author = `GitModule <git@gitx.do> ${timestamp} ${timezone}`;
509
- let commitContent = `tree ${treeSha}\n`;
510
- if (this.currentCommit) {
511
- commitContent += `parent ${this.currentCommit}\n`;
512
- }
513
- commitContent += `author ${author}\n`;
514
- commitContent += `committer ${author}\n`;
515
- commitContent += `\n${message}\n`;
516
- const commitContentBytes = encoder.encode(commitContent);
517
- const commitHeader = encoder.encode(`commit ${commitContentBytes.length}\0`);
518
- const commitData = new Uint8Array(commitHeader.length + commitContentBytes.length);
519
- commitData.set(commitHeader);
520
- commitData.set(commitContentBytes, commitHeader.length);
521
- const commitSha = await this.hashBytes(commitData);
522
- // Store commit for push
523
- this.pendingObjects.set(commitSha, { type: 'commit', data: commitContentBytes });
524
- this.currentCommit = commitSha;
525
- this.stagedFiles.clear();
526
- // Persist commit state to database and clear staged files
527
- await this.persistCommitState(commitSha);
528
- return { hash: commitSha };
529
- }
530
- /**
531
- * Build tree content from entries.
532
- * Format: mode name\0sha20bytes (repeated)
533
- */
534
- buildTreeContent(entries) {
535
- const encoder = new TextEncoder();
536
- const parts = [];
537
- for (const entry of entries) {
538
- const modeAndName = encoder.encode(`${entry.mode} ${entry.name}\0`);
539
- const sha20 = this.hexToBytes(entry.sha);
540
- const entryData = new Uint8Array(modeAndName.length + 20);
541
- entryData.set(modeAndName);
542
- entryData.set(sha20, modeAndName.length);
543
- parts.push(entryData);
544
- }
545
- // Combine all parts
546
- const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
547
- const result = new Uint8Array(totalLength);
548
- let offset = 0;
549
- for (const part of parts) {
550
- result.set(part, offset);
551
- offset += part.length;
552
- }
553
- return result;
554
- }
555
- /**
556
- * Convert hex string to bytes.
557
- */
558
- hexToBytes(hex) {
559
- const bytes = new Uint8Array(hex.length / 2);
560
- for (let i = 0; i < hex.length; i += 2) {
561
- bytes[i / 2] = parseInt(hex.slice(i, i + 2), 16);
562
- }
563
- return bytes;
564
- }
565
- /**
566
- * Hash raw bytes using SHA-1.
567
- */
568
- async hashBytes(data) {
569
- const hashBuffer = await crypto.subtle.digest('SHA-1', data);
570
- return this.bytesToHex(new Uint8Array(hashBuffer));
571
- }
572
- /**
573
- * Get diff between references or working tree.
574
- *
575
- * @param _ref - Reference to diff against (not yet implemented)
576
- * @returns Unified diff output
577
- */
578
- async diff(_ref) {
579
- // Placeholder - would need full diff implementation
580
- return `diff --git a/ b/\n(diff not yet implemented)`;
581
- }
582
- /**
583
- * Get commit history.
584
- *
585
- * @param _options - Options for filtering results (not yet implemented)
586
- * @returns Array of commit objects
587
- */
588
- async log(_options) {
589
- // Placeholder - would need commit traversal
590
- if (this.currentCommit) {
591
- return [{ hash: this.currentCommit, message: 'Current commit' }];
592
- }
593
- return [];
594
- }
595
- /**
596
- * Pull changes from R2 (alias for sync).
597
- *
598
- * @param _remote - Remote name (ignored, always uses R2)
599
- * @param _branch - Branch to pull (uses configured branch)
600
- */
601
- async pull(_remote, _branch) {
602
- const result = await this.sync();
603
- if (!result.success) {
604
- throw new Error(result.error ?? 'Pull failed');
605
- }
606
- }
607
- // ═══════════════════════════════════════════════════════════════════════════
608
- // Private Helper Methods
609
- // ═══════════════════════════════════════════════════════════════════════════
610
- /**
611
- * Fetch a git object from R2 by SHA.
612
- */
613
- async fetchObject(sha) {
614
- if (!this.r2)
615
- return null;
616
- const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
617
- const object = await this.r2.get(key);
618
- if (!object)
619
- return null;
620
- const buffer = await object.arrayBuffer();
621
- return new Uint8Array(buffer);
622
- }
623
- /**
624
- * Store a git object in R2.
625
- */
626
- async storeObject(sha, data) {
627
- if (!this.r2)
628
- return;
629
- const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
630
- await this.r2.put(key, data);
631
- }
632
- /**
633
- * Recursively sync a tree and its contents.
634
- */
635
- async syncTree(treeSha, basePath) {
636
- let objects = 0;
637
- let files = 0;
638
- const treeData = await this.fetchObject(treeSha);
639
- if (!treeData)
640
- return { objects, files };
641
- objects++;
642
- // Parse tree entries
643
- // Tree format: mode name\0sha20bytes (repeated)
644
- let offset = 0;
645
- const decoder = new TextDecoder();
646
- while (offset < treeData.length) {
647
- // Find the null byte
648
- let nullIdx = offset;
649
- while (nullIdx < treeData.length && treeData[nullIdx] !== 0) {
650
- nullIdx++;
651
- }
652
- const modeAndName = decoder.decode(treeData.slice(offset, nullIdx));
653
- const spaceIdx = modeAndName.indexOf(' ');
654
- const mode = modeAndName.slice(0, spaceIdx);
655
- const name = modeAndName.slice(spaceIdx + 1);
656
- // Read 20-byte SHA
657
- const sha20 = treeData.slice(nullIdx + 1, nullIdx + 21);
658
- const sha = this.bytesToHex(sha20);
659
- const entryPath = basePath ? `${basePath}/${name}` : name;
660
- if (mode === '40000' || mode === '040000') {
661
- // Directory - recurse
662
- const subResult = await this.syncTree(sha, entryPath);
663
- objects += subResult.objects;
664
- files += subResult.files;
665
- }
666
- else {
667
- // File - fetch blob and write via fs
668
- const blobData = await this.fetchObject(sha);
669
- if (blobData && this.fs) {
670
- objects++;
671
- // Ensure parent directory exists
672
- const parentDir = entryPath.split('/').slice(0, -1).join('/');
673
- if (parentDir) {
674
- await this.fs.mkdir(`/${parentDir}`, { recursive: true });
675
- }
676
- // Write file content (skip git header if present)
677
- await this.fs.writeFile(`/${entryPath}`, Buffer.from(blobData));
678
- files++;
679
- }
680
- }
681
- offset = nullIdx + 21;
682
- }
683
- return { objects, files };
684
- }
685
- /**
686
- * Convert bytes to hex string.
687
- */
688
- bytesToHex(bytes) {
689
- return Array.from(bytes)
690
- .map(b => b.toString(16).padStart(2, '0'))
691
- .join('');
692
- }
693
- /**
694
- * Persist sync state to the database.
695
- * Updates the git table with the current commit and last sync timestamp.
696
- */
697
- async persistSyncState() {
698
- if (!this.storage || !this.repoId)
699
- return;
700
- const now = Date.now();
701
- this.storage.sql.exec(`UPDATE git SET commit = ?, last_sync = ?, updated_at = ? WHERE id = ?`, this.currentCommit ?? null, now, now, this.repoId);
702
- }
703
- /**
704
- * Persist a staged file to the database.
705
- * Inserts or updates a record in the git_content table.
706
- * Uses file_id foreign key to reference the shared files table when available.
707
- */
708
- async persistStagedFile(file) {
709
- if (!this.storage || !this.repoId)
710
- return;
711
- const now = Date.now();
712
- // Get file_id from filesystem if getFileId is available
713
- let fileId = null;
714
- if (this.fs?.getFileId) {
715
- try {
716
- fileId = await this.fs.getFileId(file);
717
- }
718
- catch {
719
- // File may not exist in filesystem yet, that's okay
720
- fileId = null;
721
- }
722
- }
723
- // Use INSERT OR REPLACE to handle both new and existing files
724
- // Include file_id for efficient foreign key relationships
725
- this.storage.sql.exec(`INSERT INTO git_content (repo_id, file_id, path, status, created_at, updated_at)
726
- VALUES (?, ?, ?, 'staged', ?, ?)
727
- ON CONFLICT(repo_id, path) DO UPDATE SET status = 'staged', file_id = ?, updated_at = ?`, this.repoId, fileId, file, now, now, fileId, now);
728
- }
729
- /**
730
- * Persist commit state to the database.
731
- * Updates the git table with the new commit hash and clears staged files.
732
- */
733
- async persistCommitState(hash) {
734
- if (!this.storage || !this.repoId)
735
- return;
736
- const now = Date.now();
737
- // Update the commit hash in the git table
738
- this.storage.sql.exec(`UPDATE git SET commit = ?, updated_at = ? WHERE id = ?`, hash, now, this.repoId);
739
- // Update branch head
740
- this.storage.sql.exec(`UPDATE git_branches SET head = ?, updated_at = ? WHERE repo_id = ? AND name = ?`, hash, now, this.repoId, this.branch);
741
- // Clear staged files from git_content
742
- this.storage.sql.exec(`DELETE FROM git_content WHERE repo_id = ? AND status = 'staged'`, this.repoId);
743
- }
744
- }
745
- // ============================================================================
746
- // Factory Functions
747
- // ============================================================================
748
- /**
749
- * Create a GitModule instance with the given options.
750
- *
751
- * @param options - Configuration options for the module
752
- * @returns A new GitModule instance
753
- *
754
- * @example
755
- * ```typescript
756
- * import { createGitModule } from 'gitx.do/do'
757
- *
758
- * const git = createGitModule({
759
- * repo: 'org/repo',
760
- * branch: 'main',
761
- * r2: env.R2_BUCKET,
762
- * fs: workflowContext.fs
763
- * })
764
- * ```
765
- */
766
- export function createGitModule(options) {
767
- return new GitModule(options);
768
- }
769
- // ============================================================================
770
- // Type Guards
771
- // ============================================================================
772
- /**
773
- * Check if a value is a GitModule instance.
774
- *
775
- * @param value - Value to check
776
- * @returns True if value is a GitModule
777
- */
778
- export function isGitModule(value) {
779
- return value instanceof GitModule;
780
- }
781
- //# sourceMappingURL=GitModule.js.map