Docs
Mini App development guide
Build installable, permission-aware, upgradeable Mini Apps with the Beav package format, the window.redbox SDK, and Host capabilities.
A Beav Mini App is a local sandboxed app installed inside Beav. It is built from static HTML, CSS, and JavaScript, keeps its interface state through the window.redbox SDK, and calls Beav's capture, knowledge base, asset library, media, AI, and automation capabilities once the user grants permission.
This guide is written for developers and for the Agents that build Mini Apps for them. Public docs describe the stable way to develop; the capabilities, parameters, and permissions actually available on a device always come from the local runtime.
Understand the two tool sets first
Mini App work involves two separate tool sets. They are not interchangeable.
| Tool set | Used by | Purpose |
|---|---|---|
| Agent packaging tools | The Agent creating or editing a Mini App | Read, write, and verify Mini App package files |
| Mini App SDK | The open Mini App page | Keep interface state and call Host capabilities |
Agent packaging tools
Inside a Beav Mini App creation or editing session, the Agent modifies the package with these general tools:
workspace.read: reads the manifest, current version files, and the result of a write.workspace.write: writes a complete file; publishing the manifest always uses a full write.workspace.patch: makes a local edit to an existing text file in the new version.image.generate: only when the user explicitly wants a generated avatar or image asset.
The Agent should read the current device's package and SDK contract through ui.capabilities.inspect(redbox.sandbox.web@1) first. It must not guess Mini App capabilities with the chat Agent's tool_search, and must not bypass the package protocol with shell, browser automation, or the Tauri API.
The Mini App SDK at runtime
Mini App code only uses the window.redbox object injected into the page:
const permissions = window.redbox.capabilities.list();
const state = window.redbox.state.get() || {};
window.redbox.state.set({ ...state, lastInput: 'example' });
const result = await window.redbox.invoke('knowledge.search', {
query: 'topic research',
});
window.redbox.ui.notify('Done');
window.redbox.ui.close();
capabilities.list()returns the capabilities this version has been granted in the current space.state.get()/state.set()read and write the Mini App's interface state within the current space.invoke(action, payload)calls a Host action that the manifest declares and the user approved.ui.notify()shows a short status message;ui.close()closes the current Mini App window.
Do not put Agent packaging tool names into the manifest, and do not call them from Mini App code.
The smallest working package
miniapp://<app-id>/
manifest.json
host.json
versions/
1.0.0/
index.html
styles.css
app.js
icon.svg
assets/
tasks/
skills/
manifest.jsonis the pointer to the currently published version and must be written last.versions/<version>/is an immutable version directory. Never edit it in place after publishing.host.jsonis the release history maintained by the Host; neither developers nor Agents edit it.window.redbox.stateis not part of the package files; the Host stores it isolated per space.
A minimal manifest:
{
"schemaVersion": 2,
"id": "topic-helper",
"name": "Topic Helper",
"description": "Search and organize content topics",
"version": "1.0.0",
"entry": "versions/1.0.0/index.html",
"icon": "versions/1.0.0/icon.svg",
"capabilities": ["knowledge.search"],
"sdk": { "min": 2, "max": 2 },
"stateSchemaVersion": 1,
"privateSkills": [],
"agentTasks": [],
"status": "ready"
}
Main constraints:
iduses lowercase ASCII letters, digits,-, and_only, up to 64 characters.entrymust live inside the currentversions/<version>/directory.iconis a PNG, JPG, WebP, GIF, SVG, or AVIF inside the package, up to 2 MiB.capabilitiesholds at most 64 entries and must use the exact action names listed below.privateSkillsholds at most 8 entries and may only contain declarative skills, references, templates, and static assets.agentTasksholds at most 16 entries and must declare inputs, outputs, capability limits, and whether background runs are allowed.- The manifest is at most 64 KiB, the entry HTML at most 512 KiB, and the state at most 256 KiB.
status: "ready"only means the package is complete and passed read-back verification; unfinished drafts usedraft.
Versions and releases
Any change to the interface, behavior, icon, capabilities, or package files requires a new version. Renaming is the only exception.
The correct release order:
- Read the current
manifest.jsonand keep the sameid. - Create a new
versions/<next>/directory; never modify the live one. - Write the new version's HTML, CSS, JavaScript, icon, and declared resources.
- Read each file back and confirm it is complete and at the right path.
- Write the full
manifest.jsononce, at the end, soversion,entry, andiconpoint at the new version. - Read the manifest and the entry file again to confirm the release pointer switched.
Writing the new version directory without switching the manifest is still an unpublished draft. A tool call returning success is not a completed release either.
Renaming is the one exception: update only the manifest name, keep the version, entry, icon, state, and capabilities unchanged, and read the result back after the write.
All runtime capabilities
Declare only the capabilities the Mini App actually calls. Declaring one is a permission request, not a granted permission. Parameter schemas can grow with Host versions, so develop against the current device's ui.capabilities.inspect result.
Capture
capture.collect: capture public content or a profile link, download media on supported platforms, and optionally write it into the knowledge base.capture.status: read the status of one capture or research task.
When capturing a video and continuing to process it, use the Host resource reference from the response; do not read or build local file paths.
Social platforms
social.capabilitiessocial.profile.resolvesocial.profile.listContentsocial.searchsocial.detailsocial.researchsocial.collectsocial.subscription.createsocial.subscription.listsocial.subscription.updatesocial.subscription.refreshsocial.subscription.syncsocial.job.get
The social actions read platform profiles, content, and research results. Use capture.collect when you need to keep the linked content or media.
Knowledge base
knowledge.searchknowledge.listknowledge.readknowledge.createknowledge.updateknowledge.deleteknowledge.attachknowledge.inspectVisual
The knowledge base is a Host business data source. Keep your own filters, form drafts, and recent-use records in window.redbox.state; never copy the knowledge base into Mini App state.
Asset library
assets.listassets.searchassets.getassets.readTextassets.createassets.updateassets.createTextassets.patchTextassets.createFolderassets.updateFolderassets.renameassets.moveassets.setCoverassets.importassets.trashassets.restoreassets.deleteassets.categories.listassets.categories.createassets.manageassets.generateCharacterCardassets.commitInitializationCandidates
Topic center
topicCenter.readtopicCenter.manage
Drafts
manuscripts.listmanuscripts.readmanuscripts.createProjectmanuscripts.writemanuscripts.patchmanuscripts.variants.ensuremanuscripts.variants.readmanuscripts.variants.savemanuscripts.projects.promoteStandalonemanuscripts.packages.beginmanuscripts.packages.preflightmanuscripts.packages.buildmanuscripts.packages.listmanuscripts.packages.getPreview
Memory
memory.listmemory.searchmemory.recallmemory.addmemory.notememory.updatememory.archivememory.managememory.rebuildIndexmemory.diagnosticsmemory.commitInitializationCandidates
Media processing
media.transcribe: turn anassets://orminiapp-media://resource into plain text, SRT, or VTT.media.bindmedia.edit
media.import, media.search, media.get, media.inspect, and video.analyze are not Mini App actions. Do not ask users to paste absolute paths, and do not pass sourcePath, toolPath, or an output directory to media.transcribe.
Images, video, and voice
image.generatevideo.generatevoice.listvoice.getvoice.speechvoice.clonevoice.bindAssetvoice.delete
Agent
agent.runagent.getagent.eventsagent.cancelagent.runTask
agent.run starts a durable task managed by the Host, and allowedCapabilities must be a subset of the manifest capabilities. Prefer agent.runTask for the immutable Agent Tasks declared in the manifest: the Host validates the input schema, capability limits, background eligibility, and the bound skill.
Direct AI and job results
ai.generateai.analyzejobs.listjobs.getjobs.eventsjobs.cancel
Direct AI suits a single model call: it does not start an Agent and does not use tools. It supports prompts, system prompts, Host resource references, a JSON response schema, reasoning effort, and constrained generation parameters. Generation, transcription, and Agent tasks are projected into app-owned jobs, and a Mini App can only read and cancel its own executions.
Events and automations
events.subscribeevents.unsubscribeautomations.previewautomations.createautomations.listautomations.updateautomations.disableautomations.runsautomations.retry
Nothing keeps running after the iframe closes. When you need to watch the knowledge base or execute in the background, create an automation persisted by the Host: validate the definition with automations.preview to get a short-lived token, then let the user confirm the create or update. Package JavaScript itself cannot stay resident in the background.
Host UI and resource handoff
ui.notifyui.pickResourcesui.openResourceui.previewResourceui.exportResourceui.copyui.openExternal
These actions let the Host pick, preview, open, copy, or export a resource. Use canonical references such as knowledge://, assets://, and miniapp-media://, and never expose physical paths to the page.
Permissions and approvals
When a Mini App opens, the Host shows the capabilities from the manifest and binds the grant to the current space, app id, and version. On every invoke, the Host re-reads the manifest and the grants, validates the action schema, and filters out credentials and absolute paths.
- Ordinary reads run once the app has been granted the capability.
capture.collectuses the app grant in the current space and does not repeat an identical per-call prompt.- Paid generation, transcription, import, deletion, external capture, subscriptions, general manage actions, and starting or cancelling an Agent can require a typed approval.
- An automation only runs in the background when its definition, version, capabilities, budget, and concurrency limits all match the approved scope.
- Adding capabilities to the manifest never widens an old grant automatically; the user has to confirm again.
Never bypass approvals with repeated requests, renamed actions, direct network access, or hidden side effects.
Sandbox boundary
A Mini App can run the scripts and assets inside its package, but it cannot use:
- The Tauri API, Node.js, npm, shell, or subprocesses.
- The raw file system or absolute paths on the user's computer.
fetch, WebSocket, or any other direct network request.- Host credentials, cookies, API keys, or environment variables.
- Remote JavaScript, CSS, fonts, images, audio, video, or iframes.
- Popups, form submissions, browser downloads, or any external navigation.
- Browser control, extension control, Team Runtime, chat Agent tools, or
ui.surface.manage.
When you need external content or Host data, choose the matching typed action. When you need to open something externally, export a resource, or copy text, use the Host UI actions.
Common recipes
From link to subtitles
Declare at least this in the manifest:
{
"capabilities": ["capture.collect", "media.transcribe"]
}
const captured = await window.redbox.invoke('capture.collect', {
url,
platform: 'auto',
downloadMedia: true,
ingestToKnowledge: false,
});
const resourceRef = captured.items?.[0]?.evidenceRef
|| captured.knowledge?.entryIds?.[0];
const subtitles = await window.redbox.invoke('media.transcribe', {
resourceRef,
format: 'srt',
});
Transcription may only start once you hold a readable media reference. If the capture task reports completion without returning a usable resource, do not show a transcription success message.
Search the knowledge base
const result = await window.redbox.invoke('knowledge.search', {
query: input.value.trim(),
});
One Direct AI call
const result = await window.redbox.invoke('ai.generate', {
prompt: 'Turn the content below into three topic ideas',
resourceRefs: selectedRefs,
responseFormat: 'json',
responseSchema: {
type: 'object',
properties: {
topics: { type: 'array', items: { type: 'string' } }
},
required: ['topics']
}
});
When you reference knowledge or asset content, also declare the matching read capability. A JSON result only counts as success once it passes the response schema.
State and data rules
- Packages are installed globally, but state and permissions are isolated per space.
- The run context is bound to
app id + version + space; do not guess the current space after the page opens. - Keep
window.redbox.statesmall and explicit: input drafts, modes, recent records, and task references. - Knowledge, assets, drafts, and media still take the Host database as the source of truth; do not copy them into Mini App state.
- Reuse existing records for the same source, so refreshes, retries, and reopening do not create duplicates.
- Store the execution id for long tasks and resume it after reopening through
jobs.get,agent.get, or the matching status action.
UI rules
- One Mini App solves one main task and offers one obvious primary action.
- Design for a side panel around 280–420 px wide first, then scale up responsively to wider dialogs.
- Use system fonts, clear contrast, visible keyboard focus, and labeled form controls.
- Provide idle, working, success, and failure states; after a failure, keep the input and allow a retry from the same button.
- Show a short status and a refresh affordance on long tasks, and resume running tasks after reopening.
- Primary results should be copyable; add a second copy affordance only when a second format is genuinely common.
- Do not add settings pages, dashboards, onboarding essays, or entities unrelated to the main task.
- Do not depend on the Host's Tailwind, React, lucide, or style variables; all styles live inside the package.
Debugging
The Host collects limited console.* output, uncaught JavaScript errors, promise rejections, SDK actions, request ids, and durations. When editing an existing Mini App, the Agent should read the miniApp.diagnosticsRef provided in the task context instead of asking the user to copy logs or open another debug panel.
Never log credentials, full source documents, raw provider responses, or binary content. Error UI shows only what the user can understand and act on.
Definition of done
Confirm each item before publishing:
- The manifest id matches the existing Mini App, and the version directory is new and immutable.
- The entry, scripts, styles, icon, and declared resources are written and read back.
- The manifest declares only the exact capabilities actually called.
- There is no direct network access, absolute path, remote dependency, or undeclared side effect.
- Idle, working, success, failure, and retry states are complete.
- Long tasks can be re-read, and repeated actions do not create duplicate business data.
- The manifest was written last and read back with the correct version, entry, icon, and
status: "ready". - After really opening the Mini App, the results come from Host responses or persisted resources, not from a success state the page invented.
Only after the write, the persistence, and the read-back are complete may an Agent tell the user that the Mini App is published.