@agent-native/core 0.112.0 → 0.113.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (490) hide show
  1. package/corpus/README.md +4 -2
  2. package/corpus/core/CHANGELOG.md +22 -0
  3. package/corpus/core/docs/AGENTS.md +7 -0
  4. package/corpus/core/docs/content/integrations.mdx +63 -2
  5. package/corpus/core/docs/design/provider-integration-authority.md +117 -0
  6. package/corpus/core/package.json +6 -1
  7. package/corpus/core/scripts/materialize-source-corpus.mjs +9 -2
  8. package/corpus/core/src/cli/atomic-json-file.ts +324 -0
  9. package/corpus/core/src/cli/claude-code-participant.ts +515 -0
  10. package/corpus/core/src/cli/code-agent-executor.ts +18 -10
  11. package/corpus/core/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  12. package/corpus/core/src/cli/code-agent-runs.ts +55 -62
  13. package/corpus/core/src/cli/codex-cli-participant.ts +496 -0
  14. package/corpus/core/src/cli/multi-frontier-runs.ts +1246 -135
  15. package/corpus/core/src/client/chat/ChatHistoryList.tsx +7 -404
  16. package/corpus/core/src/integrations/index.ts +10 -0
  17. package/corpus/core/src/integrations/slack-oauth.ts +1 -0
  18. package/corpus/core/src/integrations/webhook-delivery.ts +55 -0
  19. package/corpus/core/src/notifications/channels.ts +4 -10
  20. package/corpus/core/src/provider-api/actions/custom-provider-registration.ts +197 -0
  21. package/corpus/core/src/provider-api/actions/delete-staged-dataset.ts +3 -42
  22. package/corpus/core/src/provider-api/actions/list-staged-datasets.ts +3 -45
  23. package/corpus/core/src/provider-api/actions/provider-api-audit.ts +88 -0
  24. package/corpus/core/src/provider-api/actions/provider-api.ts +460 -0
  25. package/corpus/core/src/provider-api/actions/query-staged-dataset.ts +3 -140
  26. package/corpus/core/src/provider-api/actions/staged-datasets.ts +359 -0
  27. package/corpus/core/src/provider-api/gong.ts +108 -0
  28. package/corpus/core/src/scripts/docs/source-search.ts +2 -1
  29. package/corpus/core/src/server/google-oauth-credentials.ts +80 -3
  30. package/corpus/core/src/server/index.ts +6 -0
  31. package/corpus/core/src/styles/chat-history-list.css +1 -313
  32. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  33. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  34. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  35. package/corpus/core/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  36. package/corpus/core/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  37. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  38. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  39. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  40. package/corpus/core/src/templates/default/AGENTS.md +25 -18
  41. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  42. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  43. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  44. package/corpus/core/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  45. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  46. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  47. package/corpus/core/src/templates/headless/AGENTS.md +7 -0
  48. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  49. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  50. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  51. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  54. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -0
  55. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
  56. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -12
  57. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  58. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +11 -2
  59. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  60. package/corpus/templates/analytics/actions/delete-staged-dataset.ts +3 -23
  61. package/corpus/templates/analytics/actions/list-staged-datasets.ts +3 -27
  62. package/corpus/templates/analytics/actions/provider-api-catalog.ts +16 -19
  63. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -5
  64. package/corpus/templates/analytics/actions/provider-api-request.ts +162 -185
  65. package/corpus/templates/analytics/actions/query-staged-dataset.ts +3 -47
  66. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +52 -161
  67. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -12
  68. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  69. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +11 -2
  70. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  71. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +63 -160
  72. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -12
  73. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  74. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +11 -2
  75. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  76. package/corpus/templates/brain/actions/_schemas.ts +13 -7
  77. package/corpus/templates/brain/actions/delete-staged-dataset.ts +3 -24
  78. package/corpus/templates/brain/actions/list-staged-datasets.ts +3 -28
  79. package/corpus/templates/brain/actions/provider-api-catalog.ts +5 -11
  80. package/corpus/templates/brain/actions/provider-api-docs.ts +3 -5
  81. package/corpus/templates/brain/actions/provider-api-request.ts +3 -37
  82. package/corpus/templates/brain/actions/query-staged-dataset.ts +3 -48
  83. package/corpus/templates/brain/actions/update-source.ts +5 -1
  84. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +48 -154
  85. package/corpus/templates/brain/app/lib/brain.ts +55 -0
  86. package/corpus/templates/brain/app/lib/ingest-handoff.ts +35 -0
  87. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-can-now-join-configured-public-channels-befo.md +6 -0
  88. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-continue-across-the-configured-number-of.md +6 -0
  89. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-start-with-a-safe-four-week-window-and-r.md +6 -0
  90. package/corpus/templates/brain/server/lib/connectors.ts +53 -2
  91. package/corpus/templates/brain/server/lib/slack-channel-membership.ts +44 -0
  92. package/corpus/templates/brain/shared/slack-source-config.ts +60 -0
  93. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -12
  94. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  95. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +11 -2
  96. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  97. package/corpus/templates/calendar/actions/delete-staged-dataset.ts +3 -24
  98. package/corpus/templates/calendar/actions/list-staged-datasets.ts +3 -28
  99. package/corpus/templates/calendar/actions/provider-api-catalog.ts +5 -11
  100. package/corpus/templates/calendar/actions/provider-api-docs.ts +3 -5
  101. package/corpus/templates/calendar/actions/provider-api-request.ts +3 -37
  102. package/corpus/templates/calendar/actions/query-staged-dataset.ts +3 -48
  103. package/corpus/templates/calendar/server/handlers/gong.ts +6 -61
  104. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -8
  105. package/corpus/templates/calendar/server/lib/google-calendar.ts +7 -45
  106. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  107. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  108. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  109. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  110. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  111. package/corpus/templates/chat/AGENTS.md +5 -2
  112. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  113. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -12
  114. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  115. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +11 -2
  116. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  117. package/corpus/templates/clips/AGENTS.md +11 -0
  118. package/corpus/templates/clips/actions/export-to-brain.ts +505 -171
  119. package/corpus/templates/clips/changelog/2026-07-19-ready-clips-transcripts-can-be-backfilled-to-brain-for-a-bou.md +6 -0
  120. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -1
  121. package/corpus/templates/clips/server/lib/google-calendar-client.ts +12 -22
  122. package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +9 -6
  123. package/corpus/templates/clips/server/lib/slack-oauth.ts +12 -47
  124. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +2 -6
  125. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +4 -4
  126. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -12
  127. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  128. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +11 -2
  129. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  130. package/corpus/templates/content/actions/delete-staged-dataset.ts +3 -24
  131. package/corpus/templates/content/actions/list-staged-datasets.ts +3 -28
  132. package/corpus/templates/content/actions/provider-api-catalog.ts +5 -11
  133. package/corpus/templates/content/actions/provider-api-docs.ts +3 -5
  134. package/corpus/templates/content/actions/provider-api-request.ts +3 -37
  135. package/corpus/templates/content/actions/query-staged-dataset.ts +3 -48
  136. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -12
  137. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  138. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +11 -2
  139. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  140. package/corpus/templates/design/actions/delete-staged-dataset.ts +4 -23
  141. package/corpus/templates/design/actions/list-staged-datasets.ts +4 -27
  142. package/corpus/templates/design/actions/provider-api-catalog.ts +15 -18
  143. package/corpus/templates/design/actions/provider-api-docs.ts +57 -48
  144. package/corpus/templates/design/actions/provider-api-request.ts +140 -164
  145. package/corpus/templates/design/actions/query-staged-dataset.ts +4 -47
  146. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -12
  147. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  148. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +11 -2
  149. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  150. package/corpus/templates/dispatch/actions/delete-staged-dataset.ts +4 -23
  151. package/corpus/templates/dispatch/actions/list-staged-datasets.ts +4 -30
  152. package/corpus/templates/dispatch/actions/provider-api-catalog.ts +15 -18
  153. package/corpus/templates/dispatch/actions/provider-api-docs.ts +57 -48
  154. package/corpus/templates/dispatch/actions/provider-api-request.ts +138 -163
  155. package/corpus/templates/dispatch/actions/query-staged-dataset.ts +4 -47
  156. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -12
  157. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  158. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +11 -2
  159. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  160. package/corpus/templates/forms/server/lib/integrations.ts +23 -22
  161. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  162. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  163. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -12
  164. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  165. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +11 -2
  166. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  167. package/corpus/templates/mail/actions/delete-staged-dataset.ts +4 -23
  168. package/corpus/templates/mail/actions/list-staged-datasets.ts +4 -27
  169. package/corpus/templates/mail/actions/provider-api-catalog.ts +15 -18
  170. package/corpus/templates/mail/actions/provider-api-docs.ts +57 -48
  171. package/corpus/templates/mail/actions/provider-api-request.ts +146 -173
  172. package/corpus/templates/mail/actions/query-staged-dataset.ts +4 -47
  173. package/corpus/templates/mail/server/handlers/gong.ts +6 -61
  174. package/corpus/templates/mail/server/lib/google-auth.ts +10 -13
  175. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -12
  176. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  177. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +11 -2
  178. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  179. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +47 -156
  180. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -12
  181. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  182. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +11 -2
  183. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  184. package/corpus/templates/slides/actions/delete-staged-dataset.ts +4 -23
  185. package/corpus/templates/slides/actions/list-staged-datasets.ts +4 -27
  186. package/corpus/templates/slides/actions/provider-api-catalog.ts +15 -18
  187. package/corpus/templates/slides/actions/provider-api-docs.ts +57 -48
  188. package/corpus/templates/slides/actions/provider-api-request.ts +145 -172
  189. package/corpus/templates/slides/actions/query-staged-dataset.ts +4 -47
  190. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +11 -36
  191. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -12
  192. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +10 -0
  193. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  194. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +11 -2
  195. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  196. package/corpus/toolkit/CHANGELOG.md +125 -0
  197. package/corpus/toolkit/README.md +60 -0
  198. package/corpus/toolkit/export-snapshot.json +35 -0
  199. package/corpus/toolkit/migration-manifest.json +4 -0
  200. package/corpus/toolkit/package.json +281 -0
  201. package/corpus/toolkit/scripts/finalize-build.mjs +55 -0
  202. package/corpus/toolkit/src/app-shell/header-actions.tsx +84 -0
  203. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  204. package/corpus/toolkit/src/chat-history/ChatHistoryList.tsx +469 -0
  205. package/corpus/toolkit/src/chat-history/index.ts +7 -0
  206. package/corpus/toolkit/src/chat-history.css +314 -0
  207. package/corpus/toolkit/src/collab-ui/AgentPresenceChip.tsx +69 -0
  208. package/corpus/toolkit/src/collab-ui/LiveCursorOverlay.tsx +241 -0
  209. package/corpus/toolkit/src/collab-ui/PresenceBar.tsx +346 -0
  210. package/corpus/toolkit/src/collab-ui/RecentEditHighlights.tsx +225 -0
  211. package/corpus/toolkit/src/collab-ui/RemoteSelectionRings.tsx +227 -0
  212. package/corpus/toolkit/src/collab-ui/agent-identity.ts +16 -0
  213. package/corpus/toolkit/src/collab-ui/index.ts +39 -0
  214. package/corpus/toolkit/src/collab-ui/lead-client.ts +32 -0
  215. package/corpus/toolkit/src/collab-ui/types.ts +96 -0
  216. package/corpus/toolkit/src/composer/AgentComposerFrame.tsx +59 -0
  217. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +983 -0
  218. package/corpus/toolkit/src/composer/MentionPopover.tsx +412 -0
  219. package/corpus/toolkit/src/composer/PastedTextChip.tsx +150 -0
  220. package/corpus/toolkit/src/composer/PromptComposer.tsx +718 -0
  221. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +856 -0
  222. package/corpus/toolkit/src/composer/TiptapComposer.tsx +2936 -0
  223. package/corpus/toolkit/src/composer/VoiceButton.tsx +255 -0
  224. package/corpus/toolkit/src/composer/asset-picker-url.ts +80 -0
  225. package/corpus/toolkit/src/composer/attachment-accept.ts +71 -0
  226. package/corpus/toolkit/src/composer/draft-key.ts +7 -0
  227. package/corpus/toolkit/src/composer/extensions/FileReference.tsx +55 -0
  228. package/corpus/toolkit/src/composer/extensions/MentionReference.tsx +93 -0
  229. package/corpus/toolkit/src/composer/extensions/SkillReference.tsx +56 -0
  230. package/corpus/toolkit/src/composer/index.ts +79 -0
  231. package/corpus/toolkit/src/composer/pasted-text.ts +160 -0
  232. package/corpus/toolkit/src/composer/prompt-attachments.ts +93 -0
  233. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +64 -0
  234. package/corpus/toolkit/src/composer/realtime-voice-transcript.ts +134 -0
  235. package/corpus/toolkit/src/composer/runtime-adapters.tsx +343 -0
  236. package/corpus/toolkit/src/composer/types.ts +66 -0
  237. package/corpus/toolkit/src/composer/use-file-search.ts +64 -0
  238. package/corpus/toolkit/src/composer/use-mention-search.ts +90 -0
  239. package/corpus/toolkit/src/composer/use-skills.ts +45 -0
  240. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +2117 -0
  241. package/corpus/toolkit/src/composer/useVoiceDictation.ts +1191 -0
  242. package/corpus/toolkit/src/context-ui/ContextMeter.tsx +101 -0
  243. package/corpus/toolkit/src/context-ui/ContextSegmentRow.tsx +184 -0
  244. package/corpus/toolkit/src/context-ui/ContextTreemap.tsx +125 -0
  245. package/corpus/toolkit/src/context-ui/ContextXRayPanel.tsx +377 -0
  246. package/corpus/toolkit/src/context-ui/format.ts +42 -0
  247. package/corpus/toolkit/src/context-ui/index.ts +15 -0
  248. package/corpus/toolkit/src/context-ui/types.ts +43 -0
  249. package/corpus/toolkit/src/design-tweaks/index.ts +1 -0
  250. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +1084 -0
  251. package/corpus/toolkit/src/editor/BubbleToolbar.tsx +253 -0
  252. package/corpus/toolkit/src/editor/CodeBlockNode.tsx +254 -0
  253. package/corpus/toolkit/src/editor/DragHandle.ts +1437 -0
  254. package/corpus/toolkit/src/editor/ImageExtension.ts +306 -0
  255. package/corpus/toolkit/src/editor/RegistryBlockContext.tsx +107 -0
  256. package/corpus/toolkit/src/editor/RegistryBlockNode.tsx +652 -0
  257. package/corpus/toolkit/src/editor/RichMarkdownEditor.tsx +81 -0
  258. package/corpus/toolkit/src/editor/RunId.ts +61 -0
  259. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +321 -0
  260. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +310 -0
  261. package/corpus/toolkit/src/editor/extensions.ts +402 -0
  262. package/corpus/toolkit/src/editor/gfmDoc.ts +92 -0
  263. package/corpus/toolkit/src/editor/index.ts +93 -0
  264. package/corpus/toolkit/src/editor/registrySlashCommands.ts +131 -0
  265. package/corpus/toolkit/src/editor/surgical-apply.ts +192 -0
  266. package/corpus/toolkit/src/editor/useCollabReconcile.ts +589 -0
  267. package/corpus/toolkit/src/editor.css +510 -0
  268. package/corpus/toolkit/src/hooks/index.ts +2 -0
  269. package/corpus/toolkit/src/hooks/use-mobile.tsx +21 -0
  270. package/corpus/toolkit/src/hooks/use-toast.ts +188 -0
  271. package/corpus/toolkit/src/index.ts +8 -0
  272. package/corpus/toolkit/src/onboarding/index.ts +1 -0
  273. package/corpus/toolkit/src/provider.tsx +47 -0
  274. package/corpus/toolkit/src/sharing/VisibilityBadge.tsx +37 -0
  275. package/corpus/toolkit/src/sharing/index.ts +4 -0
  276. package/corpus/toolkit/src/styles.css +21 -0
  277. package/corpus/toolkit/src/ui/accordion.tsx +56 -0
  278. package/corpus/toolkit/src/ui/alert-dialog.tsx +141 -0
  279. package/corpus/toolkit/src/ui/alert.tsx +59 -0
  280. package/corpus/toolkit/src/ui/aspect-ratio.tsx +5 -0
  281. package/corpus/toolkit/src/ui/avatar.tsx +48 -0
  282. package/corpus/toolkit/src/ui/badge.tsx +37 -0
  283. package/corpus/toolkit/src/ui/breadcrumb.tsx +115 -0
  284. package/corpus/toolkit/src/ui/button.tsx +78 -0
  285. package/corpus/toolkit/src/ui/calendar.tsx +214 -0
  286. package/corpus/toolkit/src/ui/card.tsx +86 -0
  287. package/corpus/toolkit/src/ui/carousel.tsx +260 -0
  288. package/corpus/toolkit/src/ui/chart.tsx +375 -0
  289. package/corpus/toolkit/src/ui/checkbox.tsx +28 -0
  290. package/corpus/toolkit/src/ui/collapsible.tsx +9 -0
  291. package/corpus/toolkit/src/ui/command.tsx +174 -0
  292. package/corpus/toolkit/src/ui/context-menu.tsx +202 -0
  293. package/corpus/toolkit/src/ui/date-picker.tsx +64 -0
  294. package/corpus/toolkit/src/ui/dialog.tsx +146 -0
  295. package/corpus/toolkit/src/ui/drawer.tsx +126 -0
  296. package/corpus/toolkit/src/ui/dropdown-menu.tsx +218 -0
  297. package/corpus/toolkit/src/ui/form.tsx +177 -0
  298. package/corpus/toolkit/src/ui/hover-card.tsx +27 -0
  299. package/corpus/toolkit/src/ui/index.ts +52 -0
  300. package/corpus/toolkit/src/ui/input-otp.tsx +69 -0
  301. package/corpus/toolkit/src/ui/input.tsx +22 -0
  302. package/corpus/toolkit/src/ui/label.tsx +24 -0
  303. package/corpus/toolkit/src/ui/logo.tsx +36 -0
  304. package/corpus/toolkit/src/ui/menubar.tsx +235 -0
  305. package/corpus/toolkit/src/ui/navigation-menu.tsx +128 -0
  306. package/corpus/toolkit/src/ui/pagination.tsx +121 -0
  307. package/corpus/toolkit/src/ui/popover.tsx +44 -0
  308. package/corpus/toolkit/src/ui/progress.tsx +26 -0
  309. package/corpus/toolkit/src/ui/radio-group.tsx +42 -0
  310. package/corpus/toolkit/src/ui/resizable.tsx +43 -0
  311. package/corpus/toolkit/src/ui/scroll-area.tsx +46 -0
  312. package/corpus/toolkit/src/ui/select.tsx +158 -0
  313. package/corpus/toolkit/src/ui/separator.tsx +29 -0
  314. package/corpus/toolkit/src/ui/sheet.tsx +160 -0
  315. package/corpus/toolkit/src/ui/sidebar.tsx +777 -0
  316. package/corpus/toolkit/src/ui/skeleton.tsx +18 -0
  317. package/corpus/toolkit/src/ui/slider.tsx +26 -0
  318. package/corpus/toolkit/src/ui/sonner.tsx +58 -0
  319. package/corpus/toolkit/src/ui/spinner.tsx +17 -0
  320. package/corpus/toolkit/src/ui/switch.tsx +27 -0
  321. package/corpus/toolkit/src/ui/table.tsx +117 -0
  322. package/corpus/toolkit/src/ui/tabs.tsx +53 -0
  323. package/corpus/toolkit/src/ui/textarea.tsx +23 -0
  324. package/corpus/toolkit/src/ui/toast.tsx +127 -0
  325. package/corpus/toolkit/src/ui/toaster.tsx +33 -0
  326. package/corpus/toolkit/src/ui/toggle-group.tsx +59 -0
  327. package/corpus/toolkit/src/ui/toggle.tsx +43 -0
  328. package/corpus/toolkit/src/ui/tooltip.tsx +53 -0
  329. package/corpus/toolkit/src/ui/use-toast.ts +3 -0
  330. package/corpus/toolkit/src/utils.ts +8 -0
  331. package/corpus/toolkit/tsconfig.json +23 -0
  332. package/dist/cli/atomic-json-file.d.ts +30 -0
  333. package/dist/cli/atomic-json-file.d.ts.map +1 -0
  334. package/dist/cli/atomic-json-file.js +240 -0
  335. package/dist/cli/atomic-json-file.js.map +1 -0
  336. package/dist/cli/claude-code-participant.d.ts +77 -0
  337. package/dist/cli/claude-code-participant.d.ts.map +1 -0
  338. package/dist/cli/claude-code-participant.js +355 -0
  339. package/dist/cli/claude-code-participant.js.map +1 -0
  340. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  341. package/dist/cli/code-agent-executor.js +18 -10
  342. package/dist/cli/code-agent-executor.js.map +1 -1
  343. package/dist/cli/code-agent-runs.concurrent-worker.d.ts +2 -0
  344. package/dist/cli/code-agent-runs.concurrent-worker.d.ts.map +1 -0
  345. package/dist/cli/code-agent-runs.concurrent-worker.js +32 -0
  346. package/dist/cli/code-agent-runs.concurrent-worker.js.map +1 -0
  347. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  348. package/dist/cli/code-agent-runs.js +43 -56
  349. package/dist/cli/code-agent-runs.js.map +1 -1
  350. package/dist/cli/codex-cli-participant.d.ts +77 -0
  351. package/dist/cli/codex-cli-participant.d.ts.map +1 -0
  352. package/dist/cli/codex-cli-participant.js +354 -0
  353. package/dist/cli/codex-cli-participant.js.map +1 -0
  354. package/dist/cli/multi-frontier-runs.d.ts +115 -0
  355. package/dist/cli/multi-frontier-runs.d.ts.map +1 -1
  356. package/dist/cli/multi-frontier-runs.js +831 -113
  357. package/dist/cli/multi-frontier-runs.js.map +1 -1
  358. package/dist/client/chat/ChatHistoryList.d.ts +1 -87
  359. package/dist/client/chat/ChatHistoryList.d.ts.map +1 -1
  360. package/dist/client/chat/ChatHistoryList.js +1 -82
  361. package/dist/client/chat/ChatHistoryList.js.map +1 -1
  362. package/dist/integrations/index.d.ts +2 -1
  363. package/dist/integrations/index.d.ts.map +1 -1
  364. package/dist/integrations/index.js +2 -1
  365. package/dist/integrations/index.js.map +1 -1
  366. package/dist/integrations/slack-manifest.d.ts +1 -1
  367. package/dist/integrations/slack-oauth.d.ts +1 -1
  368. package/dist/integrations/slack-oauth.d.ts.map +1 -1
  369. package/dist/integrations/slack-oauth.js +1 -0
  370. package/dist/integrations/slack-oauth.js.map +1 -1
  371. package/dist/integrations/webhook-delivery.d.ts +23 -0
  372. package/dist/integrations/webhook-delivery.d.ts.map +1 -0
  373. package/dist/integrations/webhook-delivery.js +32 -0
  374. package/dist/integrations/webhook-delivery.js.map +1 -0
  375. package/dist/notifications/channels.d.ts.map +1 -1
  376. package/dist/notifications/channels.js +4 -9
  377. package/dist/notifications/channels.js.map +1 -1
  378. package/dist/notifications/routes.d.ts +3 -3
  379. package/dist/provider-api/actions/custom-provider-registration.d.ts +136 -0
  380. package/dist/provider-api/actions/custom-provider-registration.d.ts.map +1 -0
  381. package/dist/provider-api/actions/custom-provider-registration.js +154 -0
  382. package/dist/provider-api/actions/custom-provider-registration.js.map +1 -0
  383. package/dist/provider-api/actions/delete-staged-dataset.d.ts +1 -1
  384. package/dist/provider-api/actions/delete-staged-dataset.d.ts.map +1 -1
  385. package/dist/provider-api/actions/delete-staged-dataset.js +3 -34
  386. package/dist/provider-api/actions/delete-staged-dataset.js.map +1 -1
  387. package/dist/provider-api/actions/list-staged-datasets.d.ts +2 -3
  388. package/dist/provider-api/actions/list-staged-datasets.d.ts.map +1 -1
  389. package/dist/provider-api/actions/list-staged-datasets.js +3 -40
  390. package/dist/provider-api/actions/list-staged-datasets.js.map +1 -1
  391. package/dist/provider-api/actions/provider-api-audit.d.ts +7 -0
  392. package/dist/provider-api/actions/provider-api-audit.d.ts.map +1 -0
  393. package/dist/provider-api/actions/provider-api-audit.js +74 -0
  394. package/dist/provider-api/actions/provider-api-audit.js.map +1 -0
  395. package/dist/provider-api/actions/provider-api.d.ts +370 -0
  396. package/dist/provider-api/actions/provider-api.d.ts.map +1 -0
  397. package/dist/provider-api/actions/provider-api.js +280 -0
  398. package/dist/provider-api/actions/provider-api.js.map +1 -0
  399. package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
  400. package/dist/provider-api/actions/query-staged-dataset.d.ts.map +1 -1
  401. package/dist/provider-api/actions/query-staged-dataset.js +3 -116
  402. package/dist/provider-api/actions/query-staged-dataset.js.map +1 -1
  403. package/dist/provider-api/actions/staged-datasets.d.ts +190 -0
  404. package/dist/provider-api/actions/staged-datasets.d.ts.map +1 -0
  405. package/dist/provider-api/actions/staged-datasets.js +210 -0
  406. package/dist/provider-api/actions/staged-datasets.js.map +1 -0
  407. package/dist/provider-api/gong.d.ts +44 -0
  408. package/dist/provider-api/gong.d.ts.map +1 -0
  409. package/dist/provider-api/gong.js +56 -0
  410. package/dist/provider-api/gong.js.map +1 -0
  411. package/dist/scripts/docs/source-search.d.ts +2 -1
  412. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  413. package/dist/scripts/docs/source-search.js +2 -1
  414. package/dist/scripts/docs/source-search.js.map +1 -1
  415. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  416. package/dist/server/google-oauth-credentials.d.ts +35 -0
  417. package/dist/server/google-oauth-credentials.d.ts.map +1 -1
  418. package/dist/server/google-oauth-credentials.js +48 -2
  419. package/dist/server/google-oauth-credentials.js.map +1 -1
  420. package/dist/server/index.d.ts +1 -1
  421. package/dist/server/index.d.ts.map +1 -1
  422. package/dist/server/index.js +1 -1
  423. package/dist/server/index.js.map +1 -1
  424. package/dist/styles/chat-history-list.css +1 -313
  425. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  426. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  427. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  428. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  429. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  430. package/dist/templates/chat/AGENTS.md +5 -2
  431. package/dist/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  432. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -12
  433. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  434. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  435. package/dist/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  436. package/dist/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  437. package/dist/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  438. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  439. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  440. package/dist/templates/default/AGENTS.md +25 -18
  441. package/dist/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  442. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  443. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  444. package/dist/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  445. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  446. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  447. package/dist/templates/headless/AGENTS.md +7 -0
  448. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  449. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  450. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  451. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  452. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  453. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  454. package/dist/templates/workspace-core/AGENTS.md +4 -0
  455. package/dist/templates/workspace-root/AGENTS.md +4 -0
  456. package/docs/AGENTS.md +7 -0
  457. package/docs/content/integrations.mdx +63 -2
  458. package/docs/design/provider-integration-authority.md +117 -0
  459. package/package.json +7 -2
  460. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  461. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  462. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  463. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  464. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  465. package/src/templates/chat/AGENTS.md +5 -2
  466. package/src/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  467. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  468. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  469. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  470. package/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  471. package/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  472. package/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  473. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  474. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  475. package/src/templates/default/AGENTS.md +25 -18
  476. package/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  477. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  478. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  479. package/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  480. package/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  481. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  482. package/src/templates/headless/AGENTS.md +7 -0
  483. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  484. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  485. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  486. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  487. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  488. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  489. package/src/templates/workspace-core/AGENTS.md +4 -0
  490. package/src/templates/workspace-root/AGENTS.md +4 -0
@@ -4,6 +4,12 @@ import os from "os";
4
4
  import path from "path";
5
5
 
6
6
  import type { AgentPromptAttachment } from "../code-agents/prompt-attachments.js";
7
+ import {
8
+ appendUniqueJsonLineAtomically,
9
+ updateJsonFileAtomically,
10
+ withFileLockSync,
11
+ writeJsonFileAtomically,
12
+ } from "./atomic-json-file.js";
7
13
 
8
14
  export type CodeAgentRunStatus =
9
15
  | "queued"
@@ -194,14 +200,12 @@ export function readCodeAgentCommandAllowlist(): string[] {
194
200
  * are auto-approved without a prompt. Deduplicates by exact string match.
195
201
  */
196
202
  export function addCodeAgentCommandToAllowlist(command: string): void {
197
- const current = readCodeAgentCommandAllowlist();
198
- if (current.includes(command)) return;
199
- const next = [...current, command];
200
- fs.mkdirSync(codeAgentStoreRoot(), { recursive: true });
201
- fs.writeFileSync(
202
- codeAgentCommandAllowlistPath(),
203
- JSON.stringify(next, null, 2),
204
- );
203
+ const filePath = codeAgentCommandAllowlistPath();
204
+ withFileLockSync(filePath, () => {
205
+ const current = readCodeAgentCommandAllowlist();
206
+ if (current.includes(command)) return;
207
+ writeJsonFileAtomically(filePath, [...current, command], { mode: 0o600 });
208
+ });
205
209
  }
206
210
 
207
211
  /** Return true if `command` is in the stored allowlist. */
@@ -247,11 +251,8 @@ export function normalizeCodeAgentPermissionMode(
247
251
  }
248
252
 
249
253
  export function writeCodeAgentRunRecord(record: CodeAgentRunRecord): void {
250
- fs.mkdirSync(codeAgentRunsDir(), { recursive: true });
251
- writeFileAtomically(
252
- codeAgentRunRecordPath(record.id),
253
- `${JSON.stringify(record, null, 2)}\n`,
254
- );
254
+ const filePath = codeAgentRunRecordPath(record.id);
255
+ withFileLockSync(filePath, () => writeJsonFileAtomically(filePath, record));
255
256
  }
256
257
 
257
258
  export function getCodeAgentRunRecord(
@@ -266,20 +267,23 @@ export function updateCodeAgentRunRecord(
266
267
  | Partial<CodeAgentRunRecord>
267
268
  | ((record: CodeAgentRunRecord) => Partial<CodeAgentRunRecord>),
268
269
  ): CodeAgentRunRecord | null {
269
- const record = getCodeAgentRunRecord(runId);
270
- if (!record) return null;
271
- const patch = typeof updates === "function" ? updates(record) : updates;
272
- const next: CodeAgentRunRecord = {
273
- ...record,
274
- ...patch,
275
- metadata: {
276
- ...(record.metadata ?? {}),
277
- ...(patch.metadata ?? {}),
270
+ return updateJsonFileAtomically(
271
+ codeAgentRunRecordPath(runId),
272
+ readRunValue,
273
+ (record) => {
274
+ if (!record) return null;
275
+ const patch = typeof updates === "function" ? updates(record) : updates;
276
+ return {
277
+ ...record,
278
+ ...patch,
279
+ metadata: {
280
+ ...(record.metadata ?? {}),
281
+ ...(patch.metadata ?? {}),
282
+ },
283
+ updatedAt: patch.updatedAt ?? new Date().toISOString(),
284
+ };
278
285
  },
279
- updatedAt: patch.updatedAt ?? new Date().toISOString(),
280
- };
281
- writeCodeAgentRunRecord(next);
282
- return next;
286
+ );
283
287
  }
284
288
 
285
289
  export function listCodeAgentRunRecords(goalId?: string): CodeAgentRunRecord[] {
@@ -310,7 +314,6 @@ export function appendCodeAgentTranscriptEvent(
310
314
  );
311
315
  if (existing) return existing;
312
316
  }
313
-
314
317
  const createdAt = input.createdAt ?? new Date().toISOString();
315
318
  const event: CodeAgentTranscriptEvent = {
316
319
  schemaVersion: 1,
@@ -325,13 +328,13 @@ export function appendCodeAgentTranscriptEvent(
325
328
  ...(input.signal ? { signal: input.signal } : {}),
326
329
  };
327
330
 
328
- fs.mkdirSync(codeAgentTranscriptsDir(), { recursive: true });
329
- fs.appendFileSync(
331
+ const persisted = appendUniqueJsonLineAtomically(
330
332
  codeAgentRunTranscriptPath(input.runId),
331
- `${JSON.stringify(event)}\n`,
333
+ event,
334
+ readTranscriptValue,
332
335
  );
333
336
  touchCodeAgentRunRecord(input.runId, createdAt);
334
- return event;
337
+ return persisted.value;
335
338
  }
336
339
 
337
340
  export function listCodeAgentTranscriptEvents(
@@ -400,32 +403,6 @@ function codeAgentRunRecordPath(runId: string): string {
400
403
  return path.join(codeAgentRunsDir(), `${runId}.json`);
401
404
  }
402
405
 
403
- function writeFileAtomically(filePath: string, contents: string): void {
404
- const directory = path.dirname(filePath);
405
- const temporaryPath = path.join(
406
- directory,
407
- `.${path.basename(filePath)}.tmp-${process.pid}-${crypto.randomUUID()}`,
408
- );
409
- let mode: number | undefined;
410
- try {
411
- mode = fs.statSync(filePath).mode & 0o777;
412
- } catch {
413
- // A new run record uses the process umask.
414
- }
415
-
416
- try {
417
- fs.writeFileSync(temporaryPath, contents, {
418
- encoding: "utf-8",
419
- flag: "wx",
420
- });
421
- if (mode !== undefined) fs.chmodSync(temporaryPath, mode);
422
- fs.renameSync(temporaryPath, filePath);
423
- } catch (error) {
424
- fs.rmSync(temporaryPath, { force: true });
425
- throw error;
426
- }
427
- }
428
-
429
406
  function readPendingFollowUps(value: unknown): CodeAgentPendingFollowUp[] {
430
407
  if (!Array.isArray(value)) return [];
431
408
  return value
@@ -458,14 +435,23 @@ function readPendingFollowUps(value: unknown): CodeAgentPendingFollowUp[] {
458
435
  }
459
436
 
460
437
  function touchCodeAgentRunRecord(runId: string, updatedAt: string): void {
461
- const record = readRunFile(codeAgentRunRecordPath(runId));
462
- if (!record) return;
463
- writeCodeAgentRunRecord({ ...record, updatedAt });
438
+ updateJsonFileAtomically(
439
+ codeAgentRunRecordPath(runId),
440
+ readRunValue,
441
+ (record) => (record ? { ...record, updatedAt } : null),
442
+ );
464
443
  }
465
444
 
466
445
  function readRunFile(filePath: string): CodeAgentRunRecord | null {
467
446
  try {
468
- const raw = JSON.parse(fs.readFileSync(filePath, "utf-8")) as unknown;
447
+ return readRunValue(JSON.parse(fs.readFileSync(filePath, "utf-8")));
448
+ } catch {
449
+ return null;
450
+ }
451
+ }
452
+
453
+ function readRunValue(raw: unknown): CodeAgentRunRecord | null {
454
+ try {
469
455
  if (!raw || typeof raw !== "object") return null;
470
456
  const record = raw as Partial<CodeAgentRunRecord>;
471
457
  if (
@@ -488,7 +474,14 @@ function readRunFile(filePath: string): CodeAgentRunRecord | null {
488
474
 
489
475
  function readTranscriptLine(line: string): CodeAgentTranscriptEvent | null {
490
476
  try {
491
- const raw = JSON.parse(line) as unknown;
477
+ return readTranscriptValue(JSON.parse(line) as unknown);
478
+ } catch {
479
+ return null;
480
+ }
481
+ }
482
+
483
+ function readTranscriptValue(raw: unknown): CodeAgentTranscriptEvent | null {
484
+ try {
492
485
  if (!raw || typeof raw !== "object") return null;
493
486
  const event = raw as Partial<CodeAgentTranscriptEvent> & {
494
487
  type?: unknown;
@@ -0,0 +1,496 @@
1
+ import { execFile as execFileCallback, spawn } from "node:child_process";
2
+ import { isAbsolute } from "node:path";
3
+ import type { Readable, Writable } from "node:stream";
4
+ import { StringDecoder } from "node:string_decoder";
5
+ import { promisify } from "node:util";
6
+
7
+ const execFile = promisify(execFileCallback);
8
+
9
+ const CODEX_CLI_VERSION = "0.144.3";
10
+ const DEFAULT_MAX_EVENTS = 2_000;
11
+ const DEFAULT_MAX_STREAM_BYTES = 8 * 1024 * 1024;
12
+ const DEFAULT_MAX_STDERR_BYTES = 128 * 1024;
13
+ const DEFAULT_TIMEOUT_MS = 30 * 60 * 1_000;
14
+ const DEFAULT_TERMINATION_GRACE_MS = 2_000;
15
+ const DEFAULT_FORCE_SETTLE_MS = 250;
16
+ const MAX_ERROR_MESSAGE_LENGTH = 200;
17
+
18
+ const SAFE_ENVIRONMENT_KEYS = [
19
+ "PATH",
20
+ "HOME",
21
+ "LANG",
22
+ "LC_ALL",
23
+ "LC_CTYPE",
24
+ "TMPDIR",
25
+ "TMP",
26
+ "TEMP",
27
+ "TERM",
28
+ "NO_COLOR",
29
+ "FORCE_COLOR",
30
+ "USER",
31
+ "LOGNAME",
32
+ "SHELL",
33
+ // Codex reads its subscription session from this config root (or HOME/.codex).
34
+ "CODEX_HOME",
35
+ ] as const;
36
+
37
+ export type CodexCliParticipantRole = "planning" | "watchdog" | "driver";
38
+
39
+ export interface CodexCliSubscriptionStatus {
40
+ loggedIn: boolean;
41
+ authMode?: "ChatGPT" | "API key" | "unknown";
42
+ }
43
+
44
+ export interface CodexCliParticipantSession {
45
+ /** Codex owns and interprets this value; Agent Native only persists it. */
46
+ resumeSessionId?: string;
47
+ }
48
+
49
+ export interface CodexCliParticipantEvent {
50
+ [key: string]: unknown;
51
+ }
52
+
53
+ export interface CodexCliParticipantResult {
54
+ exitCode: number;
55
+ events: CodexCliParticipantEvent[];
56
+ stderr: string;
57
+ stderrTruncated: boolean;
58
+ resumeSessionId?: string;
59
+ }
60
+
61
+ export interface CodexCliParticipantChild {
62
+ stdin: Writable;
63
+ stdout: Readable;
64
+ stderr: Readable;
65
+ kill(signal?: NodeJS.Signals): boolean;
66
+ once(event: "error", listener: (error: Error) => void): unknown;
67
+ once(
68
+ event: "close",
69
+ listener: (code: number | null, signal: NodeJS.Signals | null) => void,
70
+ ): unknown;
71
+ }
72
+
73
+ export interface CodexCliParticipantSpawnOptions {
74
+ cwd: string;
75
+ env: NodeJS.ProcessEnv;
76
+ shell: false;
77
+ stdio: ["pipe", "pipe", "pipe"];
78
+ }
79
+
80
+ export type CodexCliParticipantSpawn = (
81
+ command: string,
82
+ args: string[],
83
+ options: CodexCliParticipantSpawnOptions,
84
+ ) => CodexCliParticipantChild;
85
+
86
+ export interface RunCodexCliParticipantOptions {
87
+ role: CodexCliParticipantRole;
88
+ prompt: string;
89
+ cwd: string;
90
+ model?: string;
91
+ session?: CodexCliParticipantSession;
92
+ /** Drivers remain read-only unless this explicit capability is true. */
93
+ allowWorkspaceWrite?: boolean;
94
+ /** Either the fixed CLI name or an absolute executable path for packaged apps. */
95
+ command?: string;
96
+ signal?: AbortSignal;
97
+ env?: NodeJS.ProcessEnv;
98
+ maxEvents?: number;
99
+ maxStreamBytes?: number;
100
+ maxStderrBytes?: number;
101
+ timeoutMs?: number;
102
+ terminationGraceMs?: number;
103
+ forceSettleMs?: number;
104
+ onEvent?: (event: CodexCliParticipantEvent) => void;
105
+ preflight?: (
106
+ context: CodexCliParticipantPreflightContext,
107
+ ) => Promise<CodexCliSubscriptionStatus>;
108
+ spawnProcess?: CodexCliParticipantSpawn;
109
+ }
110
+
111
+ export interface CodexCliParticipantPreflightContext {
112
+ command: string;
113
+ env: NodeJS.ProcessEnv;
114
+ }
115
+
116
+ export class CodexCliSubscriptionRequiredError extends Error {
117
+ constructor() {
118
+ super(
119
+ "Codex CLI must be signed in with a ChatGPT subscription. API-key fallback is disabled.",
120
+ );
121
+ this.name = "CodexCliSubscriptionRequiredError";
122
+ }
123
+ }
124
+
125
+ export interface CodexCliSubscriptionStatusOptions {
126
+ command?: string;
127
+ env?: NodeJS.ProcessEnv;
128
+ execute?: typeof execFile;
129
+ }
130
+
131
+ export async function readCodexCliSubscriptionStatus(
132
+ options: CodexCliSubscriptionStatusOptions = {},
133
+ ): Promise<CodexCliSubscriptionStatus> {
134
+ try {
135
+ const execute = options.execute ?? execFile;
136
+ const { stdout, stderr } = await execute(
137
+ resolveCommand(options.command, "codex"),
138
+ ["login", "status"],
139
+ {
140
+ encoding: "utf8",
141
+ maxBuffer: 128 * 1024,
142
+ timeout: 3_000,
143
+ windowsHide: true,
144
+ env: safeEnvironment(options.env ?? process.env),
145
+ },
146
+ );
147
+ const output = `${stdout}\n${stderr}`;
148
+ return {
149
+ loggedIn: /logged in using/i.test(output),
150
+ authMode: /logged in using\s+chatgpt/i.test(output)
151
+ ? "ChatGPT"
152
+ : /logged in using\s+(?:an?\s+)?api key/i.test(output)
153
+ ? "API key"
154
+ : "unknown",
155
+ };
156
+ } catch {
157
+ return { loggedIn: false };
158
+ }
159
+ }
160
+
161
+ export async function runCodexCliParticipant(
162
+ options: RunCodexCliParticipantOptions,
163
+ ): Promise<CodexCliParticipantResult> {
164
+ validateInput(options);
165
+ const env = safeEnvironment(options.env ?? process.env);
166
+ const command = resolveCommand(options.command, "codex");
167
+ const subscription = await (options.preflight
168
+ ? options.preflight({ command, env })
169
+ : readCodexCliSubscriptionStatus({ command, env }));
170
+ if (!subscription.loggedIn || subscription.authMode !== "ChatGPT") {
171
+ throw new CodexCliSubscriptionRequiredError();
172
+ }
173
+ if (options.signal?.aborted) throw createAbortError();
174
+
175
+ const args = buildCodexCliParticipantArgs(options);
176
+ const spawnProcess =
177
+ options.spawnProcess ??
178
+ ((command, commandArgs, spawnOptions) =>
179
+ spawn(command, commandArgs, spawnOptions));
180
+ const child = spawnProcess(command, args, {
181
+ cwd: options.cwd,
182
+ env,
183
+ shell: false,
184
+ stdio: ["pipe", "pipe", "pipe"],
185
+ });
186
+ return collectCodexCliParticipantResult(child, options);
187
+ }
188
+
189
+ export function buildCodexCliParticipantArgs(
190
+ options: Pick<
191
+ RunCodexCliParticipantOptions,
192
+ "role" | "cwd" | "model" | "session" | "allowWorkspaceWrite"
193
+ >,
194
+ ): string[] {
195
+ const sandbox =
196
+ options.role === "driver" && options.allowWorkspaceWrite === true
197
+ ? "workspace-write"
198
+ : "read-only";
199
+ const args = [
200
+ "--ask-for-approval",
201
+ "never",
202
+ "--sandbox",
203
+ sandbox,
204
+ "--cd",
205
+ options.cwd,
206
+ "exec",
207
+ ];
208
+ const resumeSessionId = readString(options.session?.resumeSessionId);
209
+ if (resumeSessionId) args.push("resume");
210
+ args.push("--json", "--skip-git-repo-check", "--ignore-user-config");
211
+
212
+ const model = readString(options.model);
213
+ if (model) args.push("--model", model);
214
+ if (resumeSessionId) args.push("--", resumeSessionId, "-");
215
+ else args.push("-");
216
+ return args;
217
+ }
218
+
219
+ function collectCodexCliParticipantResult(
220
+ child: CodexCliParticipantChild,
221
+ options: RunCodexCliParticipantOptions,
222
+ ): Promise<CodexCliParticipantResult> {
223
+ const maxEvents = boundedLimit(options.maxEvents, DEFAULT_MAX_EVENTS);
224
+ const maxStreamBytes = boundedLimit(
225
+ options.maxStreamBytes,
226
+ DEFAULT_MAX_STREAM_BYTES,
227
+ );
228
+ const maxStderrBytes = boundedLimit(
229
+ options.maxStderrBytes,
230
+ DEFAULT_MAX_STDERR_BYTES,
231
+ );
232
+ const timeoutMs = boundedDuration(options.timeoutMs, DEFAULT_TIMEOUT_MS);
233
+ const terminationGraceMs = boundedDuration(
234
+ options.terminationGraceMs,
235
+ DEFAULT_TERMINATION_GRACE_MS,
236
+ );
237
+ const forceSettleMs = boundedDuration(
238
+ options.forceSettleMs,
239
+ DEFAULT_FORCE_SETTLE_MS,
240
+ );
241
+ const decoder = new StringDecoder("utf8");
242
+ const stderrDecoder = new StringDecoder("utf8");
243
+ const events: CodexCliParticipantEvent[] = [];
244
+ let pending = "";
245
+ let streamBytes = 0;
246
+ let stderr = "";
247
+ let stderrBytes = 0;
248
+ let stderrTruncated = false;
249
+ let fatalError: Error | undefined;
250
+ let resumeSessionId: string | undefined;
251
+
252
+ return new Promise((resolve, reject) => {
253
+ let settled = false;
254
+ let terminationTimer: NodeJS.Timeout | undefined;
255
+ let forceSettleTimer: NodeJS.Timeout | undefined;
256
+ const timeoutTimer = setTimeout(() => {
257
+ stopWithError(new Error(`Codex CLI timed out after ${timeoutMs}ms.`));
258
+ }, timeoutMs);
259
+ timeoutTimer.unref?.();
260
+ const cleanup = () => {
261
+ options.signal?.removeEventListener("abort", abort);
262
+ clearTimeout(timeoutTimer);
263
+ if (terminationTimer) clearTimeout(terminationTimer);
264
+ if (forceSettleTimer) clearTimeout(forceSettleTimer);
265
+ };
266
+ const finishError = (error: Error) => {
267
+ if (settled) return;
268
+ settled = true;
269
+ cleanup();
270
+ reject(safeError(error));
271
+ };
272
+ const stopWithError = (error: Error) => {
273
+ if (fatalError) return;
274
+ fatalError = error;
275
+ terminationTimer = setTimeout(() => {
276
+ if (settled) return;
277
+ forceSettleTimer = setTimeout(() => {
278
+ finishError(fatalError ?? error);
279
+ }, forceSettleMs);
280
+ forceSettleTimer.unref?.();
281
+ child.kill("SIGKILL");
282
+ }, terminationGraceMs);
283
+ terminationTimer.unref?.();
284
+ child.kill("SIGTERM");
285
+ };
286
+ const abort = () => stopWithError(createAbortError());
287
+ const streamError = (error: Error) => {
288
+ if (!settled) stopWithError(error);
289
+ };
290
+ const consume = (line: string) => {
291
+ const event = consumeJsonLine(line, events, maxEvents, options.onEvent);
292
+ const threadId = readString(event?.thread_id);
293
+ if (event?.type === "thread.started" && threadId) {
294
+ resumeSessionId = threadId;
295
+ }
296
+ };
297
+
298
+ child.stdin.on("error", streamError);
299
+ child.stdout.on("error", streamError);
300
+ child.stderr.on("error", streamError);
301
+
302
+ if (options.signal) {
303
+ if (options.signal.aborted) abort();
304
+ else options.signal.addEventListener("abort", abort, { once: true });
305
+ }
306
+
307
+ child.stdout.on("data", (chunk: Buffer | string) => {
308
+ if (fatalError) return;
309
+ const bytes = Buffer.isBuffer(chunk)
310
+ ? chunk.length
311
+ : Buffer.byteLength(chunk);
312
+ streamBytes += bytes;
313
+ if (streamBytes > maxStreamBytes) {
314
+ stopWithError(
315
+ new Error(`Codex CLI stream exceeded ${maxStreamBytes} bytes.`),
316
+ );
317
+ return;
318
+ }
319
+ pending += decoder.write(
320
+ Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk),
321
+ );
322
+ try {
323
+ let newline = pending.indexOf("\n");
324
+ while (newline !== -1) {
325
+ consume(pending.slice(0, newline));
326
+ pending = pending.slice(newline + 1);
327
+ newline = pending.indexOf("\n");
328
+ }
329
+ } catch (error) {
330
+ stopWithError(toError(error));
331
+ }
332
+ });
333
+ child.stderr.on("data", (chunk: Buffer | string) => {
334
+ const encoded = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
335
+ const remaining = Math.max(0, maxStderrBytes - stderrBytes);
336
+ if (remaining === 0) {
337
+ stderrTruncated = true;
338
+ return;
339
+ }
340
+ stderr += stderrDecoder.write(encoded.subarray(0, remaining));
341
+ stderrBytes += Math.min(encoded.length, remaining);
342
+ if (encoded.length > remaining) stderrTruncated = true;
343
+ });
344
+ child.once("error", finishError);
345
+ child.once("close", (exitCode, exitSignal) => {
346
+ if (settled) return;
347
+ try {
348
+ pending += decoder.end();
349
+ stderr += stderrDecoder.end();
350
+ if (pending.trim()) consume(pending);
351
+ } catch (error) {
352
+ fatalError ??= toError(error);
353
+ }
354
+ if (fatalError) {
355
+ finishError(fatalError);
356
+ return;
357
+ }
358
+ if (exitCode !== 0) {
359
+ finishError(
360
+ new Error(
361
+ `Codex CLI exited with ${exitSignal ?? exitCode ?? "unknown"}${stderr ? `: ${summarizeStderr(stderr)}` : ""}`,
362
+ ),
363
+ );
364
+ return;
365
+ }
366
+ settled = true;
367
+ cleanup();
368
+ resolve({
369
+ exitCode: 0,
370
+ events,
371
+ stderr: sanitizeStderr(stderr),
372
+ stderrTruncated,
373
+ ...(resumeSessionId ? { resumeSessionId } : {}),
374
+ });
375
+ });
376
+ try {
377
+ child.stdin.end(options.prompt);
378
+ } catch (error) {
379
+ stopWithError(toError(error));
380
+ }
381
+ });
382
+ }
383
+
384
+ function consumeJsonLine(
385
+ line: string,
386
+ events: CodexCliParticipantEvent[],
387
+ maxEvents: number,
388
+ onEvent?: (event: CodexCliParticipantEvent) => void,
389
+ ): CodexCliParticipantEvent | undefined {
390
+ const trimmed = line.trim();
391
+ if (!trimmed) return undefined;
392
+ if (events.length >= maxEvents) {
393
+ throw new Error(`Codex CLI stream exceeded ${maxEvents} events.`);
394
+ }
395
+ const parsed = JSON.parse(trimmed) as unknown;
396
+ const event = asRecord(parsed);
397
+ if (!event) throw new Error("Codex CLI emitted a non-object JSON event.");
398
+ events.push(event);
399
+ onEvent?.(event);
400
+ return event;
401
+ }
402
+
403
+ function safeEnvironment(input: NodeJS.ProcessEnv): NodeJS.ProcessEnv {
404
+ return Object.fromEntries(
405
+ SAFE_ENVIRONMENT_KEYS.flatMap((key) =>
406
+ typeof input[key] === "string" ? [[key, input[key]]] : [],
407
+ ),
408
+ );
409
+ }
410
+
411
+ function validateInput(options: RunCodexCliParticipantOptions): void {
412
+ if (!readString(options.prompt))
413
+ throw new Error("Codex CLI prompt is required.");
414
+ if (!readString(options.cwd)) throw new Error("Codex CLI cwd is required.");
415
+ if (options.allowWorkspaceWrite && options.role !== "driver") {
416
+ throw new Error("Only a Codex driver can receive workspace-write access.");
417
+ }
418
+ const model = readString(options.model);
419
+ if (model?.startsWith("-")) throw new Error("Codex CLI model is invalid.");
420
+ const resumeSessionId = readString(options.session?.resumeSessionId);
421
+ if (resumeSessionId?.includes("\0")) {
422
+ throw new Error("Codex CLI resume state is invalid.");
423
+ }
424
+ resolveCommand(options.command, "codex");
425
+ }
426
+
427
+ function boundedLimit(value: number | undefined, maximum: number): number {
428
+ return Number.isSafeInteger(value) && (value ?? 0) > 0
429
+ ? Math.min(value as number, maximum)
430
+ : maximum;
431
+ }
432
+
433
+ function boundedDuration(value: number | undefined, fallback: number): number {
434
+ return Number.isSafeInteger(value) && (value ?? 0) > 0
435
+ ? Math.min(value as number, DEFAULT_TIMEOUT_MS)
436
+ : fallback;
437
+ }
438
+
439
+ function resolveCommand(
440
+ command: string | undefined,
441
+ defaultCommand: string,
442
+ ): string {
443
+ const value = readString(command) ?? defaultCommand;
444
+ if (value === defaultCommand) return value;
445
+ if (value.includes("\0") || !isAbsolute(value)) {
446
+ throw new Error("Codex CLI command must be an absolute executable path.");
447
+ }
448
+ return value;
449
+ }
450
+
451
+ function createAbortError(): Error {
452
+ const error = new Error("Codex CLI participant was canceled.");
453
+ error.name = "AbortError";
454
+ return error;
455
+ }
456
+
457
+ function toError(value: unknown): Error {
458
+ return value instanceof Error ? value : new Error(String(value));
459
+ }
460
+
461
+ function safeError(error: Error): Error {
462
+ const safe = new Error(summarizeStderr(error.message));
463
+ safe.name = error.name;
464
+ return safe;
465
+ }
466
+
467
+ function summarizeStderr(value: string): string {
468
+ return sanitizeStderr(value)
469
+ .replace(/\s+/g, " ")
470
+ .trim()
471
+ .slice(0, MAX_ERROR_MESSAGE_LENGTH);
472
+ }
473
+
474
+ function sanitizeStderr(value: string): string {
475
+ return value
476
+ .replace(/\bBearer\s+\S+/gi, "Bearer <redacted>")
477
+ .replace(
478
+ /(["']?)([A-Za-z_]*(?:token|key|secret|password)[A-Za-z_]*)\1\s*([=:])\s*(?:"[^"]*"|'[^']*'|[^\s,;}\]]+)/gi,
479
+ '$1$2$1$3"<redacted>"',
480
+ )
481
+ .replace(/\b(?:sk|rk)-[A-Za-z0-9_-]{8,}\b/g, "<redacted>");
482
+ }
483
+
484
+ function readString(value: unknown): string | undefined {
485
+ if (typeof value !== "string") return undefined;
486
+ const trimmed = value.trim();
487
+ return trimmed || undefined;
488
+ }
489
+
490
+ function asRecord(value: unknown): CodexCliParticipantEvent | undefined {
491
+ return value !== null && typeof value === "object" && !Array.isArray(value)
492
+ ? (value as CodexCliParticipantEvent)
493
+ : undefined;
494
+ }
495
+
496
+ export const CODEX_CLI_PARTICIPANT_TESTED_VERSION = CODEX_CLI_VERSION;