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/list.ts
DELETED
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* List command implementation
|
|
3
|
-
* Handles 'gssh list' (workspaces), 'gssh list projects', and 'gssh list workspaces'
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { existsSync, readdirSync } from 'fs'
|
|
7
|
-
import { join } from 'path'
|
|
8
|
-
import {
|
|
9
|
-
getCurrentProject,
|
|
10
|
-
getProjectWorkspacesDir,
|
|
11
|
-
readGlobalConfig,
|
|
12
|
-
} from '../core/config.js'
|
|
13
|
-
import { listProjectSummaries } from '../core/project-catalog.js'
|
|
14
|
-
import { getWorktreeInfo } from '../core/git.js'
|
|
15
|
-
import { logger } from '../utils/logger.js'
|
|
16
|
-
import { SpacesError, NoProjectError } from '../types/errors.js'
|
|
17
|
-
import type { ProjectInfo, WorktreeInfo } from '../types/workspace.js'
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* List all projects
|
|
21
|
-
*/
|
|
22
|
-
export async function listProjects(
|
|
23
|
-
options: {
|
|
24
|
-
json?: boolean
|
|
25
|
-
verbose?: boolean
|
|
26
|
-
} = {}
|
|
27
|
-
): Promise<void> {
|
|
28
|
-
const projects = listProjectSummaries().map((project) => ({
|
|
29
|
-
...project,
|
|
30
|
-
path: getProjectWorkspacesDir(project.name),
|
|
31
|
-
}))
|
|
32
|
-
|
|
33
|
-
if (projects.length === 0) {
|
|
34
|
-
logger.info('No projects found')
|
|
35
|
-
logger.log('\nCreate a project:\n gssh add project')
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (options.json) {
|
|
40
|
-
console.log(JSON.stringify(projects, null, 2))
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
logger.bold('Projects:')
|
|
45
|
-
|
|
46
|
-
for (const project of projects) {
|
|
47
|
-
const indicator = project.isCurrent ? ' *' : ' '
|
|
48
|
-
const currentLabel = project.isCurrent ? ' (current)' : ''
|
|
49
|
-
|
|
50
|
-
if (options.verbose) {
|
|
51
|
-
logger.log(
|
|
52
|
-
`${indicator} ${project.name.padEnd(20)} ${project.repository.padEnd(
|
|
53
|
-
30
|
|
54
|
-
)} ${project.workspaceCount} workspaces${currentLabel}`
|
|
55
|
-
)
|
|
56
|
-
} else {
|
|
57
|
-
logger.log(
|
|
58
|
-
`${indicator} ${project.name.padEnd(20)} ${
|
|
59
|
-
project.repository
|
|
60
|
-
}${currentLabel}`
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Calculate days since last commit
|
|
68
|
-
*/
|
|
69
|
-
function daysSinceCommit(date: Date): number {
|
|
70
|
-
const now = new Date()
|
|
71
|
-
const diff = now.getTime() - date.getTime()
|
|
72
|
-
return Math.floor(diff / (1000 * 60 * 60 * 24))
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* List workspaces in the current project
|
|
77
|
-
*/
|
|
78
|
-
export async function listWorkspaces(
|
|
79
|
-
options: {
|
|
80
|
-
json?: boolean
|
|
81
|
-
verbose?: boolean
|
|
82
|
-
} = {}
|
|
83
|
-
): Promise<void> {
|
|
84
|
-
const currentProject = getCurrentProject()
|
|
85
|
-
if (!currentProject) {
|
|
86
|
-
throw new NoProjectError()
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const workspacesDir = getProjectWorkspacesDir(currentProject)
|
|
90
|
-
|
|
91
|
-
if (!existsSync(workspacesDir)) {
|
|
92
|
-
logger.info(`No workspaces found in project "${currentProject}"`)
|
|
93
|
-
logger.log('\nCreate a workspace:\n gssh add')
|
|
94
|
-
return
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const workspaceNames = readdirSync(workspacesDir).filter((entry) => {
|
|
98
|
-
const path = join(workspacesDir, entry)
|
|
99
|
-
return existsSync(path)
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
if (workspaceNames.length === 0) {
|
|
103
|
-
logger.info(`No workspaces found in project "${currentProject}"`)
|
|
104
|
-
logger.log('\nCreate a workspace:\n gssh add')
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// Get workspace info
|
|
109
|
-
const workspaces: WorktreeInfo[] = []
|
|
110
|
-
const globalConfig = readGlobalConfig()
|
|
111
|
-
|
|
112
|
-
for (const name of workspaceNames) {
|
|
113
|
-
const workspacePath = join(workspacesDir, name)
|
|
114
|
-
const info = await getWorktreeInfo(workspacePath)
|
|
115
|
-
|
|
116
|
-
if (info) {
|
|
117
|
-
workspaces.push(info)
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (options.json) {
|
|
122
|
-
console.log(JSON.stringify(workspaces, null, 2))
|
|
123
|
-
return
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
logger.bold(`Workspaces (${currentProject}):`)
|
|
127
|
-
|
|
128
|
-
for (const workspace of workspaces) {
|
|
129
|
-
const parts: string[] = []
|
|
130
|
-
parts.push(addSpace(2)) // indent
|
|
131
|
-
parts.push(truncateName(workspace.name, 40).padEnd(45)) // workspace name
|
|
132
|
-
|
|
133
|
-
// Branch and ahead/behind
|
|
134
|
-
if (workspace.ahead > 0 || workspace.behind > 0) {
|
|
135
|
-
parts.push(`+${workspace.ahead} -${workspace.behind}`.padEnd(10))
|
|
136
|
-
} else {
|
|
137
|
-
parts.push('+0 -0'.padEnd(10))
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Uncommitted changes
|
|
141
|
-
if (workspace.uncommittedChanges > 0) {
|
|
142
|
-
parts.push(`${workspace.uncommittedChanges} uncommitted`.padEnd(20))
|
|
143
|
-
} else {
|
|
144
|
-
parts.push('clean'.padEnd(20))
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Stale workspace warning
|
|
148
|
-
const daysSince = daysSinceCommit(workspace.lastCommitDate)
|
|
149
|
-
if (daysSince > globalConfig.staleDays) {
|
|
150
|
-
parts.push(`[stale: ${daysSince} days]`)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
logger.log(parts.join(' '))
|
|
154
|
-
|
|
155
|
-
// Verbose mode: show last commit
|
|
156
|
-
if (options.verbose) {
|
|
157
|
-
logger.dim(` Last commit: ${workspace.lastCommit}`)
|
|
158
|
-
logger.dim(` Date: ${workspace.lastCommitDate.toLocaleDateString()}\n`)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function truncateName(
|
|
164
|
-
name: string,
|
|
165
|
-
maxLength: number,
|
|
166
|
-
includeEllipsis = true
|
|
167
|
-
): string {
|
|
168
|
-
if (name.length <= maxLength) {
|
|
169
|
-
return name
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (includeEllipsis) {
|
|
173
|
-
return name.substring(0, maxLength - 3) + '...'
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return name.substring(0, maxLength)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function addSpace(size: number): string {
|
|
180
|
-
return ' '.repeat(size)
|
|
181
|
-
}
|
package/src/commands/migrate.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { getSecretMigrationInputs } from '../core/secret-runtime.js';
|
|
2
|
-
import { logger } from '../utils/logger.js';
|
|
3
|
-
import { promptConfirm } from '../utils/prompts.js';
|
|
4
|
-
import { cleanupLegacySecretEntries, preloadAllSecrets } from '../utils/secrets.js';
|
|
5
|
-
|
|
6
|
-
export interface CleanupLegacyOptions {
|
|
7
|
-
yes?: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export async function migrateCleanupLegacy(
|
|
11
|
-
options: CleanupLegacyOptions = {}
|
|
12
|
-
): Promise<void> {
|
|
13
|
-
const migrationInputs = getSecretMigrationInputs();
|
|
14
|
-
|
|
15
|
-
if (!options.yes) {
|
|
16
|
-
const confirmed = await promptConfirm(
|
|
17
|
-
'Delete legacy keychain entries (project:*, global, and old per-key entries)? Unified secrets are kept.',
|
|
18
|
-
false
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
if (!confirmed) {
|
|
22
|
-
logger.info('Cancelled');
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// Ensure legacy entries are copied into unified storage before cleanup.
|
|
28
|
-
await preloadAllSecrets(migrationInputs.projectNames, {
|
|
29
|
-
projectLegacyKeys: migrationInputs.projectSecretKeys,
|
|
30
|
-
globalLegacyKeys: migrationInputs.globalSecretKeys,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const result = await cleanupLegacySecretEntries(migrationInputs.projectNames, {
|
|
34
|
-
projectLegacyKeys: migrationInputs.projectSecretKeys,
|
|
35
|
-
globalLegacyKeys: migrationInputs.globalSecretKeys,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
if (result.errors.length > 0) {
|
|
39
|
-
logger.warning(`Legacy cleanup completed with ${result.errors.length} error(s).`);
|
|
40
|
-
for (const error of result.errors) {
|
|
41
|
-
logger.error(` ${error}`);
|
|
42
|
-
}
|
|
43
|
-
logger.info(
|
|
44
|
-
`Legacy cleanup finished with issues. Deleted ${result.deleted} entries (${result.missing} already absent).`
|
|
45
|
-
);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
logger.success(
|
|
50
|
-
`Legacy cleanup complete. Deleted ${result.deleted} entries (${result.missing} already absent).`
|
|
51
|
-
);
|
|
52
|
-
}
|
|
@@ -1,351 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Notifications command - manage shell integration hooks
|
|
3
|
-
*
|
|
4
|
-
* Commands:
|
|
5
|
-
* gssh notifications install - Install shell hooks for notification integration
|
|
6
|
-
* gssh notifications uninstall - Remove shell hooks
|
|
7
|
-
* gssh notifications hook - Print shell hook snippet
|
|
8
|
-
* gssh notifications status - Show current notification config
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { existsSync, readFileSync, writeFileSync, appendFileSync, mkdirSync } from 'fs';
|
|
12
|
-
import { join } from 'path';
|
|
13
|
-
import { homedir } from 'os';
|
|
14
|
-
import { logger } from '../utils/logger.js';
|
|
15
|
-
import { getNotificationConfig } from '../core/config.js';
|
|
16
|
-
|
|
17
|
-
// ============================================================================
|
|
18
|
-
// Shell Hook Snippets
|
|
19
|
-
// ============================================================================
|
|
20
|
-
|
|
21
|
-
const MARKER_START = '# >>> gitspace notifications >>>';
|
|
22
|
-
const MARKER_END = '# <<< gitspace notifications <<<';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Bash/Zsh hook snippet
|
|
26
|
-
* Uses PROMPT_COMMAND for bash, precmd for zsh
|
|
27
|
-
* Emits OSC 133 C/D for command start/done and OSC 777 for exit codes
|
|
28
|
-
*/
|
|
29
|
-
const BASH_ZSH_HOOK = `${MARKER_START}
|
|
30
|
-
# GitSpace notification hooks - do not edit this block manually
|
|
31
|
-
# Emits OSC 133 (semantic shell integration) and OSC 777 (exit notifications)
|
|
32
|
-
|
|
33
|
-
# Only run inside tmux-lite sessions
|
|
34
|
-
if [[ -n "\${TMUX_LITE:-}" ]]; then
|
|
35
|
-
# OSC 133 command start
|
|
36
|
-
__gitspace_preexec() {
|
|
37
|
-
printf '\\033]133;C\\007'
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
# OSC 133 command done + OSC 777 exit notification
|
|
41
|
-
__gitspace_precmd() {
|
|
42
|
-
local exit_code=$?
|
|
43
|
-
printf '\\033]133;D;%d\\007' "$exit_code"
|
|
44
|
-
if [[ $exit_code -ne 0 ]]; then
|
|
45
|
-
printf '\\033]777;exit:%d\\007' "$exit_code"
|
|
46
|
-
fi
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
# Install hooks based on shell
|
|
50
|
-
if [[ -n "\${ZSH_VERSION:-}" ]]; then
|
|
51
|
-
# Zsh: use preexec and precmd hooks
|
|
52
|
-
autoload -Uz add-zsh-hook 2>/dev/null || true
|
|
53
|
-
if type add-zsh-hook &>/dev/null; then
|
|
54
|
-
add-zsh-hook preexec __gitspace_preexec
|
|
55
|
-
add-zsh-hook precmd __gitspace_precmd
|
|
56
|
-
fi
|
|
57
|
-
elif [[ -n "\${BASH_VERSION:-}" ]]; then
|
|
58
|
-
# Bash: use DEBUG trap and PROMPT_COMMAND
|
|
59
|
-
__gitspace_debug_trap() {
|
|
60
|
-
if [[ "\${BASH_COMMAND:-}" != "\${PROMPT_COMMAND:-}" ]] && [[ -z "\${__gitspace_in_prompt:-}" ]]; then
|
|
61
|
-
__gitspace_preexec
|
|
62
|
-
fi
|
|
63
|
-
}
|
|
64
|
-
trap '__gitspace_debug_trap' DEBUG
|
|
65
|
-
|
|
66
|
-
__gitspace_prompt_cmd() {
|
|
67
|
-
__gitspace_in_prompt=1
|
|
68
|
-
__gitspace_precmd
|
|
69
|
-
unset __gitspace_in_prompt
|
|
70
|
-
}
|
|
71
|
-
PROMPT_COMMAND="__gitspace_prompt_cmd\${PROMPT_COMMAND:+;}\${PROMPT_COMMAND:-}"
|
|
72
|
-
fi
|
|
73
|
-
fi
|
|
74
|
-
${MARKER_END}`;
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Fish hook snippet
|
|
78
|
-
* Uses fish_preexec and fish_postexec
|
|
79
|
-
*/
|
|
80
|
-
const FISH_HOOK = `${MARKER_START}
|
|
81
|
-
# GitSpace notification hooks - do not edit this block manually
|
|
82
|
-
# Emits OSC 133 (semantic shell integration) and OSC 777 (exit notifications)
|
|
83
|
-
|
|
84
|
-
# Only run inside tmux-lite sessions
|
|
85
|
-
if set -q TMUX_LITE
|
|
86
|
-
function __gitspace_preexec --on-event fish_preexec
|
|
87
|
-
printf '\\033]133;C\\007'
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
function __gitspace_postexec --on-event fish_postexec
|
|
91
|
-
set -l exit_code $status
|
|
92
|
-
printf '\\033]133;D;%d\\007' $exit_code
|
|
93
|
-
if test $exit_code -ne 0
|
|
94
|
-
printf '\\033]777;exit:%d\\007' $exit_code
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
${MARKER_END}`;
|
|
99
|
-
|
|
100
|
-
// ============================================================================
|
|
101
|
-
// Shell Config Paths
|
|
102
|
-
// ============================================================================
|
|
103
|
-
|
|
104
|
-
interface ShellConfig {
|
|
105
|
-
name: string;
|
|
106
|
-
paths: string[];
|
|
107
|
-
hook: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function getShellConfigs(): ShellConfig[] {
|
|
111
|
-
const home = homedir();
|
|
112
|
-
return [
|
|
113
|
-
{
|
|
114
|
-
name: 'bash',
|
|
115
|
-
paths: [
|
|
116
|
-
join(home, '.bashrc'),
|
|
117
|
-
join(home, '.bash_profile'),
|
|
118
|
-
],
|
|
119
|
-
hook: BASH_ZSH_HOOK,
|
|
120
|
-
},
|
|
121
|
-
{
|
|
122
|
-
name: 'zsh',
|
|
123
|
-
paths: [
|
|
124
|
-
join(home, '.zshrc'),
|
|
125
|
-
],
|
|
126
|
-
hook: BASH_ZSH_HOOK,
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
name: 'fish',
|
|
130
|
-
paths: [
|
|
131
|
-
join(home, '.config', 'fish', 'config.fish'),
|
|
132
|
-
],
|
|
133
|
-
hook: FISH_HOOK,
|
|
134
|
-
},
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ============================================================================
|
|
139
|
-
// Install/Uninstall Functions (exported for testing)
|
|
140
|
-
// ============================================================================
|
|
141
|
-
|
|
142
|
-
/** Exported for testing */
|
|
143
|
-
export const MARKER_START_EXPORT = MARKER_START;
|
|
144
|
-
export const MARKER_END_EXPORT = MARKER_END;
|
|
145
|
-
export const BASH_ZSH_HOOK_EXPORT = BASH_ZSH_HOOK;
|
|
146
|
-
export const FISH_HOOK_EXPORT = FISH_HOOK;
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Check if hook is already installed in a file
|
|
150
|
-
*/
|
|
151
|
-
export function isHookInstalled(filePath: string): boolean {
|
|
152
|
-
if (!existsSync(filePath)) return false;
|
|
153
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
154
|
-
return content.includes(MARKER_START);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Install hook in a file (idempotent)
|
|
159
|
-
*/
|
|
160
|
-
export function installHook(filePath: string, hook: string): { installed: boolean; created: boolean } {
|
|
161
|
-
try {
|
|
162
|
-
// Check if already installed
|
|
163
|
-
if (isHookInstalled(filePath)) {
|
|
164
|
-
return { installed: false, created: false };
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Create parent directories if needed
|
|
168
|
-
const dir = join(filePath, '..');
|
|
169
|
-
if (!existsSync(dir)) {
|
|
170
|
-
mkdirSync(dir, { recursive: true });
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Create file if it doesn't exist
|
|
174
|
-
const created = !existsSync(filePath);
|
|
175
|
-
if (created) {
|
|
176
|
-
writeFileSync(filePath, '', 'utf-8');
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Check for existing DEBUG trap in Bash
|
|
180
|
-
if (!created && (filePath.endsWith('.bashrc') || filePath.endsWith('.bash_profile'))) {
|
|
181
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
182
|
-
if (content.includes('trap') && content.includes('DEBUG')) {
|
|
183
|
-
logger.warning(`Warning: Existing DEBUG trap found in ${filePath}. The GitSpace hook may overwrite it.`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Append hook
|
|
188
|
-
appendFileSync(filePath, '\n' + hook + '\n', 'utf-8');
|
|
189
|
-
return { installed: true, created };
|
|
190
|
-
} catch (error) {
|
|
191
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
192
|
-
logger.error(`Failed to install hook in ${filePath}: ${msg}`);
|
|
193
|
-
return { installed: false, created: false };
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Remove hook from a file
|
|
199
|
-
*/
|
|
200
|
-
export function uninstallHook(filePath: string): boolean {
|
|
201
|
-
try {
|
|
202
|
-
if (!existsSync(filePath)) return false;
|
|
203
|
-
|
|
204
|
-
const content = readFileSync(filePath, 'utf-8');
|
|
205
|
-
if (!content.includes(MARKER_START)) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// Remove the hook block (including surrounding newlines)
|
|
210
|
-
const pattern = new RegExp(
|
|
211
|
-
`\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`,
|
|
212
|
-
'g'
|
|
213
|
-
);
|
|
214
|
-
const newContent = content.replace(pattern, '\n');
|
|
215
|
-
writeFileSync(filePath, newContent, 'utf-8');
|
|
216
|
-
return true;
|
|
217
|
-
} catch (error) {
|
|
218
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
219
|
-
logger.error(`Failed to uninstall hook from ${filePath}: ${msg}`);
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function escapeRegExp(s: string): string {
|
|
225
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// ============================================================================
|
|
229
|
-
// Command Handlers
|
|
230
|
-
// ============================================================================
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Install shell hooks for all detected shells
|
|
234
|
-
*/
|
|
235
|
-
export async function notificationsInstall(): Promise<void> {
|
|
236
|
-
const configs = getShellConfigs();
|
|
237
|
-
let anyInstalled = false;
|
|
238
|
-
|
|
239
|
-
logger.log('Installing GitSpace notification hooks...\n');
|
|
240
|
-
|
|
241
|
-
for (const config of configs) {
|
|
242
|
-
for (const path of config.paths) {
|
|
243
|
-
// Only install to the first existing file for each shell, or create the primary one
|
|
244
|
-
const isPrimary = path === config.paths[0];
|
|
245
|
-
|
|
246
|
-
if (existsSync(path) || isPrimary) {
|
|
247
|
-
const result = installHook(path, config.hook);
|
|
248
|
-
if (result.installed) {
|
|
249
|
-
if (result.created) {
|
|
250
|
-
logger.success(`Created and installed hook in: ${path}`);
|
|
251
|
-
} else {
|
|
252
|
-
logger.success(`Installed hook in: ${path}`);
|
|
253
|
-
}
|
|
254
|
-
anyInstalled = true;
|
|
255
|
-
} else {
|
|
256
|
-
logger.dim(`Already installed in: ${path}`);
|
|
257
|
-
}
|
|
258
|
-
break; // Only install once per shell
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (anyInstalled) {
|
|
264
|
-
logger.log('\nRestart your shell or run "source ~/.bashrc" (or equivalent) to activate.');
|
|
265
|
-
logger.log('Hooks only activate inside tmux-lite sessions (gssh workspaces).');
|
|
266
|
-
} else {
|
|
267
|
-
logger.log('\nAll hooks were already installed.');
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Remove shell hooks from all shell configs
|
|
273
|
-
*/
|
|
274
|
-
export async function notificationsUninstall(): Promise<void> {
|
|
275
|
-
const configs = getShellConfigs();
|
|
276
|
-
let anyRemoved = false;
|
|
277
|
-
|
|
278
|
-
logger.log('Removing GitSpace notification hooks...\n');
|
|
279
|
-
|
|
280
|
-
for (const config of configs) {
|
|
281
|
-
for (const path of config.paths) {
|
|
282
|
-
if (uninstallHook(path)) {
|
|
283
|
-
logger.success(`Removed hook from: ${path}`);
|
|
284
|
-
anyRemoved = true;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (anyRemoved) {
|
|
290
|
-
logger.log('\nHooks removed. Restart your shell to complete.');
|
|
291
|
-
} else {
|
|
292
|
-
logger.log('\nNo hooks were installed.');
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Print shell hook snippet for manual installation
|
|
298
|
-
*/
|
|
299
|
-
export async function notificationsHook(shell?: string): Promise<void> {
|
|
300
|
-
const configs = getShellConfigs();
|
|
301
|
-
|
|
302
|
-
if (!shell) {
|
|
303
|
-
logger.log('Available shells: bash, zsh, fish');
|
|
304
|
-
logger.log('Usage: gssh notifications hook --shell <shell>\n');
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
const config = configs.find(c => c.name === shell.toLowerCase());
|
|
309
|
-
if (!config) {
|
|
310
|
-
logger.error(`Unknown shell: ${shell}`);
|
|
311
|
-
logger.log('Available shells: bash, zsh, fish');
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
logger.log(`# Add this to your ${config.paths[0]}:\n`);
|
|
316
|
-
console.log(config.hook);
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
/**
|
|
320
|
-
* Show current notification settings
|
|
321
|
-
*/
|
|
322
|
-
export async function notificationsStatus(): Promise<void> {
|
|
323
|
-
const config = getNotificationConfig();
|
|
324
|
-
|
|
325
|
-
logger.bold('Notification Settings\n');
|
|
326
|
-
|
|
327
|
-
logger.log(`Enabled: ${config.enabled ? 'yes' : 'no'}`);
|
|
328
|
-
logger.log(`Min command duration: ${config.minCommandDurationMs}ms`);
|
|
329
|
-
logger.log(`Toast notifications: ${config.toast.enabled ? 'enabled' : 'disabled'}`);
|
|
330
|
-
|
|
331
|
-
logger.log('\nNotification types:');
|
|
332
|
-
logger.log(` Exit notifications: ${config.types.exit ? 'on' : 'off'}`);
|
|
333
|
-
logger.log(` Idle notifications: ${config.types.idle ? 'on' : 'off'}`);
|
|
334
|
-
logger.log(` Bell notifications: ${config.types.bell ? 'on' : 'off'}`);
|
|
335
|
-
logger.log(` Title change notifications: ${config.types.title ? 'on' : 'off'}`);
|
|
336
|
-
logger.log(` OSC notifications: ${config.types.osc ? 'on' : 'off'}`);
|
|
337
|
-
|
|
338
|
-
// Check shell hook installation status
|
|
339
|
-
logger.log('\nShell hooks:');
|
|
340
|
-
const configs = getShellConfigs();
|
|
341
|
-
for (const shellConfig of configs) {
|
|
342
|
-
for (const path of shellConfig.paths) {
|
|
343
|
-
if (existsSync(path)) {
|
|
344
|
-
const installed = isHookInstalled(path);
|
|
345
|
-
const status = installed ? 'installed' : 'not installed';
|
|
346
|
-
logger.log(` ${shellConfig.name} (${path}): ${status}`);
|
|
347
|
-
break;
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
package/src/commands/process.ts
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Process commands
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { logger } from '../utils/logger.js';
|
|
6
|
-
import { SpacesError } from '../types/errors.js';
|
|
7
|
-
import { listSessions } from '../lib/tmux-lite/cli.js';
|
|
8
|
-
import {
|
|
9
|
-
getProcessSpecs,
|
|
10
|
-
startProcessInstance,
|
|
11
|
-
stopProcessInstance,
|
|
12
|
-
listProcessSessions,
|
|
13
|
-
} from '../lib/processes/manager.js';
|
|
14
|
-
import { loadProcessesConfig, getProcessDefinition } from '../lib/processes/config.js';
|
|
15
|
-
import { normalizeProcessInstanceCount } from '../lib/processes/instances.js';
|
|
16
|
-
|
|
17
|
-
interface ProcessCommandOptions {
|
|
18
|
-
workspace?: string;
|
|
19
|
-
name?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function resolveWorkspacePath(): string {
|
|
23
|
-
return process.cwd();
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function listProcesses(options: ProcessCommandOptions): Promise<void> {
|
|
27
|
-
const workspacePath = options.workspace || resolveWorkspacePath();
|
|
28
|
-
const specs = getProcessSpecs(workspacePath);
|
|
29
|
-
const sessions = await listProcessSessions(workspacePath);
|
|
30
|
-
|
|
31
|
-
if (specs.length === 0) {
|
|
32
|
-
logger.info('No processes configured in .gitspace/processes.json.');
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
for (const spec of specs) {
|
|
37
|
-
const running = sessions.find(
|
|
38
|
-
(session) => session.processName === spec.name && session.instance === spec.instance
|
|
39
|
-
);
|
|
40
|
-
const status = running ? 'running' : 'stopped';
|
|
41
|
-
logger.log(`${spec.name}#${spec.instance} ${status}`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export async function startProcess(options: ProcessCommandOptions): Promise<void> {
|
|
46
|
-
const workspacePath = options.workspace || resolveWorkspacePath();
|
|
47
|
-
if (!options.name) {
|
|
48
|
-
throw new SpacesError('Provide process name via --name', 'USER_ERROR');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const specs = getProcessSpecs(workspacePath).filter((spec) => spec.name === options.name);
|
|
52
|
-
if (specs.length === 0) {
|
|
53
|
-
const processConfig = loadProcessesConfig(workspacePath);
|
|
54
|
-
const definition = getProcessDefinition(processConfig, options.name);
|
|
55
|
-
if (definition && normalizeProcessInstanceCount(definition.instances) === 0) {
|
|
56
|
-
throw new SpacesError(`Process is disabled (instances: 0): ${options.name}`, 'USER_ERROR');
|
|
57
|
-
}
|
|
58
|
-
throw new SpacesError(`Process not found: ${options.name}`, 'USER_ERROR');
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
for (const spec of specs) {
|
|
62
|
-
const result = await startProcessInstance(workspacePath, spec);
|
|
63
|
-
const note = result.created ? 'started' : 'already running';
|
|
64
|
-
logger.log(`${spec.name}#${spec.instance} ${note} (${result.sessionId})`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export async function stopProcess(options: ProcessCommandOptions): Promise<void> {
|
|
69
|
-
const workspacePath = options.workspace || resolveWorkspacePath();
|
|
70
|
-
if (!options.name) {
|
|
71
|
-
throw new SpacesError('Provide process name via --name', 'USER_ERROR');
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const specs = getProcessSpecs(workspacePath).filter((spec) => spec.name === options.name);
|
|
75
|
-
if (specs.length === 0) {
|
|
76
|
-
throw new SpacesError(`Process not found: ${options.name}`, 'USER_ERROR');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
for (const spec of specs) {
|
|
80
|
-
await stopProcessInstance(workspacePath, spec);
|
|
81
|
-
logger.log(`${spec.name}#${spec.instance} stopped`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export async function attachProcess(options: ProcessCommandOptions): Promise<void> {
|
|
86
|
-
const workspacePath = options.workspace || resolveWorkspacePath();
|
|
87
|
-
if (!options.name) {
|
|
88
|
-
throw new SpacesError('Provide process name via --name', 'USER_ERROR');
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const sessions = await listProcessSessions(workspacePath);
|
|
92
|
-
const target = sessions.find((session) => session.processName === options.name);
|
|
93
|
-
if (!target) {
|
|
94
|
-
throw new SpacesError(`Process not running: ${options.name}`, 'USER_ERROR');
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const sessionList = await listSessions();
|
|
98
|
-
const session = sessionList.find((item) => item.id === target.sessionId);
|
|
99
|
-
if (!session) {
|
|
100
|
-
throw new SpacesError(`Session not found for process ${options.name}`, 'SYSTEM_ERROR');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
logger.info(`Attach with: gssh tmux attach ${session.id}`);
|
|
104
|
-
}
|