{# the pieces every module is built from; a page composes, it does not restate #} {# the mark for an operating system, as the node names it #} {% set os_icons = {"Linux": "si-linux", "Darwin": "si-apple", "Windows": "grid-2x2"} %} {# a Lucide icon by name, inlined so it takes the text colour; the set lives in icons/ #} {% macro icon(name) -%} {% include "icons/" ~ name ~ ".svg" %} {%- endmacro %} {# a button that copies the text of what stands right before it, and ticks for a moment #} {% macro copy() -%} {%- endmacro %} {# a select that looks like the rest of the page: the native control, drawn over #} {% macro select(id, name, options, selected, attrs="") -%} {{ icon("chevron-down") }} {%- endmacro %} {# an avatar; one that `opens` a card keeps the card by the pointer while the pointer is on it, within the window #} {% macro avatar(identity, small=false, opens=none) -%}
{{ identity|identicon|safe }}
{%- endmacro %} {% macro dot(status) -%}
{%- endmacro %} {% macro column_header(title) -%}
{{ title }}{% if caller is defined %}{{ caller() }}{% endif %}
{%- endmacro %} {# the mark for a channel, in the channel's own colour; one this page has no mark for is named instead #} {% set channel_icons = {"telegram": "si-telegram", "lark": "lark", "wecom": "wecom"} %} {# the mark for a runtime, by the kind the node names it; one with no mark is named instead #} {% set runtime_icons = {"codex": "openai", "claudecode": "si-claude"} %} {% macro runtimes(kinds) -%} {% for kind in kinds %}{% if kind in runtime_icons %}{{ icon(runtime_icons[kind]) }}{% else %}{{ kind }}{% endif %}{% endfor %} {%- endmacro %} {% macro channels(kinds) -%} {% for kind in kinds %}{% if kind in channel_icons %}{{ icon(channel_icons[kind]) }}{% else %}{{ kind }}{% endif %}{% endfor %} {%- endmacro %} {# the computer an agent runs on, by its operating system's mark; the name is the tooltip, and stands in for a system this page has no mark for #} {% macro system(agent) -%} {% if agent.system in os_icons %}{{ icon(os_icons[agent.system]) }}{% else %}{{ agent.computer_name }}{% endif %} {%- endmacro %} {# more marks than a row has room for: the first few, and how many more, named in its tooltip #} {% set icons_shown = 5 %} {# what an agent is made of; on its computer's own page the system goes without saying #} {% macro agent_icons(agent, with_system=true) -%} {% set ns = namespace(marks=[], names=[]) %} {% if with_system %}{% set ns.marks = ns.marks + [system(agent)] %}{% set ns.names = ns.names + [agent.computer_name] %}{% endif %} {% for kind in agent.runtimes %}{% set ns.marks = ns.marks + [runtimes((kind,))] %}{% set ns.names = ns.names + [kind] %}{% endfor %} {% for kind in agent.channels %}{% set ns.marks = ns.marks + [channels((kind,))] %}{% set ns.names = ns.names + [kind] %}{% endfor %} {% if ns.marks|length > icons_shown %}{{ ns.marks[:icons_shown - 1]|join }}+{{ ns.marks|length - icons_shown + 1 }}{% else %}{{ ns.marks|join }}{% endif %} {%- endmacro %} {# a row in a list column: avatar (optional), title + subtitle, status dot (optional); with an href it navigates through htmx, swapping `target` (the whole module unless told otherwise), otherwise it is a plain row. an off row is greyed and does not navigate: there is nothing live behind it (an agent); a row that only looks off (extra_class="off") still opens, the way an offline computer does, since removing it happens from its page. what the row shows sits in its own box, so a long list can leave the rows off screen unrendered while the row itself, and what hangs off it, stay; the status dot is one of those, sitting on the avatar's corner and out past its edge, where the box would clip it #} {% macro list_item(title, subtitle=none, status=none, identity=none, icon_name=none, icons=none, settings=none, href=none, push=none, on=false, off=false, extra_class="", id=none, target="#main", attrs="", opens=none) -%} {% set href = none if off else href %} <{{ "a" if href else "div" }} class="li{% if extra_class %} {{ extra_class }}{% endif %}{% if on %} on{% endif %}{% if off %} off{% endif %}"{% if href %} href="{{ href }}" hx-get="{{ href }}" hx-target="{{ target }}" hx-push-url="{{ push or 'true' }}"{% if settings %} hx-trigger="click[!event.target.closest('.gear')]"{% endif %}{% endif %}{% if id %} id="{{ id }}"{% endif %}{% if attrs %} {{ attrs|safe }}{% endif %}>
{% if identity is not none %}{{ avatar(identity, opens=opens) }}{% elif icon_name %}
{{ icon(icon_name) }}
{% endif %}
{{ title }}{% if subtitle %}{{ subtitle }}{% endif %}
{% if icons %}{{ icons }}{% endif %} {# the way to the thing's own page, at the row's end: a button inside the row's link, so a click on it goes there and not where the row goes; it turns while the page is on its way #} {% if settings %}{% endif %}
{% if status %}{{ dot(status) }}{% endif %} {% if caller is defined %}{{ caller() }}{% endif %} {%- endmacro %} {# the end of what a list has loaded, carrying the id it ends at so a refresh can ask for the same stretch; while the list goes on, scrolling it into view asks for the next page, which takes its place #} {% macro edge(at, more, url) -%}
{%- endmacro %} {# where a conversation's messages are read from: the agent and the conversation by their numbers, and what the row that opened it said the conversation is called and is on #} {% macro messages_url(agent, contact) -%} /agents/{{ ref(agent.computer_id) }}/{{ ref(agent.id) }}/contacts/{{ ref(contact.thread_id) }}/messages?actor={{ ref(contact.actor_id) }}&target={{ ref(contact.target) }}&channel={{ contact.channel|urlencode }}&name={{ contact.name|urlencode }} {%- endmacro %} {# a heading inside a body, for the groups a detail pane is made of #} {% macro section_title(text) -%}
{{ text }}
{%- endmacro %} {% macro empty(text) -%}
{{ text }}
{%- endmacro %}