Agentic UI framework

One import, one JSX line, one export. That is the module wiring.

AgentDock, ActionRail, ProgressiveActionCard, ContextPackBuilder, and CapabilityResolver are first-party primitives installed once at the shell level. Every module page inherits the full agent surface through three lines of code.

Primitives

Six packages. One framework contract.

Each primitive owns one layer of the agent surface. They compose through AgentContextProvider (installed once at the app shell) and the CapabilityResolver registry (populated by every FeatureModule manifest at boot).

@karmanflow/agent-dock

AgentDock

Shell-level context + ask surface

Mounts in the app shell. Reads the current route, selected entity IDs, active filters, and recent receipt IDs from AgentContextProvider, then resolves them into a ContextPack via the backend. Three tabs: Context (what the agent sees), Ask (SSE stream to /api/agent/ask), and Tools (context-advertised read tools). Raw model output never dispatches commands from the dock.

AgentDock, AgentContextProvider, useAgentContext
@karmanflow/action-rail

ActionRail

Module-level proposal rail

One rail per module page. Reads from the shared AgentContextProvider installed by the dock. Renders ProgressiveActionCards from incoming agent recommendations. Policy filters proposals before they reach the rail; operators only see cards at or below their current risk-class ceiling.

ActionRail
@karmanflow/progressive-action-card

ProgressiveActionCard

Propose → preview → approve → execute lifecycle

The transactional primitive. Walks propose, preview, approve, execute with explicit decline and cancel off-ramps. Local state machine stays in sync with the backend progressive_actions.status via caller-supplied handlers. ModuleProgressiveRail wraps the boilerplate: 1 import + 1 JSX line + 1 agentSurface export is the full module wiring.

ProgressiveActionCard, ModuleProgressiveRail, createProgressiveActionHandlers
@karmanflow/evidence-drawer

EvidenceDrawer

Audit trail for every recommendation

Attached to any ProgressiveActionCard. Shows source records, freshness and stream cursor, recent command receipts, recent domain events, relevant policy decisions, model and profile used, prompt template version, and context pack hash. Makes every recommendation reproducible and defensible.

EvidenceDrawer
@karmanflow/context-pack-builder

ContextPackBuilder

UI state → bounded agent context

Turns the current UI state (route, entity IDs, filters, metric cards, active receipts) into a signed ContextPack the agent runtime can consume. Runs server-side; the pack is never user-constructable. Freshness is bounded by the stream cursor in the pack.

buildContextPack, ContextPack
@karmanflow/capability-resolver

CapabilityResolver

UI state → available actions

Given the current actor, module, and entity selection, resolves which commands are available at what risk class. The ActionRail and ProgressiveActionCard use this to filter proposals before rendering; the AgentDock uses it to populate the Tools tab. Registry-backed; every FeatureModule contributes its capability slots.

resolveCapabilities, CapabilitySlot

Module wiring

Three lines to a fully wired agentic module page.

ModuleProgressiveRail wraps the full propose-preview-approve-execute lifecycle. Per ADR D-054: one import + one JSX line + one agentSurface export is the complete per-module contract.

  1. Import
    import { ModuleProgressiveRail } from "@karmanflow/progressive-action-card";

    One package import. No custom state management needed.

  2. JSX
    <ModuleProgressiveRail module="inventory" subject={selectedRow} />

    One JSX line in the module page. The rail renders and connects itself.

  3. Export
    export const agentSurface: AgentSurface = {
      module: "inventory",
      capabilities: ["adjust", "transfer", "reconcile"],
    };

    One typed export declares what the agent can propose in this module.

Risk classes

Four gates. Agents operate within the same boundary as every other actor.

Commands are classified R0-R3 in the command registry. The CapabilityResolver enforces this at the ActionRail level: proposals above the current operator's risk ceiling never reach the UI. R3 commands are never agent-executable; agents may propose them for human review only.

ClassLabelGateExamplesAgent-executable
R0Read-onlyImmediate, no log requiredATP lookup, receipt read, event replay, status queryYes
R1Low-risk writeExecuted and logged; no approval pauseMinor inventory adjustment, schedule creation, webhook testYes
R2High-risk writePreview required; named operator approval before executionReservation cancellation, oversell policy change, allocation overrideYes
R3Broad-impactHuman-only; agents may propose, never executeTenant config change, environment teardown, mass-cancel runPropose only

Context and capability

How the agent knows what is available right now.

ContextPackBuilder runs server-side on every dock open or module route change. It reads the current actor, environment, entity selection, and filter state, then calls resolveCapabilities to build an authenticated ContextPack. The pack is signed and freshness-bounded; the client cannot construct or modify it.

CapabilityResolver is registry-backed. Every FeatureModule declares its capability slots in the manifest; the resolver materializes them at boot. Adding a new module-level agent action is a manifest change, not a wiring change.

Route + entity selectioncurrent UI state
AgentContextProviderReact context
ContextPackBuilderserver-side, signed
CapabilityResolverregistry-backed
ContextPackfreshness-bounded
AgentDock + ActionRailrender from pack

Build with it

First agentic module page in five steps.

The agent quickstart covers MCP key generation, ContextPack wiring, your first ProgressiveActionCard, an approval-bound R2 action, and reading the receipt in the run timeline.

Privacy choices

This controls app-managed marketing analytics: cookie-free Plausible, optional Cloudflare Web Analytics, and first-party event logs with session-only UTM attribution. The site works without it.

Read the privacy notice