@alumbwe/anvil 1.0.20 → 1.0.22

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 (328) hide show
  1. package/package.json +74 -70
  2. package/src/agents/bundled-agents.generated.ts +4 -4
  3. package/src/chat.tsx +1703 -1698
  4. package/src/cli-args.ts +134 -134
  5. package/src/components/status-bar.tsx +331 -313
  6. package/src/hooks/helpers/send-message.ts +663 -654
  7. package/src/hooks/use-send-message.ts +806 -773
  8. package/src/index.tsx +473 -473
  9. package/src/state/chat-store.ts +553 -544
  10. package/src/utils/create-run-config.ts +121 -121
  11. package/src/utils/format-compact-number.ts +37 -0
  12. package/vendor/@anvil/common/package.json +27 -0
  13. package/vendor/@anvil/common/src/__tests__/agent-validation.test.ts +846 -0
  14. package/vendor/@anvil/common/src/__tests__/anvil-model-availability.test.ts +101 -0
  15. package/vendor/@anvil/common/src/__tests__/anvil-models.test.ts +1408 -0
  16. package/vendor/@anvil/common/src/__tests__/anvil-public-data-use-copy.test.ts +258 -0
  17. package/vendor/@anvil/common/src/__tests__/anvil-referral-tiers.test.ts +48 -0
  18. package/vendor/@anvil/common/src/__tests__/anvil-spend-ceilings.test.ts +282 -0
  19. package/vendor/@anvil/common/src/__tests__/anvil-trust.test.ts +526 -0
  20. package/vendor/@anvil/common/src/__tests__/deepseek-direct.test.ts +68 -0
  21. package/vendor/@anvil/common/src/__tests__/disposable-email.test.ts +132 -0
  22. package/vendor/@anvil/common/src/__tests__/dynamic-agent-template-schema.test.ts +422 -0
  23. package/vendor/@anvil/common/src/__tests__/env-ci.test.ts +167 -0
  24. package/vendor/@anvil/common/src/__tests__/env-process.test.ts +145 -0
  25. package/vendor/@anvil/common/src/__tests__/foreign-client-shipped-agents.test.ts +234 -0
  26. package/vendor/@anvil/common/src/__tests__/foreign-client-signals.test.ts +379 -0
  27. package/vendor/@anvil/common/src/__tests__/free-agents.test.ts +807 -0
  28. package/vendor/@anvil/common/src/__tests__/gravity-capi.test.ts +154 -0
  29. package/vendor/@anvil/common/src/__tests__/handlesteps-parsing.test.ts +246 -0
  30. package/vendor/@anvil/common/src/__tests__/kimi-k3-god-only.test.ts +77 -0
  31. package/vendor/@anvil/common/src/__tests__/model-config.test.ts +89 -0
  32. package/vendor/@anvil/common/src/__tests__/project-file-tree.test.ts +298 -0
  33. package/vendor/@anvil/common/src/__tests__/provisioned-model-tiers.test.ts +116 -0
  34. package/vendor/@anvil/common/src/__tests__/reasoning-effort.test.ts +167 -0
  35. package/vendor/@anvil/common/src/__tests__/reddit-capi.test.ts +132 -0
  36. package/vendor/@anvil/common/src/__tests__/response-ad-positions.test.ts +72 -0
  37. package/vendor/@anvil/common/src/__tests__/user-state.test.ts +30 -0
  38. package/vendor/@anvil/common/src/actions.ts +215 -0
  39. package/vendor/@anvil/common/src/analytics-core.ts +69 -0
  40. package/vendor/@anvil/common/src/analytics.ts +93 -0
  41. package/vendor/@anvil/common/src/api-keys/constants.ts +26 -0
  42. package/vendor/@anvil/common/src/browser-actions.ts +413 -0
  43. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding-gate.test.ts +63 -0
  44. package/vendor/@anvil/common/src/constants/__tests__/anvil-onboarding.test.ts +246 -0
  45. package/vendor/@anvil/common/src/constants/__tests__/cf-worker-signals.test.ts +106 -0
  46. package/vendor/@anvil/common/src/constants/agents.ts +99 -0
  47. package/vendor/@anvil/common/src/constants/analytics-events.ts +435 -0
  48. package/vendor/@anvil/common/src/constants/anthropic.ts +73 -0
  49. package/vendor/@anvil/common/src/constants/anvil-data-use.ts +81 -0
  50. package/vendor/@anvil/common/src/constants/anvil-errors.ts +7 -0
  51. package/vendor/@anvil/common/src/constants/anvil-gemini-thinker.ts +21 -0
  52. package/vendor/@anvil/common/src/constants/anvil-model-ids.ts +11 -0
  53. package/vendor/@anvil/common/src/constants/anvil-models.ts +2130 -0
  54. package/vendor/@anvil/common/src/constants/anvil-onboarding-gate.ts +55 -0
  55. package/vendor/@anvil/common/src/constants/anvil-onboarding.ts +307 -0
  56. package/vendor/@anvil/common/src/constants/anvil-referral-tiers.ts +87 -0
  57. package/vendor/@anvil/common/src/constants/anvil-signup-block.ts +68 -0
  58. package/vendor/@anvil/common/src/constants/anvil-spend-ceilings.ts +450 -0
  59. package/vendor/@anvil/common/src/constants/anvil-trust.ts +976 -0
  60. package/vendor/@anvil/common/src/constants/auth.ts +18 -0
  61. package/vendor/@anvil/common/src/constants/byok.ts +2 -0
  62. package/vendor/@anvil/common/src/constants/cf-worker-signals.ts +132 -0
  63. package/vendor/@anvil/common/src/constants/composio.ts +34 -0
  64. package/vendor/@anvil/common/src/constants/deepseek-direct.ts +55 -0
  65. package/vendor/@anvil/common/src/constants/feedback.ts +13 -0
  66. package/vendor/@anvil/common/src/constants/foreign-client-signals.ts +272 -0
  67. package/vendor/@anvil/common/src/constants/free-agents.ts +777 -0
  68. package/vendor/@anvil/common/src/constants/gemini.ts +15 -0
  69. package/vendor/@anvil/common/src/constants/grant-priorities.ts +13 -0
  70. package/vendor/@anvil/common/src/constants/hosts.ts +6 -0
  71. package/vendor/@anvil/common/src/constants/images.ts +51 -0
  72. package/vendor/@anvil/common/src/constants/index.ts +7 -0
  73. package/vendor/@anvil/common/src/constants/knowledge.ts +35 -0
  74. package/vendor/@anvil/common/src/constants/limits.ts +23 -0
  75. package/vendor/@anvil/common/src/constants/model-config.ts +277 -0
  76. package/vendor/@anvil/common/src/constants/openrouter-attribution.ts +8 -0
  77. package/vendor/@anvil/common/src/constants/paths.ts +69 -0
  78. package/vendor/@anvil/common/src/constants/provider-routes.ts +317 -0
  79. package/vendor/@anvil/common/src/constants/reasoning-effort.ts +79 -0
  80. package/vendor/@anvil/common/src/constants/skills.ts +60 -0
  81. package/vendor/@anvil/common/src/constants/subscription-plans.ts +49 -0
  82. package/vendor/@anvil/common/src/constants/ui.ts +25 -0
  83. package/vendor/@anvil/common/src/env-ci.ts +36 -0
  84. package/vendor/@anvil/common/src/env-process.ts +95 -0
  85. package/vendor/@anvil/common/src/env-schema.ts +95 -0
  86. package/vendor/@anvil/common/src/env.ts +24 -0
  87. package/vendor/@anvil/common/src/gravity-capi.ts +207 -0
  88. package/vendor/@anvil/common/src/mcp/client.ts +233 -0
  89. package/vendor/@anvil/common/src/old-constants.ts +10 -0
  90. package/vendor/@anvil/common/src/project-file-tree.ts +355 -0
  91. package/vendor/@anvil/common/src/reddit-capi.ts +254 -0
  92. package/vendor/@anvil/common/src/schemas/feedback.ts +52 -0
  93. package/vendor/@anvil/common/src/schemas/logs.ts +66 -0
  94. package/vendor/@anvil/common/src/templates/agent-validation.ts +392 -0
  95. package/vendor/@anvil/common/src/templates/initial-agents-dir/LICENSE +202 -0
  96. package/vendor/@anvil/common/src/templates/initial-agents-dir/README.md +294 -0
  97. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/01-basic-diff-reviewer.ts +17 -0
  98. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/02-intermediate-git-committer.ts +78 -0
  99. package/vendor/@anvil/common/src/templates/initial-agents-dir/examples/03-advanced-file-explorer.ts +73 -0
  100. package/vendor/@anvil/common/src/templates/initial-agents-dir/my-custom-agent.ts +40 -0
  101. package/vendor/@anvil/common/src/templates/initial-agents-dir/package.json +6 -0
  102. package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/README.md +65 -0
  103. package/vendor/@anvil/common/src/templates/initial-agents-dir/skills/example-skill/SKILL.md +29 -0
  104. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/agent-definition.ts +497 -0
  105. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/tools.ts +444 -0
  106. package/vendor/@anvil/common/src/templates/initial-agents-dir/types/util-types.ts +178 -0
  107. package/vendor/@anvil/common/src/testing/TESTING_PATTERNS.md +351 -0
  108. package/vendor/@anvil/common/src/testing/anvil-offer-invariants.ts +169 -0
  109. package/vendor/@anvil/common/src/testing/errors.ts +33 -0
  110. package/vendor/@anvil/common/src/testing/fixtures/agent-runtime.ts +334 -0
  111. package/vendor/@anvil/common/src/testing/impl/agent-runtime.ts +6 -0
  112. package/vendor/@anvil/common/src/testing/index.ts +84 -0
  113. package/vendor/@anvil/common/src/testing/mock-modules.ts +53 -0
  114. package/vendor/@anvil/common/src/testing/mock-types.ts +123 -0
  115. package/vendor/@anvil/common/src/testing/mocks/analytics.ts +261 -0
  116. package/vendor/@anvil/common/src/testing/mocks/child-process.ts +93 -0
  117. package/vendor/@anvil/common/src/testing/mocks/crypto.ts +218 -0
  118. package/vendor/@anvil/common/src/testing/mocks/database.ts +337 -0
  119. package/vendor/@anvil/common/src/testing/mocks/fetch.ts +219 -0
  120. package/vendor/@anvil/common/src/testing/mocks/filesystem.ts +166 -0
  121. package/vendor/@anvil/common/src/testing/mocks/index.ts +101 -0
  122. package/vendor/@anvil/common/src/testing/mocks/logger.ts +135 -0
  123. package/vendor/@anvil/common/src/testing/mocks/stream.ts +313 -0
  124. package/vendor/@anvil/common/src/testing/mocks/timers.ts +132 -0
  125. package/vendor/@anvil/common/src/testing/mocks/tree-sitter.ts +127 -0
  126. package/vendor/@anvil/common/src/testing/setup.ts +282 -0
  127. package/vendor/@anvil/common/src/testing-env-ci.ts +15 -0
  128. package/vendor/@anvil/common/src/testing-env-process.ts +78 -0
  129. package/vendor/@anvil/common/src/tools/__tests__/compile-tool-definitions.test.ts +34 -0
  130. package/vendor/@anvil/common/src/tools/compile-tool-definitions.ts +157 -0
  131. package/vendor/@anvil/common/src/tools/constants.ts +117 -0
  132. package/vendor/@anvil/common/src/tools/list.ts +190 -0
  133. package/vendor/@anvil/common/src/tools/params/__tests__/coerce-to-array.test.ts +213 -0
  134. package/vendor/@anvil/common/src/tools/params/__tests__/read-docs.test.ts +47 -0
  135. package/vendor/@anvil/common/src/tools/params/__tests__/render-ui.test.ts +65 -0
  136. package/vendor/@anvil/common/src/tools/params/tool/__tests__/run-terminal-command-timeout.test.ts +49 -0
  137. package/vendor/@anvil/common/src/tools/params/tool/add-message.ts +39 -0
  138. package/vendor/@anvil/common/src/tools/params/tool/add-subgoal.ts +57 -0
  139. package/vendor/@anvil/common/src/tools/params/tool/apply-patch.ts +110 -0
  140. package/vendor/@anvil/common/src/tools/params/tool/ask-user.ts +181 -0
  141. package/vendor/@anvil/common/src/tools/params/tool/browser-logs.ts +85 -0
  142. package/vendor/@anvil/common/src/tools/params/tool/cloud-plan-ready.ts +94 -0
  143. package/vendor/@anvil/common/src/tools/params/tool/code-search.ts +159 -0
  144. package/vendor/@anvil/common/src/tools/params/tool/composio.ts +131 -0
  145. package/vendor/@anvil/common/src/tools/params/tool/create-plan.ts +80 -0
  146. package/vendor/@anvil/common/src/tools/params/tool/end-turn.ts +57 -0
  147. package/vendor/@anvil/common/src/tools/params/tool/find-files.ts +60 -0
  148. package/vendor/@anvil/common/src/tools/params/tool/glob.ts +80 -0
  149. package/vendor/@anvil/common/src/tools/params/tool/gravity-index.ts +93 -0
  150. package/vendor/@anvil/common/src/tools/params/tool/list-directory.ts +58 -0
  151. package/vendor/@anvil/common/src/tools/params/tool/lookup-agent-info.ts +37 -0
  152. package/vendor/@anvil/common/src/tools/params/tool/propose-str-replace.ts +103 -0
  153. package/vendor/@anvil/common/src/tools/params/tool/propose-write-file.ts +71 -0
  154. package/vendor/@anvil/common/src/tools/params/tool/read-docs.ts +90 -0
  155. package/vendor/@anvil/common/src/tools/params/tool/read-files.ts +109 -0
  156. package/vendor/@anvil/common/src/tools/params/tool/read-subtree.ts +79 -0
  157. package/vendor/@anvil/common/src/tools/params/tool/read-url.ts +81 -0
  158. package/vendor/@anvil/common/src/tools/params/tool/render-ui.ts +168 -0
  159. package/vendor/@anvil/common/src/tools/params/tool/run-file-change-hooks.ts +57 -0
  160. package/vendor/@anvil/common/src/tools/params/tool/run-terminal-command.ts +211 -0
  161. package/vendor/@anvil/common/src/tools/params/tool/screenshot.ts +97 -0
  162. package/vendor/@anvil/common/src/tools/params/tool/set-messages.ts +44 -0
  163. package/vendor/@anvil/common/src/tools/params/tool/set-output.ts +61 -0
  164. package/vendor/@anvil/common/src/tools/params/tool/skill.ts +59 -0
  165. package/vendor/@anvil/common/src/tools/params/tool/spawn-agent-inline.ts +56 -0
  166. package/vendor/@anvil/common/src/tools/params/tool/spawn-agents.ts +154 -0
  167. package/vendor/@anvil/common/src/tools/params/tool/str-replace.ts +107 -0
  168. package/vendor/@anvil/common/src/tools/params/tool/suggest-followups.ts +97 -0
  169. package/vendor/@anvil/common/src/tools/params/tool/task-completed.ts +61 -0
  170. package/vendor/@anvil/common/src/tools/params/tool/think-deeply.ts +56 -0
  171. package/vendor/@anvil/common/src/tools/params/tool/update-subgoal.ts +89 -0
  172. package/vendor/@anvil/common/src/tools/params/tool/vision-analyze.ts +82 -0
  173. package/vendor/@anvil/common/src/tools/params/tool/web-search.ts +73 -0
  174. package/vendor/@anvil/common/src/tools/params/tool/write-file.ts +71 -0
  175. package/vendor/@anvil/common/src/tools/params/tool/write-todos.ts +67 -0
  176. package/vendor/@anvil/common/src/tools/params/utils.ts +150 -0
  177. package/vendor/@anvil/common/src/tools/utils.ts +24 -0
  178. package/vendor/@anvil/common/src/types/__tests__/dynamic-agent-template.test.ts +20 -0
  179. package/vendor/@anvil/common/src/types/agent-template.ts +215 -0
  180. package/vendor/@anvil/common/src/types/anvil-session.ts +535 -0
  181. package/vendor/@anvil/common/src/types/anvil-streak.ts +6 -0
  182. package/vendor/@anvil/common/src/types/anvil-usage.ts +64 -0
  183. package/vendor/@anvil/common/src/types/api/agents/publish.ts +61 -0
  184. package/vendor/@anvil/common/src/types/bun-test.d.ts +5 -0
  185. package/vendor/@anvil/common/src/types/contracts/agent-runtime.ts +75 -0
  186. package/vendor/@anvil/common/src/types/contracts/analytics.ts +9 -0
  187. package/vendor/@anvil/common/src/types/contracts/bigquery.ts +55 -0
  188. package/vendor/@anvil/common/src/types/contracts/billing.ts +46 -0
  189. package/vendor/@anvil/common/src/types/contracts/client.ts +53 -0
  190. package/vendor/@anvil/common/src/types/contracts/database.ts +112 -0
  191. package/vendor/@anvil/common/src/types/contracts/env.ts +203 -0
  192. package/vendor/@anvil/common/src/types/contracts/llm.ts +191 -0
  193. package/vendor/@anvil/common/src/types/contracts/logger.ts +14 -0
  194. package/vendor/@anvil/common/src/types/contracts/logs.ts +34 -0
  195. package/vendor/@anvil/common/src/types/contracts/trace.ts +21 -0
  196. package/vendor/@anvil/common/src/types/dynamic-agent-template.ts +328 -0
  197. package/vendor/@anvil/common/src/types/filesystem.ts +10 -0
  198. package/vendor/@anvil/common/src/types/function-params.ts +33 -0
  199. package/vendor/@anvil/common/src/types/grant.ts +20 -0
  200. package/vendor/@anvil/common/src/types/gravity-index.ts +170 -0
  201. package/vendor/@anvil/common/src/types/json.ts +29 -0
  202. package/vendor/@anvil/common/src/types/mcp.ts +24 -0
  203. package/vendor/@anvil/common/src/types/messages/anvil-message.ts +58 -0
  204. package/vendor/@anvil/common/src/types/messages/content-part.ts +59 -0
  205. package/vendor/@anvil/common/src/types/messages/data-content.ts +14 -0
  206. package/vendor/@anvil/common/src/types/messages/provider-metadata.ts +13 -0
  207. package/vendor/@anvil/common/src/types/organization.ts +118 -0
  208. package/vendor/@anvil/common/src/types/print-mode.ts +121 -0
  209. package/vendor/@anvil/common/src/types/publisher.ts +67 -0
  210. package/vendor/@anvil/common/src/types/session-state.ts +149 -0
  211. package/vendor/@anvil/common/src/types/skill.ts +86 -0
  212. package/vendor/@anvil/common/src/types/source.ts +11 -0
  213. package/vendor/@anvil/common/src/types/spawn.ts +13 -0
  214. package/vendor/@anvil/common/src/types/subscription.ts +67 -0
  215. package/vendor/@anvil/common/src/types/usage.ts +16 -0
  216. package/vendor/@anvil/common/src/types/util.ts +3 -0
  217. package/vendor/@anvil/common/src/util/__tests__/ad-user-agent.test.ts +26 -0
  218. package/vendor/@anvil/common/src/util/__tests__/analytics-dispatcher.test.ts +122 -0
  219. package/vendor/@anvil/common/src/util/__tests__/analytics-log.test.ts +102 -0
  220. package/vendor/@anvil/common/src/util/__tests__/analytics-sampling.test.ts +143 -0
  221. package/vendor/@anvil/common/src/util/__tests__/anvil-streak.test.ts +202 -0
  222. package/vendor/@anvil/common/src/util/__tests__/anvil-usage-summary.test.ts +193 -0
  223. package/vendor/@anvil/common/src/util/__tests__/axiom-only-log.test.ts +140 -0
  224. package/vendor/@anvil/common/src/util/__tests__/client-user-agent.test.ts +148 -0
  225. package/vendor/@anvil/common/src/util/__tests__/engagement-tracker.test.ts +115 -0
  226. package/vendor/@anvil/common/src/util/__tests__/env-file-path.test.ts +57 -0
  227. package/vendor/@anvil/common/src/util/__tests__/error-abort.test.ts +774 -0
  228. package/vendor/@anvil/common/src/util/__tests__/error-api-details.test.ts +206 -0
  229. package/vendor/@anvil/common/src/util/__tests__/file-read-limits.test.ts +173 -0
  230. package/vendor/@anvil/common/src/util/__tests__/format-code-search.test.ts +60 -0
  231. package/vendor/@anvil/common/src/util/__tests__/log-mirror.test.ts +31 -0
  232. package/vendor/@anvil/common/src/util/__tests__/messages.test.ts +1252 -0
  233. package/vendor/@anvil/common/src/util/__tests__/partial-json-delta.test.ts +505 -0
  234. package/vendor/@anvil/common/src/util/__tests__/path.test.ts +22 -0
  235. package/vendor/@anvil/common/src/util/__tests__/project-ignore.test.ts +90 -0
  236. package/vendor/@anvil/common/src/util/__tests__/promise.test.ts +325 -0
  237. package/vendor/@anvil/common/src/util/__tests__/rate-limit.test.ts +28 -0
  238. package/vendor/@anvil/common/src/util/__tests__/reddit-anvil-retention.test.ts +130 -0
  239. package/vendor/@anvil/common/src/util/__tests__/saxy.test.ts +1008 -0
  240. package/vendor/@anvil/common/src/util/__tests__/split-data.test.ts +289 -0
  241. package/vendor/@anvil/common/src/util/__tests__/string.test.ts +239 -0
  242. package/vendor/@anvil/common/src/util/__tests__/thread-title.test.ts +70 -0
  243. package/vendor/@anvil/common/src/util/__tests__/tool-result-media-order.test.ts +108 -0
  244. package/vendor/@anvil/common/src/util/__tests__/ttft-histogram.test.ts +180 -0
  245. package/vendor/@anvil/common/src/util/__tests__/with-timeout.test.ts +24 -0
  246. package/vendor/@anvil/common/src/util/__tests__/zoned-time.test.ts +88 -0
  247. package/vendor/@anvil/common/src/util/ad-user-agent.ts +25 -0
  248. package/vendor/@anvil/common/src/util/agent-file-utils.ts +110 -0
  249. package/vendor/@anvil/common/src/util/agent-id-parsing.ts +136 -0
  250. package/vendor/@anvil/common/src/util/agent-name-normalization.ts +38 -0
  251. package/vendor/@anvil/common/src/util/agent-name-resolver.ts +86 -0
  252. package/vendor/@anvil/common/src/util/analytics-dispatcher.ts +82 -0
  253. package/vendor/@anvil/common/src/util/analytics-log.ts +78 -0
  254. package/vendor/@anvil/common/src/util/analytics-sampling.ts +255 -0
  255. package/vendor/@anvil/common/src/util/anvil-model-availability.ts +102 -0
  256. package/vendor/@anvil/common/src/util/anvil-privacy.ts +82 -0
  257. package/vendor/@anvil/common/src/util/anvil-streak-line.ts +103 -0
  258. package/vendor/@anvil/common/src/util/anvil-streak.ts +156 -0
  259. package/vendor/@anvil/common/src/util/anvil-usage-summary.ts +125 -0
  260. package/vendor/@anvil/common/src/util/array.ts +31 -0
  261. package/vendor/@anvil/common/src/util/axiom-only-log.ts +124 -0
  262. package/vendor/@anvil/common/src/util/cache-debug.ts +171 -0
  263. package/vendor/@anvil/common/src/util/client-user-agent.ts +114 -0
  264. package/vendor/@anvil/common/src/util/credentials.ts +26 -0
  265. package/vendor/@anvil/common/src/util/currency.ts +25 -0
  266. package/vendor/@anvil/common/src/util/dates.ts +81 -0
  267. package/vendor/@anvil/common/src/util/disposable-email.ts +277 -0
  268. package/vendor/@anvil/common/src/util/engagement-tracker.ts +129 -0
  269. package/vendor/@anvil/common/src/util/env-file-path.ts +40 -0
  270. package/vendor/@anvil/common/src/util/error.ts +562 -0
  271. package/vendor/@anvil/common/src/util/file-read-limits.ts +236 -0
  272. package/vendor/@anvil/common/src/util/file.ts +339 -0
  273. package/vendor/@anvil/common/src/util/format-code-search.ts +115 -0
  274. package/vendor/@anvil/common/src/util/lazy-response-ads.ts +92 -0
  275. package/vendor/@anvil/common/src/util/log-data.ts +57 -0
  276. package/vendor/@anvil/common/src/util/log-ingest.ts +58 -0
  277. package/vendor/@anvil/common/src/util/log-mirror.ts +34 -0
  278. package/vendor/@anvil/common/src/util/lru-cache.ts +67 -0
  279. package/vendor/@anvil/common/src/util/messages.ts +685 -0
  280. package/vendor/@anvil/common/src/util/min-heap.ts +87 -0
  281. package/vendor/@anvil/common/src/util/model-utils.ts +4 -0
  282. package/vendor/@anvil/common/src/util/object.ts +128 -0
  283. package/vendor/@anvil/common/src/util/partial-json-delta.ts +89 -0
  284. package/vendor/@anvil/common/src/util/path.ts +15 -0
  285. package/vendor/@anvil/common/src/util/project-ignore.ts +119 -0
  286. package/vendor/@anvil/common/src/util/promise.ts +73 -0
  287. package/vendor/@anvil/common/src/util/random.ts +15 -0
  288. package/vendor/@anvil/common/src/util/rate-limit.ts +56 -0
  289. package/vendor/@anvil/common/src/util/reddit-anvil-retention.ts +60 -0
  290. package/vendor/@anvil/common/src/util/reddit-capi-events.ts +36 -0
  291. package/vendor/@anvil/common/src/util/response-ad-positions.ts +54 -0
  292. package/vendor/@anvil/common/src/util/saxy.ts +741 -0
  293. package/vendor/@anvil/common/src/util/skills.test.ts +44 -0
  294. package/vendor/@anvil/common/src/util/skills.ts +36 -0
  295. package/vendor/@anvil/common/src/util/split-data.ts +259 -0
  296. package/vendor/@anvil/common/src/util/stop-sequence.ts +61 -0
  297. package/vendor/@anvil/common/src/util/string.ts +426 -0
  298. package/vendor/@anvil/common/src/util/system-info.ts +53 -0
  299. package/vendor/@anvil/common/src/util/thread-title.ts +46 -0
  300. package/vendor/@anvil/common/src/util/ttft-histogram.ts +73 -0
  301. package/vendor/@anvil/common/src/util/xml-parser.ts +27 -0
  302. package/vendor/@anvil/common/src/util/xml.ts +17 -0
  303. package/vendor/@anvil/common/src/util/zod-schema.ts +25 -0
  304. package/vendor/@anvil/common/src/util/zoned-time.ts +136 -0
  305. package/vendor/@anvil/common/src/utils/ask-user-bridge.ts +44 -0
  306. package/vendor/@anvil/sdk/dist/index.cjs +52297 -0
  307. package/vendor/@anvil/sdk/dist/index.cjs.map +440 -0
  308. package/vendor/@anvil/sdk/dist/index.d.ts +4277 -0
  309. package/vendor/@anvil/sdk/dist/index.mjs +52290 -0
  310. package/vendor/@anvil/sdk/dist/index.mjs.map +440 -0
  311. package/vendor/@anvil/sdk/dist/vendor/ai.cjs +30886 -0
  312. package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-darwin/rg +0 -0
  313. package/vendor/@anvil/sdk/dist/vendor/ripgrep/arm64-linux/rg +0 -0
  314. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-darwin/rg +0 -0
  315. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-linux/rg +0 -0
  316. package/vendor/@anvil/sdk/dist/vendor/ripgrep/x64-win32/rg.exe +0 -0
  317. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-c-sharp.wasm +0 -0
  318. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-cpp.wasm +0 -0
  319. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-go.wasm +0 -0
  320. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-java.wasm +0 -0
  321. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-javascript.wasm +0 -0
  322. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-python.wasm +0 -0
  323. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-ruby.wasm +0 -0
  324. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-rust.wasm +0 -0
  325. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-tsx.wasm +0 -0
  326. package/vendor/@anvil/sdk/dist/wasm/tree-sitter-typescript.wasm +0 -0
  327. package/vendor/@anvil/sdk/dist/wasm/tree-sitter.wasm +0 -0
  328. package/vendor/@anvil/sdk/package.json +21 -0
@@ -0,0 +1,149 @@
1
+ import { z } from 'zod/v4'
2
+
3
+ import { MAX_AGENT_STEPS_DEFAULT } from '../constants/agents'
4
+
5
+ import type { Message } from './messages/anvil-message'
6
+ import type { ProjectFileContext } from '../util/file'
7
+
8
+ export const toolCallSchema = z.object({
9
+ toolName: z.string(),
10
+ toolCallId: z.string(),
11
+ input: z.record(z.string(), z.any()),
12
+ })
13
+ export type ToolCall = z.infer<typeof toolCallSchema>
14
+
15
+ export const subgoalSchema = z.object({
16
+ objective: z.string().optional(),
17
+ status: z
18
+ .enum(['NOT_STARTED', 'IN_PROGRESS', 'COMPLETE', 'ABORTED'])
19
+ .optional(),
20
+ plan: z.string().optional(),
21
+ logs: z.string().array(),
22
+ })
23
+ export type Subgoal = z.infer<typeof subgoalSchema>
24
+
25
+ export type AgentState = {
26
+ /**
27
+ * @deprecated agentId is replaced by runId
28
+ */
29
+ agentId: string
30
+ agentType: AgentTemplateType | null
31
+ agentContext: Record<string, Subgoal>
32
+ ancestorRunIds: string[]
33
+ runId?: string
34
+ subagents: AgentState[]
35
+ childRunIds: string[]
36
+ messageHistory: Message[]
37
+ stepsRemaining: number
38
+ creditsUsed: number
39
+ directCreditsUsed: number
40
+ output?: Record<string, any>
41
+ parentId?: string
42
+ systemPrompt: string
43
+ toolDefinitions: Record<
44
+ string,
45
+ { description: string | undefined; inputSchema: {} }
46
+ >
47
+ /**
48
+ * The accurate token count from the Anthropic API.
49
+ * This is updated on every agent step via the /api/v1/token-count endpoint.
50
+ */
51
+ contextTokenCount: number
52
+ }
53
+
54
+ export const AgentOutputSchema = z.discriminatedUnion('type', [
55
+ z.object({
56
+ type: z.literal('structuredOutput'),
57
+ value: z.record(z.string(), z.any()).or(z.null()),
58
+ }),
59
+ z.object({
60
+ type: z.literal('lastMessage'),
61
+ value: z.array(z.any()), // Array of assistant and tool messages from the last turn, including tool results
62
+ }),
63
+ z.object({
64
+ type: z.literal('allMessages'),
65
+ value: z.array(z.any()),
66
+ }),
67
+ z.object({
68
+ type: z.literal('error'),
69
+ message: z.string(),
70
+ statusCode: z.number().optional(),
71
+ error: z.string().optional(),
72
+ countryCode: z.string().optional(),
73
+ countryBlockReason: z.string().optional(),
74
+ ipPrivacySignals: z.array(z.string()).optional(),
75
+ }),
76
+ ])
77
+ export type AgentOutput = z.infer<typeof AgentOutputSchema>
78
+
79
+ export const AgentTemplateTypeList = [
80
+ // Base agents
81
+ 'base',
82
+ 'base_free',
83
+ 'base_max',
84
+ 'base_experimental',
85
+ 'claude4_gemini_thinking',
86
+ 'superagent',
87
+ 'base_agent_builder',
88
+
89
+ // Ask mode
90
+ 'ask',
91
+
92
+ // Planning / Thinking
93
+ 'planner',
94
+ 'dry_run',
95
+ 'thinker',
96
+
97
+ // Other agents
98
+ 'file_picker',
99
+ 'file_explorer',
100
+ 'researcher',
101
+ 'reviewer',
102
+ 'agent_builder',
103
+ 'example_programmatic',
104
+ ] as const
105
+ type UnderscoreToDash<S extends string> = S extends `${infer L}_${infer R}`
106
+ ? `${L}-${UnderscoreToDash<R>}` // recurse on the remainder
107
+ : S
108
+ export const AgentTemplateTypes = Object.fromEntries(
109
+ AgentTemplateTypeList.map((name) => [name, name.replaceAll('_', '-')]),
110
+ ) as { [K in (typeof AgentTemplateTypeList)[number]]: UnderscoreToDash<K> }
111
+ const agentTemplateTypeSchema = z.enum(AgentTemplateTypeList)
112
+ // Allow dynamic agent types by extending the base enum with string
113
+ export type AgentTemplateType =
114
+ | z.infer<typeof agentTemplateTypeSchema>
115
+ | (string & {})
116
+
117
+ export type SessionState = {
118
+ fileContext: ProjectFileContext
119
+ mainAgentState: AgentState
120
+ }
121
+
122
+ export function getInitialAgentState(): AgentState {
123
+ return {
124
+ agentId: 'main-agent',
125
+ agentType: null,
126
+ agentContext: {},
127
+ ancestorRunIds: [],
128
+ runId: undefined,
129
+ subagents: [],
130
+ childRunIds: [],
131
+ messageHistory: [],
132
+ stepsRemaining: MAX_AGENT_STEPS_DEFAULT,
133
+ creditsUsed: 0,
134
+ directCreditsUsed: 0,
135
+ output: undefined,
136
+ parentId: undefined,
137
+ systemPrompt: '',
138
+ toolDefinitions: {},
139
+ contextTokenCount: 0,
140
+ }
141
+ }
142
+ export function getInitialSessionState(
143
+ fileContext: ProjectFileContext,
144
+ ): SessionState {
145
+ return {
146
+ mainAgentState: getInitialAgentState(),
147
+ fileContext,
148
+ }
149
+ }
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod/v4'
2
+
3
+ import {
4
+ SKILL_NAME_MAX_LENGTH,
5
+ SKILL_NAME_REGEX,
6
+ SKILL_DESCRIPTION_MAX_LENGTH,
7
+ } from '../constants/skills'
8
+
9
+ /**
10
+ * Zod schema for skill frontmatter metadata.
11
+ *
12
+ * Values are unconstrained on purpose: `metadata` is a free-form bag that
13
+ * publishers and registries nest their own structures into (skills.sh writes a
14
+ * `hermes:` block into every skill it serves). Requiring flat strings here
15
+ * rejected the whole skill over a field nothing reads.
16
+ */
17
+ export const SkillMetadataSchema = z.record(z.string(), z.unknown())
18
+
19
+ /**
20
+ * Zod schema for skill frontmatter (parsed from YAML).
21
+ */
22
+ export const SkillFrontmatterSchema = z.object({
23
+ name: z
24
+ .string()
25
+ .min(1)
26
+ .max(SKILL_NAME_MAX_LENGTH)
27
+ .regex(
28
+ SKILL_NAME_REGEX,
29
+ 'Name must be lowercase alphanumeric with single hyphen separators',
30
+ ),
31
+ // clamped rather than rejected: an over-long description is a reason to show
32
+ // less of it, never a reason to make the skill unusable
33
+ description: z
34
+ .string()
35
+ .min(1)
36
+ .transform((d) => d.slice(0, SKILL_DESCRIPTION_MAX_LENGTH)),
37
+ license: z.string().optional(),
38
+ 'disable-model-invocation': z.boolean().optional(),
39
+ metadata: SkillMetadataSchema.optional(),
40
+ })
41
+
42
+ export type SkillFrontmatter = z.infer<typeof SkillFrontmatterSchema>
43
+
44
+ /**
45
+ * Full skill definition including content and source path.
46
+ */
47
+ export const SkillDefinitionSchema = z.object({
48
+ /** Skill name (must match directory name) */
49
+ name: z.string(),
50
+ /** Short description for agent discovery */
51
+ description: z.string(),
52
+ /** Optional license */
53
+ license: z.string().optional(),
54
+ /** Whether only the user may invoke this skill. */
55
+ disableModelInvocation: z.boolean().optional(),
56
+ /** Optional key-value metadata */
57
+ metadata: SkillMetadataSchema.optional(),
58
+ /** Full SKILL.md content (including frontmatter) */
59
+ content: z.string(),
60
+ /** Source file path */
61
+ filePath: z.string(),
62
+ })
63
+
64
+ export type SkillDefinition = z.infer<typeof SkillDefinitionSchema>
65
+
66
+ export function createSkillDefinition(params: {
67
+ frontmatter: SkillFrontmatter
68
+ content: string
69
+ filePath: string
70
+ }): SkillDefinition {
71
+ const { frontmatter, content, filePath } = params
72
+ return {
73
+ name: frontmatter.name,
74
+ description: frontmatter.description,
75
+ license: frontmatter.license,
76
+ disableModelInvocation: frontmatter['disable-model-invocation'],
77
+ metadata: frontmatter.metadata,
78
+ content,
79
+ filePath,
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Collection of skills keyed by skill name.
85
+ */
86
+ export type SkillsMap = Record<string, SkillDefinition>
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Represents a source of data.
3
+ *
4
+ * By default, can be a value or a promise.
5
+ *
6
+ * In the case that the type is a not function itself, this can also be a function that returns the value or promise.
7
+ */
8
+ export type Source<T> =
9
+ | T
10
+ | Promise<T>
11
+ | (T extends (...args: unknown[]) => unknown ? never : () => T | Promise<T>)
@@ -0,0 +1,13 @@
1
+ import type { ChildProcess, SpawnOptions } from 'child_process'
2
+
3
+ /**
4
+ * Spawn function for running shell commands.
5
+ *
6
+ * Compatible with `child_process.spawn` from Node.js.
7
+ * Returns ChildProcess to support full streaming capabilities (stdin, stdout, stderr).
8
+ */
9
+ export type AnvilSpawn = (
10
+ command: string,
11
+ args?: readonly string[],
12
+ options?: SpawnOptions,
13
+ ) => ChildProcess
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Core subscription information for an active subscription.
3
+ */
4
+ export interface SubscriptionInfo {
5
+ id: string
6
+ status: string
7
+ billingPeriodEnd: string
8
+ cancelAtPeriodEnd: boolean
9
+ canceledAt: string | null
10
+ tier: number
11
+ scheduledTier?: number | null
12
+ }
13
+
14
+ /**
15
+ * Rate limit information for subscription usage.
16
+ */
17
+ export interface SubscriptionRateLimit {
18
+ limited: boolean
19
+ reason?: 'block_exhausted' | 'weekly_limit'
20
+ canStartNewBlock: boolean
21
+ blockUsed?: number
22
+ blockLimit?: number
23
+ blockResetsAt?: string
24
+ weeklyUsed: number
25
+ weeklyLimit: number
26
+ weeklyResetsAt: string
27
+ weeklyPercentUsed: number
28
+ }
29
+
30
+ /**
31
+ * Subscription limits configuration.
32
+ */
33
+ export interface SubscriptionLimits {
34
+ creditsPerBlock: number
35
+ blockDurationHours: number
36
+ weeklyCreditsLimit: number
37
+ }
38
+
39
+ /**
40
+ * Response when user has no active subscription.
41
+ */
42
+ export interface NoSubscriptionResponse {
43
+ hasSubscription: false
44
+ /** Whether user prefers to fallback to a-la-carte credits when subscription limits are reached */
45
+ fallbackToALaCarte: boolean
46
+ }
47
+
48
+ /**
49
+ * Response when user has an active subscription.
50
+ * All fields are required - no invalid states possible.
51
+ */
52
+ export interface ActiveSubscriptionResponse {
53
+ hasSubscription: true
54
+ displayName: string
55
+ subscription: SubscriptionInfo
56
+ rateLimit: SubscriptionRateLimit
57
+ limits: SubscriptionLimits
58
+
59
+ /** Whether user prefers to fallback to a-la-carte credits when subscription limits are reached */
60
+ fallbackToALaCarte: boolean
61
+ }
62
+
63
+ /**
64
+ * Discriminated union for subscription API response.
65
+ * Use `hasSubscription` to narrow the type.
66
+ */
67
+ export type SubscriptionResponse = NoSubscriptionResponse | ActiveSubscriptionResponse
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod/v4'
2
+
3
+ import { GrantTypeValues } from './grant'
4
+
5
+ export const usageDataSchema = z.object({
6
+ usageThisCycle: z.number(),
7
+ balance: z.object({
8
+ totalRemaining: z.number(),
9
+ totalDebt: z.number(),
10
+ netBalance: z.number(),
11
+ breakdown: z.record(z.enum(GrantTypeValues), z.number()),
12
+ }),
13
+ nextQuotaReset: z.coerce.date().nullable(),
14
+ })
15
+
16
+ export type UsageData = z.infer<typeof usageDataSchema>
@@ -0,0 +1,3 @@
1
+ export type Prettify<T> = {
2
+ [K in keyof T]: T[K]
3
+ } & {}
@@ -0,0 +1,26 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+
3
+ import { getAdUserAgent } from '../ad-user-agent'
4
+
5
+ describe('getAdUserAgent', () => {
6
+ test.each([
7
+ ['darwin', 'Macintosh; Intel Mac OS X'],
8
+ ['win32', 'Windows NT 10.0'],
9
+ ['linux', 'X11; Linux x86_64'],
10
+ ])('returns a browser-like UA for %s', (platform, osFragment) => {
11
+ const userAgent = getAdUserAgent(platform)
12
+
13
+ expect(userAgent).toContain(osFragment)
14
+ expect(userAgent).toContain('Chrome/')
15
+ expect(userAgent).not.toStartWith('Bun/')
16
+ })
17
+
18
+ test('falls back to Linux for an unknown platform', () => {
19
+ expect(getAdUserAgent('other')).toBe(getAdUserAgent('linux'))
20
+ })
21
+
22
+ test('accepts the device OS names used by the ads API', () => {
23
+ expect(getAdUserAgent('macos')).toBe(getAdUserAgent('darwin'))
24
+ expect(getAdUserAgent('windows')).toBe(getAdUserAgent('win32'))
25
+ })
26
+ })
@@ -0,0 +1,122 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+
3
+ import { AnalyticsEvent } from '@anvil/common/constants/analytics-events'
4
+
5
+ import { createAnalyticsDispatcher } from '../analytics-dispatcher'
6
+
7
+ describe('analytics dispatcher', () => {
8
+ const level = 'info'
9
+ const msg = 'hello'
10
+
11
+ it('no-ops in dev environment', () => {
12
+ const dispatcher = createAnalyticsDispatcher({
13
+ envName: 'dev',
14
+ bufferWhenNoUser: true,
15
+ })
16
+
17
+ const out = dispatcher.process({
18
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED, userId: 'u' },
19
+ level,
20
+ msg,
21
+ })
22
+
23
+ expect(out).toEqual([])
24
+ })
25
+
26
+ it('emits payload when event and user are present', () => {
27
+ const dispatcher = createAnalyticsDispatcher({ envName: 'prod' })
28
+
29
+ const out = dispatcher.process({
30
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED, userId: 'u' },
31
+ level,
32
+ msg,
33
+ })
34
+
35
+ expect(out).toHaveLength(1)
36
+ expect(out[0]).toMatchObject({
37
+ event: AnalyticsEvent.APP_LAUNCHED,
38
+ userId: 'u',
39
+ properties: expect.objectContaining({
40
+ userId: 'u',
41
+ level,
42
+ msg,
43
+ }),
44
+ })
45
+ })
46
+
47
+ it('buffers when no user and flushes once user appears', () => {
48
+ const dispatcher = createAnalyticsDispatcher({
49
+ envName: 'prod',
50
+ bufferWhenNoUser: true,
51
+ })
52
+
53
+ // Missing user; should buffer
54
+ const first = dispatcher.process({
55
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED },
56
+ level,
57
+ msg,
58
+ })
59
+ expect(first).toEqual([])
60
+
61
+ // With user; should flush buffered event first, then this one
62
+ const second = dispatcher.process({
63
+ data: {
64
+ eventId: AnalyticsEvent.AGENT_STEP,
65
+ userId: 'user-1',
66
+ },
67
+ level,
68
+ msg,
69
+ })
70
+
71
+ expect(second).toHaveLength(2)
72
+ expect(second[0]).toMatchObject({
73
+ event: AnalyticsEvent.APP_LAUNCHED,
74
+ userId: 'user-1',
75
+ })
76
+ expect(second[1]).toMatchObject({
77
+ event: AnalyticsEvent.AGENT_STEP,
78
+ userId: 'user-1',
79
+ })
80
+ })
81
+
82
+ it('uses fallbackUserId when rebuilding buffered events', () => {
83
+ const dispatcher = createAnalyticsDispatcher({
84
+ envName: 'prod',
85
+ bufferWhenNoUser: true,
86
+ })
87
+
88
+ dispatcher.process({
89
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED },
90
+ level,
91
+ msg,
92
+ })
93
+
94
+ const out = dispatcher.process({
95
+ data: {
96
+ eventId: AnalyticsEvent.AGENT_STEP,
97
+ },
98
+ level,
99
+ msg,
100
+ fallbackUserId: 'fallback-user',
101
+ })
102
+
103
+ expect(out).toHaveLength(2)
104
+ expect(out[0].userId).toBe('fallback-user')
105
+ expect(out[1].userId).toBe('fallback-user')
106
+ })
107
+
108
+ it('ignores unknown events even when buffering is on', () => {
109
+ const dispatcher = createAnalyticsDispatcher({
110
+ envName: 'prod',
111
+ bufferWhenNoUser: true,
112
+ })
113
+
114
+ const out = dispatcher.process({
115
+ data: { eventId: 'not-real' },
116
+ level,
117
+ msg,
118
+ })
119
+
120
+ expect(out).toEqual([])
121
+ })
122
+ })
@@ -0,0 +1,102 @@
1
+ import { describe, expect, it } from 'bun:test'
2
+
3
+ import { AnalyticsEvent } from '@anvil/common/constants/analytics-events'
4
+
5
+ import {
6
+ getAnalyticsEventId,
7
+ toTrackableAnalyticsPayload,
8
+ type AnalyticsLogData,
9
+ } from '../analytics-log'
10
+
11
+ describe('analytics-log helpers', () => {
12
+ const baseMsg = 'hello'
13
+ const baseLevel = 'info'
14
+
15
+ it('returns null for non-object data', () => {
16
+ expect(
17
+ toTrackableAnalyticsPayload({ data: null, level: baseLevel, msg: baseMsg }),
18
+ ).toBeNull()
19
+ expect(
20
+ toTrackableAnalyticsPayload({ data: 'x', level: baseLevel, msg: baseMsg }),
21
+ ).toBeNull()
22
+ })
23
+
24
+ it('returns null when eventId is missing or unknown', () => {
25
+ expect(
26
+ toTrackableAnalyticsPayload({
27
+ data: {},
28
+ level: baseLevel,
29
+ msg: baseMsg,
30
+ }),
31
+ ).toBeNull()
32
+
33
+ expect(
34
+ toTrackableAnalyticsPayload({
35
+ data: { eventId: 'not-real' },
36
+ level: baseLevel,
37
+ msg: baseMsg,
38
+ }),
39
+ ).toBeNull()
40
+ })
41
+
42
+ it('returns null when user cannot be resolved', () => {
43
+ expect(
44
+ toTrackableAnalyticsPayload({
45
+ data: { eventId: AnalyticsEvent.AGENT_STEP },
46
+ level: baseLevel,
47
+ msg: baseMsg,
48
+ }),
49
+ ).toBeNull()
50
+ })
51
+
52
+ it('builds payload when event and userId exist', () => {
53
+ const payload = toTrackableAnalyticsPayload({
54
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED, userId: 'u1', extra: 123 },
55
+ level: baseLevel,
56
+ msg: baseMsg,
57
+ })!
58
+
59
+ expect(payload.event).toBe(AnalyticsEvent.APP_LAUNCHED)
60
+ expect(payload.userId).toBe('u1')
61
+ expect(payload.properties).toMatchObject({
62
+ userId: 'u1',
63
+ extra: 123,
64
+ level: baseLevel,
65
+ msg: baseMsg,
66
+ })
67
+ })
68
+
69
+ it('falls back to nested and underscored user ids', () => {
70
+ const fromUser = toTrackableAnalyticsPayload({
71
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED, user: { id: 'nested' } },
72
+ level: baseLevel,
73
+ msg: baseMsg,
74
+ })
75
+ expect(fromUser?.userId).toBe('nested')
76
+
77
+ const fromUnderscore = toTrackableAnalyticsPayload({
78
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED, user_id: 'underscored' },
79
+ level: baseLevel,
80
+ msg: baseMsg,
81
+ })
82
+ expect(fromUnderscore?.userId).toBe('underscored')
83
+ })
84
+
85
+ it('uses fallbackUserId when no user fields exist', () => {
86
+ const payload = toTrackableAnalyticsPayload({
87
+ data: { eventId: AnalyticsEvent.APP_LAUNCHED },
88
+ level: baseLevel,
89
+ msg: baseMsg,
90
+ fallbackUserId: 'fallback',
91
+ })!
92
+
93
+ expect(payload.userId).toBe('fallback')
94
+ })
95
+
96
+ it('getAnalyticsEventId returns only known events', () => {
97
+ const data: AnalyticsLogData = { eventId: AnalyticsEvent.APP_LAUNCHED }
98
+ expect(getAnalyticsEventId(data)).toBe(AnalyticsEvent.APP_LAUNCHED)
99
+ expect(getAnalyticsEventId({ eventId: 'nope' })).toBeNull()
100
+ expect(getAnalyticsEventId(null)).toBeNull()
101
+ })
102
+ })