gitspace 0.2.0-rc.2 → 0.2.0-rc.21

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 (316) hide show
  1. package/README.md +68 -38
  2. package/package.json +36 -25
  3. package/.claude/settings.local.json +0 -21
  4. package/.gitspace/bundle.json +0 -50
  5. package/.gitspace/select/01-status.sh +0 -40
  6. package/.gitspace/setup/01-install-deps.sh +0 -12
  7. package/.gitspace/setup/02-typecheck.sh +0 -16
  8. package/AGENTS.md +0 -439
  9. package/CLAUDE.md +0 -1
  10. package/bun.lock +0 -647
  11. package/docs/CONNECTION.md +0 -623
  12. package/docs/GATEWAY-WORKER.md +0 -319
  13. package/docs/GETTING-STARTED.md +0 -448
  14. package/docs/GITSPACE-PLATFORM.md +0 -1819
  15. package/docs/INFRASTRUCTURE.md +0 -1347
  16. package/docs/PROTOCOL.md +0 -619
  17. package/docs/QUICKSTART.md +0 -174
  18. package/docs/RELAY.md +0 -327
  19. package/docs/REMOTE-DESIGN.md +0 -549
  20. package/docs/ROADMAP.md +0 -564
  21. package/docs/SITE_DOCS_FIGMA_MAKE.md +0 -1167
  22. package/docs/STACK-DESIGN.md +0 -588
  23. package/docs/UNIFIED_ARCHITECTURE.md +0 -292
  24. package/experiments/pty-benchmark.ts +0 -148
  25. package/experiments/pty-latency.ts +0 -100
  26. package/experiments/router/client.ts +0 -199
  27. package/experiments/router/protocol.ts +0 -74
  28. package/experiments/router/router.ts +0 -217
  29. package/experiments/router/session.ts +0 -180
  30. package/experiments/router/test.ts +0 -133
  31. package/experiments/socket-bandwidth.ts +0 -77
  32. package/homebrew/gitspace.rb +0 -45
  33. package/landing-page/ATTRIBUTIONS.md +0 -3
  34. package/landing-page/README.md +0 -11
  35. package/landing-page/bun.lock +0 -801
  36. package/landing-page/guidelines/Guidelines.md +0 -61
  37. package/landing-page/index.html +0 -37
  38. package/landing-page/package.json +0 -90
  39. package/landing-page/postcss.config.mjs +0 -15
  40. package/landing-page/public/_redirects +0 -1
  41. package/landing-page/public/favicon.png +0 -0
  42. package/landing-page/src/app/App.tsx +0 -53
  43. package/landing-page/src/app/components/figma/ImageWithFallback.tsx +0 -27
  44. package/landing-page/src/app/components/ui/accordion.tsx +0 -66
  45. package/landing-page/src/app/components/ui/alert-dialog.tsx +0 -157
  46. package/landing-page/src/app/components/ui/alert.tsx +0 -66
  47. package/landing-page/src/app/components/ui/aspect-ratio.tsx +0 -11
  48. package/landing-page/src/app/components/ui/avatar.tsx +0 -53
  49. package/landing-page/src/app/components/ui/badge.tsx +0 -46
  50. package/landing-page/src/app/components/ui/breadcrumb.tsx +0 -109
  51. package/landing-page/src/app/components/ui/button.tsx +0 -57
  52. package/landing-page/src/app/components/ui/calendar.tsx +0 -75
  53. package/landing-page/src/app/components/ui/card.tsx +0 -92
  54. package/landing-page/src/app/components/ui/carousel.tsx +0 -241
  55. package/landing-page/src/app/components/ui/chart.tsx +0 -353
  56. package/landing-page/src/app/components/ui/checkbox.tsx +0 -32
  57. package/landing-page/src/app/components/ui/collapsible.tsx +0 -33
  58. package/landing-page/src/app/components/ui/command.tsx +0 -177
  59. package/landing-page/src/app/components/ui/context-menu.tsx +0 -252
  60. package/landing-page/src/app/components/ui/dialog.tsx +0 -135
  61. package/landing-page/src/app/components/ui/drawer.tsx +0 -132
  62. package/landing-page/src/app/components/ui/dropdown-menu.tsx +0 -257
  63. package/landing-page/src/app/components/ui/form.tsx +0 -168
  64. package/landing-page/src/app/components/ui/hover-card.tsx +0 -44
  65. package/landing-page/src/app/components/ui/input-otp.tsx +0 -77
  66. package/landing-page/src/app/components/ui/input.tsx +0 -21
  67. package/landing-page/src/app/components/ui/label.tsx +0 -24
  68. package/landing-page/src/app/components/ui/menubar.tsx +0 -276
  69. package/landing-page/src/app/components/ui/navigation-menu.tsx +0 -168
  70. package/landing-page/src/app/components/ui/pagination.tsx +0 -127
  71. package/landing-page/src/app/components/ui/popover.tsx +0 -48
  72. package/landing-page/src/app/components/ui/progress.tsx +0 -31
  73. package/landing-page/src/app/components/ui/radio-group.tsx +0 -45
  74. package/landing-page/src/app/components/ui/resizable.tsx +0 -56
  75. package/landing-page/src/app/components/ui/scroll-area.tsx +0 -58
  76. package/landing-page/src/app/components/ui/select.tsx +0 -189
  77. package/landing-page/src/app/components/ui/separator.tsx +0 -28
  78. package/landing-page/src/app/components/ui/sheet.tsx +0 -139
  79. package/landing-page/src/app/components/ui/sidebar.tsx +0 -726
  80. package/landing-page/src/app/components/ui/skeleton.tsx +0 -13
  81. package/landing-page/src/app/components/ui/slider.tsx +0 -63
  82. package/landing-page/src/app/components/ui/sonner.tsx +0 -25
  83. package/landing-page/src/app/components/ui/switch.tsx +0 -31
  84. package/landing-page/src/app/components/ui/table.tsx +0 -116
  85. package/landing-page/src/app/components/ui/tabs.tsx +0 -66
  86. package/landing-page/src/app/components/ui/textarea.tsx +0 -18
  87. package/landing-page/src/app/components/ui/toggle-group.tsx +0 -73
  88. package/landing-page/src/app/components/ui/toggle.tsx +0 -47
  89. package/landing-page/src/app/components/ui/tooltip.tsx +0 -61
  90. package/landing-page/src/app/components/ui/use-mobile.ts +0 -21
  91. package/landing-page/src/app/components/ui/utils.ts +0 -6
  92. package/landing-page/src/components/docs/DocsContent.tsx +0 -718
  93. package/landing-page/src/components/docs/DocsSidebar.tsx +0 -84
  94. package/landing-page/src/components/landing/CTA.tsx +0 -59
  95. package/landing-page/src/components/landing/Comparison.tsx +0 -84
  96. package/landing-page/src/components/landing/FaultyTerminal.tsx +0 -424
  97. package/landing-page/src/components/landing/Features.tsx +0 -201
  98. package/landing-page/src/components/landing/Hero.tsx +0 -142
  99. package/landing-page/src/components/landing/Pricing.tsx +0 -140
  100. package/landing-page/src/components/landing/Roadmap.tsx +0 -86
  101. package/landing-page/src/components/landing/Security.tsx +0 -81
  102. package/landing-page/src/components/landing/TerminalWindow.tsx +0 -27
  103. package/landing-page/src/components/landing/UseCases.tsx +0 -55
  104. package/landing-page/src/components/landing/Workflow.tsx +0 -101
  105. package/landing-page/src/components/layout/DashboardNavbar.tsx +0 -37
  106. package/landing-page/src/components/layout/Footer.tsx +0 -55
  107. package/landing-page/src/components/layout/LandingNavbar.tsx +0 -82
  108. package/landing-page/src/components/ui/badge.tsx +0 -39
  109. package/landing-page/src/components/ui/breadcrumb.tsx +0 -115
  110. package/landing-page/src/components/ui/button.tsx +0 -57
  111. package/landing-page/src/components/ui/card.tsx +0 -79
  112. package/landing-page/src/components/ui/mock-terminal.tsx +0 -68
  113. package/landing-page/src/components/ui/separator.tsx +0 -28
  114. package/landing-page/src/lib/utils.ts +0 -6
  115. package/landing-page/src/main.tsx +0 -10
  116. package/landing-page/src/pages/Dashboard.tsx +0 -133
  117. package/landing-page/src/pages/DocsPage.tsx +0 -79
  118. package/landing-page/src/pages/LandingPage.tsx +0 -31
  119. package/landing-page/src/pages/TerminalView.tsx +0 -106
  120. package/landing-page/src/styles/fonts.css +0 -0
  121. package/landing-page/src/styles/index.css +0 -3
  122. package/landing-page/src/styles/tailwind.css +0 -4
  123. package/landing-page/src/styles/theme.css +0 -181
  124. package/landing-page/vite.config.ts +0 -19
  125. package/npm/darwin-arm64/bin/gssh +0 -0
  126. package/npm/darwin-arm64/package.json +0 -20
  127. package/scripts/build.ts +0 -298
  128. package/scripts/release.ts +0 -140
  129. package/src/__tests__/test-utils.ts +0 -298
  130. package/src/commands/__tests__/serve-messages.test.ts +0 -190
  131. package/src/commands/access.ts +0 -298
  132. package/src/commands/add.ts +0 -452
  133. package/src/commands/auth.ts +0 -364
  134. package/src/commands/connect.ts +0 -287
  135. package/src/commands/directory.ts +0 -16
  136. package/src/commands/host.ts +0 -396
  137. package/src/commands/identity.ts +0 -184
  138. package/src/commands/list.ts +0 -200
  139. package/src/commands/relay.ts +0 -315
  140. package/src/commands/remove.ts +0 -241
  141. package/src/commands/serve.ts +0 -1493
  142. package/src/commands/share.ts +0 -456
  143. package/src/commands/status.ts +0 -125
  144. package/src/commands/switch.ts +0 -353
  145. package/src/commands/tmux.ts +0 -317
  146. package/src/core/__tests__/access.test.ts +0 -240
  147. package/src/core/access.ts +0 -277
  148. package/src/core/bundle.ts +0 -342
  149. package/src/core/config.ts +0 -510
  150. package/src/core/git.ts +0 -317
  151. package/src/core/github.ts +0 -151
  152. package/src/core/identity.ts +0 -631
  153. package/src/core/linear.ts +0 -225
  154. package/src/core/shell.ts +0 -161
  155. package/src/core/trusted-relays.ts +0 -315
  156. package/src/index.ts +0 -810
  157. package/src/lib/remote-session/index.ts +0 -7
  158. package/src/lib/remote-session/protocol.ts +0 -267
  159. package/src/lib/remote-session/session-handler.ts +0 -581
  160. package/src/lib/remote-session/workspace-scanner.ts +0 -167
  161. package/src/lib/tmux-lite/README.md +0 -81
  162. package/src/lib/tmux-lite/cli.ts +0 -796
  163. package/src/lib/tmux-lite/crypto/__tests__/helpers/handshake-runner.ts +0 -349
  164. package/src/lib/tmux-lite/crypto/__tests__/helpers/mock-relay.ts +0 -291
  165. package/src/lib/tmux-lite/crypto/__tests__/helpers/test-identities.ts +0 -142
  166. package/src/lib/tmux-lite/crypto/__tests__/integration/authorization.integration.test.ts +0 -339
  167. package/src/lib/tmux-lite/crypto/__tests__/integration/e2e-communication.integration.test.ts +0 -477
  168. package/src/lib/tmux-lite/crypto/__tests__/integration/error-handling.integration.test.ts +0 -499
  169. package/src/lib/tmux-lite/crypto/__tests__/integration/handshake.integration.test.ts +0 -371
  170. package/src/lib/tmux-lite/crypto/__tests__/integration/security.integration.test.ts +0 -573
  171. package/src/lib/tmux-lite/crypto/access-control.test.ts +0 -512
  172. package/src/lib/tmux-lite/crypto/access-control.ts +0 -320
  173. package/src/lib/tmux-lite/crypto/frames.test.ts +0 -262
  174. package/src/lib/tmux-lite/crypto/frames.ts +0 -141
  175. package/src/lib/tmux-lite/crypto/handshake.ts +0 -894
  176. package/src/lib/tmux-lite/crypto/identity.test.ts +0 -220
  177. package/src/lib/tmux-lite/crypto/identity.ts +0 -286
  178. package/src/lib/tmux-lite/crypto/index.ts +0 -51
  179. package/src/lib/tmux-lite/crypto/invites.test.ts +0 -381
  180. package/src/lib/tmux-lite/crypto/invites.ts +0 -215
  181. package/src/lib/tmux-lite/crypto/keyexchange.ts +0 -435
  182. package/src/lib/tmux-lite/crypto/keys.test.ts +0 -58
  183. package/src/lib/tmux-lite/crypto/keys.ts +0 -47
  184. package/src/lib/tmux-lite/crypto/secretbox.test.ts +0 -169
  185. package/src/lib/tmux-lite/crypto/secretbox.ts +0 -124
  186. package/src/lib/tmux-lite/handshake-handler.ts +0 -451
  187. package/src/lib/tmux-lite/protocol.test.ts +0 -307
  188. package/src/lib/tmux-lite/protocol.ts +0 -266
  189. package/src/lib/tmux-lite/relay-client.ts +0 -506
  190. package/src/lib/tmux-lite/server.ts +0 -1250
  191. package/src/lib/tmux-lite/shell-integration.sh +0 -37
  192. package/src/lib/tmux-lite/terminal-queries.test.ts +0 -54
  193. package/src/lib/tmux-lite/terminal-queries.ts +0 -49
  194. package/src/relay/__tests__/e2e-flow.test.ts +0 -1284
  195. package/src/relay/__tests__/helpers/auth.ts +0 -354
  196. package/src/relay/__tests__/helpers/ports.ts +0 -51
  197. package/src/relay/__tests__/protocol-validation.test.ts +0 -265
  198. package/src/relay/authorization.ts +0 -303
  199. package/src/relay/embedded-assets.generated.d.ts +0 -15
  200. package/src/relay/identity.ts +0 -352
  201. package/src/relay/index.ts +0 -57
  202. package/src/relay/pipes.test.ts +0 -427
  203. package/src/relay/pipes.ts +0 -195
  204. package/src/relay/protocol.ts +0 -804
  205. package/src/relay/registries.test.ts +0 -437
  206. package/src/relay/registries.ts +0 -593
  207. package/src/relay/server.test.ts +0 -1323
  208. package/src/relay/server.ts +0 -1092
  209. package/src/relay/signing.ts +0 -238
  210. package/src/relay/types.ts +0 -69
  211. package/src/serve/client-session-manager.ts +0 -622
  212. package/src/serve/daemon.ts +0 -497
  213. package/src/serve/pty-session.ts +0 -236
  214. package/src/serve/types.ts +0 -169
  215. package/src/shared/components/Flow.tsx +0 -453
  216. package/src/shared/components/Flow.tui.tsx +0 -343
  217. package/src/shared/components/Flow.web.tsx +0 -442
  218. package/src/shared/components/Inbox.tsx +0 -446
  219. package/src/shared/components/Inbox.tui.tsx +0 -262
  220. package/src/shared/components/Inbox.web.tsx +0 -329
  221. package/src/shared/components/MachineList.tsx +0 -187
  222. package/src/shared/components/MachineList.tui.tsx +0 -161
  223. package/src/shared/components/MachineList.web.tsx +0 -210
  224. package/src/shared/components/ProjectList.tsx +0 -176
  225. package/src/shared/components/ProjectList.tui.tsx +0 -109
  226. package/src/shared/components/ProjectList.web.tsx +0 -143
  227. package/src/shared/components/SpacesBrowser.tsx +0 -332
  228. package/src/shared/components/SpacesBrowser.tui.tsx +0 -163
  229. package/src/shared/components/SpacesBrowser.web.tsx +0 -221
  230. package/src/shared/components/index.ts +0 -103
  231. package/src/shared/hooks/index.ts +0 -16
  232. package/src/shared/hooks/useNavigation.ts +0 -226
  233. package/src/shared/index.ts +0 -122
  234. package/src/shared/providers/LocalMachineProvider.ts +0 -425
  235. package/src/shared/providers/MachineProvider.ts +0 -165
  236. package/src/shared/providers/RemoteMachineProvider.ts +0 -444
  237. package/src/shared/providers/index.ts +0 -26
  238. package/src/shared/types.ts +0 -145
  239. package/src/tui/adapters.ts +0 -120
  240. package/src/tui/app.tsx +0 -1816
  241. package/src/tui/components/Terminal.tsx +0 -580
  242. package/src/tui/hooks/index.ts +0 -35
  243. package/src/tui/hooks/useAppState.ts +0 -314
  244. package/src/tui/hooks/useDaemonStatus.ts +0 -174
  245. package/src/tui/hooks/useInboxTUI.ts +0 -113
  246. package/src/tui/hooks/useRemoteMachines.ts +0 -209
  247. package/src/tui/index.ts +0 -24
  248. package/src/tui/state.ts +0 -299
  249. package/src/tui/terminal-bracketed-paste.test.ts +0 -45
  250. package/src/tui/terminal-bracketed-paste.ts +0 -47
  251. package/src/types/bundle.ts +0 -112
  252. package/src/types/config.ts +0 -89
  253. package/src/types/errors.ts +0 -206
  254. package/src/types/identity.ts +0 -284
  255. package/src/types/workspace-fuzzy.ts +0 -49
  256. package/src/types/workspace.ts +0 -151
  257. package/src/utils/bun-socket-writer.ts +0 -80
  258. package/src/utils/deps.ts +0 -127
  259. package/src/utils/fuzzy-match.ts +0 -125
  260. package/src/utils/logger.ts +0 -127
  261. package/src/utils/markdown.ts +0 -254
  262. package/src/utils/onboarding.ts +0 -229
  263. package/src/utils/prompts.ts +0 -114
  264. package/src/utils/run-commands.ts +0 -112
  265. package/src/utils/run-scripts.ts +0 -142
  266. package/src/utils/sanitize.ts +0 -98
  267. package/src/utils/secrets.ts +0 -122
  268. package/src/utils/shell-escape.ts +0 -40
  269. package/src/utils/utf8.ts +0 -79
  270. package/src/utils/workspace-state.ts +0 -47
  271. package/src/web/README.md +0 -73
  272. package/src/web/bun.lock +0 -575
  273. package/src/web/eslint.config.js +0 -23
  274. package/src/web/index.html +0 -16
  275. package/src/web/package.json +0 -37
  276. package/src/web/public/vite.svg +0 -1
  277. package/src/web/src/App.tsx +0 -604
  278. package/src/web/src/assets/react.svg +0 -1
  279. package/src/web/src/components/Terminal.tsx +0 -207
  280. package/src/web/src/hooks/useRelayConnection.ts +0 -224
  281. package/src/web/src/hooks/useTerminal.ts +0 -699
  282. package/src/web/src/index.css +0 -55
  283. package/src/web/src/lib/crypto/__tests__/web-terminal.test.ts +0 -1158
  284. package/src/web/src/lib/crypto/frames.ts +0 -205
  285. package/src/web/src/lib/crypto/handshake.ts +0 -396
  286. package/src/web/src/lib/crypto/identity.ts +0 -128
  287. package/src/web/src/lib/crypto/keyexchange.ts +0 -246
  288. package/src/web/src/lib/crypto/relay-signing.ts +0 -53
  289. package/src/web/src/lib/invite.ts +0 -58
  290. package/src/web/src/lib/storage/identity-store.ts +0 -94
  291. package/src/web/src/main.tsx +0 -10
  292. package/src/web/src/types/identity.ts +0 -45
  293. package/src/web/tsconfig.app.json +0 -28
  294. package/src/web/tsconfig.json +0 -7
  295. package/src/web/tsconfig.node.json +0 -26
  296. package/src/web/vite.config.ts +0 -31
  297. package/todo-security.md +0 -92
  298. package/tsconfig.json +0 -23
  299. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite +0 -0
  300. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite-shm +0 -0
  301. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite-wal +0 -0
  302. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite +0 -0
  303. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite-shm +0 -0
  304. package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite-wal +0 -0
  305. package/worker/bun.lock +0 -237
  306. package/worker/package.json +0 -22
  307. package/worker/schema.sql +0 -96
  308. package/worker/src/handlers/auth.ts +0 -451
  309. package/worker/src/handlers/subdomains.ts +0 -376
  310. package/worker/src/handlers/user.ts +0 -98
  311. package/worker/src/index.ts +0 -70
  312. package/worker/src/middleware/auth.ts +0 -152
  313. package/worker/src/services/cloudflare.ts +0 -609
  314. package/worker/src/types.ts +0 -96
  315. package/worker/tsconfig.json +0 -15
  316. package/worker/wrangler.toml +0 -26
@@ -1,588 +0,0 @@
1
- # Stacked PR Feature - Architecture Design
2
-
3
- > **⚠️ FUTURE FEATURE DOCUMENT**
4
- >
5
- > This document describes a **planned feature** that is **not yet implemented**.
6
- > The `gssh stack` command does not currently exist. This is a design document for future development.
7
-
8
- ---
9
-
10
- > AI-assisted splitting of work-in-progress commits into clean, logical PRs
11
-
12
- ## Overview
13
-
14
- The `gssh stack` command helps developers split messy WIP commits into clean, reviewable PRs using AI-assisted code analysis in a sandboxed environment.
15
-
16
- ## Core Concept
17
-
18
- ```
19
- User's messy branch:
20
- main ── wip1 ── wip2 ── debug ── wip3 ── fixup ── wip4 ── more...
21
- └──────────── logical unit A ───────────┘ └── continued ──
22
-
23
- After `gssh stack`:
24
- main ── "Add auth" ── "Add tests" ──┬── (PR #1 created)
25
-
26
- └── user's work rebased on top
27
- ```
28
-
29
- **Key insight**: Instead of building a fixed algorithm, we give the AI tools (AST analysis, git operations) in a sandbox and let it explore different ways to split the code.
30
-
31
- ## Architecture
32
-
33
- ### High-Level Components
34
-
35
- ```
36
- ┌─────────────────────────────────────────────────────────────────────┐
37
- │ gssh stack command │
38
- ├─────────────────────────────────────────────────────────────────────┤
39
- │ │
40
- │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
41
- │ │ Diff │ │ Sandbox │ │ Interactive UI │ │
42
- │ │ Analyzer │───▶│ + AI │───▶│ (TUI/Prompts) │ │
43
- │ │ │ │ Explorer │ │ │ │
44
- │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
45
- │ │ │ │ │
46
- │ ▼ ▼ ▼ │
47
- │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
48
- │ │ AST │ │ Virtual │ │ Git Operations │ │
49
- │ │ Bindings │ │ Filesystem │ │ (rebase, PR create) │ │
50
- │ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
51
- │ │
52
- └─────────────────────────────────────────────────────────────────────┘
53
- ```
54
-
55
- ### Dependencies
56
-
57
- ```json
58
- {
59
- "dependencies": {
60
- "isomorphic-git": "^1.25.0", // Git ops in sandbox
61
- "memfs": "^4.6.0", // Virtual filesystem
62
- "@babel/parser": "^7.23.0", // AST parsing for JS/TS
63
- "@babel/traverse": "^7.23.0", // AST traversal
64
- "@babel/types": "^7.23.0", // AST type utilities
65
- "isolated-vm": "^4.7.0", // V8 isolate sandbox
66
- "ai-flow": "...", // AI abstraction (OpenAI responses API compatible)
67
- "tensorzero": "..." // Multi-provider AI routing
68
- }
69
- }
70
- ```
71
-
72
- ---
73
-
74
- ## Component Design
75
-
76
- ### 1. Diff Analyzer (`src/core/stack/diff-analyzer.ts`)
77
-
78
- Parses git diff and extracts structured change information.
79
-
80
- ```typescript
81
- interface FileChange {
82
- path: string;
83
- status: 'added' | 'modified' | 'deleted' | 'renamed';
84
- hunks: Hunk[];
85
- oldContent?: string;
86
- newContent?: string;
87
- }
88
-
89
- interface Hunk {
90
- oldStart: number;
91
- oldLines: number;
92
- newStart: number;
93
- newLines: number;
94
- content: string;
95
- addedLines: Line[];
96
- removedLines: Line[];
97
- }
98
-
99
- // Functions
100
- function parseDiff(diffText: string): FileChange[];
101
- function getChangesInRange(repoPath: string, range: string): Promise<FileChange[]>;
102
- function getFileAtRevision(repoPath: string, file: string, rev: string): Promise<string>;
103
- ```
104
-
105
- ### 2. AST Analysis Bindings (`src/core/stack/ast-bindings.ts`)
106
-
107
- Provides TypeScript API for the AI sandbox to analyze code.
108
-
109
- ```typescript
110
- interface Symbol {
111
- name: string;
112
- kind: 'function' | 'class' | 'type' | 'variable' | 'import' | 'export';
113
- file: string;
114
- line: number;
115
- exported: boolean;
116
- }
117
-
118
- interface Reference {
119
- symbol: string;
120
- file: string;
121
- line: number;
122
- }
123
-
124
- interface ASTBindings {
125
- // Parse code and return AST
126
- parse(code: string, language: string): AST;
127
-
128
- // Extract symbols defined in code
129
- findDefinitions(code: string, language: string): Symbol[];
130
-
131
- // Extract symbols referenced in code
132
- findReferences(code: string, language: string): Reference[];
133
-
134
- // Check if a set of changes is self-consistent
135
- checkDependencies(changes: FileChange[]): {
136
- valid: boolean;
137
- missing: Symbol[]; // Referenced but not defined
138
- circular: Symbol[][]; // Mutually dependent
139
- };
140
-
141
- // Get language from file extension
142
- detectLanguage(filename: string): string;
143
- }
144
- ```
145
-
146
- ### 3. Dependency Graph (`src/core/stack/dependency-graph.ts`)
147
-
148
- Builds and analyzes the dependency graph of changes.
149
-
150
- ```typescript
151
- interface ChangeNode {
152
- id: string;
153
- files: string[];
154
- hunks: Hunk[];
155
- defines: Symbol[];
156
- references: Symbol[];
157
- }
158
-
159
- interface DependencyGraph {
160
- nodes: Map<string, ChangeNode>;
161
- edges: Map<string, Set<string>>; // node -> depends on
162
- }
163
-
164
- // Functions
165
- function buildGraph(changes: FileChange[], ast: ASTBindings): DependencyGraph;
166
- function findStronglyConnectedComponents(graph: DependencyGraph): ChangeNode[][];
167
- function topologicalSort(graph: DependencyGraph): ChangeNode[];
168
- function suggestGroupings(graph: DependencyGraph): ProposedCommit[];
169
- ```
170
-
171
- **Dependency Analysis Flow:**
172
-
173
- ```
174
- Change A: Define `validateUser()` function
175
- Change B: Use `validateUser()` in login.ts
176
- Change C: Add `UserRole` type
177
- Change D: Use `UserRole` in validateUser()
178
-
179
- Dependency graph:
180
- ─────────────────────────────────
181
- C (UserRole)
182
-
183
-
184
- A (validateUser) ◄── D (uses UserRole in A)
185
-
186
-
187
- B (uses validateUser)
188
- ─────────────────────────────────
189
-
190
- Valid orderings: C → A+D → B
191
- Invalid: B before A (undefined function)
192
- ```
193
-
194
- ### 4. Virtual Filesystem + Sandbox (`src/core/stack/sandbox.ts`)
195
-
196
- Creates an isolated environment where AI can experiment with different commit arrangements.
197
-
198
- ```typescript
199
- interface SandboxFS {
200
- // Read file (from base + overlay)
201
- readFile(path: string): Promise<string>;
202
-
203
- // Write to overlay (doesn't affect real FS)
204
- writeFile(path: string, content: string): Promise<void>;
205
-
206
- // Apply a patch to the virtual FS
207
- applyPatch(patch: string): Promise<void>;
208
-
209
- // Reset overlay, keep base
210
- reset(): void;
211
-
212
- // Snapshot current state
213
- snapshot(): FSSnapshot;
214
-
215
- // Restore from snapshot
216
- restore(snapshot: FSSnapshot): void;
217
- }
218
-
219
- interface Sandbox {
220
- fs: SandboxFS;
221
- git: SandboxGit; // isomorphic-git bound to virtual FS
222
- ast: ASTBindings;
223
-
224
- // Execute AI-generated code in isolated environment
225
- execute(code: string): Promise<any>;
226
- }
227
-
228
- // Implementation using memfs + isolated-vm
229
- function createSandbox(repoPath: string, baseRef: string): Promise<Sandbox>;
230
- ```
231
-
232
- **Sandbox Architecture:**
233
-
234
- ```
235
- ┌─────────────────────────────────────────────────────────────────┐
236
- │ Virtual FS Layer │
237
- ├─────────────────────────────────────────────────────────────────┤
238
- │ │
239
- │ Base: Git tree at main (read-only) │
240
- │ │ │
241
- │ ├── Overlay: Proposed changes (copy-on-write) │
242
- │ │ │
243
- │ └── AI can: │
244
- │ • Apply patch A, run tree-sitter, check deps │
245
- │ • Apply patch A+B, run tsc, see if it compiles │
246
- │ • Rollback, try different arrangement │
247
- │ • Read any file as it would exist at that state │
248
- │ │
249
- └─────────────────────────────────────────────────────────────────┘
250
- ```
251
-
252
- ### 5. AI Integration (`src/core/stack/ai-explorer.ts`)
253
-
254
- Orchestrates AI exploration of different commit arrangements.
255
-
256
- ```typescript
257
- interface ProposedCommit {
258
- message: string;
259
- files: string[];
260
- hunks: Hunk[];
261
- reasoning: string;
262
- }
263
-
264
- interface StackProposal {
265
- commits: ProposedCommit[];
266
- dependencyOrder: string[]; // Commit order
267
- warnings: string[]; // Things user should review
268
- conflicts: ConflictInfo[]; // Where user input needed
269
- }
270
-
271
- interface ConflictInfo {
272
- type: 'circular' | 'interleaved' | 'ambiguous';
273
- files: string[];
274
- description: string;
275
- options: string[];
276
- }
277
- ```
278
-
279
- **AI Sandbox Bindings:**
280
-
281
- ```typescript
282
- import { AIFlow } from 'ai-flow'; // OpenAI responses API compatible
283
-
284
- const AI_SYSTEM_PROMPT = `
285
- You are analyzing code changes to split them into logical PRs.
286
-
287
- You have access to these TypeScript APIs in your sandbox:
288
- - git.getDiff(range): Get diff for commit range
289
- - git.getFile(path, rev): Get file at revision
290
- - ast.parse(code): Parse JS/TS to AST
291
- - ast.findDefinitions(code): Find defined symbols
292
- - ast.findReferences(code): Find referenced symbols
293
- - ast.checkDeps(changes): Check if changes are self-consistent
294
- - propose.group(files[], message): Propose a commit grouping
295
- - propose.validate(groups[]): Validate proposed groupings
296
-
297
- Write TypeScript code to explore the changes and propose logical groupings.
298
- Return your final proposal via propose.finalize(groups[]).
299
- `;
300
- ```
301
-
302
- ### 6. Interactive UI (`src/core/stack/ui.ts`)
303
-
304
- TUI components for user interaction.
305
-
306
- ```
307
- ┌─────────────────────────────────────────────────────────────────┐
308
- │ gssh stack - Analyzing changes... │
309
- ├─────────────────────────────────────────────────────────────────┤
310
- │ │
311
- │ Found 47 changed lines across 8 files │
312
- │ Base: main (3 commits behind) │
313
- │ │
314
- │ Proposed Stack: │
315
- │ ─────────────── │
316
- │ PR #1: "Add user authentication middleware" │
317
- │ ├── src/middleware/auth.ts (+45 -12) │
318
- │ ├── src/types/user.ts (+8 -0) │
319
- │ └── src/routes/login.ts (+15 -3) │
320
- │ │
321
- │ PR #2: "Update button styles" │
322
- │ └── src/styles/button.css (+5 -2) │
323
- │ │
324
- │ ⚠️ Needs Review: │
325
- │ src/utils/helpers.ts has changes for both PRs │
326
- │ │
327
- │ [a] Accept [e] Edit [s] Split file [?] Help │
328
- └─────────────────────────────────────────────────────────────────┘
329
- ```
330
-
331
- **Features:**
332
- - Show proposed groupings with file lists
333
- - Highlight conflicts/warnings
334
- - Allow editing commit messages
335
- - Allow reassigning files/hunks to different commits
336
- - Preview resulting git history
337
- - Confirm before executing
338
-
339
- ### 7. Git Execution (`src/core/stack/git-executor.ts`)
340
-
341
- Actually creates the branches and PRs.
342
-
343
- ```typescript
344
- interface StackExecutionPlan {
345
- prBranches: string[]; // e.g., ["feature-auth", "feature-styles"]
346
- continuationBranch: string; // Where remaining work goes
347
- commits: Map<string, ProposedCommit[]>;
348
- rebaseOnto: string;
349
- }
350
-
351
- async function executeStack(
352
- workspacePath: string,
353
- plan: StackExecutionPlan,
354
- createPRs: boolean
355
- ): Promise<{
356
- createdBranches: string[];
357
- prUrls?: string[];
358
- continuationBranch: string;
359
- }>;
360
- ```
361
-
362
- ### 8. Stack State Tracking (`src/core/stack/stack-state.ts`)
363
-
364
- Persists stack relationships for future `gssh stack sync`.
365
-
366
- ```typescript
367
- // Stored in ~/gitspace/<project>/.stack-state.json
368
- interface StackState {
369
- stacks: Stack[];
370
- }
371
-
372
- interface Stack {
373
- id: string; // UUID
374
- createdAt: string;
375
- baseBranch: string; // e.g., "main"
376
- prs: StackedPR[]; // Ordered list (bottom to top)
377
- continuationBranch?: string; // Branch with remaining work
378
- }
379
-
380
- interface StackedPR {
381
- branch: string;
382
- prNumber?: number;
383
- prUrl?: string;
384
- status: 'pending' | 'open' | 'merged' | 'closed';
385
- baseBranch: string; // What this PR targets
386
- headCommit: string; // For detecting updates
387
- }
388
- ```
389
-
390
- ### 9. Stack Sync (`src/core/stack/sync.ts`) - Future
391
-
392
- Handles rebasing when PRs are merged/updated.
393
-
394
- ```typescript
395
- // gssh stack sync
396
- async function syncStack(
397
- workspacePath: string,
398
- stackId: string
399
- ): Promise<{
400
- rebased: string[]; // Branches that were rebased
401
- conflicts: string[]; // Branches with conflicts
402
- }>;
403
-
404
- // Workflow:
405
- // 1. Check status of each PR in stack (via gh api)
406
- // 2. For merged PRs: rebase dependent branches onto new base
407
- // 3. For updated PRs: detect force-push, rebase dependents
408
- // 4. Report conflicts for manual resolution
409
- ```
410
-
411
- ---
412
-
413
- ## File Structure
414
-
415
- ```
416
- src/
417
- ├── commands/
418
- │ └── stack.ts # Command entry point
419
- ├── core/
420
- │ └── stack/
421
- │ ├── index.ts # Main orchestrator
422
- │ ├── diff-analyzer.ts # Diff parsing
423
- │ ├── ast-bindings.ts # AST analysis API (Babel-based)
424
- │ ├── dependency-graph.ts # Graph analysis
425
- │ ├── sandbox.ts # Virtual FS + isolate
426
- │ ├── ai-explorer.ts # AI integration (ai-flow)
427
- │ ├── git-executor.ts # Git operations
428
- │ ├── stack-state.ts # Persist stack relationships
429
- │ ├── sync.ts # Stack sync operations (future)
430
- │ └── ui.ts # Interactive UI components
431
- ├── types/
432
- │ └── stack.ts # Type definitions
433
- ```
434
-
435
- **Integration Points:**
436
- - `src/index.ts` - Register `stack` command with Commander.js
437
- - `src/core/git.ts` - Reuse existing git utilities
438
- - `src/utils/prompts.ts` - Reuse selectItem, promptInput, promptConfirm
439
- - `src/core/config.ts` - Add getStackStateFile() path helper
440
-
441
- ---
442
-
443
- ## Command Interface
444
-
445
- ```bash
446
- # Basic usage - analyze current branch vs main
447
- gssh stack
448
-
449
- # Specify base branch
450
- gssh stack --base develop
451
-
452
- # Specify commit range
453
- gssh stack --range HEAD~5..HEAD
454
-
455
- # Non-interactive mode (for CI/scripts)
456
- gssh stack --auto
457
-
458
- # Just analyze, don't execute
459
- gssh stack --dry-run
460
-
461
- # Provide hints to AI
462
- gssh stack --hint "The auth changes should be separate from the UI changes"
463
-
464
- # Stack sync - rebase dependent branches when PRs merge/update
465
- gssh stack sync
466
-
467
- # List active stacks
468
- gssh stack list
469
-
470
- # Show stack status (PR states, rebase needed)
471
- gssh stack status
472
- ```
473
-
474
- **Interactive Prompts:**
475
- 1. After analysis: "Create PRs now, or just prepare branches?" → [Create PRs] [Branches only]
476
- 2. Conflict resolution: "These files have interleaved changes" → [Split] [Keep together] [Show diff]
477
- 3. Commit messages: "Edit commit messages?" → [Accept] [Edit]
478
-
479
- ---
480
-
481
- ## Implementation Phases
482
-
483
- ### Phase 1: Foundation
484
- **Files:** `package.json`, `src/types/stack.ts`, `src/core/stack/diff-analyzer.ts`
485
-
486
- 1. Add dependencies: `@babel/parser`, `@babel/traverse`, `memfs`, `isomorphic-git`, `isolated-vm`
487
- 2. Create type definitions
488
- 3. Implement diff analyzer
489
- 4. Add basic `gssh stack --dry-run` command
490
-
491
- ### Phase 2: AST Analysis
492
- **Files:** `src/core/stack/ast-bindings.ts`, `src/core/stack/dependency-graph.ts`
493
-
494
- 1. Implement AST parsing with @babel/parser
495
- 2. Build dependency graph
496
- 3. Implement SCC detection and topological sort
497
-
498
- ### Phase 3: Sandbox Environment
499
- **Files:** `src/core/stack/sandbox.ts`
500
-
501
- 1. Set up memfs virtual filesystem
502
- 2. Integrate isomorphic-git
503
- 3. Create isolated-vm sandbox with bindings
504
-
505
- ### Phase 4: AI Integration
506
- **Files:** `src/core/stack/ai-explorer.ts`
507
-
508
- 1. Integrate ai-flow client
509
- 2. Create system prompt with binding docs
510
- 3. Implement exploration loop
511
-
512
- ### Phase 5: Interactive UI
513
- **Files:** `src/core/stack/ui.ts`, `src/commands/stack.ts`
514
-
515
- 1. Analysis display
516
- 2. Conflict resolution UI
517
- 3. Commit message editing
518
- 4. File/hunk reassignment
519
-
520
- ### Phase 6: Git Execution
521
- **Files:** `src/core/stack/git-executor.ts`, `src/core/stack/stack-state.ts`
522
-
523
- 1. Branch creation and commit application
524
- 2. PR creation via `gh` CLI
525
- 3. Continuation branch rebasing
526
- 4. State persistence
527
-
528
- ### Phase 7: Stack Management (Future)
529
- **Files:** `src/core/stack/sync.ts`
530
-
531
- 1. `gssh stack list`
532
- 2. `gssh stack status`
533
- 3. `gssh stack sync`
534
-
535
- ### Phase 8: Polish
536
- 1. `--auto` mode
537
- 2. Progress indicators
538
- 3. Rollback on failure
539
- 4. Documentation
540
-
541
- ---
542
-
543
- ## Technical Decisions
544
-
545
- | Decision | Choice | Rationale |
546
- |----------|--------|-----------|
547
- | AST Parser | @babel/parser | Pure JS, no native deps, excellent JS/TS support |
548
- | Sandbox | isolated-vm + memfs | True V8 isolate, fast startup, matches Cloudflare's approach |
549
- | AI Provider | ai-flow + TensorZero | OpenAI responses API compatible, multi-provider support |
550
- | PR Creation | User choice per run | Prompt each time for flexibility |
551
-
552
- ---
553
-
554
- ## Risk Mitigation
555
-
556
- | Risk | Mitigation |
557
- |------|------------|
558
- | AI produces invalid groupings | Validate with AST before presenting to user |
559
- | Complex merges fail | Always work on copies, never modify user's branch until confirmed |
560
- | Large diffs overwhelm AI | Chunk analysis, summarize first |
561
- | Circular dependencies | Detect and flag for user resolution |
562
- | isolated-vm compatibility | Fall back to worker threads if needed |
563
-
564
- ---
565
-
566
- ## Success Criteria
567
-
568
- 1. User can run `gssh stack` and see proposed commit groupings
569
- 2. Each proposed commit is syntactically valid (passes AST validation)
570
- 3. User can adjust groupings interactively
571
- 4. User chooses: create PRs automatically OR just prepare branches
572
- 5. Executing creates clean branches with logical commits
573
- 6. User's remaining work is correctly rebased on top of stack
574
- 7. Stack state is persisted for future `gssh stack sync`
575
-
576
- ---
577
-
578
- ## External Dependencies
579
-
580
- 1. **ai-flow** - AI abstraction library (OpenAI responses API compatible)
581
- 2. **TensorZero** - Multi-provider routing (optional)
582
-
583
- ---
584
-
585
- ## References
586
-
587
- - [Cloudflare Code Mode](https://blog.cloudflare.com/code-mode/) - Inspiration for sandbox approach
588
- - [Graphite](https://graphite.dev/) - Stacked PR workflow reference