Work in progress. This documentation is being actively written — content is placeholder text and will change. Source and canonical info live in the Depot repository.

Depot

A structured data editor for games, tools, and anything else.

Introduction#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Depot is a structured data editor for games, tools, and anything else that benefits from schema-first design. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae.

Placeholder content — to be replaced with real introductory copy once the feature docs are outlined.

What is Depot?#

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Proin pharetra nonummy pede. Mauris et orci. Aenean nec lorem. In porttitor. Donec laoreet nonummy augue.

Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc. Mauris eget neque at sem venenatis eleifend. Ut nonummy.

Installation#

Fusce aliquet pede non pede. Suspendisse dapibus lorem pellentesque magna. Integer nulla:

# placeholder install command
brew install depot-editor

Integer pellentesque quam vel velit. Duis pulvinar.

Core concepts#

  • Sheets — tables of structured rows
  • Columns — typed fields, including nested types
  • Views — saved sort/group/filter configurations
  • CEL expressions — for computed values and filters

Sheets & Columns#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sheets are the primary organizing unit in Depot — a sheet is a typed table of rows, each row conforming to the sheet's column schema.

Creating a sheet#

Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.

Nunc viverra imperdiet enim. Fusce est. Vivamus a tellus.

Column types#

Depot supports a range of column types:

Type Description
string Plain text
int, float Numbers
bool Booleans
enum Fixed set of options
lineReference Reference to another row
sheetReference Reference to a sheet
list Ordered list of values
props Nested object
grid 2D grid of values

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

Defaults#

Proin pharetra nonummy pede. Mauris et orci. Default values are stored with the schema and applied to new rows on insert.

Renaming and deleting#

Aenean nec lorem. In porttitor. Donec laoreet nonummy augue. Renaming a column preserves its data; deleting it removes the data permanently (undoable via the history panel).

Views#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. A view is a saved combination of sort rules, group rules, filters, and column order — independent of the underlying data.

Creating a view#

Suspendisse dapibus lorem pellentesque magna. Integer nulla. Click + New View from the view switcher in the sheet toolbar. Each sheet has a default view that cannot be deleted or renamed.

Sort, group, filter#

Morbi in sem quis dui placerat ornare. Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. Sort and group rules stack in order; filters are combined with AND.

Temp views#

Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien. Donec venenatis vulputate lorem. Morbi nec metus. Temporary views strip all sort/group/filter rules so a navigated-to row is always visible.

Column order#

Maecenas porttitor congue massa. Each view stores its own column order. Reordering columns in one view does not affect others.

CEL Expressions#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Depot uses CEL (Common Expression Language) for sort keys, group keys, filters, formulas, and the Eval panel.

Syntax basics#

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.

HP > 100 && tier == "boss"

Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc.

Referencing other sheets#

Fusce aliquet pede non pede. A full-project CEL expression can reach across sheets by name:

Enemies.filter(e, e.HP > 100).size()

Mauris eget neque at sem venenatis eleifend.

Available functions#

  • size(x) — length of a string or list
  • string(x), int(x), double(x) — type coercions
  • x.filter(v, pred), x.map(v, expr), x.exists(v, pred), x.all(v, pred) — list macros

Donec laoreet nonummy augue. Suspendisse dui purus, scelerisque at, vulputate vitae, pretium mattis, nunc.

Type caveats#

CEL is strictly typed. Mixing int and double in a comparison will throw — coerce explicitly with double(x) when in doubt.

Exports#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Exports turn your project data into files or HTTP requests — run on save (auto) or on demand.

Creating an export#

Maecenas porttitor congue massa. Fusce posuere, magna sed pulvinar ultricies, purus lectus malesuada libero, sit amet commodo magna eros quis urna.

Each export has:

  • Language — CEL or JavaScript
  • Script — the expression or JS function that produces output
  • Target — a file path or webhook URL
  • Trigger — auto-run on data change, or manual

Language: CEL vs JS#

Nunc viverra imperdiet enim. Fusce est. CEL is safer and sandboxed. JavaScript is more expressive but requires trust.

// Example JS export
export default (ctx) => {
  return JSON.stringify(
    ctx.sheets.Enemies._rows.map(e => ({ id: e.id, hp: e.HP })),
    null,
    2
  );
};

Trust and security#

Aenean nec lorem. JavaScript export scripts are SHA-256 trusted per project path. Modifying a script auto-trusts the new hash under the localhost-trust model.

Untrusted JS exports short-circuit to lastRun.status = "untrusted" and display a pending-trust banner.

Targets#

Donec laoreet nonummy augue. Exports can write to:

  1. A file path (relative to the .dpo file). The path must include a file extension — any extension is fine (.json, .txt, .foo), but bare names like data/out are rejected.
  2. A webhook URL (POST body = script output)

While you're typing in the file-path field, auto-run pauses for ~1.5s after your last keystroke so a half-typed filename doesn't fire an export.

Search & Navigation#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. The search panel is a full-panel UI accessible via Cmd+F or the sidebar icon.

Searching#

Suspendisse dapibus lorem pellentesque magna. Integer nulla. Results group by category (sheet name, column name, row id, cell value) and then hierarchically by breadcrumb.

Morbi in sem quis dui placerat ornare. Clicking a result activates a temp view (if needed), expands nested rows, scrolls to the line, and flashes it briefly.

Temp views#

Pellentesque odio nisi, euismod in, pharetra a, ultricies in, diam. A temp view strips all sort/group/filter rules on the target sheet so the row is always visible. Temp views are client-only and never synced.

Keyboard shortcuts#

Shortcut Action
Cmd+F Open search
Esc Close search
↑ / ↓ Move through results
Enter Navigate to selected result

Prop Hoisting#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Hoisting projects a scalar field from a nested props chain onto the nearest non-props ancestor's view.

Why hoist?#

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Props sheets don't support sort or group — to sort or group by a nested scalar, hoist it.

How it works#

Proin pharetra nonummy pede. Hoists are view-level projections (stored in DepotView.hoists + columnOrder), not schema changes. The hoist cluster sits immediately to the right of its parent column.

Enemies
├── name
├── Stats (props)
│   ├── HP        ← hoisted
│   └── Defense   ← hoisted
└── tier

List-aware hoist root#

Mauris et orci. When hoisting inside a list column, the hoist lands on the list's backing sheet — not on the root. The walk stops at the first non-props ancestor.

CEL integration#

Aenean nec lorem. Sort and group rules on a hoisted column use the hoist path as their CEL identifier. Removing a hoist eagerly strips matching sort/group rules.

Layouts#

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Depot's layout system lets you render sheet data in custom forms — card views, galleries, dashboards — using a small KDL-based markup language.

Defining a layout#

Suspendisse dapibus lorem pellentesque magna. Integer nulla. Layouts are stored per-view in the .depot config and edited via a dedicated layout editor.

card {
  image path=".image"
  title ".name"
  subtitle ".tier"
  badges ".tags"
}

Morbi nec metus.

Available nodes#

  • card, row, column — containers
  • image, title, subtitle, text — leaves
  • badges, bar, swatch — specialized displays

Nunc nulla. Fusce risus nisl, viverra et, tempor et, pretium in, sapien.

Binding expressions#

Donec venenatis vulputate lorem. Bindings use a leading dot to reference columns on the current row:

text ".description"

Or a full CEL expression:

text "size(.tags) + ' tags'"

Mauris et orci. Aenean nec lorem. In porttitor.