{% from "_macros.html" import icon %}
{#
The plan card: what was found, what it is for, and the work as phases of
tasks -- the one structure the harness spec has LLeMbas and the LLeMbas CLI
keep per conversation (services/plans.py).
Rendered from `plan`, already normalised: a message's snapshot
(`message.plan`, in a bubble), the chat's own (`chat.plan`, in the panel
above the composer), or the one on a card waiting to be approved
(`item.plan`). Every caller sets `plan`, so this template never sees two
shapes; a row written before version 2 came through `normalise` as one phase.
Every line is model output and is escaped; a task is shown as text, never as
Markdown, because a plan is the last thing that should be able to emit a link.
A status is a CLASS, never a character in the text: a tick written into the
string would be indistinguishable from a tick the model wrote itself.
A bubble's card does not re-render as work goes on: the newest bubble carries
the plan as it was then and the panel carries it now -- that is what a
transcript is, and it makes "what did it think at step three" answerable.
`plan_actions` (default on) draws the Execute button: on a message, for that
snapshot; in the panel, for the plan as it stands (`current`). Off on the
approval card, whose own buttons are the decision. In an agent chat Execute
switches to Edit, never Auto -- the plan was written under a mode where every
command stopped for approval, and a button that also removed the asking is
not the button anybody pressed; in a chat it leaves Plan mode and carries on.
The confirm dialog says which.
#}
{% set plan_actions = plan_actions if plan_actions is defined else true %}
{% set plan_message_id = message.id if message is defined and message else "current" %}
{{ icon("check", "icon--sm") }}
{{ plan.title or "A plan" }}
{% if plan.summary %}
{{ plan.summary }}
{% endif %}
{% if plan.findings %}
{{ t("What was found") }}
{% for finding in plan.findings %}
{{ finding.text }}
{% endfor %}
{% endif %}
{% if plan.objectives %}
{{ t("What it is for") }}
{% for objective in plan.objectives %}
{{ objective.text }}
{% endfor %}
{% endif %}
{% for phase in plan.phases %}
{# A single unnamed phase is what a version-1 row becomes, and heading it
"Plan" above a plan headed "Plan" reads as a mistake. #}
{% if plan.phases | length > 1 or phase.title not in ("Plan", "Work") %}