@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,741 @@
1
+ /**
2
+ * This is a modified version of the Saxy library that emits text nodes immediately
3
+ */
4
+ import { Transform } from 'node:stream'
5
+ import { StringDecoder } from 'string_decoder'
6
+
7
+ import { includesMatch, isWhitespace } from './string'
8
+
9
+ export type TextNode = {
10
+ /** The text value */
11
+ contents: string
12
+ }
13
+
14
+ export type CDATANode = {
15
+ /** The CDATA contents */
16
+ contents: string
17
+ }
18
+
19
+ export type CommentNode = {
20
+ /** The comment contents */
21
+ contents: string
22
+ }
23
+
24
+ export type ProcessingInstructionNode = {
25
+ /** The instruction contents */
26
+ contents: string
27
+ }
28
+
29
+ /** Information about an opened tag */
30
+ export type TagOpenNode = {
31
+ /** Name of the tag that was opened. */
32
+ name: string
33
+ /**
34
+ * Attributes passed to the tag, in a string representation
35
+ * (use Saxy.parseAttributes to get an attribute-value mapping).
36
+ */
37
+ attrs: string
38
+ /**
39
+ * Whether the tag self-closes (tags of the form ``).
40
+ * Such tags will not be followed by a closing tag.
41
+ */
42
+ isSelfClosing: boolean
43
+
44
+ /**
45
+ * The original text of the tag, including angle brackets and attributes.
46
+ */
47
+ rawTag: string
48
+ }
49
+
50
+ /** Information about a closed tag */
51
+ export type TagCloseNode = {
52
+ /** Name of the tag that was closed. */
53
+ name: string
54
+
55
+ /**
56
+ * The original text of the tag, including angle brackets.
57
+ */
58
+ rawTag: string
59
+ }
60
+
61
+ export type NextFunction = (err?: Error) => void
62
+
63
+ export interface SaxyEvents {
64
+ finish: () => void
65
+ error: (err: Error) => void
66
+ text: (data: TextNode) => void
67
+ cdata: (data: CDATANode) => void
68
+ comment: (data: CommentNode) => void
69
+ processinginstruction: (data: ProcessingInstructionNode) => void
70
+ tagopen: (data: TagOpenNode) => void
71
+ tagclose: (data: TagCloseNode) => void
72
+ }
73
+
74
+ export type SaxyEventNames = keyof SaxyEvents
75
+
76
+ export type SaxyEventArgs =
77
+ | Error
78
+ | TextNode
79
+ | CDATANode
80
+ | CommentNode
81
+ | ProcessingInstructionNode
82
+ | TagOpenNode
83
+ | TagCloseNode
84
+
85
+ export interface Saxy {
86
+ on<U extends SaxyEventNames>(event: U, listener: SaxyEvents[U]): this
87
+ on(event: string | symbol | Event, listener: (...args: any[]) => void): this
88
+ once<U extends SaxyEventNames>(event: U, listener: SaxyEvents[U]): this
89
+ }
90
+
91
+ /**
92
+ * Schema for defining allowed tags and their children
93
+ */
94
+ export type TagSchema = {
95
+ [topLevelTag: string]: (string | RegExp)[] // Allowed child tags
96
+ }
97
+
98
+ /**
99
+ * Nodes that can be found inside an XML stream.
100
+ */
101
+ const Node = {
102
+ text: 'text',
103
+ cdata: 'cdata',
104
+ comment: 'comment',
105
+ processingInstruction: 'processinginstruction',
106
+ tagOpen: 'tagopen',
107
+ tagClose: 'tagclose',
108
+ // markupDeclaration: 'markupDeclaration',
109
+ } as Record<string, SaxyEventNames>
110
+
111
+ /**
112
+ * Expand a piece of XML text by replacing all XML entities by
113
+ * their canonical value. Ignore invalid and unknown entities.
114
+ *
115
+ * @param input A string of XML text
116
+ * @return The input string, expanded
117
+ */
118
+ const parseEntities = (input: string): string => {
119
+ let position = 0
120
+ let next = 0
121
+ const parts = []
122
+
123
+ while ((next = input.indexOf('&', position)) !== -1) {
124
+ if (next > position) {
125
+ const beforeEntity = input.slice(position, next)
126
+ parts.push(beforeEntity)
127
+ }
128
+
129
+ const semiColonPos = input.indexOf(';', next)
130
+
131
+ if (semiColonPos === -1) {
132
+ const remaining = input.slice(next)
133
+ parts.push(remaining)
134
+ position = input.length
135
+ break
136
+ }
137
+
138
+ const entityName = input.slice(next + 1, semiColonPos)
139
+
140
+ // If entityName contains invalid characters (space, &, <, >) or is empty,
141
+ // treat the initial & as a literal character
142
+ if (/[ &<>]/.test(entityName) || entityName.length === 0) {
143
+ parts.push('&')
144
+ position = next + 1
145
+ continue
146
+ }
147
+
148
+ if (entityName === 'quot') {
149
+ parts.push('"')
150
+ } else if (entityName === 'amp') {
151
+ parts.push('&')
152
+ } else if (entityName === 'apos') {
153
+ parts.push("'")
154
+ } else if (entityName === 'lt') {
155
+ parts.push('<')
156
+ } else if (entityName === 'gt') {
157
+ parts.push('>')
158
+ } else if (entityName.startsWith('#')) {
159
+ let value
160
+ if (entityName[1] === 'x' || entityName[1] === 'X') {
161
+ value = parseInt(entityName.slice(2), 16)
162
+ } else {
163
+ value = parseInt(entityName.slice(1), 10)
164
+ }
165
+
166
+ if (isNaN(value)) {
167
+ parts.push('&' + entityName + ';')
168
+ } else {
169
+ parts.push(String.fromCharCode(value))
170
+ }
171
+ } else {
172
+ // Unrecognized named entity, pass through
173
+ parts.push('&' + entityName + ';')
174
+ }
175
+ position = semiColonPos + 1
176
+ }
177
+
178
+ if (position < input.length) {
179
+ const remaining = input.slice(position)
180
+ parts.push(remaining)
181
+ }
182
+
183
+ const result = parts.join('')
184
+ return result
185
+ }
186
+
187
+ /**
188
+ * Parse a string of XML attributes to a map of attribute names to their values.
189
+ *
190
+ * @param input A string of XML attributes
191
+ * @throws If the string is malformed
192
+ * @return A map of attribute names to their values
193
+ */
194
+ export const parseAttrs = (
195
+ input: string,
196
+ ): { attrs: Record<string, string>; errors: string[] } => {
197
+ const attrs = {} as Record<string, string>
198
+ const end = input.length
199
+ let position = 0
200
+ const errors: string[] = []
201
+
202
+ const seekNextWhitespace = (pos: number): number => {
203
+ pos += 1
204
+ while (pos < end && !isWhitespace(input[pos])) {
205
+ pos += 1
206
+ }
207
+ return pos
208
+ }
209
+
210
+ attrLoop: while (position < end) {
211
+ // Skip all whitespace
212
+ if (isWhitespace(input[position])) {
213
+ position += 1
214
+ continue
215
+ }
216
+
217
+ // Check that the attribute name contains valid chars
218
+ let startName = position
219
+
220
+ while (input[position] !== '=' && position < end) {
221
+ if (isWhitespace(input[position])) {
222
+ errors.push(
223
+ `Attribute names may not contain whitespace: ${input.slice(startName, position)}`,
224
+ )
225
+ continue attrLoop
226
+ }
227
+
228
+ position += 1
229
+ }
230
+
231
+ // This is XML, so we need a value for the attribute
232
+ if (position === end) {
233
+ errors.push(
234
+ `Expected a value for the attribute: ${input.slice(startName, position)}`,
235
+ )
236
+ break
237
+ }
238
+
239
+ const attrName = input.slice(startName, position)
240
+ position += 1
241
+ const startQuote = input[position]
242
+ position += 1
243
+
244
+ if (startQuote !== '"' && startQuote !== "'") {
245
+ position = seekNextWhitespace(position)
246
+ errors.push(
247
+ `Attribute values should be quoted: ${input.slice(startName, position)}`,
248
+ )
249
+ continue
250
+ }
251
+
252
+ const endQuote = input.indexOf(startQuote, position)
253
+
254
+ if (endQuote === -1) {
255
+ position = seekNextWhitespace(position)
256
+ errors.push(
257
+ `Unclosed attribute value: ${input.slice(startName, position)}`,
258
+ )
259
+ continue
260
+ }
261
+
262
+ const attrValue = input.slice(position, endQuote)
263
+
264
+ attrs[attrName] = attrValue
265
+ position = endQuote + 1
266
+ }
267
+
268
+ return { attrs, errors }
269
+ }
270
+
271
+ /**
272
+ * Find the first character in a string that matches a predicate
273
+ * while being outside the given delimiters.
274
+ *
275
+ * @param haystack String to search in
276
+ * @param predicate Checks whether a character is permissible
277
+ * @param [delim=''] Delimiter inside which no match should be
278
+ * returned. If empty, all characters are considered.
279
+ * @param [fromIndex=0] Start the search from this index
280
+ * @return Index of the first match, or -1 if no match
281
+ */
282
+ const findIndexOutside = (
283
+ haystack: string,
284
+ predicate: Function,
285
+ delim = '',
286
+ fromIndex = 0,
287
+ ) => {
288
+ const length = haystack.length
289
+ let index = fromIndex
290
+ let inDelim = false
291
+
292
+ while (index < length && (inDelim || !predicate(haystack[index]))) {
293
+ if (haystack[index] === delim) {
294
+ inDelim = !inDelim
295
+ }
296
+
297
+ ++index
298
+ }
299
+
300
+ return index === length ? -1 : index
301
+ }
302
+
303
+ /**
304
+ * Parse an XML stream and emit events corresponding
305
+ * to the different tokens encountered.
306
+ */
307
+ export class Saxy extends Transform {
308
+ private _decoder: StringDecoder
309
+ private _tagStack: string[]
310
+ private _waiting: { token: string; data: unknown } | null
311
+ private _schema: TagSchema | null
312
+ private _textBuffer: string // NEW: Text buffer as class member
313
+ private _shouldParseEntities: boolean
314
+
315
+ /**
316
+ * Parse a string of XML attributes to a map of attribute names
317
+ * to their values
318
+ *
319
+ * @param input A string of XML attributes
320
+ * @throws If the string is malformed
321
+ * @return A map of attribute names to their values
322
+ */
323
+ static parseAttrs = parseAttrs
324
+
325
+ /**
326
+ * Expand a piece of XML text by replacing all XML entities
327
+ * by their canonical value. Ignore invalid and unknown
328
+ * entities
329
+ *
330
+ * @param input A string of XML text
331
+ * @return The input string, expanded
332
+ */
333
+ static parseEntities = parseEntities
334
+
335
+ /**
336
+ * Create a new parser instance.
337
+ * @param schema Optional schema defining allowed top-level tags and their children
338
+ */
339
+ constructor(schema?: TagSchema, shouldParseEntities: boolean = true) {
340
+ super({ decodeStrings: false, defaultEncoding: 'utf8' })
341
+
342
+ this._decoder = new StringDecoder('utf8')
343
+
344
+ // Stack of tags that were opened up until the current cursor position
345
+ this._tagStack = []
346
+
347
+ // Not waiting initially
348
+ this._waiting = null
349
+
350
+ // Store schema if provided
351
+ this._schema = schema || null
352
+
353
+ // Initialize text buffer
354
+ this._textBuffer = ''
355
+
356
+ this._shouldParseEntities = shouldParseEntities
357
+ }
358
+
359
+ /**
360
+ * Handle a chunk of data written into the stream.
361
+ *
362
+ * @param chunk Chunk of data.
363
+ * @param encoding Encoding of the string, or 'buffer'.
364
+ * @param callback Called when the chunk has been parsed, with
365
+ * an optional error argument.
366
+ */
367
+ public _write(
368
+ chunk: Buffer | string,
369
+ encoding: string,
370
+ callback: NextFunction,
371
+ ) {
372
+ const data =
373
+ encoding === 'buffer'
374
+ ? this._decoder.write(chunk as Buffer)
375
+ : (chunk as string)
376
+
377
+ this._parseChunk(data, callback)
378
+ }
379
+
380
+ /**
381
+ * Handle the end of incoming data.
382
+ *
383
+ * @param callback
384
+ */
385
+ public _final(callback: NextFunction) {
386
+ // Make sure all data has been extracted from the decoder
387
+ this._parseChunk(this._decoder.end(), (err?: Error) => {
388
+ if (err) {
389
+ callback(err)
390
+ return
391
+ }
392
+
393
+ // Handle any remaining text buffer
394
+ if (this._textBuffer.length > 0) {
395
+ const parsedText = this._shouldParseEntities
396
+ ? parseEntities(this._textBuffer)
397
+ : this._textBuffer
398
+ this.emit(Node.text, { contents: parsedText })
399
+ this._textBuffer = ''
400
+ }
401
+
402
+ // Handle unclosed nodes
403
+ if (this._waiting !== null) {
404
+ switch (this._waiting.token) {
405
+ case Node.text:
406
+ // Text nodes are implicitly closed
407
+ this.emit('text', { contents: this._waiting.data })
408
+ break
409
+ case Node.cdata:
410
+ callback(new Error('Unclosed CDATA section'))
411
+ return
412
+ case Node.comment:
413
+ callback(new Error('Unclosed comment'))
414
+ return
415
+ case Node.processingInstruction:
416
+ callback(new Error('Unclosed processing instruction'))
417
+ return
418
+ case Node.tagOpen:
419
+ case Node.tagClose:
420
+ // We do not distinguish between unclosed opening
421
+ // or unclosed closing tags
422
+ // callback(new Error('Unclosed tag'))
423
+ return
424
+ default:
425
+ // Pass
426
+ }
427
+ }
428
+
429
+ if (this._tagStack.length !== 0) {
430
+ // callback(new Error(`Unclosed tags: ${this._tagStack.join(',')}`))
431
+ return
432
+ }
433
+
434
+ callback()
435
+ })
436
+ }
437
+
438
+ /**
439
+ * Immediately parse a complete chunk of XML and close the stream.
440
+ *
441
+ * @param input Input chunk.
442
+ */
443
+ public parse(input: Buffer | string): this {
444
+ this.end(input)
445
+ return this
446
+ }
447
+
448
+ /**
449
+ * Put the stream into waiting mode, which means we need more data
450
+ * to finish parsing the current token.
451
+ *
452
+ * @param token Type of token that is being parsed.
453
+ * @param data Pending data.
454
+ */
455
+ private _wait(token: string, data: unknown) {
456
+ this._waiting = { token, data }
457
+ }
458
+
459
+ /**
460
+ * Put the stream out of waiting mode.
461
+ *
462
+ * @return Any data that was pending.
463
+ */
464
+ private _unwait() {
465
+ if (this._waiting === null) {
466
+ return ''
467
+ }
468
+
469
+ const data = this._waiting.data
470
+ this._waiting = null
471
+ return data
472
+ }
473
+
474
+ /**
475
+ * Handle the opening of a tag in the text stream.
476
+ *
477
+ * Push the tag into the opened tag stack and emit the
478
+ * corresponding event on the event emitter.
479
+ *
480
+ * @param node Information about the opened tag.
481
+ */
482
+ private _handleTagOpening(node: TagOpenNode) {
483
+ const { name } = node
484
+
485
+ // If we have a schema, validate against it
486
+ if (this._schema) {
487
+ // For top-level tags
488
+ if (this._tagStack.length === 0) {
489
+ // Convert to text if not in schema
490
+ if (!this._schema[name]) {
491
+ this.emit(Node.text, { contents: node.rawTag })
492
+ return
493
+ }
494
+ }
495
+ // For nested tags
496
+ else {
497
+ const parentTag = this._tagStack[this._tagStack.length - 1]
498
+ // Convert to text if parent not in schema or this tag not allowed as child
499
+ if (
500
+ !this._schema[parentTag] ||
501
+ !includesMatch(this._schema[parentTag], name)
502
+ ) {
503
+ this.emit(Node.text, { contents: node.rawTag })
504
+ return
505
+ }
506
+ }
507
+ }
508
+
509
+ if (!node.isSelfClosing) {
510
+ this._tagStack.push(node.name)
511
+ }
512
+
513
+ this.emit(Node.tagOpen, node)
514
+
515
+ if (node.isSelfClosing) {
516
+ this.emit(Node.tagClose, {
517
+ name: node.name,
518
+ rawTag: '',
519
+ })
520
+ }
521
+ }
522
+
523
+ /**
524
+ * Parse a XML chunk.
525
+ *
526
+ * @private
527
+ * @param input A string with the chunk data.
528
+ * @param callback Called when the chunk has been parsed, with
529
+ * an optional error argument.
530
+ */
531
+ private _parseChunk(input: string, callback: NextFunction) {
532
+ // Use pending data if applicable and get out of waiting mode
533
+ const waitingData = this._unwait()
534
+ input = waitingData + input
535
+
536
+ let chunkPos = 0
537
+ const end = input.length
538
+
539
+ while (chunkPos < end) {
540
+ if (
541
+ input[chunkPos] !== '<' ||
542
+ (chunkPos + 1 < end && !this._isXMLTagStart(input, chunkPos + 1))
543
+ ) {
544
+ // Find next potential tag, but verify it's actually a tag
545
+ let nextTag = input.indexOf('<', chunkPos)
546
+ while (
547
+ nextTag !== -1 &&
548
+ nextTag + 1 < end &&
549
+ !this._isXMLTagStart(input, nextTag + 1)
550
+ ) {
551
+ nextTag = input.indexOf('<', nextTag + 1)
552
+ }
553
+
554
+ // We read a TEXT node but there might be some
555
+ // more text data left, so we wait
556
+ if (nextTag === -1) {
557
+ let chunk = input.slice(chunkPos)
558
+
559
+ if (this._tagStack.length === 1 && !chunk.trim()) {
560
+ chunk = ''
561
+ }
562
+
563
+ // Check for incomplete entity at end
564
+ const lastAmp = chunk.lastIndexOf('&')
565
+ if (
566
+ this._shouldParseEntities &&
567
+ lastAmp !== -1 &&
568
+ chunk.indexOf(';', lastAmp) === -1
569
+ ) {
570
+ // Only consider it a pending entity if it looks like the start of one
571
+ const postAmp = chunk.slice(lastAmp + 1)
572
+ const isPotentialEntity =
573
+ /^(#\d*)?$/.test(postAmp) || // Numeric entity
574
+ /^[a-zA-Z]{0,6}$/.test(postAmp) // Named entity
575
+ if (isPotentialEntity) {
576
+ // Store incomplete entity for next chunk
577
+ this._wait(Node.text, chunk.slice(lastAmp))
578
+ chunk = chunk.slice(0, lastAmp)
579
+ }
580
+ }
581
+
582
+ if (chunk.length > 0) {
583
+ this._textBuffer += chunk
584
+ }
585
+
586
+ chunkPos = end
587
+ break
588
+ }
589
+
590
+ // A tag follows, so we can be confident that
591
+ // we have all the data needed for the TEXT node
592
+ let chunk = input.slice(chunkPos, nextTag)
593
+
594
+ if (this._tagStack.length === 1 && !chunk.trim()) {
595
+ chunk = ''
596
+ }
597
+
598
+ // Only emit non-whitespace text or text within a single tag (not between tags)
599
+ if (chunk.length > 0) {
600
+ this._textBuffer += chunk
601
+ }
602
+
603
+ // We've reached a tag boundary, emit any buffered text
604
+ if (this._textBuffer.length > 0) {
605
+ const parsedText = this._shouldParseEntities
606
+ ? parseEntities(this._textBuffer)
607
+ : this._textBuffer
608
+ this.emit(Node.text, { contents: parsedText })
609
+ this._textBuffer = ''
610
+ }
611
+
612
+ chunkPos = nextTag
613
+ }
614
+
615
+ // Invariant: the cursor now points on the name of a tag,
616
+ // after an opening angled bracket
617
+ chunkPos += 1
618
+
619
+ // Recognize regular tags (< ... >)
620
+ const tagClose = findIndexOutside(
621
+ input,
622
+ (char: string) => char === '>',
623
+ '"',
624
+ chunkPos,
625
+ )
626
+
627
+ if (tagClose === -1) {
628
+ this._wait(Node.tagOpen, input.slice(chunkPos - 1))
629
+ break
630
+ }
631
+
632
+ // Check if the tag is a closing tag
633
+ if (input[chunkPos] === '/') {
634
+ const tagName = input.slice(chunkPos + 1, tagClose)
635
+ const stackedTagName = this._tagStack[this._tagStack.length - 1]
636
+
637
+ // Convert closing tag to text if it doesn't match schema validation
638
+ if (this._schema) {
639
+ // For top-level tags
640
+ if (this._tagStack.length === 1) {
641
+ if (!this._schema[tagName]) {
642
+ const rawTag = input.slice(chunkPos - 1, tagClose + 1)
643
+ this.emit(Node.text, { contents: rawTag })
644
+ chunkPos = tagClose + 1
645
+ continue
646
+ }
647
+ }
648
+ // For nested tags
649
+ else {
650
+ const parentTag = this._tagStack[this._tagStack.length - 2]
651
+ if (
652
+ !this._schema[parentTag] ||
653
+ !includesMatch(this._schema[parentTag], tagName)
654
+ ) {
655
+ const rawTag = input.slice(chunkPos - 1, tagClose + 1)
656
+ this.emit(Node.text, { contents: rawTag })
657
+ chunkPos = tagClose + 1
658
+ continue
659
+ }
660
+ }
661
+ }
662
+
663
+ if (tagName === stackedTagName) {
664
+ this._tagStack.pop()
665
+ }
666
+
667
+ // Only emit if the tag matches what we expect (or if there is no schema)
668
+ if (!this._schema || stackedTagName === tagName) {
669
+ this.emit(Node.tagClose, {
670
+ name: tagName,
671
+ rawTag: input.slice(chunkPos - 1, tagClose + 1),
672
+ })
673
+ } else {
674
+ // Emit as text if the tag doesn't match
675
+ const rawTag = input.slice(chunkPos - 1, tagClose + 1)
676
+ this.emit(Node.text, { contents: rawTag })
677
+ }
678
+
679
+ chunkPos = tagClose + 1
680
+ continue
681
+ }
682
+
683
+ // Check if the tag is self-closing
684
+ const isSelfClosing = input[tagClose - 1] === '/'
685
+ let realTagClose = isSelfClosing ? tagClose - 1 : tagClose
686
+
687
+ // Extract the tag name and attributes
688
+ const whitespace = input.slice(chunkPos).search(/\s/)
689
+
690
+ // Get the raw tag text for potential text node conversion
691
+ const rawTag = input.slice(chunkPos - 1, tagClose + 1)
692
+
693
+ if (whitespace === -1 || whitespace >= tagClose - chunkPos) {
694
+ // Tag without any attribute
695
+ this._handleTagOpening({
696
+ name: input.slice(chunkPos, realTagClose),
697
+ attrs: '',
698
+ isSelfClosing,
699
+ rawTag,
700
+ })
701
+ } else if (whitespace === 0) {
702
+ // Invalid tag starting with whitespace - emit as text
703
+ this.emit(Node.text, { contents: rawTag })
704
+ } else {
705
+ // Tag with attributes
706
+ this._handleTagOpening({
707
+ name: input.slice(chunkPos, chunkPos + whitespace),
708
+ attrs: input.slice(chunkPos + whitespace, realTagClose),
709
+ isSelfClosing,
710
+ rawTag,
711
+ })
712
+ }
713
+
714
+ chunkPos = tagClose + 1
715
+ }
716
+
717
+ // Emit any buffered text at the end of the chunk if there's no pending entity
718
+ if (this._textBuffer.length > 0) {
719
+ const parsedText = this._shouldParseEntities
720
+ ? parseEntities(this._textBuffer)
721
+ : this._textBuffer
722
+ this.emit(Node.text, { contents: parsedText })
723
+ this._textBuffer = ''
724
+ }
725
+
726
+ callback()
727
+ }
728
+
729
+ /**
730
+ * Check if a potential XML tag start is actually a valid tag
731
+ * @param input The input string
732
+ * @param pos Position after the < character
733
+ * @returns true if this is a valid XML tag start
734
+ */
735
+ private _isXMLTagStart(input: string, pos: number): boolean {
736
+ // Valid XML tags must start with a letter, underscore or colon
737
+ // https://www.w3.org/TR/xml/#NT-NameStartChar
738
+ const firstChar = input[pos]
739
+ return /[A-Za-z_:]/.test(firstChar) || firstChar === '/'
740
+ }
741
+ }