Skip to content

docs(blog): showcase the Orchestrator's new SSH session feature#2240

Open
sinelaw wants to merge 18 commits into
masterfrom
claude/orchestrator-ssh-showcase-gif-XASVQ
Open

docs(blog): showcase the Orchestrator's new SSH session feature#2240
sinelaw wants to merge 18 commits into
masterfrom
claude/orchestrator-ssh-showcase-gif-XASVQ

Conversation

@sinelaw

@sinelaw sinelaw commented Jun 4, 2026

Copy link
Copy Markdown
Owner

Adds an animated GIF showcase for the SSH backend of the Orchestrator's
"New Session" dialog, generated end-to-end against a real connection.

A new ignored e2e test, blog_showcase_fresh_0_3_10_ssh_session, spins
up a throwaway, non-root sshd on 127.0.0.1, reaches it through a fake
hostname (demo-box) that resolves via /etc/hosts, and drives the New
Session dialog exactly as a user would: pick the SSH tab, type
demo-box:<port>, set the remote path / identity / a -o UserKnownHostsFile=… ssh option, and submit. Fresh then attaches the
full remote-agent stack (ssh bootstraps the Python agent), so the
"Connecting…" → live-session transition and the ls / cat run in the
born-attached terminal are genuinely remote, not staged.

The test is Linux-only and self-skipping: it returns (rather than fails)
when ssh/sshd/ssh-keygen are absent or demo-box can't be made to
resolve. It only appends 127.0.0.1 demo-box to /etc/hosts when the
name is entirely absent and the file is writable, and never rewrites an
existing mapping.

Regenerate with:
cargo test -p fresh-editor --test e2e_tests
blog_showcase_fresh_0_3_10_ssh_session -- --ignored
scripts/frames-to-gif.sh docs/blog/fresh-0.3.10/ssh-session

@sinelaw sinelaw force-pushed the claude/orchestrator-ssh-showcase-gif-XASVQ branch 3 times, most recently from 8e6ee5c to 0f40868 Compare June 10, 2026 17:32
@sinelaw sinelaw force-pushed the claude/orchestrator-ssh-showcase-gif-XASVQ branch from 8f325b7 to 442a80a Compare June 15, 2026 06:16
claude added 16 commits June 15, 2026 09:21
Adds an animated GIF showcase for the SSH backend of the Orchestrator's
"New Session" dialog, generated end-to-end against a real connection.

A new ignored e2e test, `blog_showcase_fresh_0_3_10_ssh_session`, spins
up a throwaway, non-root `sshd` on `127.0.0.1`, reaches it through a fake
hostname (`demo-box`) that resolves via `/etc/hosts`, and drives the New
Session dialog exactly as a user would: pick the SSH tab, type
`demo-box:<port>`, set the remote path / identity / a `-o
UserKnownHostsFile=…` ssh option, and submit. Fresh then attaches the
full remote-agent stack (ssh bootstraps the Python agent), so the
"Connecting…" → live-session transition and the `ls` / `cat` run in the
born-attached terminal are genuinely remote, not staged.

The test is Linux-only and self-skipping: it returns (rather than fails)
when `ssh`/`sshd`/`ssh-keygen` are absent or `demo-box` can't be made to
resolve. It only appends `127.0.0.1 demo-box` to `/etc/hosts` when the
name is entirely absent and the file is writable, and never rewrites an
existing mapping.

Regenerate with:
  cargo test -p fresh-editor --test e2e_tests \
    blog_showcase_fresh_0_3_10_ssh_session -- --ignored
  scripts/frames-to-gif.sh docs/blog/fresh-0.3.10/ssh-session
…l switch

Builds on the New SSH Session showcase to cover the fuller workflow:

- The launch session now opens a local Rust file (`local-app/src/main.rs`),
  so "Local" is the starting context.
- After the SSH attach, Quick Open (Ctrl+P → Backspace) fuzzy-finds and
  opens a remote file (`app.py`) straight into a buffer over the SSH
  authority — proving remote editing, not just a remote terminal.
- `Orchestrator: Toggle Dock` brings up the persistent session dock listing
  both the local launch session and the remote `deploy-box`, and a single
  ↑ live-switches back to the local session with its own file still open.

Also tightens the connection segment so it feels snappy: faster host typing,
single-shot field fills, and a brief "Connecting…" dwell before the live
session lands.

Regenerate with:
  cargo test -p fresh-editor --test e2e_tests \
    blog_showcase_fresh_0_3_10_ssh_session -- --ignored
  scripts/frames-to-gif.sh docs/blog/fresh-0.3.10/ssh-session
Adds docs/blog/fresh-0.4.0/ — a "What's New in Fresh (0.4.0)" rollup of
everything since 0.3.0 — and starts on the headline showcase GIFs, each
generated the same way as the SSH one (an ignored e2e showcase test that
captures SVG frames, then scripts/frames-to-gif.sh).

New showcases:
- orchestrator-dock: three project sessions (Rust / TypeScript / YAML) in
  one process; toggle the persistent dock and live-switch between them with
  the arrows. Animations are disabled in the test so the dock's switch slide
  doesn't freeze mid-transition under the test clock.
- universal-search: multi-scope Live Grep overlay (files / buffers /
  terminals) with Word/Regex modes, the scope toolbar, and the live
  syntax-highlighted preview pane. Runs against a real git repo so the
  git-grep provider is selected; the plugin dir is left untracked so it
  never clutters the results.

Also moves the existing SSH-session showcase under fresh-0.4.0/ (it's a
0.4.0 headline) and renames its test to match.

The rollup index links these three GIFs and carries text sections for the
remaining Tier-1/2 features (review diff, live diff, terminal path links,
environment managers, Go to LSP Symbol, …) to be filled in with GIFs next.

Regenerate any showcase with:
  cargo test -p fresh-editor --test e2e_tests \
    blog_showcase_fresh_0_4_0_<name> -- --ignored
  scripts/frames-to-gif.sh docs/blog/fresh-0.4.0/<name>
Halve the per-frame durations in the three 0.4.0 showcase tests
(ssh-session, universal-search, orchestrator-dock) so they play about
twice as fast — same frames, snappier pacing. Roughly cancels the global
2x SPEED_FACTOR for these three without touching it (which would affect
every other showcase). Regenerated the GIFs to match.
…-line row

SSH session: after connecting, run real commands in the integrated terminal
(`ls`, `python3 app.py` — executed on the remote host over the SSH link) and
expand the file explorer, which is rooted on the SSH authority so its panel is
titled `[demo-box]` and the tree lists the workspace served over the connection.

Orchestrator dock: give each session a *different* layout to demonstrate window
independence — api is a single buffer, web runs a fake coding-agent terminal
split beside its source file, and infra has the file explorer expanded beside
the manifest. The arrow-key tour now visits all three and returns home.

Prompt line: the test harness force-enables `show_prompt_line` (for layout-
stable assertions), which reserved a blank bottom row and floated the status
bar up one line. Showcases now auto-hide it (`prompt_line_visible = false` per
window) so the status bar sits flush to the bottom like the real app, with the
prompt line still appearing for the palette / Quick Open.

Regenerated all three GIFs.
Add a fake "Coding Agent" (tests/fixtures/coding_agent.py): a Python script
that streams an agent-style log — a braille spinner animates a "thinking" line
for ~1s, then commits a result line (edit / tests / run / create / note) drawn
from a large bank, seeded by the project name so two instances diverge. It
loops forever. Everything it prints is staged; it reads and changes nothing.

The orchestrator-dock showcase now runs two of these agents in two sessions'
terminals (build-auth · auth-service, build-pay · payment-api) with a third
session holding a file explorer. A new `animate` capture helper sleeps real
wall-clock time between frames so the PTY children keep producing output —
successive frames show the spinner turning and new log lines arriving. The
tour bounces between the two agents, and because they keep running off-screen,
each return shows it further along (both dock rows carry the `*` working glyph).
Tracks the 0.4.0 rollup showcases: three done (orchestrator-dock with two live
Coding Agents, ssh-session, universal-search) and the remaining Tier-1/2 to
create, refreshed against the latest master (adds the agent-aware orchestrator,
send-to-terminal, and the first-class {trust} status-bar element). Lives under
docs/internal/ so it's excluded from the public docs build.
The decorative wave animation / idle screensaver (new on master) is pure
eye-candy and very GIF-friendly — fire it via the Wave Animation palette
command or let it kick in after the idle timeout.
Add the wave-screensaver showcase: open a code buffer, fire the Wave Animation
palette command, and capture the rising, churning sea at ~26 fps via the
real-time `animate` helper (sleeps real wall-clock between frames so the
wall-clock-driven effect actually moves).

A fluid effect needs a high frame rate, which means many frames; to keep the
GIF reasonable, give frames-to-gif.sh `--colors` / `--dither` options and build
this one with `--colors 32 --dither none`. Terminal frames are flat-colour, so
dithering only adds noise and bloat — dropping it (with a 32-colour palette)
takes the GIF from ~5 MB to ~1.9 MB at 26 fps with no visible quality loss.
Defaults are unchanged, so other showcases are unaffected.

Wired into the 0.4.0 rollup and ticked off the internal showcase plan.
Two more Tier-1 0.4.0 showcases:

- terminal-path-links: run `grep -rn` in the integrated terminal, Ctrl+hover a
  `src/main.rs:8` result to underline it, then Ctrl+Click to jump to that file
  and line. Driven via a real Ctrl+Left MouseEvent through the harness.
- live-diff: enable Live Diff (vs HEAD) on a committed file, then type — added
  lines get a green `+` gutter and an edited line shows its old text above with
  a `-` gutter, all updating live as the buffer changes.

Both embedded in the 0.4.0 rollup and ticked off the internal plan; only
review-diff remains text-only among the Tier-1 headliners.
The modified-line demo reselected the line with smart-Home (which lands after
the indent) and retyped a replacement that also started with 4 spaces, so the
new line ended up double-indented. Append a trailing comment at end-of-line
instead, leaving the original indent intact.
The headliner Tier-1 showcase: open Review Diff over working-tree changes —
a three-column layout (FILES sidebar grouped by directory | diff | COMMENTS) —
press `1` for the side-by-side OLD/NEW view, then `c` to leave a comment that
lands in the COMMENTS panel and badges the file with `*`.

(The COMMENTS panel wraps text, so the test waits on a single distinctive word
rather than a phrase.)

Embedded in the 0.4.0 rollup; all Tier-1 headliner GIFs are now done.
The New Session dialog's Agent: dropdown (terminal / claude ↻ / aider ↻ /
custom…). Click through the presets: each fills the Agent Command field, the
chosen one highlights, and the "↻ resumes on restart" legend explains the tag.
Rendered 160-wide so the legend isn't truncated off the dialog.

That's all eight Tier-1 0.4.0 showcases done.
Re-ran all eight blog_showcase_fresh_0_4_0_* tests and rebuilt every GIF
(wave with --colors 32 --dither none). Moved the Wave Screensaver section to
the top of the rollup so the page opens on the eye-catching demo.
screensaver_enabled is off by default, so the wave only kicks in as a
screensaver once you turn it on in the Settings UI (the Wave Animation command
still fires it on demand with no setup). Clarify both the rollup and the
wave-screensaver page, and the showcase test's description string.
Add the workspace-trust showcase (verified interactively first): a prod-looking
project with a direnv `.envrc` opens **Restricted** — the clickable `{trust}`
element now leads the status bar — Fresh detects the env and offers the combined
"Trust & activate" prompt; accepting flips it to **Trusted** and activates
direnv. Booted like `main.rs` (trust store + maybe_prompt_workspace_trust +
fire_plugins_loaded_hook) so trust starts undecided, mirroring a real launch.

Also fills the 0.4.0 blog gaps found by cross-checking the tagged changelog:
- promote Workspace Trust & Environments from an Also-New line to a real section
  (replacing the stale "Environment Managers" text; corrected — the local
  terminal does not inherit the env, only LSP/formatters/spawned tools do)
- send-the-selection-to-the-terminal in the Terminal section
- Live Diff word-level highlighting
- Also New: Clear Search, hide-current-line-while-selecting, File Explorer
  slot-override API, lsp_enabled, auto_read_only, configurable status-bar
  separator, color-transition animation, q-closes-help-viewers

Fix: the showcase SVG renderer now XML-escapes the key-badge label, so a label
containing `&` (e.g. "Trust & activate") no longer produces malformed SVG.
@sinelaw sinelaw force-pushed the claude/orchestrator-ssh-showcase-gif-XASVQ branch from 791d899 to 2e7ae95 Compare June 15, 2026 09:21
claude added 2 commits June 15, 2026 09:28
…ompt

Rework the workspace-trust showcase to feature the prominent full-screen
"⚠ SECURITY WARNING" prompt (the real trust UX) instead of the env-manager's
small corner popup. Open an untrusted Rust crate with a `build.rs` — Fresh
names the markers (Cargo.toml) and offers Trust / Keep Restricted / Block, each
with what it allows. ↑ selects "Trust folder & Allow Tooling", Enter flips the
{trust} status element Restricted → Trusted. This is core (no plugin); the test
boots like main.rs (trust store + maybe_prompt_workspace_trust) so an undecided
folder raises the prompt.

Blog copy updated to lead with the full-screen prompt and its three choices,
keeping the env (direnv/mise) combined-prompt note as the secondary path.
Rebased on latest master (0.4.0).
The trust UX has two divergent prompts and the integrated terminal
doesn't inherit the activated environment (tracked in #2355). Pull the
section, dedicated page, and GIF until that's resolved.
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.

2 participants