gitx.do 0.1.1 → 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 (356) 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 +14 -469
  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 -176
  20. package/dist/cli/commands/add.d.ts.map +0 -1
  21. package/dist/cli/commands/add.js +0 -979
  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/checkout.d.ts +0 -73
  32. package/dist/cli/commands/checkout.d.ts.map +0 -1
  33. package/dist/cli/commands/checkout.js +0 -725
  34. package/dist/cli/commands/checkout.js.map +0 -1
  35. package/dist/cli/commands/commit.d.ts +0 -182
  36. package/dist/cli/commands/commit.d.ts.map +0 -1
  37. package/dist/cli/commands/commit.js +0 -457
  38. package/dist/cli/commands/commit.js.map +0 -1
  39. package/dist/cli/commands/diff.d.ts +0 -464
  40. package/dist/cli/commands/diff.d.ts.map +0 -1
  41. package/dist/cli/commands/diff.js +0 -959
  42. package/dist/cli/commands/diff.js.map +0 -1
  43. package/dist/cli/commands/log.d.ts +0 -239
  44. package/dist/cli/commands/log.d.ts.map +0 -1
  45. package/dist/cli/commands/log.js +0 -535
  46. package/dist/cli/commands/log.js.map +0 -1
  47. package/dist/cli/commands/merge.d.ts +0 -106
  48. package/dist/cli/commands/merge.d.ts.map +0 -1
  49. package/dist/cli/commands/merge.js +0 -852
  50. package/dist/cli/commands/merge.js.map +0 -1
  51. package/dist/cli/commands/review.d.ts +0 -457
  52. package/dist/cli/commands/review.d.ts.map +0 -1
  53. package/dist/cli/commands/review.js +0 -558
  54. package/dist/cli/commands/review.js.map +0 -1
  55. package/dist/cli/commands/stash.d.ts +0 -157
  56. package/dist/cli/commands/stash.d.ts.map +0 -1
  57. package/dist/cli/commands/stash.js +0 -655
  58. package/dist/cli/commands/stash.js.map +0 -1
  59. package/dist/cli/commands/status.d.ts +0 -269
  60. package/dist/cli/commands/status.d.ts.map +0 -1
  61. package/dist/cli/commands/status.js +0 -492
  62. package/dist/cli/commands/status.js.map +0 -1
  63. package/dist/cli/commands/web.d.ts +0 -199
  64. package/dist/cli/commands/web.d.ts.map +0 -1
  65. package/dist/cli/commands/web.js +0 -697
  66. package/dist/cli/commands/web.js.map +0 -1
  67. package/dist/cli/fs-adapter.d.ts +0 -656
  68. package/dist/cli/fs-adapter.d.ts.map +0 -1
  69. package/dist/cli/fs-adapter.js +0 -1177
  70. package/dist/cli/fs-adapter.js.map +0 -1
  71. package/dist/cli/fsx-cli-adapter.d.ts +0 -359
  72. package/dist/cli/fsx-cli-adapter.d.ts.map +0 -1
  73. package/dist/cli/fsx-cli-adapter.js +0 -619
  74. package/dist/cli/fsx-cli-adapter.js.map +0 -1
  75. package/dist/cli/index.d.ts +0 -387
  76. package/dist/cli/index.d.ts.map +0 -1
  77. package/dist/cli/index.js +0 -579
  78. package/dist/cli/index.js.map +0 -1
  79. package/dist/cli/ui/components/DiffView.d.ts +0 -12
  80. package/dist/cli/ui/components/DiffView.d.ts.map +0 -1
  81. package/dist/cli/ui/components/DiffView.js +0 -11
  82. package/dist/cli/ui/components/DiffView.js.map +0 -1
  83. package/dist/cli/ui/components/ErrorDisplay.d.ts +0 -10
  84. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +0 -1
  85. package/dist/cli/ui/components/ErrorDisplay.js +0 -11
  86. package/dist/cli/ui/components/ErrorDisplay.js.map +0 -1
  87. package/dist/cli/ui/components/FuzzySearch.d.ts +0 -15
  88. package/dist/cli/ui/components/FuzzySearch.d.ts.map +0 -1
  89. package/dist/cli/ui/components/FuzzySearch.js +0 -12
  90. package/dist/cli/ui/components/FuzzySearch.js.map +0 -1
  91. package/dist/cli/ui/components/LoadingSpinner.d.ts +0 -10
  92. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +0 -1
  93. package/dist/cli/ui/components/LoadingSpinner.js +0 -10
  94. package/dist/cli/ui/components/LoadingSpinner.js.map +0 -1
  95. package/dist/cli/ui/components/NavigationList.d.ts +0 -14
  96. package/dist/cli/ui/components/NavigationList.d.ts.map +0 -1
  97. package/dist/cli/ui/components/NavigationList.js +0 -11
  98. package/dist/cli/ui/components/NavigationList.js.map +0 -1
  99. package/dist/cli/ui/components/ScrollableContent.d.ts +0 -13
  100. package/dist/cli/ui/components/ScrollableContent.d.ts.map +0 -1
  101. package/dist/cli/ui/components/ScrollableContent.js +0 -11
  102. package/dist/cli/ui/components/ScrollableContent.js.map +0 -1
  103. package/dist/cli/ui/components/index.d.ts +0 -7
  104. package/dist/cli/ui/components/index.d.ts.map +0 -1
  105. package/dist/cli/ui/components/index.js +0 -9
  106. package/dist/cli/ui/components/index.js.map +0 -1
  107. package/dist/cli/ui/terminal-ui.d.ts +0 -85
  108. package/dist/cli/ui/terminal-ui.d.ts.map +0 -1
  109. package/dist/cli/ui/terminal-ui.js +0 -121
  110. package/dist/cli/ui/terminal-ui.js.map +0 -1
  111. package/dist/do/BashModule.d.ts +0 -871
  112. package/dist/do/BashModule.d.ts.map +0 -1
  113. package/dist/do/BashModule.js +0 -1143
  114. package/dist/do/BashModule.js.map +0 -1
  115. package/dist/do/FsModule.d.ts +0 -612
  116. package/dist/do/FsModule.d.ts.map +0 -1
  117. package/dist/do/FsModule.js +0 -1120
  118. package/dist/do/FsModule.js.map +0 -1
  119. package/dist/do/GitModule.d.ts +0 -635
  120. package/dist/do/GitModule.d.ts.map +0 -1
  121. package/dist/do/GitModule.js +0 -784
  122. package/dist/do/GitModule.js.map +0 -1
  123. package/dist/do/GitRepoDO.d.ts +0 -281
  124. package/dist/do/GitRepoDO.d.ts.map +0 -1
  125. package/dist/do/GitRepoDO.js +0 -479
  126. package/dist/do/GitRepoDO.js.map +0 -1
  127. package/dist/do/bash-ast.d.ts +0 -246
  128. package/dist/do/bash-ast.d.ts.map +0 -1
  129. package/dist/do/bash-ast.js +0 -888
  130. package/dist/do/bash-ast.js.map +0 -1
  131. package/dist/do/container-executor.d.ts +0 -491
  132. package/dist/do/container-executor.d.ts.map +0 -1
  133. package/dist/do/container-executor.js +0 -731
  134. package/dist/do/container-executor.js.map +0 -1
  135. package/dist/do/index.d.ts +0 -53
  136. package/dist/do/index.d.ts.map +0 -1
  137. package/dist/do/index.js +0 -91
  138. package/dist/do/index.js.map +0 -1
  139. package/dist/do/tiered-storage.d.ts +0 -403
  140. package/dist/do/tiered-storage.d.ts.map +0 -1
  141. package/dist/do/tiered-storage.js +0 -689
  142. package/dist/do/tiered-storage.js.map +0 -1
  143. package/dist/do/withBash.d.ts +0 -231
  144. package/dist/do/withBash.d.ts.map +0 -1
  145. package/dist/do/withBash.js +0 -244
  146. package/dist/do/withBash.js.map +0 -1
  147. package/dist/do/withFs.d.ts +0 -237
  148. package/dist/do/withFs.d.ts.map +0 -1
  149. package/dist/do/withFs.js +0 -387
  150. package/dist/do/withFs.js.map +0 -1
  151. package/dist/do/withGit.d.ts +0 -180
  152. package/dist/do/withGit.d.ts.map +0 -1
  153. package/dist/do/withGit.js +0 -271
  154. package/dist/do/withGit.js.map +0 -1
  155. package/dist/durable-object/object-store.d.ts +0 -633
  156. package/dist/durable-object/object-store.d.ts.map +0 -1
  157. package/dist/durable-object/object-store.js +0 -1164
  158. package/dist/durable-object/object-store.js.map +0 -1
  159. package/dist/durable-object/schema.d.ts.map +0 -1
  160. package/dist/durable-object/schema.js.map +0 -1
  161. package/dist/durable-object/wal.d.ts +0 -416
  162. package/dist/durable-object/wal.d.ts.map +0 -1
  163. package/dist/durable-object/wal.js +0 -445
  164. package/dist/durable-object/wal.js.map +0 -1
  165. package/dist/mcp/adapter.d.ts +0 -772
  166. package/dist/mcp/adapter.d.ts.map +0 -1
  167. package/dist/mcp/adapter.js +0 -895
  168. package/dist/mcp/adapter.js.map +0 -1
  169. package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -22
  170. package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
  171. package/dist/mcp/sandbox/miniflare-evaluator.js +0 -140
  172. package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
  173. package/dist/mcp/sandbox/object-store-proxy.d.ts +0 -32
  174. package/dist/mcp/sandbox/object-store-proxy.d.ts.map +0 -1
  175. package/dist/mcp/sandbox/object-store-proxy.js +0 -30
  176. package/dist/mcp/sandbox/object-store-proxy.js.map +0 -1
  177. package/dist/mcp/sandbox/template.d.ts +0 -17
  178. package/dist/mcp/sandbox/template.d.ts.map +0 -1
  179. package/dist/mcp/sandbox/template.js +0 -71
  180. package/dist/mcp/sandbox/template.js.map +0 -1
  181. package/dist/mcp/sandbox.d.ts +0 -764
  182. package/dist/mcp/sandbox.d.ts.map +0 -1
  183. package/dist/mcp/sandbox.js +0 -1362
  184. package/dist/mcp/sandbox.js.map +0 -1
  185. package/dist/mcp/sdk-adapter.d.ts +0 -835
  186. package/dist/mcp/sdk-adapter.d.ts.map +0 -1
  187. package/dist/mcp/sdk-adapter.js +0 -974
  188. package/dist/mcp/sdk-adapter.js.map +0 -1
  189. package/dist/mcp/tools/do.d.ts +0 -32
  190. package/dist/mcp/tools/do.d.ts.map +0 -1
  191. package/dist/mcp/tools/do.js +0 -117
  192. package/dist/mcp/tools/do.js.map +0 -1
  193. package/dist/mcp/tools.d.ts +0 -548
  194. package/dist/mcp/tools.d.ts.map +0 -1
  195. package/dist/mcp/tools.js +0 -3170
  196. package/dist/mcp/tools.js.map +0 -1
  197. package/dist/ops/blame.d.ts +0 -551
  198. package/dist/ops/blame.d.ts.map +0 -1
  199. package/dist/ops/blame.js +0 -1037
  200. package/dist/ops/blame.js.map +0 -1
  201. package/dist/ops/branch.d.ts +0 -766
  202. package/dist/ops/branch.d.ts.map +0 -1
  203. package/dist/ops/branch.js +0 -950
  204. package/dist/ops/branch.js.map +0 -1
  205. package/dist/ops/commit-traversal.d.ts +0 -349
  206. package/dist/ops/commit-traversal.d.ts.map +0 -1
  207. package/dist/ops/commit-traversal.js +0 -821
  208. package/dist/ops/commit-traversal.js.map +0 -1
  209. package/dist/ops/commit.d.ts +0 -555
  210. package/dist/ops/commit.d.ts.map +0 -1
  211. package/dist/ops/commit.js +0 -826
  212. package/dist/ops/commit.js.map +0 -1
  213. package/dist/ops/merge-base.d.ts +0 -397
  214. package/dist/ops/merge-base.d.ts.map +0 -1
  215. package/dist/ops/merge-base.js +0 -691
  216. package/dist/ops/merge-base.js.map +0 -1
  217. package/dist/ops/merge.d.ts +0 -855
  218. package/dist/ops/merge.d.ts.map +0 -1
  219. package/dist/ops/merge.js +0 -1551
  220. package/dist/ops/merge.js.map +0 -1
  221. package/dist/ops/tag.d.ts +0 -247
  222. package/dist/ops/tag.d.ts.map +0 -1
  223. package/dist/ops/tag.js +0 -649
  224. package/dist/ops/tag.js.map +0 -1
  225. package/dist/ops/tree-builder.d.ts +0 -178
  226. package/dist/ops/tree-builder.d.ts.map +0 -1
  227. package/dist/ops/tree-builder.js +0 -271
  228. package/dist/ops/tree-builder.js.map +0 -1
  229. package/dist/ops/tree-diff.d.ts +0 -291
  230. package/dist/ops/tree-diff.d.ts.map +0 -1
  231. package/dist/ops/tree-diff.js +0 -705
  232. package/dist/ops/tree-diff.js.map +0 -1
  233. package/dist/pack/delta.d.ts +0 -248
  234. package/dist/pack/delta.d.ts.map +0 -1
  235. package/dist/pack/delta.js +0 -740
  236. package/dist/pack/delta.js.map +0 -1
  237. package/dist/pack/format.d.ts +0 -446
  238. package/dist/pack/format.d.ts.map +0 -1
  239. package/dist/pack/format.js +0 -572
  240. package/dist/pack/format.js.map +0 -1
  241. package/dist/pack/full-generation.d.ts +0 -612
  242. package/dist/pack/full-generation.d.ts.map +0 -1
  243. package/dist/pack/full-generation.js +0 -1378
  244. package/dist/pack/full-generation.js.map +0 -1
  245. package/dist/pack/generation.d.ts +0 -441
  246. package/dist/pack/generation.d.ts.map +0 -1
  247. package/dist/pack/generation.js +0 -707
  248. package/dist/pack/generation.js.map +0 -1
  249. package/dist/pack/index.d.ts +0 -502
  250. package/dist/pack/index.d.ts.map +0 -1
  251. package/dist/pack/index.js +0 -833
  252. package/dist/pack/index.js.map +0 -1
  253. package/dist/refs/branch.d.ts +0 -683
  254. package/dist/refs/branch.d.ts.map +0 -1
  255. package/dist/refs/branch.js +0 -881
  256. package/dist/refs/branch.js.map +0 -1
  257. package/dist/refs/storage.d.ts +0 -833
  258. package/dist/refs/storage.d.ts.map +0 -1
  259. package/dist/refs/storage.js +0 -1023
  260. package/dist/refs/storage.js.map +0 -1
  261. package/dist/refs/tag.d.ts +0 -860
  262. package/dist/refs/tag.d.ts.map +0 -1
  263. package/dist/refs/tag.js +0 -996
  264. package/dist/refs/tag.js.map +0 -1
  265. package/dist/storage/backend.d.ts +0 -425
  266. package/dist/storage/backend.d.ts.map +0 -1
  267. package/dist/storage/backend.js +0 -41
  268. package/dist/storage/backend.js.map +0 -1
  269. package/dist/storage/fsx-adapter.d.ts +0 -204
  270. package/dist/storage/fsx-adapter.d.ts.map +0 -1
  271. package/dist/storage/fsx-adapter.js +0 -518
  272. package/dist/storage/fsx-adapter.js.map +0 -1
  273. package/dist/storage/lru-cache.d.ts +0 -691
  274. package/dist/storage/lru-cache.d.ts.map +0 -1
  275. package/dist/storage/lru-cache.js +0 -813
  276. package/dist/storage/lru-cache.js.map +0 -1
  277. package/dist/storage/object-index.d.ts +0 -585
  278. package/dist/storage/object-index.d.ts.map +0 -1
  279. package/dist/storage/object-index.js +0 -532
  280. package/dist/storage/object-index.js.map +0 -1
  281. package/dist/storage/r2-pack.d.ts +0 -1257
  282. package/dist/storage/r2-pack.d.ts.map +0 -1
  283. package/dist/storage/r2-pack.js +0 -1773
  284. package/dist/storage/r2-pack.js.map +0 -1
  285. package/dist/tiered/cdc-pipeline.d.ts +0 -1888
  286. package/dist/tiered/cdc-pipeline.d.ts.map +0 -1
  287. package/dist/tiered/cdc-pipeline.js +0 -1880
  288. package/dist/tiered/cdc-pipeline.js.map +0 -1
  289. package/dist/tiered/migration.d.ts +0 -1104
  290. package/dist/tiered/migration.d.ts.map +0 -1
  291. package/dist/tiered/migration.js +0 -1217
  292. package/dist/tiered/migration.js.map +0 -1
  293. package/dist/tiered/parquet-writer.d.ts +0 -1145
  294. package/dist/tiered/parquet-writer.d.ts.map +0 -1
  295. package/dist/tiered/parquet-writer.js +0 -1183
  296. package/dist/tiered/parquet-writer.js.map +0 -1
  297. package/dist/tiered/read-path.d.ts +0 -835
  298. package/dist/tiered/read-path.d.ts.map +0 -1
  299. package/dist/tiered/read-path.js +0 -487
  300. package/dist/tiered/read-path.js.map +0 -1
  301. package/dist/types/capability.d.ts +0 -1385
  302. package/dist/types/capability.d.ts.map +0 -1
  303. package/dist/types/capability.js +0 -36
  304. package/dist/types/capability.js.map +0 -1
  305. package/dist/types/index.d.ts +0 -13
  306. package/dist/types/index.d.ts.map +0 -1
  307. package/dist/types/index.js +0 -18
  308. package/dist/types/index.js.map +0 -1
  309. package/dist/types/interfaces.d.ts +0 -673
  310. package/dist/types/interfaces.d.ts.map +0 -1
  311. package/dist/types/interfaces.js +0 -26
  312. package/dist/types/interfaces.js.map +0 -1
  313. package/dist/types/objects.d.ts +0 -692
  314. package/dist/types/objects.d.ts.map +0 -1
  315. package/dist/types/objects.js +0 -837
  316. package/dist/types/objects.js.map +0 -1
  317. package/dist/types/storage.d.ts +0 -603
  318. package/dist/types/storage.d.ts.map +0 -1
  319. package/dist/types/storage.js +0 -191
  320. package/dist/types/storage.js.map +0 -1
  321. package/dist/types/worker-loader.d.ts +0 -60
  322. package/dist/types/worker-loader.d.ts.map +0 -1
  323. package/dist/types/worker-loader.js +0 -62
  324. package/dist/types/worker-loader.js.map +0 -1
  325. package/dist/utils/hash.d.ts +0 -198
  326. package/dist/utils/hash.d.ts.map +0 -1
  327. package/dist/utils/hash.js +0 -272
  328. package/dist/utils/hash.js.map +0 -1
  329. package/dist/utils/sha1.d.ts +0 -325
  330. package/dist/utils/sha1.d.ts.map +0 -1
  331. package/dist/utils/sha1.js +0 -635
  332. package/dist/utils/sha1.js.map +0 -1
  333. package/dist/wire/capabilities.d.ts +0 -1044
  334. package/dist/wire/capabilities.d.ts.map +0 -1
  335. package/dist/wire/capabilities.js +0 -941
  336. package/dist/wire/capabilities.js.map +0 -1
  337. package/dist/wire/path-security.d.ts +0 -157
  338. package/dist/wire/path-security.d.ts.map +0 -1
  339. package/dist/wire/path-security.js +0 -307
  340. package/dist/wire/path-security.js.map +0 -1
  341. package/dist/wire/pkt-line.d.ts +0 -345
  342. package/dist/wire/pkt-line.d.ts.map +0 -1
  343. package/dist/wire/pkt-line.js +0 -381
  344. package/dist/wire/pkt-line.js.map +0 -1
  345. package/dist/wire/receive-pack.d.ts +0 -1059
  346. package/dist/wire/receive-pack.d.ts.map +0 -1
  347. package/dist/wire/receive-pack.js +0 -1414
  348. package/dist/wire/receive-pack.js.map +0 -1
  349. package/dist/wire/smart-http.d.ts +0 -799
  350. package/dist/wire/smart-http.d.ts.map +0 -1
  351. package/dist/wire/smart-http.js +0 -945
  352. package/dist/wire/smart-http.js.map +0 -1
  353. package/dist/wire/upload-pack.d.ts +0 -727
  354. package/dist/wire/upload-pack.d.ts.map +0 -1
  355. package/dist/wire/upload-pack.js +0 -1141
  356. package/dist/wire/upload-pack.js.map +0 -1
@@ -1,784 +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
- // Create a copy as ArrayBuffer to satisfy BufferSource type
570
- const buffer = new ArrayBuffer(data.length);
571
- new Uint8Array(buffer).set(data);
572
- const hashBuffer = await crypto.subtle.digest('SHA-1', buffer);
573
- return this.bytesToHex(new Uint8Array(hashBuffer));
574
- }
575
- /**
576
- * Get diff between references or working tree.
577
- *
578
- * @param _ref - Reference to diff against (not yet implemented)
579
- * @returns Unified diff output
580
- */
581
- async diff(_ref) {
582
- // Placeholder - would need full diff implementation
583
- return `diff --git a/ b/\n(diff not yet implemented)`;
584
- }
585
- /**
586
- * Get commit history.
587
- *
588
- * @param _options - Options for filtering results (not yet implemented)
589
- * @returns Array of commit objects
590
- */
591
- async log(_options) {
592
- // Placeholder - would need commit traversal
593
- if (this.currentCommit) {
594
- return [{ hash: this.currentCommit, message: 'Current commit' }];
595
- }
596
- return [];
597
- }
598
- /**
599
- * Pull changes from R2 (alias for sync).
600
- *
601
- * @param _remote - Remote name (ignored, always uses R2)
602
- * @param _branch - Branch to pull (uses configured branch)
603
- */
604
- async pull(_remote, _branch) {
605
- const result = await this.sync();
606
- if (!result.success) {
607
- throw new Error(result.error ?? 'Pull failed');
608
- }
609
- }
610
- // ═══════════════════════════════════════════════════════════════════════════
611
- // Private Helper Methods
612
- // ═══════════════════════════════════════════════════════════════════════════
613
- /**
614
- * Fetch a git object from R2 by SHA.
615
- */
616
- async fetchObject(sha) {
617
- if (!this.r2)
618
- return null;
619
- const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
620
- const object = await this.r2.get(key);
621
- if (!object)
622
- return null;
623
- const buffer = await object.arrayBuffer();
624
- return new Uint8Array(buffer);
625
- }
626
- /**
627
- * Store a git object in R2.
628
- */
629
- async storeObject(sha, data) {
630
- if (!this.r2)
631
- return;
632
- const key = `${this.objectPrefix}/${sha.slice(0, 2)}/${sha.slice(2)}`;
633
- await this.r2.put(key, data);
634
- }
635
- /**
636
- * Recursively sync a tree and its contents.
637
- */
638
- async syncTree(treeSha, basePath) {
639
- let objects = 0;
640
- let files = 0;
641
- const treeData = await this.fetchObject(treeSha);
642
- if (!treeData)
643
- return { objects, files };
644
- objects++;
645
- // Parse tree entries
646
- // Tree format: mode name\0sha20bytes (repeated)
647
- let offset = 0;
648
- const decoder = new TextDecoder();
649
- while (offset < treeData.length) {
650
- // Find the null byte
651
- let nullIdx = offset;
652
- while (nullIdx < treeData.length && treeData[nullIdx] !== 0) {
653
- nullIdx++;
654
- }
655
- const modeAndName = decoder.decode(treeData.slice(offset, nullIdx));
656
- const spaceIdx = modeAndName.indexOf(' ');
657
- const mode = modeAndName.slice(0, spaceIdx);
658
- const name = modeAndName.slice(spaceIdx + 1);
659
- // Read 20-byte SHA
660
- const sha20 = treeData.slice(nullIdx + 1, nullIdx + 21);
661
- const sha = this.bytesToHex(sha20);
662
- const entryPath = basePath ? `${basePath}/${name}` : name;
663
- if (mode === '40000' || mode === '040000') {
664
- // Directory - recurse
665
- const subResult = await this.syncTree(sha, entryPath);
666
- objects += subResult.objects;
667
- files += subResult.files;
668
- }
669
- else {
670
- // File - fetch blob and write via fs
671
- const blobData = await this.fetchObject(sha);
672
- if (blobData && this.fs) {
673
- objects++;
674
- // Ensure parent directory exists
675
- const parentDir = entryPath.split('/').slice(0, -1).join('/');
676
- if (parentDir) {
677
- await this.fs.mkdir(`/${parentDir}`, { recursive: true });
678
- }
679
- // Write file content (skip git header if present)
680
- await this.fs.writeFile(`/${entryPath}`, Buffer.from(blobData));
681
- files++;
682
- }
683
- }
684
- offset = nullIdx + 21;
685
- }
686
- return { objects, files };
687
- }
688
- /**
689
- * Convert bytes to hex string.
690
- */
691
- bytesToHex(bytes) {
692
- return Array.from(bytes)
693
- .map(b => b.toString(16).padStart(2, '0'))
694
- .join('');
695
- }
696
- /**
697
- * Persist sync state to the database.
698
- * Updates the git table with the current commit and last sync timestamp.
699
- */
700
- async persistSyncState() {
701
- if (!this.storage || !this.repoId)
702
- return;
703
- const now = Date.now();
704
- this.storage.sql.exec(`UPDATE git SET commit = ?, last_sync = ?, updated_at = ? WHERE id = ?`, this.currentCommit ?? null, now, now, this.repoId);
705
- }
706
- /**
707
- * Persist a staged file to the database.
708
- * Inserts or updates a record in the git_content table.
709
- * Uses file_id foreign key to reference the shared files table when available.
710
- */
711
- async persistStagedFile(file) {
712
- if (!this.storage || !this.repoId)
713
- return;
714
- const now = Date.now();
715
- // Get file_id from filesystem if getFileId is available
716
- let fileId = null;
717
- if (this.fs?.getFileId) {
718
- try {
719
- fileId = await this.fs.getFileId(file);
720
- }
721
- catch {
722
- // File may not exist in filesystem yet, that's okay
723
- fileId = null;
724
- }
725
- }
726
- // Use INSERT OR REPLACE to handle both new and existing files
727
- // Include file_id for efficient foreign key relationships
728
- this.storage.sql.exec(`INSERT INTO git_content (repo_id, file_id, path, status, created_at, updated_at)
729
- VALUES (?, ?, ?, 'staged', ?, ?)
730
- ON CONFLICT(repo_id, path) DO UPDATE SET status = 'staged', file_id = ?, updated_at = ?`, this.repoId, fileId, file, now, now, fileId, now);
731
- }
732
- /**
733
- * Persist commit state to the database.
734
- * Updates the git table with the new commit hash and clears staged files.
735
- */
736
- async persistCommitState(hash) {
737
- if (!this.storage || !this.repoId)
738
- return;
739
- const now = Date.now();
740
- // Update the commit hash in the git table
741
- this.storage.sql.exec(`UPDATE git SET commit = ?, updated_at = ? WHERE id = ?`, hash, now, this.repoId);
742
- // Update branch head
743
- this.storage.sql.exec(`UPDATE git_branches SET head = ?, updated_at = ? WHERE repo_id = ? AND name = ?`, hash, now, this.repoId, this.branch);
744
- // Clear staged files from git_content
745
- this.storage.sql.exec(`DELETE FROM git_content WHERE repo_id = ? AND status = 'staged'`, this.repoId);
746
- }
747
- }
748
- // ============================================================================
749
- // Factory Functions
750
- // ============================================================================
751
- /**
752
- * Create a GitModule instance with the given options.
753
- *
754
- * @param options - Configuration options for the module
755
- * @returns A new GitModule instance
756
- *
757
- * @example
758
- * ```typescript
759
- * import { createGitModule } from 'gitx.do/do'
760
- *
761
- * const git = createGitModule({
762
- * repo: 'org/repo',
763
- * branch: 'main',
764
- * r2: env.R2_BUCKET,
765
- * fs: workflowContext.fs
766
- * })
767
- * ```
768
- */
769
- export function createGitModule(options) {
770
- return new GitModule(options);
771
- }
772
- // ============================================================================
773
- // Type Guards
774
- // ============================================================================
775
- /**
776
- * Check if a value is a GitModule instance.
777
- *
778
- * @param value - Value to check
779
- * @returns True if value is a GitModule
780
- */
781
- export function isGitModule(value) {
782
- return value instanceof GitModule;
783
- }
784
- //# sourceMappingURL=GitModule.js.map