@agent-native/core 0.114.16 → 0.115.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent-native.eject.json +2 -0
- package/corpus/README.md +3 -3
- package/corpus/core/CHANGELOG.md +41 -0
- package/corpus/core/agent-native.eject.json +2 -0
- package/corpus/core/docs/content/agent-native-toolkit.mdx +16 -0
- package/corpus/core/docs/content/recurring-jobs.mdx +35 -6
- package/corpus/core/export-snapshot.json +4 -0
- package/corpus/core/package.json +5 -1
- package/corpus/core/src/action.ts +22 -1
- package/corpus/core/src/agent/production-agent.ts +122 -3
- package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +19 -2
- package/corpus/core/src/cli/templates-meta.ts +12 -0
- package/corpus/core/src/client/AssistantChat.tsx +53 -26
- package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +19 -0
- package/corpus/core/src/client/agent-page/use-jobs.ts +1 -0
- package/corpus/core/src/client/blocks/library/wireframe.tsx +3 -1
- package/corpus/core/src/client/chat/message-components.tsx +35 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +38 -3
- package/corpus/core/src/connections/catalog.ts +20 -1
- package/corpus/core/src/connections/reader.ts +65 -0
- package/corpus/core/src/dashboard-storage/index.ts +27 -0
- package/corpus/core/src/dashboard-storage/panel-source.ts +168 -0
- package/corpus/core/src/dashboard-storage/schema.ts +62 -0
- package/corpus/core/src/dashboard-storage/store.ts +333 -0
- package/corpus/core/src/deploy/build.ts +95 -16
- package/corpus/core/src/eject/provider-api-definitions.ts +1 -0
- package/corpus/core/src/eject/workspace-connections.ts +1 -0
- package/corpus/core/src/extensions/actions.ts +199 -73
- package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +2 -0
- package/corpus/core/src/jobs/scheduler.ts +71 -4
- package/corpus/core/src/jobs/tools.ts +31 -1
- package/corpus/core/src/localization/default-messages.ts +1 -0
- package/corpus/core/src/mcp-client/index.ts +6 -0
- package/corpus/core/src/provider-api/actions/provider-api.ts +1 -1
- package/corpus/core/src/provider-api/index.ts +190 -5
- package/corpus/core/src/secrets/register-framework-secrets.ts +8 -0
- package/corpus/core/src/server/agent-chat/context-tools.ts +9 -0
- package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
- package/corpus/core/src/server/agent-chat-plugin.ts +22 -2
- package/corpus/core/src/server/core-routes-plugin.ts +1 -0
- package/corpus/core/src/server/credential-provider.ts +9 -3
- package/corpus/core/src/server/workspace-provider-oauth.ts +181 -4
- package/corpus/core/src/styles/agent-native.css +45 -2
- package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/corpus/core/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/corpus/core/src/triggers/actions.ts +11 -2
- package/corpus/core/src/triggers/dispatcher.ts +20 -1
- package/corpus/core/src/triggers/types.ts +5 -0
- package/corpus/core/src/vite/action-types-plugin.ts +9 -1
- package/corpus/templates/analytics/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/analytics/AGENTS.md +11 -11
- package/corpus/templates/analytics/_gitignore +39 -0
- package/corpus/templates/analytics/actions/query-dashboard-panel.ts +30 -0
- package/corpus/templates/analytics/actions/update-dashboard.ts +2 -1
- package/corpus/templates/analytics/app/lib/sql-query.ts +11 -25
- package/corpus/templates/analytics/changelog/2026-07-21-fixed-extension-updates-failing-before-changes-could-be-appl.md +6 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-query.ts +1 -0
- package/corpus/templates/analytics/server/lib/dashboard-panel-source-resolver.ts +51 -0
- package/corpus/templates/analytics/server/lib/prometheus.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -1
- package/corpus/templates/assets/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/brain/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/calendar/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/calendar/_gitignore +39 -0
- package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/templates/chat/AGENTS.md +1 -1
- package/corpus/templates/clips/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/clips/AGENTS.md +7 -0
- package/corpus/templates/clips/actions/prepare-crm-call-evidence.ts +58 -0
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +88 -11
- package/corpus/templates/clips/changelog/2026-07-21-crm-call-evidence-handoff.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-21-recording-retries-and-restarts-keep-their-upload-session-so-.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +20 -5
- package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +19 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +8 -0
- package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +9 -0
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +54 -28
- package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/content/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/content/_gitignore +39 -0
- package/corpus/templates/content/learnings.defaults.md +5 -0
- package/corpus/templates/crm/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +133 -0
- package/corpus/templates/crm/.agents/skills/crm/SKILL.md +128 -0
- package/corpus/templates/crm/.agents/skills/customizing-agent-native/SKILL.md +145 -0
- package/corpus/templates/crm/.agents/skills/feature-flags/SKILL.md +169 -0
- package/corpus/templates/crm/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
- package/corpus/templates/crm/.env.example +5 -0
- package/corpus/templates/crm/AGENTS.md +120 -0
- package/corpus/templates/crm/CHANGELOG.md +1 -0
- package/corpus/templates/crm/DEVELOPING.md +66 -0
- package/corpus/templates/crm/README.md +106 -0
- package/corpus/templates/crm/_gitignore +12 -0
- package/corpus/templates/crm/actions/_crm-action-utils.ts +87 -0
- package/corpus/templates/crm/actions/_crm-dashboard.ts +69 -0
- package/corpus/templates/crm/actions/_crm-signal-utils.ts +79 -0
- package/corpus/templates/crm/actions/apply-crm-proposals.ts +203 -0
- package/corpus/templates/crm/actions/attach-call-evidence.ts +170 -0
- package/corpus/templates/crm/actions/configure-crm-connection.ts +126 -0
- package/corpus/templates/crm/actions/configure-native-crm.ts +44 -0
- package/corpus/templates/crm/actions/create-crm-record.ts +148 -0
- package/corpus/templates/crm/actions/create-crm-signal-tracker.ts +58 -0
- package/corpus/templates/crm/actions/delete-staged-dataset.ts +14 -0
- package/corpus/templates/crm/actions/get-crm-automation-recipe.ts +36 -0
- package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +33 -0
- package/corpus/templates/crm/actions/get-crm-dashboard.ts +14 -0
- package/corpus/templates/crm/actions/get-crm-overview.ts +13 -0
- package/corpus/templates/crm/actions/get-crm-pipeline-data.ts +61 -0
- package/corpus/templates/crm/actions/get-crm-record.ts +75 -0
- package/corpus/templates/crm/actions/install-crm-pipeline-dashboard.ts +81 -0
- package/corpus/templates/crm/actions/list-crm-dashboard-revisions.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-dashboards.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-proposals.ts +31 -0
- package/corpus/templates/crm/actions/list-crm-records.ts +79 -0
- package/corpus/templates/crm/actions/list-crm-saved-views.ts +15 -0
- package/corpus/templates/crm/actions/list-crm-signal-hits.ts +43 -0
- package/corpus/templates/crm/actions/list-crm-signal-trackers.ts +32 -0
- package/corpus/templates/crm/actions/list-crm-tasks.ts +22 -0
- package/corpus/templates/crm/actions/list-staged-datasets.ts +14 -0
- package/corpus/templates/crm/actions/list-workspace-connections.ts +47 -0
- package/corpus/templates/crm/actions/manage-crm-signal-tracker.ts +87 -0
- package/corpus/templates/crm/actions/manage-crm-task.ts +132 -0
- package/corpus/templates/crm/actions/navigate.ts +63 -0
- package/corpus/templates/crm/actions/provider-api-catalog.ts +22 -0
- package/corpus/templates/crm/actions/provider-api-docs.ts +54 -0
- package/corpus/templates/crm/actions/provider-api-request.ts +92 -0
- package/corpus/templates/crm/actions/query-staged-dataset.ts +44 -0
- package/corpus/templates/crm/actions/record-crm-call-insight.ts +160 -0
- package/corpus/templates/crm/actions/record-crm-smart-signal.ts +150 -0
- package/corpus/templates/crm/actions/restore-crm-dashboard-revision.ts +23 -0
- package/corpus/templates/crm/actions/review-crm-signal.ts +31 -0
- package/corpus/templates/crm/actions/run-crm-saved-view-program.ts +103 -0
- package/corpus/templates/crm/actions/run-crm-signal-trackers.ts +275 -0
- package/corpus/templates/crm/actions/run.ts +11 -0
- package/corpus/templates/crm/actions/save-crm-dashboard.ts +51 -0
- package/corpus/templates/crm/actions/save-crm-saved-view.ts +119 -0
- package/corpus/templates/crm/actions/sync-crm.ts +146 -0
- package/corpus/templates/crm/actions/update-crm-record.ts +508 -0
- package/corpus/templates/crm/actions/view-screen.ts +218 -0
- package/corpus/templates/crm/agent-native.app-skill.json +58 -0
- package/corpus/templates/crm/app/components/crm/CreateCrmRecordDialog.tsx +158 -0
- package/corpus/templates/crm/app/components/crm/CrmDashboardPanel.tsx +83 -0
- package/corpus/templates/crm/app/components/crm/CrmSignalsPanel.tsx +225 -0
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +413 -0
- package/corpus/templates/crm/app/components/crm/RecordActions.tsx +510 -0
- package/corpus/templates/crm/app/components/crm/RecordGrid.tsx +134 -0
- package/corpus/templates/crm/app/components/crm/RecordWorkspace.tsx +367 -0
- package/corpus/templates/crm/app/components/crm/SavedViewDataProgram.tsx +92 -0
- package/corpus/templates/crm/app/components/crm/Surface.tsx +96 -0
- package/corpus/templates/crm/app/components/crm/WorkOverview.tsx +180 -0
- package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +106 -0
- package/corpus/templates/crm/app/components/layout/CrmSidebar.tsx +84 -0
- package/corpus/templates/crm/app/entry.client.tsx +16 -0
- package/corpus/templates/crm/app/entry.server.tsx +10 -0
- package/corpus/templates/crm/app/global.css +167 -0
- package/corpus/templates/crm/app/hooks/use-navigation-state.ts +60 -0
- package/corpus/templates/crm/app/i18n/en-US.ts +89 -0
- package/corpus/templates/crm/app/i18n/index.ts +34 -0
- package/corpus/templates/crm/app/lib/dashboard.ts +13 -0
- package/corpus/templates/crm/app/lib/navigation.ts +54 -0
- package/corpus/templates/crm/app/lib/tab-id.ts +1 -0
- package/corpus/templates/crm/app/lib/types.ts +172 -0
- package/corpus/templates/crm/app/lib/utils.ts +1 -0
- package/corpus/templates/crm/app/root.tsx +88 -0
- package/corpus/templates/crm/app/routes/_index.tsx +26 -0
- package/corpus/templates/crm/app/routes/accounts.tsx +41 -0
- package/corpus/templates/crm/app/routes/agent.tsx +5 -0
- package/corpus/templates/crm/app/routes/ask.tsx +53 -0
- package/corpus/templates/crm/app/routes/dashboard.tsx +118 -0
- package/corpus/templates/crm/app/routes/opportunities.tsx +41 -0
- package/corpus/templates/crm/app/routes/people.tsx +41 -0
- package/corpus/templates/crm/app/routes/proposals.tsx +266 -0
- package/corpus/templates/crm/app/routes/records.$recordId.tsx +35 -0
- package/corpus/templates/crm/app/routes/settings.tsx +63 -0
- package/corpus/templates/crm/app/routes/setup.tsx +308 -0
- package/corpus/templates/crm/app/routes/tasks.tsx +252 -0
- package/corpus/templates/crm/app/routes/views.tsx +333 -0
- package/corpus/templates/crm/app/routes.ts +17 -0
- package/corpus/templates/crm/app/vite-env.d.ts +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-agent-native-crm.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-clips-call-evidence-review-recipe.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-find-and-review-evidence-grounded-call-signals-w.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-crm-can-now-manage-keyword-and-smart-call-signal-trackers-fr.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-delegated-local-crm-automation.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-native-sql.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboard.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-pipeline-dashboards-now-install-correctly-from-the-crm-actio.md +6 -0
- package/corpus/templates/crm/changelog/2026-07-21-salesforce-connection.md +6 -0
- package/corpus/templates/crm/components.json +20 -0
- package/corpus/templates/crm/docs/architecture/crm-contract.md +180 -0
- package/corpus/templates/crm/learnings.defaults.md +5 -0
- package/corpus/templates/crm/package.json +59 -0
- package/corpus/templates/crm/public/favicon.svg +1 -0
- package/corpus/templates/crm/public/icon-180.svg +1 -0
- package/corpus/templates/crm/public/manifest.json +11 -0
- package/corpus/templates/crm/react-router.config.ts +7 -0
- package/corpus/templates/crm/server/crm/adapter.ts +32 -0
- package/corpus/templates/crm/server/crm/crm-field-firewall.ts +64 -0
- package/corpus/templates/crm/server/crm/crm-mirror.ts +711 -0
- package/corpus/templates/crm/server/crm/hubspot-adapter.ts +1143 -0
- package/corpus/templates/crm/server/crm/native-adapter.ts +1715 -0
- package/corpus/templates/crm/server/crm/read-through.ts +207 -0
- package/corpus/templates/crm/server/crm/salesforce-adapter.ts +1255 -0
- package/corpus/templates/crm/server/db/crm-store.ts +1170 -0
- package/corpus/templates/crm/server/db/index.ts +169 -0
- package/corpus/templates/crm/server/db/schema.ts +441 -0
- package/corpus/templates/crm/server/lib/intelligence/default-detectors.ts +65 -0
- package/corpus/templates/crm/server/lib/intelligence/evidence.ts +105 -0
- package/corpus/templates/crm/server/lib/intelligence/keyword-detector.ts +100 -0
- package/corpus/templates/crm/server/lib/intelligence/smart-detector.ts +144 -0
- package/corpus/templates/crm/server/lib/intelligence/summary.ts +141 -0
- package/corpus/templates/crm/server/lib/provider-api.ts +64 -0
- package/corpus/templates/crm/server/middleware/auth.ts +4 -0
- package/corpus/templates/crm/server/plugins/agent-chat.ts +68 -0
- package/corpus/templates/crm/server/plugins/auth.ts +14 -0
- package/corpus/templates/crm/server/plugins/core-routes.ts +17 -0
- package/corpus/templates/crm/server/plugins/db.ts +454 -0
- package/corpus/templates/crm/server/routes/[...page].get.ts +5 -0
- package/corpus/templates/crm/shared/crm-automation-recipes.ts +132 -0
- package/corpus/templates/crm/shared/crm-contract.ts +254 -0
- package/corpus/templates/crm/shared/crm-sales-config.ts +63 -0
- package/corpus/templates/crm/ssr-entry.ts +11 -0
- package/corpus/templates/crm/tsconfig.json +24 -0
- package/corpus/templates/crm/vite.config.ts +15 -0
- package/corpus/templates/crm/vitest.config.ts +5 -0
- package/corpus/templates/design/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/dispatch/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/forms/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/forms/_gitignore +39 -0
- package/corpus/templates/forms/learnings.defaults.md +5 -0
- package/corpus/templates/macros/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/macros/_gitignore +39 -0
- package/corpus/templates/macros/learnings.defaults.md +5 -0
- package/corpus/templates/mail/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/mail/_gitignore +39 -0
- package/corpus/templates/plan/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +19 -2
- package/corpus/templates/plan/AGENTS.md +10 -0
- package/corpus/templates/plan/actions/create-prototype-plan.ts +27 -3
- package/corpus/templates/plan/actions/get-plan-blocks.ts +1 -1
- package/corpus/templates/plan/actions/update-visual-plan.ts +3 -2
- package/corpus/templates/plan/app/components/plan/PlanContentRenderer.tsx +18 -4
- package/corpus/templates/plan/app/components/plan/PlanVisualSurface.tsx +10 -3
- package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +3 -1
- package/corpus/templates/plan/app/i18n/en-US.ts +6 -0
- package/corpus/templates/plan/app/lib/create-plan-routing.ts +39 -0
- package/corpus/templates/plan/app/pages/PlansPage.tsx +31 -107
- package/corpus/templates/plan/changelog/2026-07-22-high-fidelity-mockup-requests-now-preserve-branded-css-use-d.md +6 -0
- package/corpus/templates/plan/shared/plan-content.ts +110 -2
- package/corpus/templates/slides/.agents/skills/agent-native-docs/SKILL.md +115 -0
- package/corpus/templates/slides/_gitignore +39 -0
- package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/corpus/templates/tasks/_gitignore +39 -0
- package/corpus/toolkit/CHANGELOG.md +12 -0
- package/corpus/toolkit/README.md +30 -0
- package/corpus/toolkit/agent-native.eject.json +33 -0
- package/corpus/toolkit/package.json +15 -1
- package/corpus/toolkit/src/dashboard/DataTable.tsx +273 -0
- package/corpus/toolkit/src/dashboard/DateRangePicker.tsx +57 -0
- package/corpus/toolkit/src/dashboard/GenericChartPanel.tsx +461 -0
- package/corpus/toolkit/src/dashboard/MetricCard.tsx +54 -0
- package/corpus/toolkit/src/dashboard/StatsCard.tsx +49 -0
- package/corpus/toolkit/src/dashboard/dashboard-layout.ts +329 -0
- package/corpus/toolkit/src/dashboard/index.ts +6 -0
- package/corpus/toolkit/src/index.ts +1 -0
- package/corpus/toolkit/src/ui/calendar.tsx +8 -8
- package/corpus/toolkit/src/ui/date-picker.tsx +4 -1
- package/dist/action.d.ts +14 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js.map +1 -1
- package/dist/agent/production-agent.d.ts +3 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +97 -3
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
- package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/visual-plan-skill.js +19 -2
- package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
- package/dist/cli/templates-meta.d.ts.map +1 -1
- package/dist/cli/templates-meta.js +12 -0
- package/dist/cli/templates-meta.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +4 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +30 -17
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
- package/dist/client/agent-page/AgentJobsTab.js +3 -1
- package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
- package/dist/client/agent-page/use-jobs.d.ts +1 -0
- package/dist/client/agent-page/use-jobs.d.ts.map +1 -1
- package/dist/client/agent-page/use-jobs.js.map +1 -1
- package/dist/client/blocks/library/wireframe.d.ts.map +1 -1
- package/dist/client/blocks/library/wireframe.js +3 -2
- package/dist/client/blocks/library/wireframe.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +5 -0
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +17 -1
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +3 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +17 -7
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/connections/catalog.d.ts +17 -3
- package/dist/connections/catalog.d.ts.map +1 -1
- package/dist/connections/catalog.js +16 -1
- package/dist/connections/catalog.js.map +1 -1
- package/dist/connections/reader.d.ts +18 -0
- package/dist/connections/reader.d.ts.map +1 -1
- package/dist/connections/reader.js +41 -0
- package/dist/connections/reader.js.map +1 -1
- package/dist/dashboard-storage/index.d.ts +4 -0
- package/dist/dashboard-storage/index.d.ts.map +1 -0
- package/dist/dashboard-storage/index.js +4 -0
- package/dist/dashboard-storage/index.js.map +1 -0
- package/dist/dashboard-storage/panel-source.d.ts +68 -0
- package/dist/dashboard-storage/panel-source.d.ts.map +1 -0
- package/dist/dashboard-storage/panel-source.js +76 -0
- package/dist/dashboard-storage/panel-source.js.map +1 -0
- package/dist/dashboard-storage/schema.d.ts +562 -0
- package/dist/dashboard-storage/schema.d.ts.map +1 -0
- package/dist/dashboard-storage/schema.js +32 -0
- package/dist/dashboard-storage/schema.js.map +1 -0
- package/dist/dashboard-storage/store.d.ts +62 -0
- package/dist/dashboard-storage/store.d.ts.map +1 -0
- package/dist/dashboard-storage/store.js +227 -0
- package/dist/dashboard-storage/store.js.map +1 -0
- package/dist/deploy/build.d.ts +7 -0
- package/dist/deploy/build.d.ts.map +1 -1
- package/dist/deploy/build.js +78 -14
- package/dist/deploy/build.js.map +1 -1
- package/dist/eject/provider-api-definitions.d.ts +2 -1
- package/dist/eject/provider-api-definitions.d.ts.map +1 -1
- package/dist/eject/provider-api-definitions.js +1 -0
- package/dist/eject/provider-api-definitions.js.map +1 -1
- package/dist/eject/workspace-connections.d.ts.map +1 -1
- package/dist/eject/workspace-connections.js +1 -0
- package/dist/eject/workspace-connections.js.map +1 -1
- package/dist/extensions/actions.d.ts.map +1 -1
- package/dist/extensions/actions.js +165 -67
- package/dist/extensions/actions.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/actions/list-recurring-jobs.d.ts +1 -0
- package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -1
- package/dist/jobs/actions/list-recurring-jobs.js +1 -0
- package/dist/jobs/actions/list-recurring-jobs.js.map +1 -1
- package/dist/jobs/scheduler.d.ts +17 -2
- package/dist/jobs/scheduler.d.ts.map +1 -1
- package/dist/jobs/scheduler.js +51 -2
- package/dist/jobs/scheduler.js.map +1 -1
- package/dist/jobs/tools.d.ts.map +1 -1
- package/dist/jobs/tools.js +32 -2
- package/dist/jobs/tools.js.map +1 -1
- package/dist/localization/default-messages.d.ts +1 -0
- package/dist/localization/default-messages.d.ts.map +1 -1
- package/dist/localization/default-messages.js +1 -0
- package/dist/localization/default-messages.js.map +1 -1
- package/dist/mcp-client/index.d.ts +2 -0
- package/dist/mcp-client/index.d.ts.map +1 -1
- package/dist/mcp-client/index.js +5 -0
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
- package/dist/provider-api/actions/provider-api.d.ts +8 -6
- package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
- package/dist/provider-api/actions/provider-api.js +1 -1
- package/dist/provider-api/actions/provider-api.js.map +1 -1
- package/dist/provider-api/index.d.ts +11 -7
- package/dist/provider-api/index.d.ts.map +1 -1
- package/dist/provider-api/index.js +143 -5
- package/dist/provider-api/index.js.map +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
- package/dist/secrets/register-framework-secrets.js +7 -0
- package/dist/secrets/register-framework-secrets.js.map +1 -1
- package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
- package/dist/server/agent-chat/context-tools.js +9 -0
- package/dist/server/agent-chat/context-tools.js.map +1 -1
- package/dist/server/agent-chat/framework-prompts.js +2 -2
- package/dist/server/agent-chat/framework-prompts.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +18 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +1 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +4 -3
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +9 -3
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/workspace-provider-oauth.d.ts +6 -1
- package/dist/server/workspace-provider-oauth.d.ts.map +1 -1
- package/dist/server/workspace-provider-oauth.js +141 -4
- package/dist/server/workspace-provider-oauth.js.map +1 -1
- package/dist/styles/agent-native.css +45 -2
- package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/chat/AGENTS.md +1 -1
- package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/dist/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/dist/triggers/actions.d.ts.map +1 -1
- package/dist/triggers/actions.js +10 -2
- package/dist/triggers/actions.js.map +1 -1
- package/dist/triggers/dispatcher.d.ts.map +1 -1
- package/dist/triggers/dispatcher.js +15 -0
- package/dist/triggers/dispatcher.js.map +1 -1
- package/dist/triggers/types.d.ts +5 -0
- package/dist/triggers/types.d.ts.map +1 -1
- package/dist/triggers/types.js.map +1 -1
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +4 -1
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/content/agent-native-toolkit.mdx +16 -0
- package/docs/content/recurring-jobs.mdx +35 -6
- package/package.json +7 -3
- package/src/action.ts +22 -1
- package/src/agent/production-agent.ts +122 -3
- package/src/cli/skills-content/visual-plan-skill.ts +19 -2
- package/src/cli/templates-meta.ts +12 -0
- package/src/client/AssistantChat.tsx +53 -26
- package/src/client/agent-page/AgentJobsTab.tsx +19 -0
- package/src/client/agent-page/use-jobs.ts +1 -0
- package/src/client/blocks/library/wireframe.tsx +3 -1
- package/src/client/chat/message-components.tsx +35 -1
- package/src/client/chat/tool-call-display.tsx +38 -3
- package/src/connections/catalog.ts +20 -1
- package/src/connections/reader.ts +65 -0
- package/src/dashboard-storage/index.ts +27 -0
- package/src/dashboard-storage/panel-source.ts +168 -0
- package/src/dashboard-storage/schema.ts +62 -0
- package/src/dashboard-storage/store.ts +333 -0
- package/src/deploy/build.ts +95 -16
- package/src/eject/provider-api-definitions.ts +1 -0
- package/src/eject/workspace-connections.ts +1 -0
- package/src/extensions/actions.ts +199 -73
- package/src/jobs/actions/list-recurring-jobs.ts +2 -0
- package/src/jobs/scheduler.ts +71 -4
- package/src/jobs/tools.ts +31 -1
- package/src/localization/default-messages.ts +1 -0
- package/src/mcp-client/index.ts +6 -0
- package/src/provider-api/actions/provider-api.ts +1 -1
- package/src/provider-api/index.ts +190 -5
- package/src/secrets/register-framework-secrets.ts +8 -0
- package/src/server/agent-chat/context-tools.ts +9 -0
- package/src/server/agent-chat/framework-prompts.ts +2 -2
- package/src/server/agent-chat-plugin.ts +22 -2
- package/src/server/core-routes-plugin.ts +1 -0
- package/src/server/credential-provider.ts +9 -3
- package/src/server/workspace-provider-oauth.ts +181 -4
- package/src/styles/agent-native.css +45 -2
- package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/chat/AGENTS.md +1 -1
- package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/default/.agents/skills/app-branding/SKILL.md +159 -0
- package/src/templates/default/.agents/skills/app-permissions/SKILL.md +155 -0
- package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +27 -0
- package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +31 -18
- package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +15 -0
- package/src/triggers/actions.ts +11 -2
- package/src/triggers/dispatcher.ts +20 -1
- package/src/triggers/types.ts +5 -0
- package/src/vite/action-types-plugin.ts +9 -1
- package/corpus/templates/analytics/server/handlers/sql-query.ts +0 -36
- package/corpus/templates/analytics/server/routes/api/sql-query.post.ts +0 -1
|
@@ -46,6 +46,9 @@ const prototypeSurfaceSchema = z.enum([
|
|
|
46
46
|
"panel",
|
|
47
47
|
"browser",
|
|
48
48
|
]);
|
|
49
|
+
const prototypeRenderModeSchema = z.enum(["wireframe", "design"]);
|
|
50
|
+
const boundedPrototypeHtml = (value: string) =>
|
|
51
|
+
!/<\/?(?:html|head|body|script|style)\b/i.test(value);
|
|
49
52
|
|
|
50
53
|
const prototypeScreenSchema = z.object({
|
|
51
54
|
id: z.string().optional().describe("Stable screen id"),
|
|
@@ -55,11 +58,32 @@ const prototypeScreenSchema = z.object({
|
|
|
55
58
|
.optional()
|
|
56
59
|
.describe("What the reviewer should inspect on this screen"),
|
|
57
60
|
surface: prototypeSurfaceSchema.optional().default("browser"),
|
|
61
|
+
renderMode: prototypeRenderModeSchema
|
|
62
|
+
.optional()
|
|
63
|
+
.describe(
|
|
64
|
+
'Set to "design" for polished, high-fidelity, production-like, or branded screens. Design mode persists on the artifact and disables the rough.js treatment for every viewer.',
|
|
65
|
+
),
|
|
58
66
|
html: z
|
|
59
67
|
.string()
|
|
68
|
+
.max(40_000)
|
|
69
|
+
.refine(boundedPrototypeHtml, {
|
|
70
|
+
message:
|
|
71
|
+
"Prototype HTML must be a bounded fragment without html/head/body/script/style tags. Put scoped styles in the css field.",
|
|
72
|
+
})
|
|
73
|
+
.optional()
|
|
74
|
+
.describe(
|
|
75
|
+
'Bounded semantic HTML fragment for a real interactive prototype. Use safe Alpine-like directives (x-data, x-model, x-for, x-text, x-show, :class, @click, @keydown.enter) for local behavior; use data-goto="screen-id" only for true screen/route changes. Never include html/body/script/style tags; put visual styling in css.',
|
|
76
|
+
),
|
|
77
|
+
css: z
|
|
78
|
+
.string()
|
|
79
|
+
.max(20_000)
|
|
80
|
+
.refine(boundedPrototypeHtml, {
|
|
81
|
+
message:
|
|
82
|
+
"Prototype CSS must not include document, script, or style tags.",
|
|
83
|
+
})
|
|
60
84
|
.optional()
|
|
61
85
|
.describe(
|
|
62
|
-
|
|
86
|
+
"Scoped CSS for this screen. Required when the request is high fidelity: use real codebase or brand tokens, deliberate typography, spacing, color, and state styling instead of embedding a style tag in html.",
|
|
63
87
|
),
|
|
64
88
|
state: z
|
|
65
89
|
.array(
|
|
@@ -112,7 +136,7 @@ const createPrototypePlanSchema = z.object({
|
|
|
112
136
|
.optional()
|
|
113
137
|
.default([])
|
|
114
138
|
.describe(
|
|
115
|
-
|
|
139
|
+
'Prototype screens. Default to one functional screen when local UI behavior is enough; use 2-4 screens only for true routes/steps. Screen HTML should include working local controls, inputs, toggles, lists, filters, or lightweight flows where relevant. For higher-fidelity requests, prefer create-plan-design; when the interaction itself requires a polished prototype, set each screen renderMode to "design" and pass its styling in css.',
|
|
116
140
|
),
|
|
117
141
|
transitions: z
|
|
118
142
|
.array(prototypeTransitionSchema)
|
|
@@ -143,7 +167,7 @@ const createPrototypePlanSchema = z.object({
|
|
|
143
167
|
|
|
144
168
|
export default defineAction({
|
|
145
169
|
description:
|
|
146
|
-
|
|
170
|
+
'Create a plan whose primary review surface is a running interactive prototype. For a document-first plan use create-visual-plan; for a UI-first wireframe canvas use create-ui-plan; for a recap of an existing diff use create-visual-recap; for full-fidelity branded design use create-plan-design. Prototype screen HTML uses safe Alpine-like directives for local state and data-goto for screen navigation only. If a functional prototype must also be high fidelity, set renderMode to "design" and put scoped styles in css; never embed style tags in html because they are rejected. Publish via this tool; never deliver the plan as inline chat text.',
|
|
147
171
|
schema: createPrototypePlanSchema.refine(
|
|
148
172
|
(args) => Boolean(args.brief || args.goal),
|
|
149
173
|
{ message: "Either brief or goal is required." },
|
|
@@ -49,7 +49,7 @@ const AUTHORING_RULES_NOTE = `
|
|
|
49
49
|
|
|
50
50
|
**API endpoints**: keep \`api-endpoint\` and \`openapi-spec\` blocks in normal single-column document flow. Use \`columns\` only for an explicit before/after contract comparison.
|
|
51
51
|
|
|
52
|
-
**renderMode**: leave unset or set to \`wireframe\`
|
|
52
|
+
**Visual fidelity and renderMode**: leave \`renderMode\` unset or set it to \`wireframe\` for normal wireframes. “Higher fidelity,” “pixel-accurate,” “polished mockup,” “production-like,” “real design,” or “not a sketch/wireframe” requires \`renderMode: "design"\`, substantial branded HTML/CSS grounded in the real app, and stable \`data-design-id\` targets. Put scoped styles in the wireframe/prototype \`css\` field — never in a \`<style>\` tag. On an existing plan, update the same plan id with \`set-visual-render-mode\` plus the upgraded HTML/CSS; do not create a duplicate. The viewer-local Clean toggle is not a fidelity upgrade.\``;
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* Expose the live plan block vocabulary to the agent. The list is generated from
|
|
@@ -112,6 +112,7 @@ function contentPatchTargetId(patch: PlanContentPatch) {
|
|
|
112
112
|
if ("blockId" in patch) return patch.blockId;
|
|
113
113
|
if ("screenId" in patch) return patch.screenId;
|
|
114
114
|
if (patch.op === "set-metadata") return "plan-metadata";
|
|
115
|
+
if (patch.op === "set-visual-render-mode") return "visual-render-mode";
|
|
115
116
|
if (patch.op === "set-prototype" || patch.op === "remove-prototype") {
|
|
116
117
|
return "prototype";
|
|
117
118
|
}
|
|
@@ -451,7 +452,7 @@ function contentPatchDetails(input: {
|
|
|
451
452
|
const CONTENT_DESCRIPTION =
|
|
452
453
|
"Destructive full structured content replacement. Read the latest plan first and pass its updatedAt as expectedUpdatedAt. Prefer granular contentPatches for ordinary edits; use this only for intentional broad restructuring.";
|
|
453
454
|
const CONTENT_PATCHES_DESCRIPTION =
|
|
454
|
-
"Targeted structured content edits addressed by stable id. Prefer granular operations for live plans. The destructive replace-blocks operation requires expectedUpdatedAt from a fresh read. patch-visual-plan-source is only for exported MDX folders. Supported ops: set-metadata for title/brief, set-prototype / remove-prototype / update-prototype-screen / patch-prototype-html for live prototype surfaces; update-block / replace-block, update-rich-text, patch-wireframe-html, patch-diagram-html, update-wireframe-node, replace-wireframe-screen, update-canvas-frame, update-canvas-annotation / append-canvas-annotation, append-block / remove-block, update-custom-html.";
|
|
455
|
+
"Targeted structured content edits addressed by stable id. Prefer granular operations for live plans. The destructive replace-blocks operation requires expectedUpdatedAt from a fresh read. patch-visual-plan-source is only for exported MDX folders. Supported ops: set-metadata for title/brief; set-visual-render-mode to persist `design` (high fidelity, authored CSS, no rough.js for any viewer) or `wireframe` across canvas, linked blocks, and prototype screens; set-prototype / remove-prototype / update-prototype-screen / patch-prototype-html for live prototype surfaces; update-block / replace-block, update-rich-text, patch-wireframe-html, patch-diagram-html, update-wireframe-node, replace-wireframe-screen, update-canvas-frame, update-canvas-annotation / append-canvas-annotation, append-block / remove-block, update-custom-html. A fidelity upgrade must also replace or patch the existing screen HTML/CSS with deliberate branded design; changing render mode alone only removes the sketch treatment.";
|
|
455
456
|
|
|
456
457
|
// Named so `agentInputSchema` below can `.extend()` it with compact
|
|
457
458
|
// `content`/`contentPatches` fields instead of duplicating every other key.
|
|
@@ -528,7 +529,7 @@ const updateVisualPlanSchema = z.object({
|
|
|
528
529
|
|
|
529
530
|
export default defineAction({
|
|
530
531
|
description:
|
|
531
|
-
"Update an Agent-Native Plan's structured content blocks, prototype screens, sections, comments, or status. Prefer contentPatches for targeted edits. Use full content only for broad restructuring. Works on plans and recaps alike when you have editor access; with viewer access (common on PR recaps published by CI) only comment-only calls succeed — to change a recap you cannot edit, publish a replacement with create-visual-recap instead of retrying this call.",
|
|
532
|
+
"Update an Agent-Native Plan's structured content blocks, prototype screens, visual fidelity, sections, comments, or status. Prefer contentPatches for targeted edits. When a user asks for higher fidelity on an existing plan, update that same plan in place: use set-visual-render-mode with design and provide polished screen HTML/CSS in the same call instead of creating a duplicate plan or only toggling the viewer-local clean style. Use full content only for broad restructuring. Works on plans and recaps alike when you have editor access; with viewer access (common on PR recaps published by CI) only comment-only calls succeed — to change a recap you cannot edit, publish a replacement with create-visual-recap instead of retrying this call.",
|
|
532
533
|
schema: updateVisualPlanSchema,
|
|
533
534
|
// ADVERTISED-ONLY: same top-level shape, but `content`/`contentPatches`
|
|
534
535
|
// swap the deep per-block-type union for a compact `type`-enum stand-in.
|
|
@@ -652,10 +652,24 @@ export function PlanContentRenderer({
|
|
|
652
652
|
hiddenChangedFileBlockIds,
|
|
653
653
|
hideChangedFiles,
|
|
654
654
|
]);
|
|
655
|
-
const blockLookup = useMemo(
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
655
|
+
const blockLookup = useMemo(() => {
|
|
656
|
+
const blocks = new Map<string, PlanBlock>();
|
|
657
|
+
const visit = (block: PlanBlock) => {
|
|
658
|
+
blocks.set(block.id, block);
|
|
659
|
+
if (block.type === "tabs") {
|
|
660
|
+
for (const tab of block.data.tabs) {
|
|
661
|
+
for (const child of tab.blocks) visit(child);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (block.type === "columns") {
|
|
665
|
+
for (const column of block.data.columns) {
|
|
666
|
+
for (const child of column.blocks) visit(child);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
for (const block of content.blocks) visit(block);
|
|
671
|
+
return blocks;
|
|
672
|
+
}, [content.blocks]);
|
|
659
673
|
const fileToBlockIdMap = useMemo<Map<string, string>>(() => {
|
|
660
674
|
if (!isRecap) return new Map();
|
|
661
675
|
const map = new Map<string, string>();
|
|
@@ -60,7 +60,7 @@ export function PlanVisualSurface({
|
|
|
60
60
|
onDesignElementStyleChange,
|
|
61
61
|
}: PlanVisualSurfaceProps) {
|
|
62
62
|
const t = useT();
|
|
63
|
-
const designCanvas = isDesignCanvas(canvas);
|
|
63
|
+
const designCanvas = isDesignCanvas(canvas, blockLookup);
|
|
64
64
|
const [selectedDesignElement, setSelectedDesignElement] =
|
|
65
65
|
useState<DesignElementSelection | null>(null);
|
|
66
66
|
const selectedDesignElementKey = selectedDesignElement
|
|
@@ -226,10 +226,17 @@ export function PlanVisualSurface({
|
|
|
226
226
|
return null;
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
function isDesignCanvas(
|
|
229
|
+
function isDesignCanvas(
|
|
230
|
+
canvas: PlanContent["canvas"] | undefined,
|
|
231
|
+
blockLookup: Map<string, PlanBlock>,
|
|
232
|
+
) {
|
|
230
233
|
return Boolean(
|
|
231
234
|
canvas?.mode === "design" ||
|
|
232
|
-
canvas?.frames.some((frame) =>
|
|
235
|
+
canvas?.frames.some((frame) => {
|
|
236
|
+
if (frame.wireframe) return frame.wireframe.renderMode === "design";
|
|
237
|
+
const block = frame.blockId ? blockLookup.get(frame.blockId) : undefined;
|
|
238
|
+
return block?.type === "wireframe" && block.data.renderMode === "design";
|
|
239
|
+
}),
|
|
233
240
|
);
|
|
234
241
|
}
|
|
235
242
|
|
|
@@ -194,7 +194,7 @@ function ArtboardFrame({
|
|
|
194
194
|
const fitRef = useRef<HTMLDivElement>(null);
|
|
195
195
|
const { resolvedTheme } = useTheme();
|
|
196
196
|
const theme: "light" | "dark" = resolvedTheme === "dark" ? "dark" : "light";
|
|
197
|
-
const
|
|
197
|
+
const preferredStyle = useWireframeStyle();
|
|
198
198
|
const preset = SURFACE_PRESETS[surface] ?? SURFACE_PRESETS.desktop;
|
|
199
199
|
const height = canvasSize ?? preset.height;
|
|
200
200
|
const width = canvasWidth ?? preset.width;
|
|
@@ -202,6 +202,7 @@ function ArtboardFrame({
|
|
|
202
202
|
const maxFrameWidth = compact ? preset.width * baseScale : width;
|
|
203
203
|
const [fitScale, setFitScale] = useState(baseScale);
|
|
204
204
|
const designMode = renderMode === "design";
|
|
205
|
+
const style = designMode ? "clean" : preferredStyle;
|
|
205
206
|
const sketchy = !designMode && style === "sketchy" && !skeleton;
|
|
206
207
|
const roughEnabled = sketchy && roughOverlay;
|
|
207
208
|
const paper = designMode
|
|
@@ -560,6 +561,7 @@ function KitWireframe({
|
|
|
560
561
|
canvasSize={canvasSize}
|
|
561
562
|
canvasWidth={canvasWidth}
|
|
562
563
|
skeleton={data.skeleton}
|
|
564
|
+
renderMode={data.renderMode}
|
|
563
565
|
showFrame={showFrame}
|
|
564
566
|
selector="[data-rough]"
|
|
565
567
|
caption={data.caption}
|
|
@@ -564,6 +564,10 @@ const messages = {
|
|
|
564
564
|
label: "UI flow",
|
|
565
565
|
description: "UI flow - wireframes and states",
|
|
566
566
|
},
|
|
567
|
+
design: {
|
|
568
|
+
label: "High-fidelity design",
|
|
569
|
+
description: "High-fidelity design - polished branded screens",
|
|
570
|
+
},
|
|
567
571
|
questions: {
|
|
568
572
|
label: "Visual questions",
|
|
569
573
|
description: "Visual questions - explicit intake",
|
|
@@ -587,6 +591,8 @@ const messages = {
|
|
|
587
591
|
"# Implementation plan\n\nPaste the existing Codex or Claude Code plan here and turn it into a visual review document.",
|
|
588
592
|
},
|
|
589
593
|
assessment: {
|
|
594
|
+
design:
|
|
595
|
+
"Auto detected a high-fidelity request; the agent will create polished branded screens.",
|
|
590
596
|
ui: "Auto detected UI states or flows; the agent will make a wireframe-first plan.",
|
|
591
597
|
visual:
|
|
592
598
|
"Auto will ask the agent for a rich technical plan with diagrams and implementation detail.",
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type CreatePlanKind = "auto" | "design" | "ui" | "questions" | "visual";
|
|
2
|
+
export type ResolvedPlanKind = Exclude<CreatePlanKind, "auto">;
|
|
3
|
+
export type AutoPlanKind = Exclude<ResolvedPlanKind, "questions">;
|
|
4
|
+
|
|
5
|
+
export function isProbablyImportedPlan(prompt: string) {
|
|
6
|
+
const trimmed = prompt.trim();
|
|
7
|
+
const lines = trimmed.split(/\r?\n/).filter((line) => line.trim());
|
|
8
|
+
if (trimmed.length > 900 && lines.length > 8) return true;
|
|
9
|
+
const hasHeading = lines.some((line) => /^#{1,4}\s+\S/.test(line.trim()));
|
|
10
|
+
const checklistCount = lines.filter((line) =>
|
|
11
|
+
/^[-*]\s+\[[ x]\]\s+\S/i.test(line.trim()),
|
|
12
|
+
).length;
|
|
13
|
+
const taskCount = lines.filter((line) =>
|
|
14
|
+
/^([-*]|\d+[.)])\s+\S/.test(line.trim()),
|
|
15
|
+
).length;
|
|
16
|
+
const hasPlanLanguage =
|
|
17
|
+
/\b(implementation plan|acceptance criteria|milestones?|phases?|risks?|open questions?|test plan)\b/i.test(
|
|
18
|
+
trimmed,
|
|
19
|
+
);
|
|
20
|
+
return (
|
|
21
|
+
trimmed.includes("```") ||
|
|
22
|
+
(hasHeading && (taskCount >= 3 || hasPlanLanguage)) ||
|
|
23
|
+
(checklistCount >= 2 && trimmed.length > 220)
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function assessPlanPrompt(prompt: string): { kind: AutoPlanKind } {
|
|
28
|
+
const highFidelity =
|
|
29
|
+
/\b(high(?:er)?[- ]fidelity|full[- ]fidelity|hi[- ]fi|polished(?: mockups?)?|production[- ](?:like|ready)|pixel[- ](?:perfect|accurate)|brand(?:ed|[- ]aware)|real design|not (?:a )?(?:sketch(?:y)?|wireframe)|beyond (?:the )?(?:sketch|wireframe))\b/i.test(
|
|
30
|
+
prompt,
|
|
31
|
+
);
|
|
32
|
+
if (highFidelity) return { kind: "design" };
|
|
33
|
+
|
|
34
|
+
const uiDirection =
|
|
35
|
+
/\b(ui|screen|screens|layout|wireframe|mockup|form factor|mobile|desktop|responsive|nav|sidebar|flow|redesign|empty state|loading state|error state)\b/i.test(
|
|
36
|
+
prompt,
|
|
37
|
+
);
|
|
38
|
+
return { kind: uiDirection ? "ui" : "visual" };
|
|
39
|
+
}
|
|
@@ -239,6 +239,11 @@ import {
|
|
|
239
239
|
type PlanAccessStatusResponse,
|
|
240
240
|
type PublishVisualPlanResult,
|
|
241
241
|
} from "@/hooks/use-plans";
|
|
242
|
+
import {
|
|
243
|
+
assessPlanPrompt,
|
|
244
|
+
isProbablyImportedPlan,
|
|
245
|
+
type CreatePlanKind,
|
|
246
|
+
} from "@/lib/create-plan-routing";
|
|
242
247
|
import {
|
|
243
248
|
getDesktopPlanFiles,
|
|
244
249
|
type DesktopPlanFilesFolder,
|
|
@@ -1596,9 +1601,9 @@ function buildPlanAgentContext(input: {
|
|
|
1596
1601
|
: [
|
|
1597
1602
|
"Fast iteration workflow:",
|
|
1598
1603
|
"1. Call get-visual-plan with this plan ID to read structured content, exported HTML, sections, comments, and activity.",
|
|
1599
|
-
|
|
1604
|
+
'2. Prefer update-visual-plan contentPatches for targeted edits. Examples: update-rich-text for copy, patch-prototype-html / update-prototype-screen for live prototype states, update-wireframe-node for one kit-tree node, update-canvas-frame for frame layout, append-canvas-annotation / update-canvas-annotation for canvas markup, append-block/remove-block for document changes, or replace-block for a single block. When the user asks for higher fidelity, polished mockups, production-like UI, real design, or anything "not sketchy," update this same plan in place: rewrite the relevant screen HTML/CSS and include set-visual-render-mode with renderMode design. Do not create a second plan, put CSS in style tags, or treat the viewer-local Clean toggle as a fidelity upgrade. Use full content only for broad restructuring. Use html only when preserving or importing a legacy standalone HTML artifact.',
|
|
1600
1605
|
"3. Preserve the user's existing annotation comments and intent unless the user asks to remove or resolve them.",
|
|
1601
|
-
"4.
|
|
1606
|
+
"4. Match the requested fidelity: ordinary UI planning can use sketch diagrams and wireframes; high-fidelity requests need the persisted Design surface with deliberate branded HTML/CSS and stable data-design-id targets.",
|
|
1602
1607
|
"5. After applying feedback, keep the plan scannable, editable, and serious instead of turning it into a marketing page.",
|
|
1603
1608
|
"6. Work the actionable agent comments first. Treat human-review comments as FYI/questions/approval items; do not silently resolve those unless the user explicitly asks.",
|
|
1604
1609
|
"7. When visual screenshots are attached, each crop is centered near a comment marker and has a red ring on the exact commented point. Use the comment IDs and anchor details below to connect screenshots to threads. If a visual comment is listed as overflow, rely on its anchorDetails/coordinates and call get-plan-feedback for the full manifest.",
|
|
@@ -8323,93 +8328,6 @@ const CREATE_PLAN_PROMPTS = [
|
|
|
8323
8328
|
},
|
|
8324
8329
|
] as const;
|
|
8325
8330
|
|
|
8326
|
-
type CreatePlanKind = "auto" | "ui" | "questions" | "visual";
|
|
8327
|
-
type ResolvedPlanKind = Exclude<CreatePlanKind, "auto">;
|
|
8328
|
-
type AutoPlanKind = Exclude<ResolvedPlanKind, "questions">;
|
|
8329
|
-
|
|
8330
|
-
function isProbablyImportedPlan(prompt: string) {
|
|
8331
|
-
const trimmed = prompt.trim();
|
|
8332
|
-
const lines = trimmed.split(/\r?\n/).filter((line) => line.trim());
|
|
8333
|
-
if (trimmed.length > 900 && lines.length > 8) return true;
|
|
8334
|
-
const hasHeading = lines.some((line) => /^#{1,4}\s+\S/.test(line.trim()));
|
|
8335
|
-
const checklistCount = lines.filter((line) =>
|
|
8336
|
-
/^[-*]\s+\[[ x]\]\s+\S/i.test(line.trim()),
|
|
8337
|
-
).length;
|
|
8338
|
-
const taskCount = lines.filter((line) =>
|
|
8339
|
-
/^([-*]|\d+[.)])\s+\S/.test(line.trim()),
|
|
8340
|
-
).length;
|
|
8341
|
-
const hasPlanLanguage =
|
|
8342
|
-
/\b(implementation plan|acceptance criteria|milestones?|phases?|risks?|open questions?|test plan)\b/i.test(
|
|
8343
|
-
trimmed,
|
|
8344
|
-
);
|
|
8345
|
-
return (
|
|
8346
|
-
trimmed.includes("```") ||
|
|
8347
|
-
(hasHeading && (taskCount >= 3 || hasPlanLanguage)) ||
|
|
8348
|
-
(checklistCount >= 2 && trimmed.length > 220)
|
|
8349
|
-
);
|
|
8350
|
-
}
|
|
8351
|
-
|
|
8352
|
-
function assessPlanPrompt(prompt: string): {
|
|
8353
|
-
kind: AutoPlanKind;
|
|
8354
|
-
} {
|
|
8355
|
-
let score = 0;
|
|
8356
|
-
let ambiguitySignals = 0;
|
|
8357
|
-
|
|
8358
|
-
const wantsExploration =
|
|
8359
|
-
/\b(ask questions|questions first|intake first|show me options|explore options|help me choose|not sure|unsure|which direction|compare)\b/i.test(
|
|
8360
|
-
prompt,
|
|
8361
|
-
);
|
|
8362
|
-
const exactOrTrivial =
|
|
8363
|
-
/\b(typo|copy tweak|one line|single file|exactly|no questions|don't ask|dont ask|just implement)\b/i.test(
|
|
8364
|
-
prompt,
|
|
8365
|
-
);
|
|
8366
|
-
const uiDirection =
|
|
8367
|
-
/\b(ui|screen|screens|layout|wireframe|mockup|form factor|mobile|desktop|responsive|nav|sidebar|flow|redesign|empty state|loading state|error state)\b/i.test(
|
|
8368
|
-
prompt,
|
|
8369
|
-
);
|
|
8370
|
-
const multipleApproaches =
|
|
8371
|
-
/\b(option|variant|alternative|tradeoff|approach|architecture|data model|permission|auth|integration|migration|state machine)\b/i.test(
|
|
8372
|
-
prompt,
|
|
8373
|
-
);
|
|
8374
|
-
const newSurface =
|
|
8375
|
-
/\b(new surface|multi-screen|workflow|journey|end-to-end|dashboard|settings|checkout|onboarding|review flow)\b/i.test(
|
|
8376
|
-
prompt,
|
|
8377
|
-
);
|
|
8378
|
-
const risky =
|
|
8379
|
-
/\b(auth|permission|billing|migration|schema|integration|oauth|webhook|security|role|privacy|external)\b/i.test(
|
|
8380
|
-
prompt,
|
|
8381
|
-
);
|
|
8382
|
-
|
|
8383
|
-
if (uiDirection) {
|
|
8384
|
-
score += 2;
|
|
8385
|
-
ambiguitySignals += 1;
|
|
8386
|
-
}
|
|
8387
|
-
if (multipleApproaches) {
|
|
8388
|
-
score += 2;
|
|
8389
|
-
ambiguitySignals += 1;
|
|
8390
|
-
}
|
|
8391
|
-
if (newSurface) score += 1;
|
|
8392
|
-
if (risky) score += 1;
|
|
8393
|
-
if (
|
|
8394
|
-
wantsExploration ||
|
|
8395
|
-
/\b(best|better|improve|explore|direction|choose)\b/i.test(prompt)
|
|
8396
|
-
) {
|
|
8397
|
-
score += 1;
|
|
8398
|
-
ambiguitySignals += 1;
|
|
8399
|
-
}
|
|
8400
|
-
if (exactOrTrivial) score -= 3;
|
|
8401
|
-
|
|
8402
|
-
if (uiDirection) {
|
|
8403
|
-
return {
|
|
8404
|
-
kind: "ui",
|
|
8405
|
-
};
|
|
8406
|
-
}
|
|
8407
|
-
|
|
8408
|
-
return {
|
|
8409
|
-
kind: "visual",
|
|
8410
|
-
};
|
|
8411
|
-
}
|
|
8412
|
-
|
|
8413
8331
|
function sourceOptionDisplayLabel(
|
|
8414
8332
|
source: PlanSource,
|
|
8415
8333
|
t: ReturnType<typeof useT>,
|
|
@@ -8440,11 +8358,13 @@ function buildCreatePlanAgentMessage({
|
|
|
8440
8358
|
planKind === "auto" ? assessPlanPrompt(prompt).kind : planKind;
|
|
8441
8359
|
const routing = imported
|
|
8442
8360
|
? "Build from this existing plan while preserving its intent."
|
|
8443
|
-
: resolvedPlanKind === "
|
|
8444
|
-
? "Create a
|
|
8445
|
-
: resolvedPlanKind === "
|
|
8446
|
-
? "Create
|
|
8447
|
-
:
|
|
8361
|
+
: resolvedPlanKind === "design"
|
|
8362
|
+
? "Create a design-first plan with full-fidelity branded screens. Use create-plan-design, ground the result in the real app shell and design tokens, and treat the Design tab as the visual source of truth."
|
|
8363
|
+
: resolvedPlanKind === "ui"
|
|
8364
|
+
? "Create a UI-first plan with AI-authored wireframes and state coverage."
|
|
8365
|
+
: resolvedPlanKind === "questions"
|
|
8366
|
+
? "Create visual intake questions before generating the final plan."
|
|
8367
|
+
: "Create a general visual plan with diagrams and implementation detail.";
|
|
8448
8368
|
|
|
8449
8369
|
return [
|
|
8450
8370
|
"Create an Agent-Native Plan from this request.",
|
|
@@ -8452,7 +8372,7 @@ function buildCreatePlanAgentMessage({
|
|
|
8452
8372
|
routing,
|
|
8453
8373
|
`Source/provenance: ${sourceOptionDisplayLabel(source, t)}.`,
|
|
8454
8374
|
"",
|
|
8455
|
-
"Use the Plan actions after you have enough substance. Generate the
|
|
8375
|
+
"Use the Plan actions after you have enough substance. Generate the requested review surface, diagrams, implementation map, review prompts, and concrete file/symbol notes yourself. Do not use placeholder file names, generic scaffold text, or browser-generated fallback sections as the final plan content.",
|
|
8456
8376
|
"After creating the plan, open the plan link for review.",
|
|
8457
8377
|
"",
|
|
8458
8378
|
"Request:",
|
|
@@ -8595,11 +8515,13 @@ function CreatePlanDialog({
|
|
|
8595
8515
|
),
|
|
8596
8516
|
})
|
|
8597
8517
|
: planKindDisplayLabel("auto", t)
|
|
8598
|
-
: planKind === "
|
|
8599
|
-
? planKindDisplayLabel("
|
|
8600
|
-
: planKind === "
|
|
8601
|
-
? planKindDisplayLabel("
|
|
8602
|
-
:
|
|
8518
|
+
: planKind === "design"
|
|
8519
|
+
? planKindDisplayLabel("design", t)
|
|
8520
|
+
: planKind === "ui"
|
|
8521
|
+
? planKindDisplayLabel("ui", t)
|
|
8522
|
+
: planKind === "questions"
|
|
8523
|
+
? planKindDisplayLabel("questions", t)
|
|
8524
|
+
: planKindDisplayLabel("visual", t)}
|
|
8603
8525
|
</span>
|
|
8604
8526
|
<IconChevronDown
|
|
8605
8527
|
className={cn(
|
|
@@ -8643,13 +8565,12 @@ function CreatePlanDialog({
|
|
|
8643
8565
|
value={planKind}
|
|
8644
8566
|
onValueChange={(value) =>
|
|
8645
8567
|
setPlanKind(
|
|
8646
|
-
value === "auto"
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
: "ui",
|
|
8568
|
+
value === "auto" ||
|
|
8569
|
+
value === "design" ||
|
|
8570
|
+
value === "visual" ||
|
|
8571
|
+
value === "questions"
|
|
8572
|
+
? value
|
|
8573
|
+
: "ui",
|
|
8653
8574
|
)
|
|
8654
8575
|
}
|
|
8655
8576
|
>
|
|
@@ -8665,6 +8586,9 @@ function CreatePlanDialog({
|
|
|
8665
8586
|
<SelectItem value="ui">
|
|
8666
8587
|
{t("plansPage.create.kindOptions.ui.description")}
|
|
8667
8588
|
</SelectItem>
|
|
8589
|
+
<SelectItem value="design">
|
|
8590
|
+
{t("plansPage.create.kindOptions.design.description")}
|
|
8591
|
+
</SelectItem>
|
|
8668
8592
|
<SelectItem value="questions">
|
|
8669
8593
|
{t(
|
|
8670
8594
|
"plansPage.create.kindOptions.questions.description",
|
|
@@ -854,6 +854,15 @@ export type PlanContentPatch =
|
|
|
854
854
|
title?: string;
|
|
855
855
|
brief?: string;
|
|
856
856
|
}
|
|
857
|
+
| {
|
|
858
|
+
/**
|
|
859
|
+
* Persist the artifact's visual treatment for every viewer. `design`
|
|
860
|
+
* disables sketch rendering and preserves authored HTML/CSS; it is not
|
|
861
|
+
* the same as the viewer-local clean/sketchy preference.
|
|
862
|
+
*/
|
|
863
|
+
op: "set-visual-render-mode";
|
|
864
|
+
renderMode: PlanVisualCanvasMode;
|
|
865
|
+
}
|
|
857
866
|
| {
|
|
858
867
|
op: "set-prototype";
|
|
859
868
|
prototype: PlanPrototype;
|
|
@@ -2666,7 +2675,7 @@ const prototypeScreenPatchSchema = z
|
|
|
2666
2675
|
* Raw (uncast) discriminated union behind `planContentPatchSchema`, kept as a
|
|
2667
2676
|
* named const so `agentPlanContentPatchSchema` below can walk `.options` and
|
|
2668
2677
|
* swap only the block-carrying ops for the compact `agentPlanBlockSchema`
|
|
2669
|
-
* instead of duplicating this whole
|
|
2678
|
+
* instead of duplicating this whole discriminated union.
|
|
2670
2679
|
*/
|
|
2671
2680
|
const planContentPatchUnion = z.discriminatedUnion("op", [
|
|
2672
2681
|
z
|
|
@@ -2678,6 +2687,12 @@ const planContentPatchUnion = z.discriminatedUnion("op", [
|
|
|
2678
2687
|
.refine((patch) => patch.title !== undefined || patch.brief !== undefined, {
|
|
2679
2688
|
message: "Metadata patch must include title or brief.",
|
|
2680
2689
|
}),
|
|
2690
|
+
z.object({
|
|
2691
|
+
op: z.literal("set-visual-render-mode"),
|
|
2692
|
+
renderMode: visualCanvasModeSchema.describe(
|
|
2693
|
+
"`design` persists polished HTML/CSS rendering and disables rough.js for every viewer; `wireframe` restores the viewer-controlled sketchy/clean treatment.",
|
|
2694
|
+
),
|
|
2695
|
+
}),
|
|
2681
2696
|
z.object({
|
|
2682
2697
|
op: z.literal("set-prototype"),
|
|
2683
2698
|
prototype: prototypeSchema,
|
|
@@ -2871,7 +2886,7 @@ const AGENT_WIREFRAME_NODE_PATCH_DESCRIPTION =
|
|
|
2871
2886
|
|
|
2872
2887
|
/**
|
|
2873
2888
|
* Compact ADVERTISED-ONLY stand-in for `planContentPatchSchema`, for use as
|
|
2874
|
-
* part of `defineAction`'s `agentInputSchema`. Same
|
|
2889
|
+
* part of `defineAction`'s `agentInputSchema`. Same `op` branches as the
|
|
2875
2890
|
* real union — only the ops that carry a deep block/wireframe union swap in
|
|
2876
2891
|
* their compact stand-ins:
|
|
2877
2892
|
* - `replace-block` / `append-block` / `replace-blocks`: `agentPlanBlockSchema`
|
|
@@ -2934,6 +2949,7 @@ export function applyPlanContentPatches(
|
|
|
2934
2949
|
patches: PlanContentPatch[],
|
|
2935
2950
|
): PlanContent {
|
|
2936
2951
|
const next = cloneJson(planContentSchema.parse(content));
|
|
2952
|
+
let pendingVisualRenderMode: PlanVisualCanvasMode | undefined;
|
|
2937
2953
|
|
|
2938
2954
|
for (const patch of planContentPatchesSchema.parse(patches)) {
|
|
2939
2955
|
if (patch.op === "set-metadata") {
|
|
@@ -2941,6 +2957,10 @@ export function applyPlanContentPatches(
|
|
|
2941
2957
|
if (patch.brief !== undefined) next.brief = patch.brief;
|
|
2942
2958
|
continue;
|
|
2943
2959
|
}
|
|
2960
|
+
if (patch.op === "set-visual-render-mode") {
|
|
2961
|
+
pendingVisualRenderMode = patch.renderMode;
|
|
2962
|
+
continue;
|
|
2963
|
+
}
|
|
2944
2964
|
if (patch.op === "set-prototype") {
|
|
2945
2965
|
next.prototype = prototypeSchema.parse(patch.prototype);
|
|
2946
2966
|
continue;
|
|
@@ -3274,6 +3294,9 @@ export function applyPlanContentPatches(
|
|
|
3274
3294
|
}
|
|
3275
3295
|
}
|
|
3276
3296
|
|
|
3297
|
+
if (pendingVisualRenderMode) {
|
|
3298
|
+
setVisualRenderMode(next, pendingVisualRenderMode);
|
|
3299
|
+
}
|
|
3277
3300
|
syncCanvasWireframes(next);
|
|
3278
3301
|
return planContentSchema.parse(next);
|
|
3279
3302
|
}
|
|
@@ -3282,6 +3305,91 @@ function cloneJson<T>(value: T): T {
|
|
|
3282
3305
|
return JSON.parse(JSON.stringify(value)) as T;
|
|
3283
3306
|
}
|
|
3284
3307
|
|
|
3308
|
+
function setVisualRenderMode(
|
|
3309
|
+
content: PlanContent,
|
|
3310
|
+
renderMode: PlanVisualCanvasMode,
|
|
3311
|
+
) {
|
|
3312
|
+
const hasLegacyBlock = (blocks: PlanBlock[]): boolean =>
|
|
3313
|
+
blocks.some((block) => {
|
|
3314
|
+
if (block.type === "legacy-wireframe") return true;
|
|
3315
|
+
if (block.type === "tabs") {
|
|
3316
|
+
return block.data.tabs.some((tab) => hasLegacyBlock(tab.blocks));
|
|
3317
|
+
}
|
|
3318
|
+
if (block.type === "columns") {
|
|
3319
|
+
return block.data.columns.some((column) =>
|
|
3320
|
+
hasLegacyBlock(column.blocks),
|
|
3321
|
+
);
|
|
3322
|
+
}
|
|
3323
|
+
return false;
|
|
3324
|
+
});
|
|
3325
|
+
const hasLegacyFrame = content.canvas?.frames.some(
|
|
3326
|
+
(frame) => frame.legacyWireframe,
|
|
3327
|
+
);
|
|
3328
|
+
if (hasLegacyBlock(content.blocks) || hasLegacyFrame) {
|
|
3329
|
+
throw new Error(
|
|
3330
|
+
"Cannot set visual render mode while the plan contains legacy-wireframe content. Replace legacy-wireframe blocks and canvas legacyWireframe fields with current wireframes in the same update, then set the render mode.",
|
|
3331
|
+
);
|
|
3332
|
+
}
|
|
3333
|
+
|
|
3334
|
+
let changed = false;
|
|
3335
|
+
|
|
3336
|
+
const updateBlock = (block: PlanBlock): PlanBlock => {
|
|
3337
|
+
if (block.type === "wireframe") {
|
|
3338
|
+
changed = true;
|
|
3339
|
+
return { ...block, data: { ...block.data, renderMode } };
|
|
3340
|
+
}
|
|
3341
|
+
if (block.type === "tabs") {
|
|
3342
|
+
return {
|
|
3343
|
+
...block,
|
|
3344
|
+
data: {
|
|
3345
|
+
...block.data,
|
|
3346
|
+
tabs: block.data.tabs.map((tab) => ({
|
|
3347
|
+
...tab,
|
|
3348
|
+
blocks: tab.blocks.map(updateBlock),
|
|
3349
|
+
})),
|
|
3350
|
+
},
|
|
3351
|
+
};
|
|
3352
|
+
}
|
|
3353
|
+
if (block.type === "columns") {
|
|
3354
|
+
return {
|
|
3355
|
+
...block,
|
|
3356
|
+
data: {
|
|
3357
|
+
...block.data,
|
|
3358
|
+
columns: block.data.columns.map((column) => ({
|
|
3359
|
+
...column,
|
|
3360
|
+
blocks: column.blocks.map(updateBlock),
|
|
3361
|
+
})),
|
|
3362
|
+
},
|
|
3363
|
+
};
|
|
3364
|
+
}
|
|
3365
|
+
return block;
|
|
3366
|
+
};
|
|
3367
|
+
|
|
3368
|
+
content.blocks = content.blocks.map(updateBlock);
|
|
3369
|
+
|
|
3370
|
+
if (content.canvas) {
|
|
3371
|
+
content.canvas.mode = renderMode;
|
|
3372
|
+
changed = true;
|
|
3373
|
+
for (const frame of content.canvas.frames) {
|
|
3374
|
+
if (!frame.wireframe) continue;
|
|
3375
|
+
frame.wireframe.renderMode = renderMode;
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
if (content.prototype) {
|
|
3380
|
+
for (const screen of content.prototype.screens) {
|
|
3381
|
+
screen.renderMode = renderMode;
|
|
3382
|
+
changed = true;
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
|
|
3386
|
+
if (!changed) {
|
|
3387
|
+
throw new Error(
|
|
3388
|
+
"Cannot set visual render mode because the plan has no wireframes or prototype screens.",
|
|
3389
|
+
);
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3285
3393
|
function isWireframeBlock(
|
|
3286
3394
|
block: PlanBlock | null | undefined,
|
|
3287
3395
|
): block is PlanWireframeBlock | PlanLegacyWireframeBlock {
|