gitspace 0.2.0-rc.1
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/.claude/settings.local.json +21 -0
- package/.gitspace/bundle.json +50 -0
- package/.gitspace/select/01-status.sh +40 -0
- package/.gitspace/setup/01-install-deps.sh +12 -0
- package/.gitspace/setup/02-typecheck.sh +16 -0
- package/AGENTS.md +439 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +25 -0
- package/README.md +607 -0
- package/bin/gssh +62 -0
- package/bun.lock +647 -0
- package/docs/CONNECTION.md +623 -0
- package/docs/GATEWAY-WORKER.md +319 -0
- package/docs/GETTING-STARTED.md +448 -0
- package/docs/GITSPACE-PLATFORM.md +1819 -0
- package/docs/INFRASTRUCTURE.md +1347 -0
- package/docs/PROTOCOL.md +619 -0
- package/docs/QUICKSTART.md +174 -0
- package/docs/RELAY.md +327 -0
- package/docs/REMOTE-DESIGN.md +549 -0
- package/docs/ROADMAP.md +564 -0
- package/docs/SITE_DOCS_FIGMA_MAKE.md +1167 -0
- package/docs/STACK-DESIGN.md +588 -0
- package/docs/UNIFIED_ARCHITECTURE.md +292 -0
- package/experiments/pty-benchmark.ts +148 -0
- package/experiments/pty-latency.ts +100 -0
- package/experiments/router/client.ts +199 -0
- package/experiments/router/protocol.ts +74 -0
- package/experiments/router/router.ts +217 -0
- package/experiments/router/session.ts +180 -0
- package/experiments/router/test.ts +133 -0
- package/experiments/socket-bandwidth.ts +77 -0
- package/homebrew/gitspace.rb +45 -0
- package/landing-page/ATTRIBUTIONS.md +3 -0
- package/landing-page/README.md +11 -0
- package/landing-page/bun.lock +801 -0
- package/landing-page/guidelines/Guidelines.md +61 -0
- package/landing-page/index.html +37 -0
- package/landing-page/package.json +90 -0
- package/landing-page/postcss.config.mjs +15 -0
- package/landing-page/public/_redirects +1 -0
- package/landing-page/public/favicon.png +0 -0
- package/landing-page/src/app/App.tsx +53 -0
- package/landing-page/src/app/components/figma/ImageWithFallback.tsx +27 -0
- package/landing-page/src/app/components/ui/accordion.tsx +66 -0
- package/landing-page/src/app/components/ui/alert-dialog.tsx +157 -0
- package/landing-page/src/app/components/ui/alert.tsx +66 -0
- package/landing-page/src/app/components/ui/aspect-ratio.tsx +11 -0
- package/landing-page/src/app/components/ui/avatar.tsx +53 -0
- package/landing-page/src/app/components/ui/badge.tsx +46 -0
- package/landing-page/src/app/components/ui/breadcrumb.tsx +109 -0
- package/landing-page/src/app/components/ui/button.tsx +57 -0
- package/landing-page/src/app/components/ui/calendar.tsx +75 -0
- package/landing-page/src/app/components/ui/card.tsx +92 -0
- package/landing-page/src/app/components/ui/carousel.tsx +241 -0
- package/landing-page/src/app/components/ui/chart.tsx +353 -0
- package/landing-page/src/app/components/ui/checkbox.tsx +32 -0
- package/landing-page/src/app/components/ui/collapsible.tsx +33 -0
- package/landing-page/src/app/components/ui/command.tsx +177 -0
- package/landing-page/src/app/components/ui/context-menu.tsx +252 -0
- package/landing-page/src/app/components/ui/dialog.tsx +135 -0
- package/landing-page/src/app/components/ui/drawer.tsx +132 -0
- package/landing-page/src/app/components/ui/dropdown-menu.tsx +257 -0
- package/landing-page/src/app/components/ui/form.tsx +168 -0
- package/landing-page/src/app/components/ui/hover-card.tsx +44 -0
- package/landing-page/src/app/components/ui/input-otp.tsx +77 -0
- package/landing-page/src/app/components/ui/input.tsx +21 -0
- package/landing-page/src/app/components/ui/label.tsx +24 -0
- package/landing-page/src/app/components/ui/menubar.tsx +276 -0
- package/landing-page/src/app/components/ui/navigation-menu.tsx +168 -0
- package/landing-page/src/app/components/ui/pagination.tsx +127 -0
- package/landing-page/src/app/components/ui/popover.tsx +48 -0
- package/landing-page/src/app/components/ui/progress.tsx +31 -0
- package/landing-page/src/app/components/ui/radio-group.tsx +45 -0
- package/landing-page/src/app/components/ui/resizable.tsx +56 -0
- package/landing-page/src/app/components/ui/scroll-area.tsx +58 -0
- package/landing-page/src/app/components/ui/select.tsx +189 -0
- package/landing-page/src/app/components/ui/separator.tsx +28 -0
- package/landing-page/src/app/components/ui/sheet.tsx +139 -0
- package/landing-page/src/app/components/ui/sidebar.tsx +726 -0
- package/landing-page/src/app/components/ui/skeleton.tsx +13 -0
- package/landing-page/src/app/components/ui/slider.tsx +63 -0
- package/landing-page/src/app/components/ui/sonner.tsx +25 -0
- package/landing-page/src/app/components/ui/switch.tsx +31 -0
- package/landing-page/src/app/components/ui/table.tsx +116 -0
- package/landing-page/src/app/components/ui/tabs.tsx +66 -0
- package/landing-page/src/app/components/ui/textarea.tsx +18 -0
- package/landing-page/src/app/components/ui/toggle-group.tsx +73 -0
- package/landing-page/src/app/components/ui/toggle.tsx +47 -0
- package/landing-page/src/app/components/ui/tooltip.tsx +61 -0
- package/landing-page/src/app/components/ui/use-mobile.ts +21 -0
- package/landing-page/src/app/components/ui/utils.ts +6 -0
- package/landing-page/src/components/docs/DocsContent.tsx +718 -0
- package/landing-page/src/components/docs/DocsSidebar.tsx +84 -0
- package/landing-page/src/components/landing/CTA.tsx +59 -0
- package/landing-page/src/components/landing/Comparison.tsx +84 -0
- package/landing-page/src/components/landing/FaultyTerminal.tsx +424 -0
- package/landing-page/src/components/landing/Features.tsx +201 -0
- package/landing-page/src/components/landing/Hero.tsx +142 -0
- package/landing-page/src/components/landing/Pricing.tsx +140 -0
- package/landing-page/src/components/landing/Roadmap.tsx +86 -0
- package/landing-page/src/components/landing/Security.tsx +81 -0
- package/landing-page/src/components/landing/TerminalWindow.tsx +27 -0
- package/landing-page/src/components/landing/UseCases.tsx +55 -0
- package/landing-page/src/components/landing/Workflow.tsx +101 -0
- package/landing-page/src/components/layout/DashboardNavbar.tsx +37 -0
- package/landing-page/src/components/layout/Footer.tsx +55 -0
- package/landing-page/src/components/layout/LandingNavbar.tsx +82 -0
- package/landing-page/src/components/ui/badge.tsx +39 -0
- package/landing-page/src/components/ui/breadcrumb.tsx +115 -0
- package/landing-page/src/components/ui/button.tsx +57 -0
- package/landing-page/src/components/ui/card.tsx +79 -0
- package/landing-page/src/components/ui/mock-terminal.tsx +68 -0
- package/landing-page/src/components/ui/separator.tsx +28 -0
- package/landing-page/src/lib/utils.ts +6 -0
- package/landing-page/src/main.tsx +10 -0
- package/landing-page/src/pages/Dashboard.tsx +133 -0
- package/landing-page/src/pages/DocsPage.tsx +79 -0
- package/landing-page/src/pages/LandingPage.tsx +31 -0
- package/landing-page/src/pages/TerminalView.tsx +106 -0
- package/landing-page/src/styles/fonts.css +0 -0
- package/landing-page/src/styles/index.css +3 -0
- package/landing-page/src/styles/tailwind.css +4 -0
- package/landing-page/src/styles/theme.css +181 -0
- package/landing-page/vite.config.ts +19 -0
- package/npm/darwin-arm64/bin/gssh +0 -0
- package/npm/darwin-arm64/package.json +20 -0
- package/package.json +74 -0
- package/scripts/build.ts +284 -0
- package/scripts/release.ts +140 -0
- package/src/__tests__/test-utils.ts +298 -0
- package/src/commands/__tests__/serve-messages.test.ts +190 -0
- package/src/commands/access.ts +298 -0
- package/src/commands/add.ts +452 -0
- package/src/commands/auth.ts +364 -0
- package/src/commands/connect.ts +287 -0
- package/src/commands/directory.ts +16 -0
- package/src/commands/host.ts +396 -0
- package/src/commands/identity.ts +184 -0
- package/src/commands/list.ts +200 -0
- package/src/commands/relay.ts +315 -0
- package/src/commands/remove.ts +241 -0
- package/src/commands/serve.ts +1493 -0
- package/src/commands/share.ts +456 -0
- package/src/commands/status.ts +125 -0
- package/src/commands/switch.ts +353 -0
- package/src/commands/tmux.ts +317 -0
- package/src/core/__tests__/access.test.ts +240 -0
- package/src/core/access.ts +277 -0
- package/src/core/bundle.ts +342 -0
- package/src/core/config.ts +510 -0
- package/src/core/git.ts +317 -0
- package/src/core/github.ts +151 -0
- package/src/core/identity.ts +631 -0
- package/src/core/linear.ts +225 -0
- package/src/core/shell.ts +161 -0
- package/src/core/trusted-relays.ts +315 -0
- package/src/index.ts +821 -0
- package/src/lib/remote-session/index.ts +7 -0
- package/src/lib/remote-session/protocol.ts +267 -0
- package/src/lib/remote-session/session-handler.ts +581 -0
- package/src/lib/remote-session/workspace-scanner.ts +167 -0
- package/src/lib/tmux-lite/README.md +81 -0
- package/src/lib/tmux-lite/cli.ts +796 -0
- package/src/lib/tmux-lite/crypto/__tests__/helpers/handshake-runner.ts +349 -0
- package/src/lib/tmux-lite/crypto/__tests__/helpers/mock-relay.ts +291 -0
- package/src/lib/tmux-lite/crypto/__tests__/helpers/test-identities.ts +142 -0
- package/src/lib/tmux-lite/crypto/__tests__/integration/authorization.integration.test.ts +339 -0
- package/src/lib/tmux-lite/crypto/__tests__/integration/e2e-communication.integration.test.ts +477 -0
- package/src/lib/tmux-lite/crypto/__tests__/integration/error-handling.integration.test.ts +499 -0
- package/src/lib/tmux-lite/crypto/__tests__/integration/handshake.integration.test.ts +371 -0
- package/src/lib/tmux-lite/crypto/__tests__/integration/security.integration.test.ts +573 -0
- package/src/lib/tmux-lite/crypto/access-control.test.ts +512 -0
- package/src/lib/tmux-lite/crypto/access-control.ts +320 -0
- package/src/lib/tmux-lite/crypto/frames.test.ts +262 -0
- package/src/lib/tmux-lite/crypto/frames.ts +141 -0
- package/src/lib/tmux-lite/crypto/handshake.ts +894 -0
- package/src/lib/tmux-lite/crypto/identity.test.ts +220 -0
- package/src/lib/tmux-lite/crypto/identity.ts +286 -0
- package/src/lib/tmux-lite/crypto/index.ts +51 -0
- package/src/lib/tmux-lite/crypto/invites.test.ts +381 -0
- package/src/lib/tmux-lite/crypto/invites.ts +215 -0
- package/src/lib/tmux-lite/crypto/keyexchange.ts +435 -0
- package/src/lib/tmux-lite/crypto/keys.test.ts +58 -0
- package/src/lib/tmux-lite/crypto/keys.ts +47 -0
- package/src/lib/tmux-lite/crypto/secretbox.test.ts +169 -0
- package/src/lib/tmux-lite/crypto/secretbox.ts +124 -0
- package/src/lib/tmux-lite/handshake-handler.ts +451 -0
- package/src/lib/tmux-lite/protocol.test.ts +307 -0
- package/src/lib/tmux-lite/protocol.ts +266 -0
- package/src/lib/tmux-lite/relay-client.ts +506 -0
- package/src/lib/tmux-lite/server.ts +1250 -0
- package/src/lib/tmux-lite/shell-integration.sh +37 -0
- package/src/lib/tmux-lite/terminal-queries.test.ts +54 -0
- package/src/lib/tmux-lite/terminal-queries.ts +49 -0
- package/src/relay/__tests__/e2e-flow.test.ts +1284 -0
- package/src/relay/__tests__/helpers/auth.ts +354 -0
- package/src/relay/__tests__/helpers/ports.ts +51 -0
- package/src/relay/__tests__/protocol-validation.test.ts +265 -0
- package/src/relay/authorization.ts +303 -0
- package/src/relay/embedded-assets.generated.d.ts +15 -0
- package/src/relay/identity.ts +352 -0
- package/src/relay/index.ts +57 -0
- package/src/relay/pipes.test.ts +427 -0
- package/src/relay/pipes.ts +195 -0
- package/src/relay/protocol.ts +804 -0
- package/src/relay/registries.test.ts +437 -0
- package/src/relay/registries.ts +593 -0
- package/src/relay/server.test.ts +1323 -0
- package/src/relay/server.ts +1092 -0
- package/src/relay/signing.ts +238 -0
- package/src/relay/types.ts +69 -0
- package/src/serve/client-session-manager.ts +622 -0
- package/src/serve/daemon.ts +497 -0
- package/src/serve/pty-session.ts +236 -0
- package/src/serve/types.ts +169 -0
- package/src/shared/components/Flow.tsx +453 -0
- package/src/shared/components/Flow.tui.tsx +343 -0
- package/src/shared/components/Flow.web.tsx +442 -0
- package/src/shared/components/Inbox.tsx +446 -0
- package/src/shared/components/Inbox.tui.tsx +262 -0
- package/src/shared/components/Inbox.web.tsx +329 -0
- package/src/shared/components/MachineList.tsx +187 -0
- package/src/shared/components/MachineList.tui.tsx +161 -0
- package/src/shared/components/MachineList.web.tsx +210 -0
- package/src/shared/components/ProjectList.tsx +176 -0
- package/src/shared/components/ProjectList.tui.tsx +109 -0
- package/src/shared/components/ProjectList.web.tsx +143 -0
- package/src/shared/components/SpacesBrowser.tsx +332 -0
- package/src/shared/components/SpacesBrowser.tui.tsx +163 -0
- package/src/shared/components/SpacesBrowser.web.tsx +221 -0
- package/src/shared/components/index.ts +103 -0
- package/src/shared/hooks/index.ts +16 -0
- package/src/shared/hooks/useNavigation.ts +226 -0
- package/src/shared/index.ts +122 -0
- package/src/shared/providers/LocalMachineProvider.ts +425 -0
- package/src/shared/providers/MachineProvider.ts +165 -0
- package/src/shared/providers/RemoteMachineProvider.ts +444 -0
- package/src/shared/providers/index.ts +26 -0
- package/src/shared/types.ts +145 -0
- package/src/tui/adapters.ts +120 -0
- package/src/tui/app.tsx +1816 -0
- package/src/tui/components/Terminal.tsx +580 -0
- package/src/tui/hooks/index.ts +35 -0
- package/src/tui/hooks/useAppState.ts +314 -0
- package/src/tui/hooks/useDaemonStatus.ts +174 -0
- package/src/tui/hooks/useInboxTUI.ts +113 -0
- package/src/tui/hooks/useRemoteMachines.ts +209 -0
- package/src/tui/index.ts +24 -0
- package/src/tui/state.ts +299 -0
- package/src/tui/terminal-bracketed-paste.test.ts +45 -0
- package/src/tui/terminal-bracketed-paste.ts +47 -0
- package/src/types/bundle.ts +112 -0
- package/src/types/config.ts +89 -0
- package/src/types/errors.ts +206 -0
- package/src/types/identity.ts +284 -0
- package/src/types/workspace-fuzzy.ts +49 -0
- package/src/types/workspace.ts +151 -0
- package/src/utils/bun-socket-writer.ts +80 -0
- package/src/utils/deps.ts +127 -0
- package/src/utils/fuzzy-match.ts +125 -0
- package/src/utils/logger.ts +127 -0
- package/src/utils/markdown.ts +254 -0
- package/src/utils/onboarding.ts +229 -0
- package/src/utils/prompts.ts +114 -0
- package/src/utils/run-commands.ts +112 -0
- package/src/utils/run-scripts.ts +142 -0
- package/src/utils/sanitize.ts +98 -0
- package/src/utils/secrets.ts +122 -0
- package/src/utils/shell-escape.ts +40 -0
- package/src/utils/utf8.ts +79 -0
- package/src/utils/workspace-state.ts +47 -0
- package/src/web/README.md +73 -0
- package/src/web/bun.lock +575 -0
- package/src/web/eslint.config.js +23 -0
- package/src/web/index.html +16 -0
- package/src/web/package.json +37 -0
- package/src/web/public/vite.svg +1 -0
- package/src/web/src/App.tsx +604 -0
- package/src/web/src/assets/react.svg +1 -0
- package/src/web/src/components/Terminal.tsx +207 -0
- package/src/web/src/hooks/useRelayConnection.ts +224 -0
- package/src/web/src/hooks/useTerminal.ts +699 -0
- package/src/web/src/index.css +55 -0
- package/src/web/src/lib/crypto/__tests__/web-terminal.test.ts +1158 -0
- package/src/web/src/lib/crypto/frames.ts +205 -0
- package/src/web/src/lib/crypto/handshake.ts +396 -0
- package/src/web/src/lib/crypto/identity.ts +128 -0
- package/src/web/src/lib/crypto/keyexchange.ts +246 -0
- package/src/web/src/lib/crypto/relay-signing.ts +53 -0
- package/src/web/src/lib/invite.ts +58 -0
- package/src/web/src/lib/storage/identity-store.ts +94 -0
- package/src/web/src/main.tsx +10 -0
- package/src/web/src/types/identity.ts +45 -0
- package/src/web/tsconfig.app.json +28 -0
- package/src/web/tsconfig.json +7 -0
- package/src/web/tsconfig.node.json +26 -0
- package/src/web/vite.config.ts +31 -0
- package/todo-security.md +92 -0
- package/tsconfig.json +23 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite +0 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite-shm +0 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/12b7107e435bf1b9a8713a7f320472a63e543104d633d89a26f8d21f4e4ef182.sqlite-wal +0 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite +0 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite-shm +0 -0
- package/worker/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/1a1ac3db1ab86ecf712f90322868a9aabc2c7dc9fe2dfbe94f9b075096276b0f.sqlite-wal +0 -0
- package/worker/bun.lock +237 -0
- package/worker/package.json +22 -0
- package/worker/schema.sql +96 -0
- package/worker/src/handlers/auth.ts +451 -0
- package/worker/src/handlers/subdomains.ts +376 -0
- package/worker/src/handlers/user.ts +98 -0
- package/worker/src/index.ts +70 -0
- package/worker/src/middleware/auth.ts +152 -0
- package/worker/src/services/cloudflare.ts +609 -0
- package/worker/src/types.ts +96 -0
- package/worker/tsconfig.json +15 -0
- package/worker/wrangler.toml +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
# GitSpace CLI
|
|
2
|
+
|
|
3
|
+
A powerful CLI tool for managing GitHub repository workspaces using git worktrees and optional Linear integration. Work on multiple features/tasks simultaneously, each in its own isolated workspace. Features an interactive TUI and support for repo config bundles for team onboarding.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Interactive TUI**: Beautiful terminal interface for managing projects and workspaces
|
|
8
|
+
- **Git Worktrees**: Work on multiple branches simultaneously without stashing
|
|
9
|
+
- **Linear Integration**: Create workspaces directly from Linear issues with automatic markdown documentation
|
|
10
|
+
- **Smart Branch Management**: Automatic detection of remote branches
|
|
11
|
+
- **Workspace Status**: Track uncommitted changes, stale workspaces, and more
|
|
12
|
+
- **Custom Scripts**: Convention-based scripts for setup, select, pre-setup, and removal phases
|
|
13
|
+
- **Repo Config Bundles**: Share onboarding configurations with your team, including scripts and setup steps
|
|
14
|
+
- **Secure Secrets**: Store sensitive values in OS keychain via Bun.secrets
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
The following tools must be installed and available in your PATH:
|
|
19
|
+
|
|
20
|
+
- [GitHub CLI (`gh`)](https://cli.github.com/) - for listing repositories
|
|
21
|
+
- [Git](https://git-scm.com/) - for worktree management
|
|
22
|
+
- [jq](https://stedolan.github.io/jq/) - for JSON processing
|
|
23
|
+
- [Bun](https://bun.sh) - runtime for the CLI
|
|
24
|
+
|
|
25
|
+
**GitHub Authentication**: You must authenticate the GitHub CLI before using GitSpace:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
gh auth login
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
bun install -g https://github.com/inkibra/gitspace.sh
|
|
35
|
+
|
|
36
|
+
# Verify installation
|
|
37
|
+
gssh --version
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### Launch the TUI
|
|
43
|
+
|
|
44
|
+
Simply run `gssh` with no arguments to launch the interactive TUI:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
gssh
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The TUI provides a two-panel interface:
|
|
51
|
+
- **Left panel**: Your projects
|
|
52
|
+
- **Right panel**: Workspaces in the selected project
|
|
53
|
+
|
|
54
|
+
**Key Bindings:**
|
|
55
|
+
| Key | Action |
|
|
56
|
+
|-----|--------|
|
|
57
|
+
| `Enter` | Select project / Open workspace |
|
|
58
|
+
| `Tab` | Switch between panels |
|
|
59
|
+
| `n` | New project / workspace |
|
|
60
|
+
| `d` | Delete selected item |
|
|
61
|
+
| `?` | Show help |
|
|
62
|
+
| `q` | Quit |
|
|
63
|
+
|
|
64
|
+
### CLI Commands
|
|
65
|
+
|
|
66
|
+
You can also use traditional CLI commands:
|
|
67
|
+
|
|
68
|
+
#### 1. Add Your First Project
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gssh add project
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Select a GitHub repository, and GitSpace will:
|
|
75
|
+
- Clone the repository to `~/gitspace/<project-name>/base`
|
|
76
|
+
- Detect the default branch
|
|
77
|
+
- Run onboarding steps if a bundle is present
|
|
78
|
+
- Create project configuration
|
|
79
|
+
|
|
80
|
+
#### 2. Create a Workspace
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Create a workspace from a Linear issue (if configured)
|
|
84
|
+
gssh add
|
|
85
|
+
|
|
86
|
+
# Or create a workspace with a custom name
|
|
87
|
+
gssh add my-feature
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
#### 3. Switch Between Workspaces
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Interactive selection
|
|
94
|
+
gssh switch
|
|
95
|
+
|
|
96
|
+
# Switch to a specific workspace
|
|
97
|
+
gssh switch my-feature
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Repo Config Bundles
|
|
101
|
+
|
|
102
|
+
Repo config bundles allow repository owners to share onboarding configurations with their team. When someone clones a project that contains a bundle, they'll be guided through setup steps and have scripts automatically installed.
|
|
103
|
+
|
|
104
|
+
### Bundle Structure
|
|
105
|
+
|
|
106
|
+
A bundle is a directory (typically `.gitspace/`) containing:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
.gitspace/
|
|
110
|
+
├── bundle.json # Bundle manifest with onboarding steps
|
|
111
|
+
├── pre/ # Scripts to run before setup
|
|
112
|
+
│ └── 01-copy-env.sh
|
|
113
|
+
├── setup/ # Scripts to run on first workspace creation
|
|
114
|
+
│ └── 01-install-deps.sh
|
|
115
|
+
├── select/ # Scripts to run every time workspace is opened
|
|
116
|
+
│ └── 01-status.sh
|
|
117
|
+
└── remove/ # Scripts to run before workspace deletion
|
|
118
|
+
└── 01-cleanup.sh
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Bundle Manifest (`bundle.json`)
|
|
122
|
+
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"version": "1.0",
|
|
126
|
+
"name": "my-app-bundle",
|
|
127
|
+
"description": "Setup bundle for my-app",
|
|
128
|
+
"onboarding": [
|
|
129
|
+
{
|
|
130
|
+
"id": "welcome",
|
|
131
|
+
"type": "info",
|
|
132
|
+
"title": "Welcome",
|
|
133
|
+
"description": "Let's get you set up!"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"id": "node",
|
|
137
|
+
"type": "confirm",
|
|
138
|
+
"title": "Node.js",
|
|
139
|
+
"description": "Node.js 18+ is required",
|
|
140
|
+
"checkCommand": "node",
|
|
141
|
+
"installUrl": "https://nodejs.org"
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "api-key",
|
|
145
|
+
"type": "secret",
|
|
146
|
+
"title": "API Key",
|
|
147
|
+
"description": "Enter your API key",
|
|
148
|
+
"configKey": "apiKey"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"id": "team-name",
|
|
152
|
+
"type": "input",
|
|
153
|
+
"title": "Team Name",
|
|
154
|
+
"description": "Enter your team name",
|
|
155
|
+
"configKey": "teamName",
|
|
156
|
+
"defaultValue": "engineering"
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Onboarding Step Types
|
|
163
|
+
|
|
164
|
+
| Type | Purpose | Storage |
|
|
165
|
+
|------|---------|---------|
|
|
166
|
+
| `info` | Display information | N/A |
|
|
167
|
+
| `confirm` | Verify installation (can check command in PATH) | N/A |
|
|
168
|
+
| `secret` | Collect sensitive values (masked input) | OS Keychain |
|
|
169
|
+
| `input` | Collect plain text values | Project config |
|
|
170
|
+
|
|
171
|
+
### Using Bundle Values in Scripts
|
|
172
|
+
|
|
173
|
+
Bundle values are passed to scripts as environment variables:
|
|
174
|
+
|
|
175
|
+
- `SPACE_VALUE_<KEY>` - Regular values from input steps
|
|
176
|
+
- `SPACE_SECRET_<KEY>` - Secret values from secret steps (fetched from OS keychain)
|
|
177
|
+
|
|
178
|
+
**Example script:**
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
#!/bin/bash
|
|
182
|
+
# .gitspace/select/01-status.sh
|
|
183
|
+
|
|
184
|
+
WORKSPACE_NAME=$1
|
|
185
|
+
REPOSITORY=$2
|
|
186
|
+
|
|
187
|
+
# Access bundle values
|
|
188
|
+
if [ -n "$SPACE_VALUE_TEAMNAME" ]; then
|
|
189
|
+
echo "Welcome, $SPACE_VALUE_TEAMNAME team!"
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Access secrets (stored securely in OS keychain)
|
|
193
|
+
if [ -n "$SPACE_SECRET_APIKEY" ]; then
|
|
194
|
+
echo "API Key configured"
|
|
195
|
+
fi
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Bundle Sources
|
|
199
|
+
|
|
200
|
+
Bundles can be loaded from:
|
|
201
|
+
|
|
202
|
+
1. **In-repo** (automatic): `.gitspace/`, `.gitspace-config/`, `.spaces-config/`, or `.spaces/` in the cloned repository
|
|
203
|
+
2. **Local path**: `gssh add project --bundle-path /path/to/bundle/`
|
|
204
|
+
3. **Remote URL**: `gssh add project --bundle-url https://example.com/bundle.zip`
|
|
205
|
+
|
|
206
|
+
## Commands Reference
|
|
207
|
+
|
|
208
|
+
### `gssh` (TUI)
|
|
209
|
+
|
|
210
|
+
Launch the interactive terminal UI.
|
|
211
|
+
|
|
212
|
+
### `gssh add project`
|
|
213
|
+
|
|
214
|
+
Add a new project from GitHub.
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
gssh add project [options]
|
|
218
|
+
|
|
219
|
+
Options:
|
|
220
|
+
--bundle-url <url> Load bundle from remote URL (zip archive)
|
|
221
|
+
--bundle-path <path> Load bundle from local directory
|
|
222
|
+
--skip-bundle Skip bundle detection and onboarding
|
|
223
|
+
--no-clone Create project structure without cloning
|
|
224
|
+
--org <org> Filter repos to specific organization
|
|
225
|
+
--linear-key <key> Provide Linear API key via flag
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `gssh add [workspace-name]`
|
|
229
|
+
|
|
230
|
+
Create a new workspace in the current project.
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
gssh add [workspace-name] [options]
|
|
234
|
+
|
|
235
|
+
Options:
|
|
236
|
+
--branch <name> Specify different branch name from workspace name
|
|
237
|
+
--from <branch> Create from specific branch instead of base
|
|
238
|
+
--no-setup Skip setup commands
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### `gssh switch [workspace-name]`
|
|
242
|
+
|
|
243
|
+
Switch to a workspace in the current project.
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
gssh switch [workspace-name]
|
|
247
|
+
# Alias: gssh sw
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### `gssh switch project [project-name]`
|
|
251
|
+
|
|
252
|
+
Switch to a different project.
|
|
253
|
+
|
|
254
|
+
### `gssh list [subcommand]`
|
|
255
|
+
|
|
256
|
+
List projects or workspaces.
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
gssh list [subcommand] [options]
|
|
260
|
+
# Alias: gssh ls
|
|
261
|
+
|
|
262
|
+
Subcommands:
|
|
263
|
+
projects List all projects
|
|
264
|
+
workspaces List workspaces in current project (default)
|
|
265
|
+
|
|
266
|
+
Options:
|
|
267
|
+
--json Output in JSON format
|
|
268
|
+
--verbose Show additional details
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### `gssh remove workspace [workspace-name]`
|
|
272
|
+
|
|
273
|
+
Remove a workspace.
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
gssh remove workspace [workspace-name] [options]
|
|
277
|
+
# Alias: gssh rm workspace
|
|
278
|
+
|
|
279
|
+
Options:
|
|
280
|
+
--force Skip confirmation prompts
|
|
281
|
+
--keep-branch Don't delete git branch when removing workspace
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### `gssh remove project [project-name]`
|
|
285
|
+
|
|
286
|
+
Remove a project.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
gssh remove project [project-name] [options]
|
|
290
|
+
# Alias: gssh rm project
|
|
291
|
+
|
|
292
|
+
Options:
|
|
293
|
+
--force Skip confirmation prompts
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### `gssh directory`
|
|
297
|
+
|
|
298
|
+
Print the current project directory path.
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
gssh directory
|
|
302
|
+
# Alias: gssh dir
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Configuration
|
|
306
|
+
|
|
307
|
+
### Global Configuration
|
|
308
|
+
|
|
309
|
+
Located at `~/gitspace/.config.json`:
|
|
310
|
+
|
|
311
|
+
```json
|
|
312
|
+
{
|
|
313
|
+
"currentProject": "my-app",
|
|
314
|
+
"projectsDir": "/Users/username/gitspace",
|
|
315
|
+
"defaultBaseBranch": "main",
|
|
316
|
+
"staleDays": 30
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### Project Configuration
|
|
321
|
+
|
|
322
|
+
Located at `~/gitspace/<project-name>/.config.json`:
|
|
323
|
+
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"name": "my-app",
|
|
327
|
+
"repository": "myorg/my-app",
|
|
328
|
+
"baseBranch": "main",
|
|
329
|
+
"linearApiKey": "lin_api_...",
|
|
330
|
+
"linearTeamKey": "ENG",
|
|
331
|
+
"bundleValues": {
|
|
332
|
+
"teamName": "engineering"
|
|
333
|
+
},
|
|
334
|
+
"bundleSecretKeys": ["apiKey"],
|
|
335
|
+
"appliedBundle": {
|
|
336
|
+
"name": "my-app-bundle",
|
|
337
|
+
"version": "1.0",
|
|
338
|
+
"source": "/path/to/bundle",
|
|
339
|
+
"appliedAt": "2025-01-01T00:00:00Z"
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
- `bundleValues`: Values collected from input steps during onboarding
|
|
345
|
+
- `bundleSecretKeys`: Keys of secrets stored in OS keychain (values are NOT stored in config)
|
|
346
|
+
- `appliedBundle`: Information about the bundle that was applied
|
|
347
|
+
|
|
348
|
+
### Custom Scripts
|
|
349
|
+
|
|
350
|
+
GitSpace uses **convention over configuration** for custom scripts:
|
|
351
|
+
|
|
352
|
+
```
|
|
353
|
+
~/gitspace/<project-name>/scripts/
|
|
354
|
+
├── pre/ # Run before setup (terminal)
|
|
355
|
+
├── setup/ # Run once on workspace creation
|
|
356
|
+
├── select/ # Run every time workspace is opened
|
|
357
|
+
└── remove/ # Run before workspace deletion
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
#### Script Execution Rules
|
|
361
|
+
|
|
362
|
+
1. Scripts must be **executable** (`chmod +x`)
|
|
363
|
+
2. Scripts run **alphabetically** (use `01-`, `02-` prefixes)
|
|
364
|
+
3. **Working directory**: The workspace directory
|
|
365
|
+
4. **Arguments**: `$1` = workspace name, `$2` = repository name
|
|
366
|
+
5. **Environment**: Bundle values available as `SPACE_VALUE_*` and `SPACE_SECRET_*`
|
|
367
|
+
|
|
368
|
+
#### Script Phases
|
|
369
|
+
|
|
370
|
+
| Phase | When | Use Case |
|
|
371
|
+
|-------|------|----------|
|
|
372
|
+
| `pre/` | Once, before setup | Copy .env files, create directories |
|
|
373
|
+
| `setup/` | Once, on workspace creation | Install dependencies, initial build |
|
|
374
|
+
| `select/` | Every workspace open | Git fetch, status checks |
|
|
375
|
+
| `remove/` | Before deletion | Cleanup, notifications |
|
|
376
|
+
|
|
377
|
+
### Environment Variables
|
|
378
|
+
|
|
379
|
+
```bash
|
|
380
|
+
# Set the current project (overrides global config)
|
|
381
|
+
export SPACES_CURRENT_PROJECT="my-app"
|
|
382
|
+
|
|
383
|
+
# Available in scripts (from bundle onboarding):
|
|
384
|
+
# SPACE_VALUE_<KEY> - Regular values
|
|
385
|
+
# SPACE_SECRET_<KEY> - Secret values (from OS keychain)
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Directory Structure
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
~/gitspace/
|
|
392
|
+
├── .config.json # Global configuration
|
|
393
|
+
├── <project-name>/
|
|
394
|
+
│ ├── .config.json # Project configuration
|
|
395
|
+
│ ├── base/ # Base repository clone
|
|
396
|
+
│ ├── workspaces/ # Git worktrees
|
|
397
|
+
│ │ └── <workspace-name>/
|
|
398
|
+
│ │ ├── gitspace.lock # Setup completion marker
|
|
399
|
+
│ │ └── .prompt/ # Linear issue details (if applicable)
|
|
400
|
+
│ │ └── issue.md
|
|
401
|
+
│ └── scripts/ # Custom scripts
|
|
402
|
+
│ ├── pre/
|
|
403
|
+
│ ├── setup/
|
|
404
|
+
│ ├── select/
|
|
405
|
+
│ └── remove/
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
## Remote Access
|
|
409
|
+
|
|
410
|
+
GitSpace provides secure remote terminal access with **end-to-end encryption**. Access your terminal sessions from anywhere via web browser or CLI.
|
|
411
|
+
|
|
412
|
+
### gitspace.sh Platform
|
|
413
|
+
|
|
414
|
+
The easiest way to get remote access is through [gitspace.sh](https://gitspace.sh):
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
# 1. Authenticate with GitHub
|
|
418
|
+
gssh auth login
|
|
419
|
+
|
|
420
|
+
# 2. Reserve your subdomain (e.g., yourname.gitspace.sh)
|
|
421
|
+
gssh host reserve yourname
|
|
422
|
+
|
|
423
|
+
# 3. Start serving (creates identity if needed)
|
|
424
|
+
gssh serve
|
|
425
|
+
|
|
426
|
+
# 4. Access from browser at https://yourname.gitspace.sh
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Self-Hosted Setup
|
|
430
|
+
|
|
431
|
+
For complete control, run your own relay:
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
# Terminal 1: Start relay server
|
|
435
|
+
gssh relay start --port 4480
|
|
436
|
+
|
|
437
|
+
# Terminal 2: Initialize identity and start serving
|
|
438
|
+
gssh identity init --label "My MacBook"
|
|
439
|
+
gssh serve --relay ws://localhost:4480/ws
|
|
440
|
+
|
|
441
|
+
# Terminal 3: Create invite for remote access
|
|
442
|
+
gssh share create
|
|
443
|
+
|
|
444
|
+
# Share the invite URL with collaborators
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Identity Management
|
|
448
|
+
|
|
449
|
+
Every machine and client has a cryptographic identity (Ed25519 + X25519 keypair):
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
# Create machine identity (stored in ~/gitspace/.identity/)
|
|
453
|
+
gssh identity init --label "My MacBook"
|
|
454
|
+
|
|
455
|
+
# View identity fingerprint
|
|
456
|
+
gssh identity show
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
### Access Control
|
|
460
|
+
|
|
461
|
+
Control who can connect to your machine:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
# List authorized clients
|
|
465
|
+
gssh access list
|
|
466
|
+
|
|
467
|
+
# Add a client by public key
|
|
468
|
+
gssh access add spcs_pk_abc123... --label "Work Laptop"
|
|
469
|
+
|
|
470
|
+
# Remove client access
|
|
471
|
+
gssh access remove spcs_pk_abc123...
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### Creating Invites
|
|
475
|
+
|
|
476
|
+
Share access via signed invite tokens:
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
# Create invite (24h default)
|
|
480
|
+
gssh share create
|
|
481
|
+
|
|
482
|
+
# Custom expiration
|
|
483
|
+
gssh share create --expires 7d
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
### Connecting Remotely
|
|
487
|
+
|
|
488
|
+
```bash
|
|
489
|
+
# Connect using invite token
|
|
490
|
+
gssh connect <invite-token>
|
|
491
|
+
|
|
492
|
+
# Connect via TUI with relay
|
|
493
|
+
gssh --relay wss://relay.example.com
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Remote Access Commands
|
|
497
|
+
|
|
498
|
+
| Command | Description |
|
|
499
|
+
|---------|-------------|
|
|
500
|
+
| `gssh auth login` | Authenticate with gitspace.sh (GitHub OAuth) |
|
|
501
|
+
| `gssh auth logout` | Sign out of gitspace.sh |
|
|
502
|
+
| `gssh host reserve <name>` | Reserve a subdomain on gitspace.sh |
|
|
503
|
+
| `gssh host status` | Show hosting status |
|
|
504
|
+
| `gssh identity init` | Create machine/client identity |
|
|
505
|
+
| `gssh identity show` | Display identity fingerprint |
|
|
506
|
+
| `gssh access add <key>` | Authorize a client |
|
|
507
|
+
| `gssh access list` | List authorized clients |
|
|
508
|
+
| `gssh access remove <key>` | Revoke client access |
|
|
509
|
+
| `gssh serve` | Start machine daemon |
|
|
510
|
+
| `gssh serve start` | Start serve as background daemon |
|
|
511
|
+
| `gssh serve stop` | Stop background serve daemon |
|
|
512
|
+
| `gssh share create` | Create invite token |
|
|
513
|
+
| `gssh connect <token>` | Connect to remote machine |
|
|
514
|
+
| `gssh status` | Show all daemon statuses |
|
|
515
|
+
|
|
516
|
+
### Relay Server Commands
|
|
517
|
+
|
|
518
|
+
For self-hosted relay servers:
|
|
519
|
+
|
|
520
|
+
| Command | Description |
|
|
521
|
+
|---------|-------------|
|
|
522
|
+
| `gssh relay start` | Start relay server |
|
|
523
|
+
| `gssh relay authorize <key>` | Authorize a machine |
|
|
524
|
+
| `gssh relay revoke <key>` | Revoke machine authorization |
|
|
525
|
+
| `gssh relay machines` | List registered machines |
|
|
526
|
+
| `gssh relay trusted` | List trusted relays |
|
|
527
|
+
| `gssh relay untrust <url>` | Remove relay trust |
|
|
528
|
+
|
|
529
|
+
### Terminal Multiplexer (tmux-lite)
|
|
530
|
+
|
|
531
|
+
Manage terminal sessions:
|
|
532
|
+
|
|
533
|
+
| Command | Description |
|
|
534
|
+
|---------|-------------|
|
|
535
|
+
| `gssh tmux start` | Start tmux-lite daemon |
|
|
536
|
+
| `gssh tmux stop` | Stop tmux-lite daemon |
|
|
537
|
+
| `gssh tmux list` | List sessions |
|
|
538
|
+
| `gssh tmux attach <id>` | Attach to session |
|
|
539
|
+
| `gssh tmux new` | Create new session |
|
|
540
|
+
| `gssh tmux kill <id>` | Kill session |
|
|
541
|
+
|
|
542
|
+
### Environment Variables
|
|
543
|
+
|
|
544
|
+
```bash
|
|
545
|
+
# Relay server
|
|
546
|
+
RELAY_PORT=4480 # Default relay port
|
|
547
|
+
RELAY_BIND=0.0.0.0 # Bind address
|
|
548
|
+
|
|
549
|
+
# Machine identity
|
|
550
|
+
GSSH_IDENTITY_PATH=~/gitspace/.identity/ # Identity storage
|
|
551
|
+
|
|
552
|
+
# gitspace.sh
|
|
553
|
+
GITSPACE_API_URL=https://api.gitspace.sh # API endpoint
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Security Model
|
|
557
|
+
|
|
558
|
+
- **E2E Encryption**: All terminal I/O encrypted with AES-256-GCM
|
|
559
|
+
- **X3DH Handshake**: Forward-secret session key establishment
|
|
560
|
+
- **Ed25519 Signatures**: Cryptographic identity verification
|
|
561
|
+
- **Zero-knowledge Relay**: Relay cannot decrypt terminal content
|
|
562
|
+
|
|
563
|
+
See [docs/GETTING-STARTED.md](docs/GETTING-STARTED.md) for detailed setup and [docs/REMOTE-DESIGN.md](docs/REMOTE-DESIGN.md) for architecture.
|
|
564
|
+
|
|
565
|
+
## Troubleshooting
|
|
566
|
+
|
|
567
|
+
### GitHub CLI not authenticated
|
|
568
|
+
|
|
569
|
+
```
|
|
570
|
+
Error: GitHub CLI is not authenticated
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
**Solution:** Run `gh auth login` and follow the prompts.
|
|
574
|
+
|
|
575
|
+
### Missing dependencies
|
|
576
|
+
|
|
577
|
+
**Solution:** Install the missing dependencies using the provided URLs in the error message.
|
|
578
|
+
|
|
579
|
+
### Bundle secrets not available
|
|
580
|
+
|
|
581
|
+
If `SPACE_SECRET_*` variables are empty, ensure:
|
|
582
|
+
1. You completed the onboarding secret steps
|
|
583
|
+
2. Your OS keychain service is running (libsecret on Linux, Keychain on macOS)
|
|
584
|
+
|
|
585
|
+
## Development
|
|
586
|
+
|
|
587
|
+
```bash
|
|
588
|
+
# Install dependencies
|
|
589
|
+
bun install
|
|
590
|
+
|
|
591
|
+
# Development mode
|
|
592
|
+
bun run dev
|
|
593
|
+
|
|
594
|
+
# Type checking
|
|
595
|
+
bun run typecheck
|
|
596
|
+
|
|
597
|
+
# Run linter
|
|
598
|
+
bun run lint
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
## License
|
|
602
|
+
|
|
603
|
+
MIT
|
|
604
|
+
|
|
605
|
+
## Contributing
|
|
606
|
+
|
|
607
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/bin/gssh
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
#
|
|
3
|
+
# gssh - GitSpace CLI Launcher
|
|
4
|
+
#
|
|
5
|
+
# Tries to run the compiled binary first, falls back to bun for development.
|
|
6
|
+
#
|
|
7
|
+
# Priority:
|
|
8
|
+
# 1. Compiled binary in dist/gssh-{platform}
|
|
9
|
+
# 2. Platform-specific npm package (@gitspace/darwin-arm64, etc.)
|
|
10
|
+
# 3. Development mode via bun src/index.ts
|
|
11
|
+
#
|
|
12
|
+
|
|
13
|
+
set -e
|
|
14
|
+
|
|
15
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
16
|
+
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
17
|
+
|
|
18
|
+
# Get platform identifier
|
|
19
|
+
get_platform() {
|
|
20
|
+
case "$(uname -s)-$(uname -m)" in
|
|
21
|
+
Darwin-arm64) echo "darwin-arm64" ;;
|
|
22
|
+
Darwin-x86_64) echo "darwin-x64" ;;
|
|
23
|
+
Linux-x86_64) echo "linux-x64" ;;
|
|
24
|
+
Linux-aarch64) echo "linux-arm64" ;;
|
|
25
|
+
*) echo "" ;;
|
|
26
|
+
esac
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
PLATFORM=$(get_platform)
|
|
30
|
+
|
|
31
|
+
# 1. Check for local compiled binary (dev builds)
|
|
32
|
+
if [ -n "$PLATFORM" ] && [ -x "$ROOT_DIR/dist/gssh-$PLATFORM" ]; then
|
|
33
|
+
exec "$ROOT_DIR/dist/gssh-$PLATFORM" "$@"
|
|
34
|
+
fi
|
|
35
|
+
if [ -x "$ROOT_DIR/dist/gssh" ]; then
|
|
36
|
+
exec "$ROOT_DIR/dist/gssh" "$@"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# 2. Check for platform-specific npm package
|
|
40
|
+
if [ -n "$PLATFORM" ]; then
|
|
41
|
+
for DIR in \
|
|
42
|
+
"$ROOT_DIR/node_modules/@gitspace/$PLATFORM" \
|
|
43
|
+
"$SCRIPT_DIR/../node_modules/@gitspace/$PLATFORM" \
|
|
44
|
+
"$SCRIPT_DIR/../../@gitspace/$PLATFORM" \
|
|
45
|
+
"$SCRIPT_DIR/../../../@gitspace/$PLATFORM"
|
|
46
|
+
do
|
|
47
|
+
if [ -x "$DIR/bin/gssh" ]; then
|
|
48
|
+
exec "$DIR/bin/gssh" "$@"
|
|
49
|
+
fi
|
|
50
|
+
done
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# 3. Fall back to bun for development
|
|
54
|
+
if command -v bun >/dev/null 2>&1; then
|
|
55
|
+
exec bun "$ROOT_DIR/src/index.ts" "$@"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo "Error: Could not find gssh binary."
|
|
59
|
+
echo ""
|
|
60
|
+
echo "For development, install bun: https://bun.sh"
|
|
61
|
+
echo "For production, ensure @gitspace/$PLATFORM is installed."
|
|
62
|
+
exit 1
|