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 organizes all application code and user data into three logical layers: L0, L1, and L2. This layered model is what lets the same /mod/... URL resolve to different implementations for different users and groups, and it is what makes the admin shell firmware-only while the main app shell reflects per-user and per-group customizations. Understanding layers is foundational to understanding how modules, skills, and settings work throughout the platform.

The Three Layers

L0 — Firmware

Immutable repo-owned code. Nobody writes L0 at runtime. Changes arrive through software updates only.

L1 — Group Customware

Per-group customizations. A user may write to L1/<group>/ only if they manage that group. _admin members may write any L1 path.

L2 — User Customware

Per-user customizations. Each user writes to their own L2/<username>/. _admin members may write any L2 path.

Logical Paths vs. Physical Paths

Logical layer paths stay stable even when the writable roots are relocated. Frontend code, skill files, and API calls always use logical paths:
L1/<group-id>/...        ← group customware
L2/<username>/...        ← user customware
~/...                    ← shorthand for L2/<username>/...
/app/L1/<group-id>/...   ← absolute logical form
/app/L2/<username>/...   ← absolute logical form
By default, the writable roots live inside the repo:
app/L1/   ← group customware root (default)
app/L2/   ← user customware root (default)
When CUSTOMWARE_PATH is set, the writable roots relocate but the logical paths do not change:
$CUSTOMWARE_PATH/L1/   ← relocated group customware root
$CUSTOMWARE_PATH/L2/   ← relocated user customware root
app/L1 and app/L2 are transient runtime state in the repo and are gitignored. Do not treat them as durable framework structure.

Permission Model

WhoCan write
Any userTheir own L2/<username>/...
Group managerL1/<group-id>/... for groups they manage (direct or through a managing-group chain)
_admin memberAny L1/ and any L2/ path
NobodyL0/ — ever
The /admin shell is clamped to L0 only. It injects meta[name="space-max-layer"] with the value 0, so all module and extension resolution on that surface stays firmware-only regardless of who is logged in.

User Storage Layout

Every user’s data lives under L2/<username>/:
L2/<username>/
  user.yaml                   ← user metadata (full_name, etc.)
  meta/
    password.json             ← sealed password verifier (backend-owned)
    logins.json               ← active sessions
    user_crypto.json          ← wrapped browser key for encrypted user settings
    login_hooks.json          ← client-owned first-login marker
  conf/
    personality.system.include.md   ← user-local agent personality prompt
  memory/
    behavior.system.include.md      ← persistent agent memory (behavior rules)
    memories.transient.include.md   ← rolling agent notes
  spaces/
    <spaceId>/                ← per-space storage (see Spaces and Widgets)
  mod/
    <author>/<repo>/          ← user-owned modules
When CUSTOMWARE_GIT_HISTORY is enabled, each L2/<username>/ root may have its own local Git history managed by the server. Rollback intentionally ignores meta/password.json, meta/logins.json, and meta/user_crypto.json so time travel never alters current login, password, or wrapped browser-key state.
Frontend code derives the writable root from space.api.userSelfInfo():
const { username, groups, managedGroups } = await space.api.userSelfInfo();

// Write to the current user's home folder
await space.api.fileWrite(`~/conf/personality.system.include.md`, content);

// Write to a managed group
if (managedGroups.includes("design-team")) {
  await space.api.fileWrite(`L1/design-team/mod/...`, content);
}
The userSelfInfo() response uses camelCase for JavaScript APIs (fullName), but the persisted layer file uses snake_case (full_name in ~/user.yaml). Always write full_name to the file, not fullName.

Group Storage Layout

Groups live under L1/<group-id>/ and are described by a YAML manifest:
L1/<group-id>/
  group.yaml          ← group manifest
  mod/
    <author>/<repo>/  ← group-owned modules and skills
The group.yaml manifest controls membership and management:
included_users:
  - alice
  - bob
included_groups:
  - design-team
managing_users:
  - alice
managing_groups:
  - leads
FieldMeaning
included_usersDirect user members of this group
included_groupsNested group members
managing_usersUsers who may write to this group’s L1 area
managing_groupsGroups whose members may write to this group’s L1 area

Special Groups

_all

Every authenticated user belongs to _all. L0 firmware lives under L0/_all/ and is readable by everyone.

_admin

Members of _admin can write any L1 and L2 path and access the /admin firmware shell.

Git History for Writable Layers

When CUSTOMWARE_GIT_HISTORY is enabled, the server maintains an optional per-owner local Git history for each L1/<group>/ and L2/<user>/ root. This powers the Time Travel page at #/time_travel, which lets users page through commits, inspect diffs, preview states, and roll back or revert changes. The history APIs are available on the frontend through:
space.api.gitHistoryList(root)
space.api.gitHistoryDiff(root, commitSha)
space.api.gitHistoryPreview(root, commitSha)
space.api.gitHistoryRollback(root, commitSha)
space.api.gitHistoryRevert(root, commitSha)
Rollback preserves newer commits in backend-owned history refs when possible, so the Time Travel page can still show forward-travel options after moving back.

Build docs developers (and LLMs) love