@agent-native/core 0.146.8 → 0.148.0

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 (317) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +115 -68
  3. package/corpus/templates/analytics/.agents/skills/turn-into-app/SKILL.md +18 -6
  4. package/corpus/templates/analytics/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  5. package/corpus/templates/analytics/DEVELOPING.md +50 -3
  6. package/corpus/templates/analytics/actions/purge-first-party-analytics-postgres.ts +190 -0
  7. package/corpus/templates/analytics/app/i18n/index.ts +14 -29
  8. package/corpus/templates/analytics/app/i18n-data.ts +10 -10
  9. package/corpus/templates/analytics/app/pages/Settings.tsx +5 -21
  10. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +1 -3
  11. package/corpus/templates/analytics/app/routes/status.$slug.tsx +4 -2
  12. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery-backfill.ts +253 -24
  13. package/corpus/templates/analytics/server/db/schema.ts +23 -0
  14. package/corpus/templates/analytics/server/handlers/first-party-analytics.ts +3 -1
  15. package/corpus/templates/analytics/server/jobs/analytics-bigquery-backfill.ts +1 -1
  16. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +113 -13
  17. package/corpus/templates/analytics/server/lib/first-party-analytics-purge.ts +140 -0
  18. package/corpus/templates/analytics/server/lib/first-party-analytics-volume.ts +207 -0
  19. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +40 -9
  20. package/corpus/templates/analytics/server/lib/gcloud.ts +148 -20
  21. package/corpus/templates/analytics/server/plugins/db.ts +42 -0
  22. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +115 -68
  23. package/corpus/templates/assets/.agents/skills/turn-into-app/SKILL.md +18 -6
  24. package/corpus/templates/assets/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  25. package/corpus/templates/assets/app/i18n/index.ts +14 -29
  26. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +9 -0
  27. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +115 -68
  28. package/corpus/templates/brain/.agents/skills/turn-into-app/SKILL.md +18 -6
  29. package/corpus/templates/brain/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  30. package/corpus/templates/brain/app/i18n/index.ts +14 -29
  31. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +115 -68
  32. package/corpus/templates/calendar/.agents/skills/turn-into-app/SKILL.md +18 -6
  33. package/corpus/templates/calendar/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  34. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  35. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  36. package/corpus/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  37. package/corpus/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  38. package/corpus/templates/chat/app/i18n/index.ts +14 -29
  39. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +115 -68
  40. package/corpus/templates/clips/.agents/skills/turn-into-app/SKILL.md +18 -6
  41. package/corpus/templates/clips/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  42. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -7
  43. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +18 -13
  44. package/corpus/templates/clips/app/components/settings/ai-setup-section.tsx +87 -370
  45. package/corpus/templates/clips/app/components/settings/slack-section.tsx +59 -101
  46. package/corpus/templates/clips/app/components/settings/video-storage-section.tsx +136 -213
  47. package/corpus/templates/clips/app/i18n/en-US.ts +11 -8
  48. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +16 -4
  49. package/corpus/templates/clips/app/routes/share.meeting.$meetingId.tsx +14 -5
  50. package/corpus/templates/clips/desktop/src/app.tsx +1 -1
  51. package/corpus/templates/clips/package.json +1 -0
  52. package/corpus/templates/clips/react-router.config.ts +7 -0
  53. package/corpus/templates/clips/server/plugins/auth.ts +6 -1
  54. package/corpus/templates/clips/shared/prerendered-public-paths.ts +21 -0
  55. package/corpus/templates/clips/shared/share-meta.ts +8 -3
  56. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +115 -68
  57. package/corpus/templates/content/.agents/skills/turn-into-app/SKILL.md +18 -6
  58. package/corpus/templates/content/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  59. package/corpus/templates/content/app/i18n/index.ts +14 -29
  60. package/corpus/templates/crm/.agents/skills/turn-into-app/SKILL.md +18 -6
  61. package/corpus/templates/crm/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  62. package/corpus/templates/crm/app/i18n/index.ts +14 -29
  63. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +115 -68
  64. package/corpus/templates/design/.agents/skills/turn-into-app/SKILL.md +18 -6
  65. package/corpus/templates/design/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  66. package/corpus/templates/design/actions/analyze-brand-assets.ts +15 -15
  67. package/corpus/templates/design/actions/import-code.ts +2 -43
  68. package/corpus/templates/design/app/i18n/index.ts +14 -29
  69. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +115 -68
  70. package/corpus/templates/dispatch/.agents/skills/turn-into-app/SKILL.md +18 -6
  71. package/corpus/templates/dispatch/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  72. package/corpus/templates/dispatch/app/chat-first-pages.ts +747 -0
  73. package/corpus/templates/dispatch/app/i18n-data.ts +182 -1
  74. package/corpus/templates/dispatch/app/routes/settings.tsx +62 -1
  75. package/corpus/templates/dispatch/changelog/2026-08-08-chat-first-navigation-keeps-conversations-central-while-open.md +6 -0
  76. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +9 -0
  77. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +115 -68
  78. package/corpus/templates/factory/.agents/skills/turn-into-app/SKILL.md +18 -6
  79. package/corpus/templates/factory/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  80. package/corpus/templates/factory/AGENTS.md +40 -49
  81. package/corpus/templates/factory/actions/babysit-agent-native-pull-request.ts +66 -0
  82. package/corpus/templates/factory/actions/evaluate-triage-item.ts +37 -0
  83. package/corpus/templates/factory/actions/get-slack-feedback-context.ts +20 -0
  84. package/corpus/templates/factory/actions/get-triage-item.ts +25 -4
  85. package/corpus/templates/factory/actions/govern-agent-native-pull-request.ts +55 -0
  86. package/corpus/templates/factory/actions/ingest-github-observation.ts +21 -0
  87. package/corpus/templates/factory/actions/list-factory-audit.ts +118 -0
  88. package/corpus/templates/factory/actions/list-factory-automations.ts +2 -1
  89. package/corpus/templates/factory/actions/list-triage-items.ts +24 -2
  90. package/corpus/templates/factory/actions/poll-github-sources.ts +60 -0
  91. package/corpus/templates/factory/actions/poll-sentry-errors.ts +39 -0
  92. package/corpus/templates/factory/actions/poll-slack-channel.ts +45 -1
  93. package/corpus/templates/factory/actions/run-factory-automation.ts +1 -1
  94. package/corpus/templates/factory/actions/save-factory-automation.ts +2 -2
  95. package/corpus/templates/factory/actions/start-builder-for-item.ts +51 -0
  96. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +685 -0
  97. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +6 -0
  98. package/corpus/templates/factory/app/i18n/en-US.ts +25 -0
  99. package/corpus/templates/factory/app/routes/factory.tsx +203 -118
  100. package/corpus/templates/factory/changelog/2026-08-08-scheduler-health-moves-to-settings.md +6 -0
  101. package/corpus/templates/factory/server/db/schema.ts +37 -0
  102. package/corpus/templates/factory/server/lib/require-factory-automation.ts +5 -1
  103. package/corpus/templates/factory/server/plugins/factory-migrations.ts +29 -0
  104. package/corpus/templates/factory/server/triage/audit.ts +79 -0
  105. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +115 -68
  106. package/corpus/templates/forms/.agents/skills/turn-into-app/SKILL.md +18 -6
  107. package/corpus/templates/forms/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  108. package/corpus/templates/forms/app/i18n/index.ts +14 -29
  109. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +115 -68
  110. package/corpus/templates/macros/.agents/skills/turn-into-app/SKILL.md +18 -6
  111. package/corpus/templates/macros/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  112. package/corpus/templates/macros/app/i18n/index.ts +14 -29
  113. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +115 -68
  114. package/corpus/templates/mail/.agents/skills/turn-into-app/SKILL.md +18 -6
  115. package/corpus/templates/mail/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  116. package/corpus/templates/mail/app/i18n/index.ts +14 -29
  117. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +9 -0
  118. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +115 -68
  119. package/corpus/templates/plan/.agents/skills/turn-into-app/SKILL.md +18 -6
  120. package/corpus/templates/plan/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  121. package/corpus/templates/plan/app/components/plan/wireframe/Wireframe.tsx +7 -7
  122. package/corpus/templates/plan/app/i18n/index.ts +14 -29
  123. package/corpus/templates/plan/app/lib/plan-document-title.ts +3 -1
  124. package/corpus/templates/plan/app/root.tsx +1 -0
  125. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +115 -68
  126. package/corpus/templates/slides/.agents/skills/turn-into-app/SKILL.md +18 -6
  127. package/corpus/templates/slides/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  128. package/corpus/templates/slides/actions/analyze-brand-assets.ts +15 -15
  129. package/corpus/templates/slides/actions/import-code.ts +2 -43
  130. package/corpus/templates/slides/app/i18n/index.ts +14 -29
  131. package/corpus/templates/slides/server/routes/api/preview-images.get.ts +4 -1
  132. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +9 -0
  133. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +115 -68
  134. package/corpus/templates/tasks/.agents/skills/turn-into-app/SKILL.md +18 -6
  135. package/corpus/templates/tasks/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  136. package/corpus/templates/tasks/app/components/layout/HeaderActions.tsx +1 -84
  137. package/corpus/templates/tasks/app/hooks/use-mobile.tsx +1 -21
  138. package/corpus/templates/tasks/app/i18n/index.ts +14 -29
  139. package/dist/agent/engine/ai-sdk-engine.js +2 -1
  140. package/dist/agent/engine/builder-engine.d.ts +11 -1
  141. package/dist/agent/engine/builder-engine.js +11 -4
  142. package/dist/agent/engine/openai-compatible-endpoint.d.ts +2 -0
  143. package/dist/agent/engine/openai-compatible-endpoint.js +5 -1
  144. package/dist/agent/engine/provider-endpoint-validation.d.ts +9 -0
  145. package/dist/agent/engine/provider-endpoint-validation.js +26 -0
  146. package/dist/agent/engine/provider-env-vars.d.ts +1 -1
  147. package/dist/agent/engine/provider-env-vars.js +1 -1
  148. package/dist/agent/engine/registry.d.ts +8 -6
  149. package/dist/agent/engine/registry.js +37 -24
  150. package/dist/agent/tool-search.d.ts +1 -0
  151. package/dist/agent/tool-search.js +17 -1
  152. package/dist/automations/service.js +4 -10
  153. package/dist/brand-kit/brand-signals.d.ts +13 -0
  154. package/dist/brand-kit/brand-signals.js +15 -0
  155. package/dist/brand-kit/index.d.ts +2 -2
  156. package/dist/brand-kit/index.js +1 -1
  157. package/dist/chat-threads/store.d.ts +2 -0
  158. package/dist/chat-threads/store.js +1 -1
  159. package/dist/cli/agent-plugin.d.ts +5 -2
  160. package/dist/cli/agent-plugin.js +17 -9
  161. package/dist/cli/code-agent-executor.js +25 -5
  162. package/dist/cli/code-agent-mcp-config.d.ts +21 -0
  163. package/dist/cli/code-agent-mcp-config.js +103 -0
  164. package/dist/cli/plan-blocks.d.ts +3 -18
  165. package/dist/cli/plan-blocks.js +2 -95
  166. package/dist/cli/plan-publish-store.d.ts +2 -61
  167. package/dist/cli/plan-publish-store.js +2 -127
  168. package/dist/cli/skills-content/connection.d.ts +1 -1
  169. package/dist/cli/skills-content/connection.js +1 -52
  170. package/dist/cli/skills-content/visual-recap-skill.d.ts +1 -1
  171. package/dist/cli/skills-content/visual-recap-skill.js +1 -553
  172. package/dist/client/NewWorkspaceAppFlow.js +4 -1
  173. package/dist/client/agent-chat/index.d.ts +4 -1
  174. package/dist/client/agent-chat/index.js +4 -1
  175. package/dist/client/agent-engine-key.d.ts +14 -4
  176. package/dist/client/agent-engine-key.js +51 -5
  177. package/dist/client/agent-page/AgentTabsPage.d.ts +1 -0
  178. package/dist/client/agent-page/AgentTabsPage.js +4 -3
  179. package/dist/client/agent-provider-catalog.d.ts +20 -0
  180. package/dist/client/agent-provider-catalog.js +100 -0
  181. package/dist/client/app-providers.d.ts +3 -1
  182. package/dist/client/app-providers.js +50 -5
  183. package/dist/client/blocks/index.d.ts +1 -0
  184. package/dist/client/blocks/index.js +1 -0
  185. package/dist/client/chat/run-recovery.js +4 -48
  186. package/dist/client/chat/runtime.js +63 -0
  187. package/dist/client/chat-first/agents-pane.d.ts +2 -0
  188. package/dist/client/chat-first/agents-pane.js +6 -0
  189. package/dist/client/chat-first/app-pane.d.ts +2 -0
  190. package/dist/client/chat-first/app-pane.js +6 -0
  191. package/dist/client/chat-first/apps-rail.d.ts +2 -0
  192. package/dist/client/chat-first/apps-rail.js +103 -0
  193. package/dist/client/chat-first/browser-pane.d.ts +2 -0
  194. package/dist/client/chat-first/browser-pane.js +64 -0
  195. package/dist/client/chat-first/chat-history.d.ts +12 -0
  196. package/dist/client/chat-first/chat-history.js +10 -0
  197. package/dist/client/chat-first/copy.d.ts +2 -0
  198. package/dist/client/chat-first/copy.js +117 -0
  199. package/dist/client/chat-first/index.d.ts +13 -0
  200. package/dist/client/chat-first/index.js +12 -0
  201. package/dist/client/chat-first/primary-nav.d.ts +8 -0
  202. package/dist/client/chat-first/primary-nav.js +6 -0
  203. package/dist/client/chat-first/session-watch-pane.d.ts +2 -0
  204. package/dist/client/chat-first/session-watch-pane.js +9 -0
  205. package/dist/client/chat-first/surface-panel.d.ts +9 -0
  206. package/dist/client/chat-first/surface-panel.js +9 -0
  207. package/dist/client/chat-first/surface-tabs.d.ts +9 -0
  208. package/dist/client/chat-first/surface-tabs.js +74 -0
  209. package/dist/client/chat-first/types.d.ts +74 -0
  210. package/dist/client/chat-first/types.js +1 -0
  211. package/dist/client/chat-first-agent-activity.d.ts +11 -0
  212. package/dist/client/chat-first-agent-activity.js +51 -0
  213. package/dist/client/chat-first-surface-panel-toggle.d.ts +5 -0
  214. package/dist/client/chat-first-surface-panel-toggle.js +6 -0
  215. package/dist/client/chat-first.d.ts +208 -0
  216. package/dist/client/chat-first.js +817 -0
  217. package/dist/client/extensions/ExtensionViewer.js +8 -1
  218. package/dist/client/i18n.d.ts +14 -0
  219. package/dist/client/i18n.js +18 -0
  220. package/dist/client/resources/McpIntegrationDialog.js +3 -2
  221. package/dist/client/resources/McpServerDetail.js +6 -11
  222. package/dist/client/resources/index.d.ts +1 -0
  223. package/dist/client/resources/index.js +1 -0
  224. package/dist/client/resources/use-mcp-servers.d.ts +20 -0
  225. package/dist/client/resources/use-mcp-servers.js +82 -46
  226. package/dist/client/settings/ProviderSetupForm.d.ts +21 -0
  227. package/dist/client/settings/ProviderSetupForm.js +145 -0
  228. package/dist/client/settings/SettingsPanel.js +52 -49
  229. package/dist/client/settings/index.d.ts +3 -0
  230. package/dist/client/settings/index.js +3 -0
  231. package/dist/coding-tools/run-code.d.ts +5 -0
  232. package/dist/coding-tools/run-code.js +196 -36
  233. package/dist/coding-tools/tool-orchestration.d.ts +10 -0
  234. package/dist/coding-tools/tool-orchestration.js +107 -0
  235. package/dist/collab/routes.d.ts +1 -1
  236. package/dist/collab/struct-routes.d.ts +1 -1
  237. package/dist/jobs/background-automation-runner.js +19 -2
  238. package/dist/jobs/frontmatter.d.ts +9 -0
  239. package/dist/jobs/frontmatter.js +16 -0
  240. package/dist/jobs/scheduler-health.d.ts +20 -0
  241. package/dist/jobs/scheduler-health.js +86 -1
  242. package/dist/jobs/scheduler.js +46 -9
  243. package/dist/jobs/tools.d.ts +1 -1
  244. package/dist/jobs/tools.js +2 -7
  245. package/dist/localization/default-messages.d.ts +20 -0
  246. package/dist/localization/default-messages.js +25 -5
  247. package/dist/mcp-client/routes.d.ts +3 -0
  248. package/dist/mcp-client/routes.js +14 -0
  249. package/dist/notifications/routes.d.ts +1 -1
  250. package/dist/observability/routes.d.ts +3 -3
  251. package/dist/onboarding/app-profile.js +1 -1
  252. package/dist/provider-api/actions/custom-provider-registration.d.ts +8 -8
  253. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  254. package/dist/scripts/agent-engines/test-agent-engine.js +34 -10
  255. package/dist/secrets/routes.d.ts +6 -6
  256. package/dist/server/agent-chat/run-code-tools.d.ts +1 -1
  257. package/dist/server/agent-chat/run-code-tools.js +3 -1
  258. package/dist/server/agent-chat-plugin.js +6 -6
  259. package/dist/server/agent-engine-api-key-route.js +43 -12
  260. package/dist/server/agents-bundle.d.ts +2 -0
  261. package/dist/server/agents-bundle.js +32 -2
  262. package/dist/server/auth.js +21 -5
  263. package/dist/server/credential-provider.d.ts +8 -2
  264. package/dist/server/credential-provider.js +14 -9
  265. package/dist/server/design-token-utils.d.ts +18 -0
  266. package/dist/server/design-token-utils.js +31 -0
  267. package/dist/server/onboarding-html.js +22 -2
  268. package/dist/server/transcribe-voice.d.ts +1 -1
  269. package/dist/shared/chat-first-app-creation.d.ts +19 -0
  270. package/dist/shared/chat-first-app-creation.js +75 -0
  271. package/dist/shared/document-title.d.ts +7 -0
  272. package/dist/shared/document-title.js +29 -0
  273. package/dist/shared/index.d.ts +2 -0
  274. package/dist/shared/index.js +2 -0
  275. package/dist/styles/chat-history-list.css +16 -0
  276. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  277. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  278. package/dist/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  279. package/dist/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  280. package/dist/templates/chat/app/i18n/index.ts +14 -29
  281. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
  282. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
  283. package/dist/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
  284. package/dist/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  285. package/dist/templates/default/app/i18n/index.ts +14 -29
  286. package/dist/templates/default/react-router.config.ts +18 -0
  287. package/dist/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
  288. package/dist/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  289. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
  290. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
  291. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
  292. package/dist/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
  293. package/dist/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  294. package/dist/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
  295. package/dist/triggers/dispatcher.js +1 -8
  296. package/docs/content/environment-variables.mdx +39 -38
  297. package/package.json +5 -4
  298. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +9 -0
  299. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +115 -68
  300. package/src/templates/chat/.agents/skills/turn-into-app/SKILL.md +18 -6
  301. package/src/templates/chat/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  302. package/src/templates/chat/app/i18n/index.ts +14 -29
  303. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +9 -0
  304. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +115 -68
  305. package/src/templates/default/.agents/skills/turn-into-app/SKILL.md +18 -6
  306. package/src/templates/default/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  307. package/src/templates/default/app/i18n/index.ts +14 -29
  308. package/src/templates/default/react-router.config.ts +18 -0
  309. package/src/templates/headless/.agents/skills/turn-into-app/SKILL.md +18 -6
  310. package/src/templates/headless/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  311. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +9 -0
  312. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +22 -9
  313. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +115 -68
  314. package/src/templates/workspace-core/.agents/skills/turn-into-app/SKILL.md +18 -6
  315. package/src/templates/workspace-core/.agents/skills/turn-into-app/references/fresh-project.md +8 -1
  316. package/src/templates/workspace-core/.agents/skills/workspace-conventions/SKILL.md +7 -0
  317. package/corpus/templates/plan/app/components/plan/wireframe/sanitize-html.ts +0 -343
@@ -1,343 +0,0 @@
1
- /*
2
- * Render-layer sanitizer for model-authored wireframe HTML.
3
- *
4
- * The HTML artboard injects model HTML via dangerouslySetInnerHTML into the LIVE
5
- * page DOM (it can't be iframe-sandboxed because the rough overlay must measure
6
- * the laid-out elements). The schema's regex guard is necessary but not
7
- * sufficient — obfuscated schemes (java\tscript:, javascript:) slip past
8
- * string matching. This neutralizes the html at the render point using the
9
- * browser's OWN parser/URL normalization, which decodes entities and collapses
10
- * whitespace, so obfuscation can't survive:
11
- * - drops dangerous elements (script/style/iframe/object/embed/...);
12
- * - strips every on* event-handler attribute;
13
- * - removes url attributes whose RESOLVED scheme isn't safe;
14
- * - removes inline styles carrying expression()/javascript:/data:text/html.
15
- * Defense-in-depth: stored content should also be sanitized server-side, but
16
- * this guarantees the live DOM never carries an executable payload.
17
- */
18
-
19
- const BLOCKED_TAGS =
20
- "script,style,iframe,object,embed,link,meta,base,form,noscript,frame,frameset,applet,marquee,portal";
21
- const DIAGRAM_BLOCKED_TAGS = `${BLOCKED_TAGS},math,foreignObject,foreignobject`;
22
-
23
- const URL_ATTRS = new Set([
24
- "href",
25
- "src",
26
- "xlink:href",
27
- "srcdoc",
28
- "action",
29
- "formaction",
30
- "background",
31
- "poster",
32
- "data",
33
- "ping",
34
- ]);
35
-
36
- const SAFE_SCHEMES = new Set(["http:", "https:", "mailto:", "tel:", "ftp:"]);
37
-
38
- const WHITESPACE = /\s+/g;
39
- const HAS_SCHEME = /^[a-z][a-z0-9+.-]*:/i;
40
- const SAFE_DATA_IMAGE = /^data:image\/(png|jpe?g|gif|webp);/i;
41
-
42
- function isSafeUrl(value: string): boolean {
43
- // Strip whitespace for scheme detection ONLY (the browser collapses these when
44
- // resolving too, so obfuscated schemes like "java\tscript:" can't hide). The
45
- // original attribute is left untouched unless we decide to drop it.
46
- const v = (value || "").replace(WHITESPACE, "");
47
- if (
48
- v === "" ||
49
- v.startsWith("#") ||
50
- v.startsWith("/") ||
51
- v.startsWith("./") ||
52
- v.startsWith("../")
53
- ) {
54
- return true;
55
- }
56
- if (!HAS_SCHEME.test(v)) return true; // no scheme => relative, safe
57
- try {
58
- const a = document.createElement("a");
59
- a.href = v; // browser decodes the scheme + normalizes
60
- const proto = a.protocol.toLowerCase();
61
- // Allow only safe raster data images; block data:image/svg+xml (can script)
62
- // and data:text/html.
63
- if (proto === "data:") return SAFE_DATA_IMAGE.test(a.href);
64
- return SAFE_SCHEMES.has(proto);
65
- } catch {
66
- return false;
67
- }
68
- }
69
-
70
- const DANGEROUS_STYLE =
71
- /(expression\s*\(|javascript:|vbscript:|url\s*\(\s*['"]?\s*(?:javascript|vbscript|data:text\/html))/i;
72
- const DANGEROUS_CSS =
73
- /(@(?:import|font-face|keyframes|page|namespace|charset)\b|expression\s*\(|javascript:|vbscript:|data:text\/html|data:image\/svg\+xml|<\/?\s*(?:script|style)\b)/i;
74
- const DANGEROUS_VIEWPORT_CSS =
75
- /(?:^|[;{\s])position\s*:\s*(?:fixed|sticky)\b|(?:^|[;{\s])z-index\s*:\s*[1-9]\d{4,}\b/i;
76
-
77
- function decodeCssSafetyEscapes(value: string): string {
78
- return value.replace(/\\([0-9a-fA-F]{1,6}\s?|.)/g, (_match, escaped) => {
79
- const hex = String(escaped).match(/^[0-9a-fA-F]{1,6}/)?.[0];
80
- if (hex) {
81
- const point = Number.parseInt(hex, 16);
82
- return Number.isFinite(point) ? String.fromCodePoint(point) : "";
83
- }
84
- return String(escaped)[0] ?? "";
85
- });
86
- }
87
-
88
- function cssSafetyText(value: string): string {
89
- return decodeCssSafetyEscapes(value)
90
- .toLowerCase()
91
- .replace(/[\u0000-\u0020]+/g, "");
92
- }
93
-
94
- type SanitizeElementOptions = {
95
- stripRuntimeDirectives?: boolean;
96
- stripWireframeThemeClasses?: boolean;
97
- };
98
-
99
- const TAILWIND_THEME_COLORS =
100
- /^(?:bg|text|border|ring|outline|divide|placeholder|from|via|to|accent|caret|decoration|fill|stroke)-(?:inherit|current|transparent|black|white|slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose)(?:-\d{2,3})?(?:\/[\d.]+)?$/;
101
- const TAILWIND_ARBITRARY_THEME_COLOR =
102
- /^(?:bg|text|border|ring|outline|divide|placeholder|from|via|to|accent|caret|decoration|fill|stroke)-\[/;
103
- const TAILWIND_SHADOW = /^shadow(?:$|-)/;
104
-
105
- function baseClassName(className: string): string {
106
- let bracketDepth = 0;
107
- let lastVariantSeparator = -1;
108
- for (let index = 0; index < className.length; index += 1) {
109
- const char = className[index];
110
- if (char === "[") bracketDepth += 1;
111
- if (char === "]") bracketDepth = Math.max(0, bracketDepth - 1);
112
- if (char === ":" && bracketDepth === 0) lastVariantSeparator = index;
113
- }
114
- return className.slice(lastVariantSeparator + 1);
115
- }
116
-
117
- function isWireframeThemeClass(className: string): boolean {
118
- const base = baseClassName(className);
119
- return (
120
- TAILWIND_THEME_COLORS.test(base) ||
121
- TAILWIND_ARBITRARY_THEME_COLOR.test(base) ||
122
- TAILWIND_SHADOW.test(base)
123
- );
124
- }
125
-
126
- function stripWireframeThemeClasses(value: string): string {
127
- return value
128
- .split(/\s+/)
129
- .filter(Boolean)
130
- .filter((className) => !isWireframeThemeClass(className))
131
- .join(" ");
132
- }
133
-
134
- /** Conservative no-DOM fallback for any non-browser code path (SSR). */
135
- function fallbackStrip(html: string, options?: SanitizeElementOptions): string {
136
- // Drop the whole url attribute if its value (whitespace/control-stripped)
137
- // carries a dangerous scheme. Mirrors the DOM path for the rare no-DOMParser
138
- // case; entity-obfuscation isn't decoded here (the live DOM path handles it).
139
- const stripScheme = (m: string, dq?: string, sq?: string, uq?: string) => {
140
- const v = (dq ?? sq ?? uq ?? "").replace(/[\s\u0000-\u001f]+/g, "");
141
- return /^(?:javascript|vbscript):|^data:text\/html/i.test(v) ? "" : m;
142
- };
143
- let out = html
144
- .replace(
145
- /<\/?(?:script|style|iframe|object|embed|link|meta|base|form|noscript|frame|frameset|applet|marquee|portal)\b[^>]*>/gi,
146
- "",
147
- )
148
- .replace(/\son[a-z][\w:-]*\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi, "")
149
- .replace(
150
- /\s(?:href|src|xlink:href|action|formaction|poster|background|data|ping)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi,
151
- stripScheme,
152
- )
153
- .replace(/\sstyle\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, (m) =>
154
- DANGEROUS_STYLE.test(m) ? "" : m,
155
- );
156
- if (options?.stripWireframeThemeClasses) {
157
- out = out.replace(
158
- /\sclass\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi,
159
- (_match, doubleQuoted, singleQuoted, bare) => {
160
- const next = stripWireframeThemeClasses(
161
- doubleQuoted ?? singleQuoted ?? bare ?? "",
162
- );
163
- return next ? ` class="${next}"` : "";
164
- },
165
- );
166
- }
167
- return out;
168
- }
169
-
170
- export function sanitizeWireframeHtml(
171
- html: string | undefined,
172
- options?: { preserveThemeClasses?: boolean },
173
- ): string {
174
- if (!html) return "";
175
- const stripWireframeThemeClasses = !options?.preserveThemeClasses;
176
- if (typeof DOMParser === "undefined" || typeof document === "undefined") {
177
- return fallbackStrip(html, { stripWireframeThemeClasses });
178
- }
179
- const doc = new DOMParser().parseFromString(html, "text/html");
180
- doc.querySelectorAll(BLOCKED_TAGS).forEach((el) => el.remove());
181
- sanitizeElementAttributes(doc.body, { stripWireframeThemeClasses });
182
- return doc.body.innerHTML;
183
- }
184
-
185
- export function sanitizeDiagramHtml(html: string | undefined): string {
186
- if (!html) return "";
187
- if (typeof DOMParser === "undefined" || typeof document === "undefined") {
188
- return fallbackStrip(html)
189
- .replace(/<\/?\s*(?:math|foreignObject|foreignobject)\b[^>]*>/gi, "")
190
- .replace(
191
- /\s(?:@[\w:.-]+|x-on:[\w:.-]+|:on[\w:.-]+|x-bind:on[\w:.-]+|:style|x-bind:style)\s*=\s*("[^"]*"|'[^']*'|[^\s>]+)/gi,
192
- "",
193
- );
194
- }
195
- const doc = new DOMParser().parseFromString(html, "text/html");
196
- doc.querySelectorAll(DIAGRAM_BLOCKED_TAGS).forEach((el) => el.remove());
197
- sanitizeElementAttributes(doc.body, { stripRuntimeDirectives: true });
198
- return doc.body.innerHTML;
199
- }
200
-
201
- export function sanitizeWireframeCss(css: string | undefined): string {
202
- if (!css) return "";
203
- return css
204
- .split("\n")
205
- .filter((line) => {
206
- const decoded = decodeCssSafetyEscapes(line);
207
- const compact = cssSafetyText(line);
208
- return !(
209
- DANGEROUS_CSS.test(line) ||
210
- DANGEROUS_CSS.test(decoded) ||
211
- DANGEROUS_VIEWPORT_CSS.test(decoded) ||
212
- /(?:javascript|vbscript):|data:(?:text\/html|image\/svg\+xml)|expression\(|url\(['"]?(?:javascript|vbscript|data:(?:text\/html|image\/svg\+xml))/.test(
213
- compact,
214
- )
215
- );
216
- })
217
- .join("\n")
218
- .replace(/\bjava\s*script\s*:/gi, "")
219
- .replace(/\bvb\s*script\s*:/gi, "")
220
- .replace(/\bdata\s*:\s*(?:text\/html|image\/svg\+xml)/gi, "");
221
- }
222
-
223
- export function scopeDesignCss(css: string, scopeSelector: string): string {
224
- if (!css.trim()) return "";
225
- return css.replace(
226
- /(^|[{}])\s*([^@{}][^{}]*)\{/g,
227
- (_match, boundary: string, selectors: string) => {
228
- const scoped = splitSelectorList(selectors)
229
- .map((selector) => selector.trim())
230
- .filter(Boolean)
231
- .map((selector) => {
232
- if (selector.startsWith(scopeSelector)) return selector;
233
- if (
234
- selector === ":root" ||
235
- selector === "html" ||
236
- selector === "body"
237
- )
238
- return scopeSelector;
239
- return `${scopeSelector} ${selector}`;
240
- })
241
- .join(", ");
242
- return `${boundary} ${scoped} {`;
243
- },
244
- );
245
- }
246
-
247
- function splitSelectorList(selectors: string): string[] {
248
- const parts: string[] = [];
249
- let current = "";
250
- let parenDepth = 0;
251
- let bracketDepth = 0;
252
- let quote: '"' | "'" | null = null;
253
- let escaped = false;
254
-
255
- for (const char of selectors) {
256
- current += char;
257
- if (escaped) {
258
- escaped = false;
259
- continue;
260
- }
261
- if (char === "\\") {
262
- escaped = true;
263
- continue;
264
- }
265
- if (quote) {
266
- if (char === quote) quote = null;
267
- continue;
268
- }
269
- if (char === '"' || char === "'") {
270
- quote = char;
271
- continue;
272
- }
273
- if (char === "[") {
274
- bracketDepth += 1;
275
- continue;
276
- }
277
- if (char === "]") {
278
- bracketDepth = Math.max(0, bracketDepth - 1);
279
- continue;
280
- }
281
- if (char === "(") {
282
- parenDepth += 1;
283
- continue;
284
- }
285
- if (char === ")") {
286
- parenDepth = Math.max(0, parenDepth - 1);
287
- continue;
288
- }
289
- if (char === "," && parenDepth === 0 && bracketDepth === 0) {
290
- parts.push(current.slice(0, -1));
291
- current = "";
292
- }
293
- }
294
-
295
- parts.push(current);
296
- return parts;
297
- }
298
-
299
- function sanitizeElementAttributes(
300
- root: ParentNode,
301
- options?: SanitizeElementOptions,
302
- ) {
303
- root.querySelectorAll<HTMLElement>("*").forEach((el) => {
304
- for (const attr of Array.from(el.attributes)) {
305
- const name = attr.name.toLowerCase();
306
- if (name.startsWith("on")) {
307
- el.removeAttribute(attr.name);
308
- continue;
309
- }
310
- if (
311
- options?.stripRuntimeDirectives &&
312
- (name.startsWith("@") ||
313
- name.startsWith("x-on:") ||
314
- name.startsWith(":on") ||
315
- name.startsWith("x-bind:on") ||
316
- name === ":style" ||
317
- name === "x-bind:style")
318
- ) {
319
- el.removeAttribute(attr.name);
320
- continue;
321
- }
322
- if (URL_ATTRS.has(name) && !isSafeUrl(attr.value)) {
323
- el.removeAttribute(attr.name);
324
- continue;
325
- }
326
- if (name === "style" && DANGEROUS_STYLE.test(attr.value)) {
327
- el.removeAttribute(attr.name);
328
- continue;
329
- }
330
- if (name === "class" && options?.stripWireframeThemeClasses) {
331
- const next = stripWireframeThemeClasses(attr.value);
332
- if (next) {
333
- el.setAttribute(attr.name, next);
334
- } else {
335
- el.removeAttribute(attr.name);
336
- }
337
- }
338
- }
339
- if (el instanceof HTMLTemplateElement) {
340
- sanitizeElementAttributes(el.content, options);
341
- }
342
- });
343
- }