Live demonstration of AI-controllable React applications with @Tool decorators
This demo uses two packages:
- @supernal/interface - Open-source core package (PUBLIC)
- @supernal/interface-enterprise - Enterprise features + CLI tools (PROPRIETARY)
See Repository Structure below for development workflow.
The Supernal Interface CLI (si) is included with the enterprise package and provides portable tools for working with @Tool decorators:
# Generate tests from @Tool decorators
npm run si:generate-tests
# Scan and generate route contracts
npm run contracts:routes
# Scan and generate name contracts
npm run contracts:names
# Benchmark Story System caching
npm run si:benchmark
# Validate contracts
npm run si:validate📖 Full CLI documentation: docs/CLI.md
This demo shows how to transform any React application into an AI-controllable system using simple decorators.
Challenge: Traditional approaches to AI-controlled UIs require:
- Manual API development for every interaction
- Fragile CSS selectors that break with UI changes
- Separate test infrastructure
- Complex tool registration and discovery
- No clear safety boundaries
Solution: Supernal Interface provides:
- Single
@Tooldecorator defines everything - Stable component names prevent breakage
- Automatic test generation
- Built-in tool discovery and registration
- Explicit safety levels and approval workflows
File: src/lib/UIWidgetComponents.tsx
Simple HOC wrappers (ClickTool, ChangeTool) transform ordinary React components into AI-controllable tools:
export const SaveButton = ClickTool({
elementId: Components.Demo.saveButton,
description: 'Save user data',
aiEnabled: true,
dangerLevel: 'safe',
examples: ['save data', 'save file']
})(({ className, reportSuccess }) => {
const handleClick = async () => {
await saveData();
reportSuccess?.('Data saved!');
};
return <button onClick={handleClick}>Save</button>;
});What you get automatically:
- ✅ Tool registration in global registry
- ✅ Natural language command matching
- ✅ Success/failure reporting
- ✅ Container-aware execution
- ✅ Test generation ready
File: core/names/Components.ts
Stable, type-safe component identifiers used across testing, AI control, and analytics:
export const Components = {
Demo: {
openMainMenu: 'open-main-menu',
saveButton: 'save-button',
emailInput: 'email-input'
}
} as const;Benefits:
- No magic strings scattered in code
- TypeScript autocomplete everywhere
- Rename once, updates everywhere
- Same names for tools, tests, and UI
File: src/providers/Phase1DemoProviders.ts
Tools are test-only until explicitly enabled for AI:
@Tool({
elementId: Components.Demo.deleteButton,
description: 'Delete all user data',
aiEnabled: true, // Must explicitly enable
dangerLevel: 'dangerous', // Clear safety level
requiresApproval: true, // Requires user confirmation
examples: ['delete everything']
})
async deleteAllData() {
// Only runs if user approves
}Safety levels:
safe- Read-only or reversible actionsmoderate- State changes, requires validationdangerous- Destructive actions, requires approval
What the demo shows: The "Current State (Indicated by @Tool Methods)" display at the bottom of the widget section demonstrates that state is maintained by the @Tool decorated methods, not separate state management:
// Tool automatically updates state AND reports to AI
const result = await getUIControls().toggleNotifications(enabled);
reportSuccess?.(result.message); // AI notified automaticallyFile: src/lib/AIInterface.ts
AI matches user commands to tools using examples and descriptions:
User: "turn on notifications"
↓
Finds: NotificationsToggle tool (examples: ['toggle notifications', 'enable notifications'])
↓
Executes: Tool's onChange handler
↓
Reports: "Notifications enabled" (via reportSuccess callback)
File: src/architecture/DemoContainers.ts
Tools specify which container they belong to - AI knows where tools can execute:
export const DemoContainer = {
id: 'Demo',
components: [
'open-main-menu',
'save-button',
'email-input'
]
};
// Tool specifies its container
@ClickTool({
containerId: 'Demo', // Only available in Demo container
...
})┌─────────────────────────────────────────────────────────┐
│ Component Names Registry │
│ (Centralized, Type-Safe, Stable) │
│ │
│ Components.ts: { saveButton, emailInput, ... } │
│ Containers.ts: { Demo, Settings, Workspace, ... } │
└────────────┬─────────────────────────┬──────────────────┘
│ │
┌────────▼──────────┐ ┌────────▼──────────┐
│ UI Components │ │ Tool Providers │
│ (Plain React) │ │ (@Tool/@ClickTool)│
└───────────────────┘ └───────────────────┘
│ │
│ <button │ @ClickTool({
│ data-testid= │ elementId: Components.saveButton,
│ {Components. │ aiEnabled: true,
│ saveButton} │ containerId: 'Demo'
│ /> │ })
│ │
└────────────────────────┘
Same Names, Unified Contract
- Node.js 18+
- npm or pnpm
When developing locally in the monorepo:
# From monorepo root (@supernal-interface/)
cd docs-site
npm install
npm run devThe demo uses local builds of open-source/ and enterprise/ packages via git submodules.
When cloned from the public repo:
git clone https://github.com/supernalintelligence/interface-docs.git
cd interface-docs
npm install # Installs @supernal/interface from npm
npm run devFor enterprise features, you'll need access to the private @supernal/interface-enterprise package.
core/names/Components.ts- 35 UI component namescore/names/Containers.ts- 25 container context namescore/names/API.ts- 24 API endpoint namescore/names/Functions.ts- 29 pure function names
src/lib/UIWidgetComponents.tsx- HOC-wrapped components (ClickTool, ChangeTool)src/components/InteractiveWidgets.tsx- Live widget zoosrc/components/pages/HomePage.tsx- Landing page explaining the systemsrc/components/pages/DemoPage.tsx- Interactive demo
src/lib/UIControls.ts- Tool execution logicsrc/lib/AIInterface.ts- Simulated AI command matchingsrc/lib/ToolManager.ts- Tool execution tracking and reportingsrc/architecture/DemoContainers.ts- Container definitions
tests/phase1.spec.ts- Playwright tests verifying functionality
| Feature | LangChain | Supernal Interface |
|---|---|---|
| Tool Definition | Manual function + schema | Single @Tool decorator |
| UI Integration | Separate from UI | UI component IS the tool |
| Testing | Manual test creation | Auto-generated from decorators |
| Type Safety | Runtime validation | TypeScript compile-time |
| React-Specific | ❌ No | ✅ Yes - HOCs, hooks, components |
| Approach | Fragility | Maintenance | Safety |
|---|---|---|---|
| CSS Selectors | High (breaks with UI changes) | Manual updates | No built-in safety |
| Custom APIs | Low | High (parallel to UI) | Manual enforcement |
| Supernal Interface | Low (stable names) | Automatic | Built-in danger levels |
cd core/demo
npx playwright test tests/phase1.spec.ts- ✅ Component names render on DOM elements
- ✅ Tools execute and report success
- ✅ State updates reflect in UI
- ✅ AI command matching works
- ✅ Container-aware tool execution
- Explore the Live Demo - See tools in action
- Read the Code - Check out
UIWidgetComponents.tsxfor HOC patterns - Review Documentation -
../../docs/STATUS.mdfor implementation details - Try Integration - Follow patterns to add to your own React app
- Open-Source Package: github.com/supernalintelligence/interface
- This Demo: github.com/supernalintelligence/interface-docs
- npm Package: @supernal/interface (after publishing)
This project is part of a multi-repository setup:
Development (Monorepo):
@supernal-interface/
├── open-source/ (submodule → github.com/supernalintelligence/interface)
├── enterprise/ (private, stays in monorepo)
└── docs-site/ (submodule → github.com/supernalintelligence/interface-docs)
Published (Separate Repos):
- github.com/supernalintelligence/interface (PUBLIC - npm: @supernal/interface)
- github.com/supernalintelligence/interface-docs (PUBLIC - this repo)
- npm: @supernal/interface-enterprise (PRIVATE)
During Development (in monorepo):
- Changes made in
open-source/ordocs-site/are in their respective git repos - Commit and push to their GitHub remotes independently
- Enterprise package stays in the monorepo
Publishing Updates:
- Make changes in monorepo (e.g.,
open-source/src/...) - Commit to submodule:
cd open-source && git commit && git push - Publish to npm:
cd open-source && npm publish - Update monorepo to track new submodule commit:
cd .. && git add open-source && git commit
See HANDOFF.md for detailed workflow.
- Open-Source Issues: interface/issues
- Docs/Demo Issues: interface-docs/issues
- Enterprise Support: Contact your account representative
Built with @supernal-interface/core
Zero-boilerplate AI control for React applications