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,133 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Test router + session architecture (single client per session)
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ROUTER_SOCKET,
|
|
8
|
+
type RouterCommand,
|
|
9
|
+
type RouterResponse,
|
|
10
|
+
encodeControl,
|
|
11
|
+
isControl,
|
|
12
|
+
decodeControl,
|
|
13
|
+
type SessionEvent,
|
|
14
|
+
} from "./protocol";
|
|
15
|
+
|
|
16
|
+
async function routerCommand(cmd: RouterCommand): Promise<RouterResponse> {
|
|
17
|
+
return new Promise(async (resolve, reject) => {
|
|
18
|
+
const socket = await Bun.connect({
|
|
19
|
+
unix: ROUTER_SOCKET,
|
|
20
|
+
socket: {
|
|
21
|
+
data(socket, data) {
|
|
22
|
+
resolve(JSON.parse(data.toString()));
|
|
23
|
+
socket.end();
|
|
24
|
+
},
|
|
25
|
+
error(socket, error) {
|
|
26
|
+
reject(error);
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
socket.write(JSON.stringify(cmd));
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log("=== Testing Router Architecture (Single Client) ===\n");
|
|
35
|
+
|
|
36
|
+
// 1. Create a session
|
|
37
|
+
console.log("1. Create session test/workspace-1");
|
|
38
|
+
const create1 = await routerCommand({
|
|
39
|
+
type: "create",
|
|
40
|
+
project: "test",
|
|
41
|
+
workspace: "workspace-1",
|
|
42
|
+
cwd: process.cwd()
|
|
43
|
+
});
|
|
44
|
+
console.log(" Response:", create1.type);
|
|
45
|
+
if (create1.type !== "created") process.exit(1);
|
|
46
|
+
const session1 = create1.session;
|
|
47
|
+
|
|
48
|
+
// 2. Connect a client
|
|
49
|
+
console.log("\n2. Connect client to session");
|
|
50
|
+
let client1Kicked = false;
|
|
51
|
+
const client1 = await Bun.connect({
|
|
52
|
+
unix: session1.socketPath,
|
|
53
|
+
socket: {
|
|
54
|
+
data(socket, data) {
|
|
55
|
+
const buf = Buffer.from(data);
|
|
56
|
+
if (isControl(buf)) {
|
|
57
|
+
const event = decodeControl(buf) as SessionEvent;
|
|
58
|
+
if (event.type === "kicked") {
|
|
59
|
+
client1Kicked = true;
|
|
60
|
+
console.log(" Client 1 received: kicked");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
await Bun.sleep(100);
|
|
67
|
+
|
|
68
|
+
// 3. Check attached state
|
|
69
|
+
console.log("\n3. Check session is attached");
|
|
70
|
+
const list1 = await routerCommand({ type: "list" });
|
|
71
|
+
const attached = (list1 as any).sessions[0]?.attached;
|
|
72
|
+
console.log(" Attached:", attached ? "✓" : "✗");
|
|
73
|
+
|
|
74
|
+
// 4. Try to create same session again (should return already-attached)
|
|
75
|
+
console.log("\n4. Try to create same session again");
|
|
76
|
+
const create2 = await routerCommand({
|
|
77
|
+
type: "create",
|
|
78
|
+
project: "test",
|
|
79
|
+
workspace: "workspace-1",
|
|
80
|
+
cwd: process.cwd()
|
|
81
|
+
});
|
|
82
|
+
console.log(" Response:", create2.type, create2.type === "already-attached" ? "✓" : "✗");
|
|
83
|
+
|
|
84
|
+
// 5. Take over with kick
|
|
85
|
+
console.log("\n5. Take over session (kick client 1)");
|
|
86
|
+
const attach = await routerCommand({
|
|
87
|
+
type: "attach",
|
|
88
|
+
sessionId: session1.id,
|
|
89
|
+
mode: "take-over"
|
|
90
|
+
});
|
|
91
|
+
console.log(" Response:", attach.type);
|
|
92
|
+
await Bun.sleep(100);
|
|
93
|
+
console.log(" Client 1 was kicked:", client1Kicked ? "✓" : "✗");
|
|
94
|
+
|
|
95
|
+
// 6. Connect new client after kick
|
|
96
|
+
console.log("\n6. Connect new client after kick");
|
|
97
|
+
const client2 = await Bun.connect({
|
|
98
|
+
unix: session1.socketPath,
|
|
99
|
+
socket: { data() {} }
|
|
100
|
+
});
|
|
101
|
+
await Bun.sleep(100);
|
|
102
|
+
|
|
103
|
+
// 7. Detach client 2, check session still exists
|
|
104
|
+
console.log("\n7. Detach client 2");
|
|
105
|
+
client2.write(encodeControl({ type: "detach" }));
|
|
106
|
+
await Bun.sleep(100);
|
|
107
|
+
|
|
108
|
+
const list2 = await routerCommand({ type: "list" });
|
|
109
|
+
const stillExists = (list2 as any).sessions.length === 1;
|
|
110
|
+
const nowDetached = !(list2 as any).sessions[0]?.attached;
|
|
111
|
+
console.log(" Session still exists:", stillExists ? "✓" : "✗");
|
|
112
|
+
console.log(" Now detached:", nowDetached ? "✓" : "✗");
|
|
113
|
+
|
|
114
|
+
// 8. Reattach to detached session (no prompt needed)
|
|
115
|
+
console.log("\n8. Reattach to detached session");
|
|
116
|
+
const create3 = await routerCommand({
|
|
117
|
+
type: "create",
|
|
118
|
+
project: "test",
|
|
119
|
+
workspace: "workspace-1",
|
|
120
|
+
cwd: process.cwd()
|
|
121
|
+
});
|
|
122
|
+
console.log(" Response:", create3.type, create3.type === "created" ? "✓" : "✗");
|
|
123
|
+
|
|
124
|
+
// 9. Clean up
|
|
125
|
+
console.log("\n9. Kill session");
|
|
126
|
+
const kill = await routerCommand({ type: "kill", sessionId: session1.id });
|
|
127
|
+
console.log(" Response:", kill.type);
|
|
128
|
+
|
|
129
|
+
const list3 = await routerCommand({ type: "list" });
|
|
130
|
+
console.log(" Sessions remaining:", (list3 as any).sessions.length);
|
|
131
|
+
|
|
132
|
+
console.log("\n=== Test Complete ===");
|
|
133
|
+
process.exit(0);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unix socket bandwidth test
|
|
3
|
+
* How much can we push through a single socket?
|
|
4
|
+
*/
|
|
5
|
+
import { unlinkSync } from "fs";
|
|
6
|
+
|
|
7
|
+
const SOCKET_PATH = "/tmp/spaces-bw.sock";
|
|
8
|
+
try { unlinkSync(SOCKET_PATH); } catch {}
|
|
9
|
+
|
|
10
|
+
const CHUNK_SIZE = 64 * 1024; // 64KB chunks
|
|
11
|
+
const TEST_DURATION_MS = 2000;
|
|
12
|
+
|
|
13
|
+
let totalBytes = 0;
|
|
14
|
+
let messageCount = 0;
|
|
15
|
+
|
|
16
|
+
const server = Bun.listen({
|
|
17
|
+
unix: SOCKET_PATH,
|
|
18
|
+
socket: {
|
|
19
|
+
data(socket, data) {
|
|
20
|
+
totalBytes += data.byteLength;
|
|
21
|
+
messageCount++;
|
|
22
|
+
// Echo back (simulates bidirectional)
|
|
23
|
+
socket.write(data);
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
await Bun.sleep(50);
|
|
29
|
+
|
|
30
|
+
const chunk = Buffer.alloc(CHUNK_SIZE, "x");
|
|
31
|
+
let clientReceived = 0;
|
|
32
|
+
|
|
33
|
+
const client = await Bun.connect({
|
|
34
|
+
unix: SOCKET_PATH,
|
|
35
|
+
socket: {
|
|
36
|
+
data(socket, data) {
|
|
37
|
+
clientReceived += data.byteLength;
|
|
38
|
+
},
|
|
39
|
+
drain(socket) {
|
|
40
|
+
// Socket ready for more data - keep pumping
|
|
41
|
+
socket.write(chunk);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
console.log("Testing Unix socket bandwidth (bidirectional)...\n");
|
|
47
|
+
|
|
48
|
+
const start = performance.now();
|
|
49
|
+
|
|
50
|
+
// Prime the pump
|
|
51
|
+
for (let i = 0; i < 100; i++) {
|
|
52
|
+
client.write(chunk);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await Bun.sleep(TEST_DURATION_MS);
|
|
56
|
+
|
|
57
|
+
const elapsed = (performance.now() - start) / 1000;
|
|
58
|
+
const serverThroughput = (totalBytes / 1024 / 1024) / elapsed;
|
|
59
|
+
const clientThroughput = (clientReceived / 1024 / 1024) / elapsed;
|
|
60
|
+
|
|
61
|
+
console.log("=== Single Socket Bandwidth ===");
|
|
62
|
+
console.log(`Server received: ${(totalBytes / 1024 / 1024).toFixed(0)} MB`);
|
|
63
|
+
console.log(`Client received: ${(clientReceived / 1024 / 1024).toFixed(0)} MB`);
|
|
64
|
+
console.log(`Server throughput: ${serverThroughput.toFixed(0)} MB/s`);
|
|
65
|
+
console.log(`Client throughput: ${clientThroughput.toFixed(0)} MB/s`);
|
|
66
|
+
console.log(`Messages: ${messageCount}`);
|
|
67
|
+
console.log(`Avg chunk: ${(totalBytes / messageCount / 1024).toFixed(1)} KB`);
|
|
68
|
+
|
|
69
|
+
// Context
|
|
70
|
+
console.log("\n=== Context ===");
|
|
71
|
+
console.log(`4K terminal @ 60fps: ~${(4000 * 60 * 60 / 1024 / 1024).toFixed(1)} MB/s worst case`);
|
|
72
|
+
console.log(`Typical terminal use: < 1 MB/s`);
|
|
73
|
+
console.log(`10 concurrent sessions: < 10 MB/s`);
|
|
74
|
+
|
|
75
|
+
server.stop();
|
|
76
|
+
client.end();
|
|
77
|
+
try { unlinkSync(SOCKET_PATH); } catch {}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Homebrew formula for GitSpace CLI (gssh)
|
|
2
|
+
#
|
|
3
|
+
# To install from a tap:
|
|
4
|
+
# brew tap inkibra/gitspace
|
|
5
|
+
# brew install gitspace
|
|
6
|
+
#
|
|
7
|
+
# Or install directly from this file:
|
|
8
|
+
# brew install --formula homebrew/gitspace.rb
|
|
9
|
+
|
|
10
|
+
class Gitspace < Formula
|
|
11
|
+
desc "CLI for managing GitHub workspaces with git worktrees and secure remote terminal access"
|
|
12
|
+
homepage "https://gitspace.sh"
|
|
13
|
+
version "0.1.5"
|
|
14
|
+
license "SEE LICENSE IN LICENSE"
|
|
15
|
+
|
|
16
|
+
on_macos do
|
|
17
|
+
on_arm do
|
|
18
|
+
url "https://github.com/inkibra/gitspace.sh/releases/download/v#{version}/gssh-darwin-arm64.tar.gz"
|
|
19
|
+
# sha256 "REPLACE_WITH_ACTUAL_SHA256"
|
|
20
|
+
end
|
|
21
|
+
on_intel do
|
|
22
|
+
url "https://github.com/inkibra/gitspace.sh/releases/download/v#{version}/gssh-darwin-x64.tar.gz"
|
|
23
|
+
# sha256 "REPLACE_WITH_ACTUAL_SHA256"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
on_linux do
|
|
28
|
+
on_arm do
|
|
29
|
+
url "https://github.com/inkibra/gitspace.sh/releases/download/v#{version}/gssh-linux-arm64.tar.gz"
|
|
30
|
+
# sha256 "REPLACE_WITH_ACTUAL_SHA256"
|
|
31
|
+
end
|
|
32
|
+
on_intel do
|
|
33
|
+
url "https://github.com/inkibra/gitspace.sh/releases/download/v#{version}/gssh-linux-x64.tar.gz"
|
|
34
|
+
# sha256 "REPLACE_WITH_ACTUAL_SHA256"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def install
|
|
39
|
+
bin.install "gssh"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
test do
|
|
43
|
+
assert_match "gssh", shell_output("#{bin}/gssh --version")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
This Figma Make file includes components from [shadcn/ui](https://ui.shadcn.com/) used under [MIT license](https://github.com/shadcn-ui/ui/blob/main/LICENSE.md).
|
|
2
|
+
|
|
3
|
+
This Figma Make file includes photos from [Unsplash](https://unsplash.com) used under [license](https://unsplash.com/license).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
# Landing Page Design
|
|
3
|
+
|
|
4
|
+
This is a code bundle for Landing Page Design. The original project is available at https://www.figma.com/design/X1VjullY3NR4Kh5s63m6JS/Landing-Page-Design.
|
|
5
|
+
|
|
6
|
+
## Running the code
|
|
7
|
+
|
|
8
|
+
Run `npm i` to install the dependencies.
|
|
9
|
+
|
|
10
|
+
Run `npm run dev` to start the development server.
|
|
11
|
+
|