Skip to content

Feat/orcabotcli - #245

Merged
robdmac merged 6 commits into
mainfrom
feat/orcabotcli
Jun 20, 2026
Merged

robdmac merged 6 commits into
mainfrom
feat/orcabotcli

Conversation

@robdmac

@robdmac robdmac commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

No description provided.

robdmac and others added 6 commits June 20, 2026 15:37
Adds an `orcabot` CLI binary (second bin in the desktop crate) that controls the
stack from the terminal, plus a headless mode for the desktop app.

- Desktop app: ORCABOT_DESKTOP_HEADLESS=1 runs all services (d1-shim, workerd,
  VM) with no GUI — window starts hidden (tauri.conf.json visible=false) and is
  shown only in GUI mode; headless drops the macOS dock icon (Accessory policy).
- orcabot CLI:
  - up    — launch the desktop binary detached/headless, wait for control plane
            (:8787) + sandbox (:8080) health.
  - down  — SIGINT the headless process → the app's clean shutdown (stops the VM).
  - status— control plane / sandbox / frontend health.
  - exec  — run a shell command in the sandbox VM via /debug/exec, using the
            per-boot token from the VM console; stdout/stderr/exit passed through.
  Uses ureq (http+json, no TLS — localhost only).

Verified end-to-end: up → headless (no window) → status → exec (root in VM, eth0
lease, internet) → exit-code passthrough → down (clean, no orphaned processes).

Foundation for agent/connection/chat control next.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…, status, commands)

`orcabot` (bare, or `orcabot tui`) opens an interactive TUI: top pane lists the
dashboard's components with live status (terminals running/idle, integrations
attached), bottom pane is a command line + log — a terminal view of the canvas.

- Engine (control-plane client, dev-auth X-User-ID): list dashboards, list
  components with derived status (terminal → session status; integration → attached),
  create/delete via the same API the app uses. Headlessly testable via `orcabot ls`.
- TUI (ratatui): component list + status glyphs + command input. Commands: help,
  refresh, dash / dash new <name>, use <n>, rm <id>, exec <cmd> (runs in the VM via
  /debug/exec), status, quit. Bare `orcabot` launches it.
- `orcabot ls` prints the component list non-interactively (verification + scripting).
- Pin instability/darling to 1.86-compatible versions (ratatui 0.29 deps need 1.88).

Verified: ls lists real dashboards with correct per-component status + clean labels;
exec runs in the VM through the CLI. Interactive TUI needs a TTY (run in a terminal).

Next: create terminal-with-agent + integration connect/attach (OAuth).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…/TUI

Adds component creation to the engine and wires it into both the TUI and a
non-interactive `new` subcommand:

- create_terminal(dash, agent): creates a type=terminal item with the right
  content ({name, bootCommand, skipApprovals}) then POSTs .../items/:id/session
  to boot the agent in a PTY. agent ∈ claude|gemini|codex|shell.
- create_note(dash, text).
- TUI commands: `new terminal <agent>`, `new note <text>` (refresh the list).
- CLI: `orcabot new terminal [agent] [--dash <id>]`, `orcabot new note <text>`.

Verified: `orcabot new terminal shell` creates the item, starts the session, and
the component then shows `running` in `orcabot ls`.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Completes increment 2b (connect components):

- connect <provider>: hits the OAuth connect route without following the redirect
  and prints the authorization URL for the user to open (consent needs a browser).
  Clean message when OAuth client creds aren't configured. Providers: gmail, drive,
  calendar, contacts, github, twitter, box, onedrive.
- attach <terminal> <provider>: resolves the terminal component (item id) to its
  session PTY id (integrations key off pty_id, via ensureTerminalAccess), looks up
  the connected user_integration from /available-integrations, and POSTs the attach.
  Reports "connect first" when the account isn't linked.
- detach <terminal> <provider>.
- Wired into both the TUI command loop and as `orcabot connect|attach|detach` subcommands.

Verified to the OAuth boundary: connect reaches the handler (correctly reports
not-configured), attach resolves item→PTY and correctly reports the provider isn't
connected. Completing a real connect→attach needs OAuth client creds at launch + one
consent click; the call then flows through the gateway over the reverse-vsock route.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Foundation for the terminal I/O pane: connect to a terminal component's PTY and
stream its live output.

- open_pty_ws: connects to the control-plane PTY-WS proxy
  (ws://127.0.0.1:8787/sessions/:sessionId/ptys/:ptyId/ws). Auth via the user_id
  query param (browsers/WS can't use headers; this is how the frontend does it) —
  fixed an initial 403; also sends Origin + X-User-ID. tungstenite (no TLS).
- session_for_item: resolves a terminal item id → (control-plane session id, pty id).
- `orcabot tail <terminal> [--secs N]`: headless verification — prints streamed
  output. Verified: connects and receives the live shell prompt + control_state
  frame (controller=dev-desktop, so input is also available for 2c-2).

Adds vt100 dep (for rendering in the upcoming TUI pane). Next: render the stream in
the TUI (vt100 grid) + input/turn-taking + resize.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…size) — 2c

`open <n>` attaches to terminal #n's PTY as a live, interactive pane — the piece
that makes the CLI feel like the in-app terminal/chat. Ctrl-] detaches.

- PtySession: a background thread owns the WebSocket; binary output → vt100 parser,
  queued input/control frames → sent. Drop stops the thread.
- Render: vt100 screen grid → ratatui cells (fg/bg/bold/inverse/underline), PTY
  cursor mirrored, status bar. Faster poll (30ms) while focused.
- Input: keystrokes encoded (chars, Enter, Backspace, arrows, Ctrl-keys, etc.) →
  binary frames after take_control. Ctrl-] is the escape hatch (not forwarded).
- Resize: keeps the PTY sized to the pane (set_size + resize control frame).
- `orcabot tail --screen` / `--send <text>`: headless verification of the render +
  input pipeline.

Verified headlessly: tail --send 'echo ...' takes control, runs it, and the vt100
render shows the prompt, the command, its output, and the next prompt. (Visual
ratatui rendering needs a TTY — verify with `open <n>` in a terminal.)

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@robdmac
robdmac merged commit 8e6d8a1 into main Jun 20, 2026
1 check passed
@robdmac
robdmac deleted the feat/orcabotcli branch June 20, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant