Template viewer

Reading a published template: its steps, settings, and how each step renders for the person running it. Templates are defined in code; this page never writes.

Route: /templates/editor/[key] (the path is kept so existing links keep working)


Why it is read-only

Templates are code-owned. They are authored in applications/main/src/templates/, reviewed like any other change, and published automatically when a deploy's compiled digest differs from the stored one (see manage templates). There is no HTTP write path: PUT /api/templates/{key}, the AI-edit endpoint and the draft-compile endpoint were removed, and the templates:write permission is retired. An in-app edit would only have been reverted by the next deploy, and it forked storage away from the repository without review.

To change a template, edit its repository file — see author a template.


What it shows

The viewer takes the whole viewport — FULL_BLEED_PATHS in app-shell.tsx hides the app nav here, so ← Templates in the top bar is the way out. The header carries a Read only · defined in code badge.

Two columns and two tabs

canvas · Steps | Settings │ preview 440px
  • Steps — the ordered step list, grouped by phase. Selecting a step shows a read-only summary: its key, type, next step (or then/else), who acts, and its fields.
  • Settings — template name, key, roles, run inputs, start requirement, who can start and the completion summary. Rendered inside a disabled <fieldset>, so nothing is editable.
  • Preview — the right panel renders the selected step as the runner will show it, from the published registration's compiled presentation.

The page reads GET /api/templates/{key} (gated on templates:read) and derives its display from the registration's app-owned source metadata with readAuthoringSource. No compile round-trip is needed. If the registration carries no compatible source metadata, the page falls back to showing the closed execution program as JSON.


Files

FileRole
[key]/page.tsxViewer page: load, step ordering, canvas tabs, preview panel.
_components/EditorStepRail.tsxThe step list. With readOnly it renders a summary per step instead of the step editor.
_components/config-panel.tsxTemplateSettingsPanel (shown disabled) and the step settings forms.
_components/StepRunnerPreview.tsxThe right panel. Inert compiled-presentation preview; shares headless field semantics, not the frontend renderer.
_lib/template-flow.tsTemplate → display graph conversion (templateToFlow).

Sibling: /templates — the list view, covered in dashboard and lists.


Concepts it uses

FlowNodeData

The display shape for a step, defined in template-flow.ts. It is a flattened union — one object with the optional fields of all step types, rather than a discriminated union. It is a viewer concern only; nothing outside applications/main/src/app/templates/editor/ uses it.

Node ordering

orderNodes() in page.tsx derives display order by walking nextStepKey (then/else for conditions) from the first unreferenced step, not by node position. The graph is a real linked list.

Phases

step.phase groups consecutive steps into labelled sections in the rail. The runner reads the same field. Purely presentational — the engine ignores it.


Extending it

Adding a step type means the viewer can display it: add STEP_TYPE_META in applications/main/src/operator-ui/metadata.ts (label, icon, color), and read its fields in templateToFlow. See add a step type.


Known gaps

enabledExpression is displayed but does nothing

The authoring model carries it and the settings show it. The engine never reads it. See known issues.

Script steps cannot be authored here

Nothing is authored here. Raw JavaScript is not a runtime capability in repository templates either: use the closed template activity for reusable composition. Historical known scripts may be normalized by offline authoring migration; unknown source is rejected.