@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.
Files changed (336) hide show
  1. package/README.md +15 -15
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +109 -0
  4. package/corpus/core/docs/design/durable-agent-runs.md +217 -0
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/action.ts +89 -0
  7. package/corpus/core/src/agent/model-config.ts +0 -2
  8. package/corpus/core/src/agent/run-loop-with-resume.ts +48 -0
  9. package/corpus/core/src/changelog/parse.ts +245 -0
  10. package/corpus/core/src/cli/changelog.ts +199 -0
  11. package/corpus/core/src/cli/index.ts +19 -0
  12. package/corpus/core/src/cli/recap.ts +24 -1
  13. package/corpus/core/src/cli/skills.ts +74 -47
  14. package/corpus/core/src/client/AgentPanel.tsx +5 -3
  15. package/corpus/core/src/client/AssistantChat.tsx +8 -0
  16. package/corpus/core/src/client/CommandMenu.tsx +183 -75
  17. package/corpus/core/src/client/agent-chat-adapter.ts +44 -7
  18. package/corpus/core/src/client/analytics.ts +181 -0
  19. package/corpus/core/src/client/changelog/Changelog.tsx +321 -0
  20. package/corpus/core/src/client/client-surface.ts +41 -0
  21. package/corpus/core/src/client/composer/TiptapComposer.tsx +123 -12
  22. package/corpus/core/src/client/feedback-context.ts +4 -0
  23. package/corpus/core/src/client/index.ts +12 -0
  24. package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +54 -0
  25. package/corpus/core/src/client/settings/useBuilderStatus.ts +82 -20
  26. package/corpus/core/src/client/sse-event-processor.ts +7 -1
  27. package/corpus/core/src/mcp/build-server.ts +57 -1
  28. package/corpus/core/src/mcp/embed-app.ts +197 -7
  29. package/corpus/core/src/mcp/oauth-route.ts +109 -13
  30. package/corpus/core/src/server/attribution.ts +211 -0
  31. package/corpus/core/src/server/auth.ts +6 -0
  32. package/corpus/core/src/server/better-auth-instance.ts +49 -5
  33. package/corpus/core/src/server/builder-browser.ts +27 -1
  34. package/corpus/core/src/server/core-routes-plugin.ts +136 -0
  35. package/corpus/core/src/server/google-oauth.ts +19 -6
  36. package/corpus/core/src/server/onboarding-html.ts +35 -0
  37. package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
  38. package/corpus/core/src/styles/agent-conversation.css +21 -0
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  40. package/corpus/core/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  41. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  42. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +22 -0
  43. package/corpus/templates/analytics/AGENTS.md +8 -1
  44. package/corpus/templates/analytics/CHANGELOG.md +10 -0
  45. package/corpus/templates/analytics/actions/install-dashboard-template.ts +99 -4
  46. package/corpus/templates/analytics/actions/open-traffic-dashboard.ts +1 -1
  47. package/corpus/templates/analytics/actions/update-dashboard.ts +39 -8
  48. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -3
  49. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +180 -144
  50. package/corpus/templates/analytics/app/components/layout/Header.tsx +2 -3
  51. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
  52. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +221 -215
  53. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +6 -6
  54. package/corpus/templates/analytics/app/lib/demo-dashboard-path.ts +1 -1
  55. package/corpus/templates/analytics/app/lib/last-opened.ts +2 -1
  56. package/corpus/templates/analytics/app/pages/Settings.tsx +4 -0
  57. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +3 -3
  58. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +2 -2
  59. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +32 -2
  60. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +101 -99
  61. package/corpus/templates/analytics/app/pages/overview/OverviewPage.tsx +1 -1
  62. package/corpus/templates/analytics/app/routes/adhoc.$id.tsx +18 -5
  63. package/corpus/templates/analytics/app/routes/catalog.tsx +1 -1
  64. package/corpus/templates/analytics/app/routes/dashboards.$id.tsx +9 -0
  65. package/corpus/templates/analytics/app/routes/traffic.tsx +1 -1
  66. package/corpus/templates/analytics/changelog/2026-06-23-long-dashboard-and-analysis-names-in-the-sidebar-now-truncat.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-06-23-open-any-dashboard-chart-full-screen-in-a-modal-from-the-pan.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-06-23-the-dashboards-and-analyses-sidebar-settings-buttons-now-sta.md +6 -0
  69. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +145 -0
  70. package/corpus/templates/analytics/server/db/index.ts +1 -1
  71. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +9 -2
  72. package/corpus/templates/analytics/server/lib/demo-dashboards.ts +1 -1
  73. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -2
  74. package/corpus/templates/analytics/server/plugins/core-routes.ts +6 -6
  75. package/corpus/templates/assets/CHANGELOG.md +10 -0
  76. package/corpus/templates/assets/actions/generate-image.ts +24 -0
  77. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -2
  78. package/corpus/templates/assets/app/global.css +17 -1
  79. package/corpus/templates/assets/app/root.tsx +7 -1
  80. package/corpus/templates/assets/app/routes/_index.tsx +94 -14
  81. package/corpus/templates/assets/app/routes/settings.tsx +6 -0
  82. package/corpus/templates/assets/changelog/2026-06-23-chat-dates-in-the-sidebar-no-longer-wrap-onto-two-lines.md +6 -0
  83. package/corpus/templates/assets/changelog/2026-06-23-clicking-image-video-or-refine-on-the-start-screen-now-drops.md +6 -0
  84. package/corpus/templates/assets/changelog/2026-06-23-pick-your-image-generation-model-right-from-the-chat-model-m.md +6 -0
  85. package/corpus/templates/brain/CHANGELOG.md +10 -0
  86. package/corpus/templates/brain/app/root.tsx +7 -1
  87. package/corpus/templates/brain/app/routes/settings.tsx +8 -1
  88. package/corpus/templates/calendar/CHANGELOG.md +10 -0
  89. package/corpus/templates/calendar/app/pages/Settings.tsx +4 -0
  90. package/corpus/templates/calendar/app/root.tsx +7 -1
  91. package/corpus/templates/chat/CHANGELOG.md +10 -0
  92. package/corpus/templates/chat/app/root.tsx +7 -1
  93. package/corpus/templates/clips/CHANGELOG.md +10 -0
  94. package/corpus/templates/clips/app/components/library/library-grid.tsx +1 -20
  95. package/corpus/templates/clips/app/components/player/share-dialog.tsx +33 -7
  96. package/corpus/templates/clips/app/components/player/sign-in-prompt-dialog.tsx +8 -0
  97. package/corpus/templates/clips/app/components/player/video-player.tsx +150 -20
  98. package/corpus/templates/clips/app/components/recorder/countdown-overlay.tsx +72 -48
  99. package/corpus/templates/clips/app/components/recorder/pre-record-panel.tsx +7 -11
  100. package/corpus/templates/clips/app/components/recorder/recorder-engine.ts +31 -0
  101. package/corpus/templates/clips/app/components/sharing/slack-share-hint.tsx +71 -0
  102. package/corpus/templates/clips/app/lib/countdown-audio-cue.ts +35 -17
  103. package/corpus/templates/clips/app/root.tsx +7 -1
  104. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +15 -1
  105. package/corpus/templates/clips/app/routes/record.tsx +78 -5
  106. package/corpus/templates/clips/app/routes/share.$shareId.tsx +86 -5
  107. package/corpus/templates/clips/changelog/2026-06-23-clips-shared-in-slack-no-longer-show-a-could-not-start-playb.md +6 -0
  108. package/corpus/templates/clips/changelog/2026-06-23-made-the-play-button-on-shared-and-embedded-clips-scale-with.md +6 -0
  109. package/corpus/templates/clips/changelog/2026-06-23-public-clip-share-links-now-show-whether-they-ll-play-inline.md +6 -0
  110. package/corpus/templates/clips/changelog/2026-06-23-removed-select-button-from-library-hover-a-clip-to-select-it.md +6 -0
  111. package/corpus/templates/clips/changelog/2026-06-23-screen-camera-recordings-now-keep-the-presenter-s-face-in-th.md +6 -0
  112. package/corpus/templates/clips/changelog/2026-06-23-shared-video-links-now-play-for-anyone-without-signing-in.md +6 -0
  113. package/corpus/templates/clips/changelog/2026-06-23-skip-or-cancel-the-recording-countdown-with-buttons-beside-t.md +6 -0
  114. package/corpus/templates/clips/changelog/2026-06-23-the-desktop-camera-bubble-now-looks-sharp-the-instant-it-ope.md +6 -0
  115. package/corpus/templates/clips/changelog/2026-06-23-the-desktop-recording-widget-now-grows-downward-only-when-yo.md +6 -0
  116. package/corpus/templates/clips/changelog/2026-06-23-the-recording-start-sound-is-now-a-softer-more-modern-chime.md +6 -0
  117. package/corpus/templates/clips/chrome-extension/public/manifest.json +17 -8
  118. package/corpus/templates/clips/chrome-extension/src/background.ts +769 -180
  119. package/corpus/templates/clips/chrome-extension/src/content-script.ts +177 -0
  120. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +466 -329
  121. package/corpus/templates/clips/chrome-extension/src/overlay.css +377 -0
  122. package/corpus/templates/clips/chrome-extension/src/overlay.html +12 -0
  123. package/corpus/templates/clips/chrome-extension/src/overlay.ts +330 -0
  124. package/corpus/templates/clips/chrome-extension/src/permission.html +227 -0
  125. package/corpus/templates/clips/chrome-extension/src/permission.ts +105 -0
  126. package/corpus/templates/clips/chrome-extension/src/popup.html +3 -0
  127. package/corpus/templates/clips/chrome-extension/src/popup.ts +50 -2
  128. package/corpus/templates/clips/chrome-extension/src/styles.css +50 -0
  129. package/corpus/templates/clips/chrome-extension/vite.config.ts +3 -0
  130. package/corpus/templates/clips/desktop/src/lib/audio-cue.ts +41 -24
  131. package/corpus/templates/clips/desktop/src/lib/bubble-webrtc.ts +119 -2
  132. package/corpus/templates/clips/desktop/src/lib/recorder.ts +20 -0
  133. package/corpus/templates/clips/desktop/src/main.tsx +3 -0
  134. package/corpus/templates/clips/desktop/src/overlays/countdown.tsx +21 -2
  135. package/corpus/templates/clips/desktop/src/overlays/region-record-border.tsx +76 -0
  136. package/corpus/templates/clips/desktop/src/styles.css +119 -2
  137. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +2 -1
  138. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +140 -1
  139. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +2 -0
  140. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +4 -1
  141. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +85 -6
  142. package/corpus/templates/clips/shared/share-attribution.ts +79 -0
  143. package/corpus/templates/content/AGENTS.md +20 -3
  144. package/corpus/templates/content/CHANGELOG.md +10 -0
  145. package/corpus/templates/content/actions/_database-utils.ts +15 -0
  146. package/corpus/templates/content/actions/_property-utils.ts +371 -4
  147. package/corpus/templates/content/actions/configure-document-property.ts +35 -1
  148. package/corpus/templates/content/actions/create-content-database.ts +5 -1
  149. package/corpus/templates/content/actions/delete-document-property.ts +52 -2
  150. package/corpus/templates/content/actions/duplicate-document-property.ts +34 -17
  151. package/corpus/templates/content/actions/reorder-document-property.ts +79 -0
  152. package/corpus/templates/content/actions/set-document-property.ts +39 -0
  153. package/corpus/templates/content/app/components/editor/DocumentBlockFields.tsx +806 -0
  154. package/corpus/templates/content/app/components/editor/DocumentDatabase.tsx +226 -68
  155. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +59 -30
  156. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +25 -1
  157. package/corpus/templates/content/app/components/editor/blockFieldSaveController.ts +180 -0
  158. package/corpus/templates/content/app/components/editor/blockFieldSaveRegistry.ts +179 -0
  159. package/corpus/templates/content/app/components/editor/previewDocumentSaveController.ts +244 -0
  160. package/corpus/templates/content/app/components/editor/previewDocumentSaveRegistry.ts +132 -0
  161. package/corpus/templates/content/app/global.css +9 -0
  162. package/corpus/templates/content/app/hooks/use-document-properties.ts +21 -0
  163. package/corpus/templates/content/app/root.tsx +7 -1
  164. package/corpus/templates/content/server/db/schema.ts +30 -0
  165. package/corpus/templates/content/server/plugins/db.ts +87 -0
  166. package/corpus/templates/content/shared/api.ts +7 -0
  167. package/corpus/templates/content/shared/properties.ts +109 -0
  168. package/corpus/templates/design/CHANGELOG.md +10 -0
  169. package/corpus/templates/design/actions/generate-design.ts +4 -0
  170. package/corpus/templates/design/app/root.tsx +7 -1
  171. package/corpus/templates/design/app/routes/settings.tsx +10 -2
  172. package/corpus/templates/dispatch/CHANGELOG.md +10 -0
  173. package/corpus/templates/dispatch/app/root.tsx +7 -1
  174. package/corpus/templates/forms/.agents/skills/form-responses/SKILL.md +10 -0
  175. package/corpus/templates/forms/CHANGELOG.md +10 -0
  176. package/corpus/templates/forms/actions/export-responses.ts +6 -0
  177. package/corpus/templates/forms/actions/list-responses.ts +2 -0
  178. package/corpus/templates/forms/actions/response-insights.ts +2 -0
  179. package/corpus/templates/forms/app/pages/ResponsesPage.tsx +138 -1
  180. package/corpus/templates/forms/app/root.tsx +7 -1
  181. package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-the-page-each-submission-came-from-.md +6 -0
  182. package/corpus/templates/forms/changelog/2026-06-23-response-tables-now-show-whether-feedback-came-from-the-web-.md +6 -0
  183. package/corpus/templates/forms/server/db/schema.ts +7 -0
  184. package/corpus/templates/forms/server/handlers/submissions.ts +19 -2
  185. package/corpus/templates/forms/server/lib/integrations.ts +76 -2
  186. package/corpus/templates/forms/server/plugins/db.ts +20 -0
  187. package/corpus/templates/forms/shared/types.ts +12 -0
  188. package/corpus/templates/macros/CHANGELOG.md +10 -0
  189. package/corpus/templates/macros/app/root.tsx +7 -1
  190. package/corpus/templates/mail/CHANGELOG.md +10 -0
  191. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +3 -0
  192. package/corpus/templates/mail/app/pages/SettingsPage.tsx +27 -0
  193. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +31 -17
  194. package/corpus/templates/plan/.agents/skills/visual-plan/references/wireframe.md +7 -4
  195. package/corpus/templates/plan/.agents/skills/visual-recap/SKILL.md +34 -24
  196. package/corpus/templates/plan/.agents/skills/visual-recap/references/wireframe.md +7 -4
  197. package/corpus/templates/plan/AGENTS.md +4 -0
  198. package/corpus/templates/plan/CHANGELOG.md +10 -0
  199. package/corpus/templates/plan/actions/view-screen.ts +5 -0
  200. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +98 -1
  201. package/corpus/templates/plan/app/components/plan/wireframe/html-artboard.css +3 -1
  202. package/corpus/templates/plan/app/pages/PlansPage.tsx +107 -7
  203. package/corpus/templates/plan/app/root.tsx +7 -1
  204. package/corpus/templates/plan/changelog/2026-06-23-large-diagrams-in-a-plan-now-scroll-within-their-block-inste.md +6 -0
  205. package/corpus/templates/plan/shared/share-attribution.ts +72 -0
  206. package/corpus/templates/slides/CHANGELOG.md +10 -0
  207. package/corpus/templates/slides/app/root.tsx +7 -1
  208. package/corpus/templates/videos/CHANGELOG.md +4 -151
  209. package/corpus/templates/videos/app/root.tsx +7 -1
  210. package/dist/action.js +87 -0
  211. package/dist/action.js.map +1 -1
  212. package/dist/agent/engine/builder-engine.d.ts +1 -1
  213. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  214. package/dist/agent/model-config.d.ts +2 -2
  215. package/dist/agent/model-config.d.ts.map +1 -1
  216. package/dist/agent/model-config.js +0 -2
  217. package/dist/agent/model-config.js.map +1 -1
  218. package/dist/agent/run-loop-with-resume.d.ts +13 -0
  219. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  220. package/dist/agent/run-loop-with-resume.js +44 -0
  221. package/dist/agent/run-loop-with-resume.js.map +1 -1
  222. package/dist/changelog/parse.d.ts +70 -0
  223. package/dist/changelog/parse.d.ts.map +1 -0
  224. package/dist/changelog/parse.js +200 -0
  225. package/dist/changelog/parse.js.map +1 -0
  226. package/dist/cli/changelog.d.ts +4 -0
  227. package/dist/cli/changelog.d.ts.map +1 -0
  228. package/dist/cli/changelog.js +166 -0
  229. package/dist/cli/changelog.js.map +1 -0
  230. package/dist/cli/index.js +18 -0
  231. package/dist/cli/index.js.map +1 -1
  232. package/dist/cli/recap.d.ts.map +1 -1
  233. package/dist/cli/recap.js +22 -1
  234. package/dist/cli/recap.js.map +1 -1
  235. package/dist/cli/skills.d.ts +3 -3
  236. package/dist/cli/skills.d.ts.map +1 -1
  237. package/dist/cli/skills.js +74 -47
  238. package/dist/cli/skills.js.map +1 -1
  239. package/dist/client/AgentPanel.d.ts.map +1 -1
  240. package/dist/client/AgentPanel.js +5 -3
  241. package/dist/client/AgentPanel.js.map +1 -1
  242. package/dist/client/AssistantChat.d.ts +6 -1
  243. package/dist/client/AssistantChat.d.ts.map +1 -1
  244. package/dist/client/AssistantChat.js +2 -2
  245. package/dist/client/AssistantChat.js.map +1 -1
  246. package/dist/client/CommandMenu.d.ts +17 -1
  247. package/dist/client/CommandMenu.d.ts.map +1 -1
  248. package/dist/client/CommandMenu.js +49 -13
  249. package/dist/client/CommandMenu.js.map +1 -1
  250. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  251. package/dist/client/agent-chat-adapter.js +43 -6
  252. package/dist/client/agent-chat-adapter.js.map +1 -1
  253. package/dist/client/analytics.d.ts +18 -0
  254. package/dist/client/analytics.d.ts.map +1 -1
  255. package/dist/client/analytics.js +177 -0
  256. package/dist/client/analytics.js.map +1 -1
  257. package/dist/client/changelog/Changelog.d.ts +47 -0
  258. package/dist/client/changelog/Changelog.d.ts.map +1 -0
  259. package/dist/client/changelog/Changelog.js +138 -0
  260. package/dist/client/changelog/Changelog.js.map +1 -0
  261. package/dist/client/client-surface.d.ts +17 -0
  262. package/dist/client/client-surface.d.ts.map +1 -0
  263. package/dist/client/client-surface.js +24 -0
  264. package/dist/client/client-surface.js.map +1 -0
  265. package/dist/client/composer/TiptapComposer.d.ts +26 -1
  266. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  267. package/dist/client/composer/TiptapComposer.js +27 -5
  268. package/dist/client/composer/TiptapComposer.js.map +1 -1
  269. package/dist/client/feedback-context.d.ts +3 -0
  270. package/dist/client/feedback-context.d.ts.map +1 -1
  271. package/dist/client/feedback-context.js +2 -0
  272. package/dist/client/feedback-context.js.map +1 -1
  273. package/dist/client/index.d.ts +3 -1
  274. package/dist/client/index.d.ts.map +1 -1
  275. package/dist/client/index.js +3 -1
  276. package/dist/client/index.js.map +1 -1
  277. package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
  278. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  279. package/dist/client/mcp-apps/McpAppRenderer.js +42 -1
  280. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  281. package/dist/client/settings/useBuilderStatus.d.ts +2 -0
  282. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  283. package/dist/client/settings/useBuilderStatus.js +58 -10
  284. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  285. package/dist/client/sse-event-processor.d.ts.map +1 -1
  286. package/dist/client/sse-event-processor.js +7 -1
  287. package/dist/client/sse-event-processor.js.map +1 -1
  288. package/dist/mcp/build-server.d.ts +21 -0
  289. package/dist/mcp/build-server.d.ts.map +1 -1
  290. package/dist/mcp/build-server.js +43 -1
  291. package/dist/mcp/build-server.js.map +1 -1
  292. package/dist/mcp/embed-app.d.ts.map +1 -1
  293. package/dist/mcp/embed-app.js +197 -7
  294. package/dist/mcp/embed-app.js.map +1 -1
  295. package/dist/mcp/oauth-route.d.ts.map +1 -1
  296. package/dist/mcp/oauth-route.js +95 -12
  297. package/dist/mcp/oauth-route.js.map +1 -1
  298. package/dist/server/attribution.d.ts +83 -0
  299. package/dist/server/attribution.d.ts.map +1 -0
  300. package/dist/server/attribution.js +178 -0
  301. package/dist/server/attribution.js.map +1 -0
  302. package/dist/server/auth.d.ts.map +1 -1
  303. package/dist/server/auth.js +7 -0
  304. package/dist/server/auth.js.map +1 -1
  305. package/dist/server/better-auth-instance.d.ts +9 -1
  306. package/dist/server/better-auth-instance.d.ts.map +1 -1
  307. package/dist/server/better-auth-instance.js +32 -2
  308. package/dist/server/better-auth-instance.js.map +1 -1
  309. package/dist/server/builder-browser.d.ts +4 -0
  310. package/dist/server/builder-browser.d.ts.map +1 -1
  311. package/dist/server/builder-browser.js +20 -1
  312. package/dist/server/builder-browser.js.map +1 -1
  313. package/dist/server/core-routes-plugin.d.ts +25 -0
  314. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  315. package/dist/server/core-routes-plugin.js +101 -0
  316. package/dist/server/core-routes-plugin.js.map +1 -1
  317. package/dist/server/google-oauth.d.ts.map +1 -1
  318. package/dist/server/google-oauth.js +16 -2
  319. package/dist/server/google-oauth.js.map +1 -1
  320. package/dist/server/onboarding-html.d.ts.map +1 -1
  321. package/dist/server/onboarding-html.js +35 -0
  322. package/dist/server/onboarding-html.js.map +1 -1
  323. package/dist/shared/mcp-embed-headers.js +1 -1
  324. package/dist/shared/mcp-embed-headers.js.map +1 -1
  325. package/dist/styles/agent-conversation.css +21 -0
  326. package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  327. package/dist/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  328. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  329. package/docs/design/durable-agent-runs.md +217 -0
  330. package/package.json +1 -1
  331. package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +111 -0
  332. package/src/templates/workspace-core/.agents/skills/reliable-mutations/SKILL.md +72 -0
  333. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +46 -14
  334. package/corpus/templates/analytics/app/pages/About.tsx +0 -108
  335. package/corpus/templates/analytics/app/routes/about.tsx +0 -9
  336. /package/corpus/templates/analytics/app/routes/{dashboards.tsx → dashboards._index.tsx} +0 -0
@@ -88,13 +88,14 @@ surface.
88
88
  approach and options in the plan. Ask a clarifying question only when an
89
89
  ambiguity would change the design and you cannot resolve it from the code; use
90
90
  the host agent's normal ask-user-question flow and batch 2-4 high-leverage
91
- questions before finalizing. Do not call `create-visual-questions` from
92
- `/visual-plan`. Otherwise state the assumption explicitly and proceed, and
93
- keep anything unresolved in the plan's single bottom `question-form` Open
94
- Questions block. For complex plans, do a final open-question pass before
95
- handoff: if a decision would affect architecture, scope, UX, data shape, or
96
- rollout, either decide it in the plan with rationale or put it in that bottom
97
- form with a recommended default.
91
+ questions before finalizing. Do not call `create-visual-questions` for
92
+ ordinary clarification or preflight; reserve it for the visual-intake mode when
93
+ the user explicitly asks for a visual intake questionnaire. Otherwise state the
94
+ assumption explicitly and proceed, and keep anything unresolved in the plan's
95
+ single bottom `question-form` Open Questions block. For complex plans, do a
96
+ final open-question pass before handoff: if a decision would affect
97
+ architecture, scope, UX, data shape, or rollout, either decide it in the plan
98
+ with rationale or put it in that bottom form with a recommended default.
98
99
  - **The plan is the approval gate.** After surfacing it, ask the user to review
99
100
  and approve before you write code, and name which files/areas the work touches.
100
101
  Presenting the plan and requesting sign-off is the approval step — do not ask a
@@ -139,6 +140,11 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
139
140
 
140
141
  ## Core Workflow
141
142
 
143
+ This section describes the default hosted Plan MCP workflow. If
144
+ `AGENT_NATIVE_PLANS_MODE=local-files` is set, or the user asks for fully local
145
+ files/no hosted Plan writes, use **Local-Files Privacy Mode** instead; carry
146
+ forward only the code-research and plan-composition guidance here.
147
+
142
148
  1. Follow the host agent's normal planning flow: inspect the codebase, delegate
143
149
  wide exploration when useful, gather the info needed, and ask native
144
150
  clarifying questions as needed before generating the plan. If a source plan
@@ -185,11 +191,13 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
185
191
  backend, data, multi-file, or risky), also kick off the self-review pass in
186
192
  **Self-Review Before Handoff** while the user reads, instead of blocking the
187
193
  handoff on it.
188
- 5. Call `get-plan-feedback` before editing, after review, after any long pause,
194
+ 5. For hosted plans, call `get-plan-feedback` before editing, after review,
195
+ after any long pause,
189
196
  and before the final response. Treat `anchorDetails`, resolver intent, recent
190
197
  review events, and any focused screenshots from browser handoff as the source
191
198
  of truth for exactly what changed and exactly what each comment points at.
192
- 6. Apply changes with `update-visual-plan`, preferring targeted `contentPatches`.
199
+ 6. For hosted plans, apply changes with `update-visual-plan`, preferring
200
+ targeted `contentPatches`.
193
201
  Treat the top-level `content` payload as a full replacement, not a merge; do
194
202
  not send a partial `content` object to add a canvas or one block. If a full
195
203
  replacement is unavoidable, first read the complete plan source/content, carry
@@ -197,8 +205,8 @@ is reachable. Local-files privacy mode (after Tool Guidance) is the exception.
197
205
  afterward so the document body was not truncated. When the user wants
198
206
  source-control friendly edits, use `patch-visual-plan-source` against the MDX
199
207
  files instead of regenerating the plan.
200
- 7. Export with `export-visual-plan` only when the user wants a shareable receipt
201
- or repo-check-in artifacts.
208
+ 7. For hosted plans, export with `export-visual-plan` only when the user wants a
209
+ shareable receipt or repo-check-in artifacts.
202
210
 
203
211
  ## Self-Review Before Handoff
204
212
 
@@ -394,11 +402,12 @@ The local-files contract is:
394
402
  wants the artifact checked into the repo, or use a repo-ignored/temporary
395
403
  folder such as `.agent-native/plans/<slug>/` or `/tmp/agent-native-plans/<slug>/`
396
404
  when it should not be checked in. The folder contains `plan.mdx`, optional
397
- `canvas.mdx`, optional `prototype.mdx`, and optional `.plan-state.json`.
398
- - Run `npx @agent-native/core@latest plan local check --dir plans/<slug>`
399
- before serving, then run
400
- `npx @agent-native/core@latest plan local serve --dir plans/<slug> --kind plan --open`.
401
- Report the returned local bridge URL from stdout or `plans/<slug>/.plan-url`.
405
+ `canvas.mdx`, optional `prototype.mdx`, and optional `.plan-state.json`. Use
406
+ that exact chosen folder as `<plan-dir>` in every local CLI command below.
407
+ - Run `npx @agent-native/core@latest plan local check --dir <plan-dir>` before
408
+ serving, then run
409
+ `npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind plan --open`.
410
+ Report the returned local bridge URL from stdout or `<plan-dir>/.plan-url`.
402
411
  Treat `.plan-url` as a local token file and do not commit it. The URL opens
403
412
  the hosted Plan UI but reads from the localhost bridge on this machine, so it
404
413
  is not shareable across machines. On macOS, `--open` prefers Chromium browsers;
@@ -407,7 +416,7 @@ The local-files contract is:
407
416
  running locally with the same `PLAN_LOCAL_DIR`, the `/local-plans/<slug>` route
408
417
  is also valid.
409
418
  - For headless verification, run
410
- `npx @agent-native/core@latest plan local verify --dir plans/<slug> --kind plan`.
419
+ `npx @agent-native/core@latest plan local verify --dir <plan-dir> --kind plan`.
411
420
  It starts the bridge, checks the private-network preflight and JSON payload,
412
421
  prints diagnostics, and exits. If the browser hangs on "Loading plan", fetch
413
422
  the `bridgeUrl` from the verify/serve JSON to read the concrete validation
@@ -429,6 +438,11 @@ otherwise approved by the user.
429
438
 
430
439
  ## Interpreting comment anchors
431
440
 
441
+ This section applies to hosted plans with `get-plan-feedback` /
442
+ `update-visual-plan`. In local-files mode, do not call hosted feedback or update
443
+ tools; interpret file/chat feedback directly, edit the MDX files, rerun the
444
+ local bridge check/serve/verify command, and report the new local URL.
445
+
432
446
  `get-plan-feedback` returns rich anchors — read them before acting on any comment.
433
447
 
434
448
  - **Coordinate frames.** `targetX`/`targetY` are percentages *within* the
@@ -135,12 +135,15 @@ no labels or copy. The renderer drops borders, sketch, and color into the
135
135
  skeleton register automatically. Never escape to a `custom-html` document block
136
136
  to fake a loader.
137
137
 
138
- **Editing an existing mockup.** To change one element, text, or color in an
139
- existing html mockup, call `update-visual-plan`
140
- with `contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
138
+ **Editing an existing mockup.** In hosted mode, to change one element, text, or
139
+ color in an existing html mockup, do not regenerate the frame — call
140
+ `update-visual-plan` with
141
+ `contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
141
142
  replace }] }]`. Each `find` is a unique snippet of the current html (read it
142
143
  first with `get-visual-plan`); set `all: true` on an edit to replace every
143
- occurrence. The result is re-sanitized.
144
+ occurrence. The result is re-sanitized. In local-files privacy mode, do not call
145
+ hosted Plan tools; edit the local MDX source directly and rerun the local
146
+ check/serve or verify command for `<plan-dir>`.
144
147
 
145
148
  **Treat the wireframe border as part of the visible design.** Always wrap HTML
146
149
  wireframe content in a root container with real inner padding before drawing
@@ -36,8 +36,9 @@ In local-files mode:
36
36
  `npx @agent-native/core@latest plan blocks --out plan-blocks.md` when the Plan
37
37
  MCP connector is not registered; it calls the public no-auth
38
38
  `get-plan-blocks` route and sends no recap content. If network access is
39
- unavailable, use the bundled references and validate with
40
- `plan local check` / `plan local serve`. For `checklist` and `question-form`,
39
+ unavailable, use the bundled references and validate the MDX with
40
+ `plan local check`; do not run `plan local serve` unless the hosted Plan UI is
41
+ reachable or a local Plan app is already running. For `checklist` and `question-form`,
41
42
  copy the catalog examples verbatim: checklist items need `id` and `label`;
42
43
  question-form questions need `id`, `title`, and `mode`; and each option needs
43
44
  `id` and `label`. `plan local check` validates these required fields against
@@ -47,21 +48,24 @@ In local-files mode:
47
48
  folder such as `.agent-native/plans/<slug>/` or `/tmp/agent-native-plans/<slug>/`
48
49
  when it should not be checked in. The folder contains `plan.mdx`, optional
49
50
  `canvas.mdx`, optional `prototype.mdx`, and optional `.plan-state.json`. Set
50
- `kind: "recap"` and `localOnly: true` in frontmatter/state when authoring
51
- the source.
52
- - Run `npx @agent-native/core@latest plan local check --dir plans/<slug>`
53
- before serving, then run
54
- `npx @agent-native/core@latest plan local serve --dir plans/<slug> --kind recap --open`.
55
- Report the returned local bridge URL from stdout or `plans/<slug>/.plan-url`.
51
+ `kind: "recap"` and `localOnly: true` in frontmatter/state when authoring the
52
+ source. Use that exact chosen folder as `<plan-dir>` in every local CLI command
53
+ below.
54
+ - Run `npx @agent-native/core@latest plan local check --dir <plan-dir>` before
55
+ any preview. When the hosted Plan UI is reachable, run
56
+ `npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open`.
57
+ Report the returned local bridge URL from stdout or `<plan-dir>/.plan-url`.
56
58
  Treat `.plan-url` as a local token file and do not commit it. The URL opens
57
59
  the hosted Plan UI but reads from the localhost bridge on this machine, so it
58
60
  is not shareable across machines. On macOS, `--open` prefers Chromium browsers;
59
61
  if Safari opens, switch to Chrome/Chromium because Safari can block the hosted
60
62
  HTTPS page from fetching the HTTP localhost bridge. If the Plan app itself is
61
63
  running locally with the same `PLAN_LOCAL_DIR`, the `/local-plans/<slug>` route
62
- is also valid.
64
+ is also valid. In a truly offline environment, hand off the local `<plan-dir>`
65
+ path after `plan local check` and note that interactive preview requires either
66
+ network access to the hosted Plan UI or a running local Plan app.
63
67
  - For headless verification, run
64
- `npx @agent-native/core@latest plan local verify --dir plans/<slug> --kind recap`.
68
+ `npx @agent-native/core@latest plan local verify --dir <plan-dir> --kind recap`.
65
69
  It starts the bridge, checks the private-network preflight and JSON payload,
66
70
  prints diagnostics, and exits. If the browser hangs on "Loading plan", fetch
67
71
  the `bridgeUrl` from the verify/serve JSON to read the concrete validation
@@ -72,7 +76,9 @@ In local-files mode:
72
76
  `set-resource-visibility`, or any hosted Plan tool for that recap except the
73
77
  schema-only block catalog lookup above.
74
78
  - Treat review feedback as file or chat feedback: update the MDX files directly,
75
- rerun the local bridge command, and summarize the new local bridge URL.
79
+ rerun `plan local check`, and rerun `serve` or `verify` only when that preview
80
+ path is available. Summarize the new local URL when one exists; otherwise
81
+ summarize the checked local folder path.
76
82
  Hosted comments, sharing, screenshots, usage attachment, and PR sticky comment
77
83
  publishing are unavailable until the user explicitly opts into publishing.
78
84
 
@@ -288,10 +294,10 @@ and re-import before reporting the link. A text-match screenshot is not enough;
288
294
  visually inspect the captured image. When no browser is available (for example
289
295
  a headless CI agent), state that in the recap handoff instead.
290
296
 
291
- ## Top Canvas Recaps — read `../visual-plans/references/canvas.md`
297
+ ## Top Canvas Recaps — read `../visual-plan/references/canvas.md`
292
298
 
293
299
  When a recap includes a top canvas, storyboard, or flow view, READ
294
- `../visual-plans/references/canvas.md` before authoring `canvas.mdx`. Recap
300
+ `../visual-plan/references/canvas.md` before authoring `canvas.mdx`. Recap
295
301
  canvas artboards must use the same HTML wireframe path as good document-body
296
302
  wireframes: `<Screen surface="..." html={...} />` with a semantic HTML fragment.
297
303
  Do not author fresh kit-tree children such as `<FrameScreen>`, `<Card>`,
@@ -305,8 +311,8 @@ assume it used the legacy kit path and replace it with an HTML screen.
305
311
 
306
312
  In local-files privacy mode, run `plan local check` first, then report the local
307
313
  bridge URL from
308
- `npx @agent-native/core@latest plan local serve --dir plans/<slug> --kind recap --open`
309
- or from `plans/<slug>/.plan-url`. It opens the hosted Plan UI but reads from the
314
+ `npx @agent-native/core@latest plan local serve --dir <plan-dir> --kind recap --open`
315
+ or from `<plan-dir>/.plan-url`. It opens the hosted Plan UI but reads from the
310
316
  localhost bridge on this machine, so it is not shareable across machines. If the
311
317
  Plan app itself is running locally with the same `PLAN_LOCAL_DIR`, the
312
318
  `/local-plans/<slug>` route is also valid. Do not invent a hosted database URL
@@ -471,7 +477,8 @@ installed as plain text and no MCP tools are registered after discovery, run
471
477
  `npx @agent-native/core@latest plan blocks --out plan-blocks.md` and read that
472
478
  file first. The CLI command calls the public no-auth `get-plan-blocks` route and
473
479
  sends no plan/recap content. If network access is unavailable, use the bundled
474
- references and validate with `plan local check` / `plan local serve`.
480
+ references and validate with `plan local check`; run `plan local serve` only
481
+ when the hosted Plan UI is reachable or a local Plan app is already running.
475
482
 
476
483
  The catalog returns the authoritative, always-current block vocabulary generated
477
484
  live from the app's own block registry — the same config the renderer and MDX
@@ -579,14 +586,17 @@ inferred (not extracted) as inferred in prose.
579
586
 
580
587
  ## Bidirectional Loop
581
588
 
582
- Because a recap is a real, editable plan, the same review loop as forward plans
583
- applies: a reviewer can annotate any block, and the coding agent reads
584
- `get-plan-feedback` to drive fixes back into the code — annotation → agent →
585
- diff, the same close-the-loop flow forward plans use. After a reviewer annotates
586
- a block, call `get-plan-feedback` to read the structured feedback, then either
587
- update the recap with `create-visual-recap` (passing the existing `planId` to
588
- replace it in place) or apply targeted changes with `update-visual-plan`. The
589
- loop is live and wired. The one thing not yet automatic is PR-comment-triggered
589
+ In hosted mode, because a recap is a real, editable plan, the same review loop
590
+ as forward plans applies: a reviewer can annotate any block, and the coding
591
+ agent reads `get-plan-feedback` to drive fixes back into the code — annotation →
592
+ agent → diff, the same close-the-loop flow forward plans use. After a reviewer
593
+ annotates a block, call `get-plan-feedback` to read the structured feedback,
594
+ then either update the recap with `create-visual-recap` (passing the existing
595
+ `planId` to replace it in place) or apply targeted changes with
596
+ `update-visual-plan`. The loop is live and wired. In local-files privacy mode,
597
+ do not call those hosted tools; read review notes from chat or local files, edit
598
+ `<plan-dir>/*.mdx` directly, and rerun `plan local check`, `serve`, or `verify`
599
+ for `<plan-dir>`. The one thing not yet automatic is PR-comment-triggered
590
600
  re-runs: the GitHub Action creates an initial recap per PR, but it does not yet
591
601
  re-run automatically when new review feedback is posted in GitHub — that
592
602
  auto-re-run is the remaining fast-follow.
@@ -135,12 +135,15 @@ no labels or copy. The renderer drops borders, sketch, and color into the
135
135
  skeleton register automatically. Never escape to a `custom-html` document block
136
136
  to fake a loader.
137
137
 
138
- **Editing an existing mockup.** To change one element, text, or color in an
139
- existing html mockup, call `update-visual-plan`
140
- with `contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
138
+ **Editing an existing mockup.** In hosted mode, to change one element, text, or
139
+ color in an existing html mockup, do not regenerate the frame — call
140
+ `update-visual-plan` with
141
+ `contentPatches: [{ op: "patch-wireframe-html", blockId, edits: [{ find,
141
142
  replace }] }]`. Each `find` is a unique snippet of the current html (read it
142
143
  first with `get-visual-plan`); set `all: true` on an edit to replace every
143
- occurrence. The result is re-sanitized.
144
+ occurrence. The result is re-sanitized. In local-files privacy mode, do not call
145
+ hosted Plan tools; edit the local MDX source directly and rerun the local
146
+ check/serve or verify command for `<plan-dir>`.
144
147
 
145
148
  **Treat the wireframe border as part of the visible design.** Always wrap HTML
146
149
  wireframe content in a root container with real inner padding before drawing
@@ -46,6 +46,10 @@ review before code changes happen.
46
46
  resource paths for the latest code index, file tree, and captured source
47
47
  snapshots.
48
48
  - `navigate` moves the UI to the plan list or a specific visual plan.
49
+ - The sidebar brand header has a `Customize branding` popover. Treat it as a
50
+ source-code request, not plan data: local Code mode edits `templates/plan`
51
+ source directly, while hosted/live surfaces route people to Desktop or
52
+ Builder for code customization.
49
53
 
50
54
  ## Normal Planning Flow
51
55
 
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ All notable user-facing changes to Agent-Native Plan are documented here. Open it any
4
+ time from the command menu (Cmd+K → "What's new").
5
+
6
+ ## 2026-06-23
7
+
8
+ ### Added
9
+
10
+ - See what's new right inside Agent-Native Plan — a changelog now lives in the command menu (Cmd+K).
@@ -34,6 +34,11 @@ export default defineAction({
34
34
  const screen: Record<string, unknown> = {};
35
35
  if (navigation) screen.navigation = navigation;
36
36
  if (localCodebase) screen.localCodebase = localCodebase;
37
+ screen.brandingCustomization = {
38
+ surface: "sidebar brand header",
39
+ workflow:
40
+ "The Customize branding popover sends a source-code request. In local Code mode it routes to the local code agent; on hosted/live surfaces it should guide the user to Desktop or Builder for source edits.",
41
+ };
37
42
  const nav = navigation as {
38
43
  planId?: string;
39
44
  localPlanSlug?: string;
@@ -28,7 +28,11 @@ import {
28
28
  appPath,
29
29
  markAgentChatHomeHandoff,
30
30
  navigateWithAgentChatViewTransition,
31
+ PromptComposer,
32
+ sendToAgentChat,
33
+ useCodeMode,
31
34
  useChatThreads,
35
+ useSendToAgentChat,
32
36
  useSession,
33
37
  type ChatThreadSummary,
34
38
  } from "@agent-native/core/client";
@@ -44,6 +48,11 @@ import {
44
48
  DropdownMenuTrigger,
45
49
  } from "@/components/ui/dropdown-menu";
46
50
  import { Input } from "@/components/ui/input";
51
+ import {
52
+ Popover,
53
+ PopoverContent,
54
+ PopoverTrigger,
55
+ } from "@/components/ui/popover";
47
56
  import { Skeleton } from "@/components/ui/skeleton";
48
57
  import {
49
58
  Tooltip,
@@ -53,6 +62,23 @@ import {
53
62
 
54
63
  const PLAN_CHAT_STORAGE_KEY = "plans";
55
64
 
65
+ const PLAN_BRANDING_CODE_CONTEXT = [
66
+ "The user is using the Plan app branding customization popover.",
67
+ "Make source-code changes for Agent-Native Plan branding in templates/plan.",
68
+ "Inspect the current brand surfaces first: app/lib/app-config.ts, app/components/layout/Sidebar.tsx, app/root.tsx metadata/icons, public brand assets, and app/global.css theme tokens.",
69
+ "Keep runtime plan data, stored plans, recaps, comments, and generated plan content unchanged unless the user explicitly asks for those data changes.",
70
+ "Use existing Plan styling, shadcn primitives, Tabler icons, and repo patterns. Keep changes tightly scoped.",
71
+ ].join("\n");
72
+
73
+ function buildBrandingCustomizationMessage(request: string) {
74
+ return [
75
+ "Customize the Agent-Native Plan app branding.",
76
+ "",
77
+ "Request:",
78
+ request,
79
+ ].join("\n");
80
+ }
81
+
56
82
  const navItems = [
57
83
  { icon: IconMessageCircle, label: "Ask", href: "/" },
58
84
  { icon: IconClipboardCheck, label: "Plan", href: "/plans" },
@@ -521,6 +547,76 @@ function PlansSidebarSection({ collapsed }: { collapsed: boolean }) {
521
547
  );
522
548
  }
523
549
 
550
+ function BrandingCustomizePopover() {
551
+ const [open, setOpen] = useState(false);
552
+ const { isCodeMode } = useCodeMode();
553
+ const { send, isGenerating, codeRequiredDialog } = useSendToAgentChat();
554
+
555
+ function handleSubmit(text: string) {
556
+ const trimmed = text.trim();
557
+ if (!trimmed || isGenerating) return;
558
+ const message = buildBrandingCustomizationMessage(trimmed);
559
+ const payload = {
560
+ message,
561
+ context: PLAN_BRANDING_CODE_CONTEXT,
562
+ submit: true,
563
+ type: "code" as const,
564
+ newTab: true,
565
+ };
566
+ const tabId = isCodeMode ? sendToAgentChat(payload) : send(payload);
567
+ setOpen(false);
568
+ if (tabId) {
569
+ toast.success(
570
+ isCodeMode
571
+ ? "Sent branding request to the local code agent"
572
+ : "Sent branding request to the code agent",
573
+ );
574
+ }
575
+ }
576
+
577
+ return (
578
+ <>
579
+ {codeRequiredDialog}
580
+ <Popover open={open} onOpenChange={setOpen}>
581
+ <PopoverTrigger asChild>
582
+ <button
583
+ type="button"
584
+ aria-label="Customize Plan branding"
585
+ title="Customize branding"
586
+ className="flex size-7 shrink-0 items-center justify-center rounded-md text-sidebar-foreground/55 opacity-0 transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring group-hover/brand:opacity-100 group-focus-within/brand:opacity-100 data-[state=open]:opacity-100"
587
+ >
588
+ <IconEdit className="size-3.5" />
589
+ </button>
590
+ </PopoverTrigger>
591
+ <PopoverContent
592
+ side="right"
593
+ align="start"
594
+ sideOffset={8}
595
+ className="w-[calc(100vw-2rem)] max-w-[420px] rounded-xl border-border bg-card p-3 shadow-xl sm:w-[420px]"
596
+ >
597
+ <div className="mb-2 px-1">
598
+ <h3 className="text-sm font-semibold text-foreground">
599
+ Customize branding
600
+ </h3>
601
+ <p className="mt-1 text-xs text-muted-foreground">
602
+ Describe the brand changes to make across Plan.
603
+ </p>
604
+ </div>
605
+ <PromptComposer
606
+ autoFocus
607
+ disabled={isGenerating}
608
+ attachmentsEnabled={false}
609
+ showModelSelector={false}
610
+ placeholder="Use our logo, change the app name, update colors..."
611
+ draftScope="plans:customize-branding"
612
+ onSubmit={handleSubmit}
613
+ />
614
+ </PopoverContent>
615
+ </Popover>
616
+ </>
617
+ );
618
+ }
619
+
524
620
  export function Sidebar({
525
621
  collapsed = false,
526
622
  collapsible = true,
@@ -562,7 +658,7 @@ export function Sidebar({
562
658
  >
563
659
  <div
564
660
  className={cn(
565
- "flex h-12 shrink-0 items-center border-b border-border",
661
+ "group/brand flex h-12 shrink-0 items-center border-b border-border",
566
662
  collapsed ? "justify-center px-0" : "gap-2 px-3",
567
663
  )}
568
664
  >
@@ -590,6 +686,7 @@ export function Sidebar({
590
686
  </span>
591
687
  )}
592
688
  </div>
689
+ {!collapsed && <BrandingCustomizePopover />}
593
690
  </div>
594
691
 
595
692
  <nav className="flex-1 space-y-1 overflow-y-auto px-2 py-2">
@@ -293,7 +293,9 @@
293
293
  --wf-font: var(--wf-font-clean);
294
294
 
295
295
  position: relative;
296
- overflow: hidden;
296
+ /* Matches core blocks.css `.plan-diagram-frame`: scroll oversized diagrams
297
+ instead of clipping them (Plan's copy had drifted to `hidden`). */
298
+ overflow: auto;
297
299
  width: 100%;
298
300
  border: 0;
299
301
  border-radius: 10px;
@@ -68,6 +68,7 @@ import {
68
68
  useAgentEngineConfigured,
69
69
  useActionQuery,
70
70
  useSession,
71
+ track,
71
72
  emailToColor,
72
73
  emailToName,
73
74
  type AgentSidebarStateChangeDetail,
@@ -219,6 +220,11 @@ import {
219
220
  type PlanVersionDetail,
220
221
  type PlanVersionSummary,
221
222
  } from "@shared/types";
223
+ import {
224
+ PLAN_SHARE_SURFACE,
225
+ readPlanShareAttribution,
226
+ withPlanShareAttribution,
227
+ } from "@shared/share-attribution";
222
228
  import {
223
229
  diffPlanVersions,
224
230
  formatVersionDiffSummary,
@@ -3783,13 +3789,92 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
3783
3789
  }
3784
3790
  if (!selectedId) return undefined;
3785
3791
  const base = bundle?.plan.kind === "recap" ? "recaps" : "plans";
3786
- return `${window.location.origin}${appPath(`/${base}/${selectedId}`)}`;
3792
+ const url = `${window.location.origin}${appPath(`/${base}/${selectedId}`)}`;
3793
+ // Viral attribution: tag the shared/public plan link so signups arriving
3794
+ // from it can be attributed even when `document.referrer` is empty. `via`
3795
+ // is a non-PII owner id and is only set when the current viewer is the
3796
+ // owner (the only person whose session userId is the plan owner's id).
3797
+ const ownerViaId =
3798
+ effectivePlanAccessRole === "owner" ? (session?.userId ?? null) : null;
3799
+ return withPlanShareAttribution(url, ownerViaId);
3787
3800
  }, [
3788
3801
  bundle?.plan.kind,
3802
+ effectivePlanAccessRole,
3789
3803
  localPlanMode,
3790
3804
  localPlanRepoPath,
3791
3805
  localPlanSlug,
3792
3806
  selectedId,
3807
+ session?.userId,
3808
+ ]);
3809
+
3810
+ // Viral attribution: read the `ref`/`via` the visitor arrived on (from a
3811
+ // tagged share link) so funnel events carry the same attribution the
3812
+ // framework first-touch cookie captured. Read once from the URL on mount.
3813
+ const shareAttribution = useMemo(
3814
+ () =>
3815
+ readPlanShareAttribution(
3816
+ typeof window === "undefined" ? "" : window.location.search,
3817
+ ),
3818
+ [],
3819
+ );
3820
+
3821
+ // A logged-out visitor looking at a public plan/recap is the share funnel
3822
+ // audience. Their CTAs (comment, sign in) route through `openSignIn`.
3823
+ const isLoggedOutPublicPlanView =
3824
+ !sessionLoading &&
3825
+ !session &&
3826
+ !localPlanMode &&
3827
+ Boolean(selectedId) &&
3828
+ effectivePlanVisibility === "public";
3829
+
3830
+ // share_cta_click — fire alongside (never instead of) the real navigation.
3831
+ // `track` is non-throwing, but guard anyway so analytics can never break a
3832
+ // CTA. Only fires for the logged-out public-plan funnel audience.
3833
+ const fireShareCtaClick = useCallback(
3834
+ (cta: string) => {
3835
+ if (!isLoggedOutPublicPlanView) return;
3836
+ try {
3837
+ void track("share_cta_click", {
3838
+ surface: PLAN_SHARE_SURFACE,
3839
+ plan_id: selectedId ?? "",
3840
+ cta,
3841
+ ref: shareAttribution.ref,
3842
+ via: shareAttribution.via,
3843
+ });
3844
+ } catch {
3845
+ // Never let analytics break a CTA.
3846
+ }
3847
+ },
3848
+ [
3849
+ isLoggedOutPublicPlanView,
3850
+ selectedId,
3851
+ shareAttribution.ref,
3852
+ shareAttribution.via,
3853
+ ],
3854
+ );
3855
+
3856
+ // share_view — fire once when a logged-out visitor views a public plan. The
3857
+ // ref guard prevents double-fire across re-renders / StrictMode double-invoke.
3858
+ const shareViewFiredRef = useRef(false);
3859
+ useEffect(() => {
3860
+ if (!isLoggedOutPublicPlanView) return;
3861
+ if (shareViewFiredRef.current) return;
3862
+ shareViewFiredRef.current = true;
3863
+ try {
3864
+ void track("share_view", {
3865
+ surface: PLAN_SHARE_SURFACE,
3866
+ plan_id: selectedId ?? "",
3867
+ ref: shareAttribution.ref,
3868
+ via: shareAttribution.via,
3869
+ });
3870
+ } catch {
3871
+ // Never let analytics break the page render.
3872
+ }
3873
+ }, [
3874
+ isLoggedOutPublicPlanView,
3875
+ selectedId,
3876
+ shareAttribution.ref,
3877
+ shareAttribution.via,
3793
3878
  ]);
3794
3879
 
3795
3880
  useEffect(() => {
@@ -6227,11 +6312,14 @@ export function PlansPage({ localPlanSlug }: { localPlanSlug?: string } = {}) {
6227
6312
  {!session ? (
6228
6313
  <GuestCommentCta
6229
6314
  position={inlineCommentPosition}
6230
- onSignIn={() =>
6315
+ onSignIn={() => {
6316
+ // share funnel: logged-out viewer of a public plan
6317
+ // clicking the "create account to comment" CTA.
6318
+ fireShareCtaClick("comment_signin");
6231
6319
  openSignIn(
6232
6320
  window.location.pathname + window.location.search,
6233
- )
6234
- }
6321
+ );
6322
+ }}
6235
6323
  onCancel={closeInlineComment}
6236
6324
  />
6237
6325
  ) : (
@@ -6669,9 +6757,12 @@ function PlanShareControl({
6669
6757
  effectivePublishedUrl && hostedPlanOnCurrentOrigin && effectiveHostedPlanId
6670
6758
  ? effectiveHostedPlanId
6671
6759
  : planId;
6760
+ // Viral attribution: the owner is the one publishing/managing the share here,
6761
+ // so `via` is their non-PII session userId. `localShareUrl` is already tagged
6762
+ // upstream; tag the hosted/public URL too so both paths self-attribute.
6672
6763
  const managedShareUrl =
6673
6764
  effectivePublishedUrl && hostedPlanOnCurrentOrigin
6674
- ? effectivePublishedUrl
6765
+ ? withPlanShareAttribution(effectivePublishedUrl, session?.userId ?? null)
6675
6766
  : localShareUrl;
6676
6767
 
6677
6768
  useEffect(() => {
@@ -6713,11 +6804,20 @@ function PlanShareControl({
6713
6804
  hostedPlanId: result.hostedPlanId,
6714
6805
  });
6715
6806
  setAuthPrompt(null);
6716
- copyPublishedUrl(result.hostedPlanUrl ?? result.url);
6807
+ // Tag the freshly-minted public link so signups from it are
6808
+ // attributed. The publisher is the owner, so `via` is their userId.
6809
+ copyPublishedUrl(
6810
+ withPlanShareAttribution(
6811
+ result.hostedPlanUrl ?? result.url,
6812
+ session?.userId ?? null,
6813
+ ) ??
6814
+ result.hostedPlanUrl ??
6815
+ result.url,
6816
+ );
6717
6817
  },
6718
6818
  },
6719
6819
  );
6720
- }, [copyPublishedUrl, planId, publishPlan]);
6820
+ }, [copyPublishedUrl, planId, publishPlan, session?.userId]);
6721
6821
 
6722
6822
  // Logged-in / local-dev: manage shares for the plan in this app instance.
6723
6823
  if (canManageLocalShares) {
@@ -22,6 +22,7 @@ import {
22
22
  } from "@agent-native/core/client";
23
23
  import { IconSun, IconMoon } from "@tabler/icons-react";
24
24
  import { useTheme } from "next-themes";
25
+ import changelog from "../CHANGELOG.md?raw";
25
26
  import { Toaster } from "@/components/ui/sonner";
26
27
  import { Layout as AppLayout } from "@/components/layout/Layout";
27
28
  import { TAB_ID } from "@/lib/tab-id";
@@ -106,7 +107,12 @@ function AppContent() {
106
107
  );
107
108
  return (
108
109
  <>
109
- <CommandMenu open={cmdkOpen} onOpenChange={setCmdkOpen}>
110
+ <CommandMenu
111
+ open={cmdkOpen}
112
+ onOpenChange={setCmdkOpen}
113
+ changelog={changelog}
114
+ changelogKey="plan"
115
+ >
110
116
  <CommandMenu.Group heading="Actions">
111
117
  <CommandMenu.Item onSelect={() => go("/")}>Ask Plan</CommandMenu.Item>
112
118
  <CommandMenu.Item onSelect={() => go("/plans")}>
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-23
4
+ ---
5
+
6
+ Large diagrams in a plan now scroll within their block instead of being cut off