Design prompt content
A good prompt tells the operator what changed, what they must inspect or do, and what each available action means. Keep the main instruction short; use detail rows for values the operator needs to verify.
Define the visible fields
Section titled “Define the visible fields”A complete prompt resolves to these fields:
| Field | Requirement and behavior |
|---|---|
title |
Required, non-empty dialog title. |
message |
Required main instruction. It may be an empty string when the details carry all necessary information. |
severity |
Required: info, success, warning, or error. |
size |
Optional: sm, md, or lg; defaults to sm. |
details |
Optional label/value rows. Each row may have a when condition. |
actions |
Required list of one to 16 operator actions. |
allow_abort |
Required boolean controlling whether Ctrl shows an Abort button that aborts the current LinuxCNC task. |
hal.pins |
Optional machine-facing values and results. HAL-backed prompts require a trigger. |
Choose severity for the state being communicated, not for visual emphasis. Use error for a condition that prevents the intended operation, warning for a condition requiring caution or intervention, success for a completed positive outcome, and info for neutral guidance.
Use a larger size when translations, detail rows, or the decision itself need more room. Do not use size as a substitute for editing an overly long instruction.
Define actions
Section titled “Define actions”Every action has an identifier, a visible label, and an intent:
prompts: recovery: # ... actions: - id: retry label: Retry intent: primary
- id: stop label: Stop operation intent: dangerThe id is a stable machine-facing value. It is the key used by HAL on_action mappings and the value returned to software producers. Keep it independent of the translated label.
Action intents describe presentation and meaning:
| Intent | Use it for |
|---|---|
primary |
The main expected continuation. |
secondary |
A valid alternative or non-primary choice. |
danger |
A destructive or hazardous choice that deserves extra visual weight. |
Set allow_abort: true to add a danger-styled Abort button. Pressing it sends LinuxCNC a task-abort command, closes the prompt with an aborted result, and does not apply any HAL on_action mapping. For a HAL-backed prompt, the machine logic must still lower the trigger to release the request.
Set allow_abort: false when the operator must answer through one of the declared actions. This removes the Abort button from the prompt; it does not prevent LinuxCNC from being aborted through other controls or system behavior.
Show captured HAL values
Section titled “Show captured HAL values”Add variable to a readable in or io pin, then use the same name in templated content:
prompts: spindle-temperature: # ... hal: pins: show: direction: in type: bit trigger: rising
temperature: direction: in type: float variable: temperature
message: Spindle temperature is {{ temperature }} °CVariables may appear in:
titleandmessage;- detail
label,value, andwhen; - action
label; and - every translation of those localized fields.
Every custom variable used by the content must have exactly one readable HAL pin binding, and every declared variable must be used. A missing, duplicate, or unused binding prevents the broker from starting.
The broker captures all readable variable pins together on the trigger’s rising edge. Changing temperature while the prompt is active does not change the displayed value. Lower the trigger, update the value pins, and raise the trigger to submit a new snapshot.
Add detail rows and conditions
Section titled “Add detail rows and conditions”Details keep supporting values aligned and scannable:
prompts: tool-change: # ... details: - label: Requested tool value: "T{{ tool_number }}"
- label: Tool comment value: "{{ tools[tool_number].comment }}" when: tools[tool_number].comment != ''The when field is an expression without {{ }} delimiters. The row is omitted when the expression evaluates to false. Its label and value are rendered only when the row is visible.
Use the restricted template language
Section titled “Use the restricted template language”Prompt content uses a restricted Jinja syntax. It supports substitutions, indexing, attribute reads, comparisons, boolean expressions, and {% if %} conditions. It rejects loops, includes, macros, assignments, function calls, and arbitrary filters. Undefined variables are errors.
Two read-only values are supplied without HAL bindings:
| Value | Available data |
|---|---|
is_lathe |
true for an XZ lathe configuration and false otherwise. |
tools[number] |
exists, number, diameter, and comment for a tool-table entry. |
Looking up a tool number that is not in the table returns exists: false, the requested number, a zero diameter, and an empty comment. Check exists when absence must be distinguishable from a valid zero value.
For example:
prompts: tool-change: # ... message: >- Load tool T{{ tool_number }} {% if tools[tool_number].comment != '' %} ({{ tools[tool_number].comment }}) {% endif %}Like HAL variables, tool data, lathe status, and machine-unit scale are frozen when the request is submitted.
Format linear values
Section titled “Format linear values”Use the only supported filter, linear, for values expressed in LinuxCNC machine units:
prompts: position-check: # ... details: - label: Position value: "{{ position | linear }}"The default preserves the configured machine unit and includes its suffix. It shows three decimal places for millimetres and four for inches.
Pass mm or in when the prompt deliberately needs a particular display unit:
prompts: position-check: # ... details: - label: Position value: "{{ position | linear('mm') }}"Do not apply linear to an already converted value. The broker treats the input as a value in the machine’s native linear units and converts it only when the requested display unit differs.
Translate operator-facing text
Section titled “Translate operator-facing text”title, message, detail label, and action label may be a plain string or a locale map:
prompts: fixture-check: # ... title: en: Verify fixture pl: Sprawdź przyrząd
actions: - id: continue label: en: Continue pl: Kontynuuj intent: primaryWhen Ctrl requests pl-PL, the broker uses the pl-PL translation when it is
present. Otherwise it tries pl, then en, then the first entry in the locale
map. The same fallback order applies to every requested locale.
Plain strings are used for every locale. A detail value is always one templated string rather than a locale map; keep translated explanatory text in its label or in the main message.
When Ctrl changes locale while a prompt is active, the broker rerenders the same captured request. The prompt identity and queue position do not change.