Skip to content

Proposal: meta-agent planning-mode dispatcher#859

Draft
gupta-ujjwal wants to merge 8 commits into
juspay:masterfrom
gupta-ujjwal:proposals/0002-meta-agent-planning-dispatcher
Draft

Proposal: meta-agent planning-mode dispatcher#859
gupta-ujjwal wants to merge 8 commits into
juspay:masterfrom
gupta-ujjwal:proposals/0002-meta-agent-planning-dispatcher

Conversation

@gupta-ujjwal

Copy link
Copy Markdown
Contributor

Proposes a planning-mode "meta-agent" — a conversational layer over kolu that summarises what each active terminal is currently asking and dispatches user replies into the right session, then quiets itself the moment a terminal is focused. Originally surfaced as a wishlist item from one user juggling three Claude / opencode sessions in parallel; the cost wasn't reading or typing but the constant context-reload of switching between sessions just to keep each conversation alive.

This is a draft proposal per CONTRIBUTING.md — opening it as a draft because three open questions remain that maintainers are better placed to answer. No implementation lands in this PR; the markdown file is the entire diff.

Reshaped during structural review

The original draft framed the feature as "two surfaces over a single conversational primitive." Hickey + lowy structural review caught real complecting and a missing volatility seam — the post-review proposal reflects what landed:

Lens Finding Disposition
Lowy Read side is a presentation surface, not a new layer (closed OQ on streaming surface) Fixed
Lowy Write side is two seams (NL parser + per-CLI injection), not one dispatcher Fixed
Lowy Per-CLI injection extends AgentProvider, not a parallel adapter family (closed OQ on agent-CLI fragmentation) Fixed
Lowy Voice/text are client-side transports over a plain-string server contract (closed OQ on voice-as-primitive) Fixed
Hickey Replace "single primitive" framing with shared-UI-chrome over distinct mechanisms Fixed
Hickey Auto-quiet rule scoped to single-window assumption; second-display variant changes semantics Fixed
Hickey Mid-tool-call semantics are themselves per-CLI; lives inside the injection seam Fixed

Each finding landed as its own commit so the structural progression is reviewable in git log.

Open questions surviving the review

Happy to be steered on any of these — they're called out in the proposal's Open questions section:

  • UI shape vs. kolu's existing layout — panel inside the window, overlay over the canvas, or dedicated window that can sit on a second display?
  • Mid-tool-call arbitration on the per-CLI injection seam — queue, refuse, or interrupt? Lives per-AgentProvider.
  • NL parser authoring strategy — deterministic templating, LLM call, or hybrid?

Type of change

  • Trivial fix (bug fix, build/CI fix, doc typo, refactor with no behavior change)
  • Implements an accepted proposal in docs/proposals/
  • Adds a new proposal to docs/proposals/ (no implementation in this PR)

Generated by /do on Claude Code (model claude-opus-4-7).

gupta-ujjwal14 and others added 8 commits May 10, 2026 18:18
Field-notes proposal for a conversational layer over kolu that summarises
what each active terminal is asking and dispatches user replies into the
right session — a planning-mode-only orchestration surface that quiets
itself the moment a terminal is focused.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Per-terminal metadata subscription already publishes the "what is this
session asking" data; unified ledger is a presentation surface, not a
new streaming procedure.
…eams

NL intent parsing and per-CLI safe injection are independent volatility
axes. Naming them as separate seams prevents a single dispatcher module
from coupling algorithm-strategy changes to per-CLI protocol changes.
Per-CLI injection volatility lives on the same axis as detection and
state-watching. AgentProvider already encapsulates that axis; adding a
separate DispatchProvider family would double the blast radius of adding
a new CLI without naming a new volatility axis.
Server contract takes a plain instruction string; transport mode is
client-only, mirroring sendInput. STT and input-widget concerns stay on
the client and aren't part of this proposal's scope.
The original "two surfaces over a single conversational primitive"
framing reads as if read and write share the same authoring mechanism.
After the lowy split they don't — they share UI chrome over different
seams. Replace the framing so an implementer doesn't infer a unified
LLM context from the prose.
"Terminal focus" and "user attention" are synonymous on one monitor and
diverge on two. Note the assumption explicitly so the second-display
layout variant doesn't silently inherit a wrong trigger.
…r-CLI

The arbitration policy can't be answered once and applied uniformly
because each agent CLI surfaces "I'm busy" differently. Surface the
fragmentation inside the injection-seam description so it can't be
treated as a single global decision.
@gupta-ujjwal

This comment was marked as off-topic.

@srid

srid commented May 10, 2026

Copy link
Copy Markdown
Member

@gupta-ujjwal Check out the latest main branch; it has a new terminal switcher that pops up when you hover over the top bar.

Also, could you create a separate prototype PR as well that we can nix run and see in action? The prototype PR likely won't be merged, but it is nevertheless useful to see the idea in action, which in turn can further help us refine the proposal. Based on how this goes, I'll update CONTRIBUTING.md accordingly.

@gupta-ujjwal

This comment was marked as off-topic.

@gupta-ujjwal

This comment was marked as off-topic.

@srid

srid commented May 12, 2026

Copy link
Copy Markdown
Member

This seems related: https://claude.com/blog/agent-view-in-claude-code

@srid

srid commented May 15, 2026

Copy link
Copy Markdown
Member

@gupta-ujjwal Try out #909 and please give feedback!

srid added a commit that referenced this pull request Jun 19, 2026
You leave a Claude Code session running for days because you're blocked
— waiting on a review, a deploy, a person. The agent is idle, but its
terminal still costs a PTY, an xterm buffer, a WebGL context, and a slot
in your head. You don't want to **close** it (that throws the thread
away) and you don't want to **keep** it (it's noise). **Sleep** is the
missing third verb: freeze the terminal now, **wake** it — in place,
agent and all — whenever you're unblocked.

This PR adds the **plan of record** for that feature as an Atlas note
(`status: proposed`). No implementation lands here — the note, two
hand-authored diagrams, and an inline UI prototype are the whole diff.

## The insight

A sleeping terminal is *gone* the way a closed one is — but a **record**
survives: enough to respawn it in its saved `$PWD`, replay its agent,
and bring back its splits, theme, and canvas position. That record is
exactly what **session restore** already writes on shutdown. So Sleep
isn't a new mechanism — it's **session restore scoped to one terminal,
on demand**. The green middle of the architecture diagram is entirely
reused; only one persisted cell and two RPCs are new.

| Layer | Reused / new |
|---|---|
| Record shape | `SavedTerminal` / `SavedSession` — **reused verbatim**
|
| Snapshot | `snapshotSession`'s strip-live-fields logic, factored to
`snapshotTerminal(id)` — **reused** |
| Teardown | `handleKillWithSubs` — **reused** |
| Wake | `handleRestoreSession({ session })` (+ `resumeAgentCommand`) —
**reused** |
| Persistence | new `sleepingTerminals` surface cell (clone of the
`session` cell) |
| Verbs | new `terminal.sleep` / `terminal.wake` RPCs |

## What the note covers

- **A sleeping tile is a dormant terminal** — and the same primitive a
future *planned terminal* (#760, #859) would share: sleep has a past
(resume the agent), plan has a future (start fresh). Designed-for, not
built.
- **Where it lives** — a sleeping tile holds its canvas position (shrunk
to fit its content), plus a `sleeping` Dock bucket and a Sleeping
switcher column, so it's reachable in canvas **and** maximized mode.
Durable across kolu restarts: it rehydrates **as sleeping**, never
auto-woken.
- **Louder alerts, everywhere** — the quiet twin. An escape hatch is
what *earns* the right to make *awaiting*/alert signals insistent across
every surface (tile aura, Dock pip, switcher, PWA badge).
- **Decisions locked** (per review): Sleep/Wake naming end-to-end (no
\"suspend\"); full session-restore fidelity is non-negotiable; fail
loudly on a missing `$PWD`; persist forever like terminals; nudge at
48h+ idle; wake returns to the saved slot and nudges the occupant aside.

## Constraints called out

Local terminals only — Wake respawns at `LOCAL_LOCATION`, so remote
(kaval) sleep is gated on the P3 dial-and-adopt path, the same fence
session restore lives behind.

## Preview

Reviewers can open the committed
`docs/atlas/dist/sleeping-terminals.html` in kolu's Code tab; once
merged it publishes at `https://kolu.dev/atlas/sleeping-terminals.html`.
The `ci::atlas-sync` gate passes (dist is idempotent and
host-independent).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

3 participants