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/relay.ts
DELETED
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Relay command implementation
|
|
3
|
-
*
|
|
4
|
-
* Handles:
|
|
5
|
-
* - `gssh relay start` - Start the relay server
|
|
6
|
-
* - `gssh relay authorize` - Authorize a machine
|
|
7
|
-
* - `gssh relay revoke` - Revoke a machine's authorization
|
|
8
|
-
* - `gssh relay machines` - List authorized machines
|
|
9
|
-
* - `gssh relay trusted` - List trusted relays (machine-side)
|
|
10
|
-
* - `gssh relay untrust` - Remove relay trust (machine-side)
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { logger } from "../utils/logger.js";
|
|
14
|
-
import { createRelayServer } from "../relay/server.js";
|
|
15
|
-
import { SpacesError } from "../types/errors.js";
|
|
16
|
-
import chalk from "chalk";
|
|
17
|
-
import {
|
|
18
|
-
loadOrCreateRelayIdentity,
|
|
19
|
-
formatRelayFingerprint,
|
|
20
|
-
type RelayIdentity,
|
|
21
|
-
} from "../relay/identity.js";
|
|
22
|
-
import {
|
|
23
|
-
getAuthorizedMachines,
|
|
24
|
-
addAuthorizedMachine,
|
|
25
|
-
removeAuthorizedMachine,
|
|
26
|
-
computeMachineFingerprint,
|
|
27
|
-
type AuthorizedMachine,
|
|
28
|
-
} from "../relay/authorization.js";
|
|
29
|
-
import {
|
|
30
|
-
getTrustedRelays,
|
|
31
|
-
removeTrustedRelay,
|
|
32
|
-
type TrustedRelay,
|
|
33
|
-
} from "../core/trusted-relays.js";
|
|
34
|
-
|
|
35
|
-
/** Default port for relay server (4480 = "GIT0" on phone keypad) */
|
|
36
|
-
const DEFAULT_PORT = 4480;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Start the relay server
|
|
40
|
-
*
|
|
41
|
-
* @param options - Command options
|
|
42
|
-
*/
|
|
43
|
-
export async function startRelay(options: {
|
|
44
|
-
port?: number;
|
|
45
|
-
hostname?: string;
|
|
46
|
-
bind?: string;
|
|
47
|
-
label?: string;
|
|
48
|
-
}): Promise<void> {
|
|
49
|
-
const port = options.port ?? parseInt(process.env.PORT ?? String(DEFAULT_PORT), 10);
|
|
50
|
-
const bind = options.bind ?? process.env.RELAY_BIND ?? "0.0.0.0";
|
|
51
|
-
const hostname = options.hostname ?? process.env.RELAY_HOST;
|
|
52
|
-
|
|
53
|
-
// Load or create relay identity
|
|
54
|
-
const identity = await loadOrCreateRelayIdentity(options.label);
|
|
55
|
-
const fingerprint = formatRelayFingerprint(identity.signingPublicKey);
|
|
56
|
-
|
|
57
|
-
// Display relay identity prominently
|
|
58
|
-
logger.log("");
|
|
59
|
-
logger.log(chalk.cyan("┌────────────────────────────────────────────────┐"));
|
|
60
|
-
logger.log(chalk.cyan("│") + chalk.bold(" Relay Identity ") + chalk.cyan("│"));
|
|
61
|
-
logger.log(chalk.cyan("│") + ` Fingerprint: ${chalk.yellow(fingerprint)} ` + chalk.cyan("│"));
|
|
62
|
-
if (identity.label) {
|
|
63
|
-
const labelPadded = identity.label.substring(0, 30).padEnd(30);
|
|
64
|
-
logger.log(chalk.cyan("│") + ` Label: ${chalk.dim(labelPadded)} ` + chalk.cyan("│"));
|
|
65
|
-
}
|
|
66
|
-
logger.log(chalk.cyan("│") + ` Public Key: ` + chalk.cyan("│"));
|
|
67
|
-
logger.log(chalk.cyan("│") + ` ${chalk.dim(identity.signingPublicKey.substring(0, 44))} ` + chalk.cyan("│"));
|
|
68
|
-
logger.log(chalk.cyan("└────────────────────────────────────────────────┘"));
|
|
69
|
-
logger.log("");
|
|
70
|
-
|
|
71
|
-
logger.log(` Port: ${port}`);
|
|
72
|
-
logger.log(` Bind: ${bind}`);
|
|
73
|
-
if (hostname) {
|
|
74
|
-
logger.log(` Hostname: ${hostname} (only serving this domain)`);
|
|
75
|
-
}
|
|
76
|
-
logger.log("");
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const server = await createRelayServer({
|
|
80
|
-
port,
|
|
81
|
-
bind,
|
|
82
|
-
hostname,
|
|
83
|
-
identity,
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
logger.success(`Relay listening on ws://${hostname || bind}:${port}`);
|
|
87
|
-
logger.log("");
|
|
88
|
-
logger.dim("Press Ctrl+C to stop");
|
|
89
|
-
logger.log("");
|
|
90
|
-
|
|
91
|
-
// Set up shutdown handlers
|
|
92
|
-
const shutdown = () => {
|
|
93
|
-
logger.log("");
|
|
94
|
-
logger.info("Shutting down relay...");
|
|
95
|
-
server.stop();
|
|
96
|
-
process.exit(0);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
process.on("SIGINT", shutdown);
|
|
100
|
-
process.on("SIGTERM", shutdown);
|
|
101
|
-
|
|
102
|
-
// Keep process alive
|
|
103
|
-
await new Promise(() => {
|
|
104
|
-
// Never resolves
|
|
105
|
-
});
|
|
106
|
-
} catch (error) {
|
|
107
|
-
throw new SpacesError(
|
|
108
|
-
`Failed to start relay: ${error instanceof Error ? error.message : String(error)}`,
|
|
109
|
-
"SYSTEM_ERROR",
|
|
110
|
-
2
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// ============================================================================
|
|
116
|
-
// Authorization Commands
|
|
117
|
-
// ============================================================================
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Authorize a machine to connect to this relay
|
|
121
|
-
*
|
|
122
|
-
* @param spacesPubKey - Machine public key in gssh-pub:SIGNING:KEYEXCHANGE format
|
|
123
|
-
* @param options - Command options
|
|
124
|
-
*/
|
|
125
|
-
export async function authorizeMachine(
|
|
126
|
-
spacesPubKey: string,
|
|
127
|
-
options: { label?: string }
|
|
128
|
-
): Promise<void> {
|
|
129
|
-
const entry = addAuthorizedMachine(spacesPubKey, options.label);
|
|
130
|
-
|
|
131
|
-
if (!entry) {
|
|
132
|
-
throw new SpacesError(
|
|
133
|
-
`Invalid public key format. Expected: gssh-pub:SIGNING_KEY:KEYEXCHANGE_KEY\n` +
|
|
134
|
-
`Get this from \`gssh identity show\` on the machine you want to authorize.`,
|
|
135
|
-
"USER_ERROR",
|
|
136
|
-
1
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
logger.log("");
|
|
141
|
-
logger.success("Machine authorized!");
|
|
142
|
-
logger.log("");
|
|
143
|
-
logger.log(` Fingerprint: ${chalk.cyan(entry.fingerprint)}`);
|
|
144
|
-
if (entry.label) {
|
|
145
|
-
logger.log(` Label: ${chalk.yellow(entry.label)}`);
|
|
146
|
-
}
|
|
147
|
-
logger.log("");
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Revoke a machine's authorization
|
|
152
|
-
*
|
|
153
|
-
* @param fingerprintOrLabel - Fingerprint or label of machine to revoke
|
|
154
|
-
*/
|
|
155
|
-
export async function revokeMachine(fingerprintOrLabel: string): Promise<void> {
|
|
156
|
-
const removed = removeAuthorizedMachine(fingerprintOrLabel);
|
|
157
|
-
|
|
158
|
-
if (!removed) {
|
|
159
|
-
const machines = getAuthorizedMachines();
|
|
160
|
-
|
|
161
|
-
if (machines.length === 0) {
|
|
162
|
-
throw new SpacesError("No machines are authorized.", "USER_ERROR", 1);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
logger.error(`No machine found matching: ${fingerprintOrLabel}`);
|
|
166
|
-
logger.log("");
|
|
167
|
-
logger.log("Authorized machines:");
|
|
168
|
-
for (const m of machines) {
|
|
169
|
-
logger.log(` ${m.fingerprint} ${m.label ? `(${m.label})` : ""}`);
|
|
170
|
-
}
|
|
171
|
-
throw new SpacesError("Machine not found.", "USER_ERROR", 1);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
logger.log("");
|
|
175
|
-
logger.success("Machine authorization revoked.");
|
|
176
|
-
logger.log("");
|
|
177
|
-
logger.log(` Fingerprint: ${chalk.cyan(removed.fingerprint)}`);
|
|
178
|
-
if (removed.label) {
|
|
179
|
-
logger.log(` Label: ${chalk.yellow(removed.label)}`);
|
|
180
|
-
}
|
|
181
|
-
logger.log("");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* List all authorized machines
|
|
186
|
-
*/
|
|
187
|
-
export async function listMachines(): Promise<void> {
|
|
188
|
-
const machines = getAuthorizedMachines();
|
|
189
|
-
|
|
190
|
-
if (machines.length === 0) {
|
|
191
|
-
logger.log("");
|
|
192
|
-
logger.info("No machines authorized.");
|
|
193
|
-
logger.log("");
|
|
194
|
-
logger.log("Authorize a machine:");
|
|
195
|
-
logger.log(" gssh relay authorize gssh-pub:... --label 'My Machine'");
|
|
196
|
-
logger.log("");
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
logger.log("");
|
|
201
|
-
logger.bold("Authorized Machines:");
|
|
202
|
-
logger.log("");
|
|
203
|
-
|
|
204
|
-
// Header
|
|
205
|
-
const fpWidth = 20;
|
|
206
|
-
const labelWidth = 24;
|
|
207
|
-
const dateWidth = 12;
|
|
208
|
-
|
|
209
|
-
logger.dim(
|
|
210
|
-
"FINGERPRINT".padEnd(fpWidth) +
|
|
211
|
-
"LABEL".padEnd(labelWidth) +
|
|
212
|
-
"AUTHORIZED"
|
|
213
|
-
);
|
|
214
|
-
logger.dim("─".repeat(fpWidth + labelWidth + dateWidth));
|
|
215
|
-
|
|
216
|
-
// Entries
|
|
217
|
-
for (const m of machines) {
|
|
218
|
-
const fp = m.fingerprint.padEnd(fpWidth);
|
|
219
|
-
const label = (m.label || "-").substring(0, labelWidth - 1).padEnd(labelWidth);
|
|
220
|
-
const date = new Date(m.authorizedAt).toISOString().split("T")[0];
|
|
221
|
-
|
|
222
|
-
logger.log(chalk.cyan(fp) + label + chalk.dim(date));
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
logger.log("");
|
|
226
|
-
logger.dim(`Total: ${machines.length} machine(s)`);
|
|
227
|
-
logger.log("");
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
// ============================================================================
|
|
231
|
-
// Trusted Relay Commands (Machine-side)
|
|
232
|
-
// ============================================================================
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* List all trusted relays
|
|
236
|
-
*/
|
|
237
|
-
export async function listTrustedRelays(): Promise<void> {
|
|
238
|
-
const relays = getTrustedRelays();
|
|
239
|
-
|
|
240
|
-
if (relays.length === 0) {
|
|
241
|
-
logger.log("");
|
|
242
|
-
logger.info("No trusted relays.");
|
|
243
|
-
logger.log("");
|
|
244
|
-
logger.log("Connect to a relay to establish trust:");
|
|
245
|
-
logger.log(" gssh serve --relay wss://relay.example.com");
|
|
246
|
-
logger.log("");
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
logger.log("");
|
|
251
|
-
logger.bold("Trusted Relays:");
|
|
252
|
-
logger.log("");
|
|
253
|
-
|
|
254
|
-
// Header
|
|
255
|
-
const urlWidth = 32;
|
|
256
|
-
const fpWidth = 20;
|
|
257
|
-
const labelWidth = 16;
|
|
258
|
-
|
|
259
|
-
logger.dim(
|
|
260
|
-
"URL".padEnd(urlWidth) +
|
|
261
|
-
"FINGERPRINT".padEnd(fpWidth) +
|
|
262
|
-
"LABEL"
|
|
263
|
-
);
|
|
264
|
-
logger.dim("─".repeat(urlWidth + fpWidth + labelWidth));
|
|
265
|
-
|
|
266
|
-
// Entries
|
|
267
|
-
for (const r of relays) {
|
|
268
|
-
const url = r.url.substring(0, urlWidth - 1).padEnd(urlWidth);
|
|
269
|
-
const fp = r.fingerprint.padEnd(fpWidth);
|
|
270
|
-
const label = (r.label || "-").substring(0, labelWidth - 1);
|
|
271
|
-
|
|
272
|
-
logger.log(chalk.cyan(url) + fp + chalk.dim(label));
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
logger.log("");
|
|
276
|
-
logger.dim(`Total: ${relays.length} relay(s)`);
|
|
277
|
-
logger.log("");
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Remove trust for a relay
|
|
282
|
-
*
|
|
283
|
-
* @param urlOrFingerprint - URL, fingerprint, or label of relay to untrust
|
|
284
|
-
*/
|
|
285
|
-
export async function untrustRelay(urlOrFingerprint: string): Promise<void> {
|
|
286
|
-
const removed = removeTrustedRelay(urlOrFingerprint);
|
|
287
|
-
|
|
288
|
-
if (!removed) {
|
|
289
|
-
const relays = getTrustedRelays();
|
|
290
|
-
|
|
291
|
-
if (relays.length === 0) {
|
|
292
|
-
throw new SpacesError("No relays are trusted.", "USER_ERROR", 1);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
logger.error(`No relay found matching: ${urlOrFingerprint}`);
|
|
296
|
-
logger.log("");
|
|
297
|
-
logger.log("Trusted relays:");
|
|
298
|
-
for (const r of relays) {
|
|
299
|
-
logger.log(` ${r.url} (${r.fingerprint}${r.label ? `, ${r.label}` : ""})`);
|
|
300
|
-
}
|
|
301
|
-
throw new SpacesError("Relay not found.", "USER_ERROR", 1);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
logger.log("");
|
|
305
|
-
logger.success("Relay trust removed.");
|
|
306
|
-
logger.log("");
|
|
307
|
-
logger.log(` URL: ${chalk.cyan(removed.url)}`);
|
|
308
|
-
logger.log(` Fingerprint: ${removed.fingerprint}`);
|
|
309
|
-
if (removed.label) {
|
|
310
|
-
logger.log(` Label: ${chalk.yellow(removed.label)}`);
|
|
311
|
-
}
|
|
312
|
-
logger.log("");
|
|
313
|
-
logger.dim("You will be prompted to trust this relay again on next connection.");
|
|
314
|
-
logger.log("");
|
|
315
|
-
}
|
package/src/commands/remove.ts
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remove command implementation
|
|
3
|
-
* Handles 'gssh remove workspace' and 'gssh remove project'
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { existsSync, readdirSync } from 'fs'
|
|
7
|
-
import { join } from 'path'
|
|
8
|
-
import {
|
|
9
|
-
getCurrentProject,
|
|
10
|
-
readProjectConfig,
|
|
11
|
-
getProjectWorkspacesDir,
|
|
12
|
-
getProjectDir,
|
|
13
|
-
getAllProjectNames,
|
|
14
|
-
} from '../core/config.js'
|
|
15
|
-
import { getWorktreeInfo } from '../core/git.js'
|
|
16
|
-
import {
|
|
17
|
-
deleteWorkspaceCore,
|
|
18
|
-
deleteProjectCore,
|
|
19
|
-
} from '../core/workspace.js'
|
|
20
|
-
import { logger } from '../utils/logger.js'
|
|
21
|
-
import { selectItem, promptConfirm, promptInput } from '../utils/prompts.js'
|
|
22
|
-
import { SpacesError, NoProjectError } from '../types/errors.js'
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Remove a workspace (CLI command)
|
|
26
|
-
* Handles interactive prompts and delegates to core deletion logic
|
|
27
|
-
*/
|
|
28
|
-
export async function removeWorkspace(
|
|
29
|
-
workspaceNameArg?: string,
|
|
30
|
-
options: {
|
|
31
|
-
force?: boolean
|
|
32
|
-
keepBranch?: boolean
|
|
33
|
-
} = {}
|
|
34
|
-
): Promise<void> {
|
|
35
|
-
const currentProject = getCurrentProject()
|
|
36
|
-
if (!currentProject) {
|
|
37
|
-
throw new NoProjectError()
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const workspacesDir = getProjectWorkspacesDir(currentProject)
|
|
41
|
-
|
|
42
|
-
if (!existsSync(workspacesDir)) {
|
|
43
|
-
throw new SpacesError('No workspaces found', 'USER_ERROR', 1)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const workspaceNames = readdirSync(workspacesDir)
|
|
47
|
-
|
|
48
|
-
if (workspaceNames.length === 0) {
|
|
49
|
-
throw new SpacesError('No workspaces found', 'USER_ERROR', 1)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let workspaceName: string
|
|
53
|
-
|
|
54
|
-
if (workspaceNameArg) {
|
|
55
|
-
if (!workspaceNames.includes(workspaceNameArg)) {
|
|
56
|
-
throw new SpacesError(
|
|
57
|
-
`Workspace "${workspaceNameArg}" not found`,
|
|
58
|
-
'USER_ERROR',
|
|
59
|
-
1
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
workspaceName = workspaceNameArg
|
|
63
|
-
} else {
|
|
64
|
-
// Select workspace
|
|
65
|
-
const selected = await selectItem(
|
|
66
|
-
workspaceNames,
|
|
67
|
-
'Select workspace to remove:'
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
if (!selected) {
|
|
71
|
-
logger.info('Cancelled')
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
workspaceName = selected
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const workspacePath = join(workspacesDir, workspaceName)
|
|
79
|
-
|
|
80
|
-
// Get workspace info for display
|
|
81
|
-
const info = await getWorktreeInfo(workspacePath)
|
|
82
|
-
|
|
83
|
-
if (!info) {
|
|
84
|
-
throw new SpacesError(
|
|
85
|
-
`Could not get information for workspace "${workspaceName}"`,
|
|
86
|
-
'SYSTEM_ERROR',
|
|
87
|
-
2
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Show git status
|
|
92
|
-
logger.log(`\nWorkspace: ${workspaceName}`)
|
|
93
|
-
logger.log(`Branch: ${info.branch}`)
|
|
94
|
-
logger.log(`Uncommitted changes: ${info.uncommittedChanges}`)
|
|
95
|
-
|
|
96
|
-
if (info.uncommittedChanges > 0) {
|
|
97
|
-
logger.warning(
|
|
98
|
-
`This workspace has ${info.uncommittedChanges} uncommitted changes`
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Ask for confirmation unless --force
|
|
103
|
-
if (!options.force) {
|
|
104
|
-
const confirmed = await promptConfirm(
|
|
105
|
-
`Remove workspace "${workspaceName}"?`,
|
|
106
|
-
false
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
if (!confirmed) {
|
|
110
|
-
logger.info('Cancelled')
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Delegate to core deletion logic (interactive mode for CLI)
|
|
116
|
-
logger.info('Removing workspace...')
|
|
117
|
-
const runDelete = async (scriptPolicy: 'enforce' | 'skip') => {
|
|
118
|
-
return deleteWorkspaceCore(currentProject, workspaceName, {
|
|
119
|
-
nonInteractive: false, // CLI is interactive
|
|
120
|
-
keepBranch: options.keepBranch,
|
|
121
|
-
removeScriptPolicy: scriptPolicy,
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
let result = await runDelete('enforce')
|
|
126
|
-
|
|
127
|
-
if (!result.success && result.errorCode === 'REMOVE_SCRIPT_FAILED') {
|
|
128
|
-
logger.warning(result.error || 'Remove scripts failed')
|
|
129
|
-
const removeAnyway = options.force
|
|
130
|
-
? true
|
|
131
|
-
: await promptConfirm(
|
|
132
|
-
`Remove workspace "${workspaceName}" anyway and skip cleanup scripts?`,
|
|
133
|
-
false
|
|
134
|
-
)
|
|
135
|
-
|
|
136
|
-
if (!removeAnyway) {
|
|
137
|
-
logger.info('Cancelled')
|
|
138
|
-
return
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
result = await runDelete('skip')
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if (!result.success) {
|
|
145
|
-
throw new SpacesError(
|
|
146
|
-
result.error || 'Failed to remove workspace',
|
|
147
|
-
'SYSTEM_ERROR',
|
|
148
|
-
2
|
|
149
|
-
)
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
logger.success(`Removed worktree: ${workspaceName}`)
|
|
153
|
-
|
|
154
|
-
if (result.sessionsKilled > 0) {
|
|
155
|
-
logger.info(`Killed ${result.sessionsKilled} active session(s)`)
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (result.branchDeleted) {
|
|
159
|
-
logger.success(`Deleted branch: ${result.branch}`)
|
|
160
|
-
} else if (result.branch && !options.keepBranch) {
|
|
161
|
-
logger.warning(`Could not delete branch: ${result.branch}`)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Remove a project (CLI command)
|
|
167
|
-
* Handles interactive prompts and delegates to core deletion logic
|
|
168
|
-
*/
|
|
169
|
-
export async function removeProject(
|
|
170
|
-
projectNameArg?: string,
|
|
171
|
-
options: {
|
|
172
|
-
force?: boolean
|
|
173
|
-
} = {}
|
|
174
|
-
): Promise<void> {
|
|
175
|
-
const allProjects = getAllProjectNames()
|
|
176
|
-
|
|
177
|
-
if (allProjects.length === 0) {
|
|
178
|
-
throw new SpacesError('No projects found', 'USER_ERROR', 1)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
let projectName: string
|
|
182
|
-
|
|
183
|
-
if (projectNameArg) {
|
|
184
|
-
if (!allProjects.includes(projectNameArg)) {
|
|
185
|
-
throw new SpacesError(
|
|
186
|
-
`Project "${projectNameArg}" not found`,
|
|
187
|
-
'USER_ERROR',
|
|
188
|
-
1
|
|
189
|
-
)
|
|
190
|
-
}
|
|
191
|
-
projectName = projectNameArg
|
|
192
|
-
} else {
|
|
193
|
-
// Select project
|
|
194
|
-
const projectOptions = allProjects.map((name) => {
|
|
195
|
-
const config = readProjectConfig(name)
|
|
196
|
-
return `${name} - ${config.repository}`
|
|
197
|
-
})
|
|
198
|
-
|
|
199
|
-
const selected = await selectItem(
|
|
200
|
-
projectOptions,
|
|
201
|
-
'Select project to remove:'
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
if (!selected) {
|
|
205
|
-
logger.info('Cancelled')
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
projectName = selected.split(' - ')[0]
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
const projectDir = getProjectDir(projectName)
|
|
213
|
-
const workspacesDir = getProjectWorkspacesDir(projectName)
|
|
214
|
-
|
|
215
|
-
// List workspaces
|
|
216
|
-
let workspaceCount = 0
|
|
217
|
-
if (existsSync(workspacesDir)) {
|
|
218
|
-
workspaceCount = readdirSync(workspacesDir).length
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
logger.warning(
|
|
222
|
-
`\nThis will permanently delete project "${projectName}" and all its data:`
|
|
223
|
-
)
|
|
224
|
-
logger.log(` - Project directory: ${projectDir}`)
|
|
225
|
-
logger.log(` - Workspaces: ${workspaceCount}`)
|
|
226
|
-
|
|
227
|
-
// Ask for confirmation - require typing project name unless --force
|
|
228
|
-
if (!options.force) {
|
|
229
|
-
const confirmName = await promptInput(
|
|
230
|
-
`Type the project name "${projectName}" to confirm:`
|
|
231
|
-
)
|
|
232
|
-
|
|
233
|
-
if (confirmName !== projectName) {
|
|
234
|
-
logger.info('Cancelled (name mismatch)')
|
|
235
|
-
return
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// Delegate to core deletion logic (interactive mode for CLI)
|
|
240
|
-
logger.info('Removing project...')
|
|
241
|
-
const result = await deleteProjectCore(projectName, {
|
|
242
|
-
nonInteractive: false, // CLI is interactive
|
|
243
|
-
})
|
|
244
|
-
|
|
245
|
-
if (!result.success) {
|
|
246
|
-
if (result.errors.length > 0) {
|
|
247
|
-
for (const error of result.errors) {
|
|
248
|
-
logger.warning(` ${error}`)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
throw new SpacesError(
|
|
252
|
-
'Failed to remove project completely',
|
|
253
|
-
'SYSTEM_ERROR',
|
|
254
|
-
2
|
|
255
|
-
)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Log any partial errors that occurred during cleanup (even on success)
|
|
259
|
-
if (result.errors.length > 0) {
|
|
260
|
-
logger.warning('Some cleanup operations had issues:')
|
|
261
|
-
for (const error of result.errors) {
|
|
262
|
-
logger.warning(` ${error}`)
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
logger.success(`Removed project: ${projectName}`)
|
|
267
|
-
|
|
268
|
-
if (result.sessionsKilled > 0) {
|
|
269
|
-
logger.info(`Killed ${result.sessionsKilled} active session(s)`)
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
if (result.workspacesDeleted > 0) {
|
|
273
|
-
logger.info(`Cleaned up ${result.workspacesDeleted} workspace(s)`)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
if (result.wasCurrentProject) {
|
|
277
|
-
logger.info('Cleared current project (was this project)')
|
|
278
|
-
}
|
|
279
|
-
}
|