Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/agent0ai/space-agent/llms.txt

Use this file to discover all available pages before exploring further.

Space Agent delivers all browser-side code through a uniform module namespace — mod/<author>/<repo>/... — that the backend resolves through a layered customware inheritance chain. Every /mod/... URL is a logical address, not a fixed disk path. The same URL may resolve to firmware in L0, to a group override in L1, or to a user override in L2, depending on the authenticated user’s readable roots and the maxLayer ceiling set by the page shell.

Module Namespace

All browser modules are addressed as:
mod/<author>/<repo>/path/to/file

Firmware (L0)

Immutable core modules under L0/_all/mod/_core/. Changed only through updates.

Group Customware (L1)

Group-scoped overrides under L1/<group>/mod/. Writable by group managers.

User Customware (L2)

Per-user overrides under L2/<username>/mod/. Writable by the user themselves.

Resolution ceiling

maxLayer clamps lookup to a specific layer. The admin shell sets maxLayer=0 to stay firmware-only.
Example module paths:
/mod/_core/framework/js/initFw.js
/mod/_core/router/view.html
/mod/_core/agent/view.html
/mod/_core/file_explorer/view.html
/mod/_core/huggingface/view.html
/mod/_core/webllm/view.html
/mod/_core/documentation/documentation.js
The /admin shell injects <meta name="space-max-layer" content="0">, clamping all module and extension resolution to L0 firmware only. The main app shell allows the full L0 → L1 → L2 chain.

Hash-Based Router

The authenticated app uses a hash router. Route segments map to view.html files under the matching module path. The main router helper is available as space.router in JavaScript and as $router in Alpine components.

Built-in Routes

Hash routeResolves to
#/agent/mod/_core/agent/view.html
#/dashboard/mod/_core/dashboard/view.html
#/file_explorer/mod/_core/file_explorer/view.html
#/user/mod/_core/user/view.html
#/time_travel/mod/_core/time_travel/view.html
// Navigate to a built-in route
space.router.go('/agent');

// Navigate to a custom module route
space.router.go('/author/repo/path');

HTML Extension Anchors

Extension seams decouple composition points from their implementations. A module declares a seam with <x-extension> and other modules fill it by placing files in matching ext/html/ paths — no direct coupling required.
<!-- Declare a seam -->
<x-extension id="some/path"></x-extension>
The runtime resolves that seam by loading all files that match:
mod/<author>/<repo>/ext/html/some/path/*.html
Extension files should stay thin. They typically just mount the real component from the owning module root rather than containing the full feature implementation.

Important Shell Seams

Seam IDOwnerPurpose
_core/router/shell_startrouterTop of the authenticated app shell
_core/router/shell_endrouterBottom of the authenticated app shell
page/router/route/startrouterBefore route content
page/router/route/endrouterAfter route content
page/router/overlay/startrouterStart of floating overlay layer (above route content)
page/router/overlay/endrouterFloating overlay surfaces (e.g. browser windows)
_core/onscreen_menu/itemsonscreen_menuFeature-contributed dropdown menu items
_core/onscreen_menu/bar_startonscreen_menuLeft header bar — target for route-owned injected controls
_core/onscreen_menu/bar_endonscreen_menuRight header bar
_core/framework/head/endframeworkInjected into document.head during bootstrap

x-inject — Delayed-Target Injection

The x-inject="selector" directive on a <template> root mirrors Alpine’s x-teleport but waits for the selector to appear in the DOM. When the source template unmounts, the wait is cancelled and the injected content is removed.
<!-- Route-owned controls injected into the shell header bar -->
<template x-inject="[id='_core/onscreen_menu/bar_start']">
  <button @click="...">My Control</button>
</template>
This is how _core/dashboard, _core/spaces, and _core/time_travel contribute route-scoped controls to shared shell chrome without permanently extending the menu shell.

<x-component> — Recursive Component Loading

<x-component> loads an HTML file (full document or fragment), mounts its styles, executes its module scripts, and recursively resolves any nested <x-component> tags.
<x-component src="/mod/_core/file_explorer/component.html"></x-component>
  • Component HTML owns structure and Alpine bindings; stores own state and async work.
  • Concurrent scans of the same target share one in-flight load — observer rescans cannot leave a component half-hydrated.
  • Dynamic discovery watches the full document.documentElement, so components inserted under <head> are hydrated the same way as body-mounted ones.
  • Parent wrapper attributes are exposed to descendants through xAttrs($el).

JavaScript Extension Hooks

Behavior seams use space.extend to wrap a function and expose /start and /end hook points. Hook files live at:
mod/<author>/<repo>/ext/js/<extension-point>/*.js
// Declare a seam (in owning module)
export const myFeature = space.extend(import.meta, async function myFeature(data) {
  // core behavior
  return result;
});

// Hook into /end from another module (ext/js/owning-module/myFeature/end/my-hook.js)
export default async function myHook(data) {
  // runs after myFeature core behavior
}
Wrapped functions become async and should be awaited by callers. The /start hook runs before the core function body; the /end hook runs after. Use _core/framework/initializer.js/initialize/end when setup must stay imperative, or the _core/framework/head/end HTML seam when it can stay declarative.

Extension Batching and Resolution

Uncached HTML <x-extension> lookups are batched before hitting /api/extensions_load:
  • The runtime flushes the queue on the next animation frame by default.
  • HTML_EXTENSIONS_LOAD_BATCH_WAIT_MS in extensions.js adds an extra wait window before the frame-aligned flush.
  • JS hook lookups are not batched — they go out immediately because callers await them directly.
  • Empty extension lookups are cached as valid results; missing seams do not cause repeated polling.
The extensions_load request carries maxLayer at the top level plus ordered patterns groups, and receives grouped extensions back in the same order.

Override Rules

RuleBehavior
Same override keyHigher layer replaces lower layer
Different filenames, same seamFiles compose together
maxLayer=0Only L0 firmware files are considered

Context Tags

Modules export live runtime context through hidden <x-context> elements. Skill discovery unions data-tags values at catalog resolution time.
<!-- Static tag -->
<x-context data-tags="onscreen"></x-context>

<!-- Alpine-bound reactive tag -->
<x-context :data-tags="$store.router.current?.path ? `route:${$store.router.current.path}` : ''">
</x-context>
import { getContexts, getAttributeValues, getTags, getContents }
  from "/mod/_core/framework/js/context.js";

const tags = getTags(); // string[] of all current data-tags values
The framework automatically injects one hidden data-runtime="browser" or data-runtime="app" element with matching runtime-browser / runtime-app tags on every framework-backed page.

First-Party Module List

All first-party modules live under app/L0/_all/mod/_core/:
  • framework — bootstrap, runtime primitives, component loader, extension system, shared utilities
  • visual — shared visual language, canvas, chrome, buttons, dialog helpers, conversation rendering
  • router — authenticated app shell, hash routing, routed extension anchors
  • admin — firmware-backed admin shell and panels
  • onscreen_menu — viewport-fixed header bar, Home shortcut, dropdown action seam
  • login_hooks — authenticated-bootstrap lifecycle hooks (first-login, any-login)
  • agent — routed agent information and personality include editor
  • agent-chat — headless shared chat helpers for first-party agent surfaces
  • agent_prompt — shared prepared-prompt runtime for agent surfaces
  • onscreen_agent — floating routed overlay agent and user-facing chat runtime
  • open_router — headless OpenRouter request-policy module
  • skillset — first-party skill packs and browser-side skill discovery helpers
  • memory — agent-memory policy, auto-loads ~/memory/ prompt includes
  • promptinclude — prompt-include discovery and onscreen-agent injection
  • dashboard — routed dashboard shell and extension seams
  • spaces — routed spaces canvas, widget SDK, space runtime
  • file_explorer — reusable app-file browser component and routed Files page
  • time_travel — routed writable-layer history surface
  • user — routed account settings page
  • user_crypto — headless per-user encryption helper
  • documentation — supplemental agent-facing documentation and documentation skill
  • panelsext/panels/*.yaml manifest discovery and dashboard Panels section
  • web_browsing — draggable browser popup windows and <x-browser> element
  • webllm — unlisted routed WebLLM browser-inference test surface
  • huggingface — Local LLM page backed by Hugging Face Transformers.js

Custom Module Overrides

Users and groups contribute module overrides by placing files at the appropriate layer root. A user can override any module file by placing a same-path replacement under their L2/<username>/mod/ folder. Group managers do the same under L1/<group>/mod/. The backend resolves the highest accessible layer that contains the requested path.
L0/_all/mod/_core/agent/view.html   ← firmware default
L1/mygroup/mod/_core/agent/view.html  ← group override (if accessible)
L2/alice/mod/_core/agent/view.html    ← user override (highest priority)

Build docs developers (and LLMs) love