{% extends "base.html" %} {% block title %}Store submissions — {{ config.INSTANCE_NAME }}{% endblock %} {% block content %} {% set base_qs %} {%- if status_filter %}status={{ status_filter }}&{% endif -%} {%- if submitter_filter %}submitter={{ submitter_filter }}&{% endif -%} {%- if type_filter %}type={{ type_filter }}&{% endif -%} {%- if name_filter %}name={{ name_filter }}&{% endif -%} {%- if version_filter %}version={{ version_filter }}&{% endif -%} {%- if sort_filter %}sort={{ sort_filter }}&{% endif -%} {%- if order_filter %}order={{ order_filter }}&{% endif -%} {%- endset %} {% set base_qs_no_sort %} {%- if status_filter %}status={{ status_filter }}&{% endif -%} {%- if submitter_filter %}submitter={{ submitter_filter }}&{% endif -%} {%- if type_filter %}type={{ type_filter }}&{% endif -%} {%- if name_filter %}name={{ name_filter }}&{% endif -%} {%- if version_filter %}version={{ version_filter }}&{% endif -%} {%- endset %} {# Sort-link helper: clicking a sortable header toggles asc/desc on that column while preserving every active filter. Default order on first click of any column except created_at is ascending; clicking the active column flips it. #} {% macro sort_link(col, label) -%} {% set is_active = (sort_filter == col) %} {% set new_order = "desc" if (is_active and order_filter == "asc") else ("asc" if is_active else ("desc" if col == "created_at" else "asc")) %} {{ label }}{% if is_active %}{{ " ↓" if order_filter == "desc" else " ↑" }}{% endif %} {%- endmacro %} {# Format bytes to KB for display. Returns "—" when None. #} {% macro fmt_size(b) -%} {%- if b is none -%}—{%- elif b < 1024 -%}{{ b }} B{%- elif b < 1048576 -%}{{ "%.1f"|format(b / 1024) }} KB{%- else -%}{{ "%.1f"|format(b / 1048576) }} MB{%- endif -%} {%- endmacro %}
{% set page_hero_eyebrow = "Agent Experience" %} {% set page_hero_title = "Flea Submissions" %} {% set page_hero_subtitle = "Plugin / skill / agent submissions awaiting review." %} {% include "_page_hero.html" %}
{# Preserve status filter when submitting other filters. #} {% if status_filter %}{% endif %} {% if submitter_filter %}{% endif %}
Reset
{% if submitter_filter %}
Submitter: {{ submitter_email or submitter_filter }} ✕ clear
{% endif %}
{% set _common %}{% if submitter_filter %}submitter={{ submitter_filter }}&{% endif %}{% if type_filter %}type={{ type_filter }}&{% endif %}{% if name_filter %}name={{ name_filter }}&{% endif %}{% if version_filter %}version={{ version_filter }}&{% endif %}{% endset %} {# "All" excludes lifecycle-end states (archived, deleted) by default — admin queue stays focused on actionable rows. The Archived / Deleted chips opt back in. #} All {% set _pending = "pending_llm,pending_inline" %} Pending {# Inline failures on the upload path are hard-rejected and create no rows — the only producer of `blocked_inline` post-v30 is the admin Rescan flow, which re-runs inline checks against an already-quarantined bundle. Include it here so an admin who triggers a rescan sees the result in their default queue instead of having to scroll to 'All'. Legacy `blocked_inline` rows from pre-v30 instances also surface here, which is fine — same actionable state. #} {% set _needs = "blocked_inline,blocked_llm,review_error" %} Needs review Approved Overridden Archived Deleted
{% if items %} {% for s in items %} {% endfor %}
{{ sort_link("created_at", "When") }} Submitter Type / {{ sort_link("name", "name") }} v# Hash {{ sort_link("status", "Status") }} {{ sort_link("file_size", "Size") }} Findings Model
{{ s.created_at.strftime("%Y-%m-%d %H:%M:%S") if s.created_at else "" }} {# Filter-by-submitter link. stopPropagation in JS so row click is suppressed when clicking the email. #} {{ s.submitter_email or s.submitter_id }} {{ s.type }} {{ s.name | store_display_name }} {%- if s.version_no -%} v{{ s.version_no }} {%- if s.entity_version_no and s.entity_version_no == s.version_no %} current {%- endif %} {%- else -%} {%- endif -%} {{ s.version[:12] if s.version else "" }} {{ s.status }} {{ fmt_size(s.file_size) }} {%- if s.inline_checks and s.inline_checks.static_security and s.inline_checks.static_security.findings -%} {%- for f in s.inline_checks.static_security.findings %} [{{ f.severity }}] {{ f.file }}:{{ f.line }} — {{ f.reason }} {%- endfor %} {%- endif -%} {%- if s.inline_checks and s.inline_checks.manifest and s.inline_checks.manifest.issues %} manifest: {{ s.inline_checks.manifest.issues | join(", ") }} {%- endif -%} {%- if s.llm_findings and s.llm_findings.summary %} llm: {{ s.llm_findings.risk_level }} — {{ s.llm_findings.summary }} {%- endif -%} {%- if s.llm_findings and s.llm_findings.error %} error: {{ s.llm_findings.error }} {%- endif -%} {{ s.reviewed_by_model or "" }}
{% set first = skip + 1 if total else 0 %} {% set last = skip + items|length %} Showing {{ first }}–{{ last }} of {{ total }}
{% set prev_skip = (skip - limit) if (skip - limit) > 0 else 0 %} {% if skip > 0 %} ‹ Prev {% else %} ‹ Prev {% endif %} page {{ current_page }} of {{ pages }} {% if current_page < pages %} Next › {% else %} Next › {% endif %}
{% else %}
No submissions match the current filter.
{% endif %}
{% endblock %}