Templates
Authoring a template
Authoring a template
Adding a template to the bundled gallery means:
- Build the app as you would any other Centraid app.
- Drop it under
packages/app-templates/<id>/. - Pre-build the handlers so first-use needs no
bun install. - Add an entry to
packages/app-templates/index.json.
Steps
1. Shape the app
Build the folder using the standard layout — see App anatomy:
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.json2. 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:
cd packages/app-templates/<id>bun installbun run build # tsc → emits .js next to each .tsThe 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:
queries/├── get-today.ts└── get-today.js # ← also committedTODO(#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:
{ "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:
{ "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
colorKeyandiconKeyvalues the desktop renders. Fromindex.jsonobserved values:indigo,violet,amber,rosefor color;Water,Todo,Journal,Sparklefor icons. The full set lives inpackages/design-tokens/.
Categories
Automation templates use category to group in the gallery. Observed values:
Daily rhythmInboxEngineering
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
- App anatomy — the shape every template follows.
- Templates index — the gallery's current contents.
- Cloning a template — the user-side workflow.