Skip to content

Agent-authored apps

Tell Subspace “build me a reading tracker to replace Goodreads” and it builds you one. A seeded agent scaffolds the app as a plugin, a page type with a props schema, a live dashboard view, and any tools it needs, then installs it so it runs inside the graph: the app’s items are ordinary pages, they interlink with the rest of your knowledge base, and every action is gated and audited like everything else. There is no separate app store and no second runtime. Your app is a plugin, and it lives where your data lives.

The seeded agents/app-builder definition turns a plain-language request into a scaffolded, installed plugin.

  1. Describe the app

    Ask the app builder for what you want: the fields an item has, how to group them, a sample entry. “A reading tracker with title, author, a status of want / reading / done, and a rating.”

  2. It scaffolds a plugin

    The agent writes plugin source to a home directory (see apps.scaffold): a manifest, a draft-07 props schema, a live view-spec dashboard over the app’s directory, and an optional sample item.

  3. You approve the install

    apps.install is gated: an approval card appears, and on approval the scaffold installs through the ordinary plugin pipeline.

  4. It runs in the graph

    The dashboard is live at /p/<name>-dashboard, and new items are ordinary pages in the app’s directory that join the board the moment you create them.

apps.scaffold is ungated: it only writes source files, and installing them is the gated step. It writes plugin source to <home>/app-src/<name>/, including subspace-plugin.json, schemas/item.schema.json, the dashboard page, and the sample item.

apps.scaffold({
name: "reading",
title: "Reading Tracker",
fields: {
title: { type: "string", required: true },
author: { type: "string" },
status: { type: "string", values: ["want", "reading", "done"] },
rating: { type: "number" },
},
groupBy: "status",
sample: true,
})
Field Meaning
name The plugin and directory name.
title, description, version App metadata; bump version to iterate (see below).
fields Field name to { type: string | number | boolean, values?: [enum], required? }.
groupBy An enum field whose values become board lanes (must name a values field).
sample Whether to write one starter item.

apps.install {name} is gated by an approval card. On approval it installs the scaffold through the standard plugin install path: the pages import provenance-tagged through the command pipeline, the page type registers, and the ops.plugins row lands or repoints. Afterward:

  • the dashboard is a surface at /p/<name>-dashboard;
  • items are ordinary pages in the <name>/ directory carrying metadata.<name> props, advisory-validated against the scaffolded schema (a mismatch warns, never blocks).

Installed versions are immutable, so you iterate by re-scaffolding with a bumped version and installing again. The new version installs as a sibling directory and the row repoints, exactly like any plugin upgrade. Add a field, change the groupBy, drop in a new sample, bump the version, reinstall, and the dashboard updates in place while your existing items keep their pages.