-
Notifications
You must be signed in to change notification settings - Fork 2
plat 335
| Coordination | Value |
|---|---|
| Assigned agent | Unassigned (proposal) |
| Ticket state | pilot implemented and browser-verified |
| Last synchronized | 2026-09-20 |
-
No nested iframes, ever. One sandboxed iframe per dashboard (siblings
only when several reports share a screen). Widgets are bridge methods on
the existing
window.reportobject, not documents — the proposal adds zero frames. Verified: current dashboards contain zero<iframe. - Widgets are optional, never mandated. Full-custom dashboards remain valid; the validator and guidance must accept both styles. Widgets are a vocabulary expansion, not a template mandate.
-
Theming contract: widgets inherit the dashboard theme via the host's
CSS variables (
hsl(var(--…))app tokens,color-mix/currentColorpatterns per the existing goal/costs widgets) and impose no look of their own. No fixed palette, no imposed typeface. -
Scope split: pilot is
renderTable+renderActivityonly.renderActionsis a separate follow-up (it encodes the PLAT-293 save-then-send contract plus receipts/dedup — too much for the pilot).renderCollapsibleis a CSS-only candidate (<details>+ theme), not necessarily a JS API.renderTabs/renderKpislater. -
Survey correction: 12 local dashboards, 204–2201 lines
(salesoutreach largest at 2201, not 1952). Action APIs ARE already used
locally (
jobsearch:sendChatMessage+updateField;hetznerssh,websiteaeo,salesoutreach:updateField(s)), which strengthens therenderActionsfollow-up case.
Every dashboard in the fleet is one large self-contained HTML file because the
sandboxed srcdoc runtime cannot load relative <link>/<script src>
(report_html_tools.go warns they are "ignored inside the sandboxed report —
drop the tag or inline the asset"). Surveyed:
- Local live dashboards: 8 files, 188–1952 lines
(
workspace-docs/Workflow/*/db/reports/index.html,gstdatacollection/db/reports/gst_dashboard.html, one Crew dashboard). - Local baked static reports: ~40 ×
Comprehensive_Income_Tax_Report.html(400–641 lines each, zerowindow.reportcalls — per-client generated artifacts, a separate genre this ticket does not serve). - Confida server (
confida@116.202.210.102,/srv/confida/data/docs/Workflow/confida-login/db/reports/index.html): 3827 lines, the largest dashboard in the fleet.
Every live dashboard hand-rolls the same five things with raw
window.report.query + custom JS/CSS:
| Pattern | Live dashboards using it |
|---|---|
Tabs (nav-tabs, role=tab, data-tab) |
7/9 |
| KPI/stat tiles | 6/9 |
| Cards (4–32 per file) | 9/9 |
| Tables (1–15 per file, manual row-html loops) | 9/9 |
Activity tab (tab-activity/panel-activity, required by policy) |
6/9 |
Across all local dashboards the only window.report calls are query,
getText, fileUrl, renderMarkdown, ready, openFile, focus.
Confida additionally shows the heaviest action-button usage in the fleet
(13 sendChatMessage calls, 1 updateField) plus bespoke collapsible
detail cards (collapsible-card, smoke-detail-card, linear-detail-card).
Zero uses
of renderGoalProgress, renderCosts, getGoalMetrics, or getCosts —
the two widgets the platform ships cover goal/costs only, while agents need
tables, KPIs, tabs, and activity. renderEvaluations/getEvaluations are
additionally gone from the runtime after the PLAT-333 eval-subsystem removal,
but reporting-policy.md, report-plan.md, improve-report.md, and
design-reporting-ui.md still tell agents to call them — a stale promise
that rejects as unavailable at runtime.
No workflow can author small dashboard files today: partials via
getText+innerHTML carry markup/CSS only (<script> injected that way
never executes), local JS/CSS files never load in the sandbox, and the only
shipped widgets cover two sections agents rarely need. This is the same shape
as PLAT-293/PLAT-256 — a missing capability tier on window.report, not a
per-workflow decision. A full React/TS migration was considered and rejected:
agent-authored TSX needs a build + sandbox anyway (the iframe stays), while
validation, preview, guidance, and every existing dashboard would need a
rewrite.
Add six optional composition widgets on window.report, following the
existing renderGoalProgress/renderCosts contract (empty container,
replace contents on refresh, reject on failure, identical behavior in the
app and preview_report via the shared host runtime):
-
renderTabs(target, [{id, title, content}])— accessible tab shell honoringreport:focus; reuse the existingreportTabSelection.tspersistence. -
renderKpis(target, {query | items})—{label, value, tone}tiles. -
renderTable(target, {query, searchable, sortable})— themed, responsive table with empty state; kills the most repeated code in the fleet. -
renderActivity(target)— the policy-required activity tab fromorg_dashboard_notifications(notification_kind='run_summary'), route-grouped viaroute_summaries_json, markdown-rendered. Zero config for the one section every dashboard must have. -
renderActions(target, {actions})— save-then-send buttons per the PLAT-293 contract (updateField/updateFieldsfirst, thensendChatMessagewith stablerequestId), with built-in queued/sending/failed receipts and double-click dedup. Motivated by Confida's 13 hand-wired action calls. -
renderCollapsible(target, {sections})— themed expandable detail sections with summary rows; replaces bespoke collapsible-card JS/CSS (Confida'ssmoke-detail-card/linear-detail-cardpattern). - Shared card stylesheet (CSS only — not every widget needs JS).
Target: new dashboards drop from ~500–3800 lines to ~100–200 lines of
composition. Adoption is opt-in; existing dashboards keep working untouched.
Suggested pilot: renderActivity + renderTable first (highest
repetition, clearest contract), with renderActions as fast-follow on the
Confida evidence.
- New
frontend/src/components/workflow/reportWidgets/reportComposition.ts(+ tests besidereportOperationalMetrics.test.ts). - Wire into
window.reportinreportHostRuntime.ts: real API object, bootstrap stub queue list, and pending-call replay map. - Add names to
reportKnownReportMethodsinpkg/orchestrator/agents/workflow/step_based_workflow/report_html_tools.gosovalidate_report_htmlaccepts them; drop the stalegetEvaluations/renderEvaluationsentries so calls to the removed API are flagged instead of silently accepted. - Guidance (one rewrite, subsumes the eval-cleanup): document the new
helpers as optional in
reporting-policy.mdanddesign-reporting-ui.md, and remove therenderEvaluations/getEvaluationspromises fromreporting-policy.md,report-plan.md,improve-report.md, anddesign-reporting-ui.md. Notedocs/report-metric-widgets.mddocuments the eval widget too and needs the same cleanup (outsideguidance/). - No
views.json, multi-document, orwindow.reportdata-API changes.
-
frontend/src/components/workflow/reportWidgets/reportComposition.test.ts: 7 tests (table render/empty state, query validation, refresh race, search/sort, activity route-grouping, log fallback, limit validation, pre-injection replay through the realinstallReportHost). Green. - Full
reportWidgets/vitest suite: 61/61 green (no regressions). -
tsc -bclean;eslinton changed widget files clean. - Go validator: new
TestValidateHTMLReportCompositionWidgets(renderTable/renderActivityaccepted, removed eval methods rejected); fullstep_based_workflowpackage green. - Guidance-render suite (
agent_go/cmd/server/guidance): green after the template edits. - Browser
preview_reportrender: PASS.TestReportPreviewRealE2Eagainst a scratch composed dashboard (renderTable+renderActivityover a scratch sqlite db) renderedreadyin headless Chromium with zero script/page errors; screenshot confirms the filterable/sortable table (3 rows, numeric right-aligned) and the route-grouped activity card with markdown summary. Requires the rebuiltreport-preview.jsbundle (npm run build:report-preview) and a native workspace server (NATIVE_WORKSPACE=true, else shell-outs get the Docker PATH andagent-browseris not found).
Auto-synced from docs/ on main. Edit there, not here.