Weaving agents into your app.
Weft is an embeddable agent chat runtime SDK. Drop a streaming chat panel into your app, and the agent can drive your REST API through named tools, respect your state machine, and visually replay each call on the page with live cursor automation.
Ships as two packages:
@percena/weft— browser. Production-ready. Powers the agentic-SaaS story below.@percena/weft-node— desktop/VPS in-process host. Published on npm — see Desktop with@percena/weft-node.
Your app ──embed──▶ @percena/weft ──▶ streaming agent chat panel
(timeline · action-bridge · live cursor automation)
│
▼ agent drives your REST API · replays each call on the UI
The browser package is production-ready today — here's where that pays off.
Weft is built for vertical SaaS — industry-specific service platforms whose end user is a professional operator (not a developer) running complex, multi-step, policy-governed workflows across many interrelated resources. In these products the value is rarely a single clever API call; it's orchestrating a chain of stateful, role-gated operations — exactly the work an agent can take off the operator's hands.
Rather than rebuilding the backend, Weft layers an agent on top of the SaaS's
own existing REST / OpenAPI surface. It turns "click through eight screens to
resolve a P1 incident" into "tell the agent what you want." The agent drives the
named tools, respects the domain state machine (illegal transitions bounce
back as a 409 backstop), honors role separation, and visually replays
each action on the UI with live cursor automation. The end-user experience jumps from
expert-only console to conversational self-service — without the SaaS vendor
rewriting their product.
Concrete scenarios where this agentic-SaaS transformation pays off:
| Domain | The professional workflow an agent can drive |
|---|---|
| IT service management | P1 incident response — create + link affected CIs, assign, escalate, resolve, close; CAB change approvals + rollback; CMDB dependency traversal (our apps/itsm demo) |
| E-commerce / order ops | Order lifecycle — checkout, pay, ship, deliver, refund request / approve / deny; cart + inventory (our apps/online-store demo) |
| Healthcare / clinical ops | Lab order → result → diagnosis chain; insurance prior-authorization; care-plan adherence; multi-party handoffs |
| Banking / financial ops | Loan origination, KYC/AML review, trade settlement, account opening — compliance-heavy, multi-approver chains |
| Logistics / supply chain | Shipment booking, customs clearance, warehouse transfers, dispatch + exception handling |
| HR / people ops | Onboarding / offboarding across systems, payroll changes, leave approval, benefits enrollment |
| Legal practice mgmt | Matter lifecycle, document assembly, court-deadline calendaring, billing |
The common thread: a stateful domain model, a state machine that gates transitions, role separation, and an API surface that already encodes the business rules. Weft's job is to let an agent operate that surface correctly and visibly — delivering an agentic experience the end user can trust. The next section shows exactly how that transformation works.
Classic REST SaaS → agentic, without rewriting the backend.
Your REST SaaS (unchanged)
· OpenAPI spec → named tools: <toolset>_<operationId>
· state machine → system prompt (rendered from the SM — single source of truth)
· REST + SPA
│
│ tools execute same-origin in the browser (cookie-authed,
│ X-Weft-Actor stamped) — the agent never needs a separate API token
▼
Agent runtime — drives your REST tools, streams the canonical timeline
│
▼ chat stream (SSE) + live cursor automation
@percena/weft — TimelineAgentChatPanel · ActionReplayLayer
│
▼ illegal transition → 409 { error, allowed_actions }
agent relays the legal options + recovers — no blind retry
- Your REST SaaS stays unchanged. Same-origin SPA + API, existing OpenAPI spec, existing state machine — nothing is rewritten.
- Tools come from your OpenAPI. Each operation becomes a named tool
<toolset>_<operationId>, executed same-origin in the browser with the user's cookie (execution: client) — the agent never needs a separate token for your API. - The system prompt is rendered from your state machine — the same transitions the API enforces — so the prompt can't drift from the rules.
- The state machine is the reactive backstop. An illegal transition returns
409 { error, allowed_actions }; the agent relays the legal options and recovers — no blind retry. - A fail-open dependency graph (
required: falseby default) routes multi-step calls but never blocks — a wrong graph degrades routing hints, not correctness. - The action-bridge replays each tool call on the UI with live cursor automation, so the operator sees exactly what the agent did.
@percena/weftships the chat panel, the timeline, and the action-bridge; theintegrate-weft-kitskill builds this whole layer from your OpenAPI spec, closed-loop (build → headed test → self-repair). The two demos below are its reference outputs.
The shipped SDK is the browser package — it is what the demos and the skill use.
npm install @percena/weftMount the chat panel and plug in an embed runtime that connects it to your agent backend:
import { TimelineAgentChatPanel, useAgentSession } from '@percena/weft/chat'
import '@percena/weft/styles'
const session = useAgentSession({
sessionId,
createRuntime, // embed runtime → your agent backend
}) // → see apps/online-store/agentic/src/App.tsx for the wiring
return <TimelineAgentChatPanel runtime={session.runtime} />| Import Path | Description |
|---|---|
@percena/weft |
Core types + canonical timeline + runtime-core + hosted-mode React hooks |
@percena/weft/chat |
TimelineAgentChatPanel, useAgentSession, reconnect/catchup |
@percena/weft/action-bridge |
ActionReplayLayer, weftAction (live cursor automation) |
@percena/weft/styles |
CSS theme (custom properties) |
@percena/weft/providers/flitro |
Browser embed runtime — connects the chat panel to the hosted Weft control plane (weftd); the only runtime the demos ship today |
Building a desktop or VPS app?
@percena/weft-noderuns the agent in-process — see Desktop with@percena/weft-nodebelow.
Control-plane dependency. The browser SDK ships the chat panel, the timeline, and the action-bridge. Its embed runtime (
@percena/weft/providers/flitro) connects the panel to the Weft control plane (weftd) — a hosted service operated by Percena that provisions the agent app, mints scoped session tokens, and brokers the LLM run/timeline stream. The control plane (weftd/ the agent runtime) runs as cloud hosted service; this repository ships the SDK, the two demos, and theintegrate-weft-kitskill. To run the demos or any embed-runtime integration you register a tenant at the Weft console — see each demo'sREADME.md+.env.examplefor the credentials it expects. The SDK itself (types, timeline, runtime contract, UI, action-bridge) is MIT-licensed and usable independent of the hosted plane.
The SDK gives you the chat panel and the timeline runtime. The skill is what turns a traditional REST app into an agentic one. integrate-weft-kit is the agent skill that does it: given an existing REST API with an OpenAPI spec, it layers a Weft chat panel on top whose LLM agent drives your REST API through named tools derived from that spec — with live cursor automation that visually replays each call on the page. This is the engine of the vertical-SaaS transformation above: no rip-and-replace, no backend rewrite — the agent operates the very endpoints the page already uses, and the state machine stays the reactive backstop.
Proven end-to-end on two demos —
apps/online-store/agentic/(Node) andapps/itsm/agentic/(Python/FastAPI) — both built by this skill from theirclassic/counterparts. See Demos.
Install the skill into your project — the CLI auto-detects your agent (Claude Code, Codex, Cursor, …) and installs into the right location:
npx skills add percena/weft-sdk # all skills in the repo
npx skills add percena/weft-sdk --skill integrate-weft-kit # just this skill
npx skills add percena/weft-sdk -a codex # target a specific agent (e.g. Codex)
npx skills add -g percena/weft-sdk # user-level (~/.claude/skills/, ~/.codex/skills/, …)The skill is a multi-file package: SKILL.md (the runbook) plus templates/ (the parameterized agentic layer — Node .mjs and Python) and references/ (fail-open / plan_route / execution-model theory). Source lives in this repo under skills/.
Once installed, the skill activates when you ask your agent to make a REST API agentic, or to model/repair its state machine or API dependency graph. It runs as a closed loop — build → headed test → self-repair — not a one-shot recipe (a per-language template set could never cover every backend):
- Inventory the classic app — resources, state machines (incl.
$priorback-edges), auth roles, UI pages/tabs, SSE events. This inventory drives the test coverage. - Build the agentic layer against a 9-point integration contract: same-origin SPA + API;
POST /api/chat/session+ scoped token mint; reverse-proxy to the agent runtime (unbuffered SSE);X-Weft-Actor→ event-actor; agent-runtime provisioning (app + toolset + skill + automation + graph); the OpenAPI as the tool source (tool_name = <toolset>_<operationId>); the system prompt rendered from the shared state machine; a fail-open dependency graph; and the frontend chat + action-bridge layer. Fast-path templates exist for Node and Python; for any other backend the LLM implements the contract in your idiom. - Test every feature in a headed Playwright e2e, the test list generated from the inventory × the test categories (wiring, feature regression, agent driving, visual feedback, cross-cutting, security). Verify via ground-truth state — not chat text.
- Self-repair — on failure, reproduce → isolate root cause → fix → re-run until green. Durable findings can feed back into a forked skill (new fast-path, common mistake, or contract clarification).
The state machine is the reactive backstop (409 { error, allowed_actions } → relay + recover, no blind-retry) and the dependency graph is fail-open (required: false) — see How it works for the conceptual model.
skills/README.md— install commandsskills/integrate-weft-kit/SKILL.md— the full runbook (contract, test categories, common mistakes, Phase 3 e2e + self-repair)- The two skill-built demos —
apps/online-store/agentic/(Node) +apps/itsm/agentic/(Python) — are the canonical references; clone the repo and read them alongside the skill.
Two reference apps prove the pattern end-to-end. Each ships as a pair: classic/
(a hand-written traditional SaaS, no AI — the input) and agentic/ (the same app
- a Weft chat agent that drives it — built from
classic/by theintegrate-weft-kitskill). Together they cover two backends (Node + Python) and two domains (an approachable one + a high-stakes one).
| Demo | Domain | Backend | What the agent drives |
|---|---|---|---|
apps/online-store |
E-commerce | Node (REST + SPA) | shop_* tools — browse, cart, checkout, pay, ship, refund (8-state order SM). The skill's 1st demo + reference output. |
apps/itsm |
IT service mgmt | Python / FastAPI + React | itsm_* tools — P1 incident response, CAB change + rollback, CMDB traversal (Incident 6-state + Change 9-state SM, 3-role auth). The skill's 2nd demo: a non-JS backend + a harder domain. |
In either demo: log in, set the chat permission to Auto, and describe the
task in plain language — the agent drives the SaaS's REST API through named
tools, the action-bridge replays each call on the UI with live cursor automation, and the
result lands in /api/state. The frontend uses @percena/weft (chat panel +
action-bridge); the backend adds a chat-session endpoint and proxies chat
traffic to the agent runtime — and imports no Weft library. Build/run details
live in each app's README.md.
Each demo recorded end-to-end — the agent driving the SaaS's REST API with live
cursor automation. (GitHub's markdown sanitizer strips raw <video> tags from
README HTML, so each link below opens the recording in GitHub's built-in player
on the file's blob page.)
| Demo | Recording |
|---|---|
apps/online-store — Node e-commerce |
🎬 online-store-agentic.mp4 |
apps/itsm — Python/FastAPI ITSM |
🎬 itsm-agentic.mp4 |
For desktop and VPS apps — Electron, Tauri, or a local daemon — @percena/weft-node runs the agent in-process: the same chat panel and timeline, but driving Claude (Agent SDK + claude -p fallback) or Codex (app-server + codex exec fallback) natively, with provider-owned auth and the full extension plane (policy, sources, skills, automations).
npm install @percena/weft-node react react-domreact / react-dom are peer dependencies (React 18.2+ or 19). Add @anthropic-ai/claude-agent-sdk only when using the native Claude runtime (@percena/weft-node/providers/claude/sdk); Codex-only hosts and the claude -p CLI fallback do not require it.
Mount the panel and plug in a local runtime that drives Claude or Codex directly:
import { TimelineAgentChatPanel, useAgentSession } from '@percena/weft-node/chat'
import { createHostAgentRuntime } from '@percena/weft-node/runtime'
import '@percena/weft-node/styles'
const { runtime } = createHostAgentRuntime({
provider: 'codex', // or 'claude'
cwd: '/path/to/your/project',
candidates: [{ kind: 'app-server', available: true }],
auth: { mode: 'provider-owned', configured: true, source: 'codex-app-server' },
})
const session = useAgentSession({ sessionId: runtime.sessionId, createRuntime: () => runtime })
return <TimelineAgentChatPanel runtime={session.runtime} />@percena/weft-node exposes the same subpaths as @percena/weft (., ./chat, ./styles) plus the Node-only surfaces (./runtime, ./providers/claude, ./providers/codex, ./skills, ./sources, ./automations, ./policy, ./cli-runtime). It is not browser-safe — it imports node:child_process and other Node built-ins; for browser/web apps use @percena/weft instead. For the runtime contract, provider selection, and auth detection, see Architecture + Getting started — Desktop / Node.js.
Weft is a layered SDK: a zero-dependency type core, a canonical timeline, a runtime contract with provider adapters, an extension plane (policy / sources / skills / automations), and an embeddable chat UI. Provider event streams flow in, get sequenced into TimelineEnvelopes, and render through a pure reducer into the chat panel.
Host App (Electron / Tauri / VPS daemon / Browser)
│
▼
@weft/runtime-core ─── AgentRuntime contract · state machine · command sink
│
▼
@weft/providers ────── Claude (native SDK + CLI fallback) · Codex (app-server + CLI) · browser embed runtime · factory
│
▼
@weft/policy · @weft/sources · @weft/skills · @weft/automations (extension plane)
│
▼
@weft/timeline ─────── canonical event schema · seq / cursor / replay / merge
│
▼
@weft/ui → @weft/chat ─ TurnCard · StreamingMarkdown · PermissionRequestCard · AgentChatPanel
The full design — runtime tiers, provider selection, the timeline contract, the runtime state machine, package responsibilities, the streaming pipeline, and the extension plane — lives in docs/ARCHITECTURE.md.
- Node.js ≥ 22 (see
.nvmrc) - pnpm ≥ 10
- TypeScript ≥ 6.0
git clone https://github.com/percena/weft-sdk && cd weft-sdk
pnpm installpnpm run test # all tests
pnpm run check # type-check the monorepo
pnpm run build # build all packages (topological L0→L4)Real-provider integration tests are opt-in (they depend on personal auth):
WEFT_RUN_REAL_AGENT_E2E=1 npx vitest run packages/e2e-tests/src/real-provider-smoke.test.ts # app-server auth probe
WEFT_RUN_REAL_CODEX_TURN_E2E=1 npx vitest run packages/e2e-tests/src/real-provider-smoke.test.ts # real Codex turn
WEFT_RUN_REAL_CLAUDE_E2E=1 npx vitest run packages/e2e-tests/src/real-provider-smoke.test.ts # real Claude turnpnpm run playgroundOpen the local URL and click Start to replay canonical timeline fixtures (mock data only — no backend). Add ?autoplay=1 for auto-play.
15 internal workspace packages under packages/, dual publish facades under publish/ (@percena/weft browser + @percena/weft-node desktop), the demos under apps/, and the skill under skills/. Full tree in docs/GETTING-STARTED.md.
| Document | Description |
|---|---|
| ARCHITECTURE.md | Architecture: design principles, runtime tiers, timeline contract, streaming pipeline |
| GETTING-STARTED.md | Setup, project structure, testing, and demo usage |
| EMBEDDING.md | Embedding the chat panel: minimal embed, bootstrap sequence, CORS + a11y checklists |
| SECURITY-MODEL.md | Trust boundaries: the browser↔control-plane split, the scoped session token, header allowlists |
- The browser embed runtime depends on the hosted Weft control plane.
@percena/weft/providers/flitro(the only embed runtime shipped today) connects the chat panel to theweftdcontrol plane — a hosted service you provision a tenant for at the Weft console. This repository ships the SDK, the demos, and theintegrate-weft-kitskill. A self-hostable / offline mock runtime is on the roadmap; until then, running the demos or any embed-runtime integration requires a tenant. - ESM-only — no CJS build. The package ships ESM only (
.js+.d.ts, no.cjs/.d.cts);require('@percena/weft')throwsERR_REQUIRE_ESM. All documented usage and theintegrate-weft-kitskill templates use ESMimport, so bundler consumers (Vite/webpack 5/Next.js/Rollup) are unaffected. (A prior CJS facade existed but was broken: the code-splitting that deduplicates the@weft/uigraph across the././chat/./providers/flitroentries is ESM-only, so CJS facades each bundled the full@weft/*graph inline and a CommonJS consumer importing both.and./chatloaded two@weft/uicontext-state instances. Dropping CJS removes that footgun.)
All packages building · Claude Agent SDK + Codex app-server verified · Hosted control plane operational · @percena/weft + @percena/weft-node published on npm
- ✅ SDK-first runtime with
native-sdk/app-server/cli-fallbackselection - ✅ Canonical timeline with seq/epoch/cursor, reconnect, replay, gap detection
- ✅ Claude Agent SDK driver with permission bridge and MCP source mapping
- ✅ Codex app-server driver with JSON-RPC client and approval bridge
- ✅ Browser embed runtime provider (connects the chat panel to a remote agent backend)
- ✅ Provider-neutral permission policy with layered rules and scoped approvals
- ✅ Source/skill activation plans with credential boundary
- ✅ Automation runtime bridge with loop guard, history store, and scheduler
- ✅ Embeddable
AgentChatPanelwith reconnect/catchup and inline permissions - ✅ Two agentic-SaaS reference demos —
apps/online-store(Node) +apps/itsm(Python/FastAPI): classic REST → skill-built agentic, e2e verified - ✅ Publishable agent skill
integrate-weft-kit(npx skills add percena/weft-sdk) — turns a classic REST+OpenAPI app into an agentic one via a closed-loop contract - ✅ Host services: audit, artifacts, notifications, utility tools, privileged execution
- ✅
@percena/weft(browser) +@percena/weft-node(desktop) published on npm - ✅ Node.js runtime (Bun fully removed —
child_process,node:http,ws) - ✅ pnpm workspace + vitest test suite + tsup build pipeline
- 🔲 Tune
@percena/weftSDK and the hosted control plane for accuracy and latency - 🔲 Improve the
integrate-weft-kitskill - 🔲 Harden
@percena/weft-nodeSDK for production
MIT © Percena 2026