Executive Summary
The workbench was moved from a website-first prototype toward a KMM Reaktor module where the engine and website share the same domain model, graph, fixtures, services, interactors, app targets, design vocabulary, and most renderer-facing state.
Architecture
The central work moved into modules/engine. The shared workbench graph composes pane subgraphs, service nodes, typed API ports, actor nodes, repositories, interactors, and routes.
Parity
The website and desktop app both expose Graph, DevTools, Agent, UI, Database, Auth, AI, Testing, Deploy, and Insights. The old Run naming was retired in favor of DevTools.
Quality
The test surface was expanded across engine JVM tests, desktop smoke tests, Playwright web tests, subsystem regression tests, and performance-oriented harnesses.
Module Shape
The target shape is now a Reaktor KMM workbench module. The common layer owns vocabulary and behavior; the platform layers render and bridge external UI libraries.
modules/engine/
src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/
data/
actors/
core/
interactors/
repositories/
services/
design/
fixtures/
graph/
panes/
model/
ui/compose/
src/jsMain/kotlin/ai/bestbuds/reaktor/workbench/render/react/
atoms/
domain/
foundation/
graph/
panels/
runtime/
shell/
state/
src/jsMain/react/
main.ts
styles.css
styles-v3.css
src/jvmMain/kotlin/ai/bestbuds/reaktor/workbench/render/compose/
atoms/
design/
graph/
inspection/
panes/
shell/
| Layer | Responsibility | Representative files |
|---|---|---|
| commonMain graph | Workbench modes, pane subgraphs, routes, service nodes, typed API ports, auto-wiring, and navigation. | workbench/graph/WorkbenchGraph.kt, workbench/graph/panes/WorkbenchPaneGraphs.kt |
| commonMain data | Actors, repositories, interactors, mock-backed service contracts, and typed workbench APIs. | data/actors/*, data/interactors/*, data/repositories/*, data/services/* |
| commonMain model | Shared catalog, graph entity, edge summary, sidebar group, status, app target, and pane state models. | model/WorkbenchGraphCatalog.kt, model/WorkbenchStates.kt |
| jsMain renderer | Kotlin/React shell, panels, graph bridges, runtime bridge, scenario bridge, and typed domain conversion. | render/react/shell/*, render/react/panels/*, render/react/graph/* |
| jvmMain renderer | Compose shell, desktop graph pane, left rail, inspector, bottom drawer, preview, and semantics inspection. | render/compose/shell/*, render/compose/panes/*, render/compose/graph/* |
Website Renderer
The website renderer was moved from a JSX-heavy tree into Kotlin/JS. The remaining TypeScript file is now intentionally small and platform-like: it installs React, loads CSS, lazy-loads React Flow, installs Kotlin bridge objects, and boots the Kotlin app component.
src/jsMain/react/main.ts is still JavaScript/TypeScript because it owns boot, dynamic import of @xyflow/react, global interop installation, and the React root. The application components live under src/jsMain/kotlin/.../render/react.
Kotlin/React decomposition
| Package | Role | Examples |
|---|---|---|
render/react/shell |
Application chrome and navigation surfaces. | AppShell.kt, TopBar.kt, ModeToolbar.kt, ModeSubControls.kt |
render/react/panels |
Mode-specific screens and rich subsystem panes. | DevToolsScreen.kt, AgentRichScreen.kt, DataAuthRichScreens.kt, TestingAiRichScreens.kt |
render/react/graph |
React Flow bridge, graph screen data, node renderers, visual constants, and graph sizing. | GraphScreenBridge.kt, GraphNodesBridge.kt, GraphVisuals.kt |
render/react/domain |
BestBuds graph flow export, domain fixtures, compatibility helpers, and flow adapter bridge. | BestBudsGraphFlowBridge.kt, FlowAdapterBridge.kt, MockBridge.kt |
render/react/runtime |
Bridge installation, graph boot, service access, interactor access, and navigation synchronization. | BootBridge.kt, RuntimeBridge.kt, ServicesBridge.kt, NavigationBridge.kt |
Website behavior implemented
- Target switching now has the real app set: BestBuds, Engine, and Website.
- The graph screen uses the BestBuds graph export and maps it into the workbench catalog.
- Graph node sizing and visual density were improved through shared graph visuals and larger readable node surfaces.
- All major modes have real screens or mock-backed rich screens instead of empty tab placeholders.
- DevTools is the canonical name; Run remains a retired concept.
- Performance marks are emitted during runtime import, graph import, graph boot scheduling, and graph boot completion.
Desktop Engine
The desktop app now follows the website as the styling source of truth. The work focused on making Compose render the same control-plane vocabulary as the web app: dark chrome, compact top bar, mode toolbar, graph drawer, right inspector, bottom command drawer, DevTools command pipeline, and graph-focused panes.
Visual system
The Compose renderer gained web-aligned theme tokens, Inter and JetBrains Mono font use, compact toolbar treatments, dark surfaces, blue active controls, amber warnings, green live state, and denser panel spacing.
Layout system
The desktop shell now mirrors the website shell with a top app bar, mode toolbar, left rail, central graph or pane surface, side inspector, bottom drawer, and footer/status row.
Graph pane
The desktop graph pane was reshaped around shared graph catalog data, larger visible nodes, left tree support, preview panel support, inspector models, and mode-specific panels.
DevTools
The old Run naming was replaced. The desktop DevTools pane now presents command queue, code diff, compile, hot reload, tests, deploy, and trace-oriented controls consistent with the website.
Feature Parity
The current state is not that every backend integration is production-real. The important shift is that both renderers now see the same workbench world and can mix live graph data with mock-backed subsystem contracts without deleting unfinished surfaces.
| Feature | Shared core | Website | Desktop engine |
|---|---|---|---|
| App target switcher | Common app target fixtures: BestBuds, Engine, Website. | Switcher reflects and updates target state. | Header follows the same target set and visual treatment. |
| Graph | BestBuds graph export maps to WorkbenchGraphCatalog. |
React Flow renders actual graph data with improved node sizing. | Compose graph pane uses shared catalog and matching inspector patterns. |
| DevTools | Command API and command fixtures cover hot reload, commit, deploy, rollback, and tests. | DevTools screen shows command queue, preview, trace, and action controls. | Run was renamed to DevTools and the bottom drawer was brought closer to web. |
| Agent | Agent fixtures, command queue state, and interactor model. | Rich agent screen with command generation and queue management. | Agent mode is present in the shared toolbar and desktop pane model. |
| Database and Auth | Schema, query, provider, session, role, and RBAC-shaped fixtures. | Rich data and auth screens moved into Kotlin/React. | Desktop panes use the same subsystem summaries and visual language. |
| AI, Testing, Deploy, Insights | Subsystem fixtures and service mocks expose metrics, warnings, and actions. | Rich mode screens exist and are covered by Playwright tests. | Desktop shell exposes the same mode set and bottom command affordances. |
| Design language | Shared workbench tokens and fixture vocabulary. | Website remains visual source of truth. | Compose renderer adopted web-like typography, spacing, status colors, and shell structure. |
Tests and Performance
The test work expanded in three directions: common engine behavior, desktop renderer smoke coverage, and website browser coverage. Performance harnessing also moved toward a dedicated reaktor-performance concern.
Verified test commands
./gradlew :engine:jvmTest --no-daemon --console=plainpassed.npm run test:reaktorWeb:playwrightpassed with 84 tests../gradlew :engine:compileKotlinJs :reaktorDesktop:test --no-daemon --console=plainpassed../gradlew :reaktorDesktop:test --rerun-tasks --no-daemon --console=plainpassed with 13 desktop tests.
Coverage added
- Engine architecture, graph document, graph flow, feature, subsystem, and performance tests.
- Desktop smoke tests through the in-process driver and semantics bridge.
- Playwright shell, workbench, data/auth, testing/AI, agent, subsystem regression, cross-workbench, and performance specs.
- Bundle budget and web vitals style performance checks in
tests/reaktorWeb/performanceand Playwright performance specs.
reaktor-work Compose version warning, and Vite chunk/externalization warnings. They do not currently block the verified suites, but they are useful cleanup targets.
Real vs Mock
The direction is intentionally mixed: real where the codebase already has reliable source data, mock-backed where the subsystem surface is needed for parity but the backend is not ready.
| Status | Subsystems | Reason |
|---|---|---|
| Real | BestBuds graph topology, workbench mode model, app targets, route catalog mapping, renderer boot, desktop and website shells. | These now come from Kotlin code and existing graph/runtime data rather than disconnected web fixtures. |
| Typed mock | Auth, Database, Deploy, Testing, Insights, Agent, Messaging, Social, Media, UI, and AI subsystem summaries. | The UI needs real feature surfaces now, while the production adapters can be swapped in behind the same service contracts later. |
| Bridge | React Flow, React root, CSS loading, graph lazy loading, and JS library imports. | These stay in the thin TypeScript boundary until Reaktor has a cleaner first-class Kotlin/JS renderer bridge and code splitting story. |
Pain Points Found
The implementation worked, but it exposed where Reaktor Graph and the workbench architecture should become sharper.
Graph composition is verbose
Every workbench mode still needs a route binding, pane graph, container entry, route property, interactor property, and routeFor branch. The pattern is clear, but the amount of hand wiring is too high.
Auto-wire diagnostics are thin
autoWire() is powerful, but failures are opaque. It should explain unconnected consumers, candidate providers, qualifier mismatches, graph boundaries, and DI fallback results.
Navigation needs a registry
Mode navigation currently depends on explicit sentinel.edge(routeFor(mode)) calls and route node branches. A typed route registry would reduce boilerplate and make graph navigation inspectable.
Service mocks are too manual
Service declarations, API nodes, provider ports, and service nodes are related concepts but currently require separate declarations. A service registry could generate most of the glue.
JS bridge ergonomics are still rough
Kotlin/JS interop still requires global installation points and dynamic library bridges for React Flow. The remaining TypeScript boundary is small, but the shape should become generated and safer.
Visual graph adapters are duplicated
React Flow and Compose graph rendering both need node sizing, handles, ports, edge colors, labels, grouping, minimap metadata, and layout hints. This should be one canonical Reaktor Flow visual model.
Desktop UI testing is brittle
The in-process driver can still be forced into substring-based text interactions. Shared test tags and exact semantics actions should become mandatory for tabs, buttons, panes, and command items.
Real/mock maturity is not first-class
The fixtures express live and mock status, but graph nodes and subsystem contracts should carry maturity, adapter source, deployability, and fallback strategy as metadata.
Reaktor Graph Enhancements
The next graph work should reduce hand wiring while increasing introspection. The goal is the same BestBuds principle: fewer concepts, more expression, less bloat.
Add a graph builder that can declare a pane once and derive route binding, route node, container membership, mode registry, and navigation entrypoint.
workbenchPane(WorkbenchMode.DevTools) {
route("/devtools")
graph(::WorkbenchDevtoolsPaneGraph)
expose(::DevToolsInteractor)
}
Add a common inspection API that reports nodes, ports, edges, lifecycle state, route bindings, unconnected consumers, provider candidates, DI fallback attempts, and service handlers.
Promote graph visual concerns into shared Kotlin: node dimensions, handle placement, group bounds, minimap colors, edge category colors, labels, warnings, and layout hints. React Flow and Compose should become renderers of the same visual graph.
Deepen ActorNode so it owns a mailbox, effect handlers, supervised lifecycle, exclusive ObjectStore access, direct node map storage, durable command replay, and a Durable Object deploy path.
Let graph metadata generate smoke tests for routes, panes, services, ports, subsystem pages, and command actions. The workbench should be able to ask the graph what must be tested.
Instrument graph boot, route switch, port auto-wire, node render, edge render, layout, command queue execution, and subsystem service calls. Feed these into reaktor-performance, web vitals, app vitals, and flamegraph exports.
Next Steps
- Build the pane/route DSL inside
reaktor-graph, then rewriteWorkbenchGraphto prove the API reduces boilerplate. - Add
GraphInspectorand surface its diagnostics in both the website and desktop Graph pane. - Move graph visual sizing, handles, grouping, and layout hints into a common
ReaktorFlowVisualGraphmodel. - Turn the remaining TypeScript bridge into a small generated runtime adapter with explicit lazy-load hooks.
- Make subsystem maturity real in the graph: live, typed mock, stub, production adapter, deployable, and blocked.
- Add shared exact test IDs and semantics tags so Playwright and Compose tests can use the same intent names.
- Replace mock subsystem services one by one behind the existing common service APIs without changing the renderer contracts.
File Map
| Area | Files |
|---|---|
| Shared graph | modules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/graph/WorkbenchGraph.ktmodules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/graph/panes/WorkbenchPaneGraphs.kt |
| Shared services and ports | modules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/data/services/WorkbenchApis.ktmodules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/data/services/WorkbenchService.kt |
| Shared model and fixtures | modules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/model/WorkbenchGraphCatalog.ktmodules/engine/src/commonMain/kotlin/ai/bestbuds/reaktor/workbench/fixtures/WorkbenchFixtures.kt |
| Website Kotlin/React renderer | modules/engine/src/jsMain/kotlin/ai/bestbuds/reaktor/workbench/render/react |
| Website TypeScript boundary | modules/engine/src/jsMain/react/main.ts |
| Desktop Compose renderer | modules/engine/src/jvmMain/kotlin/ai/bestbuds/reaktor/workbench/render/compose |
| Engine tests | modules/engine/src/jvmTest/kotlin/ai/bestbuds/reaktor |
| Desktop tests | targets/reaktorDesktop/src/test/kotlin/ai/bestbuds/reaktor |
| Website tests | tests/reaktorWeb/playwrighttests/reaktorWeb/performance |