Plugin AI-Native Sessions
The in-plugin session experience: start and open AI sessions inside any marketplace plugin, with a Sessions pane, suggested-prompt chips, first-class visibility in the Inbox, an auto-context briefing the agent receives, and optional standing context contributed into your own projects.
What it is
Status: shipped (always on). The plugin-ai-native-cli feature landed 2026-08-06 — the plugin
CLI forwarder and the in-plugin session experience below are available in every installation. No Lab
flag gates them, and this surface is safe to document publicly.
The in-plugin session experience: inside every marketplace-plugin surface (GitHub Integration, Calendar, Newsletter, Smrzz, …) you can see, open, and start first-class AI sessions — "start a session right there" — and every session started there opens already knowing what the plugin is and how to drive it through its AI-callable actions.
Where to find it
It has no sidebar row of its own; it lives inside the plugins you already have. Open a marketplace plugin from wherever it sits in the app, and look beside the plugin's own screen: a Sessions pane mounts there whenever that plugin declares at least one AI-callable action, carrying the standard "+ New session" affordance, the usual section model, and the right-click management menu every integration shares. From a paired phone the same sessions are reached the ordinary way — they appear in the normal sessions list and open as the normal chat.
How it behaves
The experience is made of five pieces.
The Sessions pane
When a plugin project is active AND that plugin's OWN manifest declares at least one AI-callable
endpoint (cli.endpoints), a pane mounts beside the plugin's webview listing the AI sessions that
live at this plugin, with the standard "+ New session" affordance, section model, and right-click
management menu (the same shared SessionHostSidebar every integration uses). A plugin that
declares no cli.endpoints (a UI-only plugin, like the former Uplink messenger) never shows the
pane — it is a per-plugin manifest opt-in, not feature-wide. A plugin that DOES declare endpoints
can still decline the pane with ui.hideSessionsPane: true — the sibling of ui.hideProjectPanel,
for a plugin that owns its full width; both are needed to clear the column entirely, because
declining only one hands the slot to the other surface. Opening a session swaps the webview for the
chat; a "Show <plugin>" button swaps back. On mobile, plugin sessions appear in the normal sessions
list and open as the normal chat.
First-class visibility — from ANY entry point
Sessions the USER starts under a plugin — the pane's "+ New session" OR the global "+ New" / Cmd+N /
quick-launch (which carry source='ui') — live in the plugin's own project and appear in the
unified Inbox, project badges, and Needs-You counters like any other session. Only sessions the
PLUGIN starts for itself (the v2-worker ctx.sessions.create background research spawn,
source='plugin:<id>') stay hidden. The chokepoint decides by a POSITIVE managed-discriminator —
hidden IFF the source is plugin:<id> (or provenance is nullish → fail-safe, or the feature is
dark) — NEVER a user-source allowlist (that allowlist was a bug that hid ui/quick-launch user
sessions). The archived count AND list apply the same __plugin__ exclusion (flag-independent) so
the pane header can't drift from the list and managed sessions don't leak into the global Archive
view.
Purpose-built auto-context (the capability card)
The first message of a plugin-surface session invisibly carries: a short orientation (the agent runs
inside Omniscio; the user is viewing the chat inside this plugin's surface; Omniscio provides the
session, the inbox where approvals land, and the control server), the plugin's identity, its
AI-action list as method-bearing lines (GET status — description, [requires human approval]
marks reflecting the ask-first rule — any action that is not a declared read or marked safe,
whichever key the caller holds, not just a bare requiresConfirmation flag), how to call
http://127.0.0.1:19519/plugins/<id>/cli/<path*> (bearer from the session's own AMC_CLI_TOKEN,
plus the X-AMC-Source-Session-Id header) including
one worked curl example synthesized from the plugin's own first read action plus the generic POST
form, what to do when an action needs the user's approval (HTTP 202 + approvalRequired → the
request is in the Omniscio inbox; the AI must never claim the action already ran), a scope contract
("you are the <plugin> agent — prefer this plugin's actions; work unrelated to the plugin is out of
scope for this session, suggest a regular Omniscio session"), and the caveat that a CLI call fails
loudly (404 unknown plugin · 409 disabled / worker down) rather than silently doing nothing. Only
the SENT text carries this — the chat bubble shows just what the user typed.
Suggested-prompt chips (chat-first entry)
A plugin may declare up to 4 curated starters in its manifest — ui.sessions.suggestedPrompts: [{ label, prompt }]. The Sessions pane renders them as chips: front and center in the empty state,
a compact row above the list otherwise. ONE click starts a session with that prompt auto-sent as
the first message — zero setup. A malformed list fails the whole manifest loudly at load; no
declaration means the pane looks exactly as before. An auto-sent prompt gets no special powers: if
the agent immediately calls an action marked requiresConfirmation, the call still queues to the
inbox for the human.
Reach into YOUR OWN projects (opt-in, grant-scoped)
Everything above is about sessions living at the plugin. A plugin may also contribute standing
context to sessions you start in your own repositories — so a session in my-app opens already
knowing that plugin is there and how to drive it. Two things must both be true: the plugin declares
ui.sessions.realProjectContext: true in its manifest, and you have granted it that specific
project (the same per-project workspace grant used for file access). There is no new permission
and no new toggle — granting is the opt-in, revoking the grant or disabling the plugin is the off
switch. In an ungranted project the block never appears, which is deliberate: every action it would
advertise there would be refused anyway, so showing it would advertise a lie. Unlike the static
contextTemplate, the block is built by the plugin — the host calls the plugin's own
single-segment context action (host-called only; it is not in the agent-facing action list) and
expects { "context": "<the block>" } back. Rules the host enforces: it is frozen at spawn and
rides the whole session, so it should name only stable facts (how to call the plugin, package/test
counts, detected runners) and nothing that changes per run; it gets ~1.5 seconds and is dropped
if the plugin is slow, not running, or answers oddly — a session never waits on a plugin to launch;
it carries the same 5,000-character cap as contextTemplate, and over it the block is
dropped whole, never truncated; it is never written into your repository (no
.claude/session-context.md in your git tree); and it runs only when the plugin declares
GET context as an unflagged read — it runs automatically as the session starts, with no one
there to approve it, so anything else (a different verb, an undeclared path, or a path flagged
requiresConfirmation) is skipped entirely rather than run without the approval it would need.
You can see when it fired: the session shows a collapsed "seed-context" divider labelled with the
plugin's name. Several granted plugins compose into one block.
For agents
Where the seams live
- Sessions pane:
src/renderer/src/features/plugins/PluginSessionsPane.tsx+plugin-session-host.ts+compute-plugin-chat-active.ts+compute-plugin-sessions-pane-visible.ts(the manifest opt-in mount gate: active plugin'smanifest.cli.endpointsmust be non-empty AND it must not have opted out viamanifest.ui.hideSessionsPane) — governed by.claude/memory/contracts/session-host-contract.md. - Hide-tag managed-discriminator:
src/main/services/session/session-create.ts(applyHideTags— hidden IFFisPluginManagedSpawnSource/ nullish / dark) + the shared source classifiers insrc/shared/session-host/types.ts. - Archived count/list alignment:
src/main/db/queries-sessions/archive.ts(buildArchivedWhereexcludes__plugin__, shared by count + list) — the SOLE__plugin__filter now that RT-F004 made the "Archived (N)" total a server value (theuseArchivedTotalCounthook →SESSION_COUNT_ARCHIVED); the old renderer-sidebumpArchivedTotalCountForSessiondelta guard was removed. - Auto-context (capability card):
src/main/services/session-context/plugin-provider.ts— governed by.claude/memory/contracts/session-context-provider-contract.md(plugins-declare-context+ its AI-actions extension). - Real-project reach (piece 5):
src/main/services/session-context/plugin-project-context-provider.ts(a CONTENT provider — matched bymatches(folderPath)on a real folder, not by a__plugin_<id>__sentinel), reached throughlistEnabledPlugins/dispatchCliActiononsession-context/plugin-registry-accessor.ts(wired insrc/main/ipc/register.ts); merge rules for several matched providers insession-context/compose.ts; the manifest bitui.sessions.realProjectContextinsrc/shared/types/plugins.ts+plugin-manifest-validator.ts. Governed by.claude/memory/contracts/session-context-provider-contract.md(content-tier-is-multi-valued/suppresses-profile-gates-the-coaching-seed/real-project-access-needs-a-workspace-grant), and its refusal of arequiresConfirmation-flagged action by.claude/memory/contracts/plugin-cli-dispatch-contract.md. - Suggested prompts: manifest field in
src/shared/types/plugins.ts(PLUGIN_SUGGESTED_PROMPTS_MAX) + Zod insrc/main/services/plugin/plugin-manifest-validator.ts; chips inPluginSessionsPane.tsx(AsyncButton,plugin-suggested-promptsanchor). - The CLI forwarder the context teaches:
src/main/services/cli/cli-server-plugins-routes.ts(ALL /plugins/:id/cli/:path*) — governed by.claude/memory/contracts/plugin-cli-dispatch-contract.md(approval gating landed with DF-0005).
Proof
Unit + integration suites listed in the two contracts, plus the pure mount-gate
lock tests/unit/features/plugins/compute-plugin-sessions-pane-visible.test.ts
(the "Uplink regression lock" + empty-endpoints boundary); end-to-end:
tests/e2e/ui/plugin-sessions-pane.spec.ts (flag-on pane/row/yield/chips +
flag-off absence even with prompts declared + the manifest-scoping assertion:
flag-on with no cli.endpoints → no pane) with 3-width screenshots under
docs/edo/plugin-sessions-proof/ and 3-width light/dark chips proof under
docs/edo/plugin-suggested-prompts-proof/.
Related
Two neighbouring pages cover what a plugin's sessions can reach. The human-facing one-liner about those AI actions is plugin-capability-card.md, and the rules for what a plugin's own screen may call are plugin-bridge-capabilities.md. A session that instead has to FIND a plugin by name and drive it is plugin-cli-discovery.md, and installing or removing the plugins themselves is plugin-marketplace.md.
Last verified 2026-09-28