Commit Graph
3 Commits
Author SHA1 Message Date
6d70939824 feat(agents): make Pi a first-class agent with icon and resume (#240)
* feat(agents): make Pi a first-class agent, not a fallback one

Pi panes drew the generic robot glyph every unbranded agent shares, so a
Pi tab was indistinguishable from an Aider or Qwen one in the sidebar,
the tab chip and the tray menu (#225). Auditing the rest of the registry
turned up two more places Pi was on a default rather than handled.

The avatar. Repo practice, from the most recent addition (eced0af,
Grok): take the vendor's mark where it is usable as a 16px silhouette,
otherwise lobehub/lobe-icons' transcription (MIT) with the notice inside
the SVG. Neither applies here — lobe-icons' "Pi" is Inflection AI's
chatbot, a different product whose trademark has no business on this
agent, and Pi itself (earendil-works/pi, MIT) ships no symbol to
transcribe. So this is tty7's own geometric Greek pi on the same 24x24
grid, ~3.3 stroke weight and rounded terminals as the bundled marks,
drawn as a filled silhouette because gpui rasterizes these to a tinted
alpha mask. The letter is not a trademark; nothing is vendored in. The
sky accent and the status dot are unchanged.

Resume. Pi's `--resume`/`-r` is a *boolean* that opens the interactive
picker and `--continue`/`-c` just takes the newest session; the flag
that targets one by id is `--session <path|id>` (its own flag table,
packages/coding-agent/src/cli/args.ts). So the resume command is
`pi --session <id>`, and the stale-flag list gains an arm for the five
ways to name a different session — `--session`, `--session-id`,
`--fork`, `-r`/`-c`, and `--no-session`, which would turn saving off
entirely. `--session-dir` is deliberately not stripped: it says where
sessions live, so the injected id needs it to survive.

None of which pays off unless tty7 knows an id, and it did not — the
generated Pi extension spawned the emitter with stdin ignored, so every
event arrived with session_id: None and resume_command was never
reached. The bridge now reads Pi's id off ctx.sessionManager
.getSessionId() (exposed on the read-only session manager Pi hands each
handler) and pipes it in as the emitter's JSON payload, on session_start
— which also fires for /resume, --fork and new sessions, so a mid-pane
switch re-reports instead of going stale. The load-time presence ping
stays bare; no context exists yet.

Left alone deliberately: aliases, slug, display name, accent and the
hook install/uninstall integration were already correct, and every
render site (tab chip, sidebar row, tray menu, notifications) is generic
over icon_path/accent_rgb/display_name — no other agent changes.

Guard tests, following what the module already does: the fallback set is
pinned by slug so neither adding a mark nor regressing to bot.svg can
pass unnoticed, the Pi resume form and its flag stripping are asserted,
and the Pi bridge is checked for the stdin plumbing whose absence was
the silent half of this bug.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* no-mistakes(review): skip resume for Pi panes launched with --no-session

* no-mistakes(document): align Pi changelog flag list with stripped flags

* fix(agents): use Pi's own mark for the avatar, not tty7 artwork

The Pi avatar shipped as original artwork on the claim that Pi publishes
no symbol. That claim was wrong: Pi's mark is at pi.dev/logo-auto.svg.
Swap the drawing for the published one and correct the provenance notes
that repeated the claim (the SVG header, the asset-source arm and the
changelog entry).

The published file is the one mark in this set that arrives with a
stylesheet — an 800x800 box whose `prefers-color-scheme` block swaps
black for white. usvg renders it anyway (it applies the base rule and
ignores the media query), so this is normalisation rather than a fix:
geometry rescaled to the 24x24 grid the rest of the set uses, class and
media query dropped for the flat sentinel fill, since gpui and the tray
both tint these as alpha masks. At this size the mark lands on an exact
4x4 grid of 6-unit cells, so the rescale is lossless.

The tray's avatar test now walks the whole roster instead of one branded
and one fallback agent, and asserts the disc came back with more than one
opaque colour. It is the only test that runs the bundled SVGs through
resvg — the asset-source test proves the bytes resolve, not that they
parse into visible geometry — and a mark that parses to nothing renders
as a bare accent disc that nothing else would catch.

Refs #225

* no-mistakes(document): correct Pi changelog icon-grid claim

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-07-28 21:34:02 +08:00
l0ng-ai eced0af754 feat(agents): give Grok its brand avatar
Grok was drawing the generic robot glyph on a slate disc — the fallback
picked back when no usable mark was bundled.

xAI publishes its symbol only as a ~2:1 landscape lockup that bleeds off
its own canvas; traced and fitted to a 24x24 box it is unreadable as a
16px silhouette, which is what the tab chip and sidebar render. So the
bundled mark is lobehub/lobe-icons' square transcription (MIT), drawn for
exactly this avatar use. Its notice rides in the SVG.

The slate accent goes with it. That mid-tone exists for vendors whose
monochrome mark is grey or a gradient (Cursor), because a white field
vanishes on a light theme; a black field has no such problem — it stays
darker than even the darkest theme background and the white mark carries
the badge. Grok brands in black, like Codex, so it keeps that.

Adds a guard test: every CLIAgent::icon_path must resolve through the
asset source. A brand mark means touching two files, and forgetting the
registration costs the agent its avatar silently.
2026-07-25 20:17:24 +08:00
l0ng-aiandl0ng-ai cd9577c590 feat(agents): recognize CLI coding agents + git branch in the sidebar (#85)
* feat(agents): recognize CLI coding agents + show git branch in the sidebar

Observe (never wrap) third-party coding agents running in a pane — Claude
Code, Codex, Gemini CLI, Aider, Amp, OpenCode and ~10 more — and enrich the
UI around them, plus front each sidebar row with its git branch and diff.

Detection & identity
- Command-based detection over the foreground argv (launcher basename, and
  interpreter-wrapped `node …/cli.js` / `npx …` forms), with user rules via
  `agent_commands` in config. Brand avatars on the tab chip and sidebar row.

Rich status channel
- A per-pane state machine (idle / working / waiting-for-you / done) driven
  by agent-reported events over an OSC 777 sentinel channel
  (`tty7://cli-agent`, versioned JSON), sniffed daemon-side and streamed to
  the client (DaemonMsg::AgentStatus).
- `tty7 agent-hook claude <event>` + a palette installer wire Claude Code's
  lifecycle hooks up; the hook writes the sentinel to the controlling tty
  (with an ancestor-tty fallback for detached hook processes).
- Avatar status dot: working (blue) / waiting (amber) / done (green); an
  unread finished turn gets a crisp outer ring that clears on focus.

Notifications, resume, context feed
- "Needs your permission…" the moment an agent blocks; "finished after Ns"
  per turn, honoring the notify policy (rich turns suppress the coarse exit).
- Session resume: restored panes re-launch their conversation
  (`claude --resume …`), gated by `restore_agent_sessions` (default on).
- Palette commands send the current selection or the repo `git diff` to the
  running agent as a ready-made prompt.

Sidebar git line
- New `terminal::git_status`: off-thread `git` probe (branch, or short sha
  when detached; `git diff --numstat HEAD` line counts) with
  GIT_OPTIONAL_LOCKS=0, refreshed on cwd change or command finish, dropped
  on a stale cwd via a generation tag.
- Each row is avatar + title + `⎇ branch  +N −M` (green/red), sized to
  content; the redundant cwd/"Working…" lines and the aggregate rollup are
  gone — the status dot and branch line carry it.

672 tests pass.

* fix(agents): repair CI and refresh the git line when an agent turn ends

- The live PTY detection test used `sh -c 'exec -a codex cat'`, but
  `exec -a` is a bashism dash (Ubuntu's /bin/sh) rejects — spawn bash.
- cargo fmt over cli_agent.rs / view.rs / app.rs.
- An agent session is one long foreground command, so the back-to-prompt
  edge never refreshed the sidebar's branch/diff line while the agent
  worked — exactly when the working tree changes. poll_agent_status now
  reports a turn ending (transition into Done) and the poll reprobes git
  on that edge too.

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-07-15 14:35:24 +08:00