Skip to content
This repository was archived by the owner on Jun 10, 2026. It is now read-only.

feat: add workbench-server — mobile PWA for agentic coding#35

Closed
Blaise1030 wants to merge 1 commit into
mainfrom
claude/ssh-pwa-agentic-coding-bzltG
Closed

feat: add workbench-server — mobile PWA for agentic coding#35
Blaise1030 wants to merge 1 commit into
mainfrom
claude/ssh-pwa-agentic-coding-bzltG

Conversation

@Blaise1030

Copy link
Copy Markdown
Owner

New standalone Node.js server package (apps/server) that enables
coding from a phone browser. Provides:

  • WebSocket-based terminal (xterm.js + node-pty, sessions persist across reconnects)
  • Mobile-first Vue 3 PWA with installable manifest + Workbox service worker
  • Touch toolbar above keyboard (Esc, Tab, Ctrl+C, arrows)
  • Git workflow UI: stage/unstage, commit, push, fetch, inline diffs in a bottom sheet
  • Agent launcher for Claude Code, Codex, Cursor, Gemini via PTY sessions
  • Port preview proxy (/proxy/:port/*) for viewing running dev servers on phone
  • Static bearer token auth with QR code printed on server start
  • visualViewport keyboard height tracking so terminal adapts to iOS/Android keyboard

Server: Fastify v5 + @fastify/websocket + http-proxy
Client: Vue 3 + Vite + vite-plugin-pwa + TanStack Query + xterm.js

Run with: pnpm start:server

Comment thread apps/server/src/server/main.ts Outdated
Comment on lines +49 to +54
app.addHook("preHandler", async (request, reply) => {
const path = request.url.split("?")[0] ?? "";
if (path.startsWith("/api/") || path === "/ws/terminal") {
await authPreHandler(request, reply);
}
});
private async diffNewPathOnDisk(cwd: string, file: string): Promise<string> {
const abs = resolve(cwd, file);
try {
if (!statSync(abs).isFile()) return "";
if (depth > maxDepth) return;
let entries: import("node:fs").Dirent[];
try {
entries = readdirSync(dir, { withFileTypes: true }) as import("node:fs").Dirent[];
this.walkDir(root, abs, depth + 1, maxDepth, out);
} else if (entry.isFile()) {
try {
const stat = statSync(abs);
Comment on lines +5 to +16
<option v-for="a in agents" :key="a" :value="a">{{ a }}</option>
</select>
<button class="launch-btn" :disabled="!prompt.trim() || loading" @click="onLaunch">
<span v-if="loading">Starting…</span>
<span v-else>Run</span>
</button>
</div>
<textarea
v-model="prompt"
class="prompt-input"
placeholder="Describe what you want the agent to do…"
rows="4"

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dasd

Comment on lines +62 to +71
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}

.launcher-row {
display: flex;
gap: 8px;
}

.agent-select {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adsad

@ghost ghost force-pushed the claude/ssh-pwa-agentic-coding-bzltG branch from 7c2f058 to 0bd027d Compare May 27, 2026 19:40
@Blaise1030 Blaise1030 closed this May 30, 2026
@Blaise1030 Blaise1030 deleted the claude/ssh-pwa-agentic-coding-bzltG branch May 30, 2026 15:29
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants