@agent-native/core 0.111.4 → 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 (574) hide show
  1. package/corpus/README.md +4 -2
  2. package/corpus/core/CHANGELOG.md +34 -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 +8 -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 +35 -15
  11. package/corpus/core/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  12. package/corpus/core/src/cli/code-agent-runs.ts +70 -36
  13. package/corpus/core/src/cli/codex-cli-participant.ts +496 -0
  14. package/corpus/core/src/cli/multi-frontier-runs.ts +1952 -0
  15. package/corpus/core/src/client/chat/ChatHistoryList.tsx +7 -404
  16. package/corpus/core/src/coding-tools/index.ts +27 -8
  17. package/corpus/core/src/embeddings/index.ts +233 -0
  18. package/corpus/core/src/index.ts +2 -0
  19. package/corpus/core/src/integrations/index.ts +10 -0
  20. package/corpus/core/src/integrations/slack-oauth.ts +1 -0
  21. package/corpus/core/src/integrations/webhook-delivery.ts +55 -0
  22. package/corpus/core/src/notifications/channels.ts +4 -10
  23. package/corpus/core/src/provider-api/actions/custom-provider-registration.ts +197 -0
  24. package/corpus/core/src/provider-api/actions/delete-staged-dataset.ts +3 -42
  25. package/corpus/core/src/provider-api/actions/list-staged-datasets.ts +3 -45
  26. package/corpus/core/src/provider-api/actions/provider-api-audit.ts +88 -0
  27. package/corpus/core/src/provider-api/actions/provider-api.ts +460 -0
  28. package/corpus/core/src/provider-api/actions/query-staged-dataset.ts +3 -140
  29. package/corpus/core/src/provider-api/actions/staged-datasets.ts +359 -0
  30. package/corpus/core/src/provider-api/gong.ts +108 -0
  31. package/corpus/core/src/scripts/docs/source-search.ts +2 -1
  32. package/corpus/core/src/search/index.ts +413 -0
  33. package/corpus/core/src/server/google-oauth-credentials.ts +80 -3
  34. package/corpus/core/src/server/index.ts +6 -0
  35. package/corpus/core/src/styles/chat-history-list.css +1 -313
  36. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  37. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  38. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  39. package/corpus/core/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  40. package/corpus/core/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  41. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  42. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  43. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  44. package/corpus/core/src/templates/default/AGENTS.md +25 -18
  45. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  46. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  47. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  48. package/corpus/core/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  49. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  50. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  51. package/corpus/core/src/templates/headless/AGENTS.md +7 -0
  52. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  53. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  54. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  55. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  56. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  57. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  58. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -0
  59. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
  60. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -12
  61. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  62. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +11 -2
  63. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  64. package/corpus/templates/analytics/actions/delete-staged-dataset.ts +3 -23
  65. package/corpus/templates/analytics/actions/list-staged-datasets.ts +3 -27
  66. package/corpus/templates/analytics/actions/provider-api-catalog.ts +16 -19
  67. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -5
  68. package/corpus/templates/analytics/actions/provider-api-request.ts +162 -185
  69. package/corpus/templates/analytics/actions/query-staged-dataset.ts +3 -47
  70. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +52 -161
  71. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -12
  72. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  73. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +11 -2
  74. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  75. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +63 -160
  76. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -12
  77. package/corpus/templates/brain/.agents/skills/brain/RUNBOOK.md +48 -5
  78. package/corpus/templates/brain/.agents/skills/brain/SKILL.md +46 -14
  79. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  80. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +11 -2
  81. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  82. package/corpus/templates/brain/README.md +34 -3
  83. package/corpus/templates/brain/actions/_schemas.ts +13 -7
  84. package/corpus/templates/brain/actions/approve-proposal.ts +2 -0
  85. package/corpus/templates/brain/actions/claim-distillation.ts +24 -27
  86. package/corpus/templates/brain/actions/create-source.ts +1 -1
  87. package/corpus/templates/brain/actions/delete-staged-dataset.ts +3 -24
  88. package/corpus/templates/brain/actions/get-knowledge.ts +6 -2
  89. package/corpus/templates/brain/actions/get-pilot-report.ts +44 -8
  90. package/corpus/templates/brain/actions/import-capture.ts +21 -9
  91. package/corpus/templates/brain/actions/import-transcript.ts +42 -14
  92. package/corpus/templates/brain/actions/list-captures.ts +10 -1
  93. package/corpus/templates/brain/actions/list-distillation-queue.ts +39 -14
  94. package/corpus/templates/brain/actions/list-projects.ts +51 -0
  95. package/corpus/templates/brain/actions/list-proposals.ts +80 -4
  96. package/corpus/templates/brain/actions/list-sources.ts +17 -3
  97. package/corpus/templates/brain/actions/list-staged-datasets.ts +3 -28
  98. package/corpus/templates/brain/actions/manage-project.ts +118 -0
  99. package/corpus/templates/brain/actions/mark-capture-distilled.ts +68 -20
  100. package/corpus/templates/brain/actions/navigate.ts +1 -0
  101. package/corpus/templates/brain/actions/provider-api-catalog.ts +5 -11
  102. package/corpus/templates/brain/actions/provider-api-docs.ts +3 -5
  103. package/corpus/templates/brain/actions/provider-api-request.ts +3 -37
  104. package/corpus/templates/brain/actions/query-staged-dataset.ts +3 -48
  105. package/corpus/templates/brain/actions/reject-proposal.ts +6 -1
  106. package/corpus/templates/brain/actions/resanitize-captures.ts +159 -33
  107. package/corpus/templates/brain/actions/review-proposal.ts +2 -0
  108. package/corpus/templates/brain/actions/search-everything.ts +10 -1
  109. package/corpus/templates/brain/actions/search-knowledge.ts +1 -1
  110. package/corpus/templates/brain/actions/set-settings.ts +36 -1
  111. package/corpus/templates/brain/actions/update-proposal.ts +2 -0
  112. package/corpus/templates/brain/actions/update-source.ts +5 -1
  113. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +48 -154
  114. package/corpus/templates/brain/app/hooks/use-distillation-bridge.ts +18 -9
  115. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +3 -0
  116. package/corpus/templates/brain/app/i18n-data.ts +731 -2
  117. package/corpus/templates/brain/app/lib/brain.ts +88 -1
  118. package/corpus/templates/brain/app/lib/ingest-handoff.ts +35 -0
  119. package/corpus/templates/brain/app/routes/ops.tsx +47 -0
  120. package/corpus/templates/brain/app/routes/review.tsx +41 -2
  121. package/corpus/templates/brain/app/routes/search.tsx +33 -2
  122. package/corpus/templates/brain/app/routes/settings.tsx +158 -0
  123. package/corpus/templates/brain/app/routes/sources.tsx +31 -0
  124. package/corpus/templates/brain/changelog/2026-07-19-added-private-source-safe-semantic-search.md +6 -0
  125. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-can-now-join-configured-public-channels-befo.md +6 -0
  126. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-continue-across-the-configured-number-of.md +6 -0
  127. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-start-with-a-safe-four-week-window-and-r.md +6 -0
  128. package/corpus/templates/brain/jobs/process-ingest-queue.ts +270 -36
  129. package/corpus/templates/brain/package.json +1 -0
  130. package/corpus/templates/brain/server/db/index.ts +18 -0
  131. package/corpus/templates/brain/server/db/schema.ts +197 -1
  132. package/corpus/templates/brain/server/jobs/distillation-queue.ts +12 -5
  133. package/corpus/templates/brain/server/lib/audiences.ts +708 -0
  134. package/corpus/templates/brain/server/lib/brain-health.ts +251 -38
  135. package/corpus/templates/brain/server/lib/brain.ts +877 -50
  136. package/corpus/templates/brain/server/lib/capture-sanitization.ts +217 -53
  137. package/corpus/templates/brain/server/lib/connectors.ts +609 -72
  138. package/corpus/templates/brain/server/lib/demo.ts +17 -4
  139. package/corpus/templates/brain/server/lib/hybrid-search.ts +363 -0
  140. package/corpus/templates/brain/server/lib/ingest-queue.ts +104 -0
  141. package/corpus/templates/brain/server/lib/privacy-readiness.ts +24 -0
  142. package/corpus/templates/brain/server/lib/search-index-contracts.ts +72 -0
  143. package/corpus/templates/brain/server/lib/search-index.ts +714 -0
  144. package/corpus/templates/brain/server/lib/search.ts +120 -4
  145. package/corpus/templates/brain/server/lib/sensitivity-policy.ts +174 -0
  146. package/corpus/templates/brain/server/lib/slack-channel-membership.ts +44 -0
  147. package/corpus/templates/brain/server/lib/slack-events.ts +281 -0
  148. package/corpus/templates/brain/server/onboarding.ts +29 -0
  149. package/corpus/templates/brain/server/plugins/db.ts +204 -0
  150. package/corpus/templates/brain/server/register-secrets.ts +46 -0
  151. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +36 -16
  152. package/corpus/templates/brain/server/routes/api/_agent-native/brain/slack-events.post.ts +28 -0
  153. package/corpus/templates/brain/shared/slack-source-config.ts +60 -0
  154. package/corpus/templates/brain/shared/types.ts +10 -0
  155. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -12
  156. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  157. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +11 -2
  158. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  159. package/corpus/templates/calendar/actions/delete-staged-dataset.ts +3 -24
  160. package/corpus/templates/calendar/actions/list-staged-datasets.ts +3 -28
  161. package/corpus/templates/calendar/actions/provider-api-catalog.ts +5 -11
  162. package/corpus/templates/calendar/actions/provider-api-docs.ts +3 -5
  163. package/corpus/templates/calendar/actions/provider-api-request.ts +3 -37
  164. package/corpus/templates/calendar/actions/query-staged-dataset.ts +3 -48
  165. package/corpus/templates/calendar/server/handlers/gong.ts +6 -61
  166. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -8
  167. package/corpus/templates/calendar/server/lib/google-calendar.ts +7 -45
  168. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  169. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  170. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  171. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  172. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  173. package/corpus/templates/chat/AGENTS.md +5 -2
  174. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  175. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -12
  176. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  177. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +11 -2
  178. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  179. package/corpus/templates/clips/AGENTS.md +11 -0
  180. package/corpus/templates/clips/actions/export-to-brain.ts +505 -171
  181. package/corpus/templates/clips/changelog/2026-07-19-ready-clips-transcripts-can-be-backfilled-to-brain-for-a-bou.md +6 -0
  182. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -1
  183. package/corpus/templates/clips/server/lib/google-calendar-client.ts +12 -22
  184. package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +9 -6
  185. package/corpus/templates/clips/server/lib/slack-oauth.ts +12 -47
  186. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +2 -6
  187. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +4 -4
  188. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -12
  189. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  190. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +11 -2
  191. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  192. package/corpus/templates/content/actions/delete-staged-dataset.ts +3 -24
  193. package/corpus/templates/content/actions/list-staged-datasets.ts +3 -28
  194. package/corpus/templates/content/actions/provider-api-catalog.ts +5 -11
  195. package/corpus/templates/content/actions/provider-api-docs.ts +3 -5
  196. package/corpus/templates/content/actions/provider-api-request.ts +3 -37
  197. package/corpus/templates/content/actions/query-staged-dataset.ts +3 -48
  198. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -12
  199. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  200. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +11 -2
  201. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  202. package/corpus/templates/design/actions/delete-staged-dataset.ts +4 -23
  203. package/corpus/templates/design/actions/list-staged-datasets.ts +4 -27
  204. package/corpus/templates/design/actions/provider-api-catalog.ts +15 -18
  205. package/corpus/templates/design/actions/provider-api-docs.ts +57 -48
  206. package/corpus/templates/design/actions/provider-api-request.ts +140 -164
  207. package/corpus/templates/design/actions/query-staged-dataset.ts +4 -47
  208. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -12
  209. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  210. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +11 -2
  211. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  212. package/corpus/templates/dispatch/actions/delete-staged-dataset.ts +4 -23
  213. package/corpus/templates/dispatch/actions/list-staged-datasets.ts +4 -30
  214. package/corpus/templates/dispatch/actions/provider-api-catalog.ts +15 -18
  215. package/corpus/templates/dispatch/actions/provider-api-docs.ts +57 -48
  216. package/corpus/templates/dispatch/actions/provider-api-request.ts +138 -163
  217. package/corpus/templates/dispatch/actions/query-staged-dataset.ts +4 -47
  218. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -12
  219. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  220. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +11 -2
  221. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  222. package/corpus/templates/forms/server/lib/integrations.ts +23 -22
  223. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  224. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  225. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -12
  226. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  227. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +11 -2
  228. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  229. package/corpus/templates/mail/actions/delete-staged-dataset.ts +4 -23
  230. package/corpus/templates/mail/actions/list-staged-datasets.ts +4 -27
  231. package/corpus/templates/mail/actions/provider-api-catalog.ts +15 -18
  232. package/corpus/templates/mail/actions/provider-api-docs.ts +57 -48
  233. package/corpus/templates/mail/actions/provider-api-request.ts +146 -173
  234. package/corpus/templates/mail/actions/query-staged-dataset.ts +4 -47
  235. package/corpus/templates/mail/server/handlers/gong.ts +6 -61
  236. package/corpus/templates/mail/server/lib/google-auth.ts +10 -13
  237. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -12
  238. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  239. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +11 -2
  240. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  241. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +47 -156
  242. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -12
  243. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  244. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +11 -2
  245. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  246. package/corpus/templates/slides/actions/delete-staged-dataset.ts +4 -23
  247. package/corpus/templates/slides/actions/list-staged-datasets.ts +4 -27
  248. package/corpus/templates/slides/actions/provider-api-catalog.ts +15 -18
  249. package/corpus/templates/slides/actions/provider-api-docs.ts +57 -48
  250. package/corpus/templates/slides/actions/provider-api-request.ts +145 -172
  251. package/corpus/templates/slides/actions/query-staged-dataset.ts +4 -47
  252. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +11 -36
  253. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -12
  254. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +10 -0
  255. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  256. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +11 -2
  257. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  258. package/corpus/toolkit/CHANGELOG.md +125 -0
  259. package/corpus/toolkit/README.md +60 -0
  260. package/corpus/toolkit/export-snapshot.json +35 -0
  261. package/corpus/toolkit/migration-manifest.json +4 -0
  262. package/corpus/toolkit/package.json +281 -0
  263. package/corpus/toolkit/scripts/finalize-build.mjs +55 -0
  264. package/corpus/toolkit/src/app-shell/header-actions.tsx +84 -0
  265. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  266. package/corpus/toolkit/src/chat-history/ChatHistoryList.tsx +469 -0
  267. package/corpus/toolkit/src/chat-history/index.ts +7 -0
  268. package/corpus/toolkit/src/chat-history.css +314 -0
  269. package/corpus/toolkit/src/collab-ui/AgentPresenceChip.tsx +69 -0
  270. package/corpus/toolkit/src/collab-ui/LiveCursorOverlay.tsx +241 -0
  271. package/corpus/toolkit/src/collab-ui/PresenceBar.tsx +346 -0
  272. package/corpus/toolkit/src/collab-ui/RecentEditHighlights.tsx +225 -0
  273. package/corpus/toolkit/src/collab-ui/RemoteSelectionRings.tsx +227 -0
  274. package/corpus/toolkit/src/collab-ui/agent-identity.ts +16 -0
  275. package/corpus/toolkit/src/collab-ui/index.ts +39 -0
  276. package/corpus/toolkit/src/collab-ui/lead-client.ts +32 -0
  277. package/corpus/toolkit/src/collab-ui/types.ts +96 -0
  278. package/corpus/toolkit/src/composer/AgentComposerFrame.tsx +59 -0
  279. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +983 -0
  280. package/corpus/toolkit/src/composer/MentionPopover.tsx +412 -0
  281. package/corpus/toolkit/src/composer/PastedTextChip.tsx +150 -0
  282. package/corpus/toolkit/src/composer/PromptComposer.tsx +718 -0
  283. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +856 -0
  284. package/corpus/toolkit/src/composer/TiptapComposer.tsx +2936 -0
  285. package/corpus/toolkit/src/composer/VoiceButton.tsx +255 -0
  286. package/corpus/toolkit/src/composer/asset-picker-url.ts +80 -0
  287. package/corpus/toolkit/src/composer/attachment-accept.ts +71 -0
  288. package/corpus/toolkit/src/composer/draft-key.ts +7 -0
  289. package/corpus/toolkit/src/composer/extensions/FileReference.tsx +55 -0
  290. package/corpus/toolkit/src/composer/extensions/MentionReference.tsx +93 -0
  291. package/corpus/toolkit/src/composer/extensions/SkillReference.tsx +56 -0
  292. package/corpus/toolkit/src/composer/index.ts +79 -0
  293. package/corpus/toolkit/src/composer/pasted-text.ts +160 -0
  294. package/corpus/toolkit/src/composer/prompt-attachments.ts +93 -0
  295. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +64 -0
  296. package/corpus/toolkit/src/composer/realtime-voice-transcript.ts +134 -0
  297. package/corpus/toolkit/src/composer/runtime-adapters.tsx +343 -0
  298. package/corpus/toolkit/src/composer/types.ts +66 -0
  299. package/corpus/toolkit/src/composer/use-file-search.ts +64 -0
  300. package/corpus/toolkit/src/composer/use-mention-search.ts +90 -0
  301. package/corpus/toolkit/src/composer/use-skills.ts +45 -0
  302. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +2117 -0
  303. package/corpus/toolkit/src/composer/useVoiceDictation.ts +1191 -0
  304. package/corpus/toolkit/src/context-ui/ContextMeter.tsx +101 -0
  305. package/corpus/toolkit/src/context-ui/ContextSegmentRow.tsx +184 -0
  306. package/corpus/toolkit/src/context-ui/ContextTreemap.tsx +125 -0
  307. package/corpus/toolkit/src/context-ui/ContextXRayPanel.tsx +377 -0
  308. package/corpus/toolkit/src/context-ui/format.ts +42 -0
  309. package/corpus/toolkit/src/context-ui/index.ts +15 -0
  310. package/corpus/toolkit/src/context-ui/types.ts +43 -0
  311. package/corpus/toolkit/src/design-tweaks/index.ts +1 -0
  312. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +1084 -0
  313. package/corpus/toolkit/src/editor/BubbleToolbar.tsx +253 -0
  314. package/corpus/toolkit/src/editor/CodeBlockNode.tsx +254 -0
  315. package/corpus/toolkit/src/editor/DragHandle.ts +1437 -0
  316. package/corpus/toolkit/src/editor/ImageExtension.ts +306 -0
  317. package/corpus/toolkit/src/editor/RegistryBlockContext.tsx +107 -0
  318. package/corpus/toolkit/src/editor/RegistryBlockNode.tsx +652 -0
  319. package/corpus/toolkit/src/editor/RichMarkdownEditor.tsx +81 -0
  320. package/corpus/toolkit/src/editor/RunId.ts +61 -0
  321. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +321 -0
  322. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +310 -0
  323. package/corpus/toolkit/src/editor/extensions.ts +402 -0
  324. package/corpus/toolkit/src/editor/gfmDoc.ts +92 -0
  325. package/corpus/toolkit/src/editor/index.ts +93 -0
  326. package/corpus/toolkit/src/editor/registrySlashCommands.ts +131 -0
  327. package/corpus/toolkit/src/editor/surgical-apply.ts +192 -0
  328. package/corpus/toolkit/src/editor/useCollabReconcile.ts +589 -0
  329. package/corpus/toolkit/src/editor.css +510 -0
  330. package/corpus/toolkit/src/hooks/index.ts +2 -0
  331. package/corpus/toolkit/src/hooks/use-mobile.tsx +21 -0
  332. package/corpus/toolkit/src/hooks/use-toast.ts +188 -0
  333. package/corpus/toolkit/src/index.ts +8 -0
  334. package/corpus/toolkit/src/onboarding/index.ts +1 -0
  335. package/corpus/toolkit/src/provider.tsx +47 -0
  336. package/corpus/toolkit/src/sharing/VisibilityBadge.tsx +37 -0
  337. package/corpus/toolkit/src/sharing/index.ts +4 -0
  338. package/corpus/toolkit/src/styles.css +21 -0
  339. package/corpus/toolkit/src/ui/accordion.tsx +56 -0
  340. package/corpus/toolkit/src/ui/alert-dialog.tsx +141 -0
  341. package/corpus/toolkit/src/ui/alert.tsx +59 -0
  342. package/corpus/toolkit/src/ui/aspect-ratio.tsx +5 -0
  343. package/corpus/toolkit/src/ui/avatar.tsx +48 -0
  344. package/corpus/toolkit/src/ui/badge.tsx +37 -0
  345. package/corpus/toolkit/src/ui/breadcrumb.tsx +115 -0
  346. package/corpus/toolkit/src/ui/button.tsx +78 -0
  347. package/corpus/toolkit/src/ui/calendar.tsx +214 -0
  348. package/corpus/toolkit/src/ui/card.tsx +86 -0
  349. package/corpus/toolkit/src/ui/carousel.tsx +260 -0
  350. package/corpus/toolkit/src/ui/chart.tsx +375 -0
  351. package/corpus/toolkit/src/ui/checkbox.tsx +28 -0
  352. package/corpus/toolkit/src/ui/collapsible.tsx +9 -0
  353. package/corpus/toolkit/src/ui/command.tsx +174 -0
  354. package/corpus/toolkit/src/ui/context-menu.tsx +202 -0
  355. package/corpus/toolkit/src/ui/date-picker.tsx +64 -0
  356. package/corpus/toolkit/src/ui/dialog.tsx +146 -0
  357. package/corpus/toolkit/src/ui/drawer.tsx +126 -0
  358. package/corpus/toolkit/src/ui/dropdown-menu.tsx +218 -0
  359. package/corpus/toolkit/src/ui/form.tsx +177 -0
  360. package/corpus/toolkit/src/ui/hover-card.tsx +27 -0
  361. package/corpus/toolkit/src/ui/index.ts +52 -0
  362. package/corpus/toolkit/src/ui/input-otp.tsx +69 -0
  363. package/corpus/toolkit/src/ui/input.tsx +22 -0
  364. package/corpus/toolkit/src/ui/label.tsx +24 -0
  365. package/corpus/toolkit/src/ui/logo.tsx +36 -0
  366. package/corpus/toolkit/src/ui/menubar.tsx +235 -0
  367. package/corpus/toolkit/src/ui/navigation-menu.tsx +128 -0
  368. package/corpus/toolkit/src/ui/pagination.tsx +121 -0
  369. package/corpus/toolkit/src/ui/popover.tsx +44 -0
  370. package/corpus/toolkit/src/ui/progress.tsx +26 -0
  371. package/corpus/toolkit/src/ui/radio-group.tsx +42 -0
  372. package/corpus/toolkit/src/ui/resizable.tsx +43 -0
  373. package/corpus/toolkit/src/ui/scroll-area.tsx +46 -0
  374. package/corpus/toolkit/src/ui/select.tsx +158 -0
  375. package/corpus/toolkit/src/ui/separator.tsx +29 -0
  376. package/corpus/toolkit/src/ui/sheet.tsx +160 -0
  377. package/corpus/toolkit/src/ui/sidebar.tsx +777 -0
  378. package/corpus/toolkit/src/ui/skeleton.tsx +18 -0
  379. package/corpus/toolkit/src/ui/slider.tsx +26 -0
  380. package/corpus/toolkit/src/ui/sonner.tsx +58 -0
  381. package/corpus/toolkit/src/ui/spinner.tsx +17 -0
  382. package/corpus/toolkit/src/ui/switch.tsx +27 -0
  383. package/corpus/toolkit/src/ui/table.tsx +117 -0
  384. package/corpus/toolkit/src/ui/tabs.tsx +53 -0
  385. package/corpus/toolkit/src/ui/textarea.tsx +23 -0
  386. package/corpus/toolkit/src/ui/toast.tsx +127 -0
  387. package/corpus/toolkit/src/ui/toaster.tsx +33 -0
  388. package/corpus/toolkit/src/ui/toggle-group.tsx +59 -0
  389. package/corpus/toolkit/src/ui/toggle.tsx +43 -0
  390. package/corpus/toolkit/src/ui/tooltip.tsx +53 -0
  391. package/corpus/toolkit/src/ui/use-toast.ts +3 -0
  392. package/corpus/toolkit/src/utils.ts +8 -0
  393. package/corpus/toolkit/tsconfig.json +23 -0
  394. package/dist/cli/atomic-json-file.d.ts +30 -0
  395. package/dist/cli/atomic-json-file.d.ts.map +1 -0
  396. package/dist/cli/atomic-json-file.js +240 -0
  397. package/dist/cli/atomic-json-file.js.map +1 -0
  398. package/dist/cli/claude-code-participant.d.ts +77 -0
  399. package/dist/cli/claude-code-participant.d.ts.map +1 -0
  400. package/dist/cli/claude-code-participant.js +355 -0
  401. package/dist/cli/claude-code-participant.js.map +1 -0
  402. package/dist/cli/code-agent-executor.d.ts +8 -9
  403. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  404. package/dist/cli/code-agent-executor.js +27 -13
  405. package/dist/cli/code-agent-executor.js.map +1 -1
  406. package/dist/cli/code-agent-runs.concurrent-worker.d.ts +2 -0
  407. package/dist/cli/code-agent-runs.concurrent-worker.d.ts.map +1 -0
  408. package/dist/cli/code-agent-runs.concurrent-worker.js +32 -0
  409. package/dist/cli/code-agent-runs.concurrent-worker.js.map +1 -0
  410. package/dist/cli/code-agent-runs.d.ts +5 -0
  411. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  412. package/dist/cli/code-agent-runs.js +51 -33
  413. package/dist/cli/code-agent-runs.js.map +1 -1
  414. package/dist/cli/codex-cli-participant.d.ts +77 -0
  415. package/dist/cli/codex-cli-participant.d.ts.map +1 -0
  416. package/dist/cli/codex-cli-participant.js +354 -0
  417. package/dist/cli/codex-cli-participant.js.map +1 -0
  418. package/dist/cli/multi-frontier-runs.d.ts +246 -0
  419. package/dist/cli/multi-frontier-runs.d.ts.map +1 -0
  420. package/dist/cli/multi-frontier-runs.js +1247 -0
  421. package/dist/cli/multi-frontier-runs.js.map +1 -0
  422. package/dist/client/chat/ChatHistoryList.d.ts +1 -87
  423. package/dist/client/chat/ChatHistoryList.d.ts.map +1 -1
  424. package/dist/client/chat/ChatHistoryList.js +1 -82
  425. package/dist/client/chat/ChatHistoryList.js.map +1 -1
  426. package/dist/coding-tools/index.d.ts +1 -0
  427. package/dist/coding-tools/index.d.ts.map +1 -1
  428. package/dist/coding-tools/index.js +25 -7
  429. package/dist/coding-tools/index.js.map +1 -1
  430. package/dist/collab/awareness.d.ts +2 -2
  431. package/dist/collab/awareness.d.ts.map +1 -1
  432. package/dist/embeddings/index.d.ts +24 -0
  433. package/dist/embeddings/index.d.ts.map +1 -0
  434. package/dist/embeddings/index.js +172 -0
  435. package/dist/embeddings/index.js.map +1 -0
  436. package/dist/index.d.ts +2 -0
  437. package/dist/index.d.ts.map +1 -1
  438. package/dist/index.js +2 -0
  439. package/dist/index.js.map +1 -1
  440. package/dist/integrations/index.d.ts +2 -1
  441. package/dist/integrations/index.d.ts.map +1 -1
  442. package/dist/integrations/index.js +2 -1
  443. package/dist/integrations/index.js.map +1 -1
  444. package/dist/integrations/slack-manifest.d.ts +1 -1
  445. package/dist/integrations/slack-oauth.d.ts +1 -1
  446. package/dist/integrations/slack-oauth.d.ts.map +1 -1
  447. package/dist/integrations/slack-oauth.js +1 -0
  448. package/dist/integrations/slack-oauth.js.map +1 -1
  449. package/dist/integrations/webhook-delivery.d.ts +23 -0
  450. package/dist/integrations/webhook-delivery.d.ts.map +1 -0
  451. package/dist/integrations/webhook-delivery.js +32 -0
  452. package/dist/integrations/webhook-delivery.js.map +1 -0
  453. package/dist/notifications/channels.d.ts.map +1 -1
  454. package/dist/notifications/channels.js +4 -9
  455. package/dist/notifications/channels.js.map +1 -1
  456. package/dist/notifications/routes.d.ts +3 -3
  457. package/dist/progress/routes.d.ts +1 -1
  458. package/dist/provider-api/actions/custom-provider-registration.d.ts +136 -0
  459. package/dist/provider-api/actions/custom-provider-registration.d.ts.map +1 -0
  460. package/dist/provider-api/actions/custom-provider-registration.js +154 -0
  461. package/dist/provider-api/actions/custom-provider-registration.js.map +1 -0
  462. package/dist/provider-api/actions/delete-staged-dataset.d.ts +1 -1
  463. package/dist/provider-api/actions/delete-staged-dataset.d.ts.map +1 -1
  464. package/dist/provider-api/actions/delete-staged-dataset.js +3 -34
  465. package/dist/provider-api/actions/delete-staged-dataset.js.map +1 -1
  466. package/dist/provider-api/actions/list-staged-datasets.d.ts +2 -3
  467. package/dist/provider-api/actions/list-staged-datasets.d.ts.map +1 -1
  468. package/dist/provider-api/actions/list-staged-datasets.js +3 -40
  469. package/dist/provider-api/actions/list-staged-datasets.js.map +1 -1
  470. package/dist/provider-api/actions/provider-api-audit.d.ts +7 -0
  471. package/dist/provider-api/actions/provider-api-audit.d.ts.map +1 -0
  472. package/dist/provider-api/actions/provider-api-audit.js +74 -0
  473. package/dist/provider-api/actions/provider-api-audit.js.map +1 -0
  474. package/dist/provider-api/actions/provider-api.d.ts +370 -0
  475. package/dist/provider-api/actions/provider-api.d.ts.map +1 -0
  476. package/dist/provider-api/actions/provider-api.js +280 -0
  477. package/dist/provider-api/actions/provider-api.js.map +1 -0
  478. package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
  479. package/dist/provider-api/actions/query-staged-dataset.d.ts.map +1 -1
  480. package/dist/provider-api/actions/query-staged-dataset.js +3 -116
  481. package/dist/provider-api/actions/query-staged-dataset.js.map +1 -1
  482. package/dist/provider-api/actions/staged-datasets.d.ts +190 -0
  483. package/dist/provider-api/actions/staged-datasets.d.ts.map +1 -0
  484. package/dist/provider-api/actions/staged-datasets.js +210 -0
  485. package/dist/provider-api/actions/staged-datasets.js.map +1 -0
  486. package/dist/provider-api/gong.d.ts +44 -0
  487. package/dist/provider-api/gong.d.ts.map +1 -0
  488. package/dist/provider-api/gong.js +56 -0
  489. package/dist/provider-api/gong.js.map +1 -0
  490. package/dist/resources/handlers.d.ts +1 -1
  491. package/dist/scripts/docs/source-search.d.ts +2 -1
  492. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  493. package/dist/scripts/docs/source-search.js +2 -1
  494. package/dist/scripts/docs/source-search.js.map +1 -1
  495. package/dist/search/index.d.ts +88 -0
  496. package/dist/search/index.d.ts.map +1 -0
  497. package/dist/search/index.js +267 -0
  498. package/dist/search/index.js.map +1 -0
  499. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  500. package/dist/server/google-oauth-credentials.d.ts +35 -0
  501. package/dist/server/google-oauth-credentials.d.ts.map +1 -1
  502. package/dist/server/google-oauth-credentials.js +48 -2
  503. package/dist/server/google-oauth-credentials.js.map +1 -1
  504. package/dist/server/index.d.ts +1 -1
  505. package/dist/server/index.d.ts.map +1 -1
  506. package/dist/server/index.js +1 -1
  507. package/dist/server/index.js.map +1 -1
  508. package/dist/styles/chat-history-list.css +1 -313
  509. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  510. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  511. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  512. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  513. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  514. package/dist/templates/chat/AGENTS.md +5 -2
  515. package/dist/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  516. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -12
  517. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  518. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  519. package/dist/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  520. package/dist/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  521. package/dist/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  522. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  523. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  524. package/dist/templates/default/AGENTS.md +25 -18
  525. package/dist/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  526. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  527. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  528. package/dist/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  529. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  530. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  531. package/dist/templates/headless/AGENTS.md +7 -0
  532. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  533. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  534. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  535. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  536. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  537. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  538. package/dist/templates/workspace-core/AGENTS.md +4 -0
  539. package/dist/templates/workspace-root/AGENTS.md +4 -0
  540. package/docs/AGENTS.md +7 -0
  541. package/docs/content/integrations.mdx +63 -2
  542. package/docs/design/provider-integration-authority.md +117 -0
  543. package/package.json +9 -2
  544. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  545. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +10 -0
  546. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  547. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +11 -2
  548. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  549. package/src/templates/chat/AGENTS.md +5 -2
  550. package/src/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  551. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  552. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +10 -0
  553. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  554. package/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  555. package/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  556. package/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  557. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +11 -2
  558. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  559. package/src/templates/default/AGENTS.md +25 -18
  560. package/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  561. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +10 -0
  562. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  563. package/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  564. package/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  565. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  566. package/src/templates/headless/AGENTS.md +7 -0
  567. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  568. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +10 -0
  569. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  570. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +102 -0
  571. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +11 -2
  572. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  573. package/src/templates/workspace-core/AGENTS.md +4 -0
  574. 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"
@@ -116,6 +122,11 @@ export interface CreateCodeAgentRunInput {
116
122
  }
117
123
 
118
124
  export interface AppendCodeAgentTranscriptEventInput {
125
+ /**
126
+ * Stable event identity supplied by a retrying caller. Reusing this value
127
+ * returns the previously persisted event instead of appending a duplicate.
128
+ */
129
+ id?: string;
119
130
  runId: string;
120
131
  kind: CodeAgentTranscriptEventKind;
121
132
  message: string;
@@ -189,14 +200,12 @@ export function readCodeAgentCommandAllowlist(): string[] {
189
200
  * are auto-approved without a prompt. Deduplicates by exact string match.
190
201
  */
191
202
  export function addCodeAgentCommandToAllowlist(command: string): void {
192
- const current = readCodeAgentCommandAllowlist();
193
- if (current.includes(command)) return;
194
- const next = [...current, command];
195
- fs.mkdirSync(codeAgentStoreRoot(), { recursive: true });
196
- fs.writeFileSync(
197
- codeAgentCommandAllowlistPath(),
198
- JSON.stringify(next, null, 2),
199
- );
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
+ });
200
209
  }
201
210
 
202
211
  /** Return true if `command` is in the stored allowlist. */
@@ -242,11 +251,8 @@ export function normalizeCodeAgentPermissionMode(
242
251
  }
243
252
 
244
253
  export function writeCodeAgentRunRecord(record: CodeAgentRunRecord): void {
245
- fs.mkdirSync(codeAgentRunsDir(), { recursive: true });
246
- fs.writeFileSync(
247
- codeAgentRunRecordPath(record.id),
248
- `${JSON.stringify(record, null, 2)}\n`,
249
- );
254
+ const filePath = codeAgentRunRecordPath(record.id);
255
+ withFileLockSync(filePath, () => writeJsonFileAtomically(filePath, record));
250
256
  }
251
257
 
252
258
  export function getCodeAgentRunRecord(
@@ -261,20 +267,23 @@ export function updateCodeAgentRunRecord(
261
267
  | Partial<CodeAgentRunRecord>
262
268
  | ((record: CodeAgentRunRecord) => Partial<CodeAgentRunRecord>),
263
269
  ): CodeAgentRunRecord | null {
264
- const record = getCodeAgentRunRecord(runId);
265
- if (!record) return null;
266
- const patch = typeof updates === "function" ? updates(record) : updates;
267
- const next: CodeAgentRunRecord = {
268
- ...record,
269
- ...patch,
270
- metadata: {
271
- ...(record.metadata ?? {}),
272
- ...(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
+ };
273
285
  },
274
- updatedAt: patch.updatedAt ?? new Date().toISOString(),
275
- };
276
- writeCodeAgentRunRecord(next);
277
- return next;
286
+ );
278
287
  }
279
288
 
280
289
  export function listCodeAgentRunRecords(goalId?: string): CodeAgentRunRecord[] {
@@ -298,10 +307,19 @@ export function getLastCodeAgentRunRecord(
298
307
  export function appendCodeAgentTranscriptEvent(
299
308
  input: AppendCodeAgentTranscriptEventInput,
300
309
  ): CodeAgentTranscriptEvent {
310
+ const requestedId = input.id?.trim();
311
+ if (requestedId) {
312
+ const existing = listCodeAgentTranscriptEvents(input.runId).find(
313
+ (event) => event.id === requestedId,
314
+ );
315
+ if (existing) return existing;
316
+ }
301
317
  const createdAt = input.createdAt ?? new Date().toISOString();
302
318
  const event: CodeAgentTranscriptEvent = {
303
319
  schemaVersion: 1,
304
- id: `evt-${timestampSlug(createdAt)}-${crypto.randomUUID().slice(0, 8)}`,
320
+ id:
321
+ requestedId ??
322
+ `evt-${timestampSlug(createdAt)}-${crypto.randomUUID().slice(0, 8)}`,
305
323
  runId: input.runId,
306
324
  kind: input.kind,
307
325
  message: input.message,
@@ -310,13 +328,13 @@ export function appendCodeAgentTranscriptEvent(
310
328
  ...(input.signal ? { signal: input.signal } : {}),
311
329
  };
312
330
 
313
- fs.mkdirSync(codeAgentTranscriptsDir(), { recursive: true });
314
- fs.appendFileSync(
331
+ const persisted = appendUniqueJsonLineAtomically(
315
332
  codeAgentRunTranscriptPath(input.runId),
316
- `${JSON.stringify(event)}\n`,
333
+ event,
334
+ readTranscriptValue,
317
335
  );
318
336
  touchCodeAgentRunRecord(input.runId, createdAt);
319
- return event;
337
+ return persisted.value;
320
338
  }
321
339
 
322
340
  export function listCodeAgentTranscriptEvents(
@@ -417,14 +435,23 @@ function readPendingFollowUps(value: unknown): CodeAgentPendingFollowUp[] {
417
435
  }
418
436
 
419
437
  function touchCodeAgentRunRecord(runId: string, updatedAt: string): void {
420
- const record = readRunFile(codeAgentRunRecordPath(runId));
421
- if (!record) return;
422
- writeCodeAgentRunRecord({ ...record, updatedAt });
438
+ updateJsonFileAtomically(
439
+ codeAgentRunRecordPath(runId),
440
+ readRunValue,
441
+ (record) => (record ? { ...record, updatedAt } : null),
442
+ );
423
443
  }
424
444
 
425
445
  function readRunFile(filePath: string): CodeAgentRunRecord | null {
426
446
  try {
427
- 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 {
428
455
  if (!raw || typeof raw !== "object") return null;
429
456
  const record = raw as Partial<CodeAgentRunRecord>;
430
457
  if (
@@ -447,7 +474,14 @@ function readRunFile(filePath: string): CodeAgentRunRecord | null {
447
474
 
448
475
  function readTranscriptLine(line: string): CodeAgentTranscriptEvent | null {
449
476
  try {
450
- 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 {
451
485
  if (!raw || typeof raw !== "object") return null;
452
486
  const event = raw as Partial<CodeAgentTranscriptEvent> & {
453
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;