@agent-native/core 0.113.0 → 0.114.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 (1638) hide show
  1. package/agent-native.eject.json +164 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +20 -0
  4. package/corpus/core/README.md +61 -174
  5. package/corpus/core/agent-native.eject.json +164 -0
  6. package/corpus/core/docs/content/agent-native-toolkit.mdx +38 -0
  7. package/corpus/core/docs/content/package-lifecycle.mdx +54 -4
  8. package/corpus/core/package.json +15 -2
  9. package/corpus/core/src/cli/eject.ts +1594 -0
  10. package/corpus/core/src/cli/index.ts +16 -0
  11. package/corpus/core/src/client/build-compatibility.ts +77 -0
  12. package/corpus/core/src/client/index.ts +4 -0
  13. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +8 -2
  14. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +7 -2
  15. package/corpus/core/src/client/resources/ResourcesPanel.tsx +17 -3
  16. package/corpus/core/src/client/resources/index.ts +19 -0
  17. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +9 -1
  18. package/corpus/core/src/client/resources/runtime.ts +1 -0
  19. package/corpus/core/src/client/route-chunk-recovery/index.ts +1 -0
  20. package/corpus/core/src/client/setup-connections/catalog.ts +6 -0
  21. package/corpus/core/src/client/setup-connections/index.ts +1 -0
  22. package/corpus/core/src/client/setup-connections/runtime.ts +1 -0
  23. package/corpus/core/src/client/use-action.ts +32 -1
  24. package/corpus/core/src/connections/catalog.ts +41 -24
  25. package/corpus/core/src/connections/index.ts +1 -0
  26. package/corpus/core/src/connections/runtime.ts +1 -0
  27. package/corpus/core/src/deploy/build.ts +4 -1
  28. package/corpus/core/src/eject/provider-api-definitions.ts +193 -0
  29. package/corpus/core/src/eject/remote-mcp-presets.ts +137 -0
  30. package/corpus/core/src/eject/setup-readiness-ui.tsx +29 -0
  31. package/corpus/core/src/eject/workspace-connections.ts +92 -0
  32. package/corpus/core/src/index.ts +1 -0
  33. package/corpus/core/src/integrations/adapter-overrides.ts +12 -0
  34. package/corpus/core/src/integrations/eject/messaging-adapters.ts +85 -0
  35. package/corpus/core/src/integrations/index.ts +5 -1
  36. package/corpus/core/src/integrations/plugin.ts +34 -12
  37. package/corpus/core/src/integrations/runtime.ts +1 -0
  38. package/corpus/core/src/integrations/types.ts +3 -1
  39. package/corpus/core/src/org/context.ts +56 -30
  40. package/corpus/core/src/package-lifecycle/eject-manifest.ts +345 -0
  41. package/corpus/core/src/package-lifecycle/index.ts +1 -0
  42. package/corpus/core/src/provider-api/index.ts +46 -12
  43. package/corpus/core/src/provider-api/runtime.ts +1 -0
  44. package/corpus/core/src/server/action-routes.ts +52 -2
  45. package/corpus/core/src/server/auth-plugin.ts +9 -4
  46. package/corpus/core/src/server/better-auth-instance.ts +5 -1
  47. package/corpus/core/src/setup-connections/index.ts +1 -0
  48. package/corpus/core/src/shared/mcp-embed-headers.ts +1 -1
  49. package/corpus/core/src/shared/merge-by-id.ts +14 -0
  50. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  51. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  52. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  53. package/corpus/core/src/templates/default/AGENTS.md +6 -5
  54. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  55. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  56. package/corpus/core/src/templates/headless/AGENTS.md +5 -4
  57. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  58. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  59. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  60. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  61. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -4
  62. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -4
  63. package/corpus/core/src/vite/client.ts +42 -2
  64. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  65. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +9 -6
  66. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  67. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +9 -6
  68. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  69. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +9 -6
  70. package/corpus/templates/brain/actions/remediate-legacy-capture-audiences.ts +167 -0
  71. package/corpus/templates/brain/app/lib/brain-chat-readiness.ts +6 -0
  72. package/corpus/templates/brain/app/routes/_index.tsx +8 -0
  73. package/corpus/templates/brain/app/routes.ts +1 -0
  74. package/corpus/templates/brain/changelog/2026-07-19-ask-starts-immediately-when-builder-s-managed-ai-connection-.md +6 -0
  75. package/corpus/templates/brain/changelog/2026-07-19-slack-and-granola-backfills-now-process-captures-concurrentl.md +6 -0
  76. package/corpus/templates/brain/changelog/2026-07-19-source-review-settings-now-control-knowledge-approval.md +6 -0
  77. package/corpus/templates/brain/changelog/2026-07-19-the-manage-agent-page-now-opens-correctly-from-brain-navigat.md +6 -0
  78. package/corpus/templates/brain/server/db/schema.ts +3 -0
  79. package/corpus/templates/brain/server/lib/brain.ts +41 -2
  80. package/corpus/templates/brain/server/lib/connectors.ts +379 -113
  81. package/corpus/templates/brain/server/lib/meeting-audience.ts +38 -0
  82. package/corpus/templates/brain/server/plugins/db.ts +10 -0
  83. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +6 -4
  84. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  85. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +9 -6
  86. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  87. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  88. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  89. package/corpus/templates/chat/AGENTS.md +3 -2
  90. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  91. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +9 -6
  92. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  93. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +9 -6
  94. package/corpus/templates/content/AGENTS.md +2 -0
  95. package/corpus/templates/content/actions/_content-database-personal-view.ts +49 -5
  96. package/corpus/templates/content/actions/_content-document-access.ts +21 -0
  97. package/corpus/templates/content/actions/_content-favorites.ts +91 -0
  98. package/corpus/templates/content/actions/_content-files.ts +79 -23
  99. package/corpus/templates/content/actions/_content-sidebar-state.ts +24 -0
  100. package/corpus/templates/content/actions/_content-space-access.ts +15 -17
  101. package/corpus/templates/content/actions/_content-space-catalog-guards.ts +20 -0
  102. package/corpus/templates/content/actions/_content-spaces.ts +364 -167
  103. package/corpus/templates/content/actions/_database-source-utils.ts +8 -0
  104. package/corpus/templates/content/actions/_database-utils.ts +249 -15
  105. package/corpus/templates/content/actions/_delete-content-space.ts +84 -0
  106. package/corpus/templates/content/actions/_files-system-properties.ts +499 -0
  107. package/corpus/templates/content/actions/_local-file-documents.ts +0 -1
  108. package/corpus/templates/content/actions/_property-utils.ts +18 -9
  109. package/corpus/templates/content/actions/bind-content-database-source-field.ts +3 -0
  110. package/corpus/templates/content/actions/configure-document-property.ts +3 -0
  111. package/corpus/templates/content/actions/create-content-database.ts +2 -2
  112. package/corpus/templates/content/actions/create-content-space.ts +34 -0
  113. package/corpus/templates/content/actions/create-document.ts +4 -1
  114. package/corpus/templates/content/actions/delete-content-space.ts +19 -0
  115. package/corpus/templates/content/actions/delete-database-items.ts +28 -1
  116. package/corpus/templates/content/actions/delete-document-property.ts +3 -0
  117. package/corpus/templates/content/actions/delete-document.ts +39 -2
  118. package/corpus/templates/content/actions/duplicate-database-item.ts +6 -0
  119. package/corpus/templates/content/actions/duplicate-database-items.ts +6 -0
  120. package/corpus/templates/content/actions/duplicate-document-property.ts +3 -0
  121. package/corpus/templates/content/actions/get-content-database.ts +11 -2
  122. package/corpus/templates/content/actions/get-content-sidebar-state.ts +23 -0
  123. package/corpus/templates/content/actions/get-document.ts +32 -7
  124. package/corpus/templates/content/actions/import-content-source.ts +33 -1
  125. package/corpus/templates/content/actions/list-content-spaces.ts +34 -2
  126. package/corpus/templates/content/actions/list-documents.ts +39 -7
  127. package/corpus/templates/content/actions/reorder-document-property.ts +9 -0
  128. package/corpus/templates/content/actions/set-document-property.ts +41 -23
  129. package/corpus/templates/content/actions/share-local-file-document.ts +15 -0
  130. package/corpus/templates/content/actions/submit-content-database-form.ts +7 -0
  131. package/corpus/templates/content/actions/sync-local-folder-source.ts +14 -0
  132. package/corpus/templates/content/actions/update-content-database-view.ts +1 -0
  133. package/corpus/templates/content/actions/update-content-sidebar-state.ts +27 -0
  134. package/corpus/templates/content/actions/update-document.ts +158 -66
  135. package/corpus/templates/content/app/components/EmptyState.tsx +4 -57
  136. package/corpus/templates/content/app/components/editor/CommentsSidebar.tsx +8 -1
  137. package/corpus/templates/content/app/components/editor/DocumentEditor.tsx +519 -178
  138. package/corpus/templates/content/app/components/editor/DocumentInfoPanel.tsx +39 -0
  139. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +1 -1
  140. package/corpus/templates/content/app/components/editor/DocumentToolbar.tsx +266 -7
  141. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +430 -152
  142. package/corpus/templates/content/app/components/editor/database/sidebar.tsx +467 -66
  143. package/corpus/templates/content/app/components/editor/database/view-config.ts +9 -3
  144. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +720 -196
  145. package/corpus/templates/content/app/components/sidebar/DocumentTreeItem.tsx +173 -1
  146. package/corpus/templates/content/app/components/sidebar/document-sidebar-sections.ts +1 -1
  147. package/corpus/templates/content/app/components/sidebar/select-content-space.ts +91 -16
  148. package/corpus/templates/content/app/entry.client.tsx +5 -1
  149. package/corpus/templates/content/app/hooks/use-content-database.ts +84 -3
  150. package/corpus/templates/content/app/hooks/use-content-spaces.ts +60 -2
  151. package/corpus/templates/content/app/hooks/use-create-page.ts +30 -0
  152. package/corpus/templates/content/app/hooks/use-documents.ts +270 -19
  153. package/corpus/templates/content/app/i18n-data.ts +243 -20
  154. package/corpus/templates/content/app/lib/local-folder-picker-safety.ts +54 -0
  155. package/corpus/templates/content/app/lib/local-folder-picker-support.ts +18 -0
  156. package/corpus/templates/content/app/routes/_app.favorites.tsx +30 -0
  157. package/corpus/templates/content/app/routes/_app.local-files.tsx +18 -6
  158. package/corpus/templates/content/changelog/2026-07-17-workspace-files-now-stay-in-a-loading-state-until-automatic-.md +6 -0
  159. package/corpus/templates/content/changelog/2026-07-17-workspace-switching-now-opens-the-selected-files-database-pr.md +6 -0
  160. package/corpus/templates/content/changelog/2026-07-17-workspaces-now-expand-above-their-own-files-list-without-dup.md +6 -0
  161. package/corpus/templates/content/changelog/2026-07-18-create-named-workspaces-each-with-its-own-private-files-data.md +6 -0
  162. package/corpus/templates/content/changelog/2026-07-18-favorites-align-with-workspace-and-file-rows-in-the-sidebar.md +6 -0
  163. package/corpus/templates/content/changelog/2026-07-18-local-folder-selection-no-longer-invokes-the-unsafe-native-p.md +6 -0
  164. package/corpus/templates/content/changelog/2026-07-18-made-content-workspaces-independently-expandable-restored-or.md +6 -0
  165. package/corpus/templates/content/changelog/2026-07-18-page-details-now-live-in-a-shared-info-and-comments-rail-dat.md +6 -0
  166. package/corpus/templates/content/changelog/2026-07-18-workspace-database-views-now-control-sidebar-workspace-navig.md +6 -0
  167. package/corpus/templates/content/changelog/2026-07-18-workspace-navigation-now-aligns-favorites-with-workspace-pag.md +6 -0
  168. package/corpus/templates/content/changelog/2026-07-19-favorites-now-open-as-a-table-and-compact-breadcrumbs-make-w.md +6 -0
  169. package/corpus/templates/content/changelog/2026-07-19-files-databases-now-start-unfiltered-sidebar-rows-exactly-fo.md +6 -0
  170. package/corpus/templates/content/changelog/2026-07-19-sidebar-page-trees-now-open-only-when-expanded-remember-thei.md +6 -0
  171. package/corpus/templates/content/changelog/2026-07-19-workspace-file-databases-now-use-the-workspace-name-open-as-.md +6 -0
  172. package/corpus/templates/content/changelog/2026-07-19-workspace-navigation-now-stays-stable-on-hover-uses-folder-i.md +6 -0
  173. package/corpus/templates/content/changelog/2026-07-19-workspace-rows-now-use-folder-icons-and-deleting-a-user-crea.md +6 -0
  174. package/corpus/templates/content/changelog/2026-07-19-workspaces-can-be-created-without-leaving-the-workspaces-dat.md +6 -0
  175. package/corpus/templates/content/e2e/global-setup.ts +3 -2
  176. package/corpus/templates/content/parity/matrix.md +28 -28
  177. package/corpus/templates/content/parity/matrix.ts +8 -2
  178. package/corpus/templates/content/server/db/index.ts +1 -0
  179. package/corpus/templates/content/server/db/schema.ts +10 -0
  180. package/corpus/templates/content/server/lib/documents.ts +12 -7
  181. package/corpus/templates/content/server/plugins/db.ts +17 -0
  182. package/corpus/templates/content/shared/api.ts +9 -0
  183. package/corpus/templates/content/shared/database-form.ts +11 -2
  184. package/corpus/templates/content/vite.config.ts +1 -0
  185. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  186. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +9 -6
  187. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  188. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +9 -6
  189. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  190. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +9 -6
  191. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  192. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  193. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +9 -6
  194. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  195. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +9 -6
  196. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  197. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +9 -6
  198. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +15 -13
  199. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  200. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +9 -6
  201. package/corpus/toolkit/CHANGELOG.md +6 -0
  202. package/corpus/toolkit/agent-native.eject.json +411 -0
  203. package/corpus/toolkit/package.json +5 -2
  204. package/dist/cli/eject.d.ts +21 -0
  205. package/dist/cli/eject.d.ts.map +1 -0
  206. package/dist/cli/eject.js +1145 -0
  207. package/dist/cli/eject.js.map +1 -0
  208. package/dist/cli/index.js +15 -0
  209. package/dist/cli/index.js.map +1 -1
  210. package/dist/client/build-compatibility.d.ts +11 -0
  211. package/dist/client/build-compatibility.d.ts.map +1 -0
  212. package/dist/client/build-compatibility.js +56 -0
  213. package/dist/client/build-compatibility.js.map +1 -0
  214. package/dist/client/index.d.ts +1 -1
  215. package/dist/client/index.d.ts.map +1 -1
  216. package/dist/client/index.js +1 -1
  217. package/dist/client/index.js.map +1 -1
  218. package/dist/client/resources/McpConnectionSuggestion.d.ts +4 -3
  219. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  220. package/dist/client/resources/McpConnectionSuggestion.js +3 -3
  221. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  222. package/dist/client/resources/McpIntegrationDialog.d.ts +4 -3
  223. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  224. package/dist/client/resources/McpIntegrationDialog.js +2 -2
  225. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  226. package/dist/client/resources/ResourcesPanel.d.ts +4 -1
  227. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  228. package/dist/client/resources/ResourcesPanel.js +9 -7
  229. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  230. package/dist/client/resources/index.d.ts +3 -0
  231. package/dist/client/resources/index.d.ts.map +1 -1
  232. package/dist/client/resources/index.js +3 -0
  233. package/dist/client/resources/index.js.map +1 -1
  234. package/dist/client/resources/mcp-integration-catalog.d.ts +2 -1
  235. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  236. package/dist/client/resources/mcp-integration-catalog.js +6 -2
  237. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  238. package/dist/client/resources/runtime.d.ts +2 -0
  239. package/dist/client/resources/runtime.d.ts.map +1 -0
  240. package/dist/client/resources/runtime.js +2 -0
  241. package/dist/client/resources/runtime.js.map +1 -0
  242. package/dist/client/route-chunk-recovery/index.d.ts +1 -0
  243. package/dist/client/route-chunk-recovery/index.d.ts.map +1 -1
  244. package/dist/client/route-chunk-recovery/index.js +1 -0
  245. package/dist/client/route-chunk-recovery/index.js.map +1 -1
  246. package/dist/client/setup-connections/catalog.d.ts +2 -0
  247. package/dist/client/setup-connections/catalog.d.ts.map +1 -0
  248. package/dist/client/setup-connections/catalog.js +7 -0
  249. package/dist/client/setup-connections/catalog.js.map +1 -0
  250. package/dist/client/setup-connections/index.d.ts +1 -0
  251. package/dist/client/setup-connections/index.d.ts.map +1 -1
  252. package/dist/client/setup-connections/index.js +1 -0
  253. package/dist/client/setup-connections/index.js.map +1 -1
  254. package/dist/client/setup-connections/runtime.d.ts +2 -0
  255. package/dist/client/setup-connections/runtime.d.ts.map +1 -0
  256. package/dist/client/setup-connections/runtime.js +2 -0
  257. package/dist/client/setup-connections/runtime.js.map +1 -0
  258. package/dist/client/use-action.d.ts.map +1 -1
  259. package/dist/client/use-action.js +19 -1
  260. package/dist/client/use-action.js.map +1 -1
  261. package/dist/collab/awareness.d.ts +2 -2
  262. package/dist/collab/awareness.d.ts.map +1 -1
  263. package/dist/collab/struct-routes.d.ts +1 -1
  264. package/dist/connections/catalog.d.ts +5 -3
  265. package/dist/connections/catalog.d.ts.map +1 -1
  266. package/dist/connections/catalog.js +16 -8
  267. package/dist/connections/catalog.js.map +1 -1
  268. package/dist/connections/index.d.ts +1 -1
  269. package/dist/connections/index.d.ts.map +1 -1
  270. package/dist/connections/index.js +1 -1
  271. package/dist/connections/index.js.map +1 -1
  272. package/dist/connections/runtime.d.ts +2 -0
  273. package/dist/connections/runtime.d.ts.map +1 -0
  274. package/dist/connections/runtime.js +2 -0
  275. package/dist/connections/runtime.js.map +1 -0
  276. package/dist/deploy/build.js +2 -1
  277. package/dist/deploy/build.js.map +1 -1
  278. package/dist/eject/provider-api-definitions.d.ts +34 -0
  279. package/dist/eject/provider-api-definitions.d.ts.map +1 -0
  280. package/dist/eject/provider-api-definitions.js +88 -0
  281. package/dist/eject/provider-api-definitions.js.map +1 -0
  282. package/dist/eject/remote-mcp-presets.d.ts +17 -0
  283. package/dist/eject/remote-mcp-presets.d.ts.map +1 -0
  284. package/dist/eject/remote-mcp-presets.js +81 -0
  285. package/dist/eject/remote-mcp-presets.js.map +1 -0
  286. package/dist/eject/setup-readiness-ui.d.ts +7 -0
  287. package/dist/eject/setup-readiness-ui.d.ts.map +1 -0
  288. package/dist/eject/setup-readiness-ui.js +13 -0
  289. package/dist/eject/setup-readiness-ui.js.map +1 -0
  290. package/dist/eject/workspace-connections.d.ts +11 -0
  291. package/dist/eject/workspace-connections.d.ts.map +1 -0
  292. package/dist/eject/workspace-connections.js +47 -0
  293. package/dist/eject/workspace-connections.js.map +1 -0
  294. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  295. package/dist/index.d.ts +1 -1
  296. package/dist/index.d.ts.map +1 -1
  297. package/dist/index.js +1 -1
  298. package/dist/index.js.map +1 -1
  299. package/dist/integrations/adapter-overrides.d.ts +3 -0
  300. package/dist/integrations/adapter-overrides.d.ts.map +1 -0
  301. package/dist/integrations/adapter-overrides.js +7 -0
  302. package/dist/integrations/adapter-overrides.js.map +1 -0
  303. package/dist/integrations/eject/messaging-adapters.d.ts +12 -0
  304. package/dist/integrations/eject/messaging-adapters.d.ts.map +1 -0
  305. package/dist/integrations/eject/messaging-adapters.js +49 -0
  306. package/dist/integrations/eject/messaging-adapters.js.map +1 -0
  307. package/dist/integrations/index.d.ts +3 -2
  308. package/dist/integrations/index.d.ts.map +1 -1
  309. package/dist/integrations/index.js +2 -1
  310. package/dist/integrations/index.js.map +1 -1
  311. package/dist/integrations/plugin.d.ts +32 -1
  312. package/dist/integrations/plugin.d.ts.map +1 -1
  313. package/dist/integrations/plugin.js +19 -12
  314. package/dist/integrations/plugin.js.map +1 -1
  315. package/dist/integrations/runtime.d.ts +2 -0
  316. package/dist/integrations/runtime.d.ts.map +1 -0
  317. package/dist/integrations/runtime.js +2 -0
  318. package/dist/integrations/runtime.js.map +1 -0
  319. package/dist/integrations/types.d.ts +3 -1
  320. package/dist/integrations/types.d.ts.map +1 -1
  321. package/dist/integrations/types.js.map +1 -1
  322. package/dist/notifications/routes.d.ts +2 -2
  323. package/dist/observability/routes.d.ts +5 -5
  324. package/dist/org/context.d.ts +4 -2
  325. package/dist/org/context.d.ts.map +1 -1
  326. package/dist/org/context.js +44 -22
  327. package/dist/org/context.js.map +1 -1
  328. package/dist/package-lifecycle/eject-manifest.d.ts +43 -0
  329. package/dist/package-lifecycle/eject-manifest.d.ts.map +1 -0
  330. package/dist/package-lifecycle/eject-manifest.js +219 -0
  331. package/dist/package-lifecycle/eject-manifest.js.map +1 -0
  332. package/dist/package-lifecycle/index.d.ts +1 -0
  333. package/dist/package-lifecycle/index.d.ts.map +1 -1
  334. package/dist/package-lifecycle/index.js +1 -0
  335. package/dist/package-lifecycle/index.js.map +1 -1
  336. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  337. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  338. package/dist/provider-api/index.d.ts +6 -2
  339. package/dist/provider-api/index.d.ts.map +1 -1
  340. package/dist/provider-api/index.js +25 -12
  341. package/dist/provider-api/index.js.map +1 -1
  342. package/dist/provider-api/runtime.d.ts +2 -0
  343. package/dist/provider-api/runtime.d.ts.map +1 -0
  344. package/dist/provider-api/runtime.js +2 -0
  345. package/dist/provider-api/runtime.js.map +1 -0
  346. package/dist/resources/handlers.d.ts +1 -1
  347. package/dist/server/action-routes.d.ts.map +1 -1
  348. package/dist/server/action-routes.js +32 -2
  349. package/dist/server/action-routes.js.map +1 -1
  350. package/dist/server/auth-plugin.d.ts.map +1 -1
  351. package/dist/server/auth-plugin.js +9 -5
  352. package/dist/server/auth-plugin.js.map +1 -1
  353. package/dist/server/better-auth-instance.d.ts.map +1 -1
  354. package/dist/server/better-auth-instance.js +4 -1
  355. package/dist/server/better-auth-instance.js.map +1 -1
  356. package/dist/setup-connections/index.d.ts +1 -1
  357. package/dist/setup-connections/index.d.ts.map +1 -1
  358. package/dist/setup-connections/index.js +1 -1
  359. package/dist/setup-connections/index.js.map +1 -1
  360. package/dist/shared/mcp-embed-headers.d.ts +1 -1
  361. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  362. package/dist/shared/mcp-embed-headers.js +1 -1
  363. package/dist/shared/mcp-embed-headers.js.map +1 -1
  364. package/dist/shared/merge-by-id.d.ts +5 -0
  365. package/dist/shared/merge-by-id.d.ts.map +1 -0
  366. package/dist/shared/merge-by-id.js +7 -0
  367. package/dist/shared/merge-by-id.js.map +1 -0
  368. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  369. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  370. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  371. package/dist/templates/chat/AGENTS.md +3 -2
  372. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  373. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  374. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  375. package/dist/templates/default/AGENTS.md +6 -5
  376. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  377. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  378. package/dist/templates/headless/AGENTS.md +5 -4
  379. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  380. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  381. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  382. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  383. package/dist/templates/workspace-core/AGENTS.md +4 -4
  384. package/dist/templates/workspace-root/AGENTS.md +4 -4
  385. package/dist/vite/client.d.ts +6 -0
  386. package/dist/vite/client.d.ts.map +1 -1
  387. package/dist/vite/client.js +30 -2
  388. package/dist/vite/client.js.map +1 -1
  389. package/docs/content/agent-native-toolkit.mdx +38 -0
  390. package/docs/content/package-lifecycle.mdx +54 -4
  391. package/package.json +15 -2
  392. package/src/a2a/agent-card.ts +83 -0
  393. package/src/a2a/artifact-response.ts +1648 -0
  394. package/src/a2a/auth-policy.ts +66 -0
  395. package/src/a2a/caller-auth.ts +102 -0
  396. package/src/a2a/client.ts +876 -0
  397. package/src/a2a/correlation.ts +50 -0
  398. package/src/a2a/handlers.ts +1285 -0
  399. package/src/a2a/index.ts +50 -0
  400. package/src/a2a/invoke.ts +348 -0
  401. package/src/a2a/response-text.ts +53 -0
  402. package/src/a2a/server.ts +586 -0
  403. package/src/a2a/task-store.ts +917 -0
  404. package/src/a2a/types.ts +221 -0
  405. package/src/a2a-claims.ts +52 -0
  406. package/src/action-change-marker.ts +74 -0
  407. package/src/action-ui.ts +38 -0
  408. package/src/action.ts +1406 -0
  409. package/src/adapters/cli/index.ts +6 -0
  410. package/src/adapters/cli/registry.ts +73 -0
  411. package/src/adapters/cli/shell-adapter.ts +92 -0
  412. package/src/adapters/cli/types.ts +27 -0
  413. package/src/agent/action-continuation-guidance.ts +38 -0
  414. package/src/agent/app-model-defaults.ts +201 -0
  415. package/src/agent/context-xray/actions/context-evict.ts +56 -0
  416. package/src/agent/context-xray/actions/context-manifest-get.ts +75 -0
  417. package/src/agent/context-xray/actions/context-pin.ts +56 -0
  418. package/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  419. package/src/agent/context-xray/actions/context-report.ts +75 -0
  420. package/src/agent/context-xray/actions/context-restore.ts +51 -0
  421. package/src/agent/context-xray/actions/errors.ts +40 -0
  422. package/src/agent/context-xray/apply-directives.ts +137 -0
  423. package/src/agent/context-xray/directives-store.ts +178 -0
  424. package/src/agent/context-xray/identity.ts +37 -0
  425. package/src/agent/context-xray/manifest.ts +284 -0
  426. package/src/agent/context-xray/migrations.ts +32 -0
  427. package/src/agent/context-xray/plugin.ts +23 -0
  428. package/src/agent/context-xray/schema.ts +17 -0
  429. package/src/agent/context-xray/segments.ts +194 -0
  430. package/src/agent/context-xray/tokenize.ts +93 -0
  431. package/src/agent/default-model.ts +5 -0
  432. package/src/agent/durable-background.ts +547 -0
  433. package/src/agent/engine/ai-sdk-engine.ts +565 -0
  434. package/src/agent/engine/anthropic-engine.ts +320 -0
  435. package/src/agent/engine/builder-engine.ts +1110 -0
  436. package/src/agent/engine/builder-gateway-headers.ts +44 -0
  437. package/src/agent/engine/builtin.ts +122 -0
  438. package/src/agent/engine/context-directives-transform.ts +73 -0
  439. package/src/agent/engine/continuation-dispatch-retry.ts +168 -0
  440. package/src/agent/engine/credential-errors.ts +69 -0
  441. package/src/agent/engine/index.ts +54 -0
  442. package/src/agent/engine/openai-compatible-endpoint.ts +25 -0
  443. package/src/agent/engine/output-tokens.ts +181 -0
  444. package/src/agent/engine/provider-env-vars.ts +69 -0
  445. package/src/agent/engine/registry.ts +853 -0
  446. package/src/agent/engine/tool-call-journal-seed.ts +85 -0
  447. package/src/agent/engine/translate-ai-sdk.ts +407 -0
  448. package/src/agent/engine/translate-anthropic.ts +611 -0
  449. package/src/agent/engine/types.ts +310 -0
  450. package/src/agent/harness/acp-adapter.ts +893 -0
  451. package/src/agent/harness/acp-builtin.ts +70 -0
  452. package/src/agent/harness/ai-sdk-adapter.ts +509 -0
  453. package/src/agent/harness/background.ts +365 -0
  454. package/src/agent/harness/builtin.ts +50 -0
  455. package/src/agent/harness/index.ts +86 -0
  456. package/src/agent/harness/lifecycle.ts +498 -0
  457. package/src/agent/harness/registry.ts +97 -0
  458. package/src/agent/harness/runner.ts +182 -0
  459. package/src/agent/harness/store.ts +466 -0
  460. package/src/agent/harness/translate.ts +130 -0
  461. package/src/agent/harness/types.ts +129 -0
  462. package/src/agent/index.ts +32 -0
  463. package/src/agent/loop-settings.ts +186 -0
  464. package/src/agent/model-config.ts +363 -0
  465. package/src/agent/observational-memory/compactor.ts +78 -0
  466. package/src/agent/observational-memory/config.ts +78 -0
  467. package/src/agent/observational-memory/index.ts +79 -0
  468. package/src/agent/observational-memory/internal-run.ts +89 -0
  469. package/src/agent/observational-memory/message-text.ts +49 -0
  470. package/src/agent/observational-memory/migrations.ts +44 -0
  471. package/src/agent/observational-memory/observer.ts +128 -0
  472. package/src/agent/observational-memory/plugin.ts +35 -0
  473. package/src/agent/observational-memory/prompts.ts +53 -0
  474. package/src/agent/observational-memory/read.ts +131 -0
  475. package/src/agent/observational-memory/reflector.ts +119 -0
  476. package/src/agent/observational-memory/schema.ts +48 -0
  477. package/src/agent/observational-memory/store.ts +275 -0
  478. package/src/agent/observational-memory/types.ts +65 -0
  479. package/src/agent/processors.ts +209 -0
  480. package/src/agent/production-agent.ts +8254 -0
  481. package/src/agent/run-loop-with-resume.ts +394 -0
  482. package/src/agent/run-manager.ts +1825 -0
  483. package/src/agent/run-ownership.ts +75 -0
  484. package/src/agent/run-store.ts +2601 -0
  485. package/src/agent/runtime-context.ts +169 -0
  486. package/src/agent/thread-data-builder.ts +1584 -0
  487. package/src/agent/tool-call-journal.ts +368 -0
  488. package/src/agent/tool-error-redaction.ts +52 -0
  489. package/src/agent/tool-result-images.ts +178 -0
  490. package/src/agent/tool-search.ts +376 -0
  491. package/src/agent/types.ts +372 -0
  492. package/src/agent-native/index.ts +198 -0
  493. package/src/agent-web/config.ts +253 -0
  494. package/src/agent-web/generator.ts +382 -0
  495. package/src/agent-web/index.ts +36 -0
  496. package/src/appearance/actions/change-appearance.ts +35 -0
  497. package/src/application-state/emitter.ts +81 -0
  498. package/src/application-state/handlers.ts +121 -0
  499. package/src/application-state/index.ts +44 -0
  500. package/src/application-state/script-helpers.ts +155 -0
  501. package/src/application-state/store.ts +274 -0
  502. package/src/assets/branding/agent-native.icon/Assets/background.svg +3 -0
  503. package/src/assets/branding/agent-native.icon/Assets/foreground.svg +12 -0
  504. package/src/assets/branding/agent-native.icon/icon.json +49 -0
  505. package/src/assets/branding/favicon.png +0 -0
  506. package/src/assets/branding/favicon.svg +1 -0
  507. package/src/assets/branding/icon-on-dark.svg +10 -0
  508. package/src/assets/branding/icon-on-light.svg +10 -0
  509. package/src/assets/branding/mac-app-icon.svg +1 -0
  510. package/src/assets/branding/slack-bot/agent-native-1024.png +0 -0
  511. package/src/assets/branding/slack-bot/agent-native-512.png +0 -0
  512. package/src/assets/branding/tray-icon.svg +6 -0
  513. package/src/assets/branding/wordmark-on-dark.svg +21 -0
  514. package/src/assets/branding/wordmark-on-light.svg +21 -0
  515. package/src/assets/fonts/LICENSE_LIBERATION +96 -0
  516. package/src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC +93 -0
  517. package/src/assets/fonts/LiberationSans-Bold.ttf +0 -0
  518. package/src/assets/fonts/LiberationSans-Regular.ttf +0 -0
  519. package/src/assets/fonts/NotoNaskhArabic-Variable.ttf +0 -0
  520. package/src/audit/actions/export-audit-events.ts +162 -0
  521. package/src/audit/actions/get-audit-event.ts +24 -0
  522. package/src/audit/actions/list-audit-events.ts +66 -0
  523. package/src/audit/cleanup-job.ts +100 -0
  524. package/src/audit/config.ts +90 -0
  525. package/src/audit/index.ts +43 -0
  526. package/src/audit/record.ts +180 -0
  527. package/src/audit/redact.ts +109 -0
  528. package/src/audit/store.ts +346 -0
  529. package/src/audit/types.ts +141 -0
  530. package/src/automation/index.ts +802 -0
  531. package/src/brand-kit/brand-signals.ts +124 -0
  532. package/src/brand-kit/fig/index.ts +64 -0
  533. package/src/brand-kit/index.ts +72 -0
  534. package/src/brand-kit/types.ts +113 -0
  535. package/src/browser-sessions/actions.ts +302 -0
  536. package/src/browser-sessions/routes.ts +234 -0
  537. package/src/browser-sessions/store.ts +679 -0
  538. package/src/browser-sessions/types.ts +84 -0
  539. package/src/changelog/parse.ts +328 -0
  540. package/src/chat-threads/emitter.ts +22 -0
  541. package/src/chat-threads/schema.ts +43 -0
  542. package/src/chat-threads/store.ts +1311 -0
  543. package/src/checkpoints/index.ts +15 -0
  544. package/src/checkpoints/service.ts +142 -0
  545. package/src/checkpoints/store.ts +153 -0
  546. package/src/cli/add.ts +425 -0
  547. package/src/cli/agent.ts +424 -0
  548. package/src/cli/agents.ts +122 -0
  549. package/src/cli/app-skill.ts +1455 -0
  550. package/src/cli/atomic-json-file.ts +324 -0
  551. package/src/cli/audit-agent-web.ts +324 -0
  552. package/src/cli/changelog.ts +199 -0
  553. package/src/cli/claude-code-participant.ts +515 -0
  554. package/src/cli/code-agent-commands.ts +270 -0
  555. package/src/cli/code-agent-connector.ts +1109 -0
  556. package/src/cli/code-agent-executor.ts +1970 -0
  557. package/src/cli/code-agent-output-smoother.ts +140 -0
  558. package/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  559. package/src/cli/code-agent-runs.ts +548 -0
  560. package/src/cli/code.ts +1805 -0
  561. package/src/cli/codex-cli-participant.ts +496 -0
  562. package/src/cli/connect.ts +2714 -0
  563. package/src/cli/content-local.ts +442 -0
  564. package/src/cli/context-xray-local.ts +2193 -0
  565. package/src/cli/create-workspace.ts +30 -0
  566. package/src/cli/create.ts +2247 -0
  567. package/src/cli/deploy-build.ts +50 -0
  568. package/src/cli/design-connect.ts +3187 -0
  569. package/src/cli/doctor.ts +472 -0
  570. package/src/cli/eject.ts +1594 -0
  571. package/src/cli/eval.ts +134 -0
  572. package/src/cli/gateway-helpers.ts +70 -0
  573. package/src/cli/index.ts +1217 -0
  574. package/src/cli/info.ts +105 -0
  575. package/src/cli/invoke.ts +288 -0
  576. package/src/cli/mcp-config-writers.ts +857 -0
  577. package/src/cli/mcp.ts +594 -0
  578. package/src/cli/migrate.ts +1813 -0
  579. package/src/cli/migration-codemod.ts +646 -0
  580. package/src/cli/multi-frontier-runs.ts +1952 -0
  581. package/src/cli/package-lifecycle.ts +823 -0
  582. package/src/cli/plan-blocks.ts +143 -0
  583. package/src/cli/plan-local.ts +3189 -0
  584. package/src/cli/plan-publish-store.ts +138 -0
  585. package/src/cli/pr-visual-recap-workflow.ts +2 -0
  586. package/src/cli/recap.ts +5 -0
  587. package/src/cli/setup-agents.ts +120 -0
  588. package/src/cli/skills-content/assets-skill.ts +83 -0
  589. package/src/cli/skills-content/canvas.ts +153 -0
  590. package/src/cli/skills-content/connection.ts +52 -0
  591. package/src/cli/skills-content/content-skill.ts +120 -0
  592. package/src/cli/skills-content/design-exploration-skill.ts +118 -0
  593. package/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
  594. package/src/cli/skills-content/document-quality.ts +196 -0
  595. package/src/cli/skills-content/exemplar.ts +69 -0
  596. package/src/cli/skills-content/help.ts +77 -0
  597. package/src/cli/skills-content/index.ts +22 -0
  598. package/src/cli/skills-content/local-files.ts +100 -0
  599. package/src/cli/skills-content/plan-setup-auth.ts +80 -0
  600. package/src/cli/skills-content/visual-plan-skill.ts +493 -0
  601. package/src/cli/skills-content/visual-recap-skill.ts +553 -0
  602. package/src/cli/skills-content/visualize-repo-skill.ts +93 -0
  603. package/src/cli/skills-content/wireframe.ts +349 -0
  604. package/src/cli/skills.ts +4340 -0
  605. package/src/cli/sync-builder-starter-manifest.ts +631 -0
  606. package/src/cli/telemetry.ts +136 -0
  607. package/src/cli/templates-meta.ts +269 -0
  608. package/src/cli/upgrade.ts +956 -0
  609. package/src/cli/visualize-repo.ts +715 -0
  610. package/src/cli/workspace-dev.ts +1486 -0
  611. package/src/cli/workspacify.ts +258 -0
  612. package/src/client/AgentAskPopover.tsx +89 -0
  613. package/src/client/AgentChatHome.tsx +66 -0
  614. package/src/client/AgentNative.tsx +161 -0
  615. package/src/client/AgentNativeEmbedded.tsx +288 -0
  616. package/src/client/AgentNativeFrame.tsx +151 -0
  617. package/src/client/AgentPanel.tsx +3437 -0
  618. package/src/client/AgentTaskCard.tsx +273 -0
  619. package/src/client/AppearancePicker.tsx +79 -0
  620. package/src/client/AssistantChat.tsx +5793 -0
  621. package/src/client/ClientOnly.tsx +22 -0
  622. package/src/client/CommandMenu.tsx +726 -0
  623. package/src/client/ConnectBuilderCard.tsx +390 -0
  624. package/src/client/DefaultSpinner.tsx +47 -0
  625. package/src/client/ErrorBoundary.tsx +359 -0
  626. package/src/client/ErrorReportActions.tsx +69 -0
  627. package/src/client/FeedbackButton.tsx +553 -0
  628. package/src/client/HighlightedCodeBlock.tsx +173 -0
  629. package/src/client/IframeEmbed.tsx +151 -0
  630. package/src/client/KeepTabOpenNotice.tsx +181 -0
  631. package/src/client/MultiTabAssistantChat.tsx +2576 -0
  632. package/src/client/NewWorkspaceAppFlow.tsx +525 -0
  633. package/src/client/PoweredByBadge.tsx +284 -0
  634. package/src/client/RunStuckBanner.tsx +431 -0
  635. package/src/client/StarfieldBackground.tsx +466 -0
  636. package/src/client/Turnstile.tsx +125 -0
  637. package/src/client/active-run-state.ts +139 -0
  638. package/src/client/agent-chat/index.ts +279 -0
  639. package/src/client/agent-chat-adapter.ts +3692 -0
  640. package/src/client/agent-chat.ts +1233 -0
  641. package/src/client/agent-engine-key.ts +122 -0
  642. package/src/client/agent-page/AgentContextTab.tsx +487 -0
  643. package/src/client/agent-page/AgentEmptyState.tsx +44 -0
  644. package/src/client/agent-page/AgentJobsTab.tsx +441 -0
  645. package/src/client/agent-page/AgentTabFrame.tsx +39 -0
  646. package/src/client/agent-page/AgentTabsPage.tsx +1096 -0
  647. package/src/client/agent-page/types.ts +18 -0
  648. package/src/client/agent-page/use-jobs.ts +150 -0
  649. package/src/client/agent-sidebar-state.ts +166 -0
  650. package/src/client/analytics/index.ts +40 -0
  651. package/src/client/analytics-session.ts +70 -0
  652. package/src/client/analytics.ts +1757 -0
  653. package/src/client/api-path.ts +124 -0
  654. package/src/client/app-providers.tsx +230 -0
  655. package/src/client/appearance.ts +130 -0
  656. package/src/client/application-state.ts +154 -0
  657. package/src/client/assistant-ui-recovery.tsx +205 -0
  658. package/src/client/automation/index.ts +4 -0
  659. package/src/client/automation.ts +22 -0
  660. package/src/client/blocks/AiEditableField.tsx +30 -0
  661. package/src/client/blocks/BlockView.tsx +145 -0
  662. package/src/client/blocks/RegistryBlockDataProvider.tsx +121 -0
  663. package/src/client/blocks/SchemaBlockEditor.tsx +457 -0
  664. package/src/client/blocks/agent.ts +95 -0
  665. package/src/client/blocks/code-block-direction.ts +21 -0
  666. package/src/client/blocks/index.ts +308 -0
  667. package/src/client/blocks/library/AnnotatedCodeBlock.tsx +710 -0
  668. package/src/client/blocks/library/ApiEndpointBlock.tsx +1120 -0
  669. package/src/client/blocks/library/DataModelBlock.tsx +775 -0
  670. package/src/client/blocks/library/DiffBlock.tsx +1854 -0
  671. package/src/client/blocks/library/FileTreeBlock.tsx +868 -0
  672. package/src/client/blocks/library/HighlightedCode.tsx +260 -0
  673. package/src/client/blocks/library/JsonExplorerBlock.tsx +608 -0
  674. package/src/client/blocks/library/MermaidBlock.tsx +362 -0
  675. package/src/client/blocks/library/OpenApiSpecBlock.tsx +998 -0
  676. package/src/client/blocks/library/annotated-code.config.ts +101 -0
  677. package/src/client/blocks/library/annotation-rail.tsx +1020 -0
  678. package/src/client/blocks/library/api-endpoint.config.ts +207 -0
  679. package/src/client/blocks/library/block-copy.ts +399 -0
  680. package/src/client/blocks/library/callout.config.ts +57 -0
  681. package/src/client/blocks/library/callout.tsx +149 -0
  682. package/src/client/blocks/library/checklist.config.ts +56 -0
  683. package/src/client/blocks/library/checklist.tsx +208 -0
  684. package/src/client/blocks/library/code-filename-label.tsx +59 -0
  685. package/src/client/blocks/library/code-highlight.tsx +178 -0
  686. package/src/client/blocks/library/code-tabs.config.ts +70 -0
  687. package/src/client/blocks/library/code-tabs.tsx +606 -0
  688. package/src/client/blocks/library/code.config.ts +69 -0
  689. package/src/client/blocks/library/code.tsx +440 -0
  690. package/src/client/blocks/library/columns.config.ts +85 -0
  691. package/src/client/blocks/library/columns.tsx +334 -0
  692. package/src/client/blocks/library/data-model.config.ts +152 -0
  693. package/src/client/blocks/library/dev-doc-ui.tsx +191 -0
  694. package/src/client/blocks/library/diagram.config.ts +222 -0
  695. package/src/client/blocks/library/diagram.tsx +958 -0
  696. package/src/client/blocks/library/diff.config.ts +115 -0
  697. package/src/client/blocks/library/file-tree.config.ts +92 -0
  698. package/src/client/blocks/library/html.config.ts +79 -0
  699. package/src/client/blocks/library/html.tsx +258 -0
  700. package/src/client/blocks/library/json-explorer.config.ts +74 -0
  701. package/src/client/blocks/library/mermaid.config.ts +49 -0
  702. package/src/client/blocks/library/narrow-container.tsx +37 -0
  703. package/src/client/blocks/library/openapi-spec.config.ts +66 -0
  704. package/src/client/blocks/library/question-form.config.ts +127 -0
  705. package/src/client/blocks/library/question-form.tsx +944 -0
  706. package/src/client/blocks/library/sanitize-html.ts +343 -0
  707. package/src/client/blocks/library/server-specs.ts +338 -0
  708. package/src/client/blocks/library/specs.tsx +308 -0
  709. package/src/client/blocks/library/table.config.ts +61 -0
  710. package/src/client/blocks/library/table.tsx +449 -0
  711. package/src/client/blocks/library/tabs.config.ts +96 -0
  712. package/src/client/blocks/library/tabs.tsx +665 -0
  713. package/src/client/blocks/library/wireframe-icons.ts +210 -0
  714. package/src/client/blocks/library/wireframe-kit.tsx +1850 -0
  715. package/src/client/blocks/library/wireframe.config.ts +539 -0
  716. package/src/client/blocks/library/wireframe.tsx +535 -0
  717. package/src/client/blocks/mdx.ts +364 -0
  718. package/src/client/blocks/provider.tsx +51 -0
  719. package/src/client/blocks/registry.ts +83 -0
  720. package/src/client/blocks/schema-form/introspect.ts +201 -0
  721. package/src/client/blocks/server.ts +170 -0
  722. package/src/client/blocks/types.ts +415 -0
  723. package/src/client/browser-session-bridge.ts +548 -0
  724. package/src/client/browser-tab-id.ts +36 -0
  725. package/src/client/build-compatibility.ts +77 -0
  726. package/src/client/builder-frame.ts +194 -0
  727. package/src/client/builder-mark.tsx +21 -0
  728. package/src/client/changelog/Changelog.tsx +333 -0
  729. package/src/client/changelog/index.ts +1 -0
  730. package/src/client/chat/ChatHistoryList.tsx +7 -0
  731. package/src/client/chat/attachment-adapters.ts +426 -0
  732. package/src/client/chat/connectors.ts +1579 -0
  733. package/src/client/chat/index.ts +160 -0
  734. package/src/client/chat/markdown-renderer.tsx +693 -0
  735. package/src/client/chat/message-components.tsx +1326 -0
  736. package/src/client/chat/repo-helpers.ts +281 -0
  737. package/src/client/chat/run-recovery.tsx +994 -0
  738. package/src/client/chat/runtime.ts +1810 -0
  739. package/src/client/chat/tool-call-display.tsx +1270 -0
  740. package/src/client/chat/tool-render-registry.tsx +144 -0
  741. package/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  742. package/src/client/chat/use-reconnect-reader-owner.ts +28 -0
  743. package/src/client/chat/widgets/DataChartRenderer.tsx +242 -0
  744. package/src/client/chat/widgets/DataChartWidget.tsx +51 -0
  745. package/src/client/chat/widgets/DataInsightsWidget.tsx +59 -0
  746. package/src/client/chat/widgets/DataTableWidget.tsx +240 -0
  747. package/src/client/chat/widgets/InlineExtensionWidget.tsx +60 -0
  748. package/src/client/chat/widgets/builtin-tool-renderers.tsx +213 -0
  749. package/src/client/chat/widgets/data-widget-types.ts +1 -0
  750. package/src/client/chat/widgets/inline-extension-result.ts +86 -0
  751. package/src/client/chat-model-groups.ts +171 -0
  752. package/src/client/chat-thread-url.ts +11 -0
  753. package/src/client/chat-view-transition.ts +213 -0
  754. package/src/client/client-action.ts +21 -0
  755. package/src/client/client-bootstrap.ts +7 -0
  756. package/src/client/client-surface.ts +41 -0
  757. package/src/client/clipboard.ts +89 -0
  758. package/src/client/code-agent-chat-adapter.ts +537 -0
  759. package/src/client/collab/index.ts +60 -0
  760. package/src/client/command-navigation/index.ts +15 -0
  761. package/src/client/comments-review/index.ts +1 -0
  762. package/src/client/components/AgentPresenceChip.tsx +4 -0
  763. package/src/client/components/ApiKeySettings.tsx +309 -0
  764. package/src/client/components/CodeAgentIndicator.tsx +59 -0
  765. package/src/client/components/CodeRequiredDialog.tsx +470 -0
  766. package/src/client/components/LiveCursorOverlay.tsx +5 -0
  767. package/src/client/components/MissingKeyCard.tsx +61 -0
  768. package/src/client/components/PresenceBar.tsx +4 -0
  769. package/src/client/components/RecentEditHighlights.tsx +4 -0
  770. package/src/client/components/RemoteSelectionRings.tsx +5 -0
  771. package/src/client/components/icons/AgentNativeIcon.tsx +46 -0
  772. package/src/client/components/ui/dialog.tsx +1 -0
  773. package/src/client/components/ui/dropdown-menu.tsx +1 -0
  774. package/src/client/components/ui/hover-card.tsx +1 -0
  775. package/src/client/components/ui/message-scroller.tsx +131 -0
  776. package/src/client/components/ui/popover.tsx +1 -0
  777. package/src/client/components/ui/sheet.tsx +1 -0
  778. package/src/client/components/ui/tooltip.tsx +1 -0
  779. package/src/client/composer/index.ts +11 -0
  780. package/src/client/composer/runtime-adapters.tsx +123 -0
  781. package/src/client/composer/use-mention-search.ts +7 -0
  782. package/src/client/composer/wired-components.tsx +53 -0
  783. package/src/client/context-xray/ContextMeter.tsx +124 -0
  784. package/src/client/context-xray/ContextSegmentRow.tsx +27 -0
  785. package/src/client/context-xray/ContextTreemap.tsx +24 -0
  786. package/src/client/context-xray/ContextXRayPanel.tsx +59 -0
  787. package/src/client/context-xray/SegmentProvenancePopover.tsx +18 -0
  788. package/src/client/context-xray/format.ts +27 -0
  789. package/src/client/conversation/AgentConversation.tsx +555 -0
  790. package/src/client/conversation/code-agent-transcript.ts +283 -0
  791. package/src/client/conversation/index.ts +22 -0
  792. package/src/client/conversation/types.ts +85 -0
  793. package/src/client/conversation/use-near-bottom-autoscroll.ts +278 -0
  794. package/src/client/create-query-client.ts +86 -0
  795. package/src/client/db-admin/DataGrid.tsx +551 -0
  796. package/src/client/db-admin/DbAdminPage.tsx +218 -0
  797. package/src/client/db-admin/DevDatabaseLink.tsx +16 -0
  798. package/src/client/db-admin/EditableCell.tsx +451 -0
  799. package/src/client/db-admin/FilterBar.tsx +203 -0
  800. package/src/client/db-admin/ResultsGrid.tsx +114 -0
  801. package/src/client/db-admin/RowSidePanel.tsx +337 -0
  802. package/src/client/db-admin/SqlEditor.tsx +840 -0
  803. package/src/client/db-admin/TableBrowser.tsx +212 -0
  804. package/src/client/db-admin/TableEditor.tsx +760 -0
  805. package/src/client/db-admin/cell-format.ts +246 -0
  806. package/src/client/db-admin/changeset.ts +296 -0
  807. package/src/client/db-admin/export-utils.ts +78 -0
  808. package/src/client/db-admin/index.ts +33 -0
  809. package/src/client/db-admin/sql-storage.ts +134 -0
  810. package/src/client/db-admin/storage.ts +68 -0
  811. package/src/client/db-admin/useAgentSync.ts +226 -0
  812. package/src/client/db-admin/useDbAdmin.ts +294 -0
  813. package/src/client/dev-overlay/DevOverlay.tsx +576 -0
  814. package/src/client/dev-overlay/builtins.ts +40 -0
  815. package/src/client/dev-overlay/index.ts +23 -0
  816. package/src/client/dev-overlay/registry.ts +67 -0
  817. package/src/client/dev-overlay/types.ts +64 -0
  818. package/src/client/dev-overlay/use-dev-option.ts +78 -0
  819. package/src/client/dev-overlay/use-dev-overlay-shortcut.ts +31 -0
  820. package/src/client/dynamic-suggestions.ts +455 -0
  821. package/src/client/embed-auth.ts +544 -0
  822. package/src/client/embed.ts +54 -0
  823. package/src/client/error-capture.ts +690 -0
  824. package/src/client/error-format.ts +211 -0
  825. package/src/client/error-reporting.ts +100 -0
  826. package/src/client/extensions/AgentNativeExtensionFrame.e2e-host.tsx +136 -0
  827. package/src/client/extensions/AgentNativeExtensionFrame.tsx +708 -0
  828. package/src/client/extensions/EmbeddedExtension.tsx +604 -0
  829. package/src/client/extensions/ExtensionEditor.tsx +450 -0
  830. package/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
  831. package/src/client/extensions/ExtensionSlot.tsx +345 -0
  832. package/src/client/extensions/ExtensionViewer.tsx +1502 -0
  833. package/src/client/extensions/ExtensionViewerPage.tsx +32 -0
  834. package/src/client/extensions/ExtensionsListPage.tsx +432 -0
  835. package/src/client/extensions/ExtensionsSidebarSection.tsx +1259 -0
  836. package/src/client/extensions/InlineExtensionFrame.tsx +660 -0
  837. package/src/client/extensions/agent-native-extension-runtime.ts +495 -0
  838. package/src/client/extensions/delete-extension.ts +76 -0
  839. package/src/client/extensions/extension-load-error.ts +26 -0
  840. package/src/client/extensions/extension-order.ts +49 -0
  841. package/src/client/extensions/extension-popularity.ts +61 -0
  842. package/src/client/extensions/iframe-bridge.ts +377 -0
  843. package/src/client/extensions/index.ts +84 -0
  844. package/src/client/extensions/portable-extension.ts +712 -0
  845. package/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
  846. package/src/client/feature-flags/helpers.ts +77 -0
  847. package/src/client/feature-flags/index.ts +13 -0
  848. package/src/client/feature-flags/types.ts +29 -0
  849. package/src/client/feature-flags/use-feature-flag.ts +26 -0
  850. package/src/client/feedback-context.ts +90 -0
  851. package/src/client/frame-protocol.ts +168 -0
  852. package/src/client/frame.ts +329 -0
  853. package/src/client/guided-questions.tsx +1152 -0
  854. package/src/client/history/VersionHistoryPanel.tsx +175 -0
  855. package/src/client/history/index.ts +21 -0
  856. package/src/client/history/use-history.ts +114 -0
  857. package/src/client/hooks/index.ts +46 -0
  858. package/src/client/host/index.ts +170 -0
  859. package/src/client/host-bridge.ts +1272 -0
  860. package/src/client/host-tools.ts +190 -0
  861. package/src/client/i18n.tsx +798 -0
  862. package/src/client/index.ts +370 -0
  863. package/src/client/integrations/IntegrationCard.tsx +186 -0
  864. package/src/client/integrations/IntegrationsPanel.tsx +633 -0
  865. package/src/client/integrations/api.ts +295 -0
  866. package/src/client/integrations/index.ts +29 -0
  867. package/src/client/integrations/useIntegrationStatus.ts +52 -0
  868. package/src/client/mcp-app-host.ts +720 -0
  869. package/src/client/mcp-apps/McpAppRenderer.tsx +760 -0
  870. package/src/client/navigation/index.ts +54 -0
  871. package/src/client/notifications/NotificationsBell.tsx +383 -0
  872. package/src/client/notifications/index.ts +1 -0
  873. package/src/client/observability/ObservabilityDashboard.tsx +890 -0
  874. package/src/client/observability/ThumbsFeedback.tsx +160 -0
  875. package/src/client/observability/index.ts +20 -0
  876. package/src/client/observability/useObservability.ts +266 -0
  877. package/src/client/onboarding/OnboardingBanner.tsx +73 -0
  878. package/src/client/onboarding/OnboardingPanel.tsx +1036 -0
  879. package/src/client/onboarding/SetupButton.tsx +64 -0
  880. package/src/client/onboarding/index.ts +25 -0
  881. package/src/client/onboarding/use-onboarding.ts +164 -0
  882. package/src/client/onboarding/use-preview-mode.ts +40 -0
  883. package/src/client/org/InvitationBanner.tsx +148 -0
  884. package/src/client/org/OrgSwitcher.tsx +754 -0
  885. package/src/client/org/RequireActiveOrg.tsx +337 -0
  886. package/src/client/org/TeamPage.tsx +1432 -0
  887. package/src/client/org/hooks.ts +359 -0
  888. package/src/client/org/index.ts +70 -0
  889. package/src/client/org/workspace-app-links.ts +367 -0
  890. package/src/client/org-team/index.ts +1 -0
  891. package/src/client/progress/RunsTray.tsx +680 -0
  892. package/src/client/progress/index.ts +1 -0
  893. package/src/client/require-session.tsx +142 -0
  894. package/src/client/resources/BuiltinCapabilityDetail.tsx +258 -0
  895. package/src/client/resources/McpConnectionSuggestion.tsx +276 -0
  896. package/src/client/resources/McpIntegrationDialog.tsx +808 -0
  897. package/src/client/resources/McpServerDetail.tsx +230 -0
  898. package/src/client/resources/ResourceEditor.tsx +872 -0
  899. package/src/client/resources/ResourceTree.tsx +860 -0
  900. package/src/client/resources/ResourcesPanel.tsx +1960 -0
  901. package/src/client/resources/index.ts +25 -0
  902. package/src/client/resources/mcp-integration-catalog.ts +771 -0
  903. package/src/client/resources/mcp-integration-logos.ts +108 -0
  904. package/src/client/resources/runtime.ts +1 -0
  905. package/src/client/resources/use-builtin-capabilities.ts +113 -0
  906. package/src/client/resources/use-mcp-servers.ts +217 -0
  907. package/src/client/resources/use-resources.ts +402 -0
  908. package/src/client/review/ReviewCommentComposer.tsx +123 -0
  909. package/src/client/review/ReviewStatusBadge.tsx +39 -0
  910. package/src/client/review/ReviewThreadPanel.tsx +625 -0
  911. package/src/client/review/index.ts +38 -0
  912. package/src/client/review/use-review.ts +186 -0
  913. package/src/client/route-chunk-recovery/index.ts +2 -0
  914. package/src/client/route-chunk-recovery.ts +331 -0
  915. package/src/client/route-state.ts +455 -0
  916. package/src/client/route-warmup.tsx +543 -0
  917. package/src/client/session-replay-iframe.e2e-host.tsx +100 -0
  918. package/src/client/session-replay.ts +3417 -0
  919. package/src/client/settings/AgentsSection.tsx +441 -0
  920. package/src/client/settings/AutomationsSection.tsx +516 -0
  921. package/src/client/settings/BackgroundAgentSection.tsx +189 -0
  922. package/src/client/settings/BrowserSection.tsx +110 -0
  923. package/src/client/settings/DemoModeSection.tsx +48 -0
  924. package/src/client/settings/SecretsSection.tsx +875 -0
  925. package/src/client/settings/SettingsPanel.tsx +3162 -0
  926. package/src/client/settings/SettingsSection.tsx +283 -0
  927. package/src/client/settings/SettingsTabsPage.tsx +592 -0
  928. package/src/client/settings/UsageSection.tsx +401 -0
  929. package/src/client/settings/VoiceTranscriptionSection.tsx +960 -0
  930. package/src/client/settings/agent-settings-search.ts +220 -0
  931. package/src/client/settings/index.ts +27 -0
  932. package/src/client/settings/useBuilderStatus.ts +1055 -0
  933. package/src/client/setup-connections/BuilderConnectCard.tsx +89 -0
  934. package/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  935. package/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  936. package/src/client/setup-connections/catalog.ts +6 -0
  937. package/src/client/setup-connections/index.ts +47 -0
  938. package/src/client/setup-connections/runtime.ts +1 -0
  939. package/src/client/sharing/ShareButton.tsx +1748 -0
  940. package/src/client/sharing/ShareDialog.tsx +846 -0
  941. package/src/client/sharing/VisibilityBadge.tsx +4 -0
  942. package/src/client/sharing/index.ts +2 -0
  943. package/src/client/sse-event-processor.ts +2002 -0
  944. package/src/client/terminal/AgentTerminal.tsx +488 -0
  945. package/src/client/terminal/index.ts +7 -0
  946. package/src/client/theme.ts +27 -0
  947. package/src/client/tombstone/agent-presence-chip.ts +17 -0
  948. package/src/client/tombstone/editor.ts +265 -0
  949. package/src/client/tombstone/live-cursor-overlay.ts +21 -0
  950. package/src/client/tombstone/presence-bar.ts +17 -0
  951. package/src/client/tombstone/recent-edit-highlights.ts +17 -0
  952. package/src/client/tombstone/remote-selection-rings.ts +21 -0
  953. package/src/client/tombstone/rich-markdown-editor.ts +265 -0
  954. package/src/client/tombstone/ui-dialog.ts +49 -0
  955. package/src/client/tombstone/ui-dropdown-menu.ts +69 -0
  956. package/src/client/tombstone/ui-hover-card.ts +21 -0
  957. package/src/client/tombstone/ui-popover.ts +25 -0
  958. package/src/client/tombstone/ui-sheet.ts +49 -0
  959. package/src/client/tombstone/ui-tooltip.ts +29 -0
  960. package/src/client/tombstone/visual-style-controls.ts +61 -0
  961. package/src/client/tool-cells/BashCell.tsx +164 -0
  962. package/src/client/tool-cells/EditCell.tsx +303 -0
  963. package/src/client/tool-cells/FilesChangedSummary.tsx +208 -0
  964. package/src/client/tool-cells/WriteCell.tsx +145 -0
  965. package/src/client/tool-cells/index.ts +7 -0
  966. package/src/client/tool-display.ts +41 -0
  967. package/src/client/track.ts +57 -0
  968. package/src/client/transcription/BuilderTranscriptionCta.tsx +120 -0
  969. package/src/client/transcription/use-live-transcription.ts +292 -0
  970. package/src/client/ui/index.ts +55 -0
  971. package/src/client/uploads/index.ts +6 -0
  972. package/src/client/uploads/upload-editor-image.ts +79 -0
  973. package/src/client/uploads/use-upload-resource.ts +24 -0
  974. package/src/client/url-scrub.ts +51 -0
  975. package/src/client/use-action.ts +797 -0
  976. package/src/client/use-agent-chat-context.ts +63 -0
  977. package/src/client/use-agent-chat-home-handoff.ts +207 -0
  978. package/src/client/use-agent-chat.ts +53 -0
  979. package/src/client/use-agent-engine-configured.ts +211 -0
  980. package/src/client/use-avatar.ts +127 -0
  981. package/src/client/use-change-version.ts +150 -0
  982. package/src/client/use-chat-models.ts +252 -0
  983. package/src/client/use-chat-threads.ts +1262 -0
  984. package/src/client/use-db-sync.ts +1112 -0
  985. package/src/client/use-demo-mode-status.ts +30 -0
  986. package/src/client/use-dev-mode.ts +177 -0
  987. package/src/client/use-external-value.ts +40 -0
  988. package/src/client/use-pausing-interval.ts +65 -0
  989. package/src/client/use-pinch-zoom.ts +202 -0
  990. package/src/client/use-run-stuck-detection.ts +427 -0
  991. package/src/client/use-send-to-agent-chat.ts +85 -0
  992. package/src/client/use-session.ts +114 -0
  993. package/src/client/utils.ts +7 -0
  994. package/src/client/visual-style-controls.tsx +1 -0
  995. package/src/client/vite-dev-recovery-script.ts +226 -0
  996. package/src/client/voice-provider-status.ts +44 -0
  997. package/src/client/widgets/index.ts +41 -0
  998. package/src/code-agents/background-controller.ts +398 -0
  999. package/src/code-agents/background-run.ts +156 -0
  1000. package/src/code-agents/index.ts +95 -0
  1001. package/src/code-agents/prompt-attachments.ts +39 -0
  1002. package/src/code-agents/transcript-normalizer.ts +750 -0
  1003. package/src/code-agents/transcript-order.ts +73 -0
  1004. package/src/coding-tools/index.ts +742 -0
  1005. package/src/coding-tools/run-code.ts +1662 -0
  1006. package/src/coding-tools/sandbox/adapter.ts +82 -0
  1007. package/src/coding-tools/sandbox/background.ts +406 -0
  1008. package/src/coding-tools/sandbox/executions-store.ts +517 -0
  1009. package/src/coding-tools/sandbox/index.ts +132 -0
  1010. package/src/coding-tools/sandbox/local-child-process-adapter.ts +217 -0
  1011. package/src/collab/agent-identity.ts +5 -0
  1012. package/src/collab/agent-presence.ts +341 -0
  1013. package/src/collab/awareness-store.ts +196 -0
  1014. package/src/collab/awareness.ts +317 -0
  1015. package/src/collab/client-struct.ts +366 -0
  1016. package/src/collab/client.ts +1205 -0
  1017. package/src/collab/emitter.ts +31 -0
  1018. package/src/collab/follow-mode.ts +107 -0
  1019. package/src/collab/index.ts +151 -0
  1020. package/src/collab/json-to-yjs.ts +504 -0
  1021. package/src/collab/presence.ts +207 -0
  1022. package/src/collab/recent-edits.ts +215 -0
  1023. package/src/collab/routes.ts +191 -0
  1024. package/src/collab/storage.ts +228 -0
  1025. package/src/collab/struct-routes.ts +133 -0
  1026. package/src/collab/text-to-yjs.ts +79 -0
  1027. package/src/collab/undo.ts +432 -0
  1028. package/src/collab/xml-ops.ts +68 -0
  1029. package/src/collab/ydoc-manager.ts +544 -0
  1030. package/src/command-navigation/actions.ts +100 -0
  1031. package/src/command-navigation/index.ts +12 -0
  1032. package/src/comments-review/index.ts +1 -0
  1033. package/src/connections/catalog.ts +451 -0
  1034. package/src/connections/index.ts +48 -0
  1035. package/src/connections/reader.ts +911 -0
  1036. package/src/connections/runtime.ts +1 -0
  1037. package/src/credentials/index.ts +187 -0
  1038. package/src/data-programs/actions.ts +335 -0
  1039. package/src/data-programs/contract.ts +284 -0
  1040. package/src/data-programs/execute.ts +693 -0
  1041. package/src/data-programs/index.ts +72 -0
  1042. package/src/data-programs/schema.ts +148 -0
  1043. package/src/data-programs/store.ts +755 -0
  1044. package/src/data-widgets/index.ts +376 -0
  1045. package/src/db/client.ts +1627 -0
  1046. package/src/db/create-get-db.ts +579 -0
  1047. package/src/db/ddl-guard.ts +302 -0
  1048. package/src/db/drizzle-config.ts +190 -0
  1049. package/src/db/ensure-additive-columns.ts +430 -0
  1050. package/src/db/index.ts +57 -0
  1051. package/src/db/migrations.ts +691 -0
  1052. package/src/db/request-telemetry.ts +154 -0
  1053. package/src/db/runtime-diagnostics.ts +331 -0
  1054. package/src/db/schema.ts +121 -0
  1055. package/src/db/widen-columns.ts +75 -0
  1056. package/src/db-admin/agent-tools.ts +202 -0
  1057. package/src/db-admin/index.ts +26 -0
  1058. package/src/db-admin/operations.ts +803 -0
  1059. package/src/db-admin/routes.ts +174 -0
  1060. package/src/db-admin/types.ts +110 -0
  1061. package/src/demo/browser-state.ts +47 -0
  1062. package/src/demo/fetch-interceptor.ts +175 -0
  1063. package/src/demo/redact.ts +575 -0
  1064. package/src/deploy/build.ts +3938 -0
  1065. package/src/deploy/immutable-assets.ts +65 -0
  1066. package/src/deploy/route-discovery.ts +458 -0
  1067. package/src/deploy/workspace-core.ts +282 -0
  1068. package/src/deploy/workspace-deploy.ts +1488 -0
  1069. package/src/eject/provider-api-definitions.ts +193 -0
  1070. package/src/eject/remote-mcp-presets.ts +137 -0
  1071. package/src/eject/setup-readiness-ui.tsx +29 -0
  1072. package/src/eject/workspace-connections.ts +92 -0
  1073. package/src/embedding/agent.ts +159 -0
  1074. package/src/embedding/bridge.ts +297 -0
  1075. package/src/embedding/index.ts +43 -0
  1076. package/src/embedding/protocol.ts +185 -0
  1077. package/src/embedding/react.tsx +319 -0
  1078. package/src/embeddings/index.ts +233 -0
  1079. package/src/eval/agent-runner.ts +210 -0
  1080. package/src/eval/define-eval.ts +55 -0
  1081. package/src/eval/index.ts +49 -0
  1082. package/src/eval/report.ts +75 -0
  1083. package/src/eval/runner.ts +369 -0
  1084. package/src/eval/scorer.ts +244 -0
  1085. package/src/eval/types.ts +188 -0
  1086. package/src/event-bus/bus.ts +140 -0
  1087. package/src/event-bus/index.ts +3 -0
  1088. package/src/event-bus/registry.ts +79 -0
  1089. package/src/event-bus/types.ts +29 -0
  1090. package/src/extensions/actions.ts +1636 -0
  1091. package/src/extensions/change-marker.ts +54 -0
  1092. package/src/extensions/content-patch.ts +468 -0
  1093. package/src/extensions/fetch-tool.ts +461 -0
  1094. package/src/extensions/html-shell.ts +803 -0
  1095. package/src/extensions/local.ts +462 -0
  1096. package/src/extensions/path.ts +40 -0
  1097. package/src/extensions/proxy-security.ts +171 -0
  1098. package/src/extensions/routes.ts +1080 -0
  1099. package/src/extensions/schema.ts +269 -0
  1100. package/src/extensions/session-replay-iframe.ts +131 -0
  1101. package/src/extensions/slots/routes.ts +126 -0
  1102. package/src/extensions/slots/schema.ts +87 -0
  1103. package/src/extensions/slots/store.ts +450 -0
  1104. package/src/extensions/store.ts +1347 -0
  1105. package/src/extensions/theme.ts +114 -0
  1106. package/src/extensions/url-safety.ts +316 -0
  1107. package/src/extensions/web-content.ts +663 -0
  1108. package/src/extensions/web-search-tool.ts +437 -0
  1109. package/src/feature-flags/a2a-action-route.ts +56 -0
  1110. package/src/feature-flags/actions/get-feature-flags.ts +24 -0
  1111. package/src/feature-flags/actions/list-feature-flags.ts +69 -0
  1112. package/src/feature-flags/actions/set-feature-flag.ts +89 -0
  1113. package/src/feature-flags/index.ts +21 -0
  1114. package/src/feature-flags/permissions.ts +53 -0
  1115. package/src/feature-flags/plugin.ts +44 -0
  1116. package/src/feature-flags/registry.ts +96 -0
  1117. package/src/feature-flags/store.ts +176 -0
  1118. package/src/file-upload/actions/upload-image.ts +213 -0
  1119. package/src/file-upload/builder.ts +431 -0
  1120. package/src/file-upload/index.ts +24 -0
  1121. package/src/file-upload/pre-upload-attachments.ts +305 -0
  1122. package/src/file-upload/registry.ts +125 -0
  1123. package/src/file-upload/types.ts +89 -0
  1124. package/src/guards/db-tool-scoping.ts +129 -0
  1125. package/src/guards/index.ts +23 -0
  1126. package/src/guards/no-drizzle-push.ts +116 -0
  1127. package/src/guards/no-env-credentials.ts +229 -0
  1128. package/src/guards/no-env-mutation.ts +114 -0
  1129. package/src/guards/no-localhost-fallback.ts +124 -0
  1130. package/src/guards/no-unscoped-credentials.ts +227 -0
  1131. package/src/guards/no-unscoped-queries.ts +834 -0
  1132. package/src/guards/scan-utils.ts +105 -0
  1133. package/src/guards/types.ts +30 -0
  1134. package/src/history/actions/create-resource-version.ts +92 -0
  1135. package/src/history/actions/get-resource-version.ts +60 -0
  1136. package/src/history/actions/list-resource-history.ts +53 -0
  1137. package/src/history/actions/list-resource-versions.ts +43 -0
  1138. package/src/history/actions/restore-resource-version.ts +96 -0
  1139. package/src/history/index.ts +26 -0
  1140. package/src/history/registry.ts +111 -0
  1141. package/src/history/store.ts +379 -0
  1142. package/src/history/types.ts +69 -0
  1143. package/src/index.browser.ts +155 -0
  1144. package/src/index.ts +408 -0
  1145. package/src/ingestion/docx.ts +158 -0
  1146. package/src/ingestion/figma-node-to-html.ts +1860 -0
  1147. package/src/ingestion/figma.ts +548 -0
  1148. package/src/ingestion/index.ts +107 -0
  1149. package/src/ingestion/media.ts +264 -0
  1150. package/src/ingestion/notion.ts +121 -0
  1151. package/src/ingestion/office.ts +213 -0
  1152. package/src/ingestion/orchestration.ts +160 -0
  1153. package/src/ingestion/pptx.ts +331 -0
  1154. package/src/ingestion/selection.ts +81 -0
  1155. package/src/ingestion/website.ts +151 -0
  1156. package/src/integrations/a2a-continuation-marker.ts +2 -0
  1157. package/src/integrations/a2a-continuation-processor.ts +888 -0
  1158. package/src/integrations/a2a-continuations-store.ts +643 -0
  1159. package/src/integrations/adapter-overrides.ts +12 -0
  1160. package/src/integrations/adapters/discord.ts +364 -0
  1161. package/src/integrations/adapters/email.ts +1164 -0
  1162. package/src/integrations/adapters/google-docs.ts +371 -0
  1163. package/src/integrations/adapters/index.ts +29 -0
  1164. package/src/integrations/adapters/microsoft-teams.ts +413 -0
  1165. package/src/integrations/adapters/slack.ts +1914 -0
  1166. package/src/integrations/adapters/telegram.ts +386 -0
  1167. package/src/integrations/adapters/whatsapp.ts +358 -0
  1168. package/src/integrations/awaiting-input-store.ts +130 -0
  1169. package/src/integrations/catalog.ts +571 -0
  1170. package/src/integrations/computer-supervision-store.ts +423 -0
  1171. package/src/integrations/computer-supervision.ts +213 -0
  1172. package/src/integrations/config-store.ts +131 -0
  1173. package/src/integrations/controls-store.ts +187 -0
  1174. package/src/integrations/eject/messaging-adapters.ts +85 -0
  1175. package/src/integrations/google-docs-poller.ts +671 -0
  1176. package/src/integrations/identity-links-store.ts +210 -0
  1177. package/src/integrations/identity.ts +196 -0
  1178. package/src/integrations/index.ts +220 -0
  1179. package/src/integrations/installations-store.ts +677 -0
  1180. package/src/integrations/integration-memory.ts +187 -0
  1181. package/src/integrations/internal-token.ts +106 -0
  1182. package/src/integrations/pending-tasks-retry-job.ts +286 -0
  1183. package/src/integrations/pending-tasks-store.ts +468 -0
  1184. package/src/integrations/plugin.ts +3048 -0
  1185. package/src/integrations/remote-commands-store.ts +690 -0
  1186. package/src/integrations/remote-devices-store.ts +492 -0
  1187. package/src/integrations/remote-json-safety.ts +127 -0
  1188. package/src/integrations/remote-push-delivery-job.ts +48 -0
  1189. package/src/integrations/remote-push-delivery.ts +370 -0
  1190. package/src/integrations/remote-push-store.ts +664 -0
  1191. package/src/integrations/remote-retry-job.ts +55 -0
  1192. package/src/integrations/remote-run-events-store.ts +222 -0
  1193. package/src/integrations/remote-types.ts +186 -0
  1194. package/src/integrations/runtime.ts +1 -0
  1195. package/src/integrations/scope-store.ts +498 -0
  1196. package/src/integrations/slack-manifest.ts +78 -0
  1197. package/src/integrations/slack-oauth.ts +344 -0
  1198. package/src/integrations/task-queue-stats.ts +144 -0
  1199. package/src/integrations/thread-mapping-store.ts +134 -0
  1200. package/src/integrations/types.ts +485 -0
  1201. package/src/integrations/usage-budget-store.ts +906 -0
  1202. package/src/integrations/webhook-delivery.ts +55 -0
  1203. package/src/integrations/webhook-handler.ts +1939 -0
  1204. package/src/jobs/actions/list-recurring-jobs.ts +105 -0
  1205. package/src/jobs/actions/manage-recurring-job.ts +85 -0
  1206. package/src/jobs/cron.ts +126 -0
  1207. package/src/jobs/index.ts +9 -0
  1208. package/src/jobs/scheduler.ts +703 -0
  1209. package/src/jobs/tools.ts +367 -0
  1210. package/src/local-artifacts/index.ts +1372 -0
  1211. package/src/localization/actions/get-localization-preference.ts +24 -0
  1212. package/src/localization/actions/set-localization-preference.ts +32 -0
  1213. package/src/localization/default-messages.ts +1009 -0
  1214. package/src/localization/index.ts +2 -0
  1215. package/src/localization/server.ts +131 -0
  1216. package/src/localization/shared.ts +208 -0
  1217. package/src/mcp/actions/call-mcp-tool.ts +19 -0
  1218. package/src/mcp/actions/create-org-service-token.ts +87 -0
  1219. package/src/mcp/actions/list-mcp-tools.ts +18 -0
  1220. package/src/mcp/actions/list-org-service-tokens.ts +44 -0
  1221. package/src/mcp/actions/revoke-org-service-token.ts +30 -0
  1222. package/src/mcp/actions/service-token-access.ts +121 -0
  1223. package/src/mcp/ask-app-inline-tasks.ts +125 -0
  1224. package/src/mcp/build-server.ts +2356 -0
  1225. package/src/mcp/builtin-tools.ts +1506 -0
  1226. package/src/mcp/connect-route.ts +1460 -0
  1227. package/src/mcp/connect-store.ts +680 -0
  1228. package/src/mcp/embed-app.ts +2051 -0
  1229. package/src/mcp/embed-route.ts +84 -0
  1230. package/src/mcp/external-agent-policy.ts +18 -0
  1231. package/src/mcp/index.ts +47 -0
  1232. package/src/mcp/oauth-route.ts +1016 -0
  1233. package/src/mcp/oauth-store.ts +581 -0
  1234. package/src/mcp/oauth-token.ts +227 -0
  1235. package/src/mcp/org-directory.ts +343 -0
  1236. package/src/mcp/route-paths.ts +34 -0
  1237. package/src/mcp/screen-memory-stdio.ts +290 -0
  1238. package/src/mcp/server.ts +507 -0
  1239. package/src/mcp/stdio.ts +328 -0
  1240. package/src/mcp/workspace-resolve.ts +261 -0
  1241. package/src/mcp-client/app-api.ts +136 -0
  1242. package/src/mcp-client/app-result.ts +64 -0
  1243. package/src/mcp-client/builtin-capabilities.ts +146 -0
  1244. package/src/mcp-client/builtin-store.ts +93 -0
  1245. package/src/mcp-client/config.ts +281 -0
  1246. package/src/mcp-client/errors.ts +54 -0
  1247. package/src/mcp-client/hub-client.ts +172 -0
  1248. package/src/mcp-client/hub-routes.ts +198 -0
  1249. package/src/mcp-client/index.ts +504 -0
  1250. package/src/mcp-client/manager.ts +968 -0
  1251. package/src/mcp-client/oauth-client.ts +462 -0
  1252. package/src/mcp-client/oauth-routes.ts +307 -0
  1253. package/src/mcp-client/remote-store.ts +674 -0
  1254. package/src/mcp-client/remote-url.ts +97 -0
  1255. package/src/mcp-client/routes.ts +1093 -0
  1256. package/src/mcp-client/screen-memory-local.ts +461 -0
  1257. package/src/mcp-client/tool-policy.ts +182 -0
  1258. package/src/mcp-client/visibility.ts +56 -0
  1259. package/src/mcp-client/workspace-servers.ts +379 -0
  1260. package/src/navigation/index.ts +170 -0
  1261. package/src/notifications/actions.ts +151 -0
  1262. package/src/notifications/channels.ts +410 -0
  1263. package/src/notifications/index.ts +22 -0
  1264. package/src/notifications/registry.ts +216 -0
  1265. package/src/notifications/routes.ts +106 -0
  1266. package/src/notifications/store.ts +236 -0
  1267. package/src/notifications/types.ts +52 -0
  1268. package/src/oauth-tokens/google-refresh.ts +175 -0
  1269. package/src/oauth-tokens/index.ts +15 -0
  1270. package/src/oauth-tokens/store.ts +384 -0
  1271. package/src/observability/cleanup-job.ts +124 -0
  1272. package/src/observability/evals.ts +507 -0
  1273. package/src/observability/experiments.ts +359 -0
  1274. package/src/observability/feedback.ts +332 -0
  1275. package/src/observability/hosted-model-experiment.ts +118 -0
  1276. package/src/observability/index.ts +62 -0
  1277. package/src/observability/plugin.ts +31 -0
  1278. package/src/observability/routes.ts +431 -0
  1279. package/src/observability/sentiment.ts +261 -0
  1280. package/src/observability/store.ts +1347 -0
  1281. package/src/observability/traces.ts +789 -0
  1282. package/src/observability/tracing.ts +157 -0
  1283. package/src/observability/tracking-identity.ts +55 -0
  1284. package/src/observability/types.ts +211 -0
  1285. package/src/onboarding/default-steps.ts +428 -0
  1286. package/src/onboarding/index.ts +22 -0
  1287. package/src/onboarding/plugin.ts +262 -0
  1288. package/src/onboarding/registry.ts +47 -0
  1289. package/src/onboarding/types.ts +96 -0
  1290. package/src/org/accept-pending.ts +98 -0
  1291. package/src/org/auto-join-domain.ts +113 -0
  1292. package/src/org/context.ts +640 -0
  1293. package/src/org/free-email-providers.ts +124 -0
  1294. package/src/org/handlers.ts +1153 -0
  1295. package/src/org/index.ts +63 -0
  1296. package/src/org/migrations.ts +105 -0
  1297. package/src/org/permissions.ts +30 -0
  1298. package/src/org/plugin.ts +255 -0
  1299. package/src/org/schema.ts +28 -0
  1300. package/src/org/types.ts +57 -0
  1301. package/src/org-team/index.ts +1 -0
  1302. package/src/package-lifecycle/deprecated-imports.ts +179 -0
  1303. package/src/package-lifecycle/eject-manifest.ts +345 -0
  1304. package/src/package-lifecycle/index.ts +7 -0
  1305. package/src/package-lifecycle/manifest.ts +120 -0
  1306. package/src/package-lifecycle/migration-manifest.ts +159 -0
  1307. package/src/package-lifecycle/migration-message.ts +6 -0
  1308. package/src/package-lifecycle/tombstone.ts +58 -0
  1309. package/src/package-lifecycle/upgrade-error.ts +37 -0
  1310. package/src/private-blob/index.ts +18 -0
  1311. package/src/private-blob/registry.ts +242 -0
  1312. package/src/private-blob/types.ts +55 -0
  1313. package/src/progress/actions.ts +179 -0
  1314. package/src/progress/index.ts +16 -0
  1315. package/src/progress/registry.ts +127 -0
  1316. package/src/progress/routes.ts +89 -0
  1317. package/src/progress/store.ts +353 -0
  1318. package/src/progress/types.ts +59 -0
  1319. package/src/provider-api/actions/custom-provider-registration.ts +197 -0
  1320. package/src/provider-api/actions/delete-staged-dataset.ts +5 -0
  1321. package/src/provider-api/actions/github-repo-files.ts +266 -0
  1322. package/src/provider-api/actions/list-staged-datasets.ts +5 -0
  1323. package/src/provider-api/actions/provider-api-audit.ts +88 -0
  1324. package/src/provider-api/actions/provider-api.ts +460 -0
  1325. package/src/provider-api/actions/query-staged-dataset.ts +5 -0
  1326. package/src/provider-api/actions/staged-datasets.ts +359 -0
  1327. package/src/provider-api/corpus-jobs-store.ts +522 -0
  1328. package/src/provider-api/corpus-jobs.ts +1817 -0
  1329. package/src/provider-api/custom-registry.ts +456 -0
  1330. package/src/provider-api/github-repo.ts +675 -0
  1331. package/src/provider-api/gong.ts +108 -0
  1332. package/src/provider-api/index.ts +5444 -0
  1333. package/src/provider-api/quota-governor.ts +562 -0
  1334. package/src/provider-api/runtime.ts +1 -0
  1335. package/src/provider-api/staged-datasets-aggregate.ts +304 -0
  1336. package/src/provider-api/staged-datasets-store.ts +441 -0
  1337. package/src/provider-api/staging.ts +483 -0
  1338. package/src/resources/agents.ts +65 -0
  1339. package/src/resources/emitter.ts +54 -0
  1340. package/src/resources/handlers.ts +728 -0
  1341. package/src/resources/index.ts +4 -0
  1342. package/src/resources/metadata.ts +252 -0
  1343. package/src/resources/script-helpers.ts +160 -0
  1344. package/src/resources/store.ts +1618 -0
  1345. package/src/review/actions/consume-review-feedback.ts +48 -0
  1346. package/src/review/actions/create-review-comment.ts +108 -0
  1347. package/src/review/actions/delete-review-comment.ts +67 -0
  1348. package/src/review/actions/get-review-feedback.ts +49 -0
  1349. package/src/review/actions/list-review-comments.ts +87 -0
  1350. package/src/review/actions/reply-review-comment.ts +118 -0
  1351. package/src/review/actions/resolve-review-thread.ts +94 -0
  1352. package/src/review/actions/send-review-thread-to-agent.ts +62 -0
  1353. package/src/review/actions/set-review-status.ts +58 -0
  1354. package/src/review/identity.ts +101 -0
  1355. package/src/review/index.ts +45 -0
  1356. package/src/review/mentions.ts +44 -0
  1357. package/src/review/registry.ts +111 -0
  1358. package/src/review/store.ts +997 -0
  1359. package/src/review/types.ts +101 -0
  1360. package/src/router/index.ts +24 -0
  1361. package/src/scripts/agent-engines/list-agent-engines.ts +130 -0
  1362. package/src/scripts/agent-engines/manage-agent-engine.ts +197 -0
  1363. package/src/scripts/agent-engines/set-agent-engine.ts +84 -0
  1364. package/src/scripts/agent-engines/test-agent-engine.ts +174 -0
  1365. package/src/scripts/call-agent.ts +792 -0
  1366. package/src/scripts/chat/index.ts +8 -0
  1367. package/src/scripts/chat/open-chat.ts +56 -0
  1368. package/src/scripts/chat/search-chats.ts +121 -0
  1369. package/src/scripts/core-scripts.ts +22 -0
  1370. package/src/scripts/db/check-scoping.ts +212 -0
  1371. package/src/scripts/db/exec.ts +791 -0
  1372. package/src/scripts/db/index.ts +19 -0
  1373. package/src/scripts/db/migrate-encrypt-credentials.ts +223 -0
  1374. package/src/scripts/db/migrate-encrypt-oauth-tokens.ts +213 -0
  1375. package/src/scripts/db/migrate-user-api-keys.ts +257 -0
  1376. package/src/scripts/db/patch.ts +820 -0
  1377. package/src/scripts/db/query.ts +299 -0
  1378. package/src/scripts/db/reset-dev-owner.ts +285 -0
  1379. package/src/scripts/db/safety.ts +286 -0
  1380. package/src/scripts/db/schema.ts +364 -0
  1381. package/src/scripts/db/scoping.ts +341 -0
  1382. package/src/scripts/db/sqlite-client.ts +78 -0
  1383. package/src/scripts/db/tool-mode.ts +23 -0
  1384. package/src/scripts/db/tool-schemas.ts +31 -0
  1385. package/src/scripts/db/wipe-leaked-builder-keys.ts +201 -0
  1386. package/src/scripts/dev/index.ts +296 -0
  1387. package/src/scripts/dev/list-files.ts +119 -0
  1388. package/src/scripts/dev/read-file.ts +77 -0
  1389. package/src/scripts/dev/search-files.ts +151 -0
  1390. package/src/scripts/dev/shell.ts +111 -0
  1391. package/src/scripts/dev/write-file.ts +56 -0
  1392. package/src/scripts/dev-session.ts +96 -0
  1393. package/src/scripts/docs/index.ts +8 -0
  1394. package/src/scripts/docs/search.ts +274 -0
  1395. package/src/scripts/docs/source-search.ts +363 -0
  1396. package/src/scripts/index.ts +15 -0
  1397. package/src/scripts/manage-agent-loop-settings.ts +84 -0
  1398. package/src/scripts/parse-args.ts +46 -0
  1399. package/src/scripts/resources/delete-memory.ts +67 -0
  1400. package/src/scripts/resources/delete.ts +69 -0
  1401. package/src/scripts/resources/effective.ts +71 -0
  1402. package/src/scripts/resources/index.ts +18 -0
  1403. package/src/scripts/resources/list.ts +103 -0
  1404. package/src/scripts/resources/migrate-learnings.ts +40 -0
  1405. package/src/scripts/resources/read.ts +107 -0
  1406. package/src/scripts/resources/save-memory.ts +99 -0
  1407. package/src/scripts/resources/write.ts +158 -0
  1408. package/src/scripts/runner.ts +339 -0
  1409. package/src/scripts/utils.ts +130 -0
  1410. package/src/search/index.ts +413 -0
  1411. package/src/search-utils/index.ts +112 -0
  1412. package/src/secrets/crypto.ts +228 -0
  1413. package/src/secrets/index.ts +65 -0
  1414. package/src/secrets/onboarding.ts +101 -0
  1415. package/src/secrets/register-framework-secrets.ts +228 -0
  1416. package/src/secrets/register.ts +129 -0
  1417. package/src/secrets/routes.ts +697 -0
  1418. package/src/secrets/schema.ts +52 -0
  1419. package/src/secrets/storage.ts +561 -0
  1420. package/src/secrets/substitution.ts +305 -0
  1421. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +150 -0
  1422. package/src/server/action-change.ts +66 -0
  1423. package/src/server/action-discovery.ts +774 -0
  1424. package/src/server/action-routes.ts +658 -0
  1425. package/src/server/agent-access.ts +72 -0
  1426. package/src/server/agent-chat/action-filters-a2a.ts +339 -0
  1427. package/src/server/agent-chat/browser-team-tools.ts +510 -0
  1428. package/src/server/agent-chat/context-tools.ts +599 -0
  1429. package/src/server/agent-chat/framework-prompts.ts +467 -0
  1430. package/src/server/agent-chat/lazy-fs.ts +11 -0
  1431. package/src/server/agent-chat/mcp-glue.ts +91 -0
  1432. package/src/server/agent-chat/plugin-options.ts +379 -0
  1433. package/src/server/agent-chat/process-run-failure.ts +62 -0
  1434. package/src/server/agent-chat/prompt-resources.ts +1004 -0
  1435. package/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
  1436. package/src/server/agent-chat/request-surface.ts +71 -0
  1437. package/src/server/agent-chat/run-code-tools.ts +67 -0
  1438. package/src/server/agent-chat/script-entries.ts +796 -0
  1439. package/src/server/agent-chat/shared-thread.ts +301 -0
  1440. package/src/server/agent-chat/skill-frontmatter.ts +41 -0
  1441. package/src/server/agent-chat-plugin.ts +5930 -0
  1442. package/src/server/agent-discovery.ts +706 -0
  1443. package/src/server/agent-engine-api-key-route.ts +236 -0
  1444. package/src/server/agent-run-context.ts +204 -0
  1445. package/src/server/agent-teams-run-queue.ts +344 -0
  1446. package/src/server/agent-teams.ts +2257 -0
  1447. package/src/server/agents-bundle.ts +464 -0
  1448. package/src/server/analytics.ts +105 -0
  1449. package/src/server/app-base-path.ts +79 -0
  1450. package/src/server/app-name.ts +53 -0
  1451. package/src/server/app-url.ts +184 -0
  1452. package/src/server/attachment-actions.ts +276 -0
  1453. package/src/server/attribution.ts +214 -0
  1454. package/src/server/auth-marketing.ts +260 -0
  1455. package/src/server/auth-plugin.ts +32 -0
  1456. package/src/server/auth.ts +3803 -0
  1457. package/src/server/better-auth-instance.ts +1201 -0
  1458. package/src/server/builder-browser.ts +1701 -0
  1459. package/src/server/builder-design-systems.ts +668 -0
  1460. package/src/server/builder-space.ts +176 -0
  1461. package/src/server/captcha.ts +63 -0
  1462. package/src/server/capture-error.ts +64 -0
  1463. package/src/server/cli-capture.ts +141 -0
  1464. package/src/server/collab-plugin.ts +391 -0
  1465. package/src/server/complete-text.ts +231 -0
  1466. package/src/server/cookie-namespace.ts +159 -0
  1467. package/src/server/core-routes-plugin.ts +4122 -0
  1468. package/src/server/cors-origins.ts +60 -0
  1469. package/src/server/create-server.ts +268 -0
  1470. package/src/server/credential-provider.ts +1202 -0
  1471. package/src/server/csrf.ts +229 -0
  1472. package/src/server/date-utils.ts +42 -0
  1473. package/src/server/deep-link.ts +119 -0
  1474. package/src/server/derived-secret.ts +32 -0
  1475. package/src/server/design-token-utils.ts +1032 -0
  1476. package/src/server/desktop-sso.ts +83 -0
  1477. package/src/server/edge.ts +69 -0
  1478. package/src/server/email-actions.ts +218 -0
  1479. package/src/server/email-template.ts +192 -0
  1480. package/src/server/email-templates.ts +148 -0
  1481. package/src/server/email.ts +219 -0
  1482. package/src/server/embed-route.ts +283 -0
  1483. package/src/server/embed-session.ts +805 -0
  1484. package/src/server/embedded.ts +252 -0
  1485. package/src/server/entry-server.tsx +154 -0
  1486. package/src/server/framework-request-handler.ts +848 -0
  1487. package/src/server/fusion-app.ts +447 -0
  1488. package/src/server/google-auth-mode.ts +34 -0
  1489. package/src/server/google-auth-plugin.ts +496 -0
  1490. package/src/server/google-oauth-credentials.ts +128 -0
  1491. package/src/server/google-oauth.ts +972 -0
  1492. package/src/server/google-realtime-session.ts +182 -0
  1493. package/src/server/h3-helpers.ts +174 -0
  1494. package/src/server/http-response-telemetry.ts +396 -0
  1495. package/src/server/identity-sso-store.ts +304 -0
  1496. package/src/server/identity-sso.ts +514 -0
  1497. package/src/server/index.ts +593 -0
  1498. package/src/server/missing-key.ts +36 -0
  1499. package/src/server/oauth-helpers.ts +44 -0
  1500. package/src/server/oauth-public-origin.ts +44 -0
  1501. package/src/server/oauth-return-url.ts +120 -0
  1502. package/src/server/og-fonts-data.ts +15 -0
  1503. package/src/server/og-fonts.ts +75 -0
  1504. package/src/server/onboarding-html.ts +4040 -0
  1505. package/src/server/open-route.ts +311 -0
  1506. package/src/server/org-admin.ts +28 -0
  1507. package/src/server/poll-events.ts +88 -0
  1508. package/src/server/poll.ts +1224 -0
  1509. package/src/server/prompts/framework-core-compact.ts +107 -0
  1510. package/src/server/prompts/framework-core.ts +143 -0
  1511. package/src/server/prompts/index.ts +16 -0
  1512. package/src/server/prompts/model-overlays.ts +54 -0
  1513. package/src/server/prompts/shared-rules.ts +104 -0
  1514. package/src/server/realtime-voice.ts +967 -0
  1515. package/src/server/recap-image-route.ts +242 -0
  1516. package/src/server/recap-image-store.ts +185 -0
  1517. package/src/server/request-context.ts +416 -0
  1518. package/src/server/request-origin.ts +67 -0
  1519. package/src/server/resources-plugin.ts +119 -0
  1520. package/src/server/schema-prompt.ts +429 -0
  1521. package/src/server/scoped-key-storage.ts +223 -0
  1522. package/src/server/security-headers.ts +170 -0
  1523. package/src/server/self-dispatch.ts +224 -0
  1524. package/src/server/sentry-config.ts +73 -0
  1525. package/src/server/sentry-plugin.ts +138 -0
  1526. package/src/server/sentry.ts +444 -0
  1527. package/src/server/short-lived-token.ts +170 -0
  1528. package/src/server/social-og-image.ts +454 -0
  1529. package/src/server/sse.ts +102 -0
  1530. package/src/server/ssr-handler.ts +466 -0
  1531. package/src/server/transcribe-voice.ts +1076 -0
  1532. package/src/server/voice-providers-status.ts +118 -0
  1533. package/src/server/workspace-oauth.ts +31 -0
  1534. package/src/server/workspace-provider-oauth.ts +970 -0
  1535. package/src/session-replay-iframe-protocol.ts +58 -0
  1536. package/src/settings/handlers.ts +44 -0
  1537. package/src/settings/index.ts +34 -0
  1538. package/src/settings/org-settings.ts +83 -0
  1539. package/src/settings/script-helpers.ts +24 -0
  1540. package/src/settings/store.ts +247 -0
  1541. package/src/settings/user-settings.ts +47 -0
  1542. package/src/setup-connections/index.ts +90 -0
  1543. package/src/setup-connections/onboarding.ts +47 -0
  1544. package/src/shared/agent-access.ts +112 -0
  1545. package/src/shared/agent-chat.ts +124 -0
  1546. package/src/shared/agent-env.ts +46 -0
  1547. package/src/shared/agent-readable-resource.ts +111 -0
  1548. package/src/shared/agent-sidebar-url.ts +39 -0
  1549. package/src/shared/cache-control.ts +25 -0
  1550. package/src/shared/cloudflare-globals.d.ts +34 -0
  1551. package/src/shared/context-xray.ts +172 -0
  1552. package/src/shared/embed-auth.ts +6 -0
  1553. package/src/shared/index.ts +83 -0
  1554. package/src/shared/llm-connection.ts +42 -0
  1555. package/src/shared/markdown-block-split.ts +129 -0
  1556. package/src/shared/mcp-connect-content.ts +130 -0
  1557. package/src/shared/mcp-embed-headers.ts +175 -0
  1558. package/src/shared/mcp-integration-config.ts +101 -0
  1559. package/src/shared/merge-by-id.ts +14 -0
  1560. package/src/shared/oauth-state.ts +39 -0
  1561. package/src/shared/reasoning-effort.ts +228 -0
  1562. package/src/shared/route-warmup-config.ts +128 -0
  1563. package/src/shared/runtime.ts +31 -0
  1564. package/src/shared/social-meta.ts +82 -0
  1565. package/src/shared/streaming-text-smoothing.ts +184 -0
  1566. package/src/shared/truncate.ts +13 -0
  1567. package/src/shared/workspace-app-audience.ts +177 -0
  1568. package/src/shared/workspace-app-id.ts +54 -0
  1569. package/src/sharing/access.ts +585 -0
  1570. package/src/sharing/actions/create-agent-resource-link.ts +91 -0
  1571. package/src/sharing/actions/extension-change.ts +22 -0
  1572. package/src/sharing/actions/list-resource-shares.ts +93 -0
  1573. package/src/sharing/actions/set-resource-visibility.ts +91 -0
  1574. package/src/sharing/actions/share-resource.ts +322 -0
  1575. package/src/sharing/actions/unshare-resource.ts +72 -0
  1576. package/src/sharing/index.ts +35 -0
  1577. package/src/sharing/registry.ts +201 -0
  1578. package/src/sharing/schema.ts +99 -0
  1579. package/src/styles/agent-conversation.css +766 -0
  1580. package/src/styles/agent-native.css +938 -0
  1581. package/src/styles/blocks.css +1717 -0
  1582. package/src/styles/chat-history-list.css +1 -0
  1583. package/src/styles/rich-markdown-editor.css +1 -0
  1584. package/src/tailwind.preset.ts +140 -0
  1585. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1586. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1587. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1588. package/src/templates/chat/AGENTS.md +3 -2
  1589. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1590. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1591. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1592. package/src/templates/default/AGENTS.md +6 -5
  1593. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1594. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1595. package/src/templates/headless/AGENTS.md +5 -4
  1596. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +15 -13
  1597. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +3 -2
  1598. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +63 -20
  1599. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +9 -6
  1600. package/src/templates/workspace-core/AGENTS.md +4 -4
  1601. package/src/templates/workspace-root/AGENTS.md +4 -4
  1602. package/src/terminal/cli-registry.ts +57 -0
  1603. package/src/terminal/index.ts +22 -0
  1604. package/src/terminal/pty-server.ts +389 -0
  1605. package/src/terminal/terminal-plugin.ts +265 -0
  1606. package/src/testing.ts +23 -0
  1607. package/src/tracking/index.ts +10 -0
  1608. package/src/tracking/providers.ts +422 -0
  1609. package/src/tracking/registry.ts +102 -0
  1610. package/src/tracking/route.ts +108 -0
  1611. package/src/tracking/types.ts +16 -0
  1612. package/src/transcription/builder-transcription.ts +118 -0
  1613. package/src/triggers/actions/list-automations.ts +99 -0
  1614. package/src/triggers/actions/manage-automation.ts +78 -0
  1615. package/src/triggers/actions.ts +333 -0
  1616. package/src/triggers/condition-evaluator.ts +163 -0
  1617. package/src/triggers/dispatcher.ts +536 -0
  1618. package/src/triggers/index.ts +13 -0
  1619. package/src/triggers/routes.ts +322 -0
  1620. package/src/triggers/types.ts +42 -0
  1621. package/src/types/pglite.d.ts +26 -0
  1622. package/src/usage/store.ts +698 -0
  1623. package/src/vite/action-types-plugin.ts +481 -0
  1624. package/src/vite/agent-web-plugin.ts +78 -0
  1625. package/src/vite/agents-bundle-plugin.ts +185 -0
  1626. package/src/vite/client.ts +3056 -0
  1627. package/src/vite/index.ts +21 -0
  1628. package/src/voice/index.ts +18 -0
  1629. package/src/voice/voice-cleanup-prompt.ts +38 -0
  1630. package/src/voice/voice-context.ts +217 -0
  1631. package/src/voice/voice-replacements.ts +75 -0
  1632. package/src/workspace-connections/credentials.ts +603 -0
  1633. package/src/workspace-connections/index.ts +72 -0
  1634. package/src/workspace-connections/lifecycle.ts +43 -0
  1635. package/src/workspace-connections/store.ts +1943 -0
  1636. package/src/workspace-files/index.ts +18 -0
  1637. package/src/workspace-files/store.ts +339 -0
  1638. package/src/workspace-files/tool.ts +266 -0
@@ -0,0 +1,4340 @@
1
+ /**
2
+ * `agent-native skills` is the friendly install surface for app-backed skills.
3
+ * The lower-level `app-skill` commands remain the packaging primitives; this
4
+ * command handles the common "install Assets for my agent" path in one step.
5
+ */
6
+
7
+ import { spawn } from "node:child_process";
8
+ import { createHash } from "node:crypto";
9
+ import fs from "node:fs";
10
+ import os from "node:os";
11
+ import path from "node:path";
12
+ import { fileURLToPath } from "node:url";
13
+
14
+ import {
15
+ MCP_LEGACY_ROUTE_PREFIX,
16
+ MCP_PUBLIC_ROUTE_PREFIX,
17
+ } from "../mcp/route-paths.js";
18
+ import {
19
+ buildAppSkillPack,
20
+ ensureAppSkill,
21
+ loadAppSkillManifest,
22
+ normalizeAppSkillManifest,
23
+ type AppSkillManifest,
24
+ type LoadedAppSkillManifest,
25
+ } from "./app-skill.js";
26
+ import {
27
+ resolveClients,
28
+ runConnect,
29
+ writeConnectClientPreferences,
30
+ } from "./connect.js";
31
+ import {
32
+ CONTEXT_XRAY_SKILL_MD,
33
+ installLocalContextXray,
34
+ } from "./context-xray-local.js";
35
+ import { CLIENTS, type ClientId } from "./mcp-config-writers.js";
36
+ import { PR_VISUAL_RECAP_SETUP, writePrVisualRecapWorkflow } from "./recap.js";
37
+ import { setupAgentSymlinks } from "./setup-agents.js";
38
+ import {
39
+ ASSETS_SKILL_MD,
40
+ CANVAS_REFERENCE_MD,
41
+ CONNECTION_REFERENCE_MD,
42
+ CONTENT_SKILL_MD,
43
+ DESIGN_EXPLORATION_SKILL_MD,
44
+ DESIGN_VISUAL_EDIT_SKILL_MD,
45
+ DOCUMENT_QUALITY_REFERENCE_MD,
46
+ EXEMPLAR_REFERENCE_MD,
47
+ HELP,
48
+ LOCAL_FILES_REFERENCE_MD,
49
+ VISUAL_PLANS_SKILL_MD,
50
+ VISUAL_RECAP_SKILL_MD,
51
+ VISUALIZE_REPO_SKILL_MD,
52
+ WIREFRAME_REFERENCE_MD,
53
+ } from "./skills-content/index.js";
54
+ import { createCliTelemetry, type CliTelemetry } from "./telemetry.js";
55
+
56
+ export {
57
+ CANVAS_REFERENCE_MD,
58
+ CONNECTION_REFERENCE_MD,
59
+ DOCUMENT_QUALITY_REFERENCE_MD,
60
+ EXEMPLAR_REFERENCE_MD,
61
+ LOCAL_FILES_REFERENCE_MD,
62
+ VISUAL_PLANS_SKILL_MD,
63
+ VISUAL_RECAP_SKILL_MD,
64
+ VISUALIZE_REPO_SKILL_MD,
65
+ WIREFRAME_REFERENCE_MD,
66
+ };
67
+
68
+ export const BUILT_IN_APP_SKILLS = {
69
+ assets: {
70
+ skillName: "assets",
71
+ manifest: normalizeAppSkillManifest({
72
+ schemaVersion: 1,
73
+ id: "assets",
74
+ displayName: "Assets",
75
+ description:
76
+ "Create, search, select, and export brand image and video assets from the Assets app.",
77
+ hosted: {
78
+ url: "https://assets.agent-native.com",
79
+ mcpUrl: "https://assets.agent-native.com/mcp",
80
+ },
81
+ mcp: { serverName: "agent-native-assets" },
82
+ auth: {
83
+ mode: "oauth",
84
+ setup:
85
+ "Authenticate with the Assets MCP connector in the host app. No shared secrets are stored in skill files.",
86
+ },
87
+ surfaces: [
88
+ {
89
+ id: "asset-picker",
90
+ action: "open-asset-picker",
91
+ path: "/picker",
92
+ mediaTypes: ["image", "video"],
93
+ defaultMediaType: "image",
94
+ },
95
+ ],
96
+ skills: [
97
+ {
98
+ path: "skills/assets",
99
+ visibility: "exported",
100
+ exportAs: "assets",
101
+ },
102
+ ],
103
+ hostAdapters: [
104
+ "codex-plugin",
105
+ "claude-marketplace",
106
+ "vercel-skills",
107
+ "plain-skill",
108
+ "claude-skill",
109
+ "chatgpt-mcp",
110
+ "generic-mcp",
111
+ ],
112
+ }),
113
+ skillMarkdown: ASSETS_SKILL_MD,
114
+ },
115
+ content: {
116
+ skillName: "content",
117
+ manifest: normalizeAppSkillManifest({
118
+ schemaVersion: 1,
119
+ id: "content",
120
+ displayName: "Content",
121
+ description:
122
+ "Edit docs, blogs, resources, and MDX content through the Content app, including database-backed local-folder sources.",
123
+ hosted: {
124
+ url: "https://content.agent-native.com",
125
+ mcpUrl: "https://content.agent-native.com/mcp",
126
+ },
127
+ mcp: { serverName: "agent-native-content" },
128
+ auth: {
129
+ mode: "oauth",
130
+ setup:
131
+ "Authenticate with the Content MCP connector in the host app. Local-folder synchronization requires a local Content app, Agent Native Desktop, or trusted local bridge for filesystem access.",
132
+ },
133
+ surfaces: [
134
+ {
135
+ id: "content-documents",
136
+ action: "list-documents",
137
+ path: "/",
138
+ },
139
+ {
140
+ id: "content-local-files",
141
+ action: "share-local-file-document",
142
+ path: "/local-files",
143
+ },
144
+ ],
145
+ skills: [
146
+ {
147
+ path: "skills/content",
148
+ visibility: "exported",
149
+ exportAs: "content",
150
+ },
151
+ ],
152
+ hostAdapters: [
153
+ "codex-plugin",
154
+ "claude-marketplace",
155
+ "vercel-skills",
156
+ "plain-skill",
157
+ "claude-skill",
158
+ "chatgpt-mcp",
159
+ "generic-mcp",
160
+ ],
161
+ }),
162
+ skillMarkdown: CONTENT_SKILL_MD,
163
+ },
164
+ design: {
165
+ skillName: "design-exploration",
166
+ extraSkills: {
167
+ "visual-edit": DESIGN_VISUAL_EDIT_SKILL_MD,
168
+ },
169
+ manifest: normalizeAppSkillManifest({
170
+ schemaVersion: 1,
171
+ id: "design",
172
+ displayName: "Design",
173
+ description:
174
+ "Explore, compare, iterate, and export interactive UI design prototypes from the Design app.",
175
+ hosted: {
176
+ url: "https://design.agent-native.com",
177
+ mcpUrl: "https://design.agent-native.com/mcp",
178
+ },
179
+ mcp: { serverName: "agent-native-design" },
180
+ auth: {
181
+ mode: "oauth",
182
+ setup:
183
+ "Authenticate with the Design MCP connector in the host app. No shared secrets are stored in skill files.",
184
+ },
185
+ surfaces: [
186
+ {
187
+ id: "design-exploration",
188
+ action: "present-design-variants",
189
+ path: "/design",
190
+ },
191
+ {
192
+ id: "visual-edit",
193
+ action: "add-localhost-screens",
194
+ path: "/design",
195
+ },
196
+ ],
197
+ skills: [
198
+ {
199
+ path: "skills/design-exploration",
200
+ visibility: "exported",
201
+ exportAs: "design-exploration",
202
+ },
203
+ {
204
+ path: "skills/visual-edit",
205
+ visibility: "exported",
206
+ exportAs: "visual-edit",
207
+ },
208
+ ],
209
+ hostAdapters: [
210
+ "codex-plugin",
211
+ "claude-marketplace",
212
+ "vercel-skills",
213
+ "plain-skill",
214
+ "claude-skill",
215
+ "chatgpt-mcp",
216
+ "generic-mcp",
217
+ ],
218
+ }),
219
+ skillMarkdown: DESIGN_EXPLORATION_SKILL_MD,
220
+ },
221
+ "visual-plans": {
222
+ skillName: "visual-plan",
223
+ extraSkills: {
224
+ "visual-recap": VISUAL_RECAP_SKILL_MD,
225
+ "visualize-repo": VISUALIZE_REPO_SKILL_MD,
226
+ },
227
+ // Sibling reference files materialized alongside each skill's SKILL.md
228
+ // (progressive disclosure). Keyed by skill name -> relative path -> content.
229
+ // Both plan skills ship the same canonical wireframe-quality reference; the
230
+ // canvas / document-quality / exemplar references are visual-plan only.
231
+ extraFiles: {
232
+ "visual-plan": {
233
+ "references/wireframe.md": WIREFRAME_REFERENCE_MD,
234
+ "references/canvas.md": CANVAS_REFERENCE_MD,
235
+ "references/document-quality.md": DOCUMENT_QUALITY_REFERENCE_MD,
236
+ "references/exemplar.md": EXEMPLAR_REFERENCE_MD,
237
+ "references/connection.md": CONNECTION_REFERENCE_MD,
238
+ "references/local-files.md": LOCAL_FILES_REFERENCE_MD,
239
+ },
240
+ "visual-recap": {
241
+ "references/wireframe.md": WIREFRAME_REFERENCE_MD,
242
+ "references/connection.md": CONNECTION_REFERENCE_MD,
243
+ "references/local-files.md": LOCAL_FILES_REFERENCE_MD,
244
+ },
245
+ },
246
+ manifest: normalizeAppSkillManifest({
247
+ schemaVersion: 1,
248
+ id: "visual-plans",
249
+ displayName: "Agent-Native Plan",
250
+ description:
251
+ "Create rich interactive visual plans, recaps, and repo-native visual docs with diagrams, file maps, annotated code and diffs, API/schema summaries, feedback, and HTML export.",
252
+ hosted: {
253
+ url: "https://plan.agent-native.com",
254
+ mcpUrl: "https://plan.agent-native.com/mcp",
255
+ },
256
+ mcp: { serverName: "plan", aliases: ["agent-native-plans"] },
257
+ auth: {
258
+ mode: "oauth",
259
+ setup:
260
+ "The marketplace plugin uses hosted Agent-Native Plans by default. To choose local-files or self-hosted mode, install with the Agent-Native CLI. Authenticate only for hosted/account-backed sharing.",
261
+ },
262
+ surfaces: [
263
+ {
264
+ id: "visual-plan",
265
+ action: "create-visual-plan",
266
+ path: "/plans",
267
+ description:
268
+ "Create a rich interactive visual plan instead of a plain-text plan, with diagrams, file maps, annotated code, questions, and optional UI/prototype review.",
269
+ },
270
+ {
271
+ id: "visual-recap",
272
+ action: "create-visual-recap",
273
+ path: "/plans",
274
+ description:
275
+ "Create an interactive visual recap from a PR, commit, branch, or git diff so reviewers see the shape of the change before raw diff review.",
276
+ },
277
+ {
278
+ id: "visualize-repo",
279
+ path: "/local-plans",
280
+ description:
281
+ "Open a local, repo-backed visual documentation workspace for APIs, components, models, flows, comments, and coding-agent handoff.",
282
+ },
283
+ ],
284
+ skills: [
285
+ {
286
+ path: "skills/visual-plan",
287
+ visibility: "exported",
288
+ exportAs: "visual-plan",
289
+ },
290
+ {
291
+ path: "skills/visual-recap",
292
+ visibility: "exported",
293
+ exportAs: "visual-recap",
294
+ },
295
+ {
296
+ path: "skills/visualize-repo",
297
+ visibility: "exported",
298
+ exportAs: "visualize-repo",
299
+ },
300
+ ],
301
+ hostAdapters: [
302
+ "codex-plugin",
303
+ "claude-marketplace",
304
+ "vercel-skills",
305
+ "plain-skill",
306
+ "claude-skill",
307
+ "chatgpt-mcp",
308
+ "generic-mcp",
309
+ ],
310
+ }),
311
+ skillMarkdown: VISUAL_PLANS_SKILL_MD,
312
+ },
313
+ "context-xray": {
314
+ skillName: "context-xray",
315
+ localOnly: true,
316
+ manifest: normalizeAppSkillManifest({
317
+ schemaVersion: 1,
318
+ id: "context-xray",
319
+ displayName: "Context X-Ray",
320
+ description:
321
+ "Visualize local Codex and Claude Code context usage with warnings and optimization tips.",
322
+ hosted: {
323
+ url: "https://context-xray.agent-native.com",
324
+ mcpUrl: "https://context-xray.agent-native.com/mcp",
325
+ },
326
+ mcp: { serverName: "agent-native-context-xray" },
327
+ auth: { mode: "none" },
328
+ surfaces: [
329
+ {
330
+ id: "context-xray-report",
331
+ path: "/",
332
+ },
333
+ ],
334
+ skills: [
335
+ {
336
+ path: "skills/context-xray",
337
+ visibility: "exported",
338
+ exportAs: "context-xray",
339
+ },
340
+ ],
341
+ hostAdapters: ["plain-skill", "claude-skill"],
342
+ }),
343
+ skillMarkdown: CONTEXT_XRAY_SKILL_MD,
344
+ },
345
+ } satisfies Record<
346
+ string,
347
+ {
348
+ manifest: AppSkillManifest;
349
+ skillMarkdown: string;
350
+ skillName: string;
351
+ extraSkills?: Record<string, string>;
352
+ /**
353
+ * Extra sibling files materialized alongside a skill's SKILL.md, for
354
+ * progressive disclosure (e.g. `references/wireframe.md`). Keyed by skill
355
+ * name, then by skill-relative path -> file content.
356
+ */
357
+ extraFiles?: Record<string, Record<string, string>>;
358
+ localOnly?: boolean;
359
+ }
360
+ >;
361
+
362
+ type BuiltInAppSkillId = keyof typeof BUILT_IN_APP_SKILLS;
363
+ type ModeAwareAppSkillId = "visual-plans" | "content";
364
+
365
+ export const AGENT_NATIVE_SKILL_METADATA_FILE = "agent-native-skill.json";
366
+
367
+ const BUILT_IN_APP_SKILL_ALIASES = {
368
+ assets: "assets",
369
+ asset: "assets",
370
+ "asset-generation": "assets",
371
+ images: "assets",
372
+ image: "assets",
373
+ "image-generation": "assets",
374
+ "agent-native-assets": "assets",
375
+ "agent-native-images": "assets",
376
+ content: "content",
377
+ docs: "content",
378
+ documents: "content",
379
+ "local-content": "content",
380
+ "content-local-files": "content",
381
+ "agent-native-content": "content",
382
+ design: "design",
383
+ "ui-design": "design",
384
+ "ux-design": "design",
385
+ "design-exploration": "design",
386
+ "visual-edit": "design",
387
+ "local-visual-edit": "design",
388
+ "design-visual-edit": "design",
389
+ "ux-exploration": "design",
390
+ "agent-native-design": "design",
391
+ "agent-native-design-exploration": "design",
392
+ "visual-plans": "visual-plans",
393
+ "visual-plan": "visual-plans",
394
+ "visual-recap": "visual-plans",
395
+ "visual-recaps": "visual-plans",
396
+ "visualize-repo": "visual-plans",
397
+ visualize: "visual-plans",
398
+ "repo-visualizer": "visual-plans",
399
+ "visual-docs": "visual-plans",
400
+ "code-review-recap": "visual-plans",
401
+ "code-review-recaps": "visual-plans",
402
+ "html-plan": "visual-plans",
403
+ "plan-mode": "visual-plans",
404
+ plannotate: "visual-plans",
405
+ plannotator: "visual-plans",
406
+ "agent-native-visual-plans": "visual-plans",
407
+ "context-xray": "context-xray",
408
+ "local-context-xray": "context-xray",
409
+ xray: "context-xray",
410
+ "context-window": "context-xray",
411
+ "context-usage": "context-xray",
412
+ "agent-native-context-xray": "context-xray",
413
+ } satisfies Record<string, BuiltInAppSkillId>;
414
+
415
+ const BUILT_IN_APP_SKILL_DISPLAY_ALIASES = {
416
+ assets: ["images", "image-generation", "agent-native-images"],
417
+ content: [
418
+ "docs",
419
+ "documents",
420
+ "local-content",
421
+ "content-local-files",
422
+ "agent-native-content",
423
+ ],
424
+ design: [
425
+ "design-exploration",
426
+ "visual-edit",
427
+ "local-visual-edit",
428
+ "ux-exploration",
429
+ "agent-native-design-exploration",
430
+ ],
431
+ "visual-plans": [
432
+ "visual-plan",
433
+ "visual-recap",
434
+ "visualize-repo",
435
+ "code-review-recap",
436
+ "html-plan",
437
+ "plannotate",
438
+ ],
439
+ "context-xray": ["xray", "context-window", "context-usage"],
440
+ } satisfies Record<BuiltInAppSkillId, string[]>;
441
+
442
+ const CLIENT_LABELS: Record<ClientId, string> = {
443
+ "claude-code": "Claude Code",
444
+ "claude-code-cli": "Claude Code CLI",
445
+ codex: "Codex",
446
+ cowork: "Claude Cowork",
447
+ cursor: "Cursor",
448
+ opencode: "OpenCode",
449
+ "github-copilot": "GitHub Copilot / VS Code",
450
+ };
451
+
452
+ const CLIENT_HINTS: Record<ClientId, string> = {
453
+ "claude-code": ".mcp.json or ~/.claude.json",
454
+ "claude-code-cli": ".mcp.json or ~/.claude.json",
455
+ codex: "$CODEX_HOME/config.toml or ~/.codex/config.toml",
456
+ cowork: "~/.cowork/mcp.json",
457
+ cursor: ".cursor/mcp.json or ~/.cursor/mcp.json",
458
+ opencode: "opencode.json or ~/.config/opencode/opencode.json",
459
+ "github-copilot": ".vscode/mcp.json or VS Code user mcp.json",
460
+ };
461
+
462
+ type SkillInstructionClientId = ClientId | "pi";
463
+
464
+ const SKILLS_CLIENTS: ClientId[] = [
465
+ "claude-code",
466
+ "codex",
467
+ "cowork",
468
+ "cursor",
469
+ "opencode",
470
+ "github-copilot",
471
+ ];
472
+ const SKILL_INSTRUCTION_CLIENTS: SkillInstructionClientId[] = [
473
+ "codex",
474
+ "claude-code",
475
+ "pi",
476
+ ];
477
+ const SKILL_INSTRUCTION_PROMPT_CLIENTS: SkillInstructionClientId[] = [
478
+ "codex",
479
+ "claude-code",
480
+ ];
481
+ // Clients that don't write their own instruction files but READ the shared
482
+ // `.agents/skills` path the codex install writes. In instructions/local-files
483
+ // mode they resolve to that shared-agents install instead of being dropped, so
484
+ // `--client cursor --mode local-files` (etc.) installs the skills they read
485
+ // rather than failing with an empty client set.
486
+ const SHARED_AGENTS_READER_CLIENTS = new Set<SkillInstructionClientId>([
487
+ "cursor",
488
+ "opencode",
489
+ "github-copilot",
490
+ "cowork",
491
+ ]);
492
+ const SKILL_INSTRUCTION_CLIENT_LABELS: Record<
493
+ SkillInstructionClientId,
494
+ string
495
+ > = {
496
+ "claude-code": "Claude Code",
497
+ "claude-code-cli": "Claude Code",
498
+ codex: "Shared .agents skills",
499
+ cowork: "MCP only",
500
+ pi: "Pi",
501
+ };
502
+ const SKILL_INSTRUCTION_CLIENT_HINTS: Record<SkillInstructionClientId, string> =
503
+ {
504
+ "claude-code":
505
+ "Also write Claude Code's native .claude/skills and commands files.",
506
+ "claude-code-cli":
507
+ "Also write Claude Code's native .claude/skills and commands files.",
508
+ codex:
509
+ "Project scope writes .agents skills/commands for Codex, Pi, Cursor, OpenCode, Copilot, and similar agents; user scope writes Codex's ~/.codex skills/commands.",
510
+ cowork: "MCP only",
511
+ pi: "Project scope writes .agents/skills plus .pi/prompts; user scope writes ~/.agents/skills plus ~/.pi/agent/prompts.",
512
+ };
513
+
514
+ type SkillsCommand = "list" | "add" | "status" | "update" | "help";
515
+ type PlanInstallMode = "hosted" | "local-files" | "self-hosted";
516
+
517
+ export interface ParsedSkillsArgs {
518
+ command: SkillsCommand;
519
+ target?: string;
520
+ baseDir?: string;
521
+ client: string;
522
+ clientExplicit: boolean;
523
+ clients?: SkillInstructionClientId[];
524
+ plainSkillNames?: string[];
525
+ scope: string;
526
+ scopeExplicit: boolean;
527
+ yes: boolean;
528
+ dryRun: boolean;
529
+ printJson: boolean;
530
+ instructions: boolean;
531
+ mcp: boolean;
532
+ /**
533
+ * Run the browser/device auth flow after registering a hosted MCP connector
534
+ * so the user does not hit an OAuth wall on the first tool call. Default true;
535
+ * `--no-connect` opts out and leaves authentication for the host/`agent-native
536
+ * connect`.
537
+ */
538
+ connect: boolean;
539
+ /**
540
+ * Optional MCP URL override. When set, the skill's hosted MCP connector is
541
+ * registered against this URL instead of the built-in hosted default — e.g.
542
+ * an ngrok tunnel, a local dev origin, or a self-hosted deployment.
543
+ */
544
+ mcpUrl?: string;
545
+ /**
546
+ * Storage/backend mode for app-backed skills that support install modes. The
547
+ * field name is kept for CLI/API compatibility with the original Plan-only
548
+ * implementation.
549
+ */
550
+ planMode?: PlanInstallMode;
551
+ /**
552
+ * When installing the visual-plan skill, also write the PR Visual Recap
553
+ * GitHub Action workflow into `.github/workflows/` so PRs get automatic
554
+ * recaps. Only applies to the `visual-plan` target.
555
+ */
556
+ withGithubAction?: boolean;
557
+ /**
558
+ * Set once the PR Visual Recap workflow decision has already been made up
559
+ * front (in `runSkills`, before any install/registration) so the per-target
560
+ * `addAgentNativeSkill` doesn't prompt for it again mid-flow. The chosen
561
+ * value lands in `withGithubAction`.
562
+ */
563
+ githubActionResolved?: boolean;
564
+ /**
565
+ * Plain skill repos can add a managed AGENTS.md / CLAUDE.md block for skills
566
+ * that only become automatic through project instructions.
567
+ */
568
+ updateInstructions?: boolean;
569
+ /**
570
+ * When `--with-github-action` is set and the existing workflow file differs
571
+ * from the bundled template, overwrite it. Without this flag the command
572
+ * refuses and prints a message.
573
+ */
574
+ force?: boolean;
575
+ }
576
+
577
+ export interface SkillsAddResult {
578
+ id: string;
579
+ displayName: string;
580
+ instructionSource?: string;
581
+ skillNames: string[];
582
+ skillsAgents: string[];
583
+ mcpUrl: string;
584
+ mcpClients: ClientId[];
585
+ dryRun: boolean;
586
+ commands: string[];
587
+ local?: boolean;
588
+ scriptPath?: string;
589
+ written?: string[];
590
+ /**
591
+ * True when the install also kicked off (or prepared) the browser/device auth
592
+ * flow for the hosted MCP connector. False when connect was skipped
593
+ * (`--no-connect`, no-auth skills, or non-interactive without a connect step).
594
+ */
595
+ connected?: boolean;
596
+ /**
597
+ * The exact `npx @agent-native/core@latest connect <url>` command to run when interactive auth
598
+ * was skipped (non-interactive shell / CI). Empty when connect ran inline or
599
+ * was not needed.
600
+ */
601
+ connectCommand?: string;
602
+ /**
603
+ * When `--with-github-action` installed the PR Visual Recap workflow, the
604
+ * repo-relative path it was written to (and whether it overwrote an existing
605
+ * file).
606
+ */
607
+ githubActionPath?: string;
608
+ githubActionExisted?: boolean;
609
+ githubActionSuggestedCommand?: string;
610
+ localManifestPath?: string;
611
+ planMode?: PlanInstallMode;
612
+ }
613
+
614
+ interface SkillInstallMetadata {
615
+ schemaVersion: 1;
616
+ source: "agent-native";
617
+ appSkillId: string;
618
+ displayName: string;
619
+ skillName: string;
620
+ contentHash: string;
621
+ mcpUrl: string;
622
+ installedAt: string;
623
+ installCommand: string;
624
+ updateCommand: string;
625
+ planMode?: PlanInstallMode;
626
+ }
627
+
628
+ interface SkillFolderBundle {
629
+ appSkillId: BuiltInAppSkillId;
630
+ displayName: string;
631
+ skillName: string;
632
+ mcpUrl: string;
633
+ files: Record<string, string>;
634
+ contentHash: string;
635
+ planMode?: PlanInstallMode;
636
+ }
637
+
638
+ interface SkillInstallState {
639
+ appSkillId: BuiltInAppSkillId;
640
+ displayName: string;
641
+ skillName: string;
642
+ path: string;
643
+ root: string;
644
+ scope: "project" | "user";
645
+ client: string;
646
+ latestHash: string;
647
+ installedHash: string | null;
648
+ metadataHash?: string;
649
+ planMode?: PlanInstallMode;
650
+ mcpUrl?: string;
651
+ current: boolean;
652
+ managed: boolean;
653
+ }
654
+
655
+ interface ScaffoldGuidanceState {
656
+ kind: "workspace-core" | "standalone";
657
+ displayName: string;
658
+ templateName: "workspace-core" | "headless" | "default";
659
+ path: string;
660
+ sourcePath: string;
661
+ projectRoot: string;
662
+ workspaceRoot?: string;
663
+ sharedPackageDir?: string;
664
+ current: boolean;
665
+ skillCount: number;
666
+ }
667
+
668
+ interface SkillInstallTarget {
669
+ id: string;
670
+ displayName: string;
671
+ loaded: LoadedAppSkillManifest;
672
+ skillNames: string[];
673
+ modeAwareId?: ModeAwareAppSkillId;
674
+ materializeInstructions(outDir: string): string;
675
+ cleanup?: () => void;
676
+ }
677
+
678
+ interface RunCommandOptions {
679
+ stdio?: "inherit" | "stderr" | "silent";
680
+ }
681
+
682
+ export type SkillsCatalogMode = "agent-native" | "all";
683
+
684
+ export interface PublicSkillCatalogEntry {
685
+ name: string;
686
+ description?: string;
687
+ }
688
+
689
+ interface ConnectSpinner {
690
+ start(message?: string): void;
691
+ clear(): void;
692
+ }
693
+
694
+ export interface RunSkillsOptions {
695
+ baseDir?: string;
696
+ /**
697
+ * Which skills appear in the shared add/list picker. `agent-native` is the
698
+ * core CLI surface; `all` is used by @agent-native/skills to append public
699
+ * skill-repo entries while keeping every prompt and install decision here.
700
+ */
701
+ catalogMode?: SkillsCatalogMode;
702
+ /**
703
+ * The plain skills repo/source to install when a public catalog entry is
704
+ * selected. @agent-native/skills usually passes the materialized source root.
705
+ */
706
+ publicSkillSource?: string;
707
+ /**
708
+ * Public skill-repo entries discovered by @agent-native/skills. Core owns the
709
+ * user-facing flow; the wrapper owns materializing the broader catalog.
710
+ */
711
+ publicSkillEntries?: PublicSkillCatalogEntry[];
712
+ /**
713
+ * Built-in Agent Native skill prompt/list entries to hide for wrapper CLIs.
714
+ * Direct installs by explicit name still work; this only controls discovery.
715
+ */
716
+ hiddenBuiltInSkillTargets?: string[];
717
+ isInteractive?: () => boolean;
718
+ log?: (message: string) => void;
719
+ /**
720
+ * Optional output hook for the embedded `agent-native connect` transcript.
721
+ * Defaults to `log`; the clack-based CLI uses this to render the multi-line
722
+ * auth details as one continuous guide block instead of separate status logs.
723
+ */
724
+ connectLog?: (message: string) => void;
725
+ /**
726
+ * Optional spinner factory for the embedded connect flow. The default CLI only
727
+ * enables this for real TTYs so captured/test output stays deterministic.
728
+ */
729
+ createConnectSpinner?: () => ConnectSpinner | undefined;
730
+ promptClients?: (
731
+ context: SkillsClientPromptContext,
732
+ ) => Promise<SkillInstructionClientId[] | null>;
733
+ promptSkills?: (
734
+ context: SkillsTargetPromptContext,
735
+ ) => Promise<string[] | null>;
736
+ promptGithubAction?: (
737
+ context: SkillsGithubActionPromptContext,
738
+ ) => Promise<boolean | null>;
739
+ promptScope?: (
740
+ context: SkillsScopePromptContext,
741
+ ) => Promise<"project" | "user" | null>;
742
+ promptPlanMode?: (
743
+ context: SkillsPlanModePromptContext,
744
+ ) => Promise<PlanInstallMode | null>;
745
+ promptPlanMcpUrl?: () => Promise<string | null>;
746
+ promptUpdateInstructions?: () => Promise<boolean | null>;
747
+ runCommand?: (
748
+ cmd: string,
749
+ args: string[],
750
+ options?: RunCommandOptions,
751
+ ) => Promise<number>;
752
+ /**
753
+ * Injectable connect/auth entrypoint (defaults to the real `agent-native
754
+ * connect`). Tests stub this so the install flow does not perform a real
755
+ * browser/device OAuth round-trip.
756
+ */
757
+ runConnect?: (args: string[]) => Promise<void>;
758
+ /**
759
+ * Best-effort install-funnel telemetry. Created once per `runSkills` run and
760
+ * threaded through resolution/install/connect so each `track` is fire-and-
761
+ * forget and never blocks or throws into the install flow. Absent when
762
+ * `addAgentNativeSkill` is called directly (e.g. tests).
763
+ */
764
+ telemetry?: CliTelemetry;
765
+ }
766
+
767
+ interface SkillsClientPromptContext {
768
+ initialClients: SkillInstructionClientId[];
769
+ options: Array<{
770
+ value: SkillInstructionClientId;
771
+ label: string;
772
+ hint: string;
773
+ }>;
774
+ installsMcp: boolean;
775
+ }
776
+
777
+ interface SkillsTargetPromptContext {
778
+ initialTargets: string[];
779
+ options: Array<{ value: string; label: string; hint: string }>;
780
+ }
781
+
782
+ interface SkillsGithubActionPromptContext {
783
+ workflowPath: string;
784
+ setupCommand: string;
785
+ docsUrl: string;
786
+ }
787
+
788
+ interface SkillsScopePromptContext {
789
+ initialScope: "project" | "user";
790
+ }
791
+
792
+ interface SkillsPlanModePromptContext {
793
+ initialMode: PlanInstallMode;
794
+ }
795
+
796
+ function normalizeKnownSkillTarget(
797
+ value: string | undefined,
798
+ ): BuiltInAppSkillId | undefined {
799
+ const key = value?.trim().toLowerCase();
800
+ if (!key) return undefined;
801
+ return BUILT_IN_APP_SKILL_ALIASES[key];
802
+ }
803
+
804
+ function isKnownSkill(value: string | undefined): boolean {
805
+ return Boolean(normalizeKnownSkillTarget(value));
806
+ }
807
+
808
+ function isLocalOnlyBuiltInSkill(
809
+ entry: (typeof BUILT_IN_APP_SKILLS)[BuiltInAppSkillId] | null | undefined,
810
+ ): boolean {
811
+ return Boolean(entry && "localOnly" in entry && entry.localOnly);
812
+ }
813
+
814
+ function targetSupportsInstallMode(
815
+ targetId: string | undefined,
816
+ ): targetId is ModeAwareAppSkillId {
817
+ return targetId === "visual-plans" || targetId === "content";
818
+ }
819
+
820
+ function localFilesModeSkipsMcp(
821
+ targetId: string | undefined,
822
+ mode: PlanInstallMode | undefined,
823
+ ): boolean {
824
+ return mode === "local-files" && targetSupportsInstallMode(targetId);
825
+ }
826
+
827
+ function builtInExtraSkills(
828
+ entry: (typeof BUILT_IN_APP_SKILLS)[BuiltInAppSkillId],
829
+ ): Record<string, string> {
830
+ return "extraSkills" in entry && entry.extraSkills ? entry.extraSkills : {};
831
+ }
832
+
833
+ /**
834
+ * Sibling reference files for a skill (skill name -> relative path -> content),
835
+ * materialized alongside its SKILL.md for progressive disclosure.
836
+ */
837
+ function builtInExtraFiles(
838
+ entry: (typeof BUILT_IN_APP_SKILLS)[BuiltInAppSkillId],
839
+ ): Record<string, Record<string, string>> {
840
+ return "extraFiles" in entry && entry.extraFiles ? entry.extraFiles : {};
841
+ }
842
+
843
+ function builtInSkillNames(
844
+ entry: (typeof BUILT_IN_APP_SKILLS)[BuiltInAppSkillId],
845
+ ): string[] {
846
+ return [entry.skillName, ...Object.keys(builtInExtraSkills(entry))];
847
+ }
848
+
849
+ /**
850
+ * When a target names a single skill that lives inside a multi-skill bundle
851
+ * (the plan bundle ships `visual-plan`, `visual-recap`, and `visualize-repo`),
852
+ * restrict the install to just that skill. The bundle aliases (`visual-plans`,
853
+ * `plannotate`, …) return undefined so they install every skill in the bundle.
854
+ */
855
+ function builtInOnlySkillNames(target: string): string[] | undefined {
856
+ const normalized = target.trim().toLowerCase();
857
+ if (normalized === "visual-plan") return ["visual-plan"];
858
+ if (normalized === "visual-recap" || normalized === "visual-recaps") {
859
+ return ["visual-recap"];
860
+ }
861
+ if (
862
+ normalized === "visualize-repo" ||
863
+ normalized === "visualize" ||
864
+ normalized === "repo-visualizer" ||
865
+ normalized === "visual-docs"
866
+ ) {
867
+ return ["visualize-repo"];
868
+ }
869
+ if (
870
+ normalized === "design-exploration" ||
871
+ normalized === "agent-native-design-exploration"
872
+ ) {
873
+ return ["design-exploration"];
874
+ }
875
+ if (
876
+ normalized === "visual-edit" ||
877
+ normalized === "local-visual-edit" ||
878
+ normalized === "design-visual-edit"
879
+ ) {
880
+ return ["visual-edit"];
881
+ }
882
+ return undefined;
883
+ }
884
+
885
+ function stableSkillHash(files: Record<string, string>): string {
886
+ const hash = createHash("sha256");
887
+ for (const rel of Object.keys(files).sort()) {
888
+ if (rel === AGENT_NATIVE_SKILL_METADATA_FILE) continue;
889
+ hash.update(rel);
890
+ hash.update("\0");
891
+ hash.update(files[rel]);
892
+ hash.update("\0");
893
+ }
894
+ return hash.digest("hex").slice(0, 16);
895
+ }
896
+
897
+ function insertAfterFrontmatter(markdown: string, block: string): string {
898
+ if (!block.trim()) return markdown;
899
+ const match = markdown.match(/^---\n[\s\S]*?\n---\n/);
900
+ if (!match) return `${block}\n\n${markdown}`;
901
+ return `${match[0]}\n${block.trim()}\n\n${markdown.slice(match[0].length)}`;
902
+ }
903
+
904
+ function planModeInstructionBlock(input: {
905
+ mode: PlanInstallMode | undefined;
906
+ mcpUrl?: string;
907
+ }): string {
908
+ if (input.mode === "local-files") {
909
+ return `## Installed Mode
910
+
911
+ Default storage for this installation: local files. Create and update plans and
912
+ recaps as MDX folders under \`plans/<slug>/\` when they should be checked in, or
913
+ under a repo-ignored/temp folder when they should stay private scratch. Before
914
+ authoring structured MDX, run
915
+ \`npx @agent-native/core@latest plan blocks --out plan-blocks.md\` and read the
916
+ no-auth block catalog; it sends no plan content. Then run
917
+ \`npx @agent-native/core@latest plan local check --dir plans/<slug>\`, then
918
+ \`npx @agent-native/core@latest plan local serve --dir plans/<slug> --kind plan|recap --open\`,
919
+ and report the local bridge URL from stdout or \`plans/<slug>/.plan-url\`. Treat
920
+ \`.plan-url\` as a local token file and do not commit it. It opens the hosted Plan
921
+ UI but reads from the localhost bridge on this machine, so it is not shareable
922
+ across machines. On macOS, use Chrome/Chromium if Safari blocks the localhost
923
+ bridge; run \`plan local verify --dir plans/<slug> --kind plan|recap\` for
924
+ headless diagnostics. No sharing, all local. Use a hosted or self-hosted Plan MCP
925
+ connector only if the user explicitly asks to publish or share.`;
926
+ }
927
+ if (input.mode === "self-hosted") {
928
+ return `## Installed Mode
929
+
930
+ Default storage for this installation: the configured self-hosted/custom Plan
931
+ app${input.mcpUrl ? ` at \`${input.mcpUrl}\`` : ""}. Use that Plan MCP connector
932
+ for plans and recaps instead of assuming \`https://plan.agent-native.com\`.`;
933
+ }
934
+ return "";
935
+ }
936
+
937
+ function contentModeInstructionBlock(input: {
938
+ mode: PlanInstallMode | undefined;
939
+ mcpUrl?: string;
940
+ }): string {
941
+ if (input.mode === "local-files") {
942
+ return `## Installed Mode
943
+
944
+ Default storage for this installation is Content's SQL database. This repo's
945
+ \`agent-native.json\` declares \`docs/\`, \`blog/\`, \`content/\`, and
946
+ \`resources/\` as local-folder sources with opaque connection ids; it does not
947
+ select a separate application mode. A trusted local Content app or Agent Native
948
+ Desktop bridge imports those files into their workspace's canonical Files
949
+ database, after which normal Content document actions read and edit the SQL-backed
950
+ pages. Use \`sync-manifest-local-folder-source\` with each root's generated
951
+ connection id, or launch \`agent-native content local-files <target>\`, to connect
952
+ and pull it. The hosted Content app cannot read private repo files by itself.`;
953
+ }
954
+ if (input.mode === "self-hosted") {
955
+ return `## Installed Mode
956
+
957
+ Default storage for this installation: the configured self-hosted/custom Content
958
+ app${input.mcpUrl ? ` at \`${input.mcpUrl}\`` : ""}. Use that Content MCP
959
+ connector instead of assuming \`https://content.agent-native.com\`.`;
960
+ }
961
+ return "";
962
+ }
963
+
964
+ function applyInstallModeToSkillMarkdown(
965
+ markdown: string,
966
+ input: {
967
+ appSkillId: BuiltInAppSkillId;
968
+ mode?: PlanInstallMode;
969
+ mcpUrl?: string;
970
+ },
971
+ ): string {
972
+ let block = "";
973
+ if (input.appSkillId === "visual-plans") {
974
+ block = planModeInstructionBlock({
975
+ mode: input.mode,
976
+ mcpUrl: input.mcpUrl,
977
+ });
978
+ } else if (input.appSkillId === "content") {
979
+ block = contentModeInstructionBlock({
980
+ mode: input.mode,
981
+ mcpUrl: input.mcpUrl,
982
+ });
983
+ }
984
+ return insertAfterFrontmatter(markdown, block);
985
+ }
986
+
987
+ function skillFilesForBuiltIn(
988
+ appSkillId: BuiltInAppSkillId,
989
+ options: { planMode?: PlanInstallMode; mcpUrl?: string } = {},
990
+ ): Record<string, SkillFolderBundle> {
991
+ const entry = BUILT_IN_APP_SKILLS[appSkillId];
992
+ const skills: Record<string, string> = {
993
+ [entry.skillName]: applyInstallModeToSkillMarkdown(entry.skillMarkdown, {
994
+ appSkillId,
995
+ mode: options.planMode,
996
+ mcpUrl: options.mcpUrl,
997
+ }),
998
+ ...builtInExtraSkills(entry),
999
+ };
1000
+ for (const [skillName, skillMarkdown] of Object.entries(
1001
+ builtInExtraSkills(entry),
1002
+ )) {
1003
+ skills[skillName] = applyInstallModeToSkillMarkdown(skillMarkdown, {
1004
+ appSkillId,
1005
+ mode: options.planMode,
1006
+ mcpUrl: options.mcpUrl,
1007
+ });
1008
+ }
1009
+ const extraFiles = builtInExtraFiles(entry);
1010
+ const out: Record<string, SkillFolderBundle> = {};
1011
+ for (const [skillName, skillMarkdown] of Object.entries(skills)) {
1012
+ const files = {
1013
+ "SKILL.md": skillMarkdown,
1014
+ ...(extraFiles[skillName] ?? {}),
1015
+ };
1016
+ out[skillName] = {
1017
+ appSkillId,
1018
+ displayName: entry.manifest.displayName,
1019
+ skillName,
1020
+ mcpUrl:
1021
+ isLocalOnlyBuiltInSkill(entry) ||
1022
+ localFilesModeSkipsMcp(appSkillId, options.planMode)
1023
+ ? ""
1024
+ : (options.mcpUrl ?? entry.manifest.hosted.mcpUrl),
1025
+ files,
1026
+ contentHash: stableSkillHash(files),
1027
+ planMode: options.planMode,
1028
+ };
1029
+ }
1030
+ return out;
1031
+ }
1032
+
1033
+ function latestSkillBundlesForTargets(
1034
+ appSkillIds: BuiltInAppSkillId[],
1035
+ ): Record<string, SkillFolderBundle> {
1036
+ const out: Record<string, SkillFolderBundle> = {};
1037
+ for (const appSkillId of appSkillIds) {
1038
+ Object.assign(out, skillFilesForBuiltIn(appSkillId));
1039
+ }
1040
+ return out;
1041
+ }
1042
+
1043
+ function writeSkillFolder(
1044
+ dir: string,
1045
+ bundle: SkillFolderBundle,
1046
+ installedAt = new Date().toISOString(),
1047
+ ): void {
1048
+ const parent = path.dirname(dir);
1049
+ const tempDir = path.join(
1050
+ parent,
1051
+ `.${path.basename(dir)}.${process.pid}.${Date.now()}.tmp`,
1052
+ );
1053
+ try {
1054
+ fs.rmSync(tempDir, { recursive: true, force: true });
1055
+ fs.mkdirSync(tempDir, { recursive: true });
1056
+ for (const [rel, content] of Object.entries(bundle.files)) {
1057
+ const target = path.join(tempDir, rel);
1058
+ fs.mkdirSync(path.dirname(target), { recursive: true });
1059
+ fs.writeFileSync(target, content, "utf-8");
1060
+ }
1061
+ const metadata: SkillInstallMetadata = {
1062
+ schemaVersion: 1,
1063
+ source: "agent-native",
1064
+ appSkillId: bundle.appSkillId,
1065
+ displayName: bundle.displayName,
1066
+ skillName: bundle.skillName,
1067
+ contentHash: bundle.contentHash,
1068
+ mcpUrl: bundle.mcpUrl,
1069
+ installedAt,
1070
+ installCommand: `npx @agent-native/core@latest skills add ${bundle.skillName}`,
1071
+ updateCommand: `npx @agent-native/core@latest skills update ${bundle.skillName}`,
1072
+ ...(bundle.planMode ? { planMode: bundle.planMode } : {}),
1073
+ };
1074
+ fs.writeFileSync(
1075
+ path.join(tempDir, AGENT_NATIVE_SKILL_METADATA_FILE),
1076
+ `${JSON.stringify(metadata, null, 2)}\n`,
1077
+ "utf-8",
1078
+ );
1079
+ fs.rmSync(dir, { recursive: true, force: true });
1080
+ fs.renameSync(tempDir, dir);
1081
+ } catch (error: any) {
1082
+ try {
1083
+ fs.rmSync(tempDir, { recursive: true, force: true });
1084
+ } catch {}
1085
+ throw new Error(
1086
+ `Cannot write Agent Native skill folder ${dir}: ${error?.message ?? error}`,
1087
+ { cause: error },
1088
+ );
1089
+ }
1090
+ }
1091
+
1092
+ function isJsonRecord(value: unknown): value is Record<string, unknown> {
1093
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
1094
+ }
1095
+
1096
+ function defaultContentLocalFilesAppConfig(): Record<string, unknown> {
1097
+ return {
1098
+ mode: "local-files",
1099
+ roots: [
1100
+ {
1101
+ name: "Docs",
1102
+ path: "docs",
1103
+ kind: "docs",
1104
+ extensions: [".md", ".mdx"],
1105
+ },
1106
+ {
1107
+ name: "Blog",
1108
+ path: "blog",
1109
+ kind: "blog",
1110
+ extensions: [".md", ".mdx"],
1111
+ },
1112
+ {
1113
+ name: "Content",
1114
+ path: "content",
1115
+ kind: "content",
1116
+ extensions: [".md", ".mdx"],
1117
+ },
1118
+ {
1119
+ name: "Resources",
1120
+ path: "resources",
1121
+ kind: "resources",
1122
+ extensions: [".md", ".mdx"],
1123
+ },
1124
+ ],
1125
+ components: "components",
1126
+ extensions: "extensions",
1127
+ hide: ["**/_*.md", "**/_*.mdx"],
1128
+ };
1129
+ }
1130
+
1131
+ function contentLocalFilesManifestPath(baseDir: string): string {
1132
+ return path.join(baseDir, "agent-native.json");
1133
+ }
1134
+
1135
+ function shouldWriteContentLocalFilesManifest(
1136
+ targetId: string | undefined,
1137
+ mode: PlanInstallMode | undefined,
1138
+ ): boolean {
1139
+ return targetId === "content" && mode === "local-files";
1140
+ }
1141
+
1142
+ function contentLocalFolderConnectionId(baseDir: string, rootPath: string) {
1143
+ const absoluteRootPath = path.resolve(baseDir, rootPath);
1144
+ let canonicalRootPath = absoluteRootPath;
1145
+ try {
1146
+ canonicalRootPath = fs.realpathSync(absoluteRootPath);
1147
+ } catch (error: any) {
1148
+ if (error?.code !== "ENOENT") throw error;
1149
+ }
1150
+ return `local-folder:${createHash("sha256")
1151
+ .update(canonicalRootPath)
1152
+ .digest("base64url")
1153
+ .slice(0, 24)}`;
1154
+ }
1155
+
1156
+ function mergeContentLocalFilesManifest(
1157
+ existing: unknown,
1158
+ baseDir: string,
1159
+ ): Record<string, unknown> {
1160
+ const manifest = isJsonRecord(existing) ? { ...existing } : {};
1161
+ if (manifest.version === undefined) manifest.version = 1;
1162
+
1163
+ const apps = isJsonRecord(manifest.apps) ? { ...manifest.apps } : {};
1164
+ const contentApp = isJsonRecord(apps.content) ? { ...apps.content } : {};
1165
+ const defaults = defaultContentLocalFilesAppConfig();
1166
+ if (!Array.isArray(contentApp.roots) || contentApp.roots.length === 0) {
1167
+ contentApp.roots = defaults.roots;
1168
+ }
1169
+ contentApp.roots = contentApp.roots.map((root: unknown) => {
1170
+ if (!isJsonRecord(root) || typeof root.path !== "string") return root;
1171
+ const source = isJsonRecord(root.source) ? root.source : {};
1172
+ return {
1173
+ ...root,
1174
+ source: {
1175
+ ...source,
1176
+ type: "local-folder",
1177
+ connectionId:
1178
+ typeof source.connectionId === "string" && source.connectionId
1179
+ ? source.connectionId
1180
+ : contentLocalFolderConnectionId(baseDir, root.path),
1181
+ truthPolicy:
1182
+ typeof source.truthPolicy === "string"
1183
+ ? source.truthPolicy
1184
+ : "source_primary",
1185
+ },
1186
+ };
1187
+ });
1188
+ delete contentApp.mode;
1189
+ if (contentApp.components === undefined) {
1190
+ contentApp.components = defaults.components;
1191
+ }
1192
+ if (contentApp.extensions === undefined) {
1193
+ contentApp.extensions = defaults.extensions;
1194
+ }
1195
+ if (!Array.isArray(contentApp.hide) || contentApp.hide.length === 0) {
1196
+ contentApp.hide = defaults.hide;
1197
+ }
1198
+ apps.content = contentApp;
1199
+ manifest.apps = apps;
1200
+ return manifest;
1201
+ }
1202
+
1203
+ function writeContentLocalFilesManifest(
1204
+ baseDir: string,
1205
+ options: { dryRun?: boolean } = {},
1206
+ ): string {
1207
+ const manifestPath = contentLocalFilesManifestPath(baseDir);
1208
+ let existing: unknown = {};
1209
+ if (fs.existsSync(manifestPath)) {
1210
+ try {
1211
+ existing = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
1212
+ } catch (error: any) {
1213
+ throw new Error(
1214
+ `Could not parse ${manifestPath}: ${error?.message ?? error}`,
1215
+ );
1216
+ }
1217
+ }
1218
+ const manifest = mergeContentLocalFilesManifest(existing, baseDir);
1219
+ if (!options.dryRun) {
1220
+ fs.writeFileSync(
1221
+ manifestPath,
1222
+ `${JSON.stringify(manifest, null, 2)}\n`,
1223
+ "utf-8",
1224
+ );
1225
+ }
1226
+ return manifestPath;
1227
+ }
1228
+
1229
+ /**
1230
+ * The skills directory a built-in skill's instructions are copied into for a
1231
+ * given agent + scope. Mirrors the layout the skills installer uses so
1232
+ * `skills status` / `skills update` find the folders again.
1233
+ */
1234
+ function builtInSkillsRootForAgent(
1235
+ agent: string,
1236
+ scope: "project" | "user",
1237
+ baseDir: string,
1238
+ ): string {
1239
+ const home = homeDir() ?? baseDir;
1240
+ if (scope === "project") {
1241
+ if (agent === "codex") return path.join(baseDir, ".agents", "skills");
1242
+ if (agent === "pi") return path.join(baseDir, ".agents", "skills");
1243
+ return path.join(baseDir, ".claude", "skills");
1244
+ }
1245
+ if (agent === "codex") {
1246
+ return process.env.CODEX_HOME
1247
+ ? path.join(process.env.CODEX_HOME, "skills")
1248
+ : path.join(home, ".codex", "skills");
1249
+ }
1250
+ if (agent === "pi") {
1251
+ return path.join(home, ".agents", "skills");
1252
+ }
1253
+ return path.join(home, ".claude", "skills");
1254
+ }
1255
+
1256
+ function builtInCommandsRootForAgent(
1257
+ agent: string,
1258
+ scope: "project" | "user",
1259
+ baseDir: string,
1260
+ ): string {
1261
+ const home = homeDir() ?? baseDir;
1262
+ if (scope === "project") {
1263
+ if (agent === "codex") return path.join(baseDir, ".agents", "commands");
1264
+ if (agent === "pi") return path.join(baseDir, ".pi", "prompts");
1265
+ return path.join(baseDir, ".claude", "commands");
1266
+ }
1267
+ if (agent === "codex") {
1268
+ return process.env.CODEX_HOME
1269
+ ? path.join(process.env.CODEX_HOME, "commands")
1270
+ : path.join(home, ".codex", "commands");
1271
+ }
1272
+ if (agent === "pi") {
1273
+ const piHome =
1274
+ process.env.PI_CODING_AGENT_DIR || path.join(home, ".pi", "agent");
1275
+ return path.join(piHome, "prompts");
1276
+ }
1277
+ return path.join(home, ".claude", "commands");
1278
+ }
1279
+
1280
+ function slashCommandForBuiltInSkill(skillName: string): string | null {
1281
+ if (skillName === "visual-plan") {
1282
+ return `---
1283
+ description: Create an interactive Agent-Native visual plan for the current task.
1284
+ argument-hint: [optional request or scope]
1285
+ ---
1286
+
1287
+ Use the visual-plan skill for this task. Treat any arguments as the user's
1288
+ requested plan scope or focus:
1289
+
1290
+ $ARGUMENTS
1291
+ `;
1292
+ }
1293
+ if (skillName === "visual-recap") {
1294
+ return `---
1295
+ description: Create an interactive Agent-Native visual recap for a PR, branch, commit, or diff.
1296
+ argument-hint: [PR, branch, commit, diff, or scope]
1297
+ ---
1298
+
1299
+ Use the visual-recap skill. Treat any arguments as the recap target or focus:
1300
+
1301
+ $ARGUMENTS
1302
+ `;
1303
+ }
1304
+ if (skillName === "visualize-repo") {
1305
+ return `---
1306
+ description: Open or create a local Agent-Native visual docs workspace for this repo.
1307
+ argument-hint: [optional targets or focus]
1308
+ ---
1309
+
1310
+ Use the visualize-repo skill. Treat any arguments as source targets, repo areas,
1311
+ or review focus:
1312
+
1313
+ $ARGUMENTS
1314
+ `;
1315
+ }
1316
+ return null;
1317
+ }
1318
+
1319
+ /**
1320
+ * Write a built-in skill's instruction folders straight into each client's
1321
+ * skills directory. Built-in skills ship their SKILL.md inside this package, so
1322
+ * there is no need to shell out to the separate @agent-native/skills installer
1323
+ * (which would have to be published to npm first). Returns the written folders.
1324
+ */
1325
+ function installBuiltInInstructions(input: {
1326
+ appSkillId: BuiltInAppSkillId;
1327
+ onlySkillNames?: string[];
1328
+ skillsAgents: string[];
1329
+ scope: "project" | "user";
1330
+ baseDir: string;
1331
+ dryRun?: boolean;
1332
+ planMode?: PlanInstallMode;
1333
+ mcpUrl?: string;
1334
+ }): string[] {
1335
+ const bundles = Object.values(
1336
+ skillFilesForBuiltIn(input.appSkillId, {
1337
+ planMode: input.planMode,
1338
+ mcpUrl: input.mcpUrl,
1339
+ }),
1340
+ ).filter(
1341
+ (bundle) =>
1342
+ !input.onlySkillNames || input.onlySkillNames.includes(bundle.skillName),
1343
+ );
1344
+ const written: string[] = [];
1345
+ for (const agent of input.skillsAgents) {
1346
+ const root = builtInSkillsRootForAgent(agent, input.scope, input.baseDir);
1347
+ const commandsRoot = builtInCommandsRootForAgent(
1348
+ agent,
1349
+ input.scope,
1350
+ input.baseDir,
1351
+ );
1352
+ for (const bundle of bundles) {
1353
+ const dir = path.join(root, bundle.skillName);
1354
+ if (!input.dryRun) writeSkillFolder(dir, bundle);
1355
+ written.push(dir);
1356
+ const command = slashCommandForBuiltInSkill(bundle.skillName);
1357
+ if (command) {
1358
+ const commandPath = path.join(commandsRoot, `${bundle.skillName}.md`);
1359
+ if (!input.dryRun) {
1360
+ fs.mkdirSync(path.dirname(commandPath), { recursive: true });
1361
+ fs.writeFileSync(commandPath, command, "utf-8");
1362
+ }
1363
+ written.push(commandPath);
1364
+ }
1365
+ }
1366
+ }
1367
+ return written;
1368
+ }
1369
+
1370
+ function listSkillFolderFiles(dir: string): Record<string, string> {
1371
+ const out: Record<string, string> = {};
1372
+ const walk = (current: string, prefix = "") => {
1373
+ for (const entry of fs.readdirSync(current, { withFileTypes: true })) {
1374
+ const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
1375
+ const abs = path.join(current, entry.name);
1376
+ if (entry.isDirectory()) {
1377
+ walk(abs, rel);
1378
+ continue;
1379
+ }
1380
+ if (!entry.isFile() || rel === AGENT_NATIVE_SKILL_METADATA_FILE) continue;
1381
+ out[rel] = fs.readFileSync(abs, "utf-8");
1382
+ }
1383
+ };
1384
+ if (fs.existsSync(dir)) walk(dir);
1385
+ return out;
1386
+ }
1387
+
1388
+ function readSkillInstallMetadata(
1389
+ dir: string,
1390
+ ): SkillInstallMetadata | undefined {
1391
+ const file = path.join(dir, AGENT_NATIVE_SKILL_METADATA_FILE);
1392
+ if (!fs.existsSync(file)) return undefined;
1393
+ try {
1394
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
1395
+ if (
1396
+ parsed &&
1397
+ parsed.source === "agent-native" &&
1398
+ typeof parsed.skillName === "string" &&
1399
+ typeof parsed.contentHash === "string"
1400
+ ) {
1401
+ return parsed as SkillInstallMetadata;
1402
+ }
1403
+ } catch {}
1404
+ return undefined;
1405
+ }
1406
+
1407
+ function homeDir(): string | undefined {
1408
+ return process.env.HOME || os.homedir();
1409
+ }
1410
+
1411
+ function skillSearchRoots(input: {
1412
+ baseDir: string;
1413
+ clients: SkillInstructionClientId[];
1414
+ scopes: Array<"project" | "user">;
1415
+ }): Array<{
1416
+ root: string;
1417
+ scope: "project" | "user";
1418
+ client: string;
1419
+ }> {
1420
+ const roots: Array<{
1421
+ root: string;
1422
+ scope: "project" | "user";
1423
+ client: string;
1424
+ }> = [];
1425
+ const clientSet = new Set<SkillInstructionClientId>(input.clients);
1426
+ const includeAll = input.clients.length === 0;
1427
+ const hasClient = (client: SkillInstructionClientId) =>
1428
+ includeAll || clientSet.has(client);
1429
+ const add = (
1430
+ root: string | undefined,
1431
+ scope: "project" | "user",
1432
+ client: string,
1433
+ ) => {
1434
+ if (root) roots.push({ root, scope, client });
1435
+ };
1436
+
1437
+ if (input.scopes.includes("project")) {
1438
+ if (hasClient("codex")) {
1439
+ add(path.join(input.baseDir, ".agents", "skills"), "project", "codex");
1440
+ }
1441
+ if (hasClient("claude-code") || hasClient("claude-code-cli")) {
1442
+ add(
1443
+ path.join(input.baseDir, ".claude", "skills"),
1444
+ "project",
1445
+ "claude-code",
1446
+ );
1447
+ }
1448
+ if (hasClient("pi")) {
1449
+ add(path.join(input.baseDir, ".agents", "skills"), "project", "pi");
1450
+ add(path.join(input.baseDir, ".pi", "skills"), "project", "pi");
1451
+ }
1452
+ if (includeAll) add(path.join(input.baseDir, "skills"), "project", "repo");
1453
+ }
1454
+
1455
+ if (input.scopes.includes("user")) {
1456
+ const home = homeDir();
1457
+ if (hasClient("codex")) {
1458
+ add(
1459
+ process.env.CODEX_HOME
1460
+ ? path.join(process.env.CODEX_HOME, "skills")
1461
+ : undefined,
1462
+ "user",
1463
+ "codex",
1464
+ );
1465
+ add(
1466
+ home ? path.join(home, ".codex", "skills") : undefined,
1467
+ "user",
1468
+ "codex",
1469
+ );
1470
+ }
1471
+ if (hasClient("claude-code") || hasClient("claude-code-cli")) {
1472
+ add(
1473
+ home ? path.join(home, ".claude", "skills") : undefined,
1474
+ "user",
1475
+ "claude-code",
1476
+ );
1477
+ }
1478
+ if (hasClient("pi")) {
1479
+ const piHome =
1480
+ process.env.PI_CODING_AGENT_DIR ||
1481
+ (home ? path.join(home, ".pi", "agent") : undefined);
1482
+ add(
1483
+ home ? path.join(home, ".agents", "skills") : undefined,
1484
+ "user",
1485
+ "pi",
1486
+ );
1487
+ add(piHome ? path.join(piHome, "skills") : undefined, "user", "pi");
1488
+ }
1489
+ }
1490
+
1491
+ const seen = new Set<string>();
1492
+ return roots.filter((entry) => {
1493
+ const key = `${entry.scope}:${entry.client}:${path.resolve(entry.root)}`;
1494
+ if (seen.has(key)) return false;
1495
+ seen.add(key);
1496
+ return true;
1497
+ });
1498
+ }
1499
+
1500
+ const SCAFFOLD_GUIDANCE_TARGETS = new Set([
1501
+ "scaffold",
1502
+ "generated",
1503
+ "generated-app",
1504
+ "generated-workspace",
1505
+ "workspace",
1506
+ "workspace-core",
1507
+ "framework-guidance",
1508
+ ]);
1509
+
1510
+ function isScaffoldGuidanceTarget(value: string | undefined): boolean {
1511
+ if (!value) return false;
1512
+ return SCAFFOLD_GUIDANCE_TARGETS.has(value.trim().toLowerCase());
1513
+ }
1514
+
1515
+ function corePackageRootDir(): string {
1516
+ const here = path.dirname(fileURLToPath(import.meta.url));
1517
+ return path.resolve(here, "../..");
1518
+ }
1519
+
1520
+ function bundledScaffoldSkillsDir(
1521
+ templateName: ScaffoldGuidanceState["templateName"],
1522
+ ): string {
1523
+ return path.join(
1524
+ corePackageRootDir(),
1525
+ "src",
1526
+ "templates",
1527
+ templateName,
1528
+ ".agents",
1529
+ "skills",
1530
+ );
1531
+ }
1532
+
1533
+ function readJsonRecord(file: string): Record<string, unknown> | undefined {
1534
+ try {
1535
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
1536
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1537
+ return parsed as Record<string, unknown>;
1538
+ }
1539
+ } catch {}
1540
+ return undefined;
1541
+ }
1542
+
1543
+ function readPackageJson(dir: string): Record<string, unknown> | undefined {
1544
+ return readJsonRecord(path.join(dir, "package.json"));
1545
+ }
1546
+
1547
+ function packageName(pkg: Record<string, unknown> | undefined): string | null {
1548
+ return typeof pkg?.name === "string" ? pkg.name : null;
1549
+ }
1550
+
1551
+ function workspaceCorePackageName(
1552
+ pkg: Record<string, unknown> | undefined,
1553
+ ): string | null {
1554
+ const agentNative = pkg?.["agent-native"];
1555
+ if (
1556
+ agentNative &&
1557
+ typeof agentNative === "object" &&
1558
+ !Array.isArray(agentNative) &&
1559
+ typeof (agentNative as Record<string, unknown>).workspaceCore === "string"
1560
+ ) {
1561
+ return (agentNative as Record<string, string>).workspaceCore;
1562
+ }
1563
+ return null;
1564
+ }
1565
+
1566
+ function hasAgentNativeCoreDependency(
1567
+ pkg: Record<string, unknown> | undefined,
1568
+ ): boolean {
1569
+ for (const field of ["dependencies", "devDependencies", "peerDependencies"]) {
1570
+ const deps = pkg?.[field];
1571
+ if (
1572
+ deps &&
1573
+ typeof deps === "object" &&
1574
+ !Array.isArray(deps) &&
1575
+ "@agent-native/core" in deps
1576
+ ) {
1577
+ return true;
1578
+ }
1579
+ }
1580
+ return false;
1581
+ }
1582
+
1583
+ function findWorkspaceCorePackageDir(
1584
+ workspaceRoot: string,
1585
+ workspaceCoreName: string,
1586
+ ): string | undefined {
1587
+ const packagesDir = path.join(workspaceRoot, "packages");
1588
+ if (!fs.existsSync(packagesDir)) return undefined;
1589
+ for (const entry of fs.readdirSync(packagesDir, { withFileTypes: true })) {
1590
+ if (!entry.isDirectory()) continue;
1591
+ const candidate = path.join(packagesDir, entry.name);
1592
+ if (packageName(readPackageJson(candidate)) === workspaceCoreName) {
1593
+ return candidate;
1594
+ }
1595
+ }
1596
+ const fallback = path.join(workspaceRoot, "packages", "shared");
1597
+ return fs.existsSync(path.join(fallback, "package.json"))
1598
+ ? fallback
1599
+ : undefined;
1600
+ }
1601
+
1602
+ function findGeneratedWorkspace(startDir: string):
1603
+ | {
1604
+ workspaceRoot: string;
1605
+ sharedPackageDir: string;
1606
+ }
1607
+ | undefined {
1608
+ let current = path.resolve(startDir);
1609
+ while (true) {
1610
+ const pkg = readPackageJson(current);
1611
+ const workspaceCoreName = workspaceCorePackageName(pkg);
1612
+ if (workspaceCoreName && fs.existsSync(path.join(current, "apps"))) {
1613
+ const sharedPackageDir = findWorkspaceCorePackageDir(
1614
+ current,
1615
+ workspaceCoreName,
1616
+ );
1617
+ if (sharedPackageDir) {
1618
+ return { workspaceRoot: current, sharedPackageDir };
1619
+ }
1620
+ }
1621
+ const parent = path.dirname(current);
1622
+ if (parent === current) break;
1623
+ current = parent;
1624
+ }
1625
+ return undefined;
1626
+ }
1627
+
1628
+ function detectStandaloneScaffoldTemplate(
1629
+ projectRoot: string,
1630
+ ): "headless" | "default" | undefined {
1631
+ const pkg = readPackageJson(projectRoot);
1632
+ if (!hasAgentNativeCoreDependency(pkg)) return undefined;
1633
+ if (!fs.existsSync(path.join(projectRoot, ".agents", "skills"))) {
1634
+ return undefined;
1635
+ }
1636
+
1637
+ const hasAppDir = fs.existsSync(path.join(projectRoot, "app"));
1638
+ const hasHeadlessHello = fs.existsSync(
1639
+ path.join(projectRoot, "actions", "hello.ts"),
1640
+ );
1641
+ if (!hasAppDir && hasHeadlessHello) return "headless";
1642
+
1643
+ const looksLikeDefaultTemplate =
1644
+ fs.existsSync(path.join(projectRoot, "app", "routes", "database.tsx")) &&
1645
+ fs.existsSync(path.join(projectRoot, "app", "routes", "_index.tsx")) &&
1646
+ fs.existsSync(path.join(projectRoot, "actions", "view-screen.ts"));
1647
+ return looksLikeDefaultTemplate ? "default" : undefined;
1648
+ }
1649
+
1650
+ function listImmediateSkillDirs(dir: string): string[] {
1651
+ if (!fs.existsSync(dir)) return [];
1652
+ return fs
1653
+ .readdirSync(dir, { withFileTypes: true })
1654
+ .filter((entry) => entry.isDirectory())
1655
+ .map((entry) => entry.name)
1656
+ .sort();
1657
+ }
1658
+
1659
+ function skillDirContentsMatch(sourceDir: string, targetDir: string): boolean {
1660
+ const expected = listSkillFolderFiles(sourceDir);
1661
+ const actual = listSkillFolderFiles(targetDir);
1662
+ const expectedFiles = Object.keys(expected).sort();
1663
+ const actualFiles = Object.keys(actual).sort();
1664
+ if (expectedFiles.length !== actualFiles.length) return false;
1665
+ for (let i = 0; i < expectedFiles.length; i += 1) {
1666
+ if (expectedFiles[i] !== actualFiles[i]) return false;
1667
+ }
1668
+ return expectedFiles.every((file) => expected[file] === actual[file]);
1669
+ }
1670
+
1671
+ function scaffoldGuidanceCurrent(
1672
+ sourceRoot: string,
1673
+ targetRoot: string,
1674
+ ): boolean {
1675
+ const skills = listImmediateSkillDirs(sourceRoot);
1676
+ if (skills.length === 0) return false;
1677
+ return skills.every((skill) =>
1678
+ skillDirContentsMatch(
1679
+ path.join(sourceRoot, skill),
1680
+ path.join(targetRoot, skill),
1681
+ ),
1682
+ );
1683
+ }
1684
+
1685
+ function collectScaffoldGuidanceStates(
1686
+ parsed: ParsedSkillsArgs,
1687
+ options: RunSkillsOptions,
1688
+ ): ScaffoldGuidanceState[] {
1689
+ if (parsed.target && !isScaffoldGuidanceTarget(parsed.target)) return [];
1690
+ if (parsed.scopeExplicit && parsed.scope !== "project") return [];
1691
+
1692
+ const baseDir = path.resolve(options.baseDir ?? process.cwd());
1693
+ const workspace = findGeneratedWorkspace(baseDir);
1694
+ if (workspace) {
1695
+ const sourcePath = bundledScaffoldSkillsDir("workspace-core");
1696
+ const targetPath = path.join(
1697
+ workspace.sharedPackageDir,
1698
+ ".agents",
1699
+ "skills",
1700
+ );
1701
+ if (!fs.existsSync(sourcePath)) return [];
1702
+ return [
1703
+ {
1704
+ kind: "workspace-core",
1705
+ displayName: "Generated workspace framework skills",
1706
+ templateName: "workspace-core",
1707
+ path: targetPath,
1708
+ sourcePath,
1709
+ projectRoot: workspace.workspaceRoot,
1710
+ workspaceRoot: workspace.workspaceRoot,
1711
+ sharedPackageDir: workspace.sharedPackageDir,
1712
+ current: scaffoldGuidanceCurrent(sourcePath, targetPath),
1713
+ skillCount: listImmediateSkillDirs(sourcePath).length,
1714
+ },
1715
+ ];
1716
+ }
1717
+
1718
+ const templateName = detectStandaloneScaffoldTemplate(baseDir);
1719
+ if (!templateName) return [];
1720
+ const sourcePath = bundledScaffoldSkillsDir(templateName);
1721
+ const targetPath = path.join(baseDir, ".agents", "skills");
1722
+ if (!fs.existsSync(sourcePath)) return [];
1723
+ return [
1724
+ {
1725
+ kind: "standalone",
1726
+ displayName: `Generated ${templateName} app framework skills`,
1727
+ templateName,
1728
+ path: targetPath,
1729
+ sourcePath,
1730
+ projectRoot: baseDir,
1731
+ current: scaffoldGuidanceCurrent(sourcePath, targetPath),
1732
+ skillCount: listImmediateSkillDirs(sourcePath).length,
1733
+ },
1734
+ ];
1735
+ }
1736
+
1737
+ function copyScaffoldGuidanceSkills(
1738
+ sourceRoot: string,
1739
+ targetRoot: string,
1740
+ ): void {
1741
+ fs.mkdirSync(targetRoot, { recursive: true });
1742
+ for (const skill of listImmediateSkillDirs(sourceRoot)) {
1743
+ const targetSkillDir = path.join(targetRoot, skill);
1744
+ if (
1745
+ fs.existsSync(targetSkillDir) &&
1746
+ fs.lstatSync(targetSkillDir).isSymbolicLink()
1747
+ ) {
1748
+ continue;
1749
+ }
1750
+ fs.rmSync(targetSkillDir, { recursive: true, force: true });
1751
+ fs.cpSync(path.join(sourceRoot, skill), targetSkillDir, {
1752
+ recursive: true,
1753
+ });
1754
+ }
1755
+ }
1756
+
1757
+ function updateScaffoldGuidanceStates(
1758
+ states: ScaffoldGuidanceState[],
1759
+ dryRun: boolean,
1760
+ ): ScaffoldGuidanceState[] {
1761
+ const updated: ScaffoldGuidanceState[] = [];
1762
+ for (const state of states) {
1763
+ if (state.current) continue;
1764
+ if (!dryRun) {
1765
+ copyScaffoldGuidanceSkills(state.sourcePath, state.path);
1766
+ }
1767
+ updated.push({
1768
+ ...state,
1769
+ current: !dryRun,
1770
+ });
1771
+ }
1772
+ return updated;
1773
+ }
1774
+
1775
+ function ensureWorkspaceRootSkillsLink(
1776
+ workspaceRoot: string,
1777
+ sharedPackageDir: string,
1778
+ ): void {
1779
+ const sharedSkillsDir = path.join(sharedPackageDir, ".agents", "skills");
1780
+ if (!fs.existsSync(sharedSkillsDir)) return;
1781
+
1782
+ const agentsDir = path.join(workspaceRoot, ".agents");
1783
+ const linkPath = path.join(agentsDir, "skills");
1784
+ const target = path.relative(agentsDir, sharedSkillsDir);
1785
+
1786
+ fs.mkdirSync(agentsDir, { recursive: true });
1787
+ try {
1788
+ const stat = fs.lstatSync(linkPath);
1789
+ if (stat.isSymbolicLink()) {
1790
+ if (fs.readlinkSync(linkPath) === target) return;
1791
+ fs.unlinkSync(linkPath);
1792
+ } else {
1793
+ copyScaffoldGuidanceSkills(sharedSkillsDir, linkPath);
1794
+ return;
1795
+ }
1796
+ } catch {}
1797
+
1798
+ try {
1799
+ fs.symlinkSync(
1800
+ target,
1801
+ linkPath,
1802
+ process.platform === "win32" ? "junction" : "dir",
1803
+ );
1804
+ } catch {
1805
+ try {
1806
+ fs.cpSync(sharedSkillsDir, linkPath, { recursive: true });
1807
+ } catch {}
1808
+ }
1809
+ }
1810
+
1811
+ function refreshCopiedClaudeSkills(projectRoot: string): void {
1812
+ const agentsSkillsDir = path.join(projectRoot, ".agents", "skills");
1813
+ const claudeSkillsDir = path.join(projectRoot, ".claude", "skills");
1814
+ if (!fs.existsSync(agentsSkillsDir) || !fs.existsSync(claudeSkillsDir)) {
1815
+ return;
1816
+ }
1817
+ try {
1818
+ if (fs.lstatSync(claudeSkillsDir).isSymbolicLink()) return;
1819
+ copyScaffoldGuidanceSkills(agentsSkillsDir, claudeSkillsDir);
1820
+ } catch {}
1821
+ }
1822
+
1823
+ function repairScaffoldAgentLinks(states: ScaffoldGuidanceState[]): void {
1824
+ const seen = new Set<string>();
1825
+ for (const state of states) {
1826
+ if (state.workspaceRoot && state.sharedPackageDir) {
1827
+ const key = `workspace:${state.workspaceRoot}`;
1828
+ if (seen.has(key)) continue;
1829
+ seen.add(key);
1830
+ ensureWorkspaceRootSkillsLink(
1831
+ state.workspaceRoot,
1832
+ state.sharedPackageDir,
1833
+ );
1834
+ setupAgentSymlinks(state.workspaceRoot);
1835
+ refreshCopiedClaudeSkills(state.workspaceRoot);
1836
+ setupAgentSymlinks(state.sharedPackageDir);
1837
+ refreshCopiedClaudeSkills(state.sharedPackageDir);
1838
+ const appsDir = path.join(state.workspaceRoot, "apps");
1839
+ if (fs.existsSync(appsDir)) {
1840
+ for (const entry of fs.readdirSync(appsDir, { withFileTypes: true })) {
1841
+ if (!entry.isDirectory()) continue;
1842
+ const appDir = path.join(appsDir, entry.name);
1843
+ if (fs.existsSync(path.join(appDir, "package.json"))) {
1844
+ setupAgentSymlinks(appDir);
1845
+ refreshCopiedClaudeSkills(appDir);
1846
+ }
1847
+ }
1848
+ }
1849
+ continue;
1850
+ }
1851
+
1852
+ const key = `standalone:${state.projectRoot}`;
1853
+ if (seen.has(key)) continue;
1854
+ seen.add(key);
1855
+ setupAgentSymlinks(state.projectRoot);
1856
+ refreshCopiedClaudeSkills(state.projectRoot);
1857
+ }
1858
+ }
1859
+
1860
+ function targetIdsForStatus(parsed: ParsedSkillsArgs): BuiltInAppSkillId[] {
1861
+ if (isScaffoldGuidanceTarget(parsed.target)) return [];
1862
+ if (!parsed.target) {
1863
+ return (Object.keys(BUILT_IN_APP_SKILLS) as BuiltInAppSkillId[]).filter(
1864
+ (id) => !isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[id]),
1865
+ );
1866
+ }
1867
+ const known = normalizeKnownSkillTarget(parsed.target);
1868
+ if (!known) {
1869
+ throw new Error(
1870
+ `Unknown built-in skill: ${parsed.target}. Run "npx @agent-native/core@latest skills list".`,
1871
+ );
1872
+ }
1873
+ if (isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[known])) {
1874
+ throw new Error(
1875
+ `${BUILT_IN_APP_SKILLS[known].manifest.displayName} is installed as a local command and cannot be refreshed with skills update yet.`,
1876
+ );
1877
+ }
1878
+ return [known];
1879
+ }
1880
+
1881
+ function scopeFilterForStatus(
1882
+ parsed: ParsedSkillsArgs,
1883
+ ): Array<"project" | "user"> {
1884
+ return parsed.scopeExplicit
1885
+ ? [parsed.scope as "project" | "user"]
1886
+ : ["project", "user"];
1887
+ }
1888
+
1889
+ function clientFilterForStatus(
1890
+ parsed: ParsedSkillsArgs,
1891
+ ): SkillInstructionClientId[] {
1892
+ return parsed.clientExplicit ? resolveSkillsClientArg(parsed.client) : [];
1893
+ }
1894
+
1895
+ function collectSkillInstallStates(
1896
+ parsed: ParsedSkillsArgs,
1897
+ options: RunSkillsOptions,
1898
+ ): SkillInstallState[] {
1899
+ const appSkillIds = targetIdsForStatus(parsed);
1900
+ const defaultLatest = latestSkillBundlesForTargets(appSkillIds);
1901
+ const roots = skillSearchRoots({
1902
+ baseDir: options.baseDir ?? process.cwd(),
1903
+ clients: clientFilterForStatus(parsed),
1904
+ scopes: scopeFilterForStatus(parsed),
1905
+ });
1906
+ const states: SkillInstallState[] = [];
1907
+ const seenDirs = new Set<string>();
1908
+
1909
+ for (const root of roots) {
1910
+ for (const bundle of Object.values(defaultLatest)) {
1911
+ const dir = path.join(root.root, bundle.skillName);
1912
+ const resolvedDir = path.resolve(dir);
1913
+ if (seenDirs.has(resolvedDir) || !fs.existsSync(dir)) continue;
1914
+ if (!fs.existsSync(path.join(dir, "SKILL.md"))) continue;
1915
+ seenDirs.add(resolvedDir);
1916
+ const files = listSkillFolderFiles(dir);
1917
+ const metadata = readSkillInstallMetadata(dir);
1918
+ const stateBundle =
1919
+ skillFilesForBuiltIn(bundle.appSkillId, {
1920
+ planMode: metadata?.planMode,
1921
+ mcpUrl: metadata?.mcpUrl,
1922
+ })[bundle.skillName] ?? bundle;
1923
+ const installedHash =
1924
+ Object.keys(files).length > 0 ? stableSkillHash(files) : null;
1925
+ states.push({
1926
+ appSkillId: stateBundle.appSkillId,
1927
+ displayName: stateBundle.displayName,
1928
+ skillName: stateBundle.skillName,
1929
+ path: dir,
1930
+ root: root.root,
1931
+ scope: root.scope,
1932
+ client: root.client,
1933
+ latestHash: stateBundle.contentHash,
1934
+ installedHash,
1935
+ metadataHash: metadata?.contentHash,
1936
+ current: installedHash === stateBundle.contentHash,
1937
+ managed: metadata?.source === "agent-native",
1938
+ planMode: metadata?.planMode,
1939
+ mcpUrl: metadata?.mcpUrl,
1940
+ });
1941
+ }
1942
+ }
1943
+
1944
+ return states.sort((a, b) =>
1945
+ `${a.skillName}:${a.path}`.localeCompare(`${b.skillName}:${b.path}`),
1946
+ );
1947
+ }
1948
+
1949
+ function updateSkillInstallStates(
1950
+ states: SkillInstallState[],
1951
+ dryRun: boolean,
1952
+ ): SkillInstallState[] {
1953
+ const updated: SkillInstallState[] = [];
1954
+ for (const state of states) {
1955
+ if (state.current && state.managed) continue;
1956
+ const bundle = skillFilesForBuiltIn(state.appSkillId, {
1957
+ planMode: state.planMode,
1958
+ mcpUrl: state.mcpUrl,
1959
+ })[state.skillName];
1960
+ if (!bundle) continue;
1961
+ if (!dryRun) writeSkillFolder(state.path, bundle);
1962
+ updated.push({
1963
+ ...state,
1964
+ current: !dryRun,
1965
+ installedHash: dryRun ? state.installedHash : bundle.contentHash,
1966
+ metadataHash: dryRun ? state.metadataHash : bundle.contentHash,
1967
+ });
1968
+ }
1969
+ return updated;
1970
+ }
1971
+
1972
+ function normalizeClientIds(values: unknown): ClientId[] {
1973
+ if (!Array.isArray(values)) return [];
1974
+ const seen = new Set<ClientId>();
1975
+ const out: ClientId[] = [];
1976
+ for (const value of values) {
1977
+ if (typeof value !== "string") continue;
1978
+ const id = value.toLowerCase();
1979
+ if (!(CLIENTS as string[]).includes(id)) continue;
1980
+ const client = id as ClientId;
1981
+ if (seen.has(client)) continue;
1982
+ seen.add(client);
1983
+ out.push(client);
1984
+ }
1985
+ return out;
1986
+ }
1987
+
1988
+ function isMcpClientId(value: SkillInstructionClientId): value is ClientId {
1989
+ return (CLIENTS as string[]).includes(value);
1990
+ }
1991
+
1992
+ function normalizeSkillInstructionClientIds(
1993
+ values: unknown,
1994
+ ): SkillInstructionClientId[] {
1995
+ if (!Array.isArray(values)) return [];
1996
+ const seen = new Set<SkillInstructionClientId>();
1997
+ const out: SkillInstructionClientId[] = [];
1998
+ for (const value of values) {
1999
+ if (typeof value !== "string") continue;
2000
+ const id = value.toLowerCase();
2001
+ let normalized: SkillInstructionClientId | null = null;
2002
+ if (id === "pi") {
2003
+ normalized = "pi";
2004
+ } else if ((CLIENTS as string[]).includes(id)) {
2005
+ const client = id as ClientId;
2006
+ normalized = client === "claude-code-cli" ? "claude-code" : client;
2007
+ }
2008
+ if (!normalized) continue;
2009
+ if (seen.has(normalized)) continue;
2010
+ seen.add(normalized);
2011
+ out.push(normalized);
2012
+ }
2013
+ return out;
2014
+ }
2015
+
2016
+ function resolveSkillsClientArg(
2017
+ client: string,
2018
+ installsMcp = false,
2019
+ ): SkillInstructionClientId[] {
2020
+ if (installsMcp)
2021
+ return normalizeSkillInstructionClientIds(resolveClients(client));
2022
+ const values = client.split(",").flatMap((raw) => {
2023
+ const id = raw.trim().toLowerCase();
2024
+ if (!id) return [];
2025
+ if (id === "all") return SKILL_INSTRUCTION_CLIENTS;
2026
+ if (id === "pi") return ["pi" as const];
2027
+ return resolveClients(id);
2028
+ });
2029
+ return normalizeSkillInstructionClientIds(values);
2030
+ }
2031
+
2032
+ function skillsClients(installsMcp: boolean): SkillInstructionClientId[] {
2033
+ return installsMcp ? SKILLS_CLIENTS : SKILL_INSTRUCTION_PROMPT_CLIENTS;
2034
+ }
2035
+
2036
+ function filterSkillsClients(
2037
+ clients: SkillInstructionClientId[],
2038
+ installsMcp: boolean,
2039
+ ): SkillInstructionClientId[] {
2040
+ if (installsMcp) {
2041
+ return clients.filter(
2042
+ (client): client is ClientId =>
2043
+ isMcpClientId(client) && SKILLS_CLIENTS.includes(client),
2044
+ );
2045
+ }
2046
+ // Instructions/local-files mode: keep the first-class instruction writers, and
2047
+ // map shared-`.agents` readers (cursor/opencode/github-copilot/cowork) onto
2048
+ // the shared-agents install (codex) so they install the skills they read
2049
+ // rather than being silently dropped to an empty set.
2050
+ const out: SkillInstructionClientId[] = [];
2051
+ for (const client of clients) {
2052
+ const resolved = SKILL_INSTRUCTION_CLIENTS.includes(client)
2053
+ ? client
2054
+ : SHARED_AGENTS_READER_CLIENTS.has(client)
2055
+ ? "codex"
2056
+ : undefined;
2057
+ if (resolved && !out.includes(resolved)) out.push(resolved);
2058
+ }
2059
+ return out;
2060
+ }
2061
+
2062
+ function clientPromptOptions(
2063
+ installsMcp: boolean,
2064
+ ): SkillsClientPromptContext["options"] {
2065
+ return skillsClients(installsMcp).map((client) => ({
2066
+ value: client,
2067
+ label:
2068
+ installsMcp && isMcpClientId(client)
2069
+ ? CLIENT_LABELS[client]
2070
+ : SKILL_INSTRUCTION_CLIENT_LABELS[client],
2071
+ hint:
2072
+ installsMcp && isMcpClientId(client)
2073
+ ? CLIENT_HINTS[client]
2074
+ : SKILL_INSTRUCTION_CLIENT_HINTS[client],
2075
+ }));
2076
+ }
2077
+
2078
+ const DEFAULT_PUBLIC_SKILLS_SOURCE = "BuilderIO/skills";
2079
+ const PUBLIC_SKILL_TARGET_PREFIX = "public-skills:";
2080
+
2081
+ const BUILT_IN_SKILL_PROMPT_OPTIONS: SkillsTargetPromptContext["options"] = [
2082
+ {
2083
+ value: "visual-plan",
2084
+ label: "visual-plan",
2085
+ hint: "Rich interactive visual plan that turns ordinary text plans into diagrams, file maps, annotated code, questions, and UI/prototype review.",
2086
+ },
2087
+ {
2088
+ value: "visual-recap",
2089
+ label: "visual-recap",
2090
+ hint: "Interactive visual recap that maps PRs/diffs with diagrams, annotated diffs, API/schema summaries, and review notes.",
2091
+ },
2092
+ {
2093
+ value: "visualize-repo",
2094
+ label: "visualize-repo",
2095
+ hint: "Local repo visual docs workspace for APIs, components, models, flows, comments, and coding-agent handoff.",
2096
+ },
2097
+ {
2098
+ value: "assets",
2099
+ label: "assets",
2100
+ hint: BUILT_IN_APP_SKILLS.assets.manifest.description,
2101
+ },
2102
+ {
2103
+ value: "content",
2104
+ label: "content",
2105
+ hint: BUILT_IN_APP_SKILLS.content.manifest.description,
2106
+ },
2107
+ {
2108
+ value: "design-exploration",
2109
+ label: "design-exploration",
2110
+ hint: BUILT_IN_APP_SKILLS.design.manifest.description,
2111
+ },
2112
+ {
2113
+ value: "visual-edit",
2114
+ label: "visual-edit",
2115
+ hint: "Open a running local app in Design overview mode as URL-backed iframe screens.",
2116
+ },
2117
+ {
2118
+ value: "context-xray",
2119
+ label: "context-xray",
2120
+ hint: BUILT_IN_APP_SKILLS["context-xray"].manifest.description,
2121
+ },
2122
+ ];
2123
+
2124
+ const DEFAULT_SKILL_PROMPT_TARGETS = [
2125
+ "visual-plan",
2126
+ "visual-recap",
2127
+ "visualize-repo",
2128
+ ];
2129
+
2130
+ function hiddenBuiltInSkillTargets(options: RunSkillsOptions): Set<string> {
2131
+ return new Set(
2132
+ (options.hiddenBuiltInSkillTargets ?? []).map((target) =>
2133
+ target.trim().toLowerCase(),
2134
+ ),
2135
+ );
2136
+ }
2137
+
2138
+ function builtInSkillPromptOptions(
2139
+ options: RunSkillsOptions,
2140
+ ): SkillsTargetPromptContext["options"] {
2141
+ const hidden = hiddenBuiltInSkillTargets(options);
2142
+ return BUILT_IN_SKILL_PROMPT_OPTIONS.filter(
2143
+ (entry) => !hidden.has(entry.value),
2144
+ );
2145
+ }
2146
+
2147
+ function publicSkillEntries(
2148
+ options: RunSkillsOptions,
2149
+ ): PublicSkillCatalogEntry[] {
2150
+ if (options.catalogMode !== "all") return [];
2151
+ const seen = new Set<string>();
2152
+ return (options.publicSkillEntries ?? [])
2153
+ .map((entry) => ({
2154
+ name: entry.name.trim().toLowerCase(),
2155
+ description: entry.description,
2156
+ }))
2157
+ .filter((entry) => {
2158
+ if (!entry.name || isKnownSkill(entry.name) || seen.has(entry.name)) {
2159
+ return false;
2160
+ }
2161
+ seen.add(entry.name);
2162
+ return true;
2163
+ })
2164
+ .sort((a, b) => a.name.localeCompare(b.name));
2165
+ }
2166
+
2167
+ function publicSkillNames(options: RunSkillsOptions): Set<string> {
2168
+ return new Set(publicSkillEntries(options).map((entry) => entry.name));
2169
+ }
2170
+
2171
+ function publicSkillPromptOptions(
2172
+ options: RunSkillsOptions,
2173
+ ): SkillsTargetPromptContext["options"] {
2174
+ return publicSkillEntries(options).map((entry) => ({
2175
+ value: entry.name,
2176
+ label: entry.name,
2177
+ hint:
2178
+ entry.description ?? "Public skill from the BuilderIO skills catalog.",
2179
+ }));
2180
+ }
2181
+
2182
+ function skillPromptOptions(
2183
+ options: RunSkillsOptions = {},
2184
+ ): SkillsTargetPromptContext["options"] {
2185
+ return [
2186
+ ...builtInSkillPromptOptions(options),
2187
+ ...publicSkillPromptOptions(options),
2188
+ ];
2189
+ }
2190
+
2191
+ function defaultSkillPromptTargets(options: RunSkillsOptions): string[] {
2192
+ const available = new Set(
2193
+ skillPromptOptions(options).map((entry) => entry.value),
2194
+ );
2195
+ return DEFAULT_SKILL_PROMPT_TARGETS.filter((target) => available.has(target));
2196
+ }
2197
+
2198
+ function publicSkillSelectionTarget(skillNames: string[]): string {
2199
+ return `${PUBLIC_SKILL_TARGET_PREFIX}${skillNames.join(",")}`;
2200
+ }
2201
+
2202
+ function publicSkillSelectionNames(target: string): string[] | null {
2203
+ if (!target.startsWith(PUBLIC_SKILL_TARGET_PREFIX)) return null;
2204
+ return target
2205
+ .slice(PUBLIC_SKILL_TARGET_PREFIX.length)
2206
+ .split(",")
2207
+ .map((name) => name.trim().toLowerCase())
2208
+ .filter(Boolean);
2209
+ }
2210
+
2211
+ function prVisualRecapWorkflowPath(baseDir: string): string {
2212
+ return path.join(baseDir, ".github", "workflows", "pr-visual-recap.yml");
2213
+ }
2214
+
2215
+ function prVisualRecapWorkflowDisplayPath(): string {
2216
+ return path.join(".github", "workflows", "pr-visual-recap.yml");
2217
+ }
2218
+
2219
+ const PR_VISUAL_RECAP_DOCS_URL =
2220
+ "https://www.agent-native.com/docs/pr-visual-recap";
2221
+
2222
+ function prVisualRecapInstallCommand(): string {
2223
+ return "npx @agent-native/core@latest skills add visual-recap --with-github-action";
2224
+ }
2225
+
2226
+ function prVisualRecapSetupCommand(): string {
2227
+ return "npx @agent-native/core@latest recap setup";
2228
+ }
2229
+
2230
+ async function promptForGithubAction(
2231
+ context: SkillsGithubActionPromptContext,
2232
+ ): Promise<boolean | null> {
2233
+ const clack = await import("@clack/prompts");
2234
+ const result = await clack.confirm({
2235
+ message:
2236
+ "Optional: add automatic PR Visual Recaps? (GitHub Action)\n" +
2237
+ " Posts a human-friendly recap on every pull request — a high-altitude\n" +
2238
+ " overview of what the PR does, with annotated code, diagrams, and\n" +
2239
+ " before/after notes instead of a raw diff.\n" +
2240
+ ` Learn more: ${PR_VISUAL_RECAP_DOCS_URL}\n` +
2241
+ ` Writes ${context.workflowPath}; ${context.setupCommand} finishes the GitHub secrets.`,
2242
+ initialValue: false,
2243
+ });
2244
+ if (clack.isCancel(result)) {
2245
+ clack.cancel("Skipped PR Visual Recap workflow.");
2246
+ return null;
2247
+ }
2248
+ return Boolean(result);
2249
+ }
2250
+
2251
+ function shouldPrompt(parsed: ParsedSkillsArgs, options: RunSkillsOptions) {
2252
+ if (parsed.yes || parsed.printJson) return false;
2253
+ if (options.isInteractive) return options.isInteractive();
2254
+ if (process.env.AGENT_NATIVE_NO_PROMPT === "1") return false;
2255
+ if (process.env.CI === "true") return false;
2256
+ return !!process.stdin.isTTY && !!process.stdout.isTTY;
2257
+ }
2258
+
2259
+ async function promptForClients(
2260
+ context: SkillsClientPromptContext,
2261
+ ): Promise<SkillInstructionClientId[] | null> {
2262
+ const clack = await import("@clack/prompts");
2263
+ const message = context.installsMcp
2264
+ ? "Install the MCP connector for which clients?\n" +
2265
+ " (space toggles, enter confirms; saved for next time)"
2266
+ : "Where should the skill instructions be written?\n" +
2267
+ " (space toggles, enter confirms; saved for next time)";
2268
+ const result = await clack.multiselect({
2269
+ message,
2270
+ options: context.options,
2271
+ initialValues: context.initialClients,
2272
+ required: true,
2273
+ });
2274
+ if (clack.isCancel(result)) {
2275
+ clack.cancel("Cancelled.");
2276
+ return null;
2277
+ }
2278
+ return normalizeSkillInstructionClientIds(result);
2279
+ }
2280
+
2281
+ async function promptForScope(
2282
+ context: SkillsScopePromptContext,
2283
+ ): Promise<"project" | "user" | null> {
2284
+ const clack = await import("@clack/prompts");
2285
+ const result = await clack.select({
2286
+ message: "Where do you want to install these skills?",
2287
+ options: [
2288
+ {
2289
+ value: "project",
2290
+ label: "Project",
2291
+ hint: "This repo only (.agents / .claude in the current directory) — committed with your project",
2292
+ },
2293
+ {
2294
+ value: "user",
2295
+ label: "User",
2296
+ hint: "Your home directory (~/.codex, ~/.claude) — available across all projects",
2297
+ },
2298
+ ],
2299
+ initialValue: context.initialScope,
2300
+ });
2301
+ if (clack.isCancel(result)) {
2302
+ clack.cancel("Cancelled.");
2303
+ return null;
2304
+ }
2305
+ return result === "project" ? "project" : "user";
2306
+ }
2307
+
2308
+ async function promptForPlanMode(
2309
+ context: SkillsPlanModePromptContext,
2310
+ ): Promise<PlanInstallMode | null> {
2311
+ const clack = await import("@clack/prompts");
2312
+ const result = await clack.select({
2313
+ message: "Where should visual plans and recaps live?",
2314
+ options: [
2315
+ {
2316
+ value: "hosted",
2317
+ label: "Hosted plans, shareable links (recommended)",
2318
+ hint: "100% free and open source. Supports comments, browser editor, and sharing. Requires one-time browser sign-in.",
2319
+ },
2320
+ {
2321
+ value: "local-files",
2322
+ label: "Local files only",
2323
+ hint: "Writes local MDX, starts a localhost bridge, and opens the hosted Plan UI. No sharing, all local.",
2324
+ },
2325
+ {
2326
+ value: "self-hosted",
2327
+ label: "Self-hosted/custom URL",
2328
+ hint: "Connect to your own Plan app or local dev tunnel.",
2329
+ },
2330
+ ],
2331
+ initialValue: context.initialMode,
2332
+ });
2333
+ if (clack.isCancel(result)) {
2334
+ clack.cancel("Cancelled.");
2335
+ return null;
2336
+ }
2337
+ return normalizePlanInstallMode(String(result));
2338
+ }
2339
+
2340
+ async function promptForPlanMcpUrl(): Promise<string | null> {
2341
+ const clack = await import("@clack/prompts");
2342
+ const result = await clack.text({
2343
+ message: "Plan app URL or MCP URL",
2344
+ placeholder: "https://my-plan-app.example.com",
2345
+ validate(value) {
2346
+ try {
2347
+ resolveMcpUrlOverride(value);
2348
+ return undefined;
2349
+ } catch (err: any) {
2350
+ return err?.message ?? "Enter a valid http:// or https:// URL.";
2351
+ }
2352
+ },
2353
+ });
2354
+ if (clack.isCancel(result)) {
2355
+ clack.cancel("Cancelled.");
2356
+ return null;
2357
+ }
2358
+ return String(result).trim();
2359
+ }
2360
+
2361
+ async function promptForUpdateInstructions(): Promise<boolean | null> {
2362
+ const clack = await import("@clack/prompts");
2363
+ const result = await clack.confirm({
2364
+ message:
2365
+ "Add managed AGENTS.md / CLAUDE.md instructions for always-on skill behavior?",
2366
+ initialValue: true,
2367
+ });
2368
+ if (clack.isCancel(result)) {
2369
+ clack.cancel("Skipped managed instruction updates.");
2370
+ return null;
2371
+ }
2372
+ return Boolean(result);
2373
+ }
2374
+
2375
+ async function promptForSkills(
2376
+ context: SkillsTargetPromptContext,
2377
+ ): Promise<string[] | null> {
2378
+ const clack = await import("@clack/prompts");
2379
+ const result = await clack.multiselect({
2380
+ message:
2381
+ "Which Agent Native skills do you want to install?\n" +
2382
+ " (space toggles, enter confirms)",
2383
+ options: context.options,
2384
+ initialValues: context.initialTargets,
2385
+ required: true,
2386
+ });
2387
+ if (clack.isCancel(result)) {
2388
+ clack.cancel("Cancelled.");
2389
+ return null;
2390
+ }
2391
+ if (!Array.isArray(result)) return [];
2392
+ return result.filter((value): value is string => typeof value === "string");
2393
+ }
2394
+
2395
+ async function resolveSkillsClients(
2396
+ parsed: ParsedSkillsArgs,
2397
+ options: RunSkillsOptions,
2398
+ installsMcp: boolean,
2399
+ ): Promise<SkillInstructionClientId[] | null> {
2400
+ if (parsed.clientExplicit || !shouldPrompt(parsed, options)) {
2401
+ const clients = filterSkillsClients(
2402
+ resolveSkillsClientArg(parsed.client, installsMcp),
2403
+ installsMcp,
2404
+ );
2405
+ if (clients.length === 0) {
2406
+ throw new Error(
2407
+ installsMcp
2408
+ ? "MCP setup supports Claude Code, Codex, Claude Cowork, Cursor, OpenCode, or GitHub Copilot / VS Code clients. Use --mode local-files or --no-mcp for Pi."
2409
+ : "Skill instructions use shared .agents for Codex, Pi, Cursor, OpenCode, Copilot, and similar agents, or Claude Code's native files.",
2410
+ );
2411
+ }
2412
+ return clients;
2413
+ }
2414
+ const initialClients = skillsClients(installsMcp);
2415
+ const prompt = options.promptClients ?? promptForClients;
2416
+ const selected = normalizeSkillInstructionClientIds(
2417
+ await prompt({
2418
+ initialClients,
2419
+ options: clientPromptOptions(installsMcp),
2420
+ installsMcp,
2421
+ }),
2422
+ );
2423
+ if (selected.length === 0) return null;
2424
+ if (!parsed.dryRun) {
2425
+ try {
2426
+ writeConnectClientPreferences(selected.filter(isMcpClientId));
2427
+ } catch {}
2428
+ }
2429
+ return selected;
2430
+ }
2431
+
2432
+ function normalizePlanInstallMode(value: string | undefined): PlanInstallMode {
2433
+ const normalized = value?.trim().toLowerCase();
2434
+ if (!normalized || normalized === "hosted") return "hosted";
2435
+ if (
2436
+ normalized === "local" ||
2437
+ normalized === "local-file" ||
2438
+ normalized === "local-files" ||
2439
+ normalized === "files"
2440
+ ) {
2441
+ return "local-files";
2442
+ }
2443
+ if (
2444
+ normalized === "self-hosted" ||
2445
+ normalized === "selfhosted" ||
2446
+ normalized === "custom" ||
2447
+ normalized === "custom-url"
2448
+ ) {
2449
+ return "self-hosted";
2450
+ }
2451
+ throw new Error(
2452
+ '--mode must be one of "hosted", "local-files", or "self-hosted".',
2453
+ );
2454
+ }
2455
+
2456
+ function targetIncludesPlans(target: string): boolean {
2457
+ return normalizeKnownSkillTarget(target) === "visual-plans";
2458
+ }
2459
+
2460
+ function targetsIncludePlans(targets: string[]): boolean {
2461
+ return targets.some(targetIncludesPlans);
2462
+ }
2463
+
2464
+ function targetIncludesInstallModeSkill(target: string): boolean {
2465
+ return targetSupportsInstallMode(normalizeKnownSkillTarget(target));
2466
+ }
2467
+
2468
+ function targetsIncludeInstallModeSkills(targets: string[]): boolean {
2469
+ return targets.some(targetIncludesInstallModeSkill);
2470
+ }
2471
+
2472
+ function planSkillNamesSelected(skillNames: string[] | undefined): boolean {
2473
+ return Boolean(
2474
+ skillNames?.some(
2475
+ (name) => normalizeKnownSkillTarget(name) === "visual-plans",
2476
+ ),
2477
+ );
2478
+ }
2479
+
2480
+ function installModeSkillNamesSelected(
2481
+ skillNames: string[] | undefined,
2482
+ ): boolean {
2483
+ return Boolean(
2484
+ skillNames?.some((name) =>
2485
+ targetSupportsInstallMode(normalizeKnownSkillTarget(name)),
2486
+ ),
2487
+ );
2488
+ }
2489
+
2490
+ function shouldForwardPlanModeFlag(
2491
+ target: string,
2492
+ skillNames: string[] | undefined,
2493
+ ): boolean {
2494
+ return (
2495
+ targetIncludesInstallModeSkill(target) ||
2496
+ installModeSkillNamesSelected(skillNames)
2497
+ );
2498
+ }
2499
+
2500
+ function recapSkillNamesSelected(skillNames: string[] | undefined): boolean {
2501
+ return Boolean(
2502
+ skillNames?.some((name) => {
2503
+ const normalized = name.trim().toLowerCase();
2504
+ return (
2505
+ normalized === "visual-recap" ||
2506
+ normalized === "visual-recaps" ||
2507
+ normalizeKnownSkillTarget(normalized) === "visual-plans"
2508
+ );
2509
+ }),
2510
+ );
2511
+ }
2512
+
2513
+ function resolveSelectedSkillTargets(
2514
+ selected: string[],
2515
+ options: RunSkillsOptions,
2516
+ ): string[] {
2517
+ const publicNames = publicSkillNames(options);
2518
+ const builtInSelections: string[] = [];
2519
+ const publicSelections: string[] = [];
2520
+
2521
+ for (const raw of selected) {
2522
+ const skill = raw.trim().toLowerCase();
2523
+ if (!skill) continue;
2524
+ if (isKnownSkill(skill)) {
2525
+ builtInSelections.push(skill);
2526
+ continue;
2527
+ }
2528
+ if (publicNames.has(skill)) {
2529
+ publicSelections.push(skill);
2530
+ continue;
2531
+ }
2532
+ throw new Error(
2533
+ `Unknown skill: ${raw}. Run "npx @agent-native/core@latest skills list".`,
2534
+ );
2535
+ }
2536
+
2537
+ const out: string[] = [];
2538
+ const planSubskills = ["visual-plan", "visual-recap", "visualize-repo"];
2539
+ const selectedPlanSubskills = planSubskills.filter((skill) =>
2540
+ builtInSelections.includes(skill),
2541
+ );
2542
+ if (selectedPlanSubskills.length === planSubskills.length) {
2543
+ out.push("visual-plans");
2544
+ } else {
2545
+ out.push(...selectedPlanSubskills);
2546
+ }
2547
+ out.push(
2548
+ ...builtInSelections.filter(
2549
+ (skill) => !planSubskills.includes(skill) && !out.includes(skill),
2550
+ ),
2551
+ );
2552
+ if (publicSelections.length > 0) {
2553
+ out.push(publicSkillSelectionTarget([...new Set(publicSelections)]));
2554
+ }
2555
+ return out;
2556
+ }
2557
+
2558
+ async function resolveSkillTargets(
2559
+ parsed: ParsedSkillsArgs,
2560
+ options: RunSkillsOptions,
2561
+ ): Promise<string[] | null> {
2562
+ if (!parsed.target && parsed.plainSkillNames?.length) {
2563
+ return resolveSelectedSkillTargets(parsed.plainSkillNames, options);
2564
+ }
2565
+ if (parsed.target || !shouldPrompt(parsed, options)) {
2566
+ const target = parsed.target ?? "assets";
2567
+ if (!parsed.target) return [target];
2568
+ const normalizedTarget = target.trim().toLowerCase();
2569
+ if (publicSkillNames(options).has(normalizedTarget)) {
2570
+ return [publicSkillSelectionTarget([normalizedTarget])];
2571
+ }
2572
+ return [target];
2573
+ }
2574
+ const prompt = options.promptSkills ?? promptForSkills;
2575
+ const promptOptions = skillPromptOptions(options);
2576
+ // The interactive multiselect skill picker is about to be shown (no --skill /
2577
+ // target passed and we are interactive) — record the funnel "prompted" step.
2578
+ options.telemetry?.track("skills_cli skills prompted", {
2579
+ availableCount: promptOptions.length,
2580
+ available: promptOptions.map((option) => option.value).join(","),
2581
+ });
2582
+ const selected = await prompt({
2583
+ initialTargets: defaultSkillPromptTargets(options),
2584
+ options: promptOptions,
2585
+ });
2586
+ if (!selected || selected.length === 0) return null;
2587
+ return resolveSelectedSkillTargets(selected, options);
2588
+ }
2589
+
2590
+ export function parseSkillsArgs(argv: string[]): ParsedSkillsArgs {
2591
+ const first = argv[0];
2592
+ let command: SkillsCommand = "list";
2593
+ let args = argv;
2594
+ if (first === "help" || first === "--help" || first === "-h") {
2595
+ command = "help";
2596
+ args = argv.slice(1);
2597
+ } else if (
2598
+ first === "list" ||
2599
+ first === "add" ||
2600
+ first === "status" ||
2601
+ first === "update"
2602
+ ) {
2603
+ command = first;
2604
+ args = argv.slice(1);
2605
+ } else if (first) {
2606
+ command = "add";
2607
+ }
2608
+
2609
+ const out: ParsedSkillsArgs = {
2610
+ command,
2611
+ client: "all",
2612
+ clientExplicit: false,
2613
+ scope: "user",
2614
+ scopeExplicit: false,
2615
+ yes: false,
2616
+ dryRun: false,
2617
+ printJson: false,
2618
+ instructions: true,
2619
+ mcp: true,
2620
+ connect: true,
2621
+ };
2622
+
2623
+ for (let i = 0; i < args.length; i++) {
2624
+ const arg = args[i];
2625
+ const eat = (flag: string): string | undefined => {
2626
+ if (arg === flag) {
2627
+ const next = args[++i];
2628
+ if (!next || next.startsWith("-")) {
2629
+ throw new Error(`Missing value for ${flag}.`);
2630
+ }
2631
+ return next;
2632
+ }
2633
+ if (arg.startsWith(`${flag}=`)) {
2634
+ const value = arg.slice(flag.length + 1);
2635
+ if (!value) throw new Error(`Missing value for ${flag}.`);
2636
+ return value;
2637
+ }
2638
+ return undefined;
2639
+ };
2640
+ let value: string | undefined;
2641
+ if ((value = eat("--client")) !== undefined) {
2642
+ out.client = value;
2643
+ out.clientExplicit = true;
2644
+ } else if ((value = eat("--agent")) !== undefined) {
2645
+ out.client = value;
2646
+ out.clientExplicit = true;
2647
+ } else if ((value = eat("-a")) !== undefined) {
2648
+ out.client = value;
2649
+ out.clientExplicit = true;
2650
+ } else if ((value = eat("--skill")) !== undefined) {
2651
+ out.plainSkillNames = [...(out.plainSkillNames ?? []), value];
2652
+ } else if ((value = eat("-s")) !== undefined) {
2653
+ out.plainSkillNames = [...(out.plainSkillNames ?? []), value];
2654
+ } else if ((value = eat("--scope")) !== undefined) {
2655
+ out.scope = value;
2656
+ out.scopeExplicit = true;
2657
+ } else if ((value = eat("--cwd")) !== undefined) out.baseDir = value;
2658
+ else if ((value = eat("--mcp-url")) !== undefined) out.mcpUrl = value;
2659
+ else if ((value = eat("--mode")) !== undefined)
2660
+ out.planMode = normalizePlanInstallMode(value);
2661
+ else if (arg === "--hosted") out.planMode = "hosted";
2662
+ else if (arg === "--local" || arg === "--local-files")
2663
+ out.planMode = "local-files";
2664
+ else if (arg === "--self-hosted" || arg === "--custom-url")
2665
+ out.planMode = "self-hosted";
2666
+ else if (arg === "--yes" || arg === "-y") out.yes = true;
2667
+ else if (arg === "--dry-run") out.dryRun = true;
2668
+ else if (arg === "--json") out.printJson = true;
2669
+ else if (arg === "-g" || arg === "--global") {
2670
+ out.scope = "user";
2671
+ out.scopeExplicit = true;
2672
+ } else if (arg === "--project") {
2673
+ out.scope = "project";
2674
+ out.scopeExplicit = true;
2675
+ } else if (arg === "--copy") {
2676
+ // Compatibility with @agent-native/skills. Core always copies skill
2677
+ // instructions instead of linking to the source repo.
2678
+ } else if (arg === "--mcp-only") out.instructions = false;
2679
+ else if (arg === "--instructions-only" || arg === "--no-mcp")
2680
+ out.mcp = false;
2681
+ else if (arg === "--no-connect" || arg === "--skip-connect")
2682
+ out.connect = false;
2683
+ else if (arg === "--with-github-action" || arg === "--with-github-actions")
2684
+ out.withGithubAction = true;
2685
+ else if (arg === "--update-instructions") out.updateInstructions = true;
2686
+ else if (arg === "--no-update-instructions") out.updateInstructions = false;
2687
+ else if (arg === "--force") out.force = true;
2688
+ else if (arg.startsWith("-")) throw new Error(`Unknown option: ${arg}`);
2689
+ else if (!out.target) out.target = arg;
2690
+ else throw new Error(`Unexpected argument: ${arg}`);
2691
+ }
2692
+
2693
+ if (out.scope !== "user" && out.scope !== "project") {
2694
+ throw new Error("--scope must be either user or project.");
2695
+ }
2696
+ if (out.planMode === "local-files" && out.mcpUrl) {
2697
+ throw new Error("--mode local-files cannot be combined with --mcp-url.");
2698
+ }
2699
+ return out;
2700
+ }
2701
+
2702
+ function loadSkillTarget(
2703
+ target: string,
2704
+ onlySkillNames?: string[],
2705
+ ): SkillInstallTarget {
2706
+ const knownTarget = normalizeKnownSkillTarget(target);
2707
+ if (knownTarget) {
2708
+ const builtIn = BUILT_IN_APP_SKILLS[knownTarget];
2709
+ const skillNames = builtInSkillNames(builtIn).filter(
2710
+ (name) => !onlySkillNames || onlySkillNames.includes(name),
2711
+ );
2712
+ return {
2713
+ id: builtIn.manifest.id,
2714
+ displayName: builtIn.manifest.displayName,
2715
+ loaded: {
2716
+ manifest: builtIn.manifest,
2717
+ file: `<built-in:${builtIn.manifest.id}>`,
2718
+ dir: process.cwd(),
2719
+ },
2720
+ skillNames,
2721
+ modeAwareId: targetSupportsInstallMode(knownTarget)
2722
+ ? knownTarget
2723
+ : undefined,
2724
+ materializeInstructions(outDir) {
2725
+ const bundles = skillFilesForBuiltIn(knownTarget);
2726
+ for (const bundle of Object.values(bundles)) {
2727
+ if (onlySkillNames && !onlySkillNames.includes(bundle.skillName)) {
2728
+ continue;
2729
+ }
2730
+ writeSkillFolder(
2731
+ path.join(outDir, "skills", bundle.skillName),
2732
+ bundle,
2733
+ );
2734
+ }
2735
+ return outDir;
2736
+ },
2737
+ };
2738
+ }
2739
+
2740
+ const resolved = path.resolve(target);
2741
+ const manifestFile = fs.statSync(resolved).isDirectory()
2742
+ ? path.join(resolved, "agent-native.app-skill.json")
2743
+ : resolved;
2744
+ const loaded = loadAppSkillManifest(manifestFile);
2745
+ return {
2746
+ id: loaded.manifest.id,
2747
+ displayName: loaded.manifest.displayName,
2748
+ loaded,
2749
+ skillNames: loaded.manifest.skills
2750
+ .filter(
2751
+ (skill) =>
2752
+ skill.visibility === "exported" || skill.visibility === "both",
2753
+ )
2754
+ .map((skill) => skill.exportAs ?? path.basename(skill.path)),
2755
+ modeAwareId: targetSupportsInstallMode(loaded.manifest.id)
2756
+ ? loaded.manifest.id
2757
+ : undefined,
2758
+ materializeInstructions(outDir) {
2759
+ const packed = buildAppSkillPack(loaded, outDir);
2760
+ const vercelAdapter = path.join(
2761
+ packed.outDir,
2762
+ "adapters",
2763
+ "vercel-skills",
2764
+ );
2765
+ return fs.existsSync(vercelAdapter) ? vercelAdapter : packed.outDir;
2766
+ },
2767
+ };
2768
+ }
2769
+
2770
+ function skillsAgentsForClients(
2771
+ clients: SkillInstructionClientId[],
2772
+ ): SkillInstructionClientId[] {
2773
+ const agents = new Set<SkillInstructionClientId>();
2774
+ for (const client of clients) {
2775
+ if (client === "codex") agents.add("codex");
2776
+ if (client === "claude-code" || client === "claude-code-cli") {
2777
+ agents.add("claude-code");
2778
+ }
2779
+ if (client === "pi") agents.add("pi");
2780
+ }
2781
+ return [...agents];
2782
+ }
2783
+
2784
+ function shellArg(value: string): string {
2785
+ if (/^[A-Za-z0-9_/:=.,@+-]+$/.test(value)) return value;
2786
+ return `'${value.replace(/'/g, `'\\''`)}'`;
2787
+ }
2788
+
2789
+ function commandString(cmd: string, args: string[]): string {
2790
+ return [cmd, ...args].map(shellArg).join(" ");
2791
+ }
2792
+
2793
+ function clientArgForClients(clients: SkillInstructionClientId[]): string {
2794
+ if (clients.length === CLIENTS.length && clients.every(isMcpClientId))
2795
+ return "all";
2796
+ if (clients.length === 1) return clients[0];
2797
+ return clients.join(",");
2798
+ }
2799
+
2800
+ function preserveMcpUrlAppPathOverride(
2801
+ target: SkillInstallTarget,
2802
+ input: string | undefined,
2803
+ ): SkillInstallTarget {
2804
+ if (!input) return target;
2805
+ let parsed: URL;
2806
+ try {
2807
+ parsed = new URL(input);
2808
+ } catch {
2809
+ return target;
2810
+ }
2811
+ const trimmedPath = parsed.pathname.replace(/\/+$/, "");
2812
+ const mcpSuffix = [MCP_LEGACY_ROUTE_PREFIX, MCP_PUBLIC_ROUTE_PREFIX].find(
2813
+ (suffix) => trimmedPath === suffix || trimmedPath.endsWith(suffix),
2814
+ );
2815
+ const appPath = mcpSuffix
2816
+ ? trimmedPath.slice(0, -mcpSuffix.length).replace(/\/+$/, "")
2817
+ : trimmedPath;
2818
+ if (!appPath) return target;
2819
+ const url = `${parsed.origin}${appPath}`;
2820
+ return {
2821
+ ...target,
2822
+ loaded: {
2823
+ ...target.loaded,
2824
+ manifest: {
2825
+ ...target.loaded.manifest,
2826
+ hosted: { url, mcpUrl: `${url}${MCP_PUBLIC_ROUTE_PREFIX}` },
2827
+ },
2828
+ },
2829
+ };
2830
+ }
2831
+
2832
+ function dryRunInstallCommand(
2833
+ parsed: ParsedSkillsArgs,
2834
+ target: string,
2835
+ options: { modeAwareTargetId?: string } = {},
2836
+ ): string {
2837
+ const clients =
2838
+ parsed.clients ??
2839
+ resolveSkillsClientArg(parsed.client, targetInstallsMcp(target, parsed));
2840
+ const args = [
2841
+ "@agent-native/core@latest",
2842
+ "skills",
2843
+ "add",
2844
+ target,
2845
+ "--client",
2846
+ clientArgForClients(clients),
2847
+ "--scope",
2848
+ parsed.scope,
2849
+ ];
2850
+ const forwardsPlanFlags = shouldForwardPlanModeFlag(
2851
+ target,
2852
+ parsed.plainSkillNames,
2853
+ );
2854
+ const forwardsInstallMode =
2855
+ forwardsPlanFlags || targetSupportsInstallMode(options.modeAwareTargetId);
2856
+ if (forwardsInstallMode && parsed.planMode)
2857
+ args.push("--mode", parsed.planMode);
2858
+ if (parsed.mcpUrl) args.push("--mcp-url", parsed.mcpUrl);
2859
+ if (parsed.instructions && !parsed.mcp) args.push("--instructions-only");
2860
+ if (!parsed.instructions && parsed.mcp) args.push("--mcp-only");
2861
+ if (!parsed.connect) args.push("--no-connect");
2862
+ if (parsed.withGithubAction) args.push("--with-github-action");
2863
+ if (parsed.updateInstructions === true) args.push("--update-instructions");
2864
+ if (parsed.updateInstructions === false)
2865
+ args.push("--no-update-instructions");
2866
+ if (parsed.yes || isKnownSkill(target)) args.push("--yes");
2867
+ return commandString("npx", args);
2868
+ }
2869
+
2870
+ async function runCommand(
2871
+ cmd: string,
2872
+ args: string[],
2873
+ options: RunCommandOptions = {},
2874
+ ): Promise<number> {
2875
+ return new Promise((resolve, reject) => {
2876
+ const pipeToStderr = options.stdio === "stderr";
2877
+ const silent = options.stdio === "silent";
2878
+ const stdoutChunks: Buffer[] = [];
2879
+ const stderrChunks: Buffer[] = [];
2880
+ const child = spawn(cmd, args, {
2881
+ stdio: pipeToStderr || silent ? ["inherit", "pipe", "pipe"] : "inherit",
2882
+ shell: process.platform === "win32",
2883
+ env: process.env,
2884
+ });
2885
+ if (pipeToStderr) {
2886
+ child.stdout?.on("data", (chunk) => process.stderr.write(chunk));
2887
+ child.stderr?.on("data", (chunk) => process.stderr.write(chunk));
2888
+ } else if (silent) {
2889
+ child.stdout?.on("data", (chunk) =>
2890
+ stdoutChunks.push(Buffer.from(chunk)),
2891
+ );
2892
+ child.stderr?.on("data", (chunk) =>
2893
+ stderrChunks.push(Buffer.from(chunk)),
2894
+ );
2895
+ }
2896
+ child.on("error", reject);
2897
+ child.on("exit", (code, signal) => {
2898
+ if (signal) {
2899
+ reject(new Error(`${cmd} was interrupted by ${signal}.`));
2900
+ return;
2901
+ }
2902
+ if (silent && code !== 0) {
2903
+ for (const chunk of stdoutChunks) process.stderr.write(chunk);
2904
+ for (const chunk of stderrChunks) process.stderr.write(chunk);
2905
+ }
2906
+ resolve(code ?? 0);
2907
+ });
2908
+ });
2909
+ }
2910
+
2911
+ /**
2912
+ * Resolve a `--mcp-url` override into the `{ url, mcpUrl }` pair the manifest
2913
+ * expects. Accepts a bare origin (`https://x.ngrok-free.dev`) — appending the
2914
+ * standard `/mcp` path — or a full MCP URL already ending in `/mcp` or the
2915
+ * legacy `/_agent-native/mcp` path.
2916
+ */
2917
+ function resolveMcpUrlOverride(input: string): { url: string; mcpUrl: string } {
2918
+ let parsed: URL;
2919
+ try {
2920
+ parsed = new URL(input);
2921
+ } catch {
2922
+ throw new Error(`--mcp-url must be a valid URL (got "${input}").`);
2923
+ }
2924
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
2925
+ throw new Error("--mcp-url must use http:// or https://.");
2926
+ }
2927
+ const origin = parsed.origin;
2928
+ const trimmedPath = parsed.pathname.replace(/\/+$/, "");
2929
+ const mcpSuffix = [MCP_LEGACY_ROUTE_PREFIX, MCP_PUBLIC_ROUTE_PREFIX].find(
2930
+ (suffix) => trimmedPath === suffix || trimmedPath.endsWith(suffix),
2931
+ );
2932
+ const mcpUrl = mcpSuffix
2933
+ ? `${origin}${trimmedPath.slice(0, -mcpSuffix.length)}${MCP_PUBLIC_ROUTE_PREFIX}`
2934
+ : `${origin}${MCP_PUBLIC_ROUTE_PREFIX}`;
2935
+ return { url: origin, mcpUrl };
2936
+ }
2937
+
2938
+ /** Return a copy of the install target with its hosted MCP URL overridden. */
2939
+ function withMcpUrlOverride(
2940
+ target: SkillInstallTarget,
2941
+ input: string,
2942
+ ): SkillInstallTarget {
2943
+ const { url, mcpUrl } = resolveMcpUrlOverride(input);
2944
+ return {
2945
+ ...target,
2946
+ loaded: {
2947
+ ...target.loaded,
2948
+ manifest: { ...target.loaded.manifest, hosted: { url, mcpUrl } },
2949
+ },
2950
+ };
2951
+ }
2952
+
2953
+ function isPlainSkillRepoPath(target: string): boolean {
2954
+ const resolved = path.resolve(target);
2955
+ if (!fs.existsSync(resolved)) return false;
2956
+ const stat = fs.statSync(resolved);
2957
+ if (!stat.isDirectory()) return false;
2958
+ const hasDirectSkill = fs.existsSync(path.join(resolved, "SKILL.md"));
2959
+ const skillsDir = path.join(resolved, "skills");
2960
+ const hasSkillsDir =
2961
+ fs.existsSync(skillsDir) &&
2962
+ fs
2963
+ .readdirSync(skillsDir, { withFileTypes: true })
2964
+ .some(
2965
+ (entry) =>
2966
+ entry.isDirectory() &&
2967
+ fs.existsSync(path.join(skillsDir, entry.name, "SKILL.md")),
2968
+ );
2969
+ const hasAppSkillManifest = fs.existsSync(
2970
+ path.join(resolved, "agent-native.app-skill.json"),
2971
+ );
2972
+ return !hasAppSkillManifest && (hasDirectSkill || hasSkillsDir);
2973
+ }
2974
+
2975
+ function isGithubSkillRepoTarget(target: string): boolean {
2976
+ if (/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:#.+)?$/.test(target)) {
2977
+ return true;
2978
+ }
2979
+ try {
2980
+ const url = new URL(target);
2981
+ return url.hostname === "github.com";
2982
+ } catch {
2983
+ return false;
2984
+ }
2985
+ }
2986
+
2987
+ function isPlainSkillRepoTarget(target: string): boolean {
2988
+ return isPlainSkillRepoPath(target) || isGithubSkillRepoTarget(target);
2989
+ }
2990
+
2991
+ function agentNativeSkillsInstallArgs(
2992
+ parsed: ParsedSkillsArgs,
2993
+ target: string,
2994
+ clients: SkillInstructionClientId[],
2995
+ baseDir: string | undefined,
2996
+ ): string[] {
2997
+ const args = [
2998
+ "--yes",
2999
+ "@agent-native/skills@latest",
3000
+ "add",
3001
+ "--quiet",
3002
+ "--copy",
3003
+ target,
3004
+ "--client",
3005
+ clientArgForClients(clients),
3006
+ "--scope",
3007
+ parsed.scope,
3008
+ ];
3009
+ if (baseDir) args.push("--cwd", baseDir);
3010
+ if (parsed.withGithubAction) args.push("--with-github-action");
3011
+ if (parsed.force) args.push("--force");
3012
+ const forwardsPlanFlags = shouldForwardPlanModeFlag(
3013
+ target,
3014
+ parsed.plainSkillNames,
3015
+ );
3016
+ if (forwardsPlanFlags && parsed.planMode)
3017
+ args.push("--mode", parsed.planMode);
3018
+ if (forwardsPlanFlags && parsed.mcpUrl) args.push("--mcp-url", parsed.mcpUrl);
3019
+ if (!parsed.mcp) args.push("--no-mcp");
3020
+ if (!parsed.connect) args.push("--no-connect");
3021
+ for (const skill of parsed.plainSkillNames ?? []) {
3022
+ args.push("--skill", skill);
3023
+ }
3024
+ if (parsed.updateInstructions === true) args.push("--update-instructions");
3025
+ if (parsed.updateInstructions === false)
3026
+ args.push("--no-update-instructions");
3027
+ if (parsed.yes) args.push("--yes");
3028
+ if (parsed.dryRun) args.push("--dry-run");
3029
+ return args;
3030
+ }
3031
+
3032
+ async function addPlainSkillRepo(
3033
+ parsed: ParsedSkillsArgs,
3034
+ options: RunSkillsOptions,
3035
+ ): Promise<SkillsAddResult> {
3036
+ const target = parsed.target!;
3037
+ if (!parsed.instructions && parsed.mcp) {
3038
+ throw new Error(
3039
+ "Plain skill repositories only install skill instructions. Run without --mcp-only.",
3040
+ );
3041
+ }
3042
+ if (parsed.mcpUrl && !installModeSkillNamesSelected(parsed.plainSkillNames)) {
3043
+ throw new Error(
3044
+ "--mcp-url only applies to app-backed Agent Native skills.",
3045
+ );
3046
+ }
3047
+
3048
+ const clients = parsed.clients ?? resolveSkillsClientArg(parsed.client);
3049
+ const skillsAgents = skillsAgentsForClients(clients);
3050
+ const selectedSkillNames = parsed.plainSkillNames ?? [];
3051
+ if (skillsAgents.length === 0) {
3052
+ throw new Error(
3053
+ "Plain skill repositories install through shared .agents for Codex, Pi, Cursor, OpenCode, Copilot, and similar agents, or Claude Code's native files.",
3054
+ );
3055
+ }
3056
+ const args = agentNativeSkillsInstallArgs(
3057
+ parsed,
3058
+ target,
3059
+ skillsAgents,
3060
+ options.baseDir,
3061
+ );
3062
+ if (!parsed.dryRun) {
3063
+ const code = await (options.runCommand ?? runCommand)("npx", args, {
3064
+ stdio: "silent",
3065
+ });
3066
+ if (code !== 0)
3067
+ throw new Error(
3068
+ `npx @agent-native/skills@latest add exited with ${code}.`,
3069
+ );
3070
+ }
3071
+ options.telemetry?.track("skills_cli install completed", {
3072
+ skills: selectedSkillNames.length ? selectedSkillNames.join(",") : target,
3073
+ clients: clients.join(","),
3074
+ scope: parsed.scope,
3075
+ dryRun: Boolean(parsed.dryRun),
3076
+ });
3077
+ return {
3078
+ id: target,
3079
+ displayName: selectedSkillNames.length
3080
+ ? selectedSkillNames.join(", ")
3081
+ : target,
3082
+ skillNames: selectedSkillNames,
3083
+ skillsAgents,
3084
+ mcpUrl: "",
3085
+ mcpClients: [],
3086
+ dryRun: parsed.dryRun,
3087
+ commands: [commandString("npx", args)],
3088
+ local: true,
3089
+ };
3090
+ }
3091
+
3092
+ /**
3093
+ * Whether we can run the interactive browser/device auth flow. CI and
3094
+ * non-TTY shells must not block on a browser approval, so we skip the inline
3095
+ * flow there and surface the exact `agent-native connect` command instead.
3096
+ */
3097
+ function canRunInteractiveConnect(options: RunSkillsOptions): boolean {
3098
+ if (options.isInteractive) return options.isInteractive();
3099
+ if (process.env.AGENT_NATIVE_NO_PROMPT === "1") return false;
3100
+ if (process.env.CI === "true") return false;
3101
+ return !!process.stdin.isTTY && !!process.stdout.isTTY;
3102
+ }
3103
+
3104
+ function normalizeConnectLogMessage(message: string): string {
3105
+ return message
3106
+ .split("\n")
3107
+ .map((line) => (line.startsWith(" ") ? line.slice(2) : line))
3108
+ .join("\n");
3109
+ }
3110
+
3111
+ function createClackConnectLog(
3112
+ clack: typeof import("@clack/prompts"),
3113
+ ): (message: string) => void {
3114
+ return (message) => {
3115
+ clack.log.message(normalizeConnectLogMessage(message), {
3116
+ symbol: clack.S_BAR,
3117
+ secondarySymbol: clack.S_BAR,
3118
+ spacing: 0,
3119
+ });
3120
+ };
3121
+ }
3122
+
3123
+ async function runWithConnectSpinner<T>(
3124
+ options: RunSkillsOptions,
3125
+ message: string,
3126
+ task: () => T | Promise<T>,
3127
+ ): Promise<T> {
3128
+ const spinner = options.createConnectSpinner?.();
3129
+ if (!spinner) return await task();
3130
+ spinner.start(message);
3131
+ try {
3132
+ return await task();
3133
+ } finally {
3134
+ spinner.clear();
3135
+ }
3136
+ }
3137
+
3138
+ /** Build the `npx @agent-native/core@latest connect <url> --client … --scope …` command. */
3139
+ function connectCommandFor(
3140
+ hostedUrl: string,
3141
+ clients: ClientId[],
3142
+ scope: string,
3143
+ ): string {
3144
+ const args = [
3145
+ "@agent-native/core@latest",
3146
+ "connect",
3147
+ hostedUrl,
3148
+ "--client",
3149
+ clientArgForClients(clients),
3150
+ "--scope",
3151
+ scope,
3152
+ ];
3153
+ return commandString("npx", args);
3154
+ }
3155
+
3156
+ /**
3157
+ * Authenticate the freshly-registered hosted MCP connector so the user does not
3158
+ * hit the OAuth wall on their first tool call. Reuses the existing
3159
+ * `agent-native connect` flow (OAuth-capable clients get URL-only config plus a
3160
+ * `/mcp` authenticate prompt; Codex / Cowork run the browser device-code flow).
3161
+ * In non-interactive shells we skip the inline flow and return the command to
3162
+ * run instead. Failures here are non-fatal: the connector is already registered,
3163
+ * so the user can authenticate later.
3164
+ */
3165
+ async function connectAfterEnsure(
3166
+ installTarget: SkillInstallTarget,
3167
+ clients: ClientId[],
3168
+ parsed: ParsedSkillsArgs,
3169
+ options: RunSkillsOptions,
3170
+ ): Promise<{ connected: boolean; connectCommand: string }> {
3171
+ const hostedUrl = installTarget.loaded.manifest.hosted.url;
3172
+ const authMode = installTarget.loaded.manifest.auth?.mode ?? "oauth";
3173
+ const connectCommand = connectCommandFor(hostedUrl, clients, parsed.scope);
3174
+
3175
+ // Skills whose connector needs no auth (e.g. open/local-only) never need the
3176
+ // connect step.
3177
+ if (authMode === "none") {
3178
+ return { connected: false, connectCommand: "" };
3179
+ }
3180
+
3181
+ if (!canRunInteractiveConnect(options)) {
3182
+ options.log?.(
3183
+ `Authentication skipped (non-interactive). To finish auth, run: ${connectCommand}`,
3184
+ );
3185
+ return { connected: false, connectCommand };
3186
+ }
3187
+
3188
+ const authMessage = `Authenticating ${installTarget.displayName}…`;
3189
+ const connectLog = options.connectLog ?? options.log;
3190
+ const spinner = options.createConnectSpinner?.();
3191
+ let spinnerActive = false;
3192
+ let wroteAuthMessage = false;
3193
+ const clearSpinner = () => {
3194
+ if (!spinnerActive) return;
3195
+ spinner.clear();
3196
+ spinnerActive = false;
3197
+ };
3198
+ const writeAuthMessage = () => {
3199
+ if (wroteAuthMessage) return;
3200
+ connectLog?.(authMessage);
3201
+ wroteAuthMessage = true;
3202
+ };
3203
+ const writeConnectLog = (message: string) => {
3204
+ clearSpinner();
3205
+ writeAuthMessage();
3206
+ connectLog?.(message);
3207
+ };
3208
+ if (spinner) {
3209
+ spinner.start(authMessage);
3210
+ spinnerActive = true;
3211
+ } else {
3212
+ writeAuthMessage();
3213
+ }
3214
+ options.telemetry?.track("skills_cli connect started");
3215
+ try {
3216
+ const connectArgs = [
3217
+ hostedUrl,
3218
+ "--client",
3219
+ clientArgForClients(clients),
3220
+ "--scope",
3221
+ parsed.scope,
3222
+ ];
3223
+ if (options.runConnect) {
3224
+ await options.runConnect(connectArgs);
3225
+ } else {
3226
+ await runConnect(connectArgs, {
3227
+ isInteractive: options.isInteractive,
3228
+ logOut: writeConnectLog,
3229
+ logErr: writeConnectLog,
3230
+ withBrowserOpenSpinner: (message, openBrowser) =>
3231
+ runWithConnectSpinner(options, message, openBrowser),
3232
+ });
3233
+ }
3234
+ clearSpinner();
3235
+ writeAuthMessage();
3236
+ options.telemetry?.track("skills_cli connect completed");
3237
+ return { connected: true, connectCommand: "" };
3238
+ } catch (err: any) {
3239
+ clearSpinner();
3240
+ writeAuthMessage();
3241
+ // Non-fatal: the MCP connector is registered. Surface the manual command.
3242
+ options.telemetry?.track("skills_cli connect failed", {
3243
+ error: err?.message ?? String(err),
3244
+ });
3245
+ connectLog?.(
3246
+ `Could not finish authentication automatically (${err?.message ?? err}). ` +
3247
+ `Run it later with: ${connectCommand}`,
3248
+ );
3249
+ return { connected: false, connectCommand };
3250
+ }
3251
+ }
3252
+
3253
+ export async function addAgentNativeSkill(
3254
+ parsed: ParsedSkillsArgs,
3255
+ options: RunSkillsOptions = {},
3256
+ ): Promise<SkillsAddResult> {
3257
+ const target = parsed.target ?? "assets";
3258
+ const publicSelection = publicSkillSelectionNames(target);
3259
+ if (publicSelection) {
3260
+ return addPlainSkillRepo(
3261
+ {
3262
+ ...parsed,
3263
+ target: options.publicSkillSource ?? DEFAULT_PUBLIC_SKILLS_SOURCE,
3264
+ plainSkillNames: publicSelection,
3265
+ },
3266
+ options,
3267
+ );
3268
+ }
3269
+ const knownTarget = normalizeKnownSkillTarget(target);
3270
+ // For multi-skill bundles (the plan bundle), a single-skill target installs
3271
+ // only that skill. `installsRecap` controls the PR Visual Recap github-action
3272
+ // offer, which is only relevant when the recap skill is part of the install.
3273
+ const onlySkillNames = knownTarget
3274
+ ? builtInOnlySkillNames(target)
3275
+ : undefined;
3276
+ const installsRecap =
3277
+ knownTarget === "visual-plans" &&
3278
+ (!onlySkillNames || onlySkillNames.includes("visual-recap"));
3279
+ if (!knownTarget && isPlainSkillRepoTarget(target)) {
3280
+ return addPlainSkillRepo({ ...parsed, target }, options);
3281
+ }
3282
+ if (!knownTarget && !fs.existsSync(path.resolve(target))) {
3283
+ throw new Error(
3284
+ `Unknown skill or manifest path: ${target}. Run "npx @agent-native/core@latest skills list".`,
3285
+ );
3286
+ }
3287
+ const knownBuiltIn = knownTarget ? BUILT_IN_APP_SKILLS[knownTarget] : null;
3288
+ const baseDir = options.baseDir ?? process.cwd();
3289
+ if (isLocalOnlyBuiltInSkill(knownBuiltIn)) {
3290
+ if (parsed.planMode) {
3291
+ throw new Error(
3292
+ "--mode only applies to visual-plan / visual-recap / visualize-repo / content.",
3293
+ );
3294
+ }
3295
+ if (parsed.mcpUrl) {
3296
+ throw new Error(
3297
+ "Context X-Ray is installed locally and does not use --mcp-url yet.",
3298
+ );
3299
+ }
3300
+ if (!parsed.instructions && parsed.mcp) {
3301
+ throw new Error(
3302
+ "Context X-Ray does not need MCP config yet. Run without --mcp-only.",
3303
+ );
3304
+ }
3305
+ const clients = (
3306
+ parsed.clients ?? resolveSkillsClientArg(parsed.client)
3307
+ ).filter(isMcpClientId);
3308
+ const skillsAgents = skillsAgentsForClients(clients);
3309
+ if (parsed.dryRun) {
3310
+ const githubActionPath =
3311
+ parsed.withGithubAction && knownTarget === "visual-plans"
3312
+ ? prVisualRecapWorkflowDisplayPath()
3313
+ : undefined;
3314
+ options.telemetry?.track("skills_cli install completed", {
3315
+ skills: knownBuiltIn.skillName,
3316
+ clients: clients.join(","),
3317
+ scope: parsed.scope,
3318
+ dryRun: true,
3319
+ });
3320
+ return {
3321
+ id: knownBuiltIn.manifest.id,
3322
+ displayName: knownBuiltIn.manifest.displayName,
3323
+ skillNames: [knownBuiltIn.skillName],
3324
+ skillsAgents,
3325
+ mcpUrl: "",
3326
+ mcpClients: [],
3327
+ dryRun: true,
3328
+ local: true,
3329
+ commands: [dryRunInstallCommand(parsed, target)],
3330
+ githubActionPath,
3331
+ };
3332
+ }
3333
+ const localInstall = installLocalContextXray({
3334
+ baseDir,
3335
+ clients,
3336
+ scope: parsed.scope,
3337
+ });
3338
+ options.telemetry?.track("skills_cli install completed", {
3339
+ skills: knownBuiltIn.skillName,
3340
+ clients: clients.join(","),
3341
+ scope: parsed.scope,
3342
+ dryRun: false,
3343
+ });
3344
+ return {
3345
+ id: knownBuiltIn.manifest.id,
3346
+ displayName: knownBuiltIn.manifest.displayName,
3347
+ instructionSource: localInstall.scriptPath,
3348
+ skillNames: [knownBuiltIn.skillName],
3349
+ skillsAgents,
3350
+ mcpUrl: "",
3351
+ mcpClients: [],
3352
+ dryRun: false,
3353
+ local: true,
3354
+ scriptPath: localInstall.scriptPath,
3355
+ written: localInstall.written,
3356
+ commands: localInstall.commands,
3357
+ };
3358
+ }
3359
+ let installTarget = loadSkillTarget(target, onlySkillNames);
3360
+ const modeAwareTargetId = installTarget.modeAwareId;
3361
+ const planMode = modeAwareTargetId
3362
+ ? (parsed.planMode ??
3363
+ (parsed.mcpUrl
3364
+ ? "self-hosted"
3365
+ : modeAwareTargetId === "visual-plans"
3366
+ ? "hosted"
3367
+ : undefined))
3368
+ : undefined;
3369
+ if (parsed.planMode && !modeAwareTargetId) {
3370
+ throw new Error(
3371
+ "--mode only applies to visual-plan / visual-recap / visualize-repo / content.",
3372
+ );
3373
+ }
3374
+ if (planMode === "local-files" && parsed.mcpUrl) {
3375
+ throw new Error("--mode local-files cannot be combined with --mcp-url.");
3376
+ }
3377
+ if (planMode === "self-hosted" && !parsed.mcpUrl) {
3378
+ throw new Error("--mode self-hosted requires --mcp-url <url>.");
3379
+ }
3380
+ const shouldRegisterMcp =
3381
+ parsed.mcp && !localFilesModeSkipsMcp(modeAwareTargetId, planMode);
3382
+ if (parsed.mcpUrl) {
3383
+ installTarget = withMcpUrlOverride(installTarget, parsed.mcpUrl);
3384
+ }
3385
+ const clients =
3386
+ parsed.clients ?? resolveSkillsClientArg(parsed.client, shouldRegisterMcp);
3387
+ const mcpClients = clients.filter(isMcpClientId);
3388
+ if (shouldRegisterMcp && mcpClients.length === 0) {
3389
+ throw new Error(
3390
+ "MCP setup supports Claude Code, Codex, Claude Cowork, Cursor, OpenCode, or GitHub Copilot / VS Code clients. Use --mode local-files or --no-mcp for Pi.",
3391
+ );
3392
+ }
3393
+ installTarget = preserveMcpUrlAppPathOverride(installTarget, parsed.mcpUrl);
3394
+ const skillsAgents = skillsAgentsForClients(clients);
3395
+ if (parsed.dryRun) {
3396
+ try {
3397
+ const localManifestPath = shouldWriteContentLocalFilesManifest(
3398
+ modeAwareTargetId,
3399
+ planMode,
3400
+ )
3401
+ ? contentLocalFilesManifestPath(baseDir)
3402
+ : undefined;
3403
+ const githubActionPath =
3404
+ parsed.withGithubAction && installsRecap
3405
+ ? prVisualRecapWorkflowDisplayPath()
3406
+ : undefined;
3407
+ const githubActionSuggestedCommand =
3408
+ installsRecap && !parsed.withGithubAction
3409
+ ? prVisualRecapInstallCommand()
3410
+ : undefined;
3411
+ options.telemetry?.track("skills_cli install completed", {
3412
+ skills: installTarget.skillNames.join(","),
3413
+ clients: clients.join(","),
3414
+ scope: parsed.scope,
3415
+ dryRun: true,
3416
+ });
3417
+ return {
3418
+ id: installTarget.id,
3419
+ displayName: installTarget.displayName,
3420
+ skillNames: installTarget.skillNames,
3421
+ skillsAgents,
3422
+ mcpUrl: localFilesModeSkipsMcp(modeAwareTargetId, planMode)
3423
+ ? ""
3424
+ : installTarget.loaded.manifest.hosted.mcpUrl,
3425
+ mcpClients: shouldRegisterMcp ? mcpClients : [],
3426
+ dryRun: true,
3427
+ commands: [
3428
+ dryRunInstallCommand(parsed, target, { modeAwareTargetId }),
3429
+ ...(localManifestPath ? [`write ${localManifestPath}`] : []),
3430
+ ],
3431
+ githubActionPath,
3432
+ githubActionSuggestedCommand,
3433
+ planMode,
3434
+ localManifestPath,
3435
+ };
3436
+ } finally {
3437
+ installTarget.cleanup?.();
3438
+ }
3439
+ }
3440
+ const commands: string[] = [];
3441
+ const tmpRoot = fs.mkdtempSync(path.join(os.tmpdir(), "an-skills-add-"));
3442
+ let instructionSource: string | undefined;
3443
+ let instructionsWritten: string[] | undefined;
3444
+ let connected = false;
3445
+ let connectCommand: string | undefined;
3446
+ let registeredMcpClients: ClientId[] = shouldRegisterMcp ? mcpClients : [];
3447
+ let localManifestPath: string | undefined;
3448
+
3449
+ try {
3450
+ if (parsed.instructions) {
3451
+ if (skillsAgents.length === 0) {
3452
+ if (!shouldRegisterMcp) {
3453
+ throw new Error(
3454
+ "Skill instructions use shared .agents for Codex, Pi, Cursor, OpenCode, Copilot, and similar agents, or Claude Code's native files. Use an MCP-capable client or omit --instructions-only.",
3455
+ );
3456
+ }
3457
+ } else if (knownTarget) {
3458
+ // Built-in skills ship their instructions inside this package, so copy
3459
+ // the skill folders straight into each client's skills directory. This
3460
+ // avoids shelling out to the separate @agent-native/skills installer
3461
+ // (which would need to be published to npm to run via npx).
3462
+ instructionsWritten = installBuiltInInstructions({
3463
+ appSkillId: knownTarget,
3464
+ onlySkillNames,
3465
+ skillsAgents,
3466
+ scope: parsed.scope as "project" | "user",
3467
+ baseDir,
3468
+ dryRun: parsed.dryRun,
3469
+ planMode,
3470
+ mcpUrl: installTarget.loaded.manifest.hosted.mcpUrl,
3471
+ });
3472
+ instructionSource = instructionsWritten[0];
3473
+ commands.push(...instructionsWritten.map((dir) => `write ${dir}`));
3474
+ } else {
3475
+ // External app-skill manifests / plain skill repos still go through the
3476
+ // standalone installer, which knows how to pack adapters and fetch
3477
+ // remote skill collections.
3478
+ instructionSource = installTarget.materializeInstructions(tmpRoot);
3479
+ const args = [
3480
+ "--yes",
3481
+ "@agent-native/skills@latest",
3482
+ "add",
3483
+ "--quiet",
3484
+ instructionSource,
3485
+ "--copy",
3486
+ ...installTarget.skillNames.flatMap((skill) => ["--skill", skill]),
3487
+ ...skillsAgents.flatMap((agent) => ["-a", agent]),
3488
+ ...(parsed.scope === "user" ? ["-g"] : []),
3489
+ ...(modeAwareTargetId && parsed.planMode
3490
+ ? ["--mode", parsed.planMode]
3491
+ : []),
3492
+ ...(modeAwareTargetId && parsed.mcpUrl
3493
+ ? ["--mcp-url", parsed.mcpUrl]
3494
+ : []),
3495
+ ...(parsed.yes || knownTarget ? ["-y"] : []),
3496
+ ];
3497
+ commands.push(commandString("npx", args));
3498
+ if (!parsed.dryRun) {
3499
+ const code = await (options.runCommand ?? runCommand)("npx", args, {
3500
+ stdio: "silent",
3501
+ });
3502
+ if (code !== 0)
3503
+ throw new Error(
3504
+ `npx @agent-native/skills@latest add exited with ${code}.`,
3505
+ );
3506
+ }
3507
+ }
3508
+ }
3509
+
3510
+ if (shouldWriteContentLocalFilesManifest(modeAwareTargetId, planMode)) {
3511
+ localManifestPath = writeContentLocalFilesManifest(baseDir);
3512
+ commands.push(`write ${localManifestPath}`);
3513
+ }
3514
+
3515
+ // Skill instructions are now on disk (built-in folders copied or external
3516
+ // pack materialized) — record the install before MCP registration/connect.
3517
+ options.telemetry?.track("skills_cli install completed", {
3518
+ skills: installTarget.skillNames.join(","),
3519
+ clients: clients.join(","),
3520
+ scope: parsed.scope,
3521
+ dryRun: Boolean(parsed.dryRun),
3522
+ });
3523
+
3524
+ if (shouldRegisterMcp) {
3525
+ commands.push(
3526
+ `npx @agent-native/core@latest app-skill ensure --manifest ${installTarget.loaded.file} --client ${parsed.client} --scope ${parsed.scope} --yes`,
3527
+ );
3528
+ if (!parsed.dryRun) {
3529
+ const ensureResult = await ensureAppSkill(installTarget.loaded, {
3530
+ clients: mcpClients,
3531
+ scope: parsed.scope,
3532
+ baseDir: options.baseDir,
3533
+ yes: parsed.yes || Boolean(knownTarget),
3534
+ confirm: true,
3535
+ log: options.log,
3536
+ });
3537
+ registeredMcpClients = ensureResult.written.map(
3538
+ (written) => written.client,
3539
+ );
3540
+ options.telemetry?.track("skills_cli mcp registered", {
3541
+ skills: installTarget.skillNames.join(","),
3542
+ });
3543
+
3544
+ // One-step install + authenticate: after registering a hosted MCP
3545
+ // connector, kick off the existing connect/device-code flow so the user
3546
+ // does not hit an OAuth wall on the first tool call. `--no-connect`
3547
+ // opts out; non-interactive shells get the exact command to run.
3548
+ if (parsed.connect) {
3549
+ const result = await connectAfterEnsure(
3550
+ installTarget,
3551
+ mcpClients,
3552
+ parsed,
3553
+ options,
3554
+ );
3555
+ connected = result.connected;
3556
+ connectCommand = result.connectCommand || undefined;
3557
+ if (connected) registeredMcpClients = mcpClients;
3558
+ if (connectCommand) commands.push(connectCommand);
3559
+ } else {
3560
+ const pendingClients = mcpClients.filter(
3561
+ (client) => !registeredMcpClients.includes(client),
3562
+ );
3563
+ if (pendingClients.length > 0) {
3564
+ connectCommand = connectCommandFor(
3565
+ installTarget.loaded.manifest.hosted.url,
3566
+ pendingClients,
3567
+ parsed.scope,
3568
+ );
3569
+ commands.push(connectCommand);
3570
+ }
3571
+ }
3572
+ }
3573
+ }
3574
+
3575
+ // `--with-github-action`: also drop the PR Visual Recap workflow into the
3576
+ // repo so PRs get automatic recaps. Only meaningful for the plan family.
3577
+ let withGithubAction = Boolean(parsed.withGithubAction);
3578
+ let githubActionPath: string | undefined;
3579
+ let githubActionExisted: boolean | undefined;
3580
+ let githubActionSuggestedCommand: string | undefined;
3581
+ if (
3582
+ installsRecap &&
3583
+ !withGithubAction &&
3584
+ !fs.existsSync(prVisualRecapWorkflowPath(baseDir))
3585
+ ) {
3586
+ // Normally the recap decision is made up front in `runSkills` (so it's
3587
+ // resolved here). Only prompt inline when a direct caller invoked
3588
+ // addAgentNativeSkill without going through that up-front step.
3589
+ if (!parsed.githubActionResolved && shouldPrompt(parsed, options)) {
3590
+ const prompt = options.promptGithubAction ?? promptForGithubAction;
3591
+ const choice = await prompt({
3592
+ workflowPath: prVisualRecapWorkflowDisplayPath(),
3593
+ setupCommand: prVisualRecapSetupCommand(),
3594
+ docsUrl: PR_VISUAL_RECAP_DOCS_URL,
3595
+ });
3596
+ if (choice === null) {
3597
+ options.telemetry?.track("skills_cli cancelled", {
3598
+ step: "github-action",
3599
+ });
3600
+ }
3601
+ withGithubAction = choice === true;
3602
+ }
3603
+ if (!withGithubAction) {
3604
+ githubActionSuggestedCommand = prVisualRecapInstallCommand();
3605
+ }
3606
+ }
3607
+
3608
+ if (withGithubAction) {
3609
+ if (!installsRecap) {
3610
+ options.log?.(
3611
+ "--with-github-action only applies to the visual-recap skill; skipping the workflow.",
3612
+ );
3613
+ } else {
3614
+ const writeResult = writePrVisualRecapWorkflow(baseDir, {
3615
+ force: Boolean(parsed.force),
3616
+ });
3617
+ if (writeResult.status === "refused") {
3618
+ throw new Error(`recap workflow: ${writeResult.message}`);
3619
+ }
3620
+ githubActionPath = writeResult.path;
3621
+ githubActionExisted =
3622
+ writeResult.status === "written" ? writeResult.existed : false;
3623
+ commands.push(`write ${writeResult.path}`);
3624
+ options.telemetry?.track("skills_cli github action added");
3625
+ }
3626
+ }
3627
+
3628
+ return {
3629
+ id: installTarget.id,
3630
+ displayName: installTarget.displayName,
3631
+ instructionSource,
3632
+ skillNames: installTarget.skillNames,
3633
+ skillsAgents,
3634
+ mcpUrl: localFilesModeSkipsMcp(modeAwareTargetId, planMode)
3635
+ ? ""
3636
+ : installTarget.loaded.manifest.hosted.mcpUrl,
3637
+ mcpClients: registeredMcpClients,
3638
+ dryRun: parsed.dryRun,
3639
+ commands,
3640
+ written: instructionsWritten,
3641
+ connected,
3642
+ connectCommand,
3643
+ planMode,
3644
+ localManifestPath,
3645
+ githubActionPath,
3646
+ githubActionExisted,
3647
+ githubActionSuggestedCommand,
3648
+ };
3649
+ } finally {
3650
+ fs.rmSync(tmpRoot, { recursive: true, force: true });
3651
+ installTarget.cleanup?.();
3652
+ }
3653
+ }
3654
+
3655
+ function listSkills(options: RunSkillsOptions = {}) {
3656
+ const hidden = hiddenBuiltInSkillTargets(options);
3657
+ return [
3658
+ ...Object.values(BUILT_IN_APP_SKILLS)
3659
+ .filter((entry) => !hidden.has(entry.skillName))
3660
+ .map((entry) => ({
3661
+ id: entry.manifest.id,
3662
+ aliases:
3663
+ BUILT_IN_APP_SKILL_DISPLAY_ALIASES[
3664
+ entry.manifest.id as BuiltInAppSkillId
3665
+ ] ?? [],
3666
+ name: entry.manifest.displayName,
3667
+ description: entry.manifest.description,
3668
+ mcpUrl: isLocalOnlyBuiltInSkill(entry)
3669
+ ? ""
3670
+ : entry.manifest.hosted.mcpUrl,
3671
+ local: isLocalOnlyBuiltInSkill(entry),
3672
+ source: "agent-native",
3673
+ })),
3674
+ ...publicSkillEntries(options).map((entry) => ({
3675
+ id: entry.name,
3676
+ aliases: [] as string[],
3677
+ name: entry.name,
3678
+ description:
3679
+ entry.description ?? "Public skill from the BuilderIO skills catalog.",
3680
+ mcpUrl: "",
3681
+ local: true,
3682
+ source: options.publicSkillSource ?? DEFAULT_PUBLIC_SKILLS_SOURCE,
3683
+ })),
3684
+ ];
3685
+ }
3686
+
3687
+ function skillStateJson(state: SkillInstallState) {
3688
+ return {
3689
+ appSkillId: state.appSkillId,
3690
+ displayName: state.displayName,
3691
+ skillName: state.skillName,
3692
+ path: state.path,
3693
+ scope: state.scope,
3694
+ client: state.client,
3695
+ status: state.current ? "current" : "stale",
3696
+ managed: state.managed,
3697
+ installedHash: state.installedHash,
3698
+ latestHash: state.latestHash,
3699
+ metadataHash: state.metadataHash,
3700
+ planMode: state.planMode,
3701
+ };
3702
+ }
3703
+
3704
+ function formatSkillState(state: SkillInstallState): string {
3705
+ const status = state.current ? "current" : "stale";
3706
+ const managed = state.managed ? "managed" : "unmarked";
3707
+ const hashes =
3708
+ state.installedHash && !state.current
3709
+ ? ` (${state.installedHash} -> ${state.latestHash})`
3710
+ : "";
3711
+ return `${state.skillName.padEnd(22)} ${status.padEnd(7)} ${state.scope}/${state.client} ${managed}${hashes}\n ${state.path}`;
3712
+ }
3713
+
3714
+ function scaffoldStateJson(state: ScaffoldGuidanceState) {
3715
+ return {
3716
+ kind: state.kind,
3717
+ displayName: state.displayName,
3718
+ templateName: state.templateName,
3719
+ path: state.path,
3720
+ sourcePath: state.sourcePath,
3721
+ projectRoot: state.projectRoot,
3722
+ workspaceRoot: state.workspaceRoot,
3723
+ sharedPackageDir: state.sharedPackageDir,
3724
+ skillCount: state.skillCount,
3725
+ status: state.current ? "current" : "stale",
3726
+ managed: true,
3727
+ };
3728
+ }
3729
+
3730
+ function formatScaffoldState(state: ScaffoldGuidanceState): string {
3731
+ const status = state.current ? "current" : "stale";
3732
+ return `${"scaffold".padEnd(22)} ${status.padEnd(7)} project/${state.kind} managed (${state.skillCount} skills)\n ${state.path}`;
3733
+ }
3734
+
3735
+ function planModeSummary(mode: PlanInstallMode): string {
3736
+ if (mode === "local-files")
3737
+ return "Local files - no hosted writes by default";
3738
+ if (mode === "self-hosted") return "Self-hosted/custom app";
3739
+ return "Hosted app";
3740
+ }
3741
+
3742
+ function skillInstructionAgentLabel(agent: string): string {
3743
+ if (agent === "codex") return SKILL_INSTRUCTION_CLIENT_LABELS.codex;
3744
+ if (agent === "claude-code")
3745
+ return SKILL_INSTRUCTION_CLIENT_LABELS["claude-code"];
3746
+ if (agent === "pi") return SKILL_INSTRUCTION_CLIENT_LABELS.pi;
3747
+ return agent;
3748
+ }
3749
+
3750
+ function targetInstallsMcp(
3751
+ target: string,
3752
+ parsed: Pick<ParsedSkillsArgs, "mcp" | "planMode">,
3753
+ ): boolean {
3754
+ if (!parsed.mcp) return false;
3755
+ if (publicSkillSelectionNames(target)) return false;
3756
+ const knownTarget = normalizeKnownSkillTarget(target);
3757
+ if (localFilesModeSkipsMcp(knownTarget, parsed.planMode)) return false;
3758
+ if (knownTarget) {
3759
+ return !isLocalOnlyBuiltInSkill(BUILT_IN_APP_SKILLS[knownTarget]);
3760
+ }
3761
+ return true;
3762
+ }
3763
+
3764
+ function targetsInstallMcp(
3765
+ targets: string[],
3766
+ parsed: ParsedSkillsArgs,
3767
+ ): boolean {
3768
+ return targets.some((target) => targetInstallsMcp(target, parsed));
3769
+ }
3770
+
3771
+ function instructionContentForSkill(skillName: string): string | null {
3772
+ if (skillName === "quick-recap") {
3773
+ return "When writing final response status indicators, use the /quick-recap skill always.";
3774
+ }
3775
+ if (skillName === "efficient-fable") {
3776
+ return "When operating as Claude Fable, use the /efficient-fable skill always.";
3777
+ }
3778
+ if (skillName === "efficient-frontier") {
3779
+ return "When using a high-cost frontier model for codebase-heavy work, use the /efficient-frontier skill always.";
3780
+ }
3781
+ if (skillName === "stay-within-limits") {
3782
+ return "When long-running or parallel work needs usage-limit checks, use the /stay-within-limits skill always.";
3783
+ }
3784
+ if (skillName === "visual-plan") {
3785
+ return "When work needs an interactive visual plan before implementation, use the /visual-plan skill always.";
3786
+ }
3787
+ if (skillName === "visual-recap") {
3788
+ return "When a PR, branch, commit, or diff needs an interactive visual recap, use the /visual-recap skill always.";
3789
+ }
3790
+ if (skillName === "visualize-repo") {
3791
+ return "When a repository needs local visual docs or a navigable Plan-backed repo viewer, use the /visualize-repo skill always.";
3792
+ }
3793
+ return null;
3794
+ }
3795
+
3796
+ function selectedPlainSkillNamesForInstructionPrompt(
3797
+ targets: string[],
3798
+ parsed: ParsedSkillsArgs,
3799
+ ): string[] {
3800
+ const names = new Set<string>(parsed.plainSkillNames ?? []);
3801
+ for (const target of targets) {
3802
+ for (const name of publicSkillSelectionNames(target) ?? []) {
3803
+ names.add(name);
3804
+ }
3805
+ }
3806
+ return [...names];
3807
+ }
3808
+
3809
+ function hasManagedInstructionBlock(skillNames: string[]): boolean {
3810
+ return skillNames.some((name) => Boolean(instructionContentForSkill(name)));
3811
+ }
3812
+
3813
+ function runSkillsStatusOrUpdate(
3814
+ parsed: ParsedSkillsArgs,
3815
+ options: RunSkillsOptions,
3816
+ update: boolean,
3817
+ ): void {
3818
+ const skillBefore = collectSkillInstallStates(parsed, options);
3819
+ const scaffoldBefore = collectScaffoldGuidanceStates(parsed, options);
3820
+ const skillChanged = update
3821
+ ? updateSkillInstallStates(skillBefore, parsed.dryRun)
3822
+ : [];
3823
+ const scaffoldChanged = update
3824
+ ? updateScaffoldGuidanceStates(scaffoldBefore, parsed.dryRun)
3825
+ : [];
3826
+ if (update && !parsed.dryRun && scaffoldChanged.length > 0) {
3827
+ repairScaffoldAgentLinks(scaffoldChanged);
3828
+ }
3829
+ const skillAfter =
3830
+ update && !parsed.dryRun
3831
+ ? collectSkillInstallStates(parsed, options)
3832
+ : skillBefore;
3833
+ const scaffoldAfter =
3834
+ update && !parsed.dryRun
3835
+ ? collectScaffoldGuidanceStates(parsed, options)
3836
+ : scaffoldBefore;
3837
+ const beforeCount = skillBefore.length + scaffoldBefore.length;
3838
+ const changedCount = skillChanged.length + scaffoldChanged.length;
3839
+
3840
+ if (parsed.printJson) {
3841
+ const outputSkillStates =
3842
+ update && !parsed.dryRun ? skillAfter : skillBefore;
3843
+ const outputScaffoldStates =
3844
+ update && !parsed.dryRun ? scaffoldAfter : scaffoldBefore;
3845
+ process.stdout.write(
3846
+ `${JSON.stringify(
3847
+ {
3848
+ ok: true,
3849
+ command: parsed.command,
3850
+ dryRun: parsed.dryRun,
3851
+ found: beforeCount,
3852
+ stale:
3853
+ outputSkillStates.filter((state) => !state.current).length +
3854
+ outputScaffoldStates.filter((state) => !state.current).length,
3855
+ updated: changedCount,
3856
+ skills: outputSkillStates.map(skillStateJson),
3857
+ scaffold: outputScaffoldStates.map(scaffoldStateJson),
3858
+ },
3859
+ null,
3860
+ 2,
3861
+ )}\n`,
3862
+ );
3863
+ return;
3864
+ }
3865
+
3866
+ if (beforeCount === 0) {
3867
+ const target = parsed.target ? ` for ${parsed.target}` : "";
3868
+ const hint = isScaffoldGuidanceTarget(parsed.target)
3869
+ ? `Run this from a generated Agent Native app or workspace root.\n`
3870
+ : update
3871
+ ? `The update command only refreshes skill folders that already exist; it does not do first-time install, MCP registration, or auth. Run "npx @agent-native/core@latest skills add ${parsed.target ?? "visual-plan"}" for one-step setup.\n`
3872
+ : `Run "npx @agent-native/core@latest skills add ${parsed.target ?? "visual-plan"}" to install one.\n`;
3873
+ process.stdout.write(
3874
+ `No installed Agent Native skill copies found${target}.\n${hint}`,
3875
+ );
3876
+ return;
3877
+ }
3878
+
3879
+ if (update) {
3880
+ if (parsed.dryRun) {
3881
+ process.stdout.write(
3882
+ changedCount
3883
+ ? `Would update ${changedCount} skill folder${changedCount === 1 ? "" : "s"}:\n`
3884
+ : "All discovered skill folders are already current.\n",
3885
+ );
3886
+ } else {
3887
+ process.stdout.write(
3888
+ changedCount
3889
+ ? `Updated ${changedCount} skill folder${changedCount === 1 ? "" : "s"}.\n`
3890
+ : "All discovered skill folders are already current.\n",
3891
+ );
3892
+ }
3893
+ }
3894
+
3895
+ const rows = [
3896
+ ...(update && parsed.dryRun ? skillBefore : skillAfter).map(
3897
+ formatSkillState,
3898
+ ),
3899
+ ...(update && parsed.dryRun ? scaffoldBefore : scaffoldAfter).map(
3900
+ formatScaffoldState,
3901
+ ),
3902
+ ];
3903
+ process.stdout.write(`${rows.join("\n")}\n`);
3904
+ }
3905
+
3906
+ /**
3907
+ * Resolve the CLI version the same way `index.ts` does — read it from the
3908
+ * package.json two levels up from the compiled module (dist/cli/skills.js →
3909
+ * ../../package.json). Best-effort: falls back to "unknown".
3910
+ */
3911
+ function readCliVersion(): string {
3912
+ try {
3913
+ const here = path.dirname(fileURLToPath(import.meta.url));
3914
+ const pkg = JSON.parse(
3915
+ fs.readFileSync(path.resolve(here, "../../package.json"), "utf8"),
3916
+ ) as { version?: unknown };
3917
+ return typeof pkg.version === "string" ? pkg.version : "unknown";
3918
+ } catch {
3919
+ return "unknown";
3920
+ }
3921
+ }
3922
+
3923
+ export async function runSkills(
3924
+ argv: string[],
3925
+ options: RunSkillsOptions = {},
3926
+ ): Promise<void> {
3927
+ const parsed = parseSkillsArgs(argv);
3928
+ if (parsed.baseDir) {
3929
+ options = { ...options, baseDir: path.resolve(parsed.baseDir) };
3930
+ }
3931
+ const clackForLog = parsed.printJson
3932
+ ? undefined
3933
+ : await import("@clack/prompts");
3934
+ const log = parsed.printJson
3935
+ ? undefined
3936
+ : (message: string) => {
3937
+ if (!message.trim()) return;
3938
+ clackForLog?.log.info(message);
3939
+ };
3940
+ const connectLog =
3941
+ !parsed.printJson && clackForLog
3942
+ ? createClackConnectLog(clackForLog)
3943
+ : undefined;
3944
+ const createConnectSpinner =
3945
+ !parsed.printJson && clackForLog && process.stdout.isTTY
3946
+ ? () => clackForLog.spinner({ indicator: "timer" })
3947
+ : undefined;
3948
+
3949
+ if (parsed.command === "help") {
3950
+ process.stdout.write(`${HELP}\n`);
3951
+ return;
3952
+ }
3953
+
3954
+ // `@agent-native/skills` now delegates its interactive install to this
3955
+ // function. For plain skill repos we still shell out to
3956
+ // `npx @agent-native/skills@latest add …`; this env guard tells that child process
3957
+ // to run its OWN headless installer instead of bouncing back into core,
3958
+ // which would otherwise be an infinite skills → core → skills loop.
3959
+ const previousDirect = process.env.AGENT_NATIVE_SKILLS_DIRECT;
3960
+ process.env.AGENT_NATIVE_SKILLS_DIRECT = "1";
3961
+
3962
+ // Best-effort install-funnel telemetry. Created once per run and flushed in a
3963
+ // finally so events send on success, error, and cancellation — the CLI is
3964
+ // short-lived, so flushing before exit is essential or the events never send.
3965
+ const startedAt = Date.now();
3966
+ const telemetry =
3967
+ options.telemetry ??
3968
+ createCliTelemetry({
3969
+ cli: "core",
3970
+ cliVersion: readCliVersion(),
3971
+ command: parsed.command,
3972
+ interactive: shouldPrompt(parsed, options),
3973
+ });
3974
+ const optionsWithTelemetry: RunSkillsOptions = {
3975
+ ...options,
3976
+ telemetry,
3977
+ connectLog: options.connectLog ?? connectLog,
3978
+ createConnectSpinner: options.createConnectSpinner ?? createConnectSpinner,
3979
+ };
3980
+
3981
+ try {
3982
+ telemetry.track("skills_cli started");
3983
+
3984
+ if (parsed.command === "list") {
3985
+ const skills = listSkills(optionsWithTelemetry);
3986
+ telemetry.track("skills_cli skills listed", {
3987
+ availableCount: skills.length,
3988
+ available: skills.map((skill) => skill.id).join(","),
3989
+ });
3990
+ if (parsed.printJson) {
3991
+ process.stdout.write(`${JSON.stringify(skills, null, 2)}\n`);
3992
+ return;
3993
+ }
3994
+ for (const skill of skills) {
3995
+ const description = skill.description.replace(/[.?!]?$/, ".");
3996
+ const aliases = skill.aliases.length
3997
+ ? ` Aliases: ${skill.aliases.join(", ")}.`
3998
+ : "";
3999
+ const target = skill.local ? "local command" : skill.mcpUrl;
4000
+ process.stdout.write(
4001
+ `${skill.id.padEnd(12)} ${description}${aliases} (${target})\n`,
4002
+ );
4003
+ }
4004
+ return;
4005
+ }
4006
+
4007
+ if (parsed.command === "status" || parsed.command === "update") {
4008
+ runSkillsStatusOrUpdate(parsed, options, parsed.command === "update");
4009
+ return;
4010
+ }
4011
+
4012
+ const targets = await resolveSkillTargets(parsed, optionsWithTelemetry);
4013
+ if (!targets) {
4014
+ telemetry.track("skills_cli cancelled", { step: "skills" });
4015
+ return;
4016
+ }
4017
+ const preselected = Boolean(parsed.target);
4018
+ telemetry.track("skills_cli skills selected", {
4019
+ selected: targets.join(","),
4020
+ selectedCount: targets.length,
4021
+ // Best-effort "took everything offered" signal: compare against the
4022
+ // interactive picker's option count (the plan sub-skills collapse into a
4023
+ // single bundle target, so this is approximate, like the standalone CLI).
4024
+ selectedAll: targets.length === skillPromptOptions(options).length,
4025
+ preselected,
4026
+ });
4027
+
4028
+ const includesPlans =
4029
+ targetsIncludePlans(targets) ||
4030
+ planSkillNamesSelected(parsed.plainSkillNames);
4031
+ const includesInstallModeSkills =
4032
+ targetsIncludeInstallModeSkills(targets) ||
4033
+ installModeSkillNamesSelected(parsed.plainSkillNames);
4034
+ if (parsed.planMode && !includesInstallModeSkills) {
4035
+ throw new Error(
4036
+ "--mode only applies to visual-plan / visual-recap / visualize-repo / content.",
4037
+ );
4038
+ }
4039
+ if (includesPlans) {
4040
+ if (!parsed.planMode && parsed.mcpUrl) {
4041
+ parsed.planMode = "self-hosted";
4042
+ }
4043
+ if (!parsed.planMode && shouldPrompt(parsed, options)) {
4044
+ const prompt = options.promptPlanMode ?? promptForPlanMode;
4045
+ const mode = await prompt({ initialMode: "hosted" });
4046
+ if (!mode) {
4047
+ telemetry.track("skills_cli cancelled", { step: "plan-mode" });
4048
+ return;
4049
+ }
4050
+ parsed.planMode = mode;
4051
+ }
4052
+ if (!parsed.planMode) parsed.planMode = "hosted";
4053
+ if (parsed.planMode === "self-hosted" && !parsed.mcpUrl) {
4054
+ if (shouldPrompt(parsed, options)) {
4055
+ const prompt = options.promptPlanMcpUrl ?? promptForPlanMcpUrl;
4056
+ const mcpUrl = await prompt();
4057
+ if (!mcpUrl) {
4058
+ telemetry.track("skills_cli cancelled", {
4059
+ step: "plan-mcp-url",
4060
+ });
4061
+ return;
4062
+ }
4063
+ parsed.mcpUrl = mcpUrl;
4064
+ } else {
4065
+ throw new Error(
4066
+ "--mode self-hosted requires --mcp-url <url> in non-interactive mode.",
4067
+ );
4068
+ }
4069
+ }
4070
+ telemetry.track("skills_cli plan mode selected", {
4071
+ mode: parsed.planMode,
4072
+ });
4073
+ }
4074
+
4075
+ const installsMcp = targetsInstallMcp(targets, parsed);
4076
+ const clients = await resolveSkillsClients(
4077
+ parsed,
4078
+ optionsWithTelemetry,
4079
+ installsMcp,
4080
+ );
4081
+ if (!clients) {
4082
+ telemetry.track("skills_cli cancelled", { step: "clients" });
4083
+ return;
4084
+ }
4085
+ telemetry.track("skills_cli clients selected", {
4086
+ clients: clients.join(","),
4087
+ clientCount: clients.length,
4088
+ });
4089
+
4090
+ // Ask where to install (project vs user) unless an explicit --scope was
4091
+ // passed or we are running non-interactively.
4092
+ if (!parsed.scopeExplicit && shouldPrompt(parsed, options)) {
4093
+ const promptScope = options.promptScope ?? promptForScope;
4094
+ const scope = await promptScope({ initialScope: "project" });
4095
+ if (!scope) {
4096
+ telemetry.track("skills_cli cancelled", { step: "scope" });
4097
+ return;
4098
+ }
4099
+ parsed.scope = scope;
4100
+ }
4101
+ telemetry.track("skills_cli scope selected", { scope: parsed.scope });
4102
+
4103
+ const instructionSkillNames = selectedPlainSkillNamesForInstructionPrompt(
4104
+ targets,
4105
+ parsed,
4106
+ );
4107
+ if (
4108
+ parsed.updateInstructions === undefined &&
4109
+ hasManagedInstructionBlock(instructionSkillNames) &&
4110
+ shouldPrompt(parsed, options)
4111
+ ) {
4112
+ const prompt =
4113
+ options.promptUpdateInstructions ?? promptForUpdateInstructions;
4114
+ const choice = await prompt();
4115
+ if (choice === null) {
4116
+ telemetry.track("skills_cli cancelled", {
4117
+ step: "managed-instructions",
4118
+ });
4119
+ return;
4120
+ }
4121
+ parsed.updateInstructions = choice === true;
4122
+ }
4123
+
4124
+ // Decide the optional PR Visual Recap GitHub Action UP FRONT — before any
4125
+ // install or MCP registration — so every prompt is answered before we touch
4126
+ // disk. The choice is threaded into each install via `withGithubAction` +
4127
+ // `githubActionResolved` (so addAgentNativeSkill doesn't re-prompt mid-flow).
4128
+ const recapBaseDir = options.baseDir ?? process.cwd();
4129
+ const anyRecapTarget =
4130
+ targets.some((target) => {
4131
+ if (normalizeKnownSkillTarget(target) !== "visual-plans") return false;
4132
+ const only = builtInOnlySkillNames(target);
4133
+ return !only || only.includes("visual-recap");
4134
+ }) || recapSkillNamesSelected(parsed.plainSkillNames);
4135
+ if (
4136
+ anyRecapTarget &&
4137
+ !parsed.withGithubAction &&
4138
+ !fs.existsSync(prVisualRecapWorkflowPath(recapBaseDir)) &&
4139
+ shouldPrompt(parsed, options)
4140
+ ) {
4141
+ const prompt = options.promptGithubAction ?? promptForGithubAction;
4142
+ const choice = await prompt({
4143
+ workflowPath: prVisualRecapWorkflowDisplayPath(),
4144
+ setupCommand: prVisualRecapSetupCommand(),
4145
+ docsUrl: PR_VISUAL_RECAP_DOCS_URL,
4146
+ });
4147
+ if (choice === null) {
4148
+ telemetry.track("skills_cli cancelled", { step: "github-action" });
4149
+ }
4150
+ parsed.withGithubAction = choice === true;
4151
+ parsed.githubActionResolved = true;
4152
+ }
4153
+
4154
+ const results: SkillsAddResult[] = [];
4155
+ for (const target of targets) {
4156
+ results.push(
4157
+ await addAgentNativeSkill(
4158
+ {
4159
+ ...parsed,
4160
+ target,
4161
+ client: clientArgForClients(clients),
4162
+ clients,
4163
+ },
4164
+ {
4165
+ ...optionsWithTelemetry,
4166
+ log,
4167
+ },
4168
+ ),
4169
+ );
4170
+ }
4171
+
4172
+ // The add flow succeeded for every target — record the funnel completion
4173
+ // before printing output (output below cannot fail the install).
4174
+ const completedSkills = [
4175
+ ...new Set(results.flatMap((result) => result.skillNames)),
4176
+ ];
4177
+ const completedClients = [
4178
+ ...new Set(results.flatMap((result) => result.mcpClients)),
4179
+ ];
4180
+ telemetry.track("skills_cli completed", {
4181
+ skills: completedSkills.join(","),
4182
+ clients: completedClients.join(","),
4183
+ scope: parsed.scope,
4184
+ durationMs: Date.now() - startedAt,
4185
+ });
4186
+
4187
+ if (parsed.printJson) {
4188
+ process.stdout.write(
4189
+ `${JSON.stringify(results.length === 1 ? results[0] : results, null, 2)}\n`,
4190
+ );
4191
+ return;
4192
+ }
4193
+
4194
+ if (parsed.dryRun) {
4195
+ process.stdout.write(
4196
+ `${results.flatMap((result) => result.commands).join("\n")}\n`,
4197
+ );
4198
+ return;
4199
+ }
4200
+
4201
+ const installedNames = results
4202
+ .map((result) => result.displayName)
4203
+ .join(", ");
4204
+ const skillsAgents = [
4205
+ ...new Set(results.flatMap((result) => result.skillsAgents)),
4206
+ ];
4207
+ const mcpClients = [
4208
+ ...new Set(results.flatMap((result) => result.mcpClients)),
4209
+ ];
4210
+ const mcpUrls = [
4211
+ ...new Set(results.map((result) => result.mcpUrl).filter(Boolean)),
4212
+ ];
4213
+ const localCommands = [
4214
+ ...new Set(
4215
+ results
4216
+ .filter((result) => result.local && result.scriptPath)
4217
+ .flatMap((result) => result.commands),
4218
+ ),
4219
+ ];
4220
+ const planModes = [
4221
+ ...new Set(
4222
+ results
4223
+ .map((result) => result.planMode)
4224
+ .filter((mode): mode is PlanInstallMode => Boolean(mode)),
4225
+ ),
4226
+ ];
4227
+ const authConnected = results.some((result) => result.connected);
4228
+ const pendingConnectCommands = [
4229
+ ...new Set(
4230
+ results
4231
+ .map((result) => result.connectCommand)
4232
+ .filter((command): command is string => Boolean(command)),
4233
+ ),
4234
+ ];
4235
+ const authLine = authConnected
4236
+ ? "Authentication: completed."
4237
+ : pendingConnectCommands.length
4238
+ ? `Authentication: pending — run ${pendingConnectCommands.join(" && ")}`
4239
+ : "";
4240
+ const githubActions = [
4241
+ ...new Set(
4242
+ results
4243
+ .map((result) => result.githubActionPath)
4244
+ .filter((p): p is string => Boolean(p)),
4245
+ ),
4246
+ ];
4247
+ const githubActionLine = githubActions.length
4248
+ ? `PR Visual Recap workflow: wrote ${githubActions.join(", ")}.\nNext: run ${prVisualRecapSetupCommand()} to configure GitHub secrets/variables, or set them manually:\n ${PR_VISUAL_RECAP_SETUP.join("\n ")}`
4249
+ : "";
4250
+ const githubActionSuggestions = [
4251
+ ...new Set(
4252
+ results
4253
+ .map((result) => result.githubActionSuggestedCommand)
4254
+ .filter((command): command is string => Boolean(command)),
4255
+ ),
4256
+ ];
4257
+ const githubActionSuggestionLine = githubActionSuggestions.length
4258
+ ? `Optional PR Visual Recap workflow: run ${githubActionSuggestions.join(
4259
+ " && ",
4260
+ )} to add automatic recap comments on pull requests.`
4261
+ : "";
4262
+ const clack = await import("@clack/prompts");
4263
+ const summary = [
4264
+ skillsAgents.length
4265
+ ? `Skill instructions ${skillsAgents.map(skillInstructionAgentLabel).join(", ")}`
4266
+ : "Skill instructions skipped",
4267
+ mcpClients.length
4268
+ ? `MCP config ${mcpClients.map((client) => CLIENT_LABELS[client]).join(", ")}`
4269
+ : "MCP config not required",
4270
+ mcpUrls.length ? `MCP URL ${mcpUrls.join(", ")}` : "",
4271
+ planModes.length
4272
+ ? `Install mode ${planModes.map(planModeSummary).join(", ")}`
4273
+ : "",
4274
+ authConnected
4275
+ ? "Authentication completed"
4276
+ : pendingConnectCommands.length
4277
+ ? `Authentication pending — run ${pendingConnectCommands.join(" && ")}`
4278
+ : "",
4279
+ localCommands.length
4280
+ ? `Local command ${localCommands.join(", ")}`
4281
+ : "",
4282
+ ].filter(Boolean);
4283
+ clack.note(
4284
+ summary.join("\n"),
4285
+ `Installed ${installedNames} skill${results.length === 1 ? "" : "s"}`,
4286
+ );
4287
+
4288
+ // OAuth clients (Claude Code) can finish auth in-host via /mcp, not only by
4289
+ // running the connect command — surface that on the no-connect/pending path
4290
+ // so a hosted install isn't left looking "done but unauthenticated".
4291
+ if (
4292
+ !authConnected &&
4293
+ mcpClients.some(
4294
+ (client) => client === "claude-code" || client === "claude-code-cli",
4295
+ )
4296
+ ) {
4297
+ clack.log.info(
4298
+ "Claude Code: reload the client, then open /mcp and choose Authenticate to finish connecting" +
4299
+ (pendingConnectCommands.length
4300
+ ? " (or run the connect command above)."
4301
+ : "."),
4302
+ );
4303
+ }
4304
+
4305
+ // GitHub Action follow-ups — kept as exact, copy-pasteable command lines.
4306
+ for (const line of [githubActionLine, githubActionSuggestionLine].filter(
4307
+ Boolean,
4308
+ )) {
4309
+ clack.log.info(line);
4310
+ }
4311
+
4312
+ const slashCommands = completedSkills.map((name) => `/${name}`).join(" ");
4313
+ const configuredEveryClient = SKILLS_CLIENTS.every((client) =>
4314
+ clients.includes(client),
4315
+ );
4316
+ const clientHint = configuredEveryClient
4317
+ ? ""
4318
+ : "\n Add another client later with --client <client> (e.g. --client claude-code).";
4319
+ const reloadTarget = mcpClients.length > 0 ? "skill + MCP server" : "skill";
4320
+ clack.outro(
4321
+ `✅ All set! Start using ${slashCommands || "your new skills"} in your agent client.` +
4322
+ `\n You may need to reload the client for the ${reloadTarget} to appear.` +
4323
+ clientHint,
4324
+ );
4325
+ } catch (error) {
4326
+ telemetry.track("skills_cli failed", {
4327
+ command: parsed.command,
4328
+ error: error instanceof Error ? error.message : String(error),
4329
+ durationMs: Date.now() - startedAt,
4330
+ });
4331
+ throw error;
4332
+ } finally {
4333
+ await telemetry.flush();
4334
+ if (previousDirect === undefined) {
4335
+ delete process.env.AGENT_NATIVE_SKILLS_DIRECT;
4336
+ } else {
4337
+ process.env.AGENT_NATIVE_SKILLS_DIRECT = previousDirect;
4338
+ }
4339
+ }
4340
+ }