@agent-native/core 0.69.0 → 0.70.1
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/README.md +15 -15
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +109 -0
- package/corpus/core/docs/design/durable-agent-runs.md +217 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/action.ts +89 -0
- package/corpus/core/src/agent/model-config.ts +0 -2
- package/corpus/core/src/agent/run-loop-with-resume.ts +48 -0
- package/corpus/core/src/changelog/parse.ts +245 -0
- package/corpus/core/src/cli/changelog.ts +199 -0
- package/corpus/core/src/cli/index.ts +19 -0
- package/corpus/core/src/cli/recap.ts +24 -1
- package/corpus/core/src/cli/skills.ts +74 -47
- package/corpus/core/src/client/AgentPanel.tsx +5 -3
- package/corpus/core/src/client/AssistantChat.tsx +8 -0
- package/corpus/core/src/client/CommandMenu.tsx +183 -75
- package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
- package/corpus/core/src/client/analytics.ts +181 -0
- package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
- package/corpus/core/src/client/client-surface.ts +41 -0
- package/corpus/core/src/client/composer/TiptapComposer.tsx +123 -12
- package/corpus/core/src/client/feedback-context.ts +4 -0
- package/corpus/core/src/client/index.ts +12 -0
- package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
- package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
- package/corpus/core/src/client/sse-event-processor.ts +7 -1
- package/corpus/core/src/mcp/build-server.ts +57 -1
- package/corpus/core/src/mcp/embed-app.ts +197 -7
- package/corpus/core/src/mcp/oauth-route.ts +109 -13
- package/corpus/core/src/server/attribution.ts +211 -0
- package/corpus/core/src/server/auth.ts +6 -0
- package/corpus/core/src/server/better-auth-instance.ts +49 -5
- package/corpus/core/src/server/builder-browser.ts +27 -1
- package/corpus/core/src/server/core-routes-plugin.ts +136 -0
- package/corpus/core/src/server/google-oauth.ts +19 -6
- package/corpus/core/src/server/onboarding-html.ts +35 -0
- package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
- package/corpus/core/src/styles/agent-conversation.css +21 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +22 -0
- package/corpus/templates/analytics/AGENTS.md +8 -1
- package/corpus/templates/analytics/CHANGELOG.md +10 -0
- package/corpus/templates/analytics/actions/install-dashboard-template.ts +99 -4
- package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
- package/corpus/templates/analytics/actions/update-dashboard.ts +39 -8
- package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -3
- package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
- package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -3
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -215
- package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -6
- package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
- package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
- package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
- package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -2
- package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
- package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
- package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
- package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
- package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
- package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
- package/corpus/templates/analytics/changelog/2026-06-23-long-dashboard-and-analysis-names-in-the-sidebar-now-truncat.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-23-open-any-dashboard-chart-full-screen-in-a-modal-from-the-pan.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
- package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
- package/corpus/templates/analytics/server/db/index.ts +1 -1
- package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
- package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
- package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
- package/corpus/templates/assets/CHANGELOG.md +10 -0
- package/corpus/templates/assets/actions/generate-image.ts +24 -0
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -2
- package/corpus/templates/assets/app/global.css +17 -1
- package/corpus/templates/assets/app/root.tsx +7 -1
- package/corpus/templates/assets/app/routes/_index.tsx +94 -14
- package/corpus/templates/assets/app/routes/settings.tsx +6 -0
- package/corpus/templates/assets/changelog/2026-06-23-chat-dates-in-the-sidebar-no-longer-wrap-onto-two-lines.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-23-clicking-image-video-or-refine-on-the-start-screen-now-drops.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-23-pick-your-image-generation-model-right-from-the-chat-model-m.md +6 -0
- package/corpus/templates/brain/CHANGELOG.md +10 -0
- package/corpus/templates/brain/app/root.tsx +7 -1
- package/corpus/templates/brain/app/routes/settings.tsx +8 -1
- package/corpus/templates/calendar/CHANGELOG.md +10 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
- package/corpus/templates/calendar/app/root.tsx +7 -1
- package/corpus/templates/chat/CHANGELOG.md +10 -0
- package/corpus/templates/chat/app/root.tsx +7 -1
- package/corpus/templates/clips/CHANGELOG.md +10 -0
- package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -20
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
- package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
- package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
- package/corpus/templates/clips/app/components/recorder/countdown-overlay.tsx +72 -48
- package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +7 -11
- package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +31 -0
- package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
- package/corpus/templates/clips/app/lib/countdown-audio-cue.ts +35 -17
- package/corpus/templates/clips/app/root.tsx +7 -1
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
- package/corpus/templates/clips/app/routes/record.tsx +78 -5
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
- package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-removed-select-button-from-library-hover-a-clip-to-select-it.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-shared-video-links-now-play-for-anyone-without-signing-in.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-skip-or-cancel-the-recording-countdown-with-buttons-beside-t.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-the-desktop-camera-bubble-now-looks-sharp-the-instant-it-ope.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-the-desktop-recording-widget-now-grows-downward-only-when-yo.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-23-the-recording-start-sound-is-now-a-softer-more-modern-chime.md +6 -0
- package/corpus/templates/clips/chrome-extension/public/manifest.json +17 -8
- package/corpus/templates/clips/chrome-extension/src/background.ts +769 -180
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +177 -0
- package/corpus/templates/clips/chrome-extension/src/offscreen.ts +466 -329
- package/corpus/templates/clips/chrome-extension/src/overlay.css +377 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.html +12 -0
- package/corpus/templates/clips/chrome-extension/src/overlay.ts +330 -0
- package/corpus/templates/clips/chrome-extension/src/permission.html +227 -0
- package/corpus/templates/clips/chrome-extension/src/permission.ts +105 -0
- package/corpus/templates/clips/chrome-extension/src/popup.html +3 -0
- package/corpus/templates/clips/chrome-extension/src/popup.ts +50 -2
- package/corpus/templates/clips/chrome-extension/src/styles.css +50 -0
- package/corpus/templates/clips/chrome-extension/vite.config.ts +3 -0
- package/corpus/templates/clips/desktop/src/lib/audio-cue.ts +41 -24
- package/corpus/templates/clips/desktop/src/lib/bubble-webrtc.ts +119 -2
- package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
- package/corpus/templates/clips/desktop/src/main.tsx +3 -0
- package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +21 -2
- package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
- package/corpus/templates/clips/desktop/src/styles.css +119 -2
- package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
- package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +140 -1
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
- package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
- package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +85 -6
- package/corpus/templates/clips/shared/share-attribution.ts +79 -0
- package/corpus/templates/content/AGENTS.md +20 -3
- package/corpus/templates/content/CHANGELOG.md +10 -0
- package/corpus/templates/content/actions/_database-utils.ts +15 -0
- package/corpus/templates/content/actions/_property-utils.ts +371 -4
- package/corpus/templates/content/actions/configure-document-property.ts +35 -1
- package/corpus/templates/content/actions/create-content-database.ts +5 -1
- package/corpus/templates/content/actions/delete-document-property.ts +52 -2
- package/corpus/templates/content/actions/duplicate-document-property.ts +34 -17
- package/corpus/templates/content/actions/reorder-document-property.ts +79 -0
- package/corpus/templates/content/actions/set-document-property.ts +39 -0
- package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +806 -0
- package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +226 -68
- package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +59 -30
- package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +25 -1
- package/corpus/templates/content/app/components/editor/blockFieldSaveController.ts +180 -0
- package/corpus/templates/content/app/components/editor/blockFieldSaveRegistry.ts +179 -0
- package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +244 -0
- package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +132 -0
- package/corpus/templates/content/app/global.css +9 -0
- package/corpus/templates/content/app/hooks/use-document-properties.ts +21 -0
- package/corpus/templates/content/app/root.tsx +7 -1
- package/corpus/templates/content/server/db/schema.ts +30 -0
- package/corpus/templates/content/server/plugins/db.ts +87 -0
- package/corpus/templates/content/shared/api.ts +7 -0
- package/corpus/templates/content/shared/properties.ts +109 -0
- package/corpus/templates/design/CHANGELOG.md +10 -0
- package/corpus/templates/design/actions/generate-design.ts +4 -0
- package/corpus/templates/design/app/root.tsx +7 -1
- package/corpus/templates/design/app/routes/settings.tsx +10 -2
- package/corpus/templates/dispatch/CHANGELOG.md +10 -0
- package/corpus/templates/dispatch/app/root.tsx +7 -1
- package/corpus/templates/forms/.agents/skills/form-responses/SKILL.md +10 -0
- package/corpus/templates/forms/CHANGELOG.md +10 -0
- package/corpus/templates/forms/actions/export-responses.ts +6 -0
- package/corpus/templates/forms/actions/list-responses.ts +2 -0
- package/corpus/templates/forms/actions/response-insights.ts +2 -0
- package/corpus/templates/forms/app/pages/ResponsesPage.tsx +138 -1
- package/corpus/templates/forms/app/root.tsx +7 -1
- package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-the-page-each-submission-came-from-.md +6 -0
- package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-whether-feedback-came-from-the-web-.md +6 -0
- package/corpus/templates/forms/server/db/schema.ts +7 -0
- package/corpus/templates/forms/server/handlers/submissions.ts +19 -2
- package/corpus/templates/forms/server/lib/integrations.ts +76 -2
- package/corpus/templates/forms/server/plugins/db.ts +20 -0
- package/corpus/templates/forms/shared/types.ts +12 -0
- package/corpus/templates/macros/CHANGELOG.md +10 -0
- package/corpus/templates/macros/app/root.tsx +7 -1
- package/corpus/templates/mail/CHANGELOG.md +10 -0
- package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
- package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
- package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
- package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
- package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
- package/corpus/templates/plan/AGENTS.md +4 -0
- package/corpus/templates/plan/CHANGELOG.md +10 -0
- package/corpus/templates/plan/actions/view-screen.ts +5 -0
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
- package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +3 -1
- package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
- package/corpus/templates/plan/app/root.tsx +7 -1
- package/corpus/templates/plan/changelog/2026-06-23-large-diagrams-in-a-plan-now-scroll-within-their-block-inste.md +6 -0
- package/corpus/templates/plan/shared/share-attribution.ts +72 -0
- package/corpus/templates/slides/CHANGELOG.md +10 -0
- package/corpus/templates/slides/app/root.tsx +7 -1
- package/corpus/templates/videos/CHANGELOG.md +4 -151
- package/corpus/templates/videos/app/root.tsx +7 -1
- package/dist/action.js +87 -0
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/builder-engine.d.ts +1 -1
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/model-config.d.ts +2 -2
- package/dist/agent/model-config.d.ts.map +1 -1
- package/dist/agent/model-config.js +0 -2
- package/dist/agent/model-config.js.map +1 -1
- package/dist/agent/run-loop-with-resume.d.ts +13 -0
- package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
- package/dist/agent/run-loop-with-resume.js +44 -0
- package/dist/agent/run-loop-with-resume.js.map +1 -1
- package/dist/changelog/parse.d.ts +70 -0
- package/dist/changelog/parse.d.ts.map +1 -0
- package/dist/changelog/parse.js +200 -0
- package/dist/changelog/parse.js.map +1 -0
- package/dist/cli/changelog.d.ts +4 -0
- package/dist/cli/changelog.d.ts.map +1 -0
- package/dist/cli/changelog.js +166 -0
- package/dist/cli/changelog.js.map +1 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/recap.d.ts.map +1 -1
- package/dist/cli/recap.js +22 -1
- package/dist/cli/recap.js.map +1 -1
- package/dist/cli/skills.d.ts +3 -3
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +74 -47
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +5 -3
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +6 -1
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +2 -2
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/CommandMenu.d.ts +17 -1
- package/dist/client/CommandMenu.d.ts.map +1 -1
- package/dist/client/CommandMenu.js +49 -13
- package/dist/client/CommandMenu.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +43 -6
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts +18 -0
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +177 -0
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/changelog/Changelog.d.ts +47 -0
- package/dist/client/changelog/Changelog.d.ts.map +1 -0
- package/dist/client/changelog/Changelog.js +138 -0
- package/dist/client/changelog/Changelog.js.map +1 -0
- package/dist/client/client-surface.d.ts +17 -0
- package/dist/client/client-surface.d.ts.map +1 -0
- package/dist/client/client-surface.js +24 -0
- package/dist/client/client-surface.js.map +1 -0
- package/dist/client/composer/TiptapComposer.d.ts +26 -1
- package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
- package/dist/client/composer/TiptapComposer.js +27 -5
- package/dist/client/composer/TiptapComposer.js.map +1 -1
- package/dist/client/feedback-context.d.ts +3 -0
- package/dist/client/feedback-context.d.ts.map +1 -1
- package/dist/client/feedback-context.js +2 -0
- package/dist/client/feedback-context.js.map +1 -1
- package/dist/client/index.d.ts +3 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
- package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
- package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +2 -0
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +58 -10
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +7 -1
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/mcp/build-server.d.ts +21 -0
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +43 -1
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.d.ts.map +1 -1
- package/dist/mcp/embed-app.js +197 -7
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +95 -12
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/server/attribution.d.ts +83 -0
- package/dist/server/attribution.d.ts.map +1 -0
- package/dist/server/attribution.js +178 -0
- package/dist/server/attribution.js.map +1 -0
- package/dist/server/auth.d.ts.map +1 -1
- package/dist/server/auth.js +7 -0
- package/dist/server/auth.js.map +1 -1
- package/dist/server/better-auth-instance.d.ts +9 -1
- package/dist/server/better-auth-instance.d.ts.map +1 -1
- package/dist/server/better-auth-instance.js +32 -2
- package/dist/server/better-auth-instance.js.map +1 -1
- package/dist/server/builder-browser.d.ts +4 -0
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +20 -1
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts +25 -0
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +101 -0
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/google-oauth.d.ts.map +1 -1
- package/dist/server/google-oauth.js +16 -2
- package/dist/server/google-oauth.js.map +1 -1
- package/dist/server/onboarding-html.d.ts.map +1 -1
- package/dist/server/onboarding-html.js +35 -0
- package/dist/server/onboarding-html.js.map +1 -1
- package/dist/shared/mcp-embed-headers.js +1 -1
- package/dist/shared/mcp-embed-headers.js.map +1 -1
- package/dist/styles/agent-conversation.css +21 -0
- package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/dist/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
- package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/docs/design/durable-agent-runs.md +217 -0
- package/package.json +1 -1
- package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
- package/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
- package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
- package/corpus/templates/analytics/app/pages/About.tsx +0 -108
- package/corpus/templates/analytics/app/routes/about.tsx +0 -9
- /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
|
@@ -590,12 +590,15 @@ no labels or copy. The renderer drops borders, sketch, and color into the
|
|
|
590
590
|
skeleton register automatically. Never escape to a \`custom-html\` document block
|
|
591
591
|
to fake a loader.
|
|
592
592
|
|
|
593
|
-
**Editing an existing mockup.**
|
|
594
|
-
existing html mockup, call
|
|
595
|
-
|
|
593
|
+
**Editing an existing mockup.** In hosted mode, to change one element, text, or
|
|
594
|
+
color in an existing html mockup, do not regenerate the frame — call
|
|
595
|
+
\`update-visual-plan\` with
|
|
596
|
+
\`contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
|
|
596
597
|
replace }] }]\`. Each \`find\` is a unique snippet of the current html (read it
|
|
597
598
|
first with \`get-visual-plan\`); set \`all: true\` on an edit to replace every
|
|
598
|
-
occurrence. The result is re-sanitized.
|
|
599
|
+
occurrence. The result is re-sanitized. In local-files privacy mode, do not call
|
|
600
|
+
hosted Plan tools; edit the local MDX source directly and rerun the local
|
|
601
|
+
check/serve or verify command for \`<plan-dir>\`.
|
|
599
602
|
|
|
600
603
|
**Treat the wireframe border as part of the visible design.** Always wrap HTML
|
|
601
604
|
wireframe content in a root container with real inner padding before drawing
|
|
@@ -1239,13 +1242,14 @@ surface.
|
|
|
1239
1242
|
approach and options in the plan. Ask a clarifying question only when an
|
|
1240
1243
|
ambiguity would change the design and you cannot resolve it from the code; use
|
|
1241
1244
|
the host agent's normal ask-user-question flow and batch 2-4 high-leverage
|
|
1242
|
-
questions before finalizing. Do not call \`create-visual-questions\`
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1245
|
+
questions before finalizing. Do not call \`create-visual-questions\` for
|
|
1246
|
+
ordinary clarification or preflight; reserve it for the visual-intake mode when
|
|
1247
|
+
the user explicitly asks for a visual intake questionnaire. Otherwise state the
|
|
1248
|
+
assumption explicitly and proceed, and keep anything unresolved in the plan's
|
|
1249
|
+
single bottom \`question-form\` Open Questions block. For complex plans, do a
|
|
1250
|
+
final open-question pass before handoff: if a decision would affect
|
|
1251
|
+
architecture, scope, UX, data shape, or rollout, either decide it in the plan
|
|
1252
|
+
with rationale or put it in that bottom form with a recommended default.
|
|
1249
1253
|
- **The plan is the approval gate.** After surfacing it, ask the user to review
|
|
1250
1254
|
and approve before you write code, and name which files/areas the work touches.
|
|
1251
1255
|
Presenting the plan and requesting sign-off is the approval step — do not ask a
|
|
@@ -1290,6 +1294,11 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
|
|
|
1290
1294
|
|
|
1291
1295
|
## Core Workflow
|
|
1292
1296
|
|
|
1297
|
+
This section describes the default hosted Plan MCP workflow. If
|
|
1298
|
+
\`AGENT_NATIVE_PLANS_MODE=local-files\` is set, or the user asks for fully local
|
|
1299
|
+
files/no hosted Plan writes, use **Local-Files Privacy Mode** instead; carry
|
|
1300
|
+
forward only the code-research and plan-composition guidance here.
|
|
1301
|
+
|
|
1293
1302
|
1. Follow the host agent's normal planning flow: inspect the codebase, delegate
|
|
1294
1303
|
wide exploration when useful, gather the info needed, and ask native
|
|
1295
1304
|
clarifying questions as needed before generating the plan. If a source plan
|
|
@@ -1336,11 +1345,13 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
|
|
|
1336
1345
|
backend, data, multi-file, or risky), also kick off the self-review pass in
|
|
1337
1346
|
**Self-Review Before Handoff** while the user reads, instead of blocking the
|
|
1338
1347
|
handoff on it.
|
|
1339
|
-
5.
|
|
1348
|
+
5. For hosted plans, call \`get-plan-feedback\` before editing, after review,
|
|
1349
|
+
after any long pause,
|
|
1340
1350
|
and before the final response. Treat \`anchorDetails\`, resolver intent, recent
|
|
1341
1351
|
review events, and any focused screenshots from browser handoff as the source
|
|
1342
1352
|
of truth for exactly what changed and exactly what each comment points at.
|
|
1343
|
-
6.
|
|
1353
|
+
6. For hosted plans, apply changes with \`update-visual-plan\`, preferring
|
|
1354
|
+
targeted \`contentPatches\`.
|
|
1344
1355
|
Treat the top-level \`content\` payload as a full replacement, not a merge; do
|
|
1345
1356
|
not send a partial \`content\` object to add a canvas or one block. If a full
|
|
1346
1357
|
replacement is unavoidable, first read the complete plan source/content, carry
|
|
@@ -1348,8 +1359,8 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
|
|
|
1348
1359
|
afterward so the document body was not truncated. When the user wants
|
|
1349
1360
|
source-control friendly edits, use \`patch-visual-plan-source\` against the MDX
|
|
1350
1361
|
files instead of regenerating the plan.
|
|
1351
|
-
7.
|
|
1352
|
-
or repo-check-in artifacts.
|
|
1362
|
+
7. For hosted plans, export with \`export-visual-plan\` only when the user wants a
|
|
1363
|
+
shareable receipt or repo-check-in artifacts.
|
|
1353
1364
|
|
|
1354
1365
|
## Self-Review Before Handoff
|
|
1355
1366
|
|
|
@@ -1545,11 +1556,12 @@ The local-files contract is:
|
|
|
1545
1556
|
wants the artifact checked into the repo, or use a repo-ignored/temporary
|
|
1546
1557
|
folder such as \`.agent-native/plans/<slug>/\` or \`/tmp/agent-native-plans/<slug>/\`
|
|
1547
1558
|
when it should not be checked in. The folder contains \`plan.mdx\`, optional
|
|
1548
|
-
\`canvas.mdx\`, optional \`prototype.mdx\`, and optional \`.plan-state.json\`.
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1559
|
+
\`canvas.mdx\`, optional \`prototype.mdx\`, and optional \`.plan-state.json\`. Use
|
|
1560
|
+
that exact chosen folder as \`<plan-dir>\` in every local CLI command below.
|
|
1561
|
+
- Run \`npx @agent-native/core@latest plan local check --dir <plan-dir>\` before
|
|
1562
|
+
serving, then run
|
|
1563
|
+
\`npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind plan --open\`.
|
|
1564
|
+
Report the returned local bridge URL from stdout or \`<plan-dir>/.plan-url\`.
|
|
1553
1565
|
Treat \`.plan-url\` as a local token file and do not commit it. The URL opens
|
|
1554
1566
|
the hosted Plan UI but reads from the localhost bridge on this machine, so it
|
|
1555
1567
|
is not shareable across machines. On macOS, \`--open\` prefers Chromium browsers;
|
|
@@ -1558,7 +1570,7 @@ The local-files contract is:
|
|
|
1558
1570
|
running locally with the same \`PLAN_LOCAL_DIR\`, the \`/local-plans/<slug>\` route
|
|
1559
1571
|
is also valid.
|
|
1560
1572
|
- For headless verification, run
|
|
1561
|
-
\`npx @agent-native/core@latest plan local verify --dir
|
|
1573
|
+
\`npx @agent-native/core@latest plan local verify --dir <plan-dir> --kind plan\`.
|
|
1562
1574
|
It starts the bridge, checks the private-network preflight and JSON payload,
|
|
1563
1575
|
prints diagnostics, and exits. If the browser hangs on "Loading plan", fetch
|
|
1564
1576
|
the \`bridgeUrl\` from the verify/serve JSON to read the concrete validation
|
|
@@ -1580,6 +1592,11 @@ otherwise approved by the user.
|
|
|
1580
1592
|
|
|
1581
1593
|
## Interpreting comment anchors
|
|
1582
1594
|
|
|
1595
|
+
This section applies to hosted plans with \`get-plan-feedback\` /
|
|
1596
|
+
\`update-visual-plan\`. In local-files mode, do not call hosted feedback or update
|
|
1597
|
+
tools; interpret file/chat feedback directly, edit the MDX files, rerun the
|
|
1598
|
+
local bridge check/serve/verify command, and report the new local URL.
|
|
1599
|
+
|
|
1583
1600
|
\`get-plan-feedback\` returns rich anchors — read them before acting on any comment.
|
|
1584
1601
|
|
|
1585
1602
|
- **Coordinate frames.** \`targetX\`/\`targetY\` are percentages *within* the
|
|
@@ -1703,8 +1720,9 @@ In local-files mode:
|
|
|
1703
1720
|
\`npx @agent-native/core@latest plan blocks --out plan-blocks.md\` when the Plan
|
|
1704
1721
|
MCP connector is not registered; it calls the public no-auth
|
|
1705
1722
|
\`get-plan-blocks\` route and sends no recap content. If network access is
|
|
1706
|
-
unavailable, use the bundled references and validate with
|
|
1707
|
-
\`plan local check
|
|
1723
|
+
unavailable, use the bundled references and validate the MDX with
|
|
1724
|
+
\`plan local check\`; do not run \`plan local serve\` unless the hosted Plan UI is
|
|
1725
|
+
reachable or a local Plan app is already running. For \`checklist\` and \`question-form\`,
|
|
1708
1726
|
copy the catalog examples verbatim: checklist items need \`id\` and \`label\`;
|
|
1709
1727
|
question-form questions need \`id\`, \`title\`, and \`mode\`; and each option needs
|
|
1710
1728
|
\`id\` and \`label\`. \`plan local check\` validates these required fields against
|
|
@@ -1714,21 +1732,24 @@ In local-files mode:
|
|
|
1714
1732
|
folder such as \`.agent-native/plans/<slug>/\` or \`/tmp/agent-native-plans/<slug>/\`
|
|
1715
1733
|
when it should not be checked in. The folder contains \`plan.mdx\`, optional
|
|
1716
1734
|
\`canvas.mdx\`, optional \`prototype.mdx\`, and optional \`.plan-state.json\`. Set
|
|
1717
|
-
\`kind: "recap"\` and \`localOnly: true\` in frontmatter/state when authoring
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1735
|
+
\`kind: "recap"\` and \`localOnly: true\` in frontmatter/state when authoring the
|
|
1736
|
+
source. Use that exact chosen folder as \`<plan-dir>\` in every local CLI command
|
|
1737
|
+
below.
|
|
1738
|
+
- Run \`npx @agent-native/core@latest plan local check --dir <plan-dir>\` before
|
|
1739
|
+
any preview. When the hosted Plan UI is reachable, run
|
|
1740
|
+
\`npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open\`.
|
|
1741
|
+
Report the returned local bridge URL from stdout or \`<plan-dir>/.plan-url\`.
|
|
1723
1742
|
Treat \`.plan-url\` as a local token file and do not commit it. The URL opens
|
|
1724
1743
|
the hosted Plan UI but reads from the localhost bridge on this machine, so it
|
|
1725
1744
|
is not shareable across machines. On macOS, \`--open\` prefers Chromium browsers;
|
|
1726
1745
|
if Safari opens, switch to Chrome/Chromium because Safari can block the hosted
|
|
1727
1746
|
HTTPS page from fetching the HTTP localhost bridge. If the Plan app itself is
|
|
1728
1747
|
running locally with the same \`PLAN_LOCAL_DIR\`, the \`/local-plans/<slug>\` route
|
|
1729
|
-
is also valid.
|
|
1748
|
+
is also valid. In a truly offline environment, hand off the local \`<plan-dir>\`
|
|
1749
|
+
path after \`plan local check\` and note that interactive preview requires either
|
|
1750
|
+
network access to the hosted Plan UI or a running local Plan app.
|
|
1730
1751
|
- For headless verification, run
|
|
1731
|
-
\`npx @agent-native/core@latest plan local verify --dir
|
|
1752
|
+
\`npx @agent-native/core@latest plan local verify --dir <plan-dir> --kind recap\`.
|
|
1732
1753
|
It starts the bridge, checks the private-network preflight and JSON payload,
|
|
1733
1754
|
prints diagnostics, and exits. If the browser hangs on "Loading plan", fetch
|
|
1734
1755
|
the \`bridgeUrl\` from the verify/serve JSON to read the concrete validation
|
|
@@ -1739,7 +1760,9 @@ In local-files mode:
|
|
|
1739
1760
|
\`set-resource-visibility\`, or any hosted Plan tool for that recap except the
|
|
1740
1761
|
schema-only block catalog lookup above.
|
|
1741
1762
|
- Treat review feedback as file or chat feedback: update the MDX files directly,
|
|
1742
|
-
rerun
|
|
1763
|
+
rerun \`plan local check\`, and rerun \`serve\` or \`verify\` only when that preview
|
|
1764
|
+
path is available. Summarize the new local URL when one exists; otherwise
|
|
1765
|
+
summarize the checked local folder path.
|
|
1743
1766
|
Hosted comments, sharing, screenshots, usage attachment, and PR sticky comment
|
|
1744
1767
|
publishing are unavailable until the user explicitly opts into publishing.
|
|
1745
1768
|
|
|
@@ -1955,10 +1978,10 @@ and re-import before reporting the link. A text-match screenshot is not enough;
|
|
|
1955
1978
|
visually inspect the captured image. When no browser is available (for example
|
|
1956
1979
|
a headless CI agent), state that in the recap handoff instead.
|
|
1957
1980
|
|
|
1958
|
-
## Top Canvas Recaps — read \`../visual-
|
|
1981
|
+
## Top Canvas Recaps — read \`../visual-plan/references/canvas.md\`
|
|
1959
1982
|
|
|
1960
1983
|
When a recap includes a top canvas, storyboard, or flow view, READ
|
|
1961
|
-
\`../visual-
|
|
1984
|
+
\`../visual-plan/references/canvas.md\` before authoring \`canvas.mdx\`. Recap
|
|
1962
1985
|
canvas artboards must use the same HTML wireframe path as good document-body
|
|
1963
1986
|
wireframes: \`<Screen surface="..." html={...} />\` with a semantic HTML fragment.
|
|
1964
1987
|
Do not author fresh kit-tree children such as \`<FrameScreen>\`, \`<Card>\`,
|
|
@@ -1972,8 +1995,8 @@ assume it used the legacy kit path and replace it with an HTML screen.
|
|
|
1972
1995
|
|
|
1973
1996
|
In local-files privacy mode, run \`plan local check\` first, then report the local
|
|
1974
1997
|
bridge URL from
|
|
1975
|
-
\`npx @agent-native/core@latest plan local serve --dir
|
|
1976
|
-
or from
|
|
1998
|
+
\`npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open\`
|
|
1999
|
+
or from \`<plan-dir>/.plan-url\`. It opens the hosted Plan UI but reads from the
|
|
1977
2000
|
localhost bridge on this machine, so it is not shareable across machines. If the
|
|
1978
2001
|
Plan app itself is running locally with the same \`PLAN_LOCAL_DIR\`, the
|
|
1979
2002
|
\`/local-plans/<slug>\` route is also valid. Do not invent a hosted database URL
|
|
@@ -2138,7 +2161,8 @@ installed as plain text and no MCP tools are registered after discovery, run
|
|
|
2138
2161
|
\`npx @agent-native/core@latest plan blocks --out plan-blocks.md\` and read that
|
|
2139
2162
|
file first. The CLI command calls the public no-auth \`get-plan-blocks\` route and
|
|
2140
2163
|
sends no plan/recap content. If network access is unavailable, use the bundled
|
|
2141
|
-
references and validate with \`plan local check
|
|
2164
|
+
references and validate with \`plan local check\`; run \`plan local serve\` only
|
|
2165
|
+
when the hosted Plan UI is reachable or a local Plan app is already running.
|
|
2142
2166
|
|
|
2143
2167
|
The catalog returns the authoritative, always-current block vocabulary generated
|
|
2144
2168
|
live from the app's own block registry — the same config the renderer and MDX
|
|
@@ -2246,14 +2270,17 @@ inferred (not extracted) as inferred in prose.
|
|
|
2246
2270
|
|
|
2247
2271
|
## Bidirectional Loop
|
|
2248
2272
|
|
|
2249
|
-
|
|
2250
|
-
applies: a reviewer can annotate any block, and the coding
|
|
2251
|
-
\`get-plan-feedback\` to drive fixes back into the code — annotation →
|
|
2252
|
-
diff, the same close-the-loop flow forward plans use. After a reviewer
|
|
2253
|
-
a block, call \`get-plan-feedback\` to read the structured feedback,
|
|
2254
|
-
update the recap with \`create-visual-recap\` (passing the existing
|
|
2255
|
-
replace it in place) or apply targeted changes with
|
|
2256
|
-
loop is live and wired.
|
|
2273
|
+
In hosted mode, because a recap is a real, editable plan, the same review loop
|
|
2274
|
+
as forward plans applies: a reviewer can annotate any block, and the coding
|
|
2275
|
+
agent reads \`get-plan-feedback\` to drive fixes back into the code — annotation →
|
|
2276
|
+
agent → diff, the same close-the-loop flow forward plans use. After a reviewer
|
|
2277
|
+
annotates a block, call \`get-plan-feedback\` to read the structured feedback,
|
|
2278
|
+
then either update the recap with \`create-visual-recap\` (passing the existing
|
|
2279
|
+
\`planId\` to replace it in place) or apply targeted changes with
|
|
2280
|
+
\`update-visual-plan\`. The loop is live and wired. In local-files privacy mode,
|
|
2281
|
+
do not call those hosted tools; read review notes from chat or local files, edit
|
|
2282
|
+
\`<plan-dir>/*.mdx\` directly, and rerun \`plan local check\`, \`serve\`, or \`verify\`
|
|
2283
|
+
for \`<plan-dir>\`. The one thing not yet automatic is PR-comment-triggered
|
|
2257
2284
|
re-runs: the GitHub Action creates an initial recap per PR, but it does not yet
|
|
2258
2285
|
re-run automatically when new review feedback is posted in GitHub — that
|
|
2259
2286
|
auto-re-run is the remaining fast-follow.
|
|
@@ -4006,8 +4033,8 @@ async function promptForPlanMode(
|
|
|
4006
4033
|
options: [
|
|
4007
4034
|
{
|
|
4008
4035
|
value: "hosted",
|
|
4009
|
-
label: "Hosted plans, shareable links",
|
|
4010
|
-
hint: "
|
|
4036
|
+
label: "Hosted plans, shareable links (recommended)",
|
|
4037
|
+
hint: "100% free and open source. Supports comments, browser editor, and sharing. Requires one-time browser sign-in.",
|
|
4011
4038
|
},
|
|
4012
4039
|
{
|
|
4013
4040
|
value: "local-files",
|
|
@@ -147,9 +147,11 @@ const SetupButton = lazy(() =>
|
|
|
147
147
|
})),
|
|
148
148
|
);
|
|
149
149
|
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
|
|
150
|
+
// The setup/onboarding checklist that used to appear above chat is disabled
|
|
151
|
+
// for every app — setup (AI engine, image/video gen, asset storage, email,
|
|
152
|
+
// GitHub, etc.) is surfaced in better places (the settings panel and the
|
|
153
|
+
// per-feature setup affordances). Keep this off; do not re-enable globally.
|
|
154
|
+
const SHOW_ONBOARDING = false;
|
|
153
155
|
|
|
154
156
|
const CLI_STORAGE_KEY = "agent-native-cli-command";
|
|
155
157
|
const CLI_DEFAULT = "claude";
|
|
@@ -86,6 +86,7 @@ import { agentNativePath } from "./api-path.js";
|
|
|
86
86
|
import {
|
|
87
87
|
TiptapComposer,
|
|
88
88
|
type ComposerSubmitIntent,
|
|
89
|
+
type ComposerImageModelMenu,
|
|
89
90
|
type TiptapComposerHandle,
|
|
90
91
|
} from "./composer/TiptapComposer.js";
|
|
91
92
|
import { AgentComposerFrame } from "./composer/AgentComposerFrame.js";
|
|
@@ -712,6 +713,11 @@ export interface AssistantChatProps {
|
|
|
712
713
|
onModelChange?: (model: string, engine: string) => void;
|
|
713
714
|
/** Callback when user picks a reasoning effort from the picker */
|
|
714
715
|
onEffortChange?: (effort: ReasoningEffort) => void;
|
|
716
|
+
/**
|
|
717
|
+
* Optional secondary model menu (e.g. an image-generation model) shown inside
|
|
718
|
+
* the composer's model picker. Opt-in; chat-only apps omit it.
|
|
719
|
+
*/
|
|
720
|
+
imageModelMenu?: ComposerImageModelMenu;
|
|
715
721
|
/** Callback when user clicks "Fork Chat" in the message actions menu */
|
|
716
722
|
onForkChat?: () => void | boolean | Promise<void | boolean>;
|
|
717
723
|
/** Override Builder/provider connect routing for embedded hosts. */
|
|
@@ -977,6 +983,7 @@ const AssistantChatInner = forwardRef<
|
|
|
977
983
|
availableModels,
|
|
978
984
|
onModelChange,
|
|
979
985
|
onEffortChange,
|
|
986
|
+
imageModelMenu,
|
|
980
987
|
onForkChat,
|
|
981
988
|
onConnectProvider,
|
|
982
989
|
plusMenuMode = "full",
|
|
@@ -3392,6 +3399,7 @@ const AssistantChatInner = forwardRef<
|
|
|
3392
3399
|
availableModels={availableModels}
|
|
3393
3400
|
onModelChange={onModelChange}
|
|
3394
3401
|
onEffortChange={onEffortChange}
|
|
3402
|
+
imageModelMenu={imageModelMenu}
|
|
3395
3403
|
onConnectProvider={onConnectProvider}
|
|
3396
3404
|
toolbarSlot={composerToolbarSlot}
|
|
3397
3405
|
contextItems={composerContextItems}
|
|
@@ -20,6 +20,7 @@ import React, {
|
|
|
20
20
|
useCallback,
|
|
21
21
|
useContext,
|
|
22
22
|
useEffect,
|
|
23
|
+
useMemo,
|
|
23
24
|
useRef,
|
|
24
25
|
useState,
|
|
25
26
|
type ReactNode,
|
|
@@ -29,9 +30,12 @@ import {
|
|
|
29
30
|
IconExternalLink,
|
|
30
31
|
IconSearch,
|
|
31
32
|
IconMessage,
|
|
33
|
+
IconHistory,
|
|
32
34
|
} from "@tabler/icons-react";
|
|
33
35
|
import { sendToAgentChat } from "./agent-chat.js";
|
|
34
36
|
import { cn } from "./utils.js";
|
|
37
|
+
import { ChangelogDialog, useChangelogSeen } from "./changelog/Changelog.js";
|
|
38
|
+
import { parseChangelog } from "../changelog/parse.js";
|
|
35
39
|
|
|
36
40
|
// ─── Context ────────────────────────────────────────────────────────────────
|
|
37
41
|
|
|
@@ -248,6 +252,22 @@ export interface CommandMenuProps {
|
|
|
248
252
|
showAgentFallback?: boolean;
|
|
249
253
|
/** Custom class for the dialog content */
|
|
250
254
|
className?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Raw CHANGELOG.md contents. When provided, the menu shows a built-in
|
|
257
|
+
* "What's new" entry that opens an in-app changelog dialog (with an unseen
|
|
258
|
+
* dot for new releases). Pass your app's own file:
|
|
259
|
+
* import changelog from "../CHANGELOG.md?raw";
|
|
260
|
+
* <CommandMenu ... changelog={changelog} />
|
|
261
|
+
*/
|
|
262
|
+
changelog?: string;
|
|
263
|
+
/** Label for the built-in changelog entry. Default: "What's new". */
|
|
264
|
+
changelogLabel?: string;
|
|
265
|
+
/**
|
|
266
|
+
* Stable key used to remember which release a user has already seen (for the
|
|
267
|
+
* unseen dot). Defaults to the document title's host app; set explicitly when
|
|
268
|
+
* multiple apps share an origin.
|
|
269
|
+
*/
|
|
270
|
+
changelogKey?: string;
|
|
251
271
|
}
|
|
252
272
|
|
|
253
273
|
export function CommandMenu({
|
|
@@ -258,12 +278,36 @@ export function CommandMenu({
|
|
|
258
278
|
emptyText: _emptyText = "No commands found.",
|
|
259
279
|
showAgentFallback = true,
|
|
260
280
|
className,
|
|
281
|
+
changelog,
|
|
282
|
+
changelogLabel = "What's new",
|
|
283
|
+
changelogKey,
|
|
261
284
|
}: CommandMenuProps) {
|
|
262
285
|
const [search, setSearch] = useState("");
|
|
263
286
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
264
287
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
265
288
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
266
289
|
|
|
290
|
+
// Built-in "What's new" changelog surface (only active when `changelog` is
|
|
291
|
+
// passed). The dialog is rendered alongside the menu so it survives the menu
|
|
292
|
+
// closing; the unseen dot persists per browser via localStorage.
|
|
293
|
+
const [changelogOpen, setChangelogOpen] = useState(false);
|
|
294
|
+
const hasChangelog =
|
|
295
|
+
typeof changelog === "string" && changelog.trim().length > 0;
|
|
296
|
+
const changelogEntries = useMemo(
|
|
297
|
+
() => (hasChangelog ? parseChangelog(changelog as string) : []),
|
|
298
|
+
[hasChangelog, changelog],
|
|
299
|
+
);
|
|
300
|
+
const latestChangelogId = changelogEntries[0]?.id;
|
|
301
|
+
const { unseen: changelogUnseen, markSeen: markChangelogSeen } =
|
|
302
|
+
useChangelogSeen(changelogKey ?? "app", latestChangelogId);
|
|
303
|
+
|
|
304
|
+
const openChangelog = useCallback(() => {
|
|
305
|
+
onOpenChange(false);
|
|
306
|
+
markChangelogSeen();
|
|
307
|
+
// Let the menu close before the dialog opens (avoids overlay flicker).
|
|
308
|
+
setTimeout(() => setChangelogOpen(true), 50);
|
|
309
|
+
}, [onOpenChange, markChangelogSeen]);
|
|
310
|
+
|
|
267
311
|
// Focus input when opening
|
|
268
312
|
useEffect(() => {
|
|
269
313
|
if (open) {
|
|
@@ -361,7 +405,22 @@ export function CommandMenu({
|
|
|
361
405
|
}
|
|
362
406
|
};
|
|
363
407
|
|
|
364
|
-
|
|
408
|
+
// The built-in "What's new" row matches changelog-ish search terms.
|
|
409
|
+
const changelogRowMatches =
|
|
410
|
+
!search ||
|
|
411
|
+
[
|
|
412
|
+
changelogLabel,
|
|
413
|
+
"changelog",
|
|
414
|
+
"what's new",
|
|
415
|
+
"whats new",
|
|
416
|
+
"updates",
|
|
417
|
+
"release notes",
|
|
418
|
+
"changes",
|
|
419
|
+
]
|
|
420
|
+
.join(" ")
|
|
421
|
+
.toLowerCase()
|
|
422
|
+
.includes(search.toLowerCase());
|
|
423
|
+
const showChangelogRow = hasChangelog && changelogRowMatches;
|
|
365
424
|
|
|
366
425
|
// Filter children based on search
|
|
367
426
|
const filterChildren = (nodes: ReactNode): ReactNode => {
|
|
@@ -423,82 +482,131 @@ export function CommandMenu({
|
|
|
423
482
|
);
|
|
424
483
|
|
|
425
484
|
return (
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
<CommandMenuContext.Provider
|
|
436
|
-
value={{ search, onOpenChange, containerRef, setSelectedIndex }}
|
|
437
|
-
>
|
|
438
|
-
{/* Search input */}
|
|
439
|
-
<div className="flex items-center border-b px-3">
|
|
440
|
-
<IconSearch className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
|
441
|
-
<input
|
|
442
|
-
ref={inputRef}
|
|
443
|
-
value={search}
|
|
444
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
445
|
-
onKeyDown={handleKeyDown}
|
|
446
|
-
placeholder={placeholder}
|
|
447
|
-
className="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
448
|
-
/>
|
|
449
|
-
</div>
|
|
450
|
-
|
|
451
|
-
{/* Command list */}
|
|
452
|
-
<div className="max-h-[300px] overflow-y-auto overflow-x-hidden">
|
|
453
|
-
{hasResults && filteredChildren}
|
|
454
|
-
|
|
455
|
-
{/* Ask AI — always visible at the bottom */}
|
|
456
|
-
{showAgentFallback && (
|
|
457
|
-
<>
|
|
458
|
-
{hasResults && <CommandSeparator />}
|
|
459
|
-
<div className="p-1">
|
|
460
|
-
<div
|
|
461
|
-
className="relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none"
|
|
462
|
-
onClick={handleSubmitToAgent}
|
|
463
|
-
onMouseEnter={(e) => {
|
|
464
|
-
const items =
|
|
465
|
-
containerRef.current?.querySelectorAll(
|
|
466
|
-
'[role="option"]',
|
|
467
|
-
);
|
|
468
|
-
if (!items) return;
|
|
469
|
-
const index = Array.from(items).indexOf(e.currentTarget);
|
|
470
|
-
if (index >= 0) setSelectedIndex(index);
|
|
471
|
-
}}
|
|
472
|
-
role="option"
|
|
473
|
-
>
|
|
474
|
-
<IconMessage className="h-4 w-4 text-muted-foreground" />
|
|
475
|
-
<span>
|
|
476
|
-
{search.trim() ? (
|
|
477
|
-
<>
|
|
478
|
-
Ask AI:{" "}
|
|
479
|
-
<span className="text-muted-foreground">
|
|
480
|
-
"{search}"
|
|
481
|
-
</span>
|
|
482
|
-
</>
|
|
483
|
-
) : (
|
|
484
|
-
<span className="text-muted-foreground">
|
|
485
|
-
Ask AI anything...
|
|
486
|
-
</span>
|
|
487
|
-
)}
|
|
488
|
-
</span>
|
|
489
|
-
{search.trim() && (
|
|
490
|
-
<span className="ml-auto text-xs text-muted-foreground">
|
|
491
|
-
↵
|
|
492
|
-
</span>
|
|
493
|
-
)}
|
|
494
|
-
</div>
|
|
495
|
-
</div>
|
|
496
|
-
</>
|
|
485
|
+
<>
|
|
486
|
+
{open && (
|
|
487
|
+
<div className="fixed inset-0 z-50 bg-black/50">
|
|
488
|
+
<div
|
|
489
|
+
ref={containerRef}
|
|
490
|
+
className={cn(
|
|
491
|
+
"fixed left-1/2 top-[15vh] -translate-x-1/2 w-full max-w-lg",
|
|
492
|
+
"rounded-lg border border-border bg-popover text-popover-foreground shadow-lg",
|
|
493
|
+
className,
|
|
497
494
|
)}
|
|
495
|
+
>
|
|
496
|
+
<CommandMenuContext.Provider
|
|
497
|
+
value={{ search, onOpenChange, containerRef, setSelectedIndex }}
|
|
498
|
+
>
|
|
499
|
+
{/* Search input */}
|
|
500
|
+
<div className="flex items-center border-b px-3">
|
|
501
|
+
<IconSearch className="mr-2 h-4 w-4 shrink-0 opacity-50" />
|
|
502
|
+
<input
|
|
503
|
+
ref={inputRef}
|
|
504
|
+
value={search}
|
|
505
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
506
|
+
onKeyDown={handleKeyDown}
|
|
507
|
+
placeholder={placeholder}
|
|
508
|
+
className="flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50"
|
|
509
|
+
/>
|
|
510
|
+
</div>
|
|
511
|
+
|
|
512
|
+
{/* Command list */}
|
|
513
|
+
<div className="max-h-[300px] overflow-y-auto overflow-x-hidden">
|
|
514
|
+
{hasResults && filteredChildren}
|
|
515
|
+
|
|
516
|
+
{/* What's new — built-in changelog entry */}
|
|
517
|
+
{showChangelogRow && (
|
|
518
|
+
<>
|
|
519
|
+
{hasResults && <CommandSeparator />}
|
|
520
|
+
<div className="p-1">
|
|
521
|
+
<div
|
|
522
|
+
className="relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none"
|
|
523
|
+
onClick={openChangelog}
|
|
524
|
+
onMouseEnter={(e) => {
|
|
525
|
+
const items =
|
|
526
|
+
containerRef.current?.querySelectorAll(
|
|
527
|
+
'[role="option"]',
|
|
528
|
+
);
|
|
529
|
+
if (!items) return;
|
|
530
|
+
const index = Array.from(items).indexOf(
|
|
531
|
+
e.currentTarget,
|
|
532
|
+
);
|
|
533
|
+
if (index >= 0) setSelectedIndex(index);
|
|
534
|
+
}}
|
|
535
|
+
role="option"
|
|
536
|
+
>
|
|
537
|
+
<IconHistory className="h-4 w-4 text-muted-foreground" />
|
|
538
|
+
<span>{changelogLabel}</span>
|
|
539
|
+
{changelogUnseen && (
|
|
540
|
+
<span
|
|
541
|
+
className="ml-auto h-2 w-2 rounded-full bg-primary"
|
|
542
|
+
aria-label="New updates available"
|
|
543
|
+
/>
|
|
544
|
+
)}
|
|
545
|
+
</div>
|
|
546
|
+
</div>
|
|
547
|
+
</>
|
|
548
|
+
)}
|
|
549
|
+
|
|
550
|
+
{/* Ask AI — always visible at the bottom */}
|
|
551
|
+
{showAgentFallback && (
|
|
552
|
+
<>
|
|
553
|
+
{(hasResults || showChangelogRow) && <CommandSeparator />}
|
|
554
|
+
<div className="p-1">
|
|
555
|
+
<div
|
|
556
|
+
className="relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-2 text-sm outline-none"
|
|
557
|
+
onClick={handleSubmitToAgent}
|
|
558
|
+
onMouseEnter={(e) => {
|
|
559
|
+
const items =
|
|
560
|
+
containerRef.current?.querySelectorAll(
|
|
561
|
+
'[role="option"]',
|
|
562
|
+
);
|
|
563
|
+
if (!items) return;
|
|
564
|
+
const index = Array.from(items).indexOf(
|
|
565
|
+
e.currentTarget,
|
|
566
|
+
);
|
|
567
|
+
if (index >= 0) setSelectedIndex(index);
|
|
568
|
+
}}
|
|
569
|
+
role="option"
|
|
570
|
+
>
|
|
571
|
+
<IconMessage className="h-4 w-4 text-muted-foreground" />
|
|
572
|
+
<span>
|
|
573
|
+
{search.trim() ? (
|
|
574
|
+
<>
|
|
575
|
+
Ask AI:{" "}
|
|
576
|
+
<span className="text-muted-foreground">
|
|
577
|
+
"{search}"
|
|
578
|
+
</span>
|
|
579
|
+
</>
|
|
580
|
+
) : (
|
|
581
|
+
<span className="text-muted-foreground">
|
|
582
|
+
Ask AI anything...
|
|
583
|
+
</span>
|
|
584
|
+
)}
|
|
585
|
+
</span>
|
|
586
|
+
{search.trim() && (
|
|
587
|
+
<span className="ml-auto text-xs text-muted-foreground">
|
|
588
|
+
↵
|
|
589
|
+
</span>
|
|
590
|
+
)}
|
|
591
|
+
</div>
|
|
592
|
+
</div>
|
|
593
|
+
</>
|
|
594
|
+
)}
|
|
595
|
+
</div>
|
|
596
|
+
</CommandMenuContext.Provider>
|
|
498
597
|
</div>
|
|
499
|
-
</
|
|
500
|
-
|
|
501
|
-
|
|
598
|
+
</div>
|
|
599
|
+
)}
|
|
600
|
+
|
|
601
|
+
{hasChangelog && (
|
|
602
|
+
<ChangelogDialog
|
|
603
|
+
open={changelogOpen}
|
|
604
|
+
onOpenChange={setChangelogOpen}
|
|
605
|
+
markdown={changelog as string}
|
|
606
|
+
title={changelogLabel}
|
|
607
|
+
/>
|
|
608
|
+
)}
|
|
609
|
+
</>
|
|
502
610
|
);
|
|
503
611
|
}
|
|
504
612
|
|