Commit Graph
23 Commits
Author SHA1 Message Date
Gabriel Brown a640b5cb94 fix(terminal): bun-safe exec attach, box self-heal, surfaced errors
The workspace terminal died everywhere: bun's node:http client never
emits the client 'upgrade' event (it surfaces the 101 as a plain
response), so docker-modem's exec.start({hijack:true}) waited forever —
a connected WebSocket with no bytes flowing (prod), or an instant close
when the socket was unreachable (dev). The pre-Phase-1 bridge avoided
dockerode attach for exactly this reason; the real-TTY-resize rewrite
reintroduced it.

- runtime/exec-stream.ts: speak the exec-start HTTP upgrade over a raw
  net socket (docker and podman both answer 101 UPGRADED). Works under
  bun and node; honors the modem's socketPath/host:port. The stream is
  returned paused so the first screen paint can't race the caller's
  data handler. Exec create/resize stay on dockerode (plain POSTs).
- user-container.ts: acquireUserBox re-ensures the container on every
  acquire instead of trusting a cached "initialized" flag, so a box
  removed behind the worker's back (manual rm, another instance's
  reaper) is recreated instead of bricking terminals and agent turns
  until restart.
- terminal.ts: bridge failures are logged and close the WebSocket with
  a clamped human-readable reason instead of a silent catch;
  xterm-session.tsx displays that reason instead of a mute
  "Session ended". Also roomier terminal line spacing (1.2 -> 1.35).
2026-07-12 22:14:37 -04:00
Gabriel Brown f89dfce3b8 fix(workspace): scroll/diff-race/recovery/editor/mobile polish 2026-07-11 17:59:25 -04:00
Gabriel Brown a5bc0434f3 chore: fix eslint errors introduced across phases 1-3 2026-07-11 13:27:23 -04:00
Gabriel Brown 12b1c98cfc feat(web): terminal copy-on-select toggle and web-links polish
Wire copy-on-select in XtermSession (shared by the workspace terminal
and the /machine terminal): a header checkbox toggles the behavior and
persists to localStorage under spoon.terminal.copyOnSelect. On mount the
stored value takes precedence over the copyOnSelect prop default. When
enabled, onSelectionChange copies the current selection via
navigator.clipboard.writeText — guarded (empty selections skipped;
clipboard-unavailable/denied errors swallowed). The handler reads the
toggle through a ref so live flips apply without reconnecting.

WebLinksAddon remains loaded so printed URLs are clickable.

Manual verification: in /machine and a workspace terminal, enabling
copy-on-select and selecting text places it on the clipboard; a printed
URL is clickable and opens in a new tab.
2026-07-11 13:17:46 -04:00
Gabriel Brown 148e060a9b feat(web): persistent workspace terminal across tab switches 2026-07-11 13:05:49 -04:00
Gabriel Brown 33e7732566 feat(web): /machine dev-box page with status, terminal, and home file browser 2026-07-11 12:57:13 -04:00
Gabriel Brown ea56b29453 refactor(web): extract reusable XtermSession from WorkspaceTerminal 2026-07-11 12:43:08 -04:00
Gabriel Brown 926008fd3a fix(workspace): skip queries for missing jobs 2026-07-10 17:24:32 -04:00
Gabriel Brown 2beeeb1732 fix(app): handle nullable detail consumers 2026-07-10 17:24:32 -04:00
Gabriel Brown feb3723753 fix(terminal): preserve animation-frame first fit 2026-07-10 17:06:33 -04:00
Gabriel Brown 75d06394ce fix(terminal): refit after fonts load 2026-07-10 17:06:33 -04:00
Gabriel Brown c103430c7d Self-host VictorMono Nerd Font icons for the terminal + editor
- Add Symbols-Only Nerd Font Mono (woff2) under public/fonts; @font-face scoped
  by unicode-range to the Nerd Font glyph ranges, so the ~1.1MB file only loads
  when an icon actually renders (latin text stays on Victor Mono)
- Terminal + editor font stacks fall back to it for icons; terminal prewarms it
  and repaints so powerline/oh-my-posh/eza/nvim icons show
- No server/env changes; ships in the spoon-next image (public/)
2026-06-24 10:17:25 -04:00
Gabriel Brown 15407e7e9c Workspace Terminal tab: xterm front end + short-lived token route
- New Terminal tab in the workspace shell, backed by xterm.js, that connects
  to the worker's PTY WebSocket using a short-lived token minted by
  /api/agent-jobs/:id/terminal-token (owner-auth'd, never exposes the worker
  secret to the browser)
- Site-matched xterm theme (light/dark, live theme switching), Victor Mono,
  binary stdin + JSON resize protocol, reconnect, graceful 'not configured'
  state when NEXT_PUBLIC_SPOON_AGENT_WORKER_WS_URL is unset
- env: NEXT_PUBLIC_SPOON_AGENT_WORKER_WS_URL (client), SPOON_AGENT_TERMINAL_SECRET
2026-06-24 08:23:58 -04:00
Gabriel Brown 1072cf10cd Editor: site-matched theme, Victor Mono font, no false TS errors
- Add spoon-dark/spoon-light Monaco themes built from the site's design tokens
  (teal --primary accent), switched by next-themes resolvedTheme
- Use Victor Mono (with ligatures + italic comments) for the editor font
- Disable Monaco's in-browser TS *semantic* diagnostics, which were false
  positives (no node_modules / path aliases in the browser) e.g. 'Cannot find
  module ~/server/auth'; keep real syntax-error reporting
2026-06-24 07:45:24 -04:00
Gabriel Brown ae90681d9b Add workspace loading state; auto-refresh diff on agent changes
- Gate the tree/diff/status loads (and 5s poll) on workspaceStatus being
  active/idle, so we no longer hammer the 'workspace is not active' endpoint
  while a worker is still picking up the job
- Show a 'Setting up your workspace…' pending state instead of surfacing
  startup as a console error / stale-workspace recovery box; escalate to a
  softer 'still waiting' hint after 90s if no worker picks it up
- Auto-reload the diff and file tree (debounced) whenever the agent records a
  workspace change or a turn starts/ends, so diffs appear without a manual
  Refresh
- The recovery box now only appears for a genuinely lost workspace (Convex
  reports active but the worker can't reach it)
2026-06-24 07:29:38 -04:00
Gabriel Brown bb471a0917 Improve workspace/chat diff viewer with syntax highlighting & per-file view
Replace the raw single-blob diff dump (Monaco, language=diff) and the plain
<pre> file diffs in chat with @git-diff-view/react:
- Parse the unified git diff into structured per-file entries (status,
  +/- counts, binary detection) via parseDiffFiles()
- Workspace Diff tab: collapsible per-file cards with status badges, line
  counts, syntax highlighting, and a Unified/Split toggle
- Agent chat: render each change's diff highlighted instead of plain text
- Theme follows next-themes resolvedTheme (light/dark)
2026-06-24 07:08:43 -04:00
Gabriel Brown c3d265d428 Fix worker 2026-06-23 20:35:01 -04:00
Gabriel Brown 5567a4be95 allow users to delete threads from spoons details page
Build and Push Spoon Images / quality (push) Successful in 2m36s
Build and Push Spoon Images / build-images (push) Successful in 9m21s
2026-06-23 16:00:34 -04:00
Gabriel Brown a6f7ea7f78 Clean up old stuff & fix ui errors
Build and Push Spoon Images / quality (push) Successful in 2m22s
Build and Push Spoon Images / build-images (push) Successful in 23m10s
2026-06-23 14:57:05 -04:00
Gabriel Brown d207b8b0b8 Add features & update project
Build and Push Spoon Images / quality (push) Successful in 1m41s
Build and Push Spoon Images / build-images (push) Successful in 7m4s
2026-06-23 02:06:58 -04:00
Gabriel Brown fe72fc2957 Add features & update project 2026-06-23 01:46:08 -04:00
Gabriel Brown 930fbf5965 Try to fix workers and workspace
Build and Push Spoon Images / quality (push) Successful in 1m40s
Build and Push Spoon Images / build-images (push) Successful in 7m0s
2026-06-22 23:17:27 -04:00
Gabriel Brown 206b64176b Move to threads based system. 2026-06-22 10:37:26 -04:00