@alumbwe/anvil 1.0.20 → 1.0.21

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 +6 -2
  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,535 @@
1
+ import type { AnvilAccessTier } from '../constants/anvil-models'
2
+ import type { AnvilStandingInfo } from '../constants/anvil-trust'
3
+
4
+ /**
5
+ * Wire-level shapes returned by `/api/v1/anvil/session`. Source of truth
6
+ * for the CLI (which deserializes these) and the server (which serializes
7
+ * them) — keep both in sync by importing this module from either side.
8
+ *
9
+ * The CLI uses these shapes directly; there are no client-only states.
10
+ */
11
+
12
+ /**
13
+ * Usage counter surfaced to the CLI so the UI can render
14
+ * "N of M sessions used" alongside active state. Present when the
15
+ * joined model consumes Anvil sessions. `recentCount` is the
16
+ * rounded session units since the current quota period began at the time the
17
+ * response was produced — see also the standalone `rate_limited` status for
18
+ * the reject path.
19
+ */
20
+ export interface AnvilSessionEntitlementBreakdown {
21
+ /** Sessions included without earning a referral or streak reward. */
22
+ base: number
23
+ /** Sessions earned from the referral program for this quota period. */
24
+ referral: number
25
+ /** Sessions earned from the active streak reward for this quota period. */
26
+ streak: number
27
+ /** Sessions added by a temporary promotion, for a user who already earned
28
+ * their way in (a qualified referral or a bounty grant). Omitted while no
29
+ * promo runs, which is the default — an older client that never reads it
30
+ * still sums to the right `limit`, because the server sends the total. */
31
+ promo?: number
32
+ }
33
+
34
+ export interface AnvilSessionRateLimit {
35
+ model: string
36
+ /** Additive detail for `limit`; omitted by older servers. New servers emit it
37
+ * for session quotas with `limit = base + referral + streak + promo`. */
38
+ entitlementBreakdown?: AnvilSessionEntitlementBreakdown
39
+ limit: number
40
+ /** 'pacific_day' for the daily pools (premium/limited, and the GLM 5.2
41
+ * referral pool since 2026-07-29). 'pacific_week' is kept for wire compat
42
+ * with servers from when the GLM pool reset weekly. */
43
+ period: 'pacific_day' | 'pacific_week'
44
+ resetTimeZone: string
45
+ resetAt: string
46
+ /** Deprecated wire field kept for older clients. Session usage now follows
47
+ * the explicit Pacific day/week period and `resetAt`. */
48
+ windowHours: number
49
+ recentCount: number
50
+ }
51
+
52
+ export type AnvilSessionRateLimitByModel = Record<
53
+ string,
54
+ AnvilSessionRateLimit
55
+ >
56
+
57
+ /** Timing needed by multi-session clients to show the active session window. */
58
+ export interface AnvilActiveSessionInfo {
59
+ model: string
60
+ admittedAt: string
61
+ expiresAt: string
62
+ }
63
+
64
+ /** Live per-user Anvil Desktop sessions, counted server-side across every
65
+ * Desktop process. Holder identities stay client-local; these totals make the
66
+ * picker honest when another project or device is using capacity. */
67
+ export interface AnvilDesktopSessionCounts {
68
+ premium: number
69
+ unlimited: number
70
+ /** Earliest capacity-release time. Premium rows include their drain grace;
71
+ * unlimited rows release at normal expiry. */
72
+ nextExpiryAt?: string
73
+ }
74
+
75
+ /**
76
+ * Referral status surfaced to the CLI model-selector so it can render an
77
+ * "invite friends" banner. The reward depends on the session's access tier:
78
+ *
79
+ * - full tier → unlock daily GLM 5.2 sessions (`weeklySessionsRemaining`
80
+ * and `resetAt` carry the live balance / next reset; the field name
81
+ * predates the weekly→daily cadence change and is kept for wire compat).
82
+ * - limited tier → earn a daily free-session bonus (+1/day per qualified
83
+ * referral, capped); the GLM-only fields are omitted, and `qualifiedCount`
84
+ * carries the bonus sessions/day already earned (capped).
85
+ *
86
+ * Present on the pre-join (`none`) response. The CLI branches on the session's
87
+ * `accessTier` to pick the right copy; both variants share the share code,
88
+ * inviter name, and GitHub-linked flag.
89
+ */
90
+ export interface AnvilReferralInfo {
91
+ /** The user's referral code (`user.referral_code`), used to build the share
92
+ * link. */
93
+ code: string
94
+ /** The inviter's display name (`user.name`), used to personalize the invite
95
+ * landing page ("X invited you to try Anvil!"). Null when the user has no
96
+ * name set. */
97
+ referrerName: string | null
98
+ /** Qualified-referral count for the tier's reward: full tier = GLM sessions
99
+ * per day (uncapped since 2026-07-30); limited tier = daily-session bonus
100
+ * earned, still capped at REFERRAL_CLI_DAILY_SESSION_BONUS_CAP, which the
101
+ * CLI knows locally. */
102
+ qualifiedCount: number
103
+ /** GLM sessions still available in the current reset window (entitlement −
104
+ * used, ≥ 0). Daily since 2026-07-29; the "weekly" name is kept for wire
105
+ * compat. Full tier only; omitted for the limited-tier daily-bonus
106
+ * variant. */
107
+ weeklySessionsRemaining?: number
108
+ /** ISO timestamp of the next GLM pool reset. Full tier only; omitted for
109
+ * the limited-tier daily-bonus variant. */
110
+ resetAt?: string
111
+ /** Whether the current user has a GitHub account linked. Referrals only
112
+ * qualify with a connected, sufficiently-old GitHub, so the CLI prompts
113
+ * Google-only users to connect one. */
114
+ githubLinked: boolean
115
+ }
116
+
117
+ /**
118
+ * A live GLM 5.2 promotion, as advertised to every surface.
119
+ *
120
+ * One block drives the CLI banner, the desktop footer, the web picker, the Earn
121
+ * page and the landing eyebrow, so their copy cannot disagree about the size of
122
+ * the promo or when it ends. Present ONLY while the promo is running: absent
123
+ * means every surface renders exactly what it rendered before promos existed,
124
+ * which is what makes closing one an env change rather than a release.
125
+ */
126
+ export interface AnvilGlmPromo {
127
+ /** Sessions per Pacific day an earned user may run while this runs. */
128
+ dailySessions: number
129
+ /** ISO timestamp the promo closes. Surfaces count down to it rather than
130
+ * hardcoding a date, so the copy can never outlive the server's window. */
131
+ endsAt: string
132
+ }
133
+
134
+ /** Pull the promo block off whichever session status carries it. Same loose
135
+ * parameter type as `getReferralInfo`, for the same reason. */
136
+ export const getGlmPromo = (
137
+ session: { status: string } | null | undefined,
138
+ ): AnvilGlmPromo | undefined =>
139
+ session && 'glmPromo' in session
140
+ ? ((session as { glmPromo?: AnvilGlmPromo }).glmPromo ?? undefined)
141
+ : undefined
142
+
143
+ /** Pull the referral block off whichever session status carries it. Loose
144
+ * parameter type for the same reason as `getRateLimitsByModel`. */
145
+ export const getReferralInfo = (
146
+ session: { status: string } | null | undefined,
147
+ ): AnvilReferralInfo | undefined =>
148
+ session && 'referral' in session
149
+ ? (session as { referral?: AnvilReferralInfo }).referral
150
+ : undefined
151
+
152
+ /** Pull the per-model shared session-quota snapshot off whichever statuses
153
+ * carry it (active, ended, none). Returns undefined for terminal /
154
+ * pre-join states that have no quota field. The parameter is intentionally
155
+ * loose so the CLI can pass its `AnvilSessionResponse` (which adds the
156
+ * client-only `takeover_prompt` variant) without a discriminated-union
157
+ * ceremony at every call site. */
158
+ export const getRateLimitsByModel = (
159
+ session: { status: string } | null | undefined,
160
+ ): AnvilSessionRateLimitByModel | undefined =>
161
+ session && 'rateLimitsByModel' in session
162
+ ? (session as { rateLimitsByModel?: AnvilSessionRateLimitByModel })
163
+ .rateLimitsByModel
164
+ : undefined
165
+
166
+ /**
167
+ * A capacity-limited model the server is offering RIGHT NOW, beyond whatever
168
+ * the client's own catalog contains.
169
+ *
170
+ * The server is the only thing that knows whether the wave's shared pool still
171
+ * has sessions in it, so it — not the client — decides whether the row exists
172
+ * at all. The field is optional and clients must render nothing when it is
173
+ * absent or empty: that is what makes an exhausted, disabled or not-yet-shipped
174
+ * offer invisible instead of a broken-looking greyed-out row.
175
+ *
176
+ * `remaining`/`total` describe the GLOBAL pool shared by every user, while
177
+ * `userRemaining` describes the caller's own daily ceiling. A row is joinable
178
+ * only while both are non-zero, and the client must treat `userRemaining === 0`
179
+ * as "not now" rather than hiding the row — the user has already had their
180
+ * session and the reset time explains when they get another.
181
+ *
182
+ * The ceiling itself is not on the wire: it is fixed by construction
183
+ * (ANVIL_LIMITED_OFFER_SESSION_LIMIT, which no streak or referral can
184
+ * raise), so a client that ever needs "N of M used" reads the shared constant
185
+ * rather than a field the server has to keep consistent.
186
+ */
187
+ export interface AnvilLimitedModelOffer {
188
+ /** Model id; always a member of SUPPORTED_ANVIL_MODELS, so the client can
189
+ * resolve its display name from the shared catalog. */
190
+ model: string
191
+ /** Sessions left in the shared global pool for the current wave. Always > 0
192
+ * — an exhausted offer is omitted rather than sent as zero. */
193
+ remaining: number
194
+ /** Pool size for the current wave, for "N of M left" copy. */
195
+ total: number
196
+ /** Sessions this user may still start today. May be 0. */
197
+ userRemaining: number
198
+ /** ISO timestamp at which `userRemaining` refills. */
199
+ userResetAt: string
200
+ }
201
+
202
+ /** Pull the limited-model offers off whichever session status carries them.
203
+ * Loose parameter type for the same reason as `getRateLimitsByModel`. Always
204
+ * returns an array so callers can map without a presence check. */
205
+ export const getLimitedModelOffers = (
206
+ session: { status: string } | null | undefined,
207
+ ): AnvilLimitedModelOffer[] =>
208
+ session && 'limitedModelOffers' in session
209
+ ? ((session as { limitedModelOffers?: AnvilLimitedModelOffer[] })
210
+ .limitedModelOffers ?? [])
211
+ : []
212
+
213
+ export type AnvilCountryBlockReason =
214
+ | 'country_not_allowed'
215
+ | 'anonymized_or_unknown_country'
216
+ | 'anonymous_network'
217
+ | 'missing_client_ip'
218
+ | 'unresolved_client_ip'
219
+ | 'ip_privacy_lookup_failed'
220
+
221
+ export type AnvilIpPrivacySignal =
222
+ | 'anonymous'
223
+ | 'vpn'
224
+ | 'proxy'
225
+ | 'tor'
226
+ | 'relay'
227
+ | 'res_proxy'
228
+ | 'hosting'
229
+ | 'service'
230
+
231
+ export type AnvilSpurStatus =
232
+ | 'not_checked'
233
+ | 'clean'
234
+ | 'suspicious'
235
+ | 'failed'
236
+ /**
237
+ * Deliberately not consulted: the provider is switched off, or its balance
238
+ * is exhausted and the breaker is open.
239
+ *
240
+ * Distinct from `failed` on purpose. `failed` means "we asked and got
241
+ * nothing", which is a signal about the IP's luck and is worth a risk-score
242
+ * floor. `skipped` means "we chose not to ask", which says nothing about the
243
+ * IP at all — scoring it would penalise every request in the world the
244
+ * moment we turn a vendor off. What it does instead is leave the escalation
245
+ * UNRESOLVED when no other provider answered, which the spend ceiling reads
246
+ * as `unverified_egress`.
247
+ */
248
+ | 'skipped'
249
+
250
+ export type AnvilScamalyticsStatus =
251
+ | 'not_checked'
252
+ | 'clean'
253
+ | 'suspicious'
254
+ | 'failed'
255
+ /** Deliberately not consulted — switched off, or balance exhausted and the
256
+ * breaker is open. Same meaning and same reasoning as the Spur variant. */
257
+ | 'skipped'
258
+
259
+ export type AnvilPrivacyDecision =
260
+ | 'allowed_clean'
261
+ | 'ipinfo_suspicious_spur_clean'
262
+ | 'corroborated_block'
263
+ | 'cloudflare_tor_block'
264
+ | 'spur_failed_limited'
265
+ /** ipinfo flagged the egress and no second opinion was obtainable at all —
266
+ * every provider disabled, exhausted, or erroring. Carries the restricted
267
+ * spend ceiling so a vendor outage cannot widen anyone's budget. */
268
+ | 'unverified_egress_limited'
269
+ | 'scamalytics_failed_limited'
270
+ | 'scamalytics_suspicious_limited'
271
+ | 'ipinfo_failed_limited'
272
+ | 'limited_other'
273
+
274
+ export type AnvilPrivacyProviderDecision =
275
+ | 'not_checked'
276
+ | 'cloudflare_tor'
277
+ | 'ipinfo_clean'
278
+ | 'ipinfo_failed'
279
+ | 'ipinfo_only'
280
+ | 'spur_failed'
281
+ | 'scamalytics_failed'
282
+ | 'scamalytics_only'
283
+ | 'corroborated_soft'
284
+ | 'corroborated_hard'
285
+
286
+ export interface AnvilLimitedModeReason {
287
+ /** Present for limited access so the model picker can explain why the
288
+ * reduced model set is shown without re-running geo/IP logic locally. */
289
+ countryCode?: string | null
290
+ countryBlockReason?: AnvilCountryBlockReason | null
291
+ ipPrivacySignals?: AnvilIpPrivacySignal[] | null
292
+ }
293
+
294
+ export type AnvilSessionServerResponse = (
295
+ | ({
296
+ /** User has no session row. CLI must POST to start a session. Also
297
+ * returned when `getSessionState` notices the user has been swept past
298
+ * the grace window. */
299
+ status: 'none'
300
+ accessTier?: AnvilAccessTier
301
+ message?: string
302
+ /** Current quota snapshots for free models, keyed by model id. Lets
303
+ * the picker show today's session usage before the user commits
304
+ * to a model. */
305
+ rateLimitsByModel?: AnvilSessionRateLimitByModel
306
+ /** Referral status for the "invite friends" banner. Full tier advertises
307
+ * GLM 5.2; limited tier advertises a daily free-session bonus. */
308
+ referral?: AnvilReferralInfo
309
+ /** Capacity-limited models the picker may additionally offer right now.
310
+ * Only sent on the pre-join response, which is the only state that
311
+ * renders a picker. Absent whenever the pool is spent or the offer is
312
+ * off — see AnvilLimitedModelOffer. */
313
+ limitedModelOffers?: AnvilLimitedModelOffer[]
314
+ /**
315
+ * The account's Access Level and the limits it currently selects.
316
+ *
317
+ * Sent on the pre-join response only, which is the state that renders a
318
+ * picker and therefore the one place a client can explain the numbers
319
+ * next to the models they apply to. Absent when the feature is off, so
320
+ * a client renders it only when there is something true to render.
321
+ */
322
+ standing?: AnvilStandingInfo
323
+ } & AnvilLimitedModeReason)
324
+ | ({
325
+ status: 'active'
326
+ accessTier: AnvilAccessTier
327
+ instanceId: string
328
+ /** Model the active session is bound to — cannot change mid-session. */
329
+ model: string
330
+ admittedAt: string
331
+ expiresAt: string
332
+ remainingMs: number
333
+ /** Shared free-session quota for this model. */
334
+ rateLimit?: AnvilSessionRateLimit
335
+ rateLimitsByModel?: AnvilSessionRateLimitByModel
336
+ /** Included for Web/Cloud picker reads that request full quota details. */
337
+ referral?: AnvilReferralInfo
338
+ } & AnvilLimitedModeReason)
339
+ | ({
340
+ /** Session is over. While `instanceId` is present we're inside the
341
+ * server-side grace window — chat requests still go through so the
342
+ * agent can finish, but the CLI must not accept new prompts. Once
343
+ * `instanceId` is absent the session is fully gone and the user must
344
+ * rejoin via POST.
345
+ *
346
+ * Server-supplied form (in-grace) carries the timing fields; the
347
+ * client may also synthesize a no-grace `{ status: 'ended' }` when a
348
+ * poll reveals the row was swept. Both render the same UI. */
349
+ status: 'ended'
350
+ accessTier?: AnvilAccessTier
351
+ instanceId?: string
352
+ admittedAt?: string
353
+ expiresAt?: string
354
+ gracePeriodEndsAt?: string
355
+ gracePeriodRemainingMs?: number
356
+ /** Snapshot of the user's free-session quota at the moment the
357
+ * session ended. Lets the post-session banner show "N of M sessions
358
+ * used today" without an extra round-trip. */
359
+ rateLimitsByModel?: AnvilSessionRateLimitByModel
360
+ /** Included for Web/Cloud picker reads that request full quota details. */
361
+ referral?: AnvilReferralInfo
362
+ } & AnvilLimitedModeReason)
363
+ | {
364
+ /** Another CLI on the same account rotated our instance id. Polling
365
+ * stops and the UI shows a "close the other CLI" screen. The server
366
+ * returns this from GET /session when the caller's instance id
367
+ * doesn't match the stored one; the chat-completions gate also
368
+ * surfaces it as a 409 for fast in-flight feedback. */
369
+ status: 'superseded'
370
+ }
371
+ | {
372
+ /** Request originated outside the free-mode allowlist, or from an
373
+ * unknown/anonymized location that cannot be trusted for free mode.
374
+ * Returned before a session is started so users aren't rejected on
375
+ * their first chat request. Terminal —
376
+ * CLI stops polling and shows a "not available in your country"
377
+ * screen. `countryCode` is the resolved country, or UNKNOWN. */
378
+ status: 'country_blocked'
379
+ message?: string
380
+ countryCode: string
381
+ countryBlockReason?: AnvilCountryBlockReason
382
+ ipPrivacySignals?: AnvilIpPrivacySignal[]
383
+ }
384
+ | {
385
+ /** User has an active session bound to a different model. Returned
386
+ * from POST /session when they pick a new model without ending their
387
+ * current session first. The CLI shows a confirmation prompt: "End
388
+ * your active DeepSeek session to switch?" → on confirm, DELETE then
389
+ * re-POST with the new model. */
390
+ status: 'model_locked'
391
+ accessTier?: AnvilAccessTier
392
+ currentModel: string
393
+ requestedModel: string
394
+ }
395
+ | {
396
+ /** Requested model is valid but not selectable right now. */
397
+ status: 'model_unavailable'
398
+ accessTier?: AnvilAccessTier
399
+ requestedModel: string
400
+ availableHours: string
401
+ }
402
+ | {
403
+ /** Account is banned. Returned from every endpoint so banned bots can't
404
+ * start a session at all. Terminal — CLI stops polling and shows a
405
+ * banned message. */
406
+ status: 'banned'
407
+ }
408
+ | {
409
+ /** Too many DISTINCT users already hold an active free session on this
410
+ * egress IP. Admission-only: existing sessions on the IP keep running,
411
+ * and the request succeeds once one of them ends, so unlike
412
+ * `rate_limited` this is not tied to a quota reset. Sent as 429 so
413
+ * older CLIs that don't know the status still back off rather than
414
+ * tight-poll a 200 they can't parse. */
415
+ status: 'ip_capped'
416
+ accessTier?: AnvilAccessTier
417
+ model: string
418
+ /** Distinct users currently active on the IP (excluding the caller). */
419
+ activeUsersForIp: number
420
+ /** The configured ceiling (ANVIL_IP_USER_CAP). */
421
+ limit: number
422
+ retryAfterMs: number
423
+ }
424
+ | {
425
+ /** User has used up their shared free-session quota for the current
426
+ * Pacific day or week. Returned from POST /session before a session is
427
+ * started. `retryAfterMs` is the time until that period resets. Terminal
428
+ * for the CLI's current poll session; the user can exit and return later. */
429
+ status: 'rate_limited'
430
+ accessTier?: AnvilAccessTier
431
+ /** The anvil model the user tried to join. */
432
+ model: string
433
+ /** Max session units permitted per period (e.g. the configured daily
434
+ * premium allowance, or the user's weekly GLM referral plus streak
435
+ * entitlement). */
436
+ limit: number
437
+ /** Additive detail for `limit`; absent on older servers. */
438
+ entitlementBreakdown?: AnvilSessionEntitlementBreakdown
439
+ period: 'pacific_day' | 'pacific_week'
440
+ resetTimeZone: string
441
+ resetAt: string
442
+ /** Deprecated wire field kept for older clients. */
443
+ windowHours: number
444
+ /** Session units since the current Pacific period began — will be ≥ limit. */
445
+ recentCount: number
446
+ /** Milliseconds from now until the next Pacific period reset. */
447
+ retryAfterMs: number
448
+ }
449
+ | {
450
+ /** The user has reached today's cross-model Anvil provider-spend
451
+ * budget. This only blocks a fresh session admission: sessions already
452
+ * running, including a reconnect to the same live session, continue. */
453
+ status: 'spend_limited'
454
+ accessTier?: AnvilAccessTier
455
+ message: string
456
+ resetAt: string
457
+ retryAfterMs: number
458
+ }
459
+ | {
460
+ /** Anvil Desktop multi-session only: the user already holds an active
461
+ * premium-bucket session and tried to admit a second one. Only one
462
+ * premium-bucket model (DeepSeek V4 Pro / MiMo 2.5 Pro / Kimi / MiniMax
463
+ * M3 / GLM 5.2) may run at a time per user; on the full tier up to three
464
+ * unlimited-model sessions (DeepSeek V4 Flash, MiMo 2.5) may run. On
465
+ * the LIMITED tier every model occupies the slot — one anvil tab at
466
+ * a time. The desktop client surfaces this and steers the tab to an
467
+ * unlimited model (or closes the holding tab). Never returned to
468
+ * CLI/web, which run one
469
+ * session per user. */
470
+ status: 'premium_slot_taken'
471
+ accessTier?: AnvilAccessTier
472
+ /** Model this tab tried to start. */
473
+ requestedModel: string
474
+ /** Model of the premium-bucket session already running. */
475
+ currentModel: string
476
+ /** Instance id of the existing premium-bucket session, so the client can
477
+ * offer "switch to / close that one". */
478
+ currentInstanceId: string
479
+ }
480
+ ) & {
481
+ /** Multi-session Desktop responses only. Counts live, unexpired rows across
482
+ * all Desktop processes for this user. */
483
+ desktopSessionCounts?: AnvilDesktopSessionCounts
484
+ }
485
+
486
+ /**
487
+ * The session gate on `/api/v1/chat/completions`, as a wire contract.
488
+ *
489
+ * A rejection is identified by its `error` code paired with its HTTP status,
490
+ * never by its `message` — the prose is written for whoever is sitting in front
491
+ * of the client and is free to be rewritten. BOTH halves are required to match:
492
+ * 409/410 are ordinary provider outcomes on their own, and the codes are
493
+ * generic enough that an upstream error body can echo one, so a status-only or
494
+ * code-only test lets an unrelated failure impersonate the gate.
495
+ *
496
+ * `endsTheSession` marks the codes that mean the caller's row is GONE. Every
497
+ * one of them has the same recovery — forget the dead window and re-admit on
498
+ * the same instance id — which is why clients collapse them into one state
499
+ * rather than handling four. `false` is a refusal the session survives.
500
+ *
501
+ * Lives here because three surfaces need it and it drifted into three copies:
502
+ * the server that emits it (chat/completions), the CLI that matches it, and
503
+ * Desktop, which classifies it out of the SDK's relayed `AgentOutput`. See
504
+ * docs/anvil-session-admission.md.
505
+ */
506
+ export const ANVIL_GATE_CODES = {
507
+ waiting_room_required: { status: 428, endsTheSession: true },
508
+ session_expired: { status: 410, endsTheSession: true },
509
+ session_superseded: { status: 409, endsTheSession: true },
510
+ session_model_mismatch: { status: 409, endsTheSession: true },
511
+ /** The ACCOUNT is over its concurrent-tab budget; this tab's row is fine. */
512
+ session_limit_reached: { status: 409, endsTheSession: false },
513
+ /** Transient admission race — the row was caught mid-admit. */
514
+ waiting_room_queued: { status: 429, endsTheSession: false },
515
+ } as const satisfies Record<string, { status: number; endsTheSession: boolean }>
516
+
517
+ export type AnvilGateCode = keyof typeof ANVIL_GATE_CODES
518
+
519
+ /** The gate rejection this error output describes, or null for anything else.
520
+ * `output` is any shape carrying the relayed `error`/`statusCode` pair.
521
+ *
522
+ * `Object.hasOwn`, not `in`: the code is whatever an upstream error body put in
523
+ * its `error` field, so `in` would accept inherited names like `toString` —
524
+ * and since their `.status` is undefined, an output carrying no `statusCode`
525
+ * would then satisfy the status check too and be classified as a gate
526
+ * rejection. */
527
+ export function getAnvilGateCode(output: {
528
+ error?: string | undefined
529
+ statusCode?: number | undefined
530
+ }): AnvilGateCode | null {
531
+ const code = output.error
532
+ if (!code || !Object.hasOwn(ANVIL_GATE_CODES, code)) return null
533
+ const gate = ANVIL_GATE_CODES[code as AnvilGateCode]
534
+ return gate.status === output.statusCode ? (code as AnvilGateCode) : null
535
+ }
@@ -0,0 +1,6 @@
1
+ export interface AnvilStreakResponse {
2
+ streak: number
3
+ todayUsed: boolean
4
+ lastUsageDate: string | null
5
+ timeZone: string
6
+ }
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Wire types for the account hub's usage summary — the cross-surface view of
3
+ * one account's activity, shared by the web hub, the CLI and Desktop.
4
+ *
5
+ * Two sources, both read on demand and nothing written ahead of time:
6
+ * `anvil_daily_usage` (one narrow row per active Pacific day, which already
7
+ * exists for the streak) and a short bounded aggregate over `message`. See
8
+ * docs/anvil-account-hub.md.
9
+ */
10
+
11
+ export interface AnvilUsageStreakSummary {
12
+ /** Days in the current run. Survives today being unused until tomorrow. */
13
+ current: number
14
+ /** Longest run in recorded history. */
15
+ longest: number
16
+ todayUsed: boolean
17
+ lastUsageDate: string | null
18
+ }
19
+
20
+ /**
21
+ * Token and message totals over a short recent window.
22
+ *
23
+ * Deliberately not all-time: the cost of aggregating `message` scales with how
24
+ * much the account sent rather than with the calendar, so a long lookback is
25
+ * the one shape that cannot ship. Null when the aggregate exceeded its
26
+ * statement timeout — the UI says so rather than showing a zero.
27
+ */
28
+ export interface AnvilRecentUsage {
29
+ /** Lookback in days, so the UI can label the figures honestly. */
30
+ days: number
31
+ messages: number
32
+ inputTokens: number
33
+ cacheReadTokens: number
34
+ outputTokens: number
35
+ /** input + cache-read + output. The one number worth showing on a tile. */
36
+ totalTokens: number
37
+ }
38
+
39
+ export interface AnvilUsageSessionsByModel {
40
+ model: string
41
+ sessions: number
42
+ units: number
43
+ }
44
+
45
+ export interface AnvilUsageSummary {
46
+ timeZone: string
47
+ /** `YYYY-MM-DD` for "today" in `timeZone`, so a client in another zone lines
48
+ * the activity map up with the server rather than with its own midnight. */
49
+ todayDateKey: string
50
+ streak: AnvilUsageStreakSummary
51
+ /**
52
+ * Days the account was active inside the activity-map window, oldest first.
53
+ * Quiet days are absent rather than listed — the renderer fills the calendar.
54
+ */
55
+ activeDates: string[]
56
+ /** How many days the map window covers, ending on `todayDateKey`. */
57
+ windowDays: number
58
+ /** Active days over the account's whole history, not just the window. */
59
+ allTimeActiveDays: number
60
+ /** Null when the aggregate timed out; absent figures beat wrong ones. */
61
+ recent: AnvilRecentUsage | null
62
+ /** Sessions admitted per model over the last 30 days, busiest first. */
63
+ sessionsByModel: AnvilUsageSessionsByModel[]
64
+ }
@@ -0,0 +1,61 @@
1
+ import { z } from 'zod/v4'
2
+
3
+ export const publishAgentsRequestSchema = z.object({
4
+ data: z.record(z.string(), z.any()).array(),
5
+ // All local agent IDs from the client, used for validation to recognize local agents
6
+ // that aren't being published but are referenced by agents being published
7
+ allLocalAgentIds: z.array(z.string()).optional(),
8
+ // DEPRECATED since CLI v1.0.0. authToken in body is for backwards compatibility with older CLI versions.
9
+ // Remove after 2025-03-31 once older clients are phased out.
10
+ // New clients should use the Authorization header instead.
11
+ authToken: z.string().optional(),
12
+ })
13
+ export type PublishAgentsRequest = z.infer<typeof publishAgentsRequestSchema>
14
+
15
+ export const publishAgentsSuccessResponseSchema = z.object({
16
+ success: z.literal(true),
17
+ publisherId: z.string(),
18
+ agents: z
19
+ .object({
20
+ id: z.string(),
21
+ version: z.string(),
22
+ displayName: z.string(),
23
+ })
24
+ .array(),
25
+ })
26
+ export type PublishAgentsSuccessResponse = z.infer<
27
+ typeof publishAgentsSuccessResponseSchema
28
+ >
29
+
30
+ export const publishAgentsErrorResponseSchema = z.object({
31
+ success: z.literal(false),
32
+ error: z.string(),
33
+ details: z.string().optional(),
34
+ hint: z.string().optional(),
35
+ availablePublishers: z
36
+ .object({
37
+ id: z.string(),
38
+ name: z.string(),
39
+ ownershipType: z.enum(['user', 'organization']),
40
+ organizationName: z.string().optional(),
41
+ })
42
+ .array()
43
+ .optional(),
44
+ validationErrors: z
45
+ .object({
46
+ code: z.string(),
47
+ message: z.string(),
48
+ path: z.array(z.string()),
49
+ })
50
+ .array()
51
+ .optional(),
52
+ })
53
+ export type PublishAgentsErrorResponse = z.infer<
54
+ typeof publishAgentsErrorResponseSchema
55
+ >
56
+
57
+ export const publishAgentsResponseSchema = z.discriminatedUnion('success', [
58
+ publishAgentsSuccessResponseSchema,
59
+ publishAgentsErrorResponseSchema,
60
+ ])
61
+ export type PublishAgentsResponse = z.infer<typeof publishAgentsResponseSchema>
@@ -0,0 +1,5 @@
1
+ declare module 'bun:test' {
2
+ export const describe: (name: string, fn: () => void) => void
3
+ export const it: (name: string, fn: () => void | Promise<void>) => void
4
+ export const expect: any
5
+ }