commit f28038abec81ab69233fedbc176505efbf7e8050 Author: jules Date: Mon Apr 27 18:32:22 2026 +1000 feat: initial commit — extracted from comfy-cloud Anything-can-drive-the-UI command bus. Single dispatch point for LLM tool calls, scripts, and (optional) WebSocket remote control. JSON canonical form plus a plain-text DSL sugar layer. Includes a visible virtual cursor that animates to elements before commands act on them. Modules: - bus.ts — CommandBus class, dispatch, handlers, vars, history, listActions, readState. Built-in handlers: navigate, click, fill, submit, select, wait, wait_for, scroll, read, expect, set - parser.ts — DSL ↔ JSON, with quoted values, # comments, # speed: directive, $name = assignment, $var interpolation, expect assertions - script.ts — script runner; loads /scripts/.script, supports sub-scripts via `run` command - cursor.ts — virtual cursor + ripple, speed-controlled, aria-hidden - provider.tsx — React glue: registers `navigate` via react-router, mounts cursor, exposes window.commandBus / runScript / runScriptText for console use - ws.ts — optional WebSocket producer (connectCommandSocket) - llm-bridge.ts — buildSystemPrompt (DSL ref + live action snapshot), extractActionBlocks, runActionBlocks, estimateTokens, trimMessages - index.tsx — barrel re-exports Peer deps: react, react-router (consuming app provides). Originally inline in `comfy-cloud/app/lib/`. Extracted as part of the crema-app-aifirst-template scaffolding. Co-Authored-By: Claude Opus 4.7 (1M context) diff --git a/README.md b/README.md new file mode 100644 index 0000000..9936a9c --- /dev/null +++ b/README.md @@ -0,0 +1,165 @@ +# @crema/action-bus + +The "anything can drive the UI" command bus. One dispatch point for LLM tool +calls, scripts, and (optional) remote control over WebSocket — all funnel +through the same handlers, run against the same DOM contract. + +Pairs with [`lib-aifirst-shell-ui`](https://git.sky-ai.com/CremaUIStudio/lib-aifirst-shell-ui) +which provides a `[data-action]`-tagged shell. Non-AI apps that want +scriptable / e2e-testable UIs can use this lib alone. + +## Public API + +```ts +import { + commandBus, // singleton + CommandBusProvider, // mounts cursor + registers `navigate` + parseScript, // DSL ↔ JSON + runScript, runScriptText, + buildSystemPrompt, // LLM bridge + extractActionBlocks, runActionBlocks, + estimateTokens, trimMessages, + connectCommandSocket, // optional WebSocket producer +} from "@crema/action-bus" +``` + +## Usage + +Wrap your app: + +```tsx +// app/root.tsx +import { CommandBusProvider } from "@crema/action-bus" + +export default function App() { + return ( + + + + ) +} +``` + +Tag interactive elements: + +```tsx + + +``` + +Drive the UI: + +```ts +commandBus.dispatch({ type: "click", target: "save-button" }) +commandBus.dispatch({ type: "fill", target: "search-input", value: "acme" }) + +// Or as text DSL: +import { runScriptText } from "@crema/action-bus" +runScriptText(` + navigate /resources + wait_for resources-table + fill search-input "acme" +`) +``` + +## Built-in commands + +| Command | Args | Purpose | +|---|---|---| +| `navigate` | `path` | React Router navigation | +| `click` | `target` | Click `[data-action=target]` | +| `fill` | `target`, `value` | Set input value, fire input + change events | +| `submit` | `target` | Submit the form containing target | +| `select` | `target`, `value` | Set `