24 KiB
lda.chat Workflow Console
A local React console for inspecting workflow JSON-RPC servers. Connects to a
loopback wf-rpc-server through a Hono proxy, displays capability and draft
workspace reads, and keeps raw protocol evidence inspectable.
Quick Start
# Terminal 1: workflow JSON-RPC server
uv run wf-rpc-server --config wf.config.json --host 127.0.0.1 --port 8765
# Terminal 2: development (Vite + Hono)
pnpm --dir web install
pnpm --dir web dev
Open http://127.0.0.1:5173/console/discover in the browser. Paste the target URL:
http://127.0.0.1:8765/rpc
Click Connect. The console will:
- Validate the target is a loopback address
- Call
workflow.healthon the upstream server - Display the read-only capability catalog and preserve the connection while navigating the console routes
- Show raw protocol evidence for each connection and workspace read
Workflow Console Routes
The root route and /console redirect to /console/discover. The routed
workspace currently exposes:
/console/discoverfor searchable, source-filtered capability discovery and input/output contract inspection/console/draftsfor the persisted draft workspace index/console/drafts/:workspaceIdfor the draft authoring workbench: a desktop capability palette, graph canvas, and context inspector with real draft mutations, revision/status diagnostics, and bounded raw-draft evidence/console/artifactsand/console/artifacts/:artifactId/:versionfor the existing read-only artifact explorer/console/deploymentsand/console/deployments/:deploymentIdfor deployment inspection/console/runsand/console/runs/:runIdfor run, interrupt, and trace inspection
Enter a loopback RPC URL in Workflow JSON-RPC URL and click Connect.
The health exchange establishes the target for the routed shell; subsequent
read-only route calls go through the Hono /api/rpc boundary. The target and
the operation-evidence ledger persist across console route navigation. The
draft workbench keeps the graph as the primary touch surface on mobile and
opens the capability palette and context inspector as independently scrolling,
accessible full-height sheets. Forms remain mounted while sheets are closed so
dirty values and selection survive palette/inspector close and reopen cycles.
Capability Playground
The Discover route includes a generated Try capability form for direct capability smoke tests. Run the local services with loopback defaults:
# Terminal 1: workflow JSON-RPC server
uv run wf-rpc-server --config wf.config.json --host 127.0.0.1 --port 8765
# Terminal 2: web console
pnpm --dir web dev
Connect to http://127.0.0.1:8765/rpc, select wf.std.concat, acknowledge the
side-effect warning, and submit items: ["hello", "world"] with
separator: " ". A direct capability call executes immediately against the
target. It is not a workflow run and creates no graph, state, route, run, or
trace records. The acknowledgement is an accidental-action guard, not
authentication or authorization; capabilities may still have side effects.
wf.source.read_resource is a useful form-generation check. Its local JSON
Schema $ref resolves into logical_source, uri, and the defaulted kind
field instead of an unresolved reference blob. A node-spec direct call can
still finish with a runtime_error when it requires workflow platform context.
That completed receipt is truthful runtime behavior, not a failed form
implementation; use a workflow deployment with the required platform context
for the successful path.
The evidence ledger retains the target, equivalent CLI, and bounded request and
response values. It keeps at most 100 records, traverses to depth 8, retains at
most 100 collection entries, limits strings to 4096 characters, and limits
each retained request or response to 32 KiB serialized. Sensitive keys such as
authorization, cookie, token, secret, password, and api_key are
redacted before evidence enters the console state.
Production Build
pnpm --dir web build
pnpm --dir web start
A single Hono process serves the built React application and API routes from
http://127.0.0.1:8787.
LAN Presentation Rehearsal
Build once, then bind the production Hono server to the laptop's LAN interfaces:
pnpm --dir web build
$env:WEB_HOST = "0.0.0.0"
pnpm --dir web start
Open http://<laptop-lan-ip>:8787/presenter on the phone and
http://<laptop-lan-ip>:8787/present on the audience display. Either route can
Start session or Join session. Starting shows a six-character code, QR
target, and opposite-route join link; the other device can scan the QR, open
the link, or enter the code. Navigation is bidirectional, and the presenter
route can end the session for every paired device.
Rooms are short-lived and in memory. After a temporary disconnect or reload, the client reconnects and applies the latest server snapshot; that snapshot wins over navigation performed locally while offline. A server restart or room expiry requires a new session.
This mode is for a trusted LAN only. The join code is not authentication,
the built server does not provide TLS, and this runbook makes no
public-internet security claim. Keep wf-rpc-server on loopback at port 8765:
browser workflow operations continue through the Hono boundary on port 8787,
so the workflow RPC server does not need a LAN binding.
Commands
| Command | Description |
|---|---|
pnpm --dir web install |
Install all workspace dependencies |
pnpm --dir web dev |
Start Vite + Hono development servers |
pnpm --dir web test |
Run all test suites |
pnpm --dir web typecheck |
Run TypeScript type checking |
pnpm --dir web build |
Build the React console for production |
pnpm --dir web start |
Start the production Hono server |
pnpm --dir web test:workflow-console:e2e |
Build and run real-server desktop/mobile console acceptance tests |
pnpm --dir web --filter @lda/workflow-rpc contract:write |
Regenerate TypeScript wire names and raw types from the checked workflow manifest |
pnpm --dir web --filter @lda/workflow-rpc contract:check |
Fail when the generated TypeScript contract has drifted |
pnpm --dir web --filter @lda/console test:presentation-sync:e2e:install |
Install the Chromium binary required by the browser smoke test |
pnpm --dir web --filter @lda/console test:presentation-sync:e2e |
Run isolated two-context presentation synchronization smoke tests against a built server |
Run the E2E install command once after pnpm install on each clean development
or CI machine. Playwright keeps the matching Chromium binary in its browser
cache for subsequent smoke runs.
Architecture
web/
apps/
console/ React + Vite frontend
server/ Hono local server (API + static serving)
packages/
rpc/ Effect-based JSON-RPC client, schemas, and errors
presentation-sync/ Bounded presentation room wire contract
The browser communicates with Hono at /api/connect and /api/rpc. Hono
validates targets against loopback policy, executes typed JSON-RPC calls
through Effect, and returns plain JSON DTOs to the browser.
Product And Design Context
The console app carries two design-context files:
apps/console/PRODUCT.mdcaptures the strategic product contract: users, purpose, personality, anti-references, and design principles.apps/console/DESIGN.mdcaptures the current visual system: tokens, typography, components, elevation, and do/don't rules.
This structure comes from the local Impeccable design workflow. PRODUCT.md
uses its product-register format, and DESIGN.md follows the DESIGN.md
convention: YAML frontmatter for machine-readable tokens, followed by six fixed
sections (Overview, Colors, Typography, Elevation, Components, and
Do's and Don'ts). Future UI work should read these files before changing
visual direction.
Workflow Console
After connecting, the console opens a route-based workspace rather than one combined explorer screen.
- Discover searches the capability catalog and inspects typed capability contracts.
- Drafts lists persisted draft workspaces and opens the authoring workbench for capability insertion, step edits, route edits, validation, diagnostics, revision, and raw protocol evidence.
- Selected-step editing exposes Setup, Inputs, and Outputs tabs for a selected capability step. Inputs replace the ordered capability input bindings, while Outputs replace output-to-state bindings; the controller sends the complete canonical row list for each save. Persisted malformed rows remain visible as repair rows and block save or clear until repaired.
- Artifacts, Deployments, and Runs provide focused lifecycle lists and detail routes, including artifact graphs, deployment validation, run interrupts, and trace evidence.
- Evidence records JSON-RPC request and response receipts with equivalent CLI text across the workspace.
- Pagination is available for cursor-backed artifact and run collections.
Security
- Only loopback targets are accepted (
127.0.0.1,localhost,[::1]) - Upstream redirects are rejected
- Request bodies are limited to 256 KiB
- Response bodies are limited to 4 MiB
- The server binds to
127.0.0.1by default - Browser capability calls are enabled automatically only when
WEB_HOSTis loopback - A non-loopback bind requires the explicit override
WEB_ENABLE_CAPABILITY_CALLS=1before the Try capability surface can call upstream capabilities - TLS-terminating proxies can allow exact browser origins with the
comma-separated
WEB_TRUSTED_ORIGINSsetting. Forwarded headers are not trusted implicitly.
The non-loopback override is an explicit risk acceptance for a trusted environment, not authentication, TLS, tenant isolation, or a public-internet security boundary. It can let LAN clients execute side-effecting capabilities against the configured workflow target:
pnpm --dir web build
$env:WEB_HOST = "0.0.0.0"
$env:WEB_ENABLE_CAPABILITY_CALLS = "1"
$env:WEB_TRUSTED_ORIGINS = "https://workflow-console.example"
pnpm --dir web start
Smoke Test
With the Python server running, verify in the browser:
- The initial page makes no upstream request
- Connect succeeds against
http://127.0.0.1:8765/rpc - Capability discovery returns catalog entries and supports qualified-name inspection
- Raw health and capability exchanges are selectable in the evidence inspector
- Equivalent CLI text is visible
- Select Try capability, acknowledge the immediate-call warning, and
submit
wf.std.concatwithitems: ["hello", "world"]andseparator: " "; verifyhello world, the target-bearing evidence receipt, and no workflow run or trace record - Select
wf.source.read_resource; verifylogical_source,uri, and the defaultedkindfield render, then verify a completedruntime_errorreceipt when it is called without platform context - Create a draft, add and edit a capability step, set a route, validate, and reload its direct draft URL while checking graph and evidence state
http://example.com:8765/rpcis rejected without upstream fetch- Stopping the Python server produces the unreachable state while preserving the entered URL
- Persisted draft workspaces populate and a selected draft shows its graph, diagnostics, and revision
- Artifact, deployment, and run routes populate independently
- Selecting an artifact shows its plan graph and detail panel
- Selecting a run shows trace frames and interrupt details
- Clicking a trace frame shows resolved input and output
LDA Report Workflow Smoke
# Terminal 1: start the workflow server with the report example
uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765
# Terminal 2: start the console dev server
pnpm --dir web dev
Connect to http://127.0.0.1:8765/rpc. The smoke passes when capability
discovery, draft inspection, lifecycle routes, graph visualization, trace
frames, and raw evidence are visible.
lda Report Workflow Demo
Start the prepared workflow RPC server from the repository root:
uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765
Start the web console:
pnpm --dir web dev
Open http://127.0.0.1:5173/, connect to
http://127.0.0.1:8765/rpc, then use the lda report workflow demo
panel. The panel expects lda_report_case_study.default to already exist
in the connected store. If it is missing, the panel displays the exact
product CLI setup commands.
Demo Timeline Modes
- Live executes the prepared deployment through public JSON-RPC calls.
- Replay uses the committed
lda-report-success-v1recording and does not contact the workflow server during playback.
Start presentation begins autoplay. Pause stops before the next
operation, and Next applies exactly one operation or recorded event.
Playback always stops at issue_review; approval remains a human action in
both modes. Replay is visibly labeled and does not create real issues.
Presentation Mode
The console exposes /present, a 720p no-scroll defense compositor for the
prepared lda_report_workflow story. It renders a 13-scene, multi-beat
storyboard with an adaptive aspect-ratio canvas, stable
stage regions, discussion branches, one editorial canvas, persistent scene-aware
assistant surfaces, and keyboard navigation.
The companion /presenter route is a speech and Q&A reader. It uses
the same #scene/<scene>/<beat> and #discuss/<branch> hashes, shows target and
cumulative timing, keeps optional detail/evidence/Q&A collapsed, and links to
the corresponding audience slide in a new tab. It performs no workflow RPC,
replay, or live-target operations. Its shared pairing controller synchronizes
canonical navigation hashes with /present through Hono without duplicating
storyboard semantics. Use ArrowLeft and ArrowRight to move between notes;
covered checkboxes remain local to the page.
Must-say notes support authored inline Markdown emphasis for rapid scanning, and
the stable Previous/Next bar remains available at narrow viewport widths.
The final presentation beats frame the evaluation as bounded evidence, make claim boundaries and future work explicit, and end on the canonical defense discussion index rather than a benchmark or generic conclusion.
Scenes 7 and 8 use the canonical prepared-authoring recording as their only execution evidence. Scene 7 is a single full-screen chat-entry beat: its prefilled request is submitted locally, then reveals the first deterministic user, assistant, and Discover tool group. It is deterministic replay, not a live LLM chat, and does not start a workflow run. Scene 8 breaks the prepared authoring into six beats with a persistent prepared-agent assistant pane on the left and a dominant phase canvas on the right. The adaptive split starts near 26/74 and keeps the matching prepared tool group synchronized with each factual source, graph, repair, artifact, or deployment view. Neither scene calls workflow authoring RPC operations — they consume deterministic prepared data. Scenes 9 through 11 use the canonical replay by default when no live target is available. When the resolved target is healthy, the same prepared run flow can execute through the public JSON-RPC operations and record live evidence using the same DemoRunFacts projection. Raw protocol payloads are available through the evidence receipt and inspector.
Scenes 7–11 share one compact footer demo rail. Scene 7 remains a local scripted conversation, with its chat composer as the main surface, while the rail owns Run prepared workflow, replay fallback, retry, running, paused, resuming, and completed labels.
With a healthy target, the rail starts the live chain through the existing
/api/rpc proxy; when health fails, it keeps Play replay walkthrough as an
explicit fallback. The presentation does not silently replace a live failure
with recorded evidence.
For local live rehearsal, run both services:
pnpm --dir web dev
uv run wf-rpc-server --config examples/lda_report_workflow/wf.config.json --host 127.0.0.1 --port 8765
The browser runs on 5173, the console server proxy runs on 8787, and the
workflow RPC server listens on 8765/rpc.
The presentation chat surface is source-owned and follows the AI Elements
conversation/message/tool/prompt-action model. It currently renders the
prepared timeline agent and approval flow; a future AI SDK driver should target
AgentMessagePart / TimelineAgent-compatible events instead of replacing the
presentation timeline.
The key deep-link-addressable defense states include:
/present#scene/agent-handoff/request— Scene 7, prepared authoring request/present#scene/prepared-lifecycle/discover— Scene 8, discover phase/present#scene/prepared-lifecycle/draft— Scene 8, draft phase/present#scene/prepared-lifecycle/deployment— Scene 8, deployment phase/present#scene/run-from-deployment/operation— Scene 9, run operation/present#scene/run-from-deployment/graph— Scene 9, workflow graph/present#scene/typed-human-boundary/approval— Scene 10, typed approval/present#scene/resume-output-evidence/resume— Scene 11, resume proof
Legacy aliases from the earlier 12-scene plan (such as workflow-demo and
interrupt-evidence) are replaced by the IDs above and no longer resolve.
Scene 11 is factual by design. It projects the reviewed/live run into visible workflow input, interrupt payload, resume decision, output, and trace facts. Empty trace frame objects are shown as captured empty objects; absent fields are called out as not captured rather than replaced by generic placeholders.
pnpm --dir web dev
# open http://127.0.0.1:5173/present
Navigation
- ArrowRight / Space: advance to the next beat within a scene, then to the next scene
- ArrowLeft: rewind to the previous beat or scene
- Escape: close overlays in priority order (node spotlight, evidence, discussion)
- P: toggle presenter controls
Hash Format
- Main scenes:
#scene/<scene-id>/<beat-id> - Discussion branches:
#discuss/<branch-id>
Invalid hashes fall back to the first scene and beat.
Chat Modes
Chat is composed per-beat with four modes: hidden, full, rail, and dock.
When dock is active, a floating button in the lower-left corner expands the
chat to rail.
Presentation Canvas
The presentation uses one warm Editorial Canvas across all scenes. Dark surfaces are local to product evidence such as chat, graphs, traces, and terminal-style operation blocks; they are not whole-stage themes.
Discussion Branches
Five discussion branches exist under the positioning scene. Opening a branch
from the main scene saves the originating beat as the return location. Direct
hash links to #discuss/<branch-id> return to the parent scene's first beat.
Replay-First Startup
Replay is the default mode. The demo timeline auto-starts in replay using the
committed lda-report-success-v1 recording. No RPC server is required.
Editorial Canvas
The presentation renders on an adaptive editorial canvas that derives its aspect
ratio from the browser viewport. The canvas fills the available viewport while
clamping its aspect ratio between 4:3 and 16:9. It intentionally avoids
transform: scale(...): React Flow figures, popovers, and floating UI measure
DOM geometry, so the stage must expose real element positions instead of scaled
coordinates. No URL query parameters or local-storage settings control the
ratio.
Scene 6 uses a recursive Interactive Figure with expand/collapse and breadcrumb navigation.
Key Scene 6 deep links:
/present#scene/architecture/client— root architecture overview/present#scene/architecture/runtime/focus/runtime-providers— one level deep/present#scene/architecture/runtime/focus/runtime-providers/configured-providers— two levels deep
Figure Controls
- Enter / click: expand a child figure
- Escape: pop one focus level
- Tab / arrows: move focus between figure nodes without advancing the presentation
- Breadcrumbs: jump to any ancestor focus level
Evidence Presentation
Evidence availability never resizes the primary presentation region. Each beat
may request an evidence presentation state (hidden, receipt, or inspector),
and a global override can be set through the presentation tool. The state is
cleared on scene navigation (next, previous, jump) but preserved through
discussion transitions.
- Receipt: a compact bottom-row button showing the count and label of available evidence records. Clicking opens the inspector.
- Inspector: a centered modal dialog with
InterpretedandRawtabs, a record selector, and focus trapping.Escapecloses the inspector.
Constraints
This plan deliberately defers:
- AI Elements / Vercel AI chat primitives
- Live LLM driver integration
- Public-internet presentation hosting, TLS, and authentication
- Final visual polish and motion choreography
Constrained Demo Agent
/present includes a prepared agent recipe for the thesis readiness report.
The recipe is deterministic: it emits standard chat message parts, workflow tool
calls, and presentation tool actions without requiring a model provider key.
The current prepared recipe can:
- identify the
lda_report_case_study.defaultworkflow deployment; - show tool calls for run start, resume, and trace read;
- focus the
review_issuesinterrupt node through a presentation tool action; - open evidence linked to the run trace.
This is intentionally not a general autonomous planner. A future server-side Vercel AI SDK driver can feed the same message-part interface.
Authoring Story (Scenes 7 and 8)
Scenes 7 and 8 are the prepared authoring story. They use deterministic data
from the committed projectPreparedAuthoring() recording and never call
workflow authoring RPC operations.
-
Scene 7 (Agent Request): a single full-screen deterministic chat entry that pre-fills the report-authoring request. Send is local presentation state and reveals the first prepared Discover tool group. This is not a live LLM chat or workflow run.
-
Scene 8 (Prepared Workflow Lifecycle): a six-beat lifecycle (discover, draft, diagnose, repair, artifact, deployment) with a compact phase rail and one dominant factual product projection per beat. A persistent prepared assistant pane stays visible on the left while the phase canvas remains dominant on the right; the starting split is approximately 26/74 and adapts to the available width. Its active tool group follows the current beat. There is no lower chat dock, detached trace modal, or second transcript.
One staged message box remains visible in every phase. Discover starts empty with useful placeholders; Draft and Artifact use the exact next authoring prompts. Sending an edited Draft advances through Diagnose and Repair and preserves that text as the projected user turn; sending an edited Artifact does the same for Deployment. Deployment Send records only
Run request prepared for the next execution slice.and makes no run or RPC request.
The authoring scenes consume deterministic prepared data and never call workflow authoring RPCs. Scene 8 ends at the truthful run-request handoff; Scenes 9–11 own run activation, typed approval, resume, output, and trace evidence. No Scene 8 message submission starts a workflow run.
Demo Climax (Scenes 7–11)
Scenes 7 through 11 are the demo climax. They keep a continuity rail visible while the prepared replay moves from persisted workflow run, to typed human interrupt, to resume/output/evidence. The rail and outcome panel are presentation-only projections over the committed replay; they do not add live backend dependencies.