feat(dashboards): table-backed dashboard files behind a rollout flag - #8305
TheodoreSpeaks wants to merge 22 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Dashboards are now ordinary workspace files, handled like Sim pages, instead of a separate resource. Creating or uploading `<Name>.dashboard` drops the suffix and stamps `text/x-sim-dashboard`; the type is sticky across content writes. The file viewer renders it live behind the `dashboards` flag, and the public share viewer shows a workspace-only notice. - Remove the dashboard resource: sidebar page, API routes, hooks, contracts, application layer, Mothership dashboards/dashboard_folders tools, resource tags, and the per-turn dashboardsEnabled payload. - Revert the file discovery column (0385) and drop the dashboard folder resource enum (0384); dashboards never shipped, so no backfill. - Chat panel decides previewability and tab/picker icons from the file type, not the name, so extensionless dashboards render and get the chart icon. - Renderer: authored left label columns are kept intact, horizontal bar frames grow with row count, and hovered rows get a label-and-bar highlight. - Simplify the create-dashboard skill around one validated example. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
Resolves conflicts in the feature-flag and skill use-case tests (moved onto staging's central mocks) and the tab strip widths. Adapts the branch's dashboard and analytics tests to staging's test-pattern audit, scopes the table operation delegation invariant to operations that admit delegated principals, and hides the rollout-gated create-dashboard built-in from the organization composer when the dashboards flag is off. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
|
There was a problem hiding this comment.
All reported issues were addressed across 86 files
Tip: instead of fixing issues one by one fix them all with cubic
Re-trigger cubic
- Size horizontal bar `.chart` previews by category count like dashboard panels. - Keep the ECharts label column for percentage bar widths, resolve percentage grid insets for the row highlight, and keep the time axis on the queried range. - Show small readout values with significant digits instead of rounding to 0. - Pass the dashboard's timezone-adjusted today to the range calendar. - Decide the Chat panel's Markdown mode from the file record. - Replace mock-call assertions in the EChartsView tests with DOM behavior. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 86 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
… resizes Unstacked bar series sit side by side in a category row, so grouped charts keep the ECharts label column and their rows fit every bar slot. The row highlight redraws the active row after each render, so a resize moves it with the plot. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 83 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
…Pages Drop the create-dashboard built-in skill and its rollout gating in the skill lists. Mothership now learns the dashboard format from a sim-dashboards reference in its own research-and-deliverables skill, the pattern Sim Pages use; Sim workspace built-ins stay Agent-block documents. The dashboards flag still gates the viewer and table analytics. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 76 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 76 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
The v2 file create, replace and edit responses now carry `diagnostics` for a dashboard file: its parse errors, or an empty list. Writes are never blocked, like the page lint; table columns and queries are still checked when panels render. Parse errors are reported as `path: message` lines, and a block with no recognized kind names the allowed kinds and unknown keys instead of Zod's union dump. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 86 files
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Fix all with cubic | Re-trigger cubic
…create revision - One diagnostics entry per parse error instead of a newline-joined string. - A panel choosing aggregate or columns drops the other mode's inherited dashboard fields, so shared defaults serve table and aggregate panels. - The v2 create response returns the revision it produced, like the replace and edit responses. - The analytics route test uses the shared createMockRequest helper. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV
|
@cubic-dev-ai review this PR |
@TheodoreSpeaks I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
1 issue found across 86 files
Confidence score: 3/5
- In
apps/sim/lib/dashboards/diagnostics.ts, the 128 KiB check runs only after converting a write of up to 50 MiB to a string and encoding it again, which can cause avoidable memory and CPU spikes before rejection; check the byte length first and return the size diagnostic.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/lib/dashboards/diagnostics.ts">
<violation number="1" location="apps/sim/lib/dashboards/diagnostics.ts:14">
P2: A dashboard write can be 50 MiB, but this converts it to a string before `parseDashboardSpec` checks its 128 KiB cap, and that check encodes the whole string again. Check the byte length first and return the size diagnostic to avoid synchronous full-payload copies on oversized writes.</violation>
</file>
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Fix all with cubic | Re-trigger cubic
| content: Buffer | string | ||
| ): string[] | undefined { | ||
| if (contentType !== DASHBOARD_CONTENT_TYPE) return undefined | ||
| const { error } = parseDashboardSpec(content.toString()) |
There was a problem hiding this comment.
P2: A dashboard write can be 50 MiB, but this converts it to a string before parseDashboardSpec checks its 128 KiB cap, and that check encodes the whole string again. Check the byte length first and return the size diagnostic to avoid synchronous full-payload copies on oversized writes.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/sim/lib/dashboards/diagnostics.ts, line 14:
<comment>A dashboard write can be 50 MiB, but this converts it to a string before `parseDashboardSpec` checks its 128 KiB cap, and that check encodes the whole string again. Check the byte length first and return the size diagnostic to avoid synchronous full-payload copies on oversized writes.</comment>
<file context>
@@ -0,0 +1,16 @@
+ content: Buffer | string
+): string[] | undefined {
+ if (contentType !== DASHBOARD_CONTENT_TYPE) return undefined
+ const { error } = parseDashboardSpec(content.toString())
+ return error ? error.split('\n') : []
+}
</file context>
| const { error } = parseDashboardSpec(content.toString()) | |
| if (Buffer.byteLength(content) > 128 * 1024) return ['Dashboard source exceeds 128 KB'] | |
| const { error } = parseDashboardSpec(content.toString()) |
| const inherited = source?.columns | ||
| ? omit(defaults ?? {}, ['aggregate', 'groupBy', 'bucket']) | ||
| : source?.aggregate | ||
| ? omit(defaults ?? {}, ['columns']) | ||
| : defaults | ||
| const merged = { ...inherited, ...source } |
There was a problem hiding this comment.
Aggregate sort breaks detail panels
When a dashboard defaults to an aggregate query sorted by an aggregate alias, a detail panel that selects columns still inherits that sort. The new mode-switch logic removes the aggregate but keeps its sort, so the detail query tries to use the alias as a table column and fails instead of showing rows. Drop or revalidate the inherited sort when switching query modes.
Summary
Adds table-backed dashboards as a workspace file type, handled like Sim pages. A dashboard is a YAML file that selects authorized table queries and lays out metrics, ECharts charts, tables, text, and tabs; aggregation runs on the server with bounded results and timeouts. The Files viewer and the Chat resource panel render it live.
Companion: https://github.com/simstudioai/mothership/pull/531
<Name>.dashboarddrops the suffix and stampstext/x-sim-dashboard, the same ingestion pattern pages use for.html. The type is metadata that content writes never reset. Dashboards live in Files and its folders, use the ordinary file tools, and appear in Chat as files. There is no separate resource type, folder tree, API, or Mothership tool.tables.rows.analyticsoperation. Conditional percentage aggregates reuse the table filter grammar, so tables need no 100/0 helper columns.dashboardsflag, targetable globally or by organization and resolved from the workspace's owning organization. It gates the live viewer and the analytics operation. Public share links show a workspace-only notice and never query.diagnosticslist for dashboard files: parse errors aspath: messagelines, or an empty list. Writes are never blocked, like the page lint. The OpenAPI document and CLI API are regenerated; create now documentsV2CreatedFileResponse.sim-dashboardsreference in its ownresearch-and-deliverablesskill (companion PR), the same way it learns Sim Pages. There is no Sim built-in skill; workspace built-ins stay Agent-block documents.Type of Change
Testing
.dashboardingestion (suffix dropped, type sticky across atext/plainwrite); it is written but was not run locally because Docker was unavailable.lint:check, and all repository audits pass after mergingstaging.Rollout and scope
No migrations: this branch leaves
packages/dbidentical tostaging. Enable the flag per organization in AppConfig (dashboards: { orgIds: [...] }), or setDASHBOARDS=truelocally. Public live dashboards, log queries, and per-chip MIME icons in the composer are deferred. No merge or deployment is included.Checklist
🤖 Generated with Claude Code
https://claude.ai/code/session_01S6aTRnkiu7PxYZPNPXYEMV