gitspace 0.2.0-rc.20 → 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.
- package/package.json +11 -6
- package/.claude/settings.local.json +0 -10
- package/.gitspace/bundle.json +0 -50
- package/.gitspace/events.json +0 -11
- package/.gitspace/processes.json +0 -23
- package/.gitspace/scripts/select/01-status.sh +0 -39
- package/.gitspace/scripts/setup/01-install-deps.sh +0 -12
- package/.gitspace/scripts/setup/02-typecheck.sh +0 -16
- package/AGENTS.md +0 -469
- package/CLAUDE.md +0 -1
- package/bun.lock +0 -794
- package/docs/CONNECTION.md +0 -623
- package/docs/GATEWAY-WORKER.md +0 -319
- package/docs/GETTING-STARTED.md +0 -448
- package/docs/GITSPACE-PLATFORM.md +0 -1819
- package/docs/INFRASTRUCTURE.md +0 -1347
- package/docs/PROTOCOL.md +0 -619
- package/docs/QUICKSTART.md +0 -183
- package/docs/RELAY.md +0 -327
- package/docs/REMOTE-DESIGN.md +0 -554
- package/docs/ROADMAP.md +0 -564
- package/docs/SITE_DOCS_FIGMA_MAKE.md +0 -1176
- package/docs/STACK-DESIGN.md +0 -588
- package/docs/UNIFIED_ARCHITECTURE.md +0 -138
- package/experiments/pty-benchmark.ts +0 -148
- package/experiments/pty-latency.ts +0 -100
- package/experiments/router/client.ts +0 -199
- package/experiments/router/protocol.ts +0 -74
- package/experiments/router/router.ts +0 -217
- package/experiments/router/session.ts +0 -180
- package/experiments/router/test.ts +0 -133
- package/experiments/socket-bandwidth.ts +0 -77
- package/homebrew/gitspace.rb +0 -45
- package/landing-page/ATTRIBUTIONS.md +0 -3
- package/landing-page/README.md +0 -11
- package/landing-page/bun.lock +0 -801
- package/landing-page/guidelines/Guidelines.md +0 -61
- package/landing-page/index.html +0 -37
- package/landing-page/package.json +0 -90
- package/landing-page/postcss.config.mjs +0 -15
- package/landing-page/public/_redirects +0 -1
- package/landing-page/public/favicon.png +0 -0
- package/landing-page/src/app/App.tsx +0 -53
- package/landing-page/src/app/components/figma/ImageWithFallback.tsx +0 -27
- package/landing-page/src/app/components/ui/accordion.tsx +0 -66
- package/landing-page/src/app/components/ui/alert-dialog.tsx +0 -157
- package/landing-page/src/app/components/ui/alert.tsx +0 -66
- package/landing-page/src/app/components/ui/aspect-ratio.tsx +0 -11
- package/landing-page/src/app/components/ui/avatar.tsx +0 -53
- package/landing-page/src/app/components/ui/badge.tsx +0 -46
- package/landing-page/src/app/components/ui/breadcrumb.tsx +0 -109
- package/landing-page/src/app/components/ui/button.tsx +0 -57
- package/landing-page/src/app/components/ui/calendar.tsx +0 -75
- package/landing-page/src/app/components/ui/card.tsx +0 -92
- package/landing-page/src/app/components/ui/carousel.tsx +0 -241
- package/landing-page/src/app/components/ui/chart.tsx +0 -353
- package/landing-page/src/app/components/ui/checkbox.tsx +0 -32
- package/landing-page/src/app/components/ui/collapsible.tsx +0 -33
- package/landing-page/src/app/components/ui/command.tsx +0 -177
- package/landing-page/src/app/components/ui/context-menu.tsx +0 -252
- package/landing-page/src/app/components/ui/dialog.tsx +0 -135
- package/landing-page/src/app/components/ui/drawer.tsx +0 -132
- package/landing-page/src/app/components/ui/dropdown-menu.tsx +0 -257
- package/landing-page/src/app/components/ui/form.tsx +0 -168
- package/landing-page/src/app/components/ui/hover-card.tsx +0 -44
- package/landing-page/src/app/components/ui/input-otp.tsx +0 -77
- package/landing-page/src/app/components/ui/input.tsx +0 -21
- package/landing-page/src/app/components/ui/label.tsx +0 -24
- package/landing-page/src/app/components/ui/menubar.tsx +0 -276
- package/landing-page/src/app/components/ui/navigation-menu.tsx +0 -168
- package/landing-page/src/app/components/ui/pagination.tsx +0 -127
- package/landing-page/src/app/components/ui/popover.tsx +0 -48
- package/landing-page/src/app/components/ui/progress.tsx +0 -31
- package/landing-page/src/app/components/ui/radio-group.tsx +0 -45
- package/landing-page/src/app/components/ui/resizable.tsx +0 -56
- package/landing-page/src/app/components/ui/scroll-area.tsx +0 -58
- package/landing-page/src/app/components/ui/select.tsx +0 -189
- package/landing-page/src/app/components/ui/separator.tsx +0 -28
- package/landing-page/src/app/components/ui/sheet.tsx +0 -139
- package/landing-page/src/app/components/ui/sidebar.tsx +0 -726
- package/landing-page/src/app/components/ui/skeleton.tsx +0 -13
- package/landing-page/src/app/components/ui/slider.tsx +0 -63
- package/landing-page/src/app/components/ui/sonner.tsx +0 -25
- package/landing-page/src/app/components/ui/switch.tsx +0 -31
- package/landing-page/src/app/components/ui/table.tsx +0 -116
- package/landing-page/src/app/components/ui/tabs.tsx +0 -66
- package/landing-page/src/app/components/ui/textarea.tsx +0 -18
- package/landing-page/src/app/components/ui/toggle-group.tsx +0 -73
- package/landing-page/src/app/components/ui/toggle.tsx +0 -47
- package/landing-page/src/app/components/ui/tooltip.tsx +0 -61
- package/landing-page/src/app/components/ui/use-mobile.ts +0 -21
- package/landing-page/src/app/components/ui/utils.ts +0 -6
- package/landing-page/src/components/docs/DocsContent.tsx +0 -801
- package/landing-page/src/components/docs/DocsSidebar.tsx +0 -90
- package/landing-page/src/components/landing/CTA.tsx +0 -59
- package/landing-page/src/components/landing/Comparison.tsx +0 -84
- package/landing-page/src/components/landing/FaultyTerminal.tsx +0 -424
- package/landing-page/src/components/landing/Features.tsx +0 -201
- package/landing-page/src/components/landing/Hero.tsx +0 -142
- package/landing-page/src/components/landing/Pricing.tsx +0 -140
- package/landing-page/src/components/landing/Roadmap.tsx +0 -86
- package/landing-page/src/components/landing/Security.tsx +0 -81
- package/landing-page/src/components/landing/TerminalWindow.tsx +0 -27
- package/landing-page/src/components/landing/UseCases.tsx +0 -55
- package/landing-page/src/components/landing/Workflow.tsx +0 -101
- package/landing-page/src/components/layout/DashboardNavbar.tsx +0 -37
- package/landing-page/src/components/layout/Footer.tsx +0 -55
- package/landing-page/src/components/layout/LandingNavbar.tsx +0 -82
- package/landing-page/src/components/ui/badge.tsx +0 -39
- package/landing-page/src/components/ui/breadcrumb.tsx +0 -115
- package/landing-page/src/components/ui/button.tsx +0 -57
- package/landing-page/src/components/ui/card.tsx +0 -79
- package/landing-page/src/components/ui/mock-terminal.tsx +0 -68
- package/landing-page/src/components/ui/separator.tsx +0 -28
- package/landing-page/src/lib/utils.ts +0 -6
- package/landing-page/src/main.tsx +0 -10
- package/landing-page/src/pages/Dashboard.tsx +0 -133
- package/landing-page/src/pages/DocsPage.tsx +0 -79
- package/landing-page/src/pages/LandingPage.tsx +0 -31
- package/landing-page/src/pages/TerminalView.tsx +0 -106
- package/landing-page/src/styles/fonts.css +0 -0
- package/landing-page/src/styles/index.css +0 -3
- package/landing-page/src/styles/tailwind.css +0 -4
- package/landing-page/src/styles/theme.css +0 -181
- package/landing-page/vite.config.ts +0 -19
- package/scripts/GHOSTTY_TAB_BUG.md +0 -106
- package/scripts/build.ts +0 -298
- package/scripts/migrate-secrets.ts +0 -77
- package/scripts/release.ts +0 -140
- package/scripts/sample-events.ts +0 -263
- package/scripts/test-tabs-minimal.ts +0 -68
- package/scripts/test-tabs-workaround.ts +0 -95
- package/scripts/test-tabs.ts +0 -171
- package/src/__tests__/test-utils.ts +0 -298
- package/src/app/input/__tests__/sessionCommands.test.ts +0 -40
- package/src/app/input/sessionCommands.ts +0 -94
- package/src/app/session/__tests__/useAttachController.test.ts +0 -229
- package/src/app/session/createSessionBackend.bun.ts +0 -76
- package/src/app/session/createSessionBackend.web.ts +0 -104
- package/src/app/session/types.ts +0 -16
- package/src/app/session/useAttachController.ts +0 -220
- package/src/app/session/useProcessActions.ts +0 -201
- package/src/app/session/useSessionClient.ts +0 -35
- package/src/app/session/useWorkspaceDeleteFlow.ts +0 -170
- package/src/app.tui.tsx +0 -2929
- package/src/app.web.tsx +0 -1454
- package/src/commands/__tests__/connect-key.test.ts +0 -10
- package/src/commands/__tests__/events.test.ts +0 -201
- package/src/commands/__tests__/notifications.test.ts +0 -349
- package/src/commands/__tests__/process.test.ts +0 -251
- package/src/commands/__tests__/serve-messages.test.ts +0 -190
- package/src/commands/__tests__/serve-process-hosting.test.ts +0 -63
- package/src/commands/access.ts +0 -298
- package/src/commands/add.ts +0 -455
- package/src/commands/auth.ts +0 -369
- package/src/commands/bundle.ts +0 -232
- package/src/commands/config.ts +0 -242
- package/src/commands/connect-key.ts +0 -1
- package/src/commands/connect.ts +0 -576
- package/src/commands/directory.ts +0 -16
- package/src/commands/events.ts +0 -157
- package/src/commands/host.ts +0 -566
- package/src/commands/identity.ts +0 -184
- package/src/commands/linear.ts +0 -717
- package/src/commands/list.ts +0 -181
- package/src/commands/migrate.ts +0 -52
- package/src/commands/notifications.ts +0 -351
- package/src/commands/process.ts +0 -104
- package/src/commands/relay.ts +0 -315
- package/src/commands/remove.ts +0 -279
- package/src/commands/review.ts +0 -787
- package/src/commands/serve.ts +0 -1946
- package/src/commands/share.ts +0 -451
- package/src/commands/status.ts +0 -125
- package/src/commands/switch.ts +0 -361
- package/src/commands/tmux.ts +0 -317
- package/src/components/DPad.web.tsx +0 -343
- package/src/components/DiffViewer.web.tsx +0 -1192
- package/src/components/Events.tsx +0 -137
- package/src/components/Events.tui.tsx +0 -129
- package/src/components/Events.web.tsx +0 -386
- package/src/components/FloatingControls.web.tsx +0 -112
- package/src/components/FloatingJogWheel.web.tsx +0 -240
- package/src/components/Flow.tsx +0 -458
- package/src/components/Flow.tui.tsx +0 -343
- package/src/components/Flow.web.tsx +0 -442
- package/src/components/Inbox.tsx +0 -448
- package/src/components/Inbox.tui.tsx +0 -262
- package/src/components/Inbox.web.tsx +0 -329
- package/src/components/MachineList.tsx +0 -187
- package/src/components/MachineList.tui.tsx +0 -161
- package/src/components/MachineList.web.tsx +0 -210
- package/src/components/NumPad.web.tsx +0 -270
- package/src/components/ProjectList.tsx +0 -175
- package/src/components/ProjectList.tui.tsx +0 -109
- package/src/components/ProjectList.web.tsx +0 -143
- package/src/components/ProjectOnboardingStep.ts +0 -23
- package/src/components/ProjectOnboardingStep.tui.tsx +0 -88
- package/src/components/ProjectOnboardingStep.web.tsx +0 -59
- package/src/components/RemoteMachineScreen.tui.tsx +0 -690
- package/src/components/ScriptTerminal.tui.tsx +0 -160
- package/src/components/ScriptTerminal.web.tsx +0 -89
- package/src/components/SessionTerminal.tui.tsx +0 -406
- package/src/components/SessionTerminal.web.tsx +0 -467
- package/src/components/SpacesBrowser.tsx +0 -540
- package/src/components/SpacesBrowser.tui.tsx +0 -258
- package/src/components/SpacesBrowser.web.tsx +0 -332
- package/src/components/TerminalControls.web.tsx +0 -464
- package/src/components/ThreadPanel.web.tsx +0 -798
- package/src/components/__tests__/SpacesBrowser.test.ts +0 -541
- package/src/components/__tests__/SpacesBrowser.tui.test.tsx +0 -249
- package/src/components/__tests__/script-terminal-buffer.tui.test.ts +0 -72
- package/src/components/index.ts +0 -105
- package/src/components/review-decision-colors.ts +0 -11
- package/src/components/script-terminal-buffer.tui.ts +0 -37
- package/src/components/session-terminal-page-navigation.ts +0 -48
- package/src/components/terminal-bracketed-paste.tui.test.ts +0 -43
- package/src/components/terminal-bracketed-paste.tui.ts +0 -46
- package/src/core/__tests__/access.test.ts +0 -240
- package/src/core/__tests__/bundle-refresh.test.ts +0 -567
- package/src/core/__tests__/bundle.test.ts +0 -209
- package/src/core/__tests__/github-review.test.ts +0 -781
- package/src/core/__tests__/project-lifecycle.test.ts +0 -137
- package/src/core/__tests__/workspace-lifecycle.test.ts +0 -159
- package/src/core/__tests__/workspace.test.ts +0 -149
- package/src/core/access.ts +0 -277
- package/src/core/bundle-refresh.ts +0 -1064
- package/src/core/bundle.ts +0 -326
- package/src/core/config.ts +0 -405
- package/src/core/git.ts +0 -768
- package/src/core/github-review.ts +0 -761
- package/src/core/github.ts +0 -151
- package/src/core/identity.ts +0 -631
- package/src/core/linear.ts +0 -403
- package/src/core/preferences-service.ts +0 -17
- package/src/core/project-catalog.ts +0 -52
- package/src/core/project-lifecycle.ts +0 -163
- package/src/core/review-executor.ts +0 -316
- package/src/core/review.ts +0 -407
- package/src/core/secret-runtime.ts +0 -167
- package/src/core/shell.ts +0 -117
- package/src/core/trusted-relays.ts +0 -315
- package/src/core/workspace-lifecycle.ts +0 -216
- package/src/core/workspace.ts +0 -363
- package/src/hooks/__tests__/useLocalSession.tui.test.ts +0 -557
- package/src/hooks/index.ts +0 -8
- package/src/hooks/index.tui.ts +0 -32
- package/src/hooks/useDaemonStatus.tui.ts +0 -174
- package/src/hooks/useLocalSession.tui.ts +0 -395
- package/src/hooks/useRelayConnection.web.ts +0 -54
- package/src/hooks/useRemoteMachines.tui.ts +0 -166
- package/src/hooks/useRemoteTerminal.tui.ts +0 -22
- package/src/hooks/useReview.web.ts +0 -248
- package/src/hooks/useTerminal.web.ts +0 -36
- package/src/hooks/useUserActivity.ts +0 -61
- package/src/hooks/useVisualViewport.web.ts +0 -104
- package/src/index.ts +0 -1376
- package/src/lib/events/__tests__/collector-filter.test.ts +0 -105
- package/src/lib/events/__tests__/store-query.test.ts +0 -103
- package/src/lib/events/collector.ts +0 -494
- package/src/lib/events/filters.ts +0 -26
- package/src/lib/events/index.ts +0 -11
- package/src/lib/events/indexer.ts +0 -14
- package/src/lib/events/paths.ts +0 -69
- package/src/lib/events/reader.ts +0 -212
- package/src/lib/events/store.ts +0 -141
- package/src/lib/invite.web.ts +0 -58
- package/src/lib/preferences-service.web.ts +0 -41
- package/src/lib/processes/__tests__/config.test.ts +0 -83
- package/src/lib/processes/__tests__/names.test.ts +0 -125
- package/src/lib/processes/__tests__/schema.test.ts +0 -208
- package/src/lib/processes/__tests__/watchdog.test.ts +0 -210
- package/src/lib/processes/autostart.ts +0 -16
- package/src/lib/processes/config.ts +0 -187
- package/src/lib/processes/control.ts +0 -53
- package/src/lib/processes/editor.ts +0 -32
- package/src/lib/processes/events-config.ts +0 -37
- package/src/lib/processes/index.ts +0 -14
- package/src/lib/processes/instances.ts +0 -20
- package/src/lib/processes/manager.ts +0 -131
- package/src/lib/processes/names.ts +0 -71
- package/src/lib/processes/registry.ts +0 -26
- package/src/lib/processes/runner.ts +0 -211
- package/src/lib/processes/scheduler.ts +0 -17
- package/src/lib/processes/schema.ts +0 -74
- package/src/lib/processes/session-list.ts +0 -15
- package/src/lib/processes/state.ts +0 -82
- package/src/lib/processes/watchdog.test.ts +0 -79
- package/src/lib/processes/watchdog.ts +0 -106
- package/src/lib/remote-session/__tests__/protocol.test.ts +0 -291
- package/src/lib/remote-session/index.ts +0 -7
- package/src/lib/remote-session/protocol.ts +0 -443
- package/src/lib/remote-session/session-handler.ts +0 -1298
- package/src/lib/remote-session/workspace-scanner.ts +0 -161
- package/src/lib/sonner.web.ts +0 -1
- package/src/lib/storage/identity-store.web.ts +0 -94
- package/src/lib/tmux-lite/README.md +0 -81
- package/src/lib/tmux-lite/cli.ts +0 -855
- package/src/lib/tmux-lite/crypto/__tests__/helpers/handshake-runner.ts +0 -349
- package/src/lib/tmux-lite/crypto/__tests__/helpers/mock-relay.ts +0 -291
- package/src/lib/tmux-lite/crypto/__tests__/helpers/test-identities.ts +0 -142
- package/src/lib/tmux-lite/crypto/__tests__/integration/authorization.integration.test.ts +0 -339
- package/src/lib/tmux-lite/crypto/__tests__/integration/e2e-communication.integration.test.ts +0 -477
- package/src/lib/tmux-lite/crypto/__tests__/integration/error-handling.integration.test.ts +0 -499
- package/src/lib/tmux-lite/crypto/__tests__/integration/handshake.integration.test.ts +0 -371
- package/src/lib/tmux-lite/crypto/__tests__/integration/security.integration.test.ts +0 -573
- package/src/lib/tmux-lite/crypto/access-control.test.ts +0 -512
- package/src/lib/tmux-lite/crypto/access-control.ts +0 -320
- package/src/lib/tmux-lite/crypto/frames.test.ts +0 -262
- package/src/lib/tmux-lite/crypto/frames.ts +0 -141
- package/src/lib/tmux-lite/crypto/handshake.ts +0 -894
- package/src/lib/tmux-lite/crypto/identity.test.ts +0 -220
- package/src/lib/tmux-lite/crypto/identity.ts +0 -286
- package/src/lib/tmux-lite/crypto/index.ts +0 -51
- package/src/lib/tmux-lite/crypto/invites.test.ts +0 -381
- package/src/lib/tmux-lite/crypto/invites.ts +0 -215
- package/src/lib/tmux-lite/crypto/keyexchange.ts +0 -435
- package/src/lib/tmux-lite/crypto/keys.test.ts +0 -58
- package/src/lib/tmux-lite/crypto/keys.ts +0 -47
- package/src/lib/tmux-lite/crypto/secretbox.test.ts +0 -169
- package/src/lib/tmux-lite/crypto/secretbox.ts +0 -124
- package/src/lib/tmux-lite/handshake-handler.ts +0 -451
- package/src/lib/tmux-lite/process-run.integration.test.ts +0 -266
- package/src/lib/tmux-lite/protocol.test.ts +0 -307
- package/src/lib/tmux-lite/protocol.ts +0 -291
- package/src/lib/tmux-lite/relay-client.ts +0 -506
- package/src/lib/tmux-lite/server-lifecycle.test.ts +0 -212
- package/src/lib/tmux-lite/server.ts +0 -1412
- package/src/lib/tmux-lite/shell-integration.sh +0 -37
- package/src/lib/tmux-lite/terminal-queries.test.ts +0 -54
- package/src/lib/tmux-lite/terminal-queries.ts +0 -49
- package/src/notifications/__tests__/useNotifications.test.ts +0 -739
- package/src/notifications/index.ts +0 -32
- package/src/notifications/policy.test.ts +0 -424
- package/src/notifications/policy.ts +0 -139
- package/src/notifications/types.ts +0 -82
- package/src/notifications/useNotifications.ts +0 -350
- package/src/pages/ReviewPage.web.tsx +0 -511
- package/src/preferences/index.ts +0 -1
- package/src/preferences/types.ts +0 -9
- package/src/relay/__tests__/e2e-flow.test.ts +0 -1284
- package/src/relay/__tests__/helpers/auth.ts +0 -354
- package/src/relay/__tests__/helpers/ports.ts +0 -51
- package/src/relay/__tests__/protocol-validation.test.ts +0 -265
- package/src/relay/authorization.ts +0 -303
- package/src/relay/embedded-assets.generated.d.ts +0 -15
- package/src/relay/identity.ts +0 -352
- package/src/relay/index.ts +0 -57
- package/src/relay/pipes.test.ts +0 -427
- package/src/relay/pipes.ts +0 -195
- package/src/relay/protocol.ts +0 -804
- package/src/relay/registries.test.ts +0 -437
- package/src/relay/registries.ts +0 -593
- package/src/relay/server.test.ts +0 -1323
- package/src/relay/server.ts +0 -1128
- package/src/relay/signing.ts +0 -238
- package/src/relay/types.ts +0 -69
- package/src/relay-client/__tests__/machine-directory-client.test.ts +0 -152
- package/src/relay-client/__tests__/useMachineDirectory.test.ts +0 -172
- package/src/relay-client/adapters/browser.ts +0 -27
- package/src/relay-client/adapters/node.ts +0 -29
- package/src/relay-client/index.ts +0 -33
- package/src/relay-client/machine-directory-client.ts +0 -244
- package/src/relay-client/useMachineDirectory.ts +0 -175
- package/src/serve/client-session-manager.ts +0 -635
- package/src/serve/daemon.ts +0 -497
- package/src/serve/pty-session.ts +0 -236
- package/src/serve/types.ts +0 -174
- package/src/session/__tests__/backend-manager.test.ts +0 -101
- package/src/session/__tests__/local-session-backend.test.ts +0 -1129
- package/src/session/__tests__/reducer.test.ts +0 -80
- package/src/session/__tests__/remote-session-backend.test.ts +0 -995
- package/src/session/__tests__/session-name.test.ts +0 -35
- package/src/session/__tests__/useBundleRefreshAttachFlow.test.ts +0 -431
- package/src/session/__tests__/useRemoteSessionClient.test.ts +0 -424
- package/src/session/__tests__/workspace-shell-hooks.integration.test.ts +0 -268
- package/src/session/__tests__/workspace-shell-hooks.test.ts +0 -24
- package/src/session/adapters/browser-remote.ts +0 -101
- package/src/session/adapters/node-remote.ts +0 -135
- package/src/session/backend-key.ts +0 -5
- package/src/session/backend-manager.ts +0 -80
- package/src/session/backend.ts +0 -93
- package/src/session/backends/local-session-backend.ts +0 -1119
- package/src/session/backends/remote-session-backend.ts +0 -1378
- package/src/session/crypto/__tests__/web-terminal.test.ts +0 -1158
- package/src/session/crypto/frames.web.ts +0 -205
- package/src/session/crypto/handshake.web.ts +0 -396
- package/src/session/crypto/identity.web.ts +0 -133
- package/src/session/crypto/keyexchange.web.ts +0 -246
- package/src/session/crypto/relay-signing.web.ts +0 -53
- package/src/session/events.ts +0 -38
- package/src/session/index.ts +0 -116
- package/src/session/reducer.ts +0 -274
- package/src/session/selectors.ts +0 -28
- package/src/session/session-name.ts +0 -50
- package/src/session/types.ts +0 -101
- package/src/session/useBundleRefreshAttachFlow.ts +0 -608
- package/src/session/useRemoteSessionClient.ts +0 -424
- package/src/session/useSessionEngine.ts +0 -432
- package/src/session/workspace-shell-hooks.ts +0 -35
- package/src/tui/__tests__/input-text.test.ts +0 -24
- package/src/tui/__tests__/local-terminal-sync.test.ts +0 -82
- package/src/tui/__tests__/session-terminal-page-navigation.test.ts +0 -94
- package/src/tui/app.tsx +0 -2
- package/src/tui/index.ts +0 -18
- package/src/tui/input-text.ts +0 -38
- package/src/tui/local-terminal-sync.ts +0 -41
- package/src/types/bundle-refresh.ts +0 -42
- package/src/types/bundle.ts +0 -130
- package/src/types/config.ts +0 -287
- package/src/types/errors.ts +0 -292
- package/src/types/events.ts +0 -91
- package/src/types/identity.ts +0 -284
- package/src/types/processes.ts +0 -45
- package/src/types/review.ts +0 -349
- package/src/types/script-phase.ts +0 -3
- package/src/types/workspace-fuzzy.ts +0 -49
- package/src/types/workspace.ts +0 -151
- package/src/utils/__tests__/onboarding.test.ts +0 -358
- package/src/utils/__tests__/run-scripts.test.ts +0 -535
- package/src/utils/__tests__/run-workspace-scripts.test.ts +0 -406
- package/src/utils/__tests__/workspace-setup.integration.test.ts +0 -633
- package/src/utils/__tests__/workspace-state.test.ts +0 -78
- package/src/utils/bun-socket-writer.ts +0 -80
- package/src/utils/clipboard.ts +0 -53
- package/src/utils/deps.test.ts +0 -31
- package/src/utils/deps.ts +0 -145
- package/src/utils/device.web.ts +0 -163
- package/src/utils/fuzzy-match.ts +0 -125
- package/src/utils/hostnames.ts +0 -43
- package/src/utils/hunk-header.ts +0 -17
- package/src/utils/id.ts +0 -9
- package/src/utils/logger.ts +0 -127
- package/src/utils/markdown.ts +0 -254
- package/src/utils/normalize-env-key.ts +0 -13
- package/src/utils/onboarding.ts +0 -279
- package/src/utils/prompts.ts +0 -176
- package/src/utils/run-commands.ts +0 -112
- package/src/utils/run-scripts.ts +0 -337
- package/src/utils/run-workspace-scripts.ts +0 -355
- package/src/utils/sanitize.test.ts +0 -149
- package/src/utils/sanitize.ts +0 -162
- package/src/utils/secrets.ts +0 -836
- package/src/utils/shell-escape.ts +0 -40
- package/src/utils/utf8.ts +0 -79
- package/src/utils/workspace-id.ts +0 -55
- package/src/utils/workspace-state.ts +0 -427
- package/src/version.generated.d.ts +0 -2
- package/todo-security.md +0 -92
- package/tsconfig.json +0 -29
- package/web/README.md +0 -73
- package/web/bun.lock +0 -675
- package/web/eslint.config.js +0 -23
- package/web/index.css +0 -249
- package/web/index.html +0 -16
- package/web/main.tsx +0 -10
- package/web/package.json +0 -39
- package/web/public/vite.svg +0 -1
- package/web/tsconfig.app.json +0 -35
- package/web/tsconfig.json +0 -7
- package/web/tsconfig.node.json +0 -26
- package/web/vite.config.ts +0 -39
- package/worker/bun.lock +0 -237
- package/worker/package.json +0 -22
- package/worker/schema.sql +0 -96
- package/worker/src/handlers/auth.ts +0 -451
- package/worker/src/handlers/subdomains.ts +0 -376
- package/worker/src/handlers/user.ts +0 -98
- package/worker/src/index.ts +0 -70
- package/worker/src/middleware/auth.ts +0 -152
- package/worker/src/services/cloudflare.ts +0 -609
- package/worker/src/types.ts +0 -96
- package/worker/tsconfig.json +0 -15
- package/worker/wrangler.toml +0 -26
package/src/commands/auth.ts
DELETED
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authentication commands for gitspace.sh
|
|
3
|
-
*
|
|
4
|
-
* Handles 'gssh auth login', 'gssh auth logout', 'gssh auth status'
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import open from 'open';
|
|
8
|
-
import os from 'os';
|
|
9
|
-
import { getSecret, setSecret, deleteSecret } from '../utils/secrets.js';
|
|
10
|
-
import { loadKeypair, keypairExists, getPublicKeyWithoutPassword } from '../core/identity.js';
|
|
11
|
-
import { sign, serializeIdentity } from '../lib/tmux-lite/crypto/identity.js';
|
|
12
|
-
import { promptPassword } from '../utils/prompts.js';
|
|
13
|
-
import { logger } from '../utils/logger.js';
|
|
14
|
-
import { NoIdentityError, SpacesError } from '../types/errors.js';
|
|
15
|
-
import { syncHostConfig } from './host.js';
|
|
16
|
-
|
|
17
|
-
// API Configuration
|
|
18
|
-
const API_BASE = process.env.GITSPACE_API_URL || 'https://api.gitspace.sh';
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Fetch GitHub Client ID from the API
|
|
22
|
-
*/
|
|
23
|
-
async function getGitHubClientId(): Promise<string> {
|
|
24
|
-
const res = await fetch(`${API_BASE}/config`);
|
|
25
|
-
if (!res.ok) {
|
|
26
|
-
throw new SpacesError('Failed to fetch config from API', 'SYSTEM_ERROR');
|
|
27
|
-
}
|
|
28
|
-
const config = await res.json() as { github_client_id: string };
|
|
29
|
-
if (!config.github_client_id) {
|
|
30
|
-
throw new SpacesError('GitHub Client ID not configured on server', 'SYSTEM_ERROR');
|
|
31
|
-
}
|
|
32
|
-
return config.github_client_id;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// ============================================================================
|
|
36
|
-
// Types
|
|
37
|
-
// ============================================================================
|
|
38
|
-
|
|
39
|
-
interface DeviceCodeResponse {
|
|
40
|
-
device_code: string;
|
|
41
|
-
user_code: string;
|
|
42
|
-
verification_uri: string;
|
|
43
|
-
expires_in: number;
|
|
44
|
-
interval: number;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
interface GitHubTokenResponse {
|
|
48
|
-
access_token?: string;
|
|
49
|
-
token_type?: string;
|
|
50
|
-
scope?: string;
|
|
51
|
-
error?: string;
|
|
52
|
-
error_description?: string;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
interface GitspaceAuthResponse {
|
|
56
|
-
token: string;
|
|
57
|
-
user: {
|
|
58
|
-
id: string;
|
|
59
|
-
github_username: string;
|
|
60
|
-
email: string | null;
|
|
61
|
-
name: string | null;
|
|
62
|
-
avatar_url: string | null;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ============================================================================
|
|
67
|
-
// Login Command
|
|
68
|
-
// ============================================================================
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Login to gitspace.sh using GitHub Device Flow
|
|
72
|
-
*/
|
|
73
|
-
export async function authLogin(): Promise<void> {
|
|
74
|
-
// Check if identity exists
|
|
75
|
-
if (!keypairExists()) {
|
|
76
|
-
throw new NoIdentityError();
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Load identity (requires password for signing)
|
|
80
|
-
logger.info('Loading identity...');
|
|
81
|
-
const password = await promptPassword('Enter identity password:');
|
|
82
|
-
if (!password) {
|
|
83
|
-
logger.info('Cancelled');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
let identity;
|
|
88
|
-
try {
|
|
89
|
-
identity = await loadKeypair(password);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error instanceof SpacesError) {
|
|
92
|
-
throw error;
|
|
93
|
-
}
|
|
94
|
-
throw new SpacesError('Failed to load identity', 'USER_ERROR');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Step 1: Get GitHub Client ID from API
|
|
98
|
-
logger.info('Starting GitHub authentication...');
|
|
99
|
-
const githubClientId = await getGitHubClientId();
|
|
100
|
-
|
|
101
|
-
// Step 2: Request device code from GitHub
|
|
102
|
-
const deviceRes = await fetch('https://github.com/login/device/code', {
|
|
103
|
-
method: 'POST',
|
|
104
|
-
headers: {
|
|
105
|
-
Accept: 'application/json',
|
|
106
|
-
'Content-Type': 'application/json',
|
|
107
|
-
},
|
|
108
|
-
body: JSON.stringify({
|
|
109
|
-
client_id: githubClientId,
|
|
110
|
-
scope: 'read:user user:email',
|
|
111
|
-
}),
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
if (!deviceRes.ok) {
|
|
115
|
-
throw new SpacesError(
|
|
116
|
-
`GitHub device flow failed: ${await deviceRes.text()}`,
|
|
117
|
-
'SYSTEM_ERROR'
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const deviceData: DeviceCodeResponse = await deviceRes.json();
|
|
122
|
-
const { device_code, user_code, verification_uri, interval } = deviceData;
|
|
123
|
-
|
|
124
|
-
// Step 2: Display code and open browser
|
|
125
|
-
logger.log('');
|
|
126
|
-
logger.bold(`! First, copy your one-time code: ${user_code}`);
|
|
127
|
-
logger.log('');
|
|
128
|
-
|
|
129
|
-
// Try to open browser, with fallback for headless/SSH environments
|
|
130
|
-
const canOpenBrowser = process.stdout.isTTY && !process.env.SSH_CLIENT;
|
|
131
|
-
|
|
132
|
-
if (canOpenBrowser) {
|
|
133
|
-
logger.log(`Press Enter to open ${verification_uri} in your browser...`);
|
|
134
|
-
await waitForEnter();
|
|
135
|
-
|
|
136
|
-
try {
|
|
137
|
-
await open(verification_uri);
|
|
138
|
-
logger.info('Browser opened. Waiting for authorization...');
|
|
139
|
-
} catch {
|
|
140
|
-
// Browser open failed (WSL, headless, etc.)
|
|
141
|
-
logger.log('');
|
|
142
|
-
logger.log(`Could not open browser automatically.`);
|
|
143
|
-
logger.log(`Please open this URL manually: ${verification_uri}`);
|
|
144
|
-
logger.log('');
|
|
145
|
-
logger.info('Waiting for authorization...');
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
// Headless environment (SSH, CI, etc.)
|
|
149
|
-
logger.log(`Open this URL in your browser: ${verification_uri}`);
|
|
150
|
-
logger.log(`Enter the code: ${user_code}`);
|
|
151
|
-
logger.log('');
|
|
152
|
-
logger.info('Waiting for authorization...');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Step 3: Poll GitHub for access token
|
|
156
|
-
const githubToken = await pollForGitHubToken(device_code, interval, githubClientId);
|
|
157
|
-
|
|
158
|
-
// Step 4: Exchange GitHub token for gitspace.sh token with signature
|
|
159
|
-
logger.info('Completing authentication...');
|
|
160
|
-
|
|
161
|
-
const authTimestamp = Date.now();
|
|
162
|
-
const authMessage = `gitspace-device-auth:${authTimestamp}`;
|
|
163
|
-
const messageBytes = new TextEncoder().encode(authMessage);
|
|
164
|
-
const signatureBytes = sign(messageBytes, identity.signing.secretKey);
|
|
165
|
-
const authSignature = Buffer.from(signatureBytes).toString('base64');
|
|
166
|
-
|
|
167
|
-
const serialized = serializeIdentity(identity);
|
|
168
|
-
|
|
169
|
-
const response = await fetch(`${API_BASE}/auth/github/device`, {
|
|
170
|
-
method: 'POST',
|
|
171
|
-
headers: { 'Content-Type': 'application/json' },
|
|
172
|
-
body: JSON.stringify({
|
|
173
|
-
github_token: githubToken,
|
|
174
|
-
machine_pubkey: serialized.signingPublicKey,
|
|
175
|
-
device_name: os.hostname(),
|
|
176
|
-
auth_timestamp: authTimestamp,
|
|
177
|
-
auth_signature: authSignature,
|
|
178
|
-
}),
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
if (!response.ok) {
|
|
182
|
-
const error = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
183
|
-
throw new SpacesError(
|
|
184
|
-
`Authentication failed: ${error.error || response.statusText}`,
|
|
185
|
-
'USER_ERROR'
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const { token, user }: GitspaceAuthResponse = await response.json();
|
|
190
|
-
|
|
191
|
-
// Step 5: Save token to keychain
|
|
192
|
-
await setSecret('GITSPACE_TOKEN', token);
|
|
193
|
-
|
|
194
|
-
logger.log('');
|
|
195
|
-
logger.success('Authentication complete');
|
|
196
|
-
logger.success(`Logged in as ${user.github_username}`);
|
|
197
|
-
logger.success('Token saved to keychain');
|
|
198
|
-
|
|
199
|
-
// Step 6: Sync host config (fetches existing subdomains from API)
|
|
200
|
-
// Interactive mode will prompt user to select primary or reserve a subdomain
|
|
201
|
-
await syncHostConfig(true);
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// ============================================================================
|
|
205
|
-
// Logout Command
|
|
206
|
-
// ============================================================================
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* Logout from gitspace.sh (clear local credentials)
|
|
210
|
-
*/
|
|
211
|
-
export async function authLogout(): Promise<void> {
|
|
212
|
-
const token = await getSecret('GITSPACE_TOKEN');
|
|
213
|
-
|
|
214
|
-
if (!token) {
|
|
215
|
-
logger.log('Not logged in');
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
await deleteSecret('GITSPACE_TOKEN');
|
|
220
|
-
logger.success('Logged out');
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
// ============================================================================
|
|
224
|
-
// Status Command
|
|
225
|
-
// ============================================================================
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Show current authentication status
|
|
229
|
-
*/
|
|
230
|
-
export async function authStatus(): Promise<void> {
|
|
231
|
-
const token = await getSecret('GITSPACE_TOKEN');
|
|
232
|
-
|
|
233
|
-
if (!token) {
|
|
234
|
-
logger.log('Not logged in');
|
|
235
|
-
logger.dim('Run: gssh auth login');
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Verify token with API
|
|
240
|
-
try {
|
|
241
|
-
const deviceFingerprint = getDeviceFingerprint();
|
|
242
|
-
if (!deviceFingerprint) {
|
|
243
|
-
logger.log('Identity not found. Run: gssh identity init');
|
|
244
|
-
return;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
const res = await fetch(`${API_BASE}/me`, {
|
|
248
|
-
headers: {
|
|
249
|
-
Authorization: `Bearer ${token}`,
|
|
250
|
-
'X-Device-Fingerprint': deviceFingerprint,
|
|
251
|
-
},
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
if (!res.ok) {
|
|
255
|
-
logger.log('Session expired or invalid');
|
|
256
|
-
logger.dim('Run: gssh auth login');
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const user = await res.json();
|
|
261
|
-
logger.log(`Logged in as: ${user.github_username}`);
|
|
262
|
-
logger.log(`Email: ${user.email || '(not set)'}`);
|
|
263
|
-
if (user.name) {
|
|
264
|
-
logger.log(`Name: ${user.name}`);
|
|
265
|
-
}
|
|
266
|
-
} catch {
|
|
267
|
-
logger.log('Could not verify session (API unreachable)');
|
|
268
|
-
logger.dim('Token is saved locally');
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// ============================================================================
|
|
273
|
-
// Helper Functions
|
|
274
|
-
// ============================================================================
|
|
275
|
-
|
|
276
|
-
function getDeviceFingerprint(): string | null {
|
|
277
|
-
try {
|
|
278
|
-
const identity = getPublicKeyWithoutPassword();
|
|
279
|
-
return identity?.signingPublicKey ?? null;
|
|
280
|
-
} catch {
|
|
281
|
-
return null;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Wait for Enter key press
|
|
287
|
-
*/
|
|
288
|
-
function waitForEnter(): Promise<void> {
|
|
289
|
-
return new Promise((resolve) => {
|
|
290
|
-
if (process.stdin.isTTY) {
|
|
291
|
-
process.stdin.setRawMode(true);
|
|
292
|
-
process.stdin.resume();
|
|
293
|
-
process.stdin.once('data', () => {
|
|
294
|
-
process.stdin.setRawMode(false);
|
|
295
|
-
process.stdin.pause(); // Release the event loop
|
|
296
|
-
resolve();
|
|
297
|
-
});
|
|
298
|
-
} else {
|
|
299
|
-
resolve();
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Poll GitHub for access token (Device Flow)
|
|
306
|
-
*/
|
|
307
|
-
async function pollForGitHubToken(
|
|
308
|
-
deviceCode: string,
|
|
309
|
-
interval: number,
|
|
310
|
-
clientId: string
|
|
311
|
-
): Promise<string> {
|
|
312
|
-
const maxAttempts = 60; // ~5 minutes with default 5s interval
|
|
313
|
-
let currentInterval = interval;
|
|
314
|
-
|
|
315
|
-
for (let i = 0; i < maxAttempts; i++) {
|
|
316
|
-
await Bun.sleep(currentInterval * 1000);
|
|
317
|
-
|
|
318
|
-
// Show polling indicator
|
|
319
|
-
process.stdout.write('.');
|
|
320
|
-
|
|
321
|
-
const res = await fetch('https://github.com/login/oauth/access_token', {
|
|
322
|
-
method: 'POST',
|
|
323
|
-
headers: {
|
|
324
|
-
Accept: 'application/json',
|
|
325
|
-
'Content-Type': 'application/json',
|
|
326
|
-
},
|
|
327
|
-
body: JSON.stringify({
|
|
328
|
-
client_id: clientId,
|
|
329
|
-
device_code: deviceCode,
|
|
330
|
-
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
331
|
-
}),
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const data: GitHubTokenResponse = await res.json();
|
|
335
|
-
|
|
336
|
-
if (data.access_token) {
|
|
337
|
-
return data.access_token;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
if (data.error === 'authorization_pending') {
|
|
341
|
-
// User hasn't authorized yet, keep polling
|
|
342
|
-
continue;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
if (data.error === 'slow_down') {
|
|
346
|
-
// Rate limited, increase interval
|
|
347
|
-
currentInterval += 5;
|
|
348
|
-
continue;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
if (data.error === 'expired_token') {
|
|
352
|
-
throw new SpacesError(
|
|
353
|
-
'Authorization expired. Please try again.',
|
|
354
|
-
'USER_ERROR'
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
if (data.error === 'access_denied') {
|
|
359
|
-
throw new SpacesError('Authorization denied by user.', 'USER_ERROR');
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
throw new SpacesError(
|
|
363
|
-
`GitHub auth error: ${data.error_description || data.error}`,
|
|
364
|
-
'SYSTEM_ERROR'
|
|
365
|
-
);
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
throw new SpacesError('Authorization timeout. Please try again.', 'USER_ERROR');
|
|
369
|
-
}
|
package/src/commands/bundle.ts
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bundle CLI commands
|
|
3
|
-
*
|
|
4
|
-
* Commands for managing bundle configuration and refresh.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { exec } from 'child_process';
|
|
8
|
-
import { promisify } from 'util';
|
|
9
|
-
import { logger } from '../utils/logger.js';
|
|
10
|
-
import { SpacesError } from '../types/errors.js';
|
|
11
|
-
import { getCurrentProject, getGitspaceDir, getProjectBaseDir, getProjectWorkspacesDir } from '../core/config.js';
|
|
12
|
-
import {
|
|
13
|
-
detectBundleChanges,
|
|
14
|
-
formatBundleChangeDetails,
|
|
15
|
-
refreshBundle,
|
|
16
|
-
type BundleRefreshOptions,
|
|
17
|
-
} from '../core/bundle-refresh.js';
|
|
18
|
-
import { join } from 'path';
|
|
19
|
-
import { existsSync } from 'fs';
|
|
20
|
-
import { detectWorkspaceContextFromCwd } from '../utils/workspace-id.js';
|
|
21
|
-
|
|
22
|
-
const execAsync = promisify(exec);
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Options for bundle refresh command
|
|
26
|
-
*/
|
|
27
|
-
export interface BundleRefreshCommandOptions {
|
|
28
|
-
/** Force refresh even if no changes detected */
|
|
29
|
-
force?: boolean;
|
|
30
|
-
/** Project name (defaults to current project) */
|
|
31
|
-
project?: string;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Options for bundle status command
|
|
36
|
-
*/
|
|
37
|
-
export interface BundleStatusOptions {
|
|
38
|
-
/** Project name (defaults to current project) */
|
|
39
|
-
project?: string;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Detect if the current working directory is inside a workspace
|
|
44
|
-
* Returns the workspace path if found, undefined otherwise
|
|
45
|
-
*/
|
|
46
|
-
function detectWorkspaceFromCwd(projectName: string): string | undefined {
|
|
47
|
-
const workspacesDir = getProjectWorkspacesDir(projectName);
|
|
48
|
-
|
|
49
|
-
const context = detectWorkspaceContextFromCwd(process.cwd(), getGitspaceDir());
|
|
50
|
-
if (!context || context.projectName !== projectName) {
|
|
51
|
-
return undefined;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const workspacePath = join(workspacesDir, context.workspaceName);
|
|
55
|
-
if (existsSync(workspacePath)) {
|
|
56
|
-
return workspacePath;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Pull latest changes in the base directory
|
|
64
|
-
*/
|
|
65
|
-
async function pullBaseRepo(baseDir: string): Promise<void> {
|
|
66
|
-
logger.info('Pulling latest changes in base repository...');
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
await execAsync('git fetch origin', { cwd: baseDir });
|
|
70
|
-
|
|
71
|
-
// Get current branch
|
|
72
|
-
const { stdout: branchOutput } = await execAsync('git rev-parse --abbrev-ref HEAD', { cwd: baseDir });
|
|
73
|
-
const currentBranch = branchOutput.trim();
|
|
74
|
-
|
|
75
|
-
// Pull current branch
|
|
76
|
-
await execAsync(`git pull origin ${currentBranch}`, { cwd: baseDir });
|
|
77
|
-
|
|
78
|
-
logger.success('Base repository updated');
|
|
79
|
-
} catch (error) {
|
|
80
|
-
logger.warning(`Could not pull latest changes: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
81
|
-
logger.dim('Continuing with existing bundle state...');
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Refresh bundle onboarding for the current project
|
|
87
|
-
*
|
|
88
|
-
* Re-runs onboarding steps with previous values as defaults.
|
|
89
|
-
* Useful when bundle.json has been updated with new configuration.
|
|
90
|
-
*/
|
|
91
|
-
export async function bundleRefresh(options: BundleRefreshCommandOptions): Promise<void> {
|
|
92
|
-
const projectName = options.project || getCurrentProject();
|
|
93
|
-
|
|
94
|
-
if (!projectName) {
|
|
95
|
-
throw new SpacesError(
|
|
96
|
-
'No project selected. Use "gssh switch project" or specify --project',
|
|
97
|
-
'USER_ERROR',
|
|
98
|
-
1
|
|
99
|
-
);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
logger.info(`Checking bundle for project: ${projectName}`);
|
|
103
|
-
|
|
104
|
-
// First, try to detect if user is in a workspace directory
|
|
105
|
-
let workspacePath = detectWorkspaceFromCwd(projectName);
|
|
106
|
-
|
|
107
|
-
if (workspacePath) {
|
|
108
|
-
logger.dim(`Using current workspace: ${workspacePath}`);
|
|
109
|
-
} else {
|
|
110
|
-
// Fall back to base directory after pulling latest
|
|
111
|
-
const baseDir = getProjectBaseDir(projectName);
|
|
112
|
-
|
|
113
|
-
if (!existsSync(baseDir)) {
|
|
114
|
-
throw new SpacesError(
|
|
115
|
-
`Project base directory not found: ${baseDir}`,
|
|
116
|
-
'USER_ERROR',
|
|
117
|
-
1
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
// Pull latest to ensure we have current bundle.json
|
|
122
|
-
await pullBaseRepo(baseDir);
|
|
123
|
-
workspacePath = baseDir;
|
|
124
|
-
logger.dim('Using base repository (no workspace detected in current directory)');
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const refreshOptions: BundleRefreshOptions = {
|
|
128
|
-
force: options.force,
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
const result = await refreshBundle(projectName, workspacePath, refreshOptions);
|
|
132
|
-
|
|
133
|
-
if (result.error) {
|
|
134
|
-
throw new SpacesError(result.error, 'USER_ERROR', 1);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (result.refreshed) {
|
|
138
|
-
logger.success('Bundle configuration updated');
|
|
139
|
-
|
|
140
|
-
if (result.newValues && Object.keys(result.newValues).length > 0) {
|
|
141
|
-
logger.log('\nUpdated values:');
|
|
142
|
-
for (const key of Object.keys(result.newValues)) {
|
|
143
|
-
logger.log(` - ${key}`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
if (result.newSecretKeys && result.newSecretKeys.length > 0) {
|
|
148
|
-
logger.log('\nSecrets configured:');
|
|
149
|
-
for (const key of result.newSecretKeys) {
|
|
150
|
-
logger.log(` - ${key}`);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
} else {
|
|
154
|
-
logger.info('No changes to apply');
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Show bundle status for the current project
|
|
160
|
-
*
|
|
161
|
-
* Displays information about the current bundle configuration.
|
|
162
|
-
*/
|
|
163
|
-
export async function bundleStatus(options: BundleStatusOptions): Promise<void> {
|
|
164
|
-
const projectName = options.project || getCurrentProject();
|
|
165
|
-
|
|
166
|
-
if (!projectName) {
|
|
167
|
-
throw new SpacesError(
|
|
168
|
-
'No project selected. Use "gssh switch project" or specify --project',
|
|
169
|
-
'USER_ERROR',
|
|
170
|
-
1
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// First, try to detect if user is in a workspace directory
|
|
175
|
-
let workspacePath = detectWorkspaceFromCwd(projectName);
|
|
176
|
-
|
|
177
|
-
if (!workspacePath) {
|
|
178
|
-
// Fall back to base directory after pulling latest
|
|
179
|
-
const baseDir = getProjectBaseDir(projectName);
|
|
180
|
-
|
|
181
|
-
if (!existsSync(baseDir)) {
|
|
182
|
-
throw new SpacesError(
|
|
183
|
-
`Project base directory not found: ${baseDir}`,
|
|
184
|
-
'USER_ERROR',
|
|
185
|
-
1
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Pull latest to ensure we have current bundle.json
|
|
190
|
-
await pullBaseRepo(baseDir);
|
|
191
|
-
workspacePath = baseDir;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const changes = detectBundleChanges(projectName, workspacePath);
|
|
195
|
-
|
|
196
|
-
logger.bold(`\nBundle Status: ${projectName}\n`);
|
|
197
|
-
|
|
198
|
-
if (!changes.hasBundle) {
|
|
199
|
-
if (changes.parseError) {
|
|
200
|
-
logger.error('Bundle file exists but could not be parsed:');
|
|
201
|
-
logger.log(` ${changes.parseError}`);
|
|
202
|
-
} else {
|
|
203
|
-
logger.log('No bundle found in this project');
|
|
204
|
-
logger.dim('Bundles are defined in .gitspace/bundle.json');
|
|
205
|
-
}
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const bundle = changes.currentBundle!;
|
|
210
|
-
logger.log(`Bundle: ${bundle.name}`);
|
|
211
|
-
logger.log(`Version: ${bundle.version}`);
|
|
212
|
-
logger.log(`Path: ${changes.bundlePath}`);
|
|
213
|
-
logger.log(`Source: ${changes.bundleSource === 'workspace' ? 'workspace .gitspace/bundle.json' : 'base .gitspace/bundle.json'}`);
|
|
214
|
-
|
|
215
|
-
if (bundle.onboarding && bundle.onboarding.length > 0) {
|
|
216
|
-
logger.log(`Onboarding steps: ${bundle.onboarding.length}`);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
logger.log('');
|
|
220
|
-
|
|
221
|
-
if (changes.hasChanged) {
|
|
222
|
-
logger.warning('Bundle has changed since last applied');
|
|
223
|
-
const details = formatBundleChangeDetails(changes)
|
|
224
|
-
.split('\n')
|
|
225
|
-
.map((line) => ` - ${line}`)
|
|
226
|
-
.join('\n');
|
|
227
|
-
logger.log(details);
|
|
228
|
-
logger.log('Run "gssh bundle refresh" to update configuration');
|
|
229
|
-
} else {
|
|
230
|
-
logger.success('Bundle is up to date');
|
|
231
|
-
}
|
|
232
|
-
}
|