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
|
@@ -0,0 +1,1167 @@
|
|
|
1
|
+
You are Figma Make editing the gitspace.sh documentation site:
|
|
2
|
+
|
|
3
|
+
You do NOT have access to our codebase. Use ONLY the factual specification below (it is copied from the repo and must be treated as truth). Update the site copy to match it exactly.
|
|
4
|
+
|
|
5
|
+
Hard constraints:
|
|
6
|
+
- Preserve the existing design system, spacing, typography, and components.
|
|
7
|
+
- Preserve existing navigation/anchors as much as possible. If the docs are a single page, keep it single-page but add a TOC at the top with anchor links.
|
|
8
|
+
- Replace any incorrect commands/flags/URLs with the exact ones below.
|
|
9
|
+
- Do not invent commands, flags, defaults, URLs, or security guarantees.
|
|
10
|
+
- Security claims must match "Security notes / current limitations" below (do not overpromise).
|
|
11
|
+
|
|
12
|
+
============================================================
|
|
13
|
+
A) PRODUCT FACTS (from the repo)
|
|
14
|
+
============================================================
|
|
15
|
+
|
|
16
|
+
Product name: GitSpace CLI
|
|
17
|
+
Binary: `gssh`
|
|
18
|
+
|
|
19
|
+
What it is:
|
|
20
|
+
- A CLI tool for managing GitHub repository workspaces using git worktrees, with an interactive TUI.
|
|
21
|
+
- Optional Linear integration for workspace creation.
|
|
22
|
+
- Supports repo config bundles for onboarding + convention-based scripts.
|
|
23
|
+
- Secure remote terminal access via E2E encrypted relay.
|
|
24
|
+
|
|
25
|
+
Key features (safe to claim):
|
|
26
|
+
- Interactive TUI for managing projects and workspaces
|
|
27
|
+
- Git worktrees for parallel branch development
|
|
28
|
+
- Linear integration (optional)
|
|
29
|
+
- Custom scripts (pre/setup/select/remove phases)
|
|
30
|
+
- Repo config bundles (in-repo or provided)
|
|
31
|
+
- Secure secrets for bundles stored via OS keychain (Bun.secrets)
|
|
32
|
+
- E2E encrypted remote terminal access
|
|
33
|
+
- Identity-based access control (not passwords)
|
|
34
|
+
- gitspace.sh instant hosting with custom subdomains
|
|
35
|
+
|
|
36
|
+
Remote access:
|
|
37
|
+
- GitSpace supports remote terminal access via a "relay" server.
|
|
38
|
+
- The relay routes traffic but cannot read terminal content (end-to-end encryption).
|
|
39
|
+
- Remote access uses identity-based cryptography with:
|
|
40
|
+
- Ed25519 signing keys (identity)
|
|
41
|
+
- X25519 key exchange keys
|
|
42
|
+
- X3DH-style handshake
|
|
43
|
+
- HKDF-SHA256 key derivation
|
|
44
|
+
- AES-256-GCM encrypted frames after handshake
|
|
45
|
+
- Ed25519-signed relay messages for client routing
|
|
46
|
+
- Challenge-response machine registration (Ed25519)
|
|
47
|
+
|
|
48
|
+
============================================================
|
|
49
|
+
B) EXACT CLI COMMANDS + FLAGS + DEFAULTS (must match)
|
|
50
|
+
============================================================
|
|
51
|
+
|
|
52
|
+
Prereqs (list these on docs site):
|
|
53
|
+
- gh (GitHub CLI)
|
|
54
|
+
- git
|
|
55
|
+
- jq
|
|
56
|
+
- bun
|
|
57
|
+
|
|
58
|
+
Optional prereqs:
|
|
59
|
+
- cloudflared (for `gssh host` commands)
|
|
60
|
+
- Linear API key (for Linear integration)
|
|
61
|
+
|
|
62
|
+
Install:
|
|
63
|
+
- `bun install -g https://github.com/inkibra/gitspace.sh`
|
|
64
|
+
- Verify: `gssh --version`
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### Workspace Management Commands
|
|
69
|
+
|
|
70
|
+
Local usage (examples you can show):
|
|
71
|
+
- `gssh` (launch TUI)
|
|
72
|
+
- `gssh add project`
|
|
73
|
+
- `gssh add [workspace-name]`
|
|
74
|
+
- `gssh switch [workspace-name]` (alias: `gssh sw`)
|
|
75
|
+
- `gssh switch project [project-name]`
|
|
76
|
+
- `gssh list projects` (alias: `gssh ls projects`)
|
|
77
|
+
- `gssh list workspaces` (alias: `gssh ls workspaces`; default `gssh list` lists workspaces)
|
|
78
|
+
- `gssh remove workspace [workspace-name]` (alias: `gssh rm workspace`)
|
|
79
|
+
- `gssh remove project [project-name]` (alias: `gssh rm project`)
|
|
80
|
+
- `gssh directory` (alias: `gssh dir`)
|
|
81
|
+
|
|
82
|
+
Options for `gssh add project`:
|
|
83
|
+
- `--bundle-url <url>` - Load bundle from remote URL (zip archive)
|
|
84
|
+
- `--bundle-path <path>` - Load bundle from local directory
|
|
85
|
+
- `--skip-bundle` - Skip bundle detection and onboarding
|
|
86
|
+
- `--no-clone` - Create project structure without cloning
|
|
87
|
+
- `--org <org>` - Filter repos to specific organization
|
|
88
|
+
- `--linear-key <key>` - Provide Linear API key via flag
|
|
89
|
+
|
|
90
|
+
Options for `gssh add [workspace-name]`:
|
|
91
|
+
- `--branch <name>` - Specify different branch name from workspace name
|
|
92
|
+
- `--from <branch>` - Create from specific branch instead of base
|
|
93
|
+
- `--no-setup` - Skip setup commands
|
|
94
|
+
|
|
95
|
+
Options for `gssh remove workspace`:
|
|
96
|
+
- `--force` - Skip confirmation prompts
|
|
97
|
+
- `--keep-branch` - Don't delete git branch when removing
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
### Identity Commands
|
|
102
|
+
|
|
103
|
+
- `gssh identity init [--label <name>] [--force]`
|
|
104
|
+
- `gssh identity show [--fingerprint] [--json]`
|
|
105
|
+
|
|
106
|
+
Identity is encrypted at rest and requires an unlock password when used for remote connections.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### Remote Access / Relay Commands
|
|
111
|
+
|
|
112
|
+
Start relay server:
|
|
113
|
+
- `gssh relay start [--port 4480] [--bind 0.0.0.0] [--hostname <host>] [--label <label>]`
|
|
114
|
+
- Default port: 4480
|
|
115
|
+
|
|
116
|
+
Relay management:
|
|
117
|
+
- `gssh relay authorize <pubkey>` - Authorize a machine by public key
|
|
118
|
+
- `gssh relay revoke <pubkey>` - Revoke a machine's authorization
|
|
119
|
+
- `gssh relay machines` - List authorized machines
|
|
120
|
+
- `gssh relay trusted` - List trusted relays (client-side)
|
|
121
|
+
- `gssh relay untrust <url>` - Remove relay trust (client-side)
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
### Serve Daemon Commands
|
|
126
|
+
|
|
127
|
+
- `gssh serve [--relay <url>] [--relay-pubkey <pubkey>]` - Start daemon (foreground)
|
|
128
|
+
- `gssh serve start [--relay <url>] [--relay-pubkey <pubkey>] [--password-stdin] [--foreground]` - Start daemon (background)
|
|
129
|
+
- `gssh serve stop` - Stop background daemon
|
|
130
|
+
- `gssh status` - Show all daemon statuses
|
|
131
|
+
|
|
132
|
+
Default relay URL for serving if not specified: `wss://relay.gitspace.sh`
|
|
133
|
+
|
|
134
|
+
When starting `gssh serve`, the user will be prompted:
|
|
135
|
+
- "Enter password to unlock identity:"
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### Invite / Sharing Commands
|
|
140
|
+
|
|
141
|
+
Create share invite token:
|
|
142
|
+
- `gssh share create [--expires <duration>] [--session <id>] [--relay <url>]`
|
|
143
|
+
- Defaults:
|
|
144
|
+
- `--expires` default: `24h`
|
|
145
|
+
- `--relay` default: `wss://relay.gitspace.sh`
|
|
146
|
+
- Output includes a share URL of the form:
|
|
147
|
+
- `https://gitspace.sh/join#<TOKEN>`
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Connect Commands
|
|
152
|
+
|
|
153
|
+
Connect via invite:
|
|
154
|
+
- `gssh connect <invite-token-or-url>`
|
|
155
|
+
- Accepts raw token OR a URL like `https://gitspace.sh/join#<TOKEN>`
|
|
156
|
+
- Options:
|
|
157
|
+
- `--relay <url>` override relay URL (from token)
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
### Access Control List (ACL) Commands
|
|
162
|
+
|
|
163
|
+
- `gssh access add <pubkey> [--label <name>]`
|
|
164
|
+
- `gssh access list [--json]` (alias: `gssh access ls`)
|
|
165
|
+
- `gssh access remove <pubkey|label> [--force]` (alias: `gssh access rm`)
|
|
166
|
+
|
|
167
|
+
Public key format shown to users:
|
|
168
|
+
- `gssh-pub:<BASE64_SIGNING_PUBLIC_KEY>:<BASE64_KEY_EXCHANGE_PUBLIC_KEY>`
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### tmux-lite Daemon Commands
|
|
173
|
+
|
|
174
|
+
- `gssh tmux start` - Start tmux-lite server daemon
|
|
175
|
+
- `gssh tmux stop` - Stop tmux-lite daemon
|
|
176
|
+
- `gssh tmux status` - Show tmux-lite daemon status
|
|
177
|
+
- `gssh tmux list` - List active terminal sessions
|
|
178
|
+
- `gssh tmux attach <id>` - Attach to session
|
|
179
|
+
- `gssh tmux new` - Create new session
|
|
180
|
+
- `gssh tmux kill <id>` - Kill session
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### gitspace.sh Authentication Commands
|
|
185
|
+
|
|
186
|
+
- `gssh auth login` - Login via GitHub OAuth device flow
|
|
187
|
+
- `gssh auth logout` - Clear local credentials
|
|
188
|
+
- `gssh auth status` - Show authentication status
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### gitspace.sh Hosting Commands
|
|
193
|
+
|
|
194
|
+
- `gssh host reserve <name>` - Reserve subdomain on gitspace.sh
|
|
195
|
+
- `gssh host release [name]` - Release a subdomain
|
|
196
|
+
- `gssh host list` - List your subdomains
|
|
197
|
+
- `gssh host set-primary <name>` - Set primary subdomain
|
|
198
|
+
- `gssh host status` - Show hosting status
|
|
199
|
+
|
|
200
|
+
============================================================
|
|
201
|
+
C) REMOTE ACCESS: CANONICAL USER FLOWS
|
|
202
|
+
============================================================
|
|
203
|
+
|
|
204
|
+
### Flow 1: gitspace.sh (Managed Service) - RECOMMENDED
|
|
205
|
+
|
|
206
|
+
This is the easiest way to get remote access:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# 1. Create identity (first time only)
|
|
210
|
+
gssh identity init --label "My MacBook"
|
|
211
|
+
|
|
212
|
+
# 2. Authenticate with GitHub
|
|
213
|
+
gssh auth login
|
|
214
|
+
|
|
215
|
+
# 3. Reserve your subdomain
|
|
216
|
+
gssh host reserve yourname
|
|
217
|
+
# You get: yourname.gitspace.sh and *.yourname.gitspace.sh
|
|
218
|
+
|
|
219
|
+
# 4. Start serving
|
|
220
|
+
gssh serve
|
|
221
|
+
# Automatically connects to gitspace.sh relay + Cloudflare tunnel
|
|
222
|
+
|
|
223
|
+
# 5. Access from browser
|
|
224
|
+
# Open: https://yourname.gitspace.sh
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Flow 2: Self-Hosted Relay
|
|
228
|
+
|
|
229
|
+
For complete control, run your own relay:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Terminal 1: Start relay server
|
|
233
|
+
gssh relay start --port 4480 --bind 0.0.0.0
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Relay listens at: `ws://<bind-or-hostname>:4480/ws`
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# Terminal 2: Create identity on the machine
|
|
240
|
+
gssh identity init --label "My MacBook"
|
|
241
|
+
gssh identity show
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
# Terminal 3: Authorize machine on relay host
|
|
246
|
+
gssh relay authorize gssh-pub:<keys> --label "My MacBook"
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# Terminal 4: Start serving
|
|
251
|
+
gssh serve --relay ws://localhost:4480/ws
|
|
252
|
+
# This will prompt for the identity password
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# Terminal 5: Create an invite (while serve is running)
|
|
257
|
+
gssh share create
|
|
258
|
+
# Output: https://gitspace.sh/join#<TOKEN>
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# On client device: Connect
|
|
263
|
+
gssh identity init --label "Work Laptop" # First time only
|
|
264
|
+
gssh connect https://gitspace.sh/join#<TOKEN>
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Flow 3: Direct Connection (Pre-Authorized)
|
|
268
|
+
|
|
269
|
+
Once authorized, connect without an invite:
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
gssh --relay ws://localhost:4480/ws
|
|
273
|
+
# Lists available machines, select one to connect
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
============================================================
|
|
277
|
+
D) CUSTOM SCRIPTS & BUNDLES
|
|
278
|
+
============================================================
|
|
279
|
+
|
|
280
|
+
### Custom Scripts
|
|
281
|
+
|
|
282
|
+
GitSpace uses convention-based scripts located at `~/gitspace/<project>/scripts/`:
|
|
283
|
+
|
|
284
|
+
```
|
|
285
|
+
scripts/
|
|
286
|
+
├── pre/ # Run before setup (once, in terminal)
|
|
287
|
+
├── setup/ # Run on workspace creation (once)
|
|
288
|
+
├── select/ # Run every time workspace is opened
|
|
289
|
+
└── remove/ # Run before workspace deletion
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Script execution rules:
|
|
293
|
+
- Scripts must be executable (`chmod +x`)
|
|
294
|
+
- Scripts run alphabetically (use `01-`, `02-` prefixes)
|
|
295
|
+
- Working directory: The workspace directory
|
|
296
|
+
- Arguments: `$1` = workspace name, `$2` = repository name
|
|
297
|
+
- Environment: Bundle values available as `SPACE_VALUE_*` and `SPACE_SECRET_*`
|
|
298
|
+
|
|
299
|
+
Example script (`scripts/select/01-status.sh`):
|
|
300
|
+
```bash
|
|
301
|
+
#!/bin/bash
|
|
302
|
+
WORKSPACE_NAME=$1
|
|
303
|
+
REPOSITORY=$2
|
|
304
|
+
|
|
305
|
+
echo "Switching to workspace: $WORKSPACE_NAME"
|
|
306
|
+
git fetch origin
|
|
307
|
+
git status
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Repo Config Bundles
|
|
311
|
+
|
|
312
|
+
Bundles allow repository owners to share onboarding configurations. Place in `.gitspace-config/` in your repo:
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
.gitspace-config/
|
|
316
|
+
├── gitspace-bundle.json # Bundle manifest with onboarding steps
|
|
317
|
+
├── pre/ # Scripts to run before setup
|
|
318
|
+
├── setup/ # Scripts to run on first workspace creation
|
|
319
|
+
├── select/ # Scripts to run every time workspace is opened
|
|
320
|
+
└── remove/ # Scripts to run before workspace deletion
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
Bundle manifest example (`gitspace-bundle.json`):
|
|
324
|
+
```json
|
|
325
|
+
{
|
|
326
|
+
"version": "1.0",
|
|
327
|
+
"name": "my-app-bundle",
|
|
328
|
+
"description": "Setup bundle for my-app",
|
|
329
|
+
"onboarding": [
|
|
330
|
+
{
|
|
331
|
+
"id": "welcome",
|
|
332
|
+
"type": "info",
|
|
333
|
+
"title": "Welcome",
|
|
334
|
+
"description": "Let's get you set up!"
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
"id": "node",
|
|
338
|
+
"type": "confirm",
|
|
339
|
+
"title": "Node.js",
|
|
340
|
+
"description": "Node.js 18+ is required",
|
|
341
|
+
"checkCommand": "node",
|
|
342
|
+
"installUrl": "https://nodejs.org"
|
|
343
|
+
},
|
|
344
|
+
{
|
|
345
|
+
"id": "api-key",
|
|
346
|
+
"type": "secret",
|
|
347
|
+
"title": "API Key",
|
|
348
|
+
"description": "Enter your API key",
|
|
349
|
+
"configKey": "apiKey"
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"id": "team-name",
|
|
353
|
+
"type": "input",
|
|
354
|
+
"title": "Team Name",
|
|
355
|
+
"description": "Enter your team name",
|
|
356
|
+
"configKey": "teamName",
|
|
357
|
+
"defaultValue": "engineering"
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
Onboarding step types:
|
|
364
|
+
|
|
365
|
+
| Type | Purpose | Storage |
|
|
366
|
+
|------|---------|---------|
|
|
367
|
+
| `info` | Display information | N/A |
|
|
368
|
+
| `confirm` | Verify installation (can check command in PATH) | N/A |
|
|
369
|
+
| `secret` | Collect sensitive values (masked input) | OS Keychain |
|
|
370
|
+
| `input` | Collect plain text values | Project config |
|
|
371
|
+
|
|
372
|
+
Using bundle values in scripts:
|
|
373
|
+
```bash
|
|
374
|
+
#!/bin/bash
|
|
375
|
+
# Values available as environment variables:
|
|
376
|
+
# SPACE_VALUE_<KEY> - Regular values from input steps
|
|
377
|
+
# SPACE_SECRET_<KEY> - Secret values from secret steps (from OS keychain)
|
|
378
|
+
|
|
379
|
+
if [ -n "$SPACE_VALUE_TEAMNAME" ]; then
|
|
380
|
+
echo "Welcome, $SPACE_VALUE_TEAMNAME team!"
|
|
381
|
+
fi
|
|
382
|
+
|
|
383
|
+
if [ -n "$SPACE_SECRET_APIKEY" ]; then
|
|
384
|
+
echo "API Key configured"
|
|
385
|
+
fi
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Bundle sources:
|
|
389
|
+
- **In-repo** (automatic): `.gitspace-config/`, `gitspace-config/`, or `.gitspace/` in the cloned repository
|
|
390
|
+
- **Local path**: `gssh add project --bundle-path /path/to/bundle/`
|
|
391
|
+
- **Remote URL**: `gssh add project --bundle-url https://example.com/bundle.zip`
|
|
392
|
+
|
|
393
|
+
============================================================
|
|
394
|
+
E) CONFIGURATION REFERENCE
|
|
395
|
+
============================================================
|
|
396
|
+
|
|
397
|
+
### Global Configuration
|
|
398
|
+
|
|
399
|
+
Location: `~/gitspace/.config.json`
|
|
400
|
+
|
|
401
|
+
```json
|
|
402
|
+
{
|
|
403
|
+
"currentProject": "my-app",
|
|
404
|
+
"projectsDir": "/Users/username/spaces",
|
|
405
|
+
"defaultBaseBranch": "main",
|
|
406
|
+
"staleDays": 30
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### Project Configuration
|
|
411
|
+
|
|
412
|
+
Location: `~/gitspace/<project>/.config.json`
|
|
413
|
+
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"name": "my-app",
|
|
417
|
+
"repository": "myorg/my-app",
|
|
418
|
+
"baseBranch": "main",
|
|
419
|
+
"linearApiKey": "lin_api_...",
|
|
420
|
+
"linearTeamKey": "ENG",
|
|
421
|
+
"bundleValues": {
|
|
422
|
+
"teamName": "engineering"
|
|
423
|
+
},
|
|
424
|
+
"bundleSecretKeys": ["apiKey"],
|
|
425
|
+
"appliedBundle": {
|
|
426
|
+
"name": "my-app-bundle",
|
|
427
|
+
"version": "1.0",
|
|
428
|
+
"source": "/path/to/bundle",
|
|
429
|
+
"appliedAt": "2025-01-01T00:00:00Z"
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Identity Storage
|
|
435
|
+
|
|
436
|
+
Location: `~/gitspace/.identity/`
|
|
437
|
+
|
|
438
|
+
| File | Purpose |
|
|
439
|
+
|------|---------|
|
|
440
|
+
| `keypair.json` | Encrypted Ed25519/X25519 keys (password-protected) |
|
|
441
|
+
| `access-list.json` | Authorized client public keys |
|
|
442
|
+
| `machine.json` | Machine ID and label |
|
|
443
|
+
| `relay.json` | Relay configuration cache |
|
|
444
|
+
|
|
445
|
+
### Environment Variables
|
|
446
|
+
|
|
447
|
+
| Variable | Description | Default |
|
|
448
|
+
|----------|-------------|---------|
|
|
449
|
+
| `RELAY_PORT` | Relay server port | `4480` |
|
|
450
|
+
| `RELAY_BIND` | Relay bind address | `0.0.0.0` |
|
|
451
|
+
| `SPACES_CURRENT_PROJECT` | Override current project | From config |
|
|
452
|
+
| `GITSPACE_API_URL` | gitspace.sh API URL | `https://api.gitspace.sh` |
|
|
453
|
+
|
|
454
|
+
### Directory Structure
|
|
455
|
+
|
|
456
|
+
```
|
|
457
|
+
~/gitspace/
|
|
458
|
+
├── .config.json # Global configuration
|
|
459
|
+
├── .identity/ # Identity files (see above)
|
|
460
|
+
├── <project-name>/
|
|
461
|
+
│ ├── .config.json # Project configuration
|
|
462
|
+
│ ├── base/ # Base repository clone
|
|
463
|
+
│ ├── workspaces/ # Git worktrees
|
|
464
|
+
│ │ └── <workspace-name>/
|
|
465
|
+
│ │ ├── gitspace.lock # Setup completion marker
|
|
466
|
+
│ │ └── .prompt/ # Linear issue details (if applicable)
|
|
467
|
+
│ │ └── issue.md
|
|
468
|
+
│ └── scripts/ # Custom scripts
|
|
469
|
+
│ ├── pre/
|
|
470
|
+
│ ├── setup/
|
|
471
|
+
│ ├── select/
|
|
472
|
+
│ └── remove/
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
============================================================
|
|
476
|
+
F) SECURITY MODEL
|
|
477
|
+
============================================================
|
|
478
|
+
|
|
479
|
+
### Cryptographic Primitives
|
|
480
|
+
|
|
481
|
+
| Purpose | Algorithm | Notes |
|
|
482
|
+
|---------|-----------|-------|
|
|
483
|
+
| Identity signing | Ed25519 | Fast, secure signatures |
|
|
484
|
+
| Key exchange | X25519 | ECDH for shared secrets |
|
|
485
|
+
| Key derivation | HKDF-SHA256 | Domain-separated key derivation |
|
|
486
|
+
| Symmetric encryption | AES-256-GCM | Authenticated encryption |
|
|
487
|
+
| Password KDF | Scrypt (N=2^15, r=8, p=1) | Encrypts identity at rest |
|
|
488
|
+
|
|
489
|
+
### What's Protected
|
|
490
|
+
|
|
491
|
+
| Data | Protection Level |
|
|
492
|
+
|------|------------------|
|
|
493
|
+
| Terminal keystrokes | E2E encrypted (AES-256-GCM) |
|
|
494
|
+
| Terminal output | E2E encrypted (AES-256-GCM) |
|
|
495
|
+
| Commands | E2E encrypted (AES-256-GCM) |
|
|
496
|
+
| Session content | E2E encrypted (AES-256-GCM) |
|
|
497
|
+
| Identity keys | Password-encrypted (Scrypt + AES-GCM) |
|
|
498
|
+
| Bundle secrets | OS Keychain (macOS Keychain, Linux libsecret) |
|
|
499
|
+
|
|
500
|
+
### What Relay Can See (Metadata Only)
|
|
501
|
+
|
|
502
|
+
| Data | Visible to Relay |
|
|
503
|
+
|------|------------------|
|
|
504
|
+
| Machine ID | Yes (required for routing) |
|
|
505
|
+
| Client identity ID | Yes (required for routing) |
|
|
506
|
+
| Connection timestamps | Yes (metadata) |
|
|
507
|
+
| Data volume (bytes) | Yes (metadata) |
|
|
508
|
+
| Online/offline status | Yes |
|
|
509
|
+
| Terminal content | NO (encrypted) |
|
|
510
|
+
| Keystrokes | NO (encrypted) |
|
|
511
|
+
| Commands and output | NO (encrypted) |
|
|
512
|
+
|
|
513
|
+
### Trust Boundaries
|
|
514
|
+
|
|
515
|
+
```
|
|
516
|
+
YOU TRUST: YOU DON'T NEED TO TRUST:
|
|
517
|
+
├── Your own machine ├── The relay operator
|
|
518
|
+
├── Clients you've authorized ├── Network infrastructure
|
|
519
|
+
└── Devices holding your identity └── Anyone without an invite
|
|
520
|
+
|
|
521
|
+
IF THE RELAY IS COMPROMISED:
|
|
522
|
+
✓ Terminal content is still safe (E2E encrypted)
|
|
523
|
+
✓ Identity keys are still safe (never sent to relay)
|
|
524
|
+
✗ Metadata is exposed (who connected when)
|
|
525
|
+
✗ Relay could deny service
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Access Types
|
|
529
|
+
|
|
530
|
+
| Type | Description | Capabilities |
|
|
531
|
+
|------|-------------|--------------|
|
|
532
|
+
| `full` | Permanent access grant | Browse all projects/workspaces, create/attach/kill sessions, manage access |
|
|
533
|
+
| `session-invite` | One-time session access | View specific session only, no browsing, read-only |
|
|
534
|
+
|
|
535
|
+
### Current Limitations
|
|
536
|
+
|
|
537
|
+
> **Important**: Include this callout on the site. These are known limitations.
|
|
538
|
+
|
|
539
|
+
1. **Client proof-of-possession**: The handshake doesn't fully enforce that the client possesses the private key corresponding to their claimed public key. If an attacker learns an authorized public key, ACL identity spoofing is theoretically possible.
|
|
540
|
+
|
|
541
|
+
2. **Permission enforcement**: Permission flags (`read`/`write`/`manage`) are not fully enforced server-side after the handshake completes. "View-only" access should be treated as intended behavior rather than a strict security guarantee.
|
|
542
|
+
|
|
543
|
+
These limitations are being addressed in future releases.
|
|
544
|
+
|
|
545
|
+
============================================================
|
|
546
|
+
G) TROUBLESHOOTING
|
|
547
|
+
============================================================
|
|
548
|
+
|
|
549
|
+
### Installation Issues
|
|
550
|
+
|
|
551
|
+
**"command not found: spaces"**
|
|
552
|
+
- Ensure Bun's global bin is in your PATH
|
|
553
|
+
- Try: `export PATH="$HOME/.bun/bin:$PATH"`
|
|
554
|
+
- Add to your shell profile (`~/.zshrc`, `~/.bashrc`)
|
|
555
|
+
|
|
556
|
+
**"GitHub CLI not authenticated"**
|
|
557
|
+
```bash
|
|
558
|
+
gh auth login
|
|
559
|
+
# Follow prompts to authenticate
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Identity Issues
|
|
563
|
+
|
|
564
|
+
**"No identity found"**
|
|
565
|
+
```bash
|
|
566
|
+
gssh identity init --label "My Device"
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**"Failed to unlock identity"**
|
|
570
|
+
- You're entering the wrong password
|
|
571
|
+
- If forgotten, recreate: `gssh identity init --force`
|
|
572
|
+
- Warning: This invalidates existing invites and access grants
|
|
573
|
+
|
|
574
|
+
**"Identity already exists"**
|
|
575
|
+
- Use `--force` to overwrite: `gssh identity init --force`
|
|
576
|
+
|
|
577
|
+
### Connection Issues
|
|
578
|
+
|
|
579
|
+
**"Machine offline"**
|
|
580
|
+
- Ensure `gssh serve` is running on the target machine
|
|
581
|
+
- Check the machine can reach the relay URL
|
|
582
|
+
- Verify the machine is authorized on the relay
|
|
583
|
+
|
|
584
|
+
**"Client not authorized"**
|
|
585
|
+
- You need an invite to connect first
|
|
586
|
+
- Or have the machine owner add your public key:
|
|
587
|
+
```bash
|
|
588
|
+
gssh access add <your-public-key> --label "Name"
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
**"Invite not found" or "Invite expired"**
|
|
592
|
+
- The invite may have expired (default: 24h)
|
|
593
|
+
- Already been used (single-use invites)
|
|
594
|
+
- Not been registered (ensure `gssh serve` was running when created)
|
|
595
|
+
- Create a new invite: `gssh share create --expires 7d`
|
|
596
|
+
|
|
597
|
+
**"Handshake timeout"**
|
|
598
|
+
- Check network connectivity
|
|
599
|
+
- Verify firewall allows WebSocket connections
|
|
600
|
+
- Both parties must have valid identities
|
|
601
|
+
- Try connecting again (transient network issue)
|
|
602
|
+
|
|
603
|
+
**"Connection refused" to relay**
|
|
604
|
+
- Verify relay URL is correct (`ws://` vs `wss://`)
|
|
605
|
+
- Check relay server is running
|
|
606
|
+
- Verify port is open/reachable
|
|
607
|
+
|
|
608
|
+
### Workspace Issues
|
|
609
|
+
|
|
610
|
+
**"Workspace already exists"**
|
|
611
|
+
- Choose a different name
|
|
612
|
+
- Or remove existing: `gssh remove workspace <name>`
|
|
613
|
+
|
|
614
|
+
**"Failed to create worktree"**
|
|
615
|
+
- Check branch doesn't already exist
|
|
616
|
+
- Ensure you have git write permissions
|
|
617
|
+
- Try: `git fetch origin` first
|
|
618
|
+
|
|
619
|
+
**"Setup scripts failed"**
|
|
620
|
+
- Check script is executable: `chmod +x scripts/setup/*.sh`
|
|
621
|
+
- Run manually to see error: `./scripts/setup/01-script.sh`
|
|
622
|
+
- Check environment variables are set
|
|
623
|
+
|
|
624
|
+
### Bundle/Secrets Issues
|
|
625
|
+
|
|
626
|
+
**"SPACE_SECRET_* variables are empty"**
|
|
627
|
+
1. Ensure you completed onboarding secret steps
|
|
628
|
+
2. Check OS keychain is accessible:
|
|
629
|
+
- macOS: Keychain Access should be running
|
|
630
|
+
- Linux: `libsecret` must be installed
|
|
631
|
+
3. Re-run onboarding if needed
|
|
632
|
+
|
|
633
|
+
### Hosting Issues (gitspace.sh)
|
|
634
|
+
|
|
635
|
+
**"Subdomain not available"**
|
|
636
|
+
- Name may be taken or reserved
|
|
637
|
+
- Try a different name
|
|
638
|
+
- Check your subdomains: `gssh host list`
|
|
639
|
+
|
|
640
|
+
**"Tunnel failed to connect"**
|
|
641
|
+
- Ensure `cloudflared` is installed
|
|
642
|
+
- Check internet connectivity
|
|
643
|
+
- Verify subdomain is reserved: `gssh host status`
|
|
644
|
+
|
|
645
|
+
**"Authentication failed" (gitspace.sh)**
|
|
646
|
+
- Token may be expired
|
|
647
|
+
- Re-authenticate: `gssh auth login`
|
|
648
|
+
|
|
649
|
+
============================================================
|
|
650
|
+
H) GLOSSARY
|
|
651
|
+
============================================================
|
|
652
|
+
|
|
653
|
+
| Term | Definition |
|
|
654
|
+
|------|------------|
|
|
655
|
+
| **Machine** | A device running `gssh serve` that accepts remote connections |
|
|
656
|
+
| **Client** | A device running `gssh connect` or browser accessing terminal |
|
|
657
|
+
| **Relay** | WebSocket server that routes encrypted traffic (default: `wss://relay.gitspace.sh`) |
|
|
658
|
+
| **Relay Identity** | Ed25519 keypair used by the relay to sign messages and challenges |
|
|
659
|
+
| **Authorized Machine** | Machine public key approved to register with a relay |
|
|
660
|
+
| **Identity** | Ed25519 signing + X25519 key exchange keypairs, encrypted at rest |
|
|
661
|
+
| **Invite** | Signed token that bootstraps trust and enables first connection |
|
|
662
|
+
| **ACL (Access Control List)** | Machine-managed list of authorized client identities |
|
|
663
|
+
| **X3DH** | Extended Triple Diffie-Hellman handshake for session key establishment |
|
|
664
|
+
| **PTY** | Pseudo-terminal, the interface between your shell and the terminal |
|
|
665
|
+
| **Worktree** | Git feature allowing multiple working directories for one repository |
|
|
666
|
+
| **Bundle** | Repository configuration package for team onboarding |
|
|
667
|
+
| **Session** | A terminal session managed by tmux-lite on the server |
|
|
668
|
+
| **Stream** | Encrypted channel within a connection (Stream 0 = master) |
|
|
669
|
+
| **TUI** | Terminal User Interface, the interactive `gssh` interface |
|
|
670
|
+
| **tmux-lite** | Built-in terminal multiplexer for managing sessions |
|
|
671
|
+
| **Subdomain** | Your custom URL on gitspace.sh (e.g., `yourname.gitspace.sh`) |
|
|
672
|
+
|
|
673
|
+
============================================================
|
|
674
|
+
I) WHAT TO WRITE ON THE SITE
|
|
675
|
+
============================================================
|
|
676
|
+
|
|
677
|
+
Update TWO pages: Home and Docs. Keep layout, replace text/code with the following.
|
|
678
|
+
|
|
679
|
+
-------------------------
|
|
680
|
+
HOME PAGE (replace copy)
|
|
681
|
+
-------------------------
|
|
682
|
+
|
|
683
|
+
Headline:
|
|
684
|
+
GitSpace: Git worktrees + secure remote access for parallel development
|
|
685
|
+
|
|
686
|
+
Subheadline:
|
|
687
|
+
Manage multiple features in one repo without stashing. Create isolated workspaces (git worktrees), switch instantly, and access your terminal remotely through end-to-end encrypted connections.
|
|
688
|
+
|
|
689
|
+
Primary CTA:
|
|
690
|
+
Get Started -> link to /docs
|
|
691
|
+
|
|
692
|
+
Feature bullets:
|
|
693
|
+
- **Interactive TUI**: Manage projects and workspaces visually
|
|
694
|
+
- **Git worktrees**: Multiple branches checked out at once
|
|
695
|
+
- **Repo onboarding bundles**: Team setup steps + custom scripts
|
|
696
|
+
- **Secure remote access**: E2E encrypted terminal from anywhere
|
|
697
|
+
- **gitspace.sh hosting**: Instant subdomains like `yourname.gitspace.sh`
|
|
698
|
+
- **Identity-based auth**: Cryptographic keys, not passwords
|
|
699
|
+
|
|
700
|
+
Short code example:
|
|
701
|
+
```bash
|
|
702
|
+
# Install
|
|
703
|
+
bun install -g https://github.com/inkibra/gitspace.sh
|
|
704
|
+
|
|
705
|
+
# Launch the TUI
|
|
706
|
+
spaces
|
|
707
|
+
|
|
708
|
+
# Or via CLI
|
|
709
|
+
gssh add project # Add a GitHub repo
|
|
710
|
+
gssh add my-feature # Create a workspace
|
|
711
|
+
gssh switch my-feature
|
|
712
|
+
|
|
713
|
+
# Remote access (optional)
|
|
714
|
+
gssh auth login # Login to gitspace.sh
|
|
715
|
+
gssh host reserve myname # Get myname.gitspace.sh
|
|
716
|
+
gssh serve # Start serving
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
-------------------------
|
|
720
|
+
DOCS PAGE (with TOC)
|
|
721
|
+
-------------------------
|
|
722
|
+
|
|
723
|
+
Title: Documentation
|
|
724
|
+
|
|
725
|
+
Table of Contents (anchor links):
|
|
726
|
+
- Overview
|
|
727
|
+
- Quick Start
|
|
728
|
+
- Installation
|
|
729
|
+
- Local Workflow
|
|
730
|
+
- TUI Interface
|
|
731
|
+
- CLI Commands
|
|
732
|
+
- Custom Scripts
|
|
733
|
+
- Repo Config Bundles
|
|
734
|
+
- Remote Access
|
|
735
|
+
- gitspace.sh (Managed)
|
|
736
|
+
- Self-Hosted Relay
|
|
737
|
+
- Identity Management
|
|
738
|
+
- Access Control
|
|
739
|
+
- Configuration
|
|
740
|
+
- Troubleshooting
|
|
741
|
+
- Security
|
|
742
|
+
- Glossary
|
|
743
|
+
|
|
744
|
+
---
|
|
745
|
+
|
|
746
|
+
SECTION: Overview
|
|
747
|
+
|
|
748
|
+
GitSpace is a CLI tool for managing GitHub repository workspaces using git worktrees, with optional secure remote terminal access.
|
|
749
|
+
|
|
750
|
+
**Local Development:**
|
|
751
|
+
- Work on multiple branches simultaneously without stashing
|
|
752
|
+
- Interactive TUI for visual workspace management
|
|
753
|
+
- Convention-based scripts for automation
|
|
754
|
+
- Team onboarding via repo config bundles
|
|
755
|
+
|
|
756
|
+
**Remote Access:**
|
|
757
|
+
- E2E encrypted terminal access from any browser or CLI
|
|
758
|
+
- Zero-trust relay: routes traffic but cannot decrypt content
|
|
759
|
+
- Identity-based auth using Ed25519/X25519 cryptographic keys
|
|
760
|
+
- Instant hosting via gitspace.sh subdomains
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
SECTION: Quick Start
|
|
765
|
+
|
|
766
|
+
### 5-Minute Setup with gitspace.sh
|
|
767
|
+
|
|
768
|
+
```bash
|
|
769
|
+
# 1. Install
|
|
770
|
+
bun install -g https://github.com/inkibra/gitspace.sh
|
|
771
|
+
|
|
772
|
+
# 2. Create identity
|
|
773
|
+
gssh identity init
|
|
774
|
+
|
|
775
|
+
# 3. Login to gitspace.sh
|
|
776
|
+
gssh auth login
|
|
777
|
+
|
|
778
|
+
# 4. Reserve your subdomain
|
|
779
|
+
gssh host reserve yourname
|
|
780
|
+
|
|
781
|
+
# 5. Start serving
|
|
782
|
+
gssh serve
|
|
783
|
+
|
|
784
|
+
# 6. Access from browser: https://yourname.gitspace.sh
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### Local-Only Quick Start
|
|
788
|
+
|
|
789
|
+
```bash
|
|
790
|
+
# Install
|
|
791
|
+
bun install -g https://github.com/inkibra/gitspace.sh
|
|
792
|
+
|
|
793
|
+
# Authenticate GitHub
|
|
794
|
+
gh auth login
|
|
795
|
+
|
|
796
|
+
# Launch TUI
|
|
797
|
+
spaces
|
|
798
|
+
|
|
799
|
+
# Or via CLI:
|
|
800
|
+
gssh add project # Add a GitHub repo
|
|
801
|
+
gssh add my-feature # Create a workspace
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
---
|
|
805
|
+
|
|
806
|
+
SECTION: Installation
|
|
807
|
+
|
|
808
|
+
### Prerequisites
|
|
809
|
+
|
|
810
|
+
Required:
|
|
811
|
+
- [Bun](https://bun.sh) - JavaScript runtime
|
|
812
|
+
- [Git](https://git-scm.com/) - Version control
|
|
813
|
+
- [GitHub CLI](https://cli.github.com/) - `gh auth login` before using GitSpace
|
|
814
|
+
- [jq](https://stedolan.github.io/jq/) - JSON processing
|
|
815
|
+
|
|
816
|
+
Optional:
|
|
817
|
+
- [cloudflared](https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/) - For `gssh host` commands
|
|
818
|
+
|
|
819
|
+
### Install GitSpace
|
|
820
|
+
|
|
821
|
+
```bash
|
|
822
|
+
bun install -g https://github.com/inkibra/gitspace.sh
|
|
823
|
+
gssh --version
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### Authenticate GitHub CLI
|
|
827
|
+
|
|
828
|
+
```bash
|
|
829
|
+
gh auth login
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
---
|
|
833
|
+
|
|
834
|
+
SECTION: Local Workflow - TUI Interface
|
|
835
|
+
|
|
836
|
+
Launch the TUI with no arguments:
|
|
837
|
+
|
|
838
|
+
```bash
|
|
839
|
+
spaces
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
The TUI provides a two-panel interface:
|
|
843
|
+
- **Left panel**: Your projects
|
|
844
|
+
- **Right panel**: Workspaces in the selected project
|
|
845
|
+
|
|
846
|
+
**Key Bindings:**
|
|
847
|
+
| Key | Action |
|
|
848
|
+
|-----|--------|
|
|
849
|
+
| `Enter` | Select project / Open workspace |
|
|
850
|
+
| `Tab` | Switch between panels |
|
|
851
|
+
| `n` | New project / workspace |
|
|
852
|
+
| `d` | Delete selected item |
|
|
853
|
+
| `?` | Show help |
|
|
854
|
+
| `q` | Quit |
|
|
855
|
+
|
|
856
|
+
---
|
|
857
|
+
|
|
858
|
+
SECTION: Local Workflow - CLI Commands
|
|
859
|
+
|
|
860
|
+
### Projects
|
|
861
|
+
|
|
862
|
+
```bash
|
|
863
|
+
gssh add project # Add from GitHub (interactive)
|
|
864
|
+
gssh add project --org myorg # Filter by organization
|
|
865
|
+
gssh switch project myapp # Switch to a project
|
|
866
|
+
gssh list projects # List all projects
|
|
867
|
+
gssh remove project myapp # Remove a project
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
### Workspaces
|
|
871
|
+
|
|
872
|
+
```bash
|
|
873
|
+
gssh add my-feature # Create workspace
|
|
874
|
+
gssh add --from develop # Create from specific branch
|
|
875
|
+
gssh switch my-feature # Switch to workspace
|
|
876
|
+
gssh switch # Interactive selection
|
|
877
|
+
gssh list # List workspaces
|
|
878
|
+
gssh remove workspace my-feature
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### Other
|
|
882
|
+
|
|
883
|
+
```bash
|
|
884
|
+
gssh directory # Print current project path
|
|
885
|
+
gssh status # Show daemon statuses
|
|
886
|
+
```
|
|
887
|
+
|
|
888
|
+
---
|
|
889
|
+
|
|
890
|
+
SECTION: Local Workflow - Custom Scripts
|
|
891
|
+
|
|
892
|
+
GitSpace uses convention-based scripts in `~/gitspace/<project>/scripts/`:
|
|
893
|
+
|
|
894
|
+
```
|
|
895
|
+
scripts/
|
|
896
|
+
├── pre/ # Run before setup (once)
|
|
897
|
+
├── setup/ # Run on workspace creation (once)
|
|
898
|
+
├── select/ # Run every time workspace is opened
|
|
899
|
+
└── remove/ # Run before workspace deletion
|
|
900
|
+
```
|
|
901
|
+
|
|
902
|
+
**Rules:**
|
|
903
|
+
- Scripts must be executable (`chmod +x`)
|
|
904
|
+
- Run alphabetically (use `01-`, `02-` prefixes)
|
|
905
|
+
- Working directory: the workspace
|
|
906
|
+
- Arguments: `$1` = workspace name, `$2` = repository
|
|
907
|
+
|
|
908
|
+
**Example:**
|
|
909
|
+
```bash
|
|
910
|
+
#!/bin/bash
|
|
911
|
+
# scripts/select/01-status.sh
|
|
912
|
+
echo "Switching to: $1"
|
|
913
|
+
git fetch origin
|
|
914
|
+
git status
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
---
|
|
918
|
+
|
|
919
|
+
SECTION: Local Workflow - Repo Config Bundles
|
|
920
|
+
|
|
921
|
+
Bundles allow teams to share onboarding configurations. Place in `.gitspace-config/`:
|
|
922
|
+
|
|
923
|
+
```
|
|
924
|
+
.gitspace-config/
|
|
925
|
+
├── gitspace-bundle.json # Manifest
|
|
926
|
+
├── pre/ # Pre-setup scripts
|
|
927
|
+
├── setup/ # Setup scripts
|
|
928
|
+
└── select/ # Select scripts
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
**Manifest example:**
|
|
932
|
+
```json
|
|
933
|
+
{
|
|
934
|
+
"version": "1.0",
|
|
935
|
+
"name": "my-app-bundle",
|
|
936
|
+
"onboarding": [
|
|
937
|
+
{ "id": "node", "type": "confirm", "title": "Node.js", "checkCommand": "node" },
|
|
938
|
+
{ "id": "api-key", "type": "secret", "title": "API Key", "configKey": "apiKey" }
|
|
939
|
+
]
|
|
940
|
+
}
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
**Step types:**
|
|
944
|
+
| Type | Purpose | Storage |
|
|
945
|
+
|------|---------|---------|
|
|
946
|
+
| `info` | Display information | N/A |
|
|
947
|
+
| `confirm` | Verify installation | N/A |
|
|
948
|
+
| `secret` | Sensitive values | OS Keychain |
|
|
949
|
+
| `input` | Plain text | Config file |
|
|
950
|
+
|
|
951
|
+
**Using values in scripts:**
|
|
952
|
+
```bash
|
|
953
|
+
echo "Team: $SPACE_VALUE_TEAMNAME"
|
|
954
|
+
echo "Has API key: $SPACE_SECRET_APIKEY"
|
|
955
|
+
```
|
|
956
|
+
|
|
957
|
+
---
|
|
958
|
+
|
|
959
|
+
SECTION: Remote Access - gitspace.sh (Managed)
|
|
960
|
+
|
|
961
|
+
The easiest way to get remote access:
|
|
962
|
+
|
|
963
|
+
```bash
|
|
964
|
+
# 1. Create identity
|
|
965
|
+
gssh identity init
|
|
966
|
+
|
|
967
|
+
# 2. Login with GitHub
|
|
968
|
+
gssh auth login
|
|
969
|
+
|
|
970
|
+
# 3. Reserve subdomain
|
|
971
|
+
gssh host reserve yourname
|
|
972
|
+
|
|
973
|
+
# 4. Start serving
|
|
974
|
+
gssh serve
|
|
975
|
+
|
|
976
|
+
# 5. Access: https://yourname.gitspace.sh
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
**Manage subdomains:**
|
|
980
|
+
```bash
|
|
981
|
+
gssh host list # List your subdomains
|
|
982
|
+
gssh host set-primary name # Set primary
|
|
983
|
+
gssh host release name # Release subdomain
|
|
984
|
+
gssh host status # Show status
|
|
985
|
+
```
|
|
986
|
+
|
|
987
|
+
---
|
|
988
|
+
|
|
989
|
+
SECTION: Remote Access - Self-Hosted Relay
|
|
990
|
+
|
|
991
|
+
For complete control:
|
|
992
|
+
|
|
993
|
+
**1. Start relay:**
|
|
994
|
+
```bash
|
|
995
|
+
gssh relay start --port 4480
|
|
996
|
+
```
|
|
997
|
+
|
|
998
|
+
**2. Authorize machine:**
|
|
999
|
+
```bash
|
|
1000
|
+
gssh identity init --label "My Mac"
|
|
1001
|
+
gssh identity show
|
|
1002
|
+
|
|
1003
|
+
# On the relay host
|
|
1004
|
+
gssh relay authorize gssh-pub:<keys> --label "My Mac"
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
**3. Serve:**
|
|
1008
|
+
```bash
|
|
1009
|
+
gssh serve --relay ws://localhost:4480/ws
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
**4. Create invite:**
|
|
1013
|
+
```bash
|
|
1014
|
+
gssh share create
|
|
1015
|
+
# Output: https://gitspace.sh/join#<TOKEN>
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
**5. Connect from client:**
|
|
1019
|
+
```bash
|
|
1020
|
+
gssh identity init --label "Laptop"
|
|
1021
|
+
gssh connect https://gitspace.sh/join#<TOKEN>
|
|
1022
|
+
```
|
|
1023
|
+
|
|
1024
|
+
---
|
|
1025
|
+
|
|
1026
|
+
SECTION: Remote Access - Identity Management
|
|
1027
|
+
|
|
1028
|
+
Every machine and client has a cryptographic identity:
|
|
1029
|
+
|
|
1030
|
+
```bash
|
|
1031
|
+
gssh identity init [--label <name>] [--force]
|
|
1032
|
+
gssh identity show [--fingerprint] [--json]
|
|
1033
|
+
```
|
|
1034
|
+
|
|
1035
|
+
Identity storage: `~/gitspace/.identity/`
|
|
1036
|
+
|
|
1037
|
+
---
|
|
1038
|
+
|
|
1039
|
+
SECTION: Remote Access - Access Control
|
|
1040
|
+
|
|
1041
|
+
**Grant access:**
|
|
1042
|
+
```bash
|
|
1043
|
+
gssh access add gssh-pub:<keys> --label "Brad's Phone"
|
|
1044
|
+
```
|
|
1045
|
+
|
|
1046
|
+
**Manage access:**
|
|
1047
|
+
```bash
|
|
1048
|
+
gssh access list [--json]
|
|
1049
|
+
gssh access remove "Brad's Phone"
|
|
1050
|
+
gssh access remove <key-prefix> --force
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
**Connect without invite (pre-authorized):**
|
|
1054
|
+
```bash
|
|
1055
|
+
gssh --relay ws://relay.example.com/ws
|
|
1056
|
+
```
|
|
1057
|
+
|
|
1058
|
+
---
|
|
1059
|
+
|
|
1060
|
+
SECTION: Configuration
|
|
1061
|
+
|
|
1062
|
+
### Global Config
|
|
1063
|
+
|
|
1064
|
+
`~/gitspace/.config.json`:
|
|
1065
|
+
```json
|
|
1066
|
+
{
|
|
1067
|
+
"currentProject": "my-app",
|
|
1068
|
+
"projectsDir": "/Users/username/spaces",
|
|
1069
|
+
"defaultBaseBranch": "main"
|
|
1070
|
+
}
|
|
1071
|
+
```
|
|
1072
|
+
|
|
1073
|
+
### Project Config
|
|
1074
|
+
|
|
1075
|
+
`~/gitspace/<project>/.config.json`:
|
|
1076
|
+
```json
|
|
1077
|
+
{
|
|
1078
|
+
"name": "my-app",
|
|
1079
|
+
"repository": "myorg/my-app",
|
|
1080
|
+
"baseBranch": "main"
|
|
1081
|
+
}
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
### Environment Variables
|
|
1085
|
+
|
|
1086
|
+
| Variable | Description | Default |
|
|
1087
|
+
|----------|-------------|---------|
|
|
1088
|
+
| `RELAY_PORT` | Relay port | `4480` |
|
|
1089
|
+
| `SPACES_CURRENT_PROJECT` | Override project | Config |
|
|
1090
|
+
|
|
1091
|
+
---
|
|
1092
|
+
|
|
1093
|
+
SECTION: Troubleshooting
|
|
1094
|
+
|
|
1095
|
+
**"No identity found"**
|
|
1096
|
+
```bash
|
|
1097
|
+
gssh identity init --label "My Device"
|
|
1098
|
+
```
|
|
1099
|
+
|
|
1100
|
+
**"Machine offline"**
|
|
1101
|
+
- Ensure `gssh serve` is running
|
|
1102
|
+
- Check relay connectivity
|
|
1103
|
+
- Verify the machine is authorized on the relay
|
|
1104
|
+
|
|
1105
|
+
**"Client not authorized"**
|
|
1106
|
+
- Use an invite: `gssh share create`
|
|
1107
|
+
- Or add public key: `gssh access add <key>`
|
|
1108
|
+
|
|
1109
|
+
**"Invite expired"**
|
|
1110
|
+
- Create new invite: `gssh share create --expires 7d`
|
|
1111
|
+
|
|
1112
|
+
**"GitHub CLI not authenticated"**
|
|
1113
|
+
```bash
|
|
1114
|
+
gh auth login
|
|
1115
|
+
```
|
|
1116
|
+
|
|
1117
|
+
---
|
|
1118
|
+
|
|
1119
|
+
SECTION: Security
|
|
1120
|
+
|
|
1121
|
+
**End-to-end encrypted:** Terminal traffic encrypted with AES-256-GCM. Relay cannot decrypt.
|
|
1122
|
+
|
|
1123
|
+
**Cryptographic identity:** Ed25519 signing + X25519 key exchange. No passwords.
|
|
1124
|
+
|
|
1125
|
+
**X3DH handshake:** Session keys derived per-connection.
|
|
1126
|
+
|
|
1127
|
+
**Current limitations:**
|
|
1128
|
+
- Client proof-of-possession for identity signing keys is not fully enforced (ACL spoofing risk if attacker learns authorized public key)
|
|
1129
|
+
- Permission flags not fully enforced server-side after handshake; "view-only" is intended behavior, not strict guarantee
|
|
1130
|
+
|
|
1131
|
+
---
|
|
1132
|
+
|
|
1133
|
+
SECTION: Glossary
|
|
1134
|
+
|
|
1135
|
+
| Term | Definition |
|
|
1136
|
+
|------|------------|
|
|
1137
|
+
| Machine | Device running `gssh serve` |
|
|
1138
|
+
| Client | Device connecting via browser or CLI |
|
|
1139
|
+
| Relay | WebSocket router (default: `wss://relay.gitspace.sh`) |
|
|
1140
|
+
| Relay Identity | Ed25519 keypair used by the relay to sign messages and challenges |
|
|
1141
|
+
| Authorized Machine | Machine public key approved to register with a relay |
|
|
1142
|
+
| Identity | Ed25519 + X25519 keypairs |
|
|
1143
|
+
| Invite | Signed token for first connection |
|
|
1144
|
+
| ACL | Access Control List |
|
|
1145
|
+
| X3DH | Key exchange handshake |
|
|
1146
|
+
| Worktree | Git feature for multiple working directories |
|
|
1147
|
+
| Bundle | Repo onboarding configuration |
|
|
1148
|
+
|
|
1149
|
+
============================================================
|
|
1150
|
+
J) FINAL CHECKLIST
|
|
1151
|
+
============================================================
|
|
1152
|
+
|
|
1153
|
+
Before finishing, verify:
|
|
1154
|
+
|
|
1155
|
+
- [ ] Every command uses exact subcommand names (especially `gssh relay start`, `gssh serve`)
|
|
1156
|
+
- [ ] Defaults match:
|
|
1157
|
+
- [ ] Relay port: 4480
|
|
1158
|
+
- [ ] Serve relay default: `wss://relay.gitspace.sh`
|
|
1159
|
+
- [ ] Share URL: `https://gitspace.sh/join#...`
|
|
1160
|
+
- [ ] Share expires default: 24h
|
|
1161
|
+
- [ ] Security notes are conservative and include "current limitations" callout
|
|
1162
|
+
- [ ] No mention of non-existent features (dashboards, OAuth flows on relay, etc.)
|
|
1163
|
+
- [ ] Custom scripts and bundles are documented
|
|
1164
|
+
- [ ] All troubleshooting items have solutions
|
|
1165
|
+
- [ ] Glossary includes all key terms
|
|
1166
|
+
|
|
1167
|
+
Now apply these changes to the Docs pages in the Figma site.
|