Skip to content

feat(new-workspace): unified source picker + non-submitted URL drafts for agents#1426

Open
nwparker wants to merge 12 commits intomainfrom
nwparker/slicker-create-2
Open

feat(new-workspace): unified source picker + non-submitted URL drafts for agents#1426
nwparker wants to merge 12 commits intomainfrom
nwparker/slicker-create-2

Conversation

@nwparker
Copy link
Copy Markdown
Contributor

@nwparker nwparker commented May 5, 2026

Summary

Two threads landed in this branch:

  1. Unified the New Workspace dialog — replaces the separate "Create from…" tab with a single source-picker (Smart / GitHub / Branch / Linear / Name) inline with the workspace name field. ~1320 lines of `CreateFromTab` removed; the smart field now owns search, mode tabs, cross-repo URL detection, and a dismissible source pill.

  2. Selected-source pill + non-submitted URL drafts — when the user picks a GitHub issue/PR or Linear item, the agent launches with that URL pre-filled in its input as a draft (no auto-submit). Replaces the previous `Complete ` autosubmitted prompt template.

What's in the pill

  • Distinct icons per kind (PR / issue / branch / Linear) — no redundant text descriptor (the icon carries the meaning).
  • Truncates long titles instead of expanding the dialog (`min-w-0` cascade through flex/grid ancestors so `truncate` actually bites).
  • Open-in-browser button (with tooltip) for items that carry a URL.
  • Clear button (with tooltip) to reset the selection.

Agent draft injection

The agent input is pre-filled via bracketed-paste mode (`\x1b[200~…\x1b[201~`) so the URL lands atomically in the TUI's input buffer without a trailing `\r` — the user reviews and sends themselves.

The hard part was timing. Different TUIs need different amounts of warm-up:

Agent Title-idle signal Min wait before paste lands
Claude `✳ Claude Code` (~500ms) ~600ms
Pi `π - ` (~1s) ~600ms
Codex none — shows a working spinner indefinitely ~600ms after fg stable
OpenCode none — title is just `OpenCode` ~3000ms

Verified empirically with a `node-pty` + `@xterm/headless` test rig that mirrors Orca's spawn flow (DSR/DA1 auto-responses, shell cold-start, then queued startup command).

The new `waitForTuiInputReady` in `src/renderer/src/lib/agent-paste-draft.ts` combines:

  • Title-idle → 200ms grace, declare ready (covers Claude, Pi).
  • Non-shell foreground stable for ≥1500ms OR non-empty title stable for ≥800ms, gated behind a 2500ms minimum floor (covers Codex, OpenCode).
  • Timeout fallback (12s) only fires if a non-shell process is in the foreground — never blast the URL into a bare shell.

One subtlety worth calling out: argv-mode agents distributed via npm (claude, codex, pi) report `process: 'node'` in node-pty even though the binary is the agent. `isAgentForeground` accepts `'node'` for this reason — the previous `expectedProcess: 'codex'` match never fired.

Other tweaks

  • `AgentStartupPlan` now carries the `agent` id so the paste path can apply per-agent behavior in the future without re-deriving it from the launch command. (Tests updated to match.)
  • Extended composer focus restore + fixed an unrelated cross-repo URL prompt edge case in the smart name field.

Known gaps (follow-ups)

  • Copilot and Cursor-agent show a permission/approval prompt on first launch, which absorbs the bracketed paste. Easiest near-term fix is to mark them as draft-injection-unsupported and surface a toast — opting to ship the working agents first and iterate. (Hook is already in place: `agent` arg on `pasteDraftWhenAgentReady`.)

Verification

  • `pnpm tc:web` clean
  • `pnpm test src/renderer/src/lib/tui-agent-startup.test.ts` — 10/10 passing (test fixtures updated for the new `agent` field on the plan)
  • `oxlint src/renderer/src/lib src/shared/tui-agent-config.ts` clean
  • Manual: Claude / Codex / Pi / OpenCode confirmed working by user ("opencode works", "works for Claude") and by simulated PTY rig for Codex/Pi.

Made with Orca 🐋

nwparker and others added 12 commits May 4, 2026 13:27
Co-authored-by: Orca <help@stably.ai>
…ertical alignment

Co-authored-by: Orca <help@stably.ai>
…e icons, tooltips on pill actions

Co-authored-by: Orca <help@stably.ai>
… actually appears in the agent input

Co-authored-by: Orca <help@stably.ai>
…i/opencode type-chars)

Co-authored-by: Orca <help@stably.ai>
…pi/opencode

Replaces per-agent strategy guesswork with a measured readiness check:
title-idle / non-shell-foreground stable for 1.5s / 2.5s minimum floor.
Verified against codex, pi, opencode, claude in a node-pty + xterm-headless
test rig — bracketed paste lands in the input buffer for all four.

Co-authored-by: Orca <help@stably.ai>
The TUI-ready heuristic in agent-paste-draft.ts works for every tested
agent (claude/codex/pi/opencode), so the AgentDraftInjectionStrategy
field, type-chars + bracketed-paste-slow code paths, and per-agent
overrides are dead. Keep the `agent` arg on pasteDraftWhenAgentReady
for future per-agent escape hatches without touching every call site.

Co-authored-by: Orca <help@stably.ai>
Both TUIs open with a 'Do you trust this folder?' menu on first launch
that consumes keystrokes as menu input — pasting a URL there either
selects an arbitrary option or quits the session. Mark them with
skipDraftUrlInjection so the workspace still opens cleanly; the user
types/pastes the URL themselves once past the trust menu.

Co-authored-by: Orca <help@stably.ai>
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