App Examples
Nebo apps are complete frontend applications built with any framework you choose. They are not HTML pages embedded in a chat window -- they are full applications that open in their own window, backed by an AI agent and an optional native sidecar binary. This page walks through real-world apps spanning vanilla HTML, HTMX, Vue 3, React 19, Solid.js, and SvelteKit -- from a 220-line minimal example to a 24-skill enterprise legal assistant.
@neboai/app-sdk for storage, identity, agent invocation, and external HTTP fetching. The frontend framework is entirely your choice -- Nebo does not impose one. Use React, Vue, Solid, Svelte, HTMX, or plain HTML.Common Architecture
Every Nebo app follows the same directory convention regardless of which frontend framework it uses. The build system is a Makefile that orchestrates pnpm (frontend) and cargo (sidecar) into a final ui/ directory and a bin/ directory.
Standard directory structure
my-app/
+-- manifest.json # App identity, window config, permissions
+-- agent.json # Skills, workflows, tools, inputs
+-- AGENT.md # Agent persona (system prompt)
+-- Makefile # Orchestrates frontend + sidecar builds
+-- frontend/ # Any framework: React, Vue, Solid, Svelte, etc.
| +-- package.json
| +-- src/
| +-- vite.config.ts
+-- sidecar/ # Optional Rust binary (gRPC over Unix socket)
| +-- Cargo.toml
| +-- src/
+-- skills/ # Bundled skill definitions (SKILL.md files)
+-- ui/ # Build output (frontend static files)
| +-- index.html
+-- bin/ # Build output (sidecar binary)
+-- my-appmanifest.json schema
The manifest declares the app's identity, window configuration, and required permissions. Every app has one.
{
"id": "my-app",
"name": "@nebo/agents/my-app",
"version": "1.0.0",
"description": "What the app does.",
"type": "app",
"permissions": [
"storage:readwrite",
"subagent:invoke",
"network:outbound"
],
"window": {
"title": "My App",
"width": 1200,
"height": 800,
"min_width": 600,
"min_height": 500,
"resizable": true
}
}agent.json schema
The agent configuration defines skills, workflows, sidecar tools, user-configurable inputs, and plugin dependencies. Simple apps may leave this mostly empty; enterprise apps can define dozens of skills and complex workflow DAGs.
{
"skills": ["skills/my-skill-1", "skills/my-skill-2"],
"inputs": [
{
"key": "setting_name",
"label": "Setting Label",
"type": "select",
"options": [
{ "label": "Option A", "value": "a" },
{ "label": "Option B", "value": "b" }
],
"default": "a",
"required": false
}
],
"requires": {
"plugins": ["plugin-slug-1", "plugin-slug-2"]
},
"tools": [
{
"name": "tool_name",
"description": "What the tool does",
"method": "GET",
"path": "/api/endpoint"
}
],
"workflows": {
"workflow-name": {
"description": "What the workflow does",
"trigger": { "type": "manual" },
"activities": [...]
}
}
}Build pattern
A typical Makefile builds the frontend and sidecar in parallel:
.PHONY: all build build-frontend build-sidecar dev clean all: build build: build-frontend build-sidecar build-frontend: cd frontend && pnpm install && pnpm build @echo "Frontend built -> ui/" build-sidecar: cd sidecar && cargo build --release mkdir -p bin cp sidecar/target/release/my-sidecar bin/my-app @echo "Sidecar built -> bin/my-app" dev: @echo "Start sidecar: cd sidecar && cargo run" @echo "Start frontend: cd frontend && pnpm dev" clean: rm -rf ui/ bin/ cd sidecar && cargo clean cd frontend && rm -rf node_modules
Minimal Example: hello-app
The simplest possible Nebo app. A single HTML file with no build step, no framework, no sidecar. It demonstrates every SDK capability: identity, storage, agent invoke, external fetch, and embedded chat.
| Property | Value |
|---|---|
| Frontend | Vanilla HTML + JS |
| Sidecar | None |
| Skills | 0 |
| Permissions | None (SDK features are always available) |
| Build step | None -- serve ui/index.html directly |
manifest.json
{
"id": "hello-app",
"name": "@nebo/agents/hello-app",
"version": "1.0.0",
"description": "A minimal Nebo app that demonstrates the SDK -- storage, agent invoke, and HTTP proxy.",
"type": "app",
"window": {
"title": "Hello App",
"width": 800,
"height": 600,
"min_width": 400,
"min_height": 300,
"resizable": true
},
"permissions": []
}agent.json
The simplest possible agent configuration -- no skills, no workflows, no inputs:
{
"workflows": {},
"skills": [],
"inputs": []
}AGENT.md (persona)
# Hello App You are the Hello App assistant. You help users understand how Nebo apps work. When asked a question, respond concisely and helpfully. Explain SDK concepts like storage, agent invoke, and HTTP proxy in simple terms. ## What You Know - Nebo apps are agents with a face (UI) and optional sidecar (binary) - The @nebo/app-sdk mirrors native browser APIs: fetch, WebSocket, localStorage - Apps always pop out in their own window -- never inline - Storage is key-value, persisted server-side, scoped to this app - External HTTP requests are proxied through Nebo (zero CORS issues)
ui/index.html -- the complete app
This single file is the entire frontend. It loads the SDK via a script tag and uses five SDK capabilities. Study this file to understand the full SDK surface area.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="nebo-app-id" content="hello-app">
<title>Hello App</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
background: #f8f9fa; color: #1a1a1a;
display: flex; flex-direction: column; min-height: 100vh;
}
header {
padding: 16px 24px; border-bottom: 1px solid #e5e7eb;
background: white; display: flex; align-items: center; gap: 12px;
}
header h1 { font-size: 16px; font-weight: 600; }
.layout { flex: 1; display: flex; min-height: 0; }
.main { flex: 1; overflow-y: auto; padding: 24px; max-width: 640px; }
.chat-panel { width: 380px; border-left: 1px solid #e5e7eb; }
.card {
background: white; border: 1px solid #e5e7eb; border-radius: 12px;
padding: 20px; margin-bottom: 16px;
}
button {
background: #0077a8; color: white; border: none; border-radius: 8px;
padding: 8px 16px; font-size: 13px; cursor: pointer;
}
.response {
background: #f0fdf4; border: 1px solid #86efac; border-radius: 8px;
padding: 12px; font-size: 13px; margin-top: 12px; white-space: pre-wrap;
}
.response.error { background: #fef2f2; border-color: #fca5a5; }
</style>
</head>
<body>
<header>
<h1 id="app-title">Hello App</h1>
</header>
<div class="layout">
<div class="main">
<div class="card">
<h2>Identity</h2>
<p>Fetch this app's agent profile from Nebo.</p>
<button onclick="loadIdentity()">Load Identity</button>
<div id="identity-result"></div>
</div>
<div class="card">
<h2>Storage</h2>
<p>Read and write key-value pairs persisted by Nebo.</p>
<input type="text" id="kv-key" placeholder="Key">
<input type="text" id="kv-value" placeholder="Value">
<button onclick="saveKV()">Save</button>
<button onclick="loadKV()">Load</button>
<button onclick="listKV()">List All</button>
</div>
<div class="card">
<h2>External Fetch</h2>
<p>Fetch data from an external API through Nebo's CORS-free proxy.</p>
<input type="text" id="fetch-url" value="https://httpbin.org/get">
<button onclick="doFetch()">Fetch</button>
<div id="fetch-result"></div>
</div>
<div class="card">
<h2>Agent Invoke</h2>
<p>Send a message to this app's agent via the SDK.</p>
<input type="text" id="agent-input" placeholder="Ask the agent something...">
<button onclick="askAgent()" id="agent-btn">Ask</button>
<div id="agent-response"></div>
</div>
</div>
<div class="chat-panel" id="chat-container"></div>
</div>
<script src="/sdk/nebo.global.js"></script>
<script>
const nebo = window.NeboAppSDK.nebo;
// -- Embedded Chat --
nebo.chat.mount(document.getElementById('chat-container'), {
height: '100%',
borderless: true,
placeholder: 'Chat with Hello App...',
});
nebo.chat.onMessage(function(msg) {
if (msg.type === 'nebo:response-complete') {
console.log('[hello-app] Agent finished:', msg.text?.substring(0, 80));
}
});
// -- Identity --
window.loadIdentity = async function() {
const me = await nebo.identity.get();
document.getElementById('app-title').textContent = me.displayName || me.name;
};
// -- Storage --
window.saveKV = async function() {
const key = document.getElementById('kv-key').value;
const value = document.getElementById('kv-value').value;
if (!key) return;
await nebo.storage.setItem(key, value);
};
window.loadKV = async function() {
const key = document.getElementById('kv-key').value;
if (!key) return;
const value = await nebo.storage.getItem(key);
alert(value !== null ? key + ' = ' + value : 'Key not found');
};
window.listKV = async function() {
const keys = await nebo.storage.keys();
const items = await Promise.all(keys.map(async function(k) {
const v = await nebo.storage.getItem(k);
return k + ': ' + v;
}));
alert(items.join('\n') || 'No items stored yet');
};
// -- Agent Invoke --
window.askAgent = async function() {
const input = document.getElementById('agent-input');
const msg = input.value.trim();
if (!msg) return;
const result = await nebo.agents.invoke(msg);
document.getElementById('agent-response').innerHTML =
'<div class="response">' + (result.text || JSON.stringify(result)) + '</div>';
};
// -- External Fetch --
window.doFetch = async function() {
const url = document.getElementById('fetch-url').value;
if (!url) return;
const resp = await nebo.fetch(url);
const data = await resp.json();
document.getElementById('fetch-result').innerHTML =
'<div class="response"><pre>' + JSON.stringify(data, null, 2) + '</pre></div>';
};
loadIdentity();
</script>
</body>
</html>nebo.identity.get() for the agent's profile, nebo.storage for persistent key-value data, nebo.agents.invoke() for programmatic agent calls, nebo.fetch() for CORS-free external HTTP, and nebo.chat.mount() for an embedded chat panel. See App SDK for the full API reference.HTMX Example: journal
A server-driven journaling app that uses HTMX instead of a JavaScript framework. The frontend is a single HTML file with no build step -- all interactivity comes from HTMX attributes that make requests to the Rust sidecar. The sidecar renders HTML partials and manages a SQLite database for journal entries.
| Property | Value |
|---|---|
| Frontend | HTMX (zero JS framework) |
| Sidecar | Rust (serves HTML partials over gRPC) |
| Permissions | storage:readwrite, subagent:invoke |
| Build step | Sidecar only (cargo build --release) |
manifest.json
{
"id": "journal",
"name": "@nebo/agents/journal",
"version": "1.0.0",
"description": "AI-powered journal with reflection prompts. Built with HTMX + Rust sidecar -- zero JS framework.",
"type": "app",
"permissions": ["storage:readwrite", "subagent:invoke"],
"window": {
"title": "Journal",
"width": 700,
"height": 800,
"min_width": 400,
"min_height": 500,
"resizable": true
}
}Architecture
The journal app demonstrates the zero-JavaScript-framework approach. HTMX sends requests to the sidecar, which returns HTML fragments that HTMX swaps into the page. The sidecar handles all data persistence in SQLite.
# Directory structure
journal/
+-- manifest.json
+-- agent.json
+-- AGENT.md
+-- Makefile
+-- sidecar/ # Rust sidecar (renders HTML partials)
| +-- Cargo.toml
| +-- src/
+-- ui/
| +-- index.html # HTMX frontend (no build step)
+-- bin/
+-- journal # Compiled sidecar binary
# Makefile -- note: no frontend build step
build: build-sidecar
build-sidecar:
cd sidecar && cargo build --release
mkdir -p bin
cp sidecar/target/release/journal-sidecar bin/journal
@echo "Frontend: ui/index.html (no build step -- HTMX)"AGENT.md
# Journal Companion You are a thoughtful journaling companion. You help users reflect on their day, clarify their thinking, and build self-awareness. ## What You Do 1. Ask reflective questions that go deeper than surface-level 2. Notice patterns across entries (recurring themes, emotions, goals) 3. Offer gentle reframes when the user is stuck in negative loops 4. Celebrate progress -- even small wins ## Communication Style - Warm but not saccharine - Questions over advice - Mirror the user's energy -- if they're brief, be brief - Never judge what they write
Vue 3 Example: contacts
A full single-page application built with Vue 3, Vite, and TypeScript. The frontend compiles to static files in ui/, and a Rust sidecar manages the contact database. This is a typical setup for apps that need reactive UI patterns and a rich component library.
| Property | Value |
|---|---|
| Frontend | Vue 3.5 + Vite 6 + TypeScript |
| Sidecar | Rust |
| Permissions | storage:readwrite, subagent:invoke, network:outbound |
manifest.json
{
"id": "contacts",
"name": "@nebo/agents/contacts",
"version": "1.0.0",
"description": "Smart contact manager with relationship intelligence. Built with Vue + Rust sidecar.",
"type": "app",
"permissions": ["storage:readwrite", "subagent:invoke", "network:outbound"],
"window": {
"title": "Contacts", "width": 960, "height": 700,
"min_width": 480, "min_height": 400, "resizable": true
}
}frontend/package.json
{
"name": "contacts-frontend",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@a2ui/lit": "^0.9.0",
"@a2ui/web_core": "^0.9.0",
"@neboai/app-sdk": "^0.1.0",
"vue": "^3.5.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.0",
"typescript": "^5.9.0",
"vite": "^6.0.0",
"vue-tsc": "^2.0.0"
}
}@a2ui/lit and @a2ui/web_core packages provide Nebo's shared component library. These are framework-agnostic web components that work with Vue, React, Solid, or any other framework.React 19 Example: portfolio
An investment portfolio tracker built with React 19, Vite 6, and TypeScript. The Rust sidecar handles market data fetching and portfolio calculations.
manifest.json
{
"id": "portfolio",
"name": "@nebo/agents/portfolio",
"version": "1.0.0",
"description": "Investment portfolio tracker with AI analysis. Built with React + Rust sidecar.",
"type": "app",
"permissions": ["storage:readwrite", "subagent:invoke", "network:outbound"],
"window": {
"title": "Portfolio", "width": 1100, "height": 750,
"min_width": 500, "min_height": 400, "resizable": true
}
}frontend/package.json
{
"name": "portfolio-frontend",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"preview": "vite preview"
},
"dependencies": {
"@a2ui/react": "^0.9.0",
"@a2ui/web_core": "^0.9.0",
"@neboai/app-sdk": "^0.1.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.0.0",
"typescript": "^5.9.0",
"vite": "^6.0.0"
}
}@a2ui/react package instead of @a2ui/lit. Nebo provides framework-specific wrappers for React that integrate with hooks and JSX patterns. The core SDK (@neboai/app-sdk) is the same across all frameworks.Solid.js Example: dashboard
A business metrics dashboard built with Solid.js 1.9 and Vite. Solid.js compiles reactive primitives into vanilla DOM operations -- no virtual DOM -- making it ideal for data-heavy dashboards that need fast updates.
manifest.json
{
"id": "dashboard",
"name": "@nebo/agents/dashboard",
"version": "1.0.0",
"description": "Business metrics dashboard with AI insights. Built with Solid.js + Rust sidecar.",
"type": "app",
"permissions": ["storage:readwrite", "subagent:invoke", "network:outbound"],
"window": {
"title": "Dashboard", "width": 1200, "height": 800,
"min_width": 600, "min_height": 450, "resizable": true
}
}frontend/package.json
{
"name": "dashboard-frontend",
"private": true,
"version": "0.1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@a2ui/lit": "^0.9.0",
"@a2ui/web_core": "^0.9.0",
"@neboai/app-sdk": "^0.1.0",
"solid-js": "^1.9.0"
},
"devDependencies": {
"typescript": "^5.7.0",
"vite": "^6.0.0",
"vite-plugin-solid": "^2.11.0"
}
}SvelteKit Example: ads-manager
A Meta Ads management dashboard built with SvelteKit 2 and the static adapter. SvelteKit provides file-based routing, server-side rendering (compiled to static), and Svelte 5 runes for reactivity.
manifest.json
{
"id": "ads-manager",
"name": "@nebo/agents/ads-manager",
"version": "1.0.0",
"description": "Meta Ads management dashboard with AI-powered optimization.",
"type": "app",
"permissions": ["storage:readwrite", "subagent:invoke", "network:outbound"],
"window": {
"title": "Ads Manager", "width": 1280, "height": 900,
"min_width": 768, "min_height": 500, "resizable": true
}
}frontend/package.json
{
"name": "ads-manager-frontend",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"typescript": "^5.9.0",
"vite": "^6.0.0"
},
"dependencies": {
"@neboai/app-sdk": "^0.1.0"
}
}ui/, SvelteKit must use @sveltejs/adapter-static to prerender all routes at build time. Runtime server-side rendering is handled by the Rust sidecar, not by SvelteKit's Node.js server.Enterprise Example: brief
Brief is a full-stack AI-powered legal assistant. SvelteKit frontend with Tailwind 4, PDF/DOCX rendering libraries, a Rust sidecar with SQLite for document storage, 24 bundled skills, 8 automated workflows, and integration with Google Workspace and DocuSign via MCP plugins. This represents the upper end of what a Nebo app can be.
| Property | Value |
|---|---|
| Frontend | SvelteKit 2 + Svelte 5 + Tailwind 4 + adapter-static |
| Sidecar | Rust + SQLite |
| Skills | 24 |
| Workflows | 8 (manual, event-driven, scheduled, watch triggers) |
| Sidecar tools | 60+ REST endpoints exposed as agent tools |
| Plugin dependencies | nebo-office, gws, docusign |
frontend/package.json
{
"name": "brief-frontend",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@sveltejs/adapter-static": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/vite": "^4.3.0",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.3.0",
"typescript": "^5.9.0",
"vite": "^6.0.0"
},
"dependencies": {
"@a2ui/lit": "^0.9.0",
"@a2ui/web_core": "^0.9.0",
"@neboai/app-sdk": "^0.1.0",
"docx-preview": "^0.3.7",
"exceljs": "^4.4.0",
"marked": "^18.0.3",
"pdfjs-dist": "^4.10.38"
}
}Directory structure
brief/
+-- manifest.json
+-- agent.json # 24 skills, 60+ tools, 8 workflows
+-- AGENT.md
+-- Makefile
+-- frontend/ # SvelteKit + Tailwind 4
| +-- package.json
| +-- src/
| +-- vite.config.ts
+-- sidecar/ # Rust + SQLite
| +-- Cargo.toml
| +-- src/
+-- proto/ # Shared gRPC definitions
+-- skills/ # 24 bundled SKILL.md files
| +-- workspace-management/
| +-- document-analysis/
| +-- contract-summary/
| +-- cp-checklist/
| +-- docx-generation/
| +-- nda-review/
| +-- pipeline-orchestration/
| +-- ... (17 more)
+-- docs/
+-- ui/ # Build output
+-- bin/
+-- briefSkills (24 bundled)
Brief ships with a comprehensive set of legal analysis skills:
workspace-management # Project/folder CRUD document-analysis # Document type identification contract-summary # Key terms extraction cp-checklist # Conditions precedent tracking tabular-extraction # Structured data extraction docx-generation # Create DOCX from markdown document-editing # Tracked change suggestions review # Tabular review orchestration nda-review # NDA-specific analysis vendor-agreement-review # Vendor agreement analysis saas-msa-review # SaaS MSA analysis amendment-history # Amendment tracking escalation-flagger # Risk escalation stakeholder-summary # Executive summaries renewal-tracker # Contract renewal tracking cold-start-interview # New user onboarding customize # User preference setup matter-workspace # Matter management review-proposals # Proposal review contract-inbox-triage # Email ingestion docusign-envelope-handler # DocuSign integration quorum-extraction # Multi-agent extraction escalation-surface # Escalation UI pipeline-orchestration # Batch processing
Workflows
Brief defines 8 workflows with different trigger types. See Workflows for trigger type documentation.
| Workflow | Trigger | Description |
|---|---|---|
contract-inbox | watch (Gmail) | Watch inbox for contract attachments, auto-analyze |
contract-review | manual | Full contract review with summary + CP checklist |
document-pipeline | event | 3-agent quorum extraction with consensus |
document-triage | event | Auto-analyze on upload |
docusign-envelope-poll | heartbeat (30m) | Poll DocuSign for signed documents |
folder-watch | folder | Watch filesystem for new documents |
morning-review-digest | schedule (cron) | Daily 8am digest of pending reviews |
webhook-ingest | event (webhook) | Ingest documents from external webhooks |
User-configurable inputs
Brief lets users configure their experience through the inputs field in agent.json. These appear as settings in the app's configuration panel:
"inputs": [
{
"key": "default_model",
"label": "Default LLM Model",
"type": "select",
"default": "claude-sonnet-4-6",
"options": [
{ "label": "Claude Opus 4.6", "value": "claude-opus-4-6" },
{ "label": "Claude Sonnet 4.6", "value": "claude-sonnet-4-6" },
{ "label": "Claude Haiku 4.5", "value": "claude-haiku-4-5" }
]
},
{
"key": "practice_area",
"label": "Primary Practice Area",
"type": "select",
"default": "corporate",
"options": [
{ "label": "Corporate / M&A", "value": "corporate" },
{ "label": "Banking & Finance", "value": "finance" },
{ "label": "Intellectual Property", "value": "ip" },
{ "label": "Litigation", "value": "litigation" },
{ "label": "General Practice", "value": "general" }
]
}
]Multi-Agent Example: small-business-suite
The largest app in the Nebo ecosystem. A complete small business command center with 31 skills, 12 MCP connector plugins, 18 workflows (scheduled, event-driven, and manual), and approval gates. Built with Solid.js for the frontend and Rust for the sidecar.
| Property | Value |
|---|---|
| Frontend | Solid.js 1.9 + Vite 6 |
| Skills | 31 |
| Workflows | 18 |
| Plugin dependencies | 12 MCP connectors |
| Permissions | storage:readwrite, subagent:invoke, network:outbound, memory:read, mcp:invoke |
Plugin dependencies (12 MCP connectors)
"requires": {
"plugins": [
"quickbooks", // Accounting + invoicing
"paypal", // Payment processing
"hubspot", // CRM + sales pipeline
"canva", // Design + marketing assets
"docusign", // Contract signing
"slack", // Team communication
"stripe", // Payment processing
"square", // POS + payments
"ms365", // Microsoft Office suite
"gmail", // Email
"google-calendar", // Calendar
"google-drive" // File storage
]
}Skills (31 bundled)
business-pulse # Real-time business health call-list # Daily prioritized call list canva-creator # Canva design generation cash-flow-snapshot # Cash flow analysis close-month # Month-end closing content-strategy # Content planning contract-review # Contract analysis crm-cleanup # CRM data hygiene crm-maintenance # Ongoing CRM upkeep customer-pulse # Customer health scoring customer-pulse-check # Customer check-in friday-brief # End-of-week summary handle-complaint # Complaint resolution invoice-chase # Overdue invoice follow-up job-post-builder # Job listing creation lead-triage # Lead scoring + routing margin-analyzer # Profit margin analysis monday-brief # Start-of-week planning month-end-prep # Pre-close preparation month-heads-up # Monthly forecast plan-payroll # Payroll preparation price-check # Competitive pricing quarterly-review # Quarterly business review review-contract # Contract review (detailed) run-campaign # Marketing campaign execution sales-brief # Sales pipeline summary smb-onboard # New business onboarding smb-router # Intent routing tax-prep # Tax preparation tax-season-organizer # Tax season planning ticket-deflector # Support ticket triage
Workflows (18)
# Scheduled workflows morning-pulse # Daily 7:30am business health check monday-brief # Weekly Monday planning friday-brief # Weekly Friday wrap-up weekly-business-review # Weekly performance review payroll-check # Bi-weekly payroll prep invoice-chase-auto # Daily overdue invoice follow-up contract-deadline-scan # Daily contract deadline check quarterly-review # Quarterly business analysis month-end-close # Monthly close process # Manual workflows run-campaign # Marketing campaign execution tax-prep # Tax season preparation crm-cleanup # CRM data maintenance review-contract # Contract review hire # Hiring workflow # Event-driven workflows check-business # On-demand business check deal-won # Triggered on deal close complaint-received # Triggered on complaint lead-qualified # Triggered on lead qualification
Shared gRPC Protocol
All app sidecars implement the same gRPC service defined in proto/ui.proto. This protocol lets Nebo communicate with any sidecar -- regardless of implementation language -- through a Unix domain socket. See App Sidecar for the full architecture.
proto/common.proto
syntax = "proto3";
package apps.v0;
message HealthCheckRequest {}
message HealthCheckResponse {
bool healthy = 1;
string version = 2;
string name = 3;
}
message SettingsMap {
map<string, string> values = 1;
}
message Empty {}
proto/ui.proto
syntax = "proto3";
package apps.v0;
import "proto/common.proto";
service UIService {
rpc HealthCheck(HealthCheckRequest) returns (HealthCheckResponse);
rpc Configure(SettingsMap) returns (Empty);
rpc HandleRequest(HttpRequest) returns (HttpResponse);
}
message HttpRequest {
string method = 1;
string path = 2;
string query = 3;
map<string, string> headers = 4;
bytes body = 5;
}
message HttpResponse {
int32 status_code = 1;
map<string, string> headers = 2;
bytes body = 3;
}The UIService has three methods:
- HealthCheck -- Nebo calls this on startup and periodically to verify the sidecar is running. Returns the sidecar's name and version.
- Configure -- Passes user configuration (from
agent.jsoninputs) to the sidecar at startup. - HandleRequest -- Proxies HTTP requests from the agent's tools to the sidecar. The agent defines tool endpoints in
agent.json(e.g.,GET /projects), and Nebo translates them into gRPCHandleRequestcalls.
SDK Integration Patterns
Every app uses @neboai/app-sdk regardless of framework. The SDK provides five core capabilities that mirror familiar browser APIs. See App SDK for the full reference.
Loading the SDK
In vanilla HTML, load via script tag. In framework apps, import the npm package:
<!-- Vanilla HTML: script tag -->
<script src="/sdk/nebo.global.js"></script>
<script>
const nebo = window.NeboAppSDK.nebo;
</script>
// Framework apps: npm import
import { nebo } from '@neboai/app-sdk';Identity
const me = await nebo.identity.get();
// { id, name, displayName, model, skills: [...] }Storage
Persistent key-value storage scoped to the current app. Mirrors the localStorage API:
await nebo.storage.setItem('key', 'value');
const value = await nebo.storage.getItem('key');
const allKeys = await nebo.storage.keys();Agent Invoke
const result = await nebo.agents.invoke('Analyze this document');
// { text: "The document contains..." }Fetch (CORS-free HTTP proxy)
const resp = await nebo.fetch('https://api.example.com/data');
const data = await resp.json();Chat Embed
nebo.chat.mount(document.getElementById('chat-container'), {
height: '100%',
borderless: true,
placeholder: 'Ask a question...',
});
nebo.chat.onMessage(function(msg) {
if (msg.type === 'nebo:response-complete') {
console.log('Agent finished:', msg.text);
}
});Summary Table
All example apps at a glance. Every one of these is a complete, standalone frontend application -- not a widget or a page fragment.
| App | Frontend | Sidecar | Skills | Complexity |
|---|---|---|---|---|
| hello-app | Vanilla HTML/JS | None | 0 | Minimal |
| journal | HTMX | Rust | 0 | Simple |
| contacts | Vue 3 + Vite | Rust | 0 | Standard |
| portfolio | React 19 + Vite | Rust | 0 | Standard |
| dashboard | Solid.js 1.9 + Vite | Rust | 0 | Standard |
| ads-manager | SvelteKit 2 + Svelte 5 | Rust | 0 | Standard |
| brief | SvelteKit 2 + Tailwind 4 | Rust + SQLite | 24 | Enterprise |
| small-business-suite | Solid.js 1.9 + Vite | Rust | 31 | Enterprise |
@neboai/app-sdk, which works identically everywhere.For more details on the underlying systems, see: Apps Overview for the app lifecycle, App SDK for the full SDK API reference, and App Sidecar for the gRPC sidecar architecture.