Templates

Authoring a template

Edit source

Authoring a template

Adding a template to the bundled gallery means:

  1. Build the app as you would any other Centraid app.
  2. Drop it under packages/app-templates/<id>/.
  3. Pre-build the handlers so first-use needs no bun install.
  4. Add an entry to packages/app-templates/index.json.

Steps

1. Shape the app

Build the folder using the standard layout — see App anatomy:

Code
packages/app-templates/<id>/├── app.json├── index.html├── app.css├── app.js├── queries/│   └── <name>.js├── actions/│   └── <name>.js├── migrations/│   └── 0001_init.sql├── automations/         # optional — see Automations tab│   └── <id>/│       ├── automation.json│       └── handler.js├── package.json└── tsconfig.json

2. Pre-build the handlers

The bundled gallery promises "click and deploy" — no bun install, no compile. So compile your TypeScript to JS in place and commit the .js alongside the .ts:

sh
cd packages/app-templates/<id>bun installbun run build       # tsc → emits .js next to each .ts

The shipped tsconfig.json uses "rootDir": "." and "outDir": "."queries/foo.ts compiles to queries/foo.js in place.

Both .ts and the compiled .js should be committed:

Code
queries/├── get-today.ts└── get-today.js      # ← also committed

TODO(#120) — the receipt for issue #105 covers template naming; there may be a similar receipt or CI check enforcing the "compiled JS is committed" property. Worth confirming.

3. Add a gallery entry

Edit packages/app-templates/index.json:

json
{  "id": "your-app-id",  "name": "Display Name",  "desc": "One-sentence description.",  "colorKey": "indigo",  "iconKey": "Sparkle",  "version": "0.1.0"}

For an automation template, also include:

json
{  "kind": "automation",  "emoji": "🌤",  "category": "Daily rhythm",  "triggerKind": "cron",  "triggerLabel": "Weekdays · 6:00 PM",  "integrations": ["Google Calendar", "Gmail"]}

4. Bump the version on subsequent changes

The version field in both app.json and the gallery entry follows semver. Bump it when the template's source changes — that's what drives any "this template has updated" surfaces in the gallery.

Color and icon keys

TODO(#120) — document the full set of colorKey and iconKey values the desktop renders. From index.json observed values: indigo, violet, amber, rose for color; Water, Todo, Journal, Sparkle for icons. The full set lives in packages/design-tokens/.

Categories

Automation templates use category to group in the gallery. Observed values:

  • Daily rhythm
  • Inbox
  • Engineering

TODO(#120) — capture the canonical set and document the convention for adding new ones (do they need a design-tokens entry, or is the string free-form?).

The manifest.json build step

packages/app-templates/manifest.json is generated by packages/app-templates/scripts/build-manifest.mjs (the script that turns the source index.json plus per-template app.json files into the gallery's runtime manifest).

TODO(#120) — describe when this build step runs (pre-commit? at desktop dev start?) and what it produces beyond index.json. Whether authors need to run it manually after adding a template depends on the wiring.

Where to go next

Was this useful?