Skip to content

refactor(agents): split the Claude harness into runtime and UI - #1719

Closed
loganj wants to merge 2 commits into
agent-host-plugin-agent-entryfrom
agent-host-claude-split
Closed

loganj wants to merge 2 commits into
agent-host-plugin-agent-entryfrom
agent-host-claude-split

Conversation

@loganj

@loganj loganj commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

🤖

Summary

Details

  • agents.register, called from the plugin's agent entry, registers the runtime half: title, defaults, run, sessions, models, usage and provider state. A new optional expose field holds the handles that the type's own UI needs from the runtime. These handles are stores (snapshot + subscribe) and calls that return promises, so a later PR can carry them between pages.
  • agents.present(typeId, (exposed) => …) is new and is called from the plugin's UI apply. It supplies the icon, Peek, Create, CreateModel, tabs, and the provider's DialogBody and DefaultControl. Only the plugin that registered a type can present it, because both use the same plugin-scoped key.
  • The service merges the two halves. Readers of types() see one type, as before. The merged object stays the same object while neither half changes. Provider getters such as attentionAction stay live. If present throws, the type's agents still run, and the error is logged.
  • AgentProvider.DialogBody is now optional, because it comes from the UI half. The provider dialog renders it only when it is present.
  • Claude: the setup, runtime, process sync and update timer move into its agent entry. The tabs now take narrow handle types in place of the ClaudeSetup, ClaudeDefaults and ClaudeRuntime classes.
  • Known gaps for the bridge PR:
    • The Activity handles include a synchronous keyed read (conversations(agent)).
    • Two of the calls take an AbortSignal.
    • The bridge must support both, or they must become a store and a cancellable call.
  • plugin-testing.ts adds appliedType, which runs both entries of a harness plugin and merges them with the service's own merge function. The Claude tests use it.

Testing

  • New service tests: present merges with the registered type and takes only presentation fields; present gets the exposed handles once; the merged type is stable; provider getters stay live; a throwing present leaves the type in place.
  • The existing Claude tests now run through both entries.

🤖 Generated with Claude Code

loganj and others added 2 commits October 27, 2026 10:23
A plugin can now export `agent = { inject, apply }` for what agents need
while they run (agent type runtimes, tools, wakes, Attention sources),
separate from its UI `apply`. Both parts start in the same page, under
the same plugin identity, each with its own dependencies; the plugin is
active once both are and fails if either does.

GitHub's watch_pr moves into its agent entry. No behavior changes.

This is the first step toward running agents in their own webview, so a
hidden or suspended UI page cannot stall them.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Logan Johnson <loganj@squareup.com>
An agent type can now come in two halves. The plugin's agent entry
registers the runtime half with `agents.register`, and may pass
`expose`: the handles its own UI reaches of the runtime (stores and
async calls). The UI entry supplies icon, Create, tabs and provider
dialogs with `agents.present(typeId, (exposed) => ...)`. The service
merges both by type key, so readers of `types()` see one type, as
before. Provider getters stay live, and a throwing `present` leaves the
type's agents running.

Claude moves its setup, runtime, process sync and update timer into its
agent entry. Its tabs take narrow handles in place of the runtime
classes. No behavior changes.

Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Logan Johnson <loganj@squareup.com>
loganj added a commit that referenced this pull request Oct 29, 2026
…s into runtime and UI

A plugin may export an `agent` entry beside `apply`. Code agents need
while they run (an agent type's runtime, tools, wakes and Attention
sources) goes there; `apply` stays the UI. Both start in the same page
for now. Claude, Codex, goose and Pi now register their types from their
agent entries and present them from their UI entries, reaching the
runtime only through the type's `expose` handles.

Inert: the app behaves the same.

Squashes #1716, #1719, #1720, #1721 and #1723.

Signed-off-by: Logan Johnson <loganj@squareup.com>
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@loganj
loganj force-pushed the agent-host-plugin-agent-entry branch from 193154a to 7ba2704 Compare October 29, 2026 12:46
@loganj

loganj commented Oct 29, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Squashed into #1716 (one PR per column of the agents split), rebased onto main.

@loganj loganj closed this Oct 29, 2026
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