Commit Graph

3 Commits

Author SHA1 Message Date
Ignacy Łątka a92c859d07 feat(argent-lens): argent lens — bind a claude session to the preview window (#416)
## What

Adds `argent lens` — open Argent Lens bound to a fresh `claude` session.

## Why

The Lens preview window and the agent communicate through a shared,
process-wide tool-server that carries **no per-agent identity** (only a
coarse telemetry header). So when the user requests changes in the
window, there's no reliable way to route them to the *specific* agent
that opened it.

`argent lens` sidesteps the problem by inverting ownership: the human
launches Lens, and Lens spawns (and therefore owns) exactly one `claude`
terminal. The binding is 1:1 by construction — no identity plumbing
required.

## How it works

1. `argent lens` ensures a tool-server and **begins a CLI Lens
session**, which opens the preview window up front (no
`await_user_selection` needed) and keeps it open across rounds.
2. It spawns a tracked `claude` terminal in the current directory — a
TypeScript port of the macOS applet's `osascript` spawn/track mechanism
— seeded to propose variants without blocking.
3. A watcher polls `GET /preview/outcome`; on each submitted round it
types a one-line feedback summary into that terminal, queuing it to the
agent as its next prompt. Requesting changes therefore "talks back" to
the bound agent instead of closing the window.

macOS only (drives Terminal/iTerm via `osascript`); off-darwin it exits
with a clear message.

## Changes

- **CLI** `lens-terminal.ts` — `osascript` spawn/track + a new
write-into-running-session path (the "outputting" channel; injects input
into the running TUI, which a tty write cannot do).
- **CLI** `lens.ts` — the command + feedback formatter.
- **tool-server** — a `cliSession` flag in the variant store (opens the
window, suppresses auto-close on submit); `POST /preview/cli-session`
and `GET /preview/outcome` routes.
- **UI** — relabels the submit action to "Request changes" while a CLI
session is active.

Behind the existing `argent-lens` feature flag.

## Verification

- Build + typecheck across the workspace; ESLint (`--max-warnings 0`) +
Prettier clean.
- 34 new unit tests; full `@argent/cli` suite **118 passing**,
tool-server variant/preview suites **46 passing**.
- **E2E (observed on this machine):**
- **tool-server HTTP** — `cli-session` toggles `cliSession` true/false;
submitted feedback round-trips through `/preview/outcome`.
- **terminal injection** — spawned a window running `cat`, confirmed
`writeToSession` lands text in the running program's **stdin** (both
iTerm and Terminal), with embedded newlines flattened.
- **full relay** — the real `watchAndRelay` loop against a real
tool-server typed two distinct submission rounds' feedback into a
stand-in agent terminal (dedup on `completedAt` verified).
- `argent lens --help` and the feature-flag gate (exit 1 with guidance,
no spawn).

Note: a real end-to-end with a live `claude` agent was not run (it would
drive a paid interactive session); the agent-facing channel is proven by
injecting into a stand-in process's stdin via the exact same code path.

---------

Co-authored-by: Filip131311 <contact@filipkaminski.com>
2026-07-01 19:57:56 +02:00
Ignacy Łątka ba7bb8b72e fix(argent-lens): native window controls, comment cursor, card layout polish (#409)
Part 1 out of N reworks for Argent Lens

Polish pass on the Argent Lens preview window.

## Changes
- **Native window controls.** `titleBarStyle: "hidden"` (+
`setWindowButtonVisibility`) shows the real macOS traffic lights on the
transparent window instead of the handcrafted close button.
`trafficLightPosition` insets them to share the corner panels' 14px
padding.
- **Comment-mode cursor.** Entering comment mode swaps the crosshair for
a Figma-style speech-bubble cursor over the stream, so "you are placing
a comment" is unmistakable. Defined as a `--cursor-comment` data-URI
token in `theme.css`.
- **Bottom toolbelt.** The "Add comment" button moved out of the
top-right cluster into a new bottom-centre floating toolbelt — the seed
of a Figma-style bottom tool tab. Same button look, placement only.
- **Cards show all variants.** Two fixes so short cards no longer clip a
variant: the left column is no longer height-limited by the bottom-right
footbar (per-column bound), and tighter variant-row padding lets a
2-variant card fit its column.
- **Cards repel / never overlap.** A deterministic per-poll de-overlap
of the spring **home** targets (a stable top-down sweep), not a
per-frame force. The damped springs glide to non-overlapping rests: no
micro-jitter, no rubber-banding, and a card wedged between two settles
instead of wiggling forever.
- **App named "Argent Lens".** The window title was already set, but the
macOS menu bar / Cmd-Tab / Dock showed "Electron" (the unpackaged
`Electron.app` bundle's `CFBundleName`, which `app.setName` can't
override). On macOS the tool-server now launches the window through a
thin **wrapper `.app`** whose `Info.plist` `CFBundleName` is "Argent
Lens" — it symlinks Electron's Frameworks/Resources (no ~270MB copy) and
is launched with `--no-sandbox` (the modified/symlinked bundle no longer
matches the signed Helper apps). Acceptable for this window: it only
loads the tool-server's localhost UI, and the renderer keeps
`contextIsolation` + `sandbox:true`. Falls back to plain Electron on
non-macOS or any failure.

## Verification
Driven live against the iOS simulator via a dev tool-server + the
Electron window over CDP:
- Native traffic lights render on the transparent window; handcrafted
close button removed.
- Comment-mode `.stage img` computed cursor is the speech-bubble
data-URI.
- "Add comment" is in `#float-toolbelt`, horizontally centred at the
window mid-line, 14px above the bottom.
- All demo cards report `bodyScrollHeight === clientHeight` (zero clip);
both variants visible.
- 5- and 9-card layouts: zero overlaps, positions identical across 2s
(no jitter), and pinning a card between two settles with no overlap and
no wiggle.
- Menu bar / Cmd-Tab read "Argent Lens"; `ps` confirms the window
launches via `…/argent-lens-app/Argent Lens.app/Contents/MacOS/Electron
--no-sandbox`.
- `tsc --build`, `eslint`, `prettier --check`, and the preview/variant
test files all pass.
2026-06-25 16:28:40 +02:00
Ignacy Łątka f3d108a5a1 feat: Argent Lens (#271)
Adds a UI for proposing and choosing between multiple agent-generated
variants on a running app.

**MCP tools** (`packages/tool-server/src/tools/variants/`)
- `propose_variant` — non-blocking; agent stages a variant for an
on-screen element (text/label/identifier/role matcher).
- `await_user_selection` — one blocking call; parks until the human
submits, then returns the picks + free-form annotations + a global
comment.

**Preview UI** (`packages/ui`)
- Floating cards anchored to live element frames via the existing
`describe` tree, with connector lines.
- Comment-mode inspector: hover spotlight (blur+dim everything else),
right-click any element to pin a comment.
- Sticky padded hitbox + trajectory-aware dismissal so focus doesn't
drop on cursor jitter.
- Footbar [Complete] [Clear], confirm modal for destructive actions,
green toast on submit.
- Single source of feel constants in `theme.css`.

**Electron host** (`packages/preview-window`)
- New workspace package. Frameless transparent BrowserWindow at fixed
size; the squeeze open/close is a CSS `transform: scaleY` on `<html>`,
GPU-composited — no OS-level resize.
- Tool-server spawns it on `await_user_selection` park, reuses it across
re-awaits, and asks it to animate-close on submit (1s grace so the toast
is visible).
- Stdio-line IPC (no extra ports). Ephemeral throughout — the renderer
hits the tool-server's already-ephemeral `/preview/*` HTTP.

---------

Co-authored-by: Filip131311 <contact@filipkaminski.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-17 15:22:04 +02:00