oh-my-opencode 5.0.0-beta.2 → 5.0.0-beta.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 (460) hide show
  1. package/.agents/command/publish.md +44 -16
  2. package/.agents/skills/publish/SKILL.md +44 -16
  3. package/.agents/skills/senpi-qa/SKILL.md +80 -0
  4. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.mjs +65 -0
  5. package/.agents/skills/senpi-qa/scripts/resolve-evidence-dir.test.mjs +171 -0
  6. package/.agents/skills/work-with-pr/SKILL.md +37 -23
  7. package/.opencode/command/publish.md +44 -16
  8. package/.opencode/skills/work-with-pr/SKILL.md +37 -23
  9. package/README.ja.md +25 -21
  10. package/README.ko.md +25 -21
  11. package/README.md +38 -23
  12. package/README.ru.md +24 -20
  13. package/README.zh-cn.md +25 -21
  14. package/dist/agents/atlas/agent.d.ts +0 -1
  15. package/dist/agents/sisyphus/grok-4.d.ts +20 -0
  16. package/dist/agents/sisyphus/index.d.ts +2 -0
  17. package/dist/agents/sisyphus-agent-config.d.ts +6 -0
  18. package/dist/agents/sisyphus-agent-factory.d.ts +1 -1
  19. package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +15 -4
  20. package/dist/agents/types.d.ts +2 -2
  21. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  22. package/dist/cli/index.js +23057 -20893
  23. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  24. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  25. package/dist/cli/runtime-commands.d.ts +1 -1
  26. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  27. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  28. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  29. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  30. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  31. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  32. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  34. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  35. package/dist/cli-node/index.js +23093 -20929
  36. package/dist/config/schema/commands.d.ts +1 -1
  37. package/dist/config/schema/hooks.d.ts +1 -1
  38. package/dist/config/schema/oh-my-opencode-config.d.ts +4 -1
  39. package/dist/config/schema/ulw-execute.d.ts +5 -0
  40. package/dist/config/validate.d.ts +2 -0
  41. package/dist/create-hooks.d.ts +3 -1
  42. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  43. package/dist/features/btw-side/context-injector.d.ts +15 -0
  44. package/dist/features/btw-side/index.d.ts +8 -0
  45. package/dist/features/btw-side/metadata.d.ts +15 -0
  46. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  47. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  48. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  49. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  50. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  51. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  52. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  53. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  54. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  55. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  56. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  57. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  58. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  59. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  60. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  61. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  62. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  63. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  64. package/dist/features/builtin-commands/types.d.ts +1 -1
  65. package/dist/features/opengateway-provider/index.d.ts +13 -0
  66. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  67. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  68. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  69. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  70. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  71. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  72. package/dist/hooks/atlas/types.d.ts +1 -0
  73. package/dist/hooks/index.d.ts +1 -1
  74. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  75. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  76. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  77. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  78. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  79. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  80. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  81. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  82. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  83. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  84. package/dist/index.js +11724 -6355
  85. package/dist/oh-my-opencode.schema.json +15 -2
  86. package/dist/plugin/chat-message/types.d.ts +3 -3
  87. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  88. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  89. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  90. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  91. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  92. package/dist/plugin/messages-transform.d.ts +1 -0
  93. package/dist/shared/index.d.ts +1 -0
  94. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  95. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  96. package/dist/shared/shell-env.d.ts +1 -1
  97. package/dist/skills/ast-grep/AGENTS.md +51 -0
  98. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  99. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  100. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  101. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  102. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  103. package/dist/skills/frontend/SKILL.md +11 -7
  104. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  105. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  106. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  107. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  108. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  109. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  110. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  111. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  112. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  113. package/dist/skills/review-work/SKILL.md +3 -3
  114. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  115. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  116. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  117. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  118. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  119. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  120. package/dist/skills/ulw-plan/SKILL.md +6 -6
  121. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  122. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  123. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  124. package/dist/skills/ulw-research/SKILL.md +1 -1
  125. package/dist/skills/visual-qa/AGENTS.md +58 -0
  126. package/dist/skills/visual-qa/SKILL.md +3 -2
  127. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  128. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  129. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  130. package/dist/tui.js +8824 -8906
  131. package/package.json +38 -35
  132. package/packages/git-bash-mcp/dist/cli.js +5 -1
  133. package/packages/git-bash-mcp/package.json +1 -1
  134. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  135. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  136. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  137. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +66 -13
  138. package/packages/lsp-core/src/lsp/client-wrapper.ts +70 -18
  139. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  140. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  141. package/packages/lsp-core/src/lsp/workspace-markers.ts +1 -0
  142. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  143. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  144. package/packages/lsp-core/src/tools/rename.ts +4 -2
  145. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  146. package/packages/lsp-daemon/dist/cli.js +246 -185
  147. package/packages/lsp-daemon/dist/client.js +222 -164
  148. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  149. package/packages/lsp-daemon/dist/index.js +236 -177
  150. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  151. package/packages/lsp-tools-mcp/dist/cli.js +198 -136
  152. package/packages/lsp-tools-mcp/dist/lsp/manager.js +62 -92
  153. package/packages/lsp-tools-mcp/dist/mcp.js +200 -138
  154. package/packages/lsp-tools-mcp/dist/request-context.js +11 -12
  155. package/packages/lsp-tools-mcp/dist/tools.js +204 -146
  156. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  157. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  158. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  159. package/packages/omo-codex/plugin/README.md +1 -1
  160. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +32 -31
  161. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  162. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  163. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  164. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +224 -81
  165. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +224 -82
  166. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  167. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  168. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  169. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  170. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  171. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  172. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  173. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  174. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  175. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  176. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  177. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  178. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  179. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  180. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  181. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  182. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  183. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  184. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  185. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  186. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  187. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  188. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  189. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  190. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  191. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +217 -171
  192. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  193. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  194. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  195. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  196. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  197. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  198. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  199. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  200. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  201. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  202. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  203. package/packages/omo-codex/plugin/components/rules/dist/cli.js +57 -42
  204. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  205. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  206. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  207. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  208. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +6 -2
  209. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  210. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  211. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  212. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  213. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  214. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  215. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  216. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  217. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  218. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  219. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  220. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  221. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  222. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  223. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  224. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  225. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  226. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  227. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +1 -2
  228. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  229. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  230. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  231. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  232. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  233. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  234. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  235. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  236. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  237. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2433 -422
  238. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2437 -426
  239. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  240. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  241. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  242. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  243. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  244. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  245. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  246. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  247. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  248. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  249. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  250. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  251. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  252. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  253. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  254. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  255. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  256. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  257. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  258. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  259. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  260. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  261. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  262. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  263. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  264. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  265. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  266. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  267. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  268. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  269. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  270. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  271. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  272. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  273. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  274. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +16 -0
  275. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  276. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  277. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  278. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2 -4
  279. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  280. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  281. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  282. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  283. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  284. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  285. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  286. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  287. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  288. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  289. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  290. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  291. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  292. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  293. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +2 -2
  294. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  295. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  296. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  297. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  298. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  299. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  300. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  301. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  302. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  303. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  304. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  305. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  306. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  307. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  308. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  309. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  310. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  311. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  312. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  313. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  314. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  315. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  316. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  317. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  318. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  319. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  320. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  321. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  322. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  323. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  324. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  325. package/packages/omo-codex/plugin/package-lock.json +681 -395
  326. package/packages/omo-codex/plugin/package.json +2 -2
  327. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  328. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  329. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  330. package/packages/omo-codex/plugin/shared/package.json +3 -4
  331. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  332. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  333. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  334. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  335. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  336. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  337. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  338. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  339. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  340. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  341. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  342. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  343. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  344. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  345. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  346. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  347. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  348. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  349. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  350. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  351. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  352. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  353. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  354. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  355. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  356. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  357. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  358. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  359. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  360. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  361. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  362. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  363. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +1 -1
  364. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  365. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  366. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  367. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  368. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  369. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  370. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  371. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  372. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  373. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  374. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  375. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  376. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  377. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  378. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  379. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  380. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  381. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  382. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  383. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  384. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  385. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  386. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  387. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  388. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  389. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  390. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2601 -528
  391. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  392. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  393. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  394. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  395. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  396. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  397. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  398. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  399. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  400. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  401. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  402. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  403. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  404. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  405. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  406. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  407. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  408. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  409. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  410. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  411. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  412. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  413. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  414. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  415. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  416. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  417. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  418. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  419. package/packages/shared-skills/skills/ulw-research/SKILL.md +1 -1
  420. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  421. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  422. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  423. package/script/qa/xterm-live-terminal.mjs +18 -2
  424. package/dist/config/schema/start-work.d.ts +0 -5
  425. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  426. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  427. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  428. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  429. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  430. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  432. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  433. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  434. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  435. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  436. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  437. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  438. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  439. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  440. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  441. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  442. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  443. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  444. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  445. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  446. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  447. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  448. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  449. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  450. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  451. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  452. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  453. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  454. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  455. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  456. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  457. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  458. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  459. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  460. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -174,6 +174,7 @@ function writePostHogActivityState(stateDir, nextState, diagnostics) {
174
174
  // ../../telemetry-core/src/constants.ts
175
175
  var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
176
176
  var DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
177
+ var UNCONFIGURED_POSTHOG_API_KEY = "phc_REPLACE_ME_OMO_NATIVE";
177
178
 
178
179
  // ../../telemetry-core/src/diagnostics.ts
179
180
  import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
@@ -310,6 +311,9 @@ function shouldDisableTelemetry(input) {
310
311
  const env = input.env ?? process.env;
311
312
  const globalPrefix = input.globalEnvPrefix ?? "OMO";
312
313
  const prefixes = Array.from(new Set([globalPrefix, input.productEnvPrefix]));
314
+ if (isDisableFlag(env["DO_NOT_TRACK"])) {
315
+ return true;
316
+ }
313
317
  for (const prefix of prefixes) {
314
318
  if (isDisableFlag(env[`${prefix}_DISABLE_POSTHOG`])) {
315
319
  return true;
@@ -323,21 +327,18 @@ function shouldDisableTelemetry(input) {
323
327
  function getTelemetryApiKey(env = process.env, defaultApiKey = DEFAULT_POSTHOG_API_KEY) {
324
328
  return env["POSTHOG_API_KEY"]?.trim() ?? defaultApiKey;
325
329
  }
326
- function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
327
- return env["POSTHOG_HOST"]?.trim() || defaultHost;
330
+ function isConfiguredTelemetryApiKey(apiKey) {
331
+ const normalized = apiKey.trim();
332
+ return normalized.length > 0 && normalized !== UNCONFIGURED_POSTHOG_API_KEY;
328
333
  }
329
-
330
- // ../../telemetry-core/src/machine-id.ts
331
- import { createHash } from "node:crypto";
332
- import os2 from "node:os";
333
- function getDefaultTelemetryOsProvider() {
334
- return os2;
334
+ function hasTelemetryApiKey(env, defaultApiKey) {
335
+ return isConfiguredTelemetryApiKey(getTelemetryApiKey(env, defaultApiKey));
335
336
  }
336
- function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
337
- return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
337
+ function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
338
+ return env["POSTHOG_HOST"]?.trim() || defaultHost;
338
339
  }
339
340
 
340
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
341
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
341
342
  import { dirname, posix, sep } from "node:path";
342
343
  function createModulerModifier() {
343
344
  const getModuleFromFileName = createGetModuleFromFilename();
@@ -373,7 +374,7 @@ function normalizeWindowsPath(path2) {
373
374
  return path2.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
374
375
  }
375
376
 
376
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/featureFlagUtils.mjs
377
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/featureFlagUtils.mjs
377
378
  var normalizeFlagsResponse = (flagsResponse) => {
378
379
  if ("flags" in flagsResponse) {
379
380
  const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
@@ -443,8 +444,69 @@ var parsePayload = (response) => {
443
444
  return response;
444
445
  }
445
446
  };
447
+ var MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES = [
448
+ "utm_source",
449
+ "utm_medium",
450
+ "utm_campaign",
451
+ "utm_content",
452
+ "utm_term",
453
+ "gad_source",
454
+ "mc_cid",
455
+ "gclid",
456
+ "gclsrc",
457
+ "dclid",
458
+ "gbraid",
459
+ "wbraid",
460
+ "fbclid",
461
+ "msclkid",
462
+ "twclid",
463
+ "li_fat_id",
464
+ "igshid",
465
+ "ttclid",
466
+ "rdt_cid",
467
+ "epik",
468
+ "qclid",
469
+ "sccid",
470
+ "irclid",
471
+ "_kx"
472
+ ];
473
+ var MINIMAL_FLAG_CALLED_EVENT_PROPERTIES = [
474
+ "$feature_flag",
475
+ "$feature_flag_response",
476
+ "$feature_flag_has_experiment",
477
+ "$feature_flag_id",
478
+ "$feature_flag_version",
479
+ "$feature_flag_reason",
480
+ "$feature_flag_request_id",
481
+ "$feature_flag_evaluated_at",
482
+ "$feature_flag_error",
483
+ "locally_evaluated",
484
+ "$groups",
485
+ "$process_person_profile",
486
+ "$geoip_disable",
487
+ "$current_url",
488
+ "$pathname",
489
+ "$referring_domain",
490
+ ...MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES,
491
+ "$session_id",
492
+ "$window_id",
493
+ "$lib",
494
+ "$lib_version",
495
+ "$device_id",
496
+ "$is_server"
497
+ ];
498
+ var minimizeFlagCalledEventProperties = (properties, transportKeys = []) => {
499
+ const minimal = {};
500
+ const copyKey = (key) => {
501
+ if (properties[key] !== undefined)
502
+ minimal[key] = properties[key];
503
+ };
504
+ MINIMAL_FLAG_CALLED_EVENT_PROPERTIES.forEach(copyKey);
505
+ transportKeys.forEach(copyKey);
506
+ return minimal;
507
+ };
446
508
 
447
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/types.mjs
509
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/types.mjs
448
510
  var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedProperty) {
449
511
  PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
450
512
  PostHogPersistedProperty["DistinctId"] = "distinct_id";
@@ -459,6 +521,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
459
521
  PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
460
522
  PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
461
523
  PostHogPersistedProperty["Queue"] = "queue";
524
+ PostHogPersistedProperty["AiQueue"] = "ai_queue";
525
+ PostHogPersistedProperty["AiCaptureQueue"] = "ai_capture_queue";
462
526
  PostHogPersistedProperty["LogsQueue"] = "logs_queue";
463
527
  PostHogPersistedProperty["OptedOut"] = "opted_out";
464
528
  PostHogPersistedProperty["SessionId"] = "session_id";
@@ -469,6 +533,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
469
533
  PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
470
534
  PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
471
535
  PostHogPersistedProperty["SessionReplay"] = "session_replay";
536
+ PostHogPersistedProperty["PushRegistered"] = "push_registered";
537
+ PostHogPersistedProperty["SessionReplayEventTriggerActivatedSession"] = "session_replay_event_trigger_activated_session";
472
538
  PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
473
539
  PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
474
540
  PostHogPersistedProperty["Surveys"] = "surveys";
@@ -478,7 +544,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
478
544
  return PostHogPersistedProperty;
479
545
  }({});
480
546
 
481
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/gzip.mjs
547
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/gzip.mjs
482
548
  function isGzipSupported() {
483
549
  return "CompressionStream" in globalThis && "TextEncoder" in globalThis && "Response" in globalThis && typeof Response.prototype.blob == "function";
484
550
  }
@@ -528,7 +594,7 @@ var validateNativeGzip = async (compressed, inputBytes) => {
528
594
  async function gzipCompress(input, isDebug = true, options) {
529
595
  try {
530
596
  const inputBytes = new TextEncoder().encode(input);
531
- const compressedStream = new CompressionStream("gzip");
597
+ const compressedStream = new globalThis.CompressionStream("gzip");
532
598
  const writer = compressedStream.writable.getWriter();
533
599
  const writePromise = writer.write(inputBytes).then(() => writer.close()).catch(async (err) => {
534
600
  try {
@@ -552,7 +618,34 @@ async function gzipCompress(input, isDebug = true, options) {
552
618
  }
553
619
  }
554
620
 
555
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/bot-detection.mjs
621
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/json-utils.mjs
622
+ var MAX_JSON_SAFE_VALUE_DEPTH = 20;
623
+ var MAX_JSON_SAFE_VALUE_ITEMS = 1000;
624
+ var MAX_JSON_SAFE_VALUE_NODES = 1e4;
625
+ var CIRCULAR_VALUE = "[Circular]";
626
+ var TRUNCATED_VALUE = "[Truncated]";
627
+ var UNSERIALIZABLE_VALUE = "[Unserializable]";
628
+ var FUNCTION_VALUE = "[Function]";
629
+ var dateGetTime = Date.prototype.getTime;
630
+ var dateToISOString = Date.prototype.toISOString;
631
+ function sanitizeString(value) {
632
+ let output = "";
633
+ for (let index = 0;index < value.length; index++) {
634
+ const codeUnit = value.charCodeAt(index);
635
+ if (codeUnit >= 55296 && codeUnit <= 56319) {
636
+ const nextCodeUnit = value.charCodeAt(index + 1);
637
+ if (nextCodeUnit >= 56320 && nextCodeUnit <= 57343) {
638
+ output += value[index] + value[index + 1];
639
+ index++;
640
+ } else
641
+ output += "�";
642
+ } else
643
+ output += codeUnit >= 56320 && codeUnit <= 57343 ? "�" : value[index];
644
+ }
645
+ return output;
646
+ }
647
+
648
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/bot-detection.mjs
556
649
  var DEFAULT_BLOCKED_UA_STRS = [
557
650
  "amazonbot",
558
651
  "amazonproductbot",
@@ -641,7 +734,31 @@ var isBlockedUA = function(ua, customBlockedUserAgents = []) {
641
734
  return uaLower.indexOf(blockedUaLower) !== -1;
642
735
  });
643
736
  };
644
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/type-utils.mjs
737
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/string-utils.mjs
738
+ function safeJsonStringify(value) {
739
+ const ancestors = [];
740
+ return JSON.stringify(value, function(_key, replacementValue) {
741
+ if (typeof replacementValue == "bigint")
742
+ return replacementValue.toString();
743
+ if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
744
+ return;
745
+ if (replacementValue instanceof Error)
746
+ return {
747
+ name: replacementValue.name,
748
+ message: replacementValue.message,
749
+ stack: replacementValue.stack
750
+ };
751
+ if (replacementValue && typeof replacementValue == "object") {
752
+ while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this)
753
+ ancestors.pop();
754
+ if (ancestors.includes(replacementValue))
755
+ return "[Circular]";
756
+ ancestors.push(replacementValue);
757
+ }
758
+ return replacementValue;
759
+ }) ?? "null";
760
+ }
761
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/type-utils.mjs
645
762
  var nativeIsArray = Array.isArray;
646
763
  var ObjProto = Object.prototype;
647
764
  var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
@@ -653,14 +770,28 @@ var isObject = (x) => x === Object(x) && !isArray(x);
653
770
  var isUndefined = (x) => x === undefined;
654
771
  var isString = (x) => type_utils_toString.call(x) == "[object String]";
655
772
  var isEmptyString = (x) => isString(x) && x.trim().length === 0;
773
+ var isNull = (x) => x === null;
774
+ var isNullish = (x) => isUndefined(x) || isNull(x);
656
775
  var isNumber = (x) => type_utils_toString.call(x) == "[object Number]" && x === x;
657
- var isPlainError = (x) => x instanceof Error;
776
+ var isBoolean = (x) => type_utils_toString.call(x) === "[object Boolean]";
658
777
  function isPrimitive(value) {
659
778
  return value === null || typeof value != "object";
660
779
  }
661
780
  function isBuiltin(candidate, className) {
662
781
  return Object.prototype.toString.call(candidate) === `[object ${className}]`;
663
782
  }
783
+ function isError(candidate) {
784
+ switch (Object.prototype.toString.call(candidate)) {
785
+ case "[object Error]":
786
+ case "[object Exception]":
787
+ case "[object DOMException]":
788
+ case "[object DOMError]":
789
+ case "[object WebAssembly.Exception]":
790
+ return true;
791
+ default:
792
+ return isInstanceOf(candidate, Error);
793
+ }
794
+ }
664
795
  function isErrorEvent(event) {
665
796
  return isBuiltin(event, "ErrorEvent");
666
797
  }
@@ -678,7 +809,7 @@ function isInstanceOf(candidate, base) {
678
809
  }
679
810
  }
680
811
 
681
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/number-utils.mjs
812
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/number-utils.mjs
682
813
  function clampToRange(value, min, max, logger, fallbackValue) {
683
814
  if (min > max) {
684
815
  logger.warn("min cannot be greater than max.");
@@ -698,8 +829,16 @@ function clampToRange(value, min, max, logger, fallbackValue) {
698
829
  return clampToRange(fallbackValue || max, min, max, logger);
699
830
  }
700
831
 
701
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
832
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
702
833
  var ONE_DAY_IN_MS = 86400000;
834
+ var DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE = 1;
835
+ var DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE = 10;
836
+ function resolveExceptionRateLimiterConfig(config = {}) {
837
+ return {
838
+ refillRate: config.exceptionRateLimiterRefillRate ?? config.__exceptionRateLimiterRefillRate ?? DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE,
839
+ bucketSize: config.exceptionRateLimiterBucketSize ?? config.__exceptionRateLimiterBucketSize ?? DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE
840
+ };
841
+ }
703
842
 
704
843
  class BucketedRateLimiter {
705
844
  constructor(options) {
@@ -742,7 +881,7 @@ class BucketedRateLimiter {
742
881
  this._buckets = {};
743
882
  }
744
883
  }
745
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
884
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
746
885
  /*! For license information please see uuidv7.mjs.LICENSE.txt */
747
886
  var DIGITS = "0123456789abcdef";
748
887
 
@@ -920,33 +1059,45 @@ var defaultGenerator;
920
1059
  var uuidv7 = () => uuidv7obj().toString();
921
1060
  var uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator)).generate();
922
1061
 
923
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/promise-queue.mjs
1062
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/promise-queue.mjs
924
1063
  class PromiseQueue {
925
1064
  add(promise) {
926
1065
  const promiseUUID = uuidv7();
927
- this.promiseByIds[promiseUUID] = promise;
1066
+ const id = ++this.nextId;
1067
+ this.promiseByIds[promiseUUID] = {
1068
+ id,
1069
+ promise
1070
+ };
928
1071
  promise.catch(() => {}).finally(() => {
929
1072
  delete this.promiseByIds[promiseUUID];
930
1073
  });
931
1074
  return promise;
932
1075
  }
933
1076
  async join() {
934
- let promises = Object.values(this.promiseByIds);
1077
+ let promises = Object.values(this.promiseByIds).map((item) => item.promise);
935
1078
  let length = promises.length;
936
1079
  while (length > 0) {
937
1080
  await Promise.all(promises);
938
- promises = Object.values(this.promiseByIds);
1081
+ promises = Object.values(this.promiseByIds).map((item) => item.promise);
939
1082
  length = promises.length;
940
1083
  }
941
1084
  }
1085
+ getPromises(ignoredPromises = [], maxId = this.nextId) {
1086
+ const ignoredPromiseSet = new Set(ignoredPromises);
1087
+ return Object.values(this.promiseByIds).filter((item) => item.id <= maxId && !ignoredPromiseSet.has(item.promise)).map((item) => item.promise);
1088
+ }
1089
+ get maxId() {
1090
+ return this.nextId;
1091
+ }
942
1092
  get length() {
943
1093
  return Object.keys(this.promiseByIds).length;
944
1094
  }
945
1095
  constructor() {
946
1096
  this.promiseByIds = {};
1097
+ this.nextId = 0;
947
1098
  }
948
1099
  }
949
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/logger.mjs
1100
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/logger.mjs
950
1101
  function createConsole(consoleLike = console) {
951
1102
  const lockedMethods = {
952
1103
  log: consoleLike.log.bind(consoleLike),
@@ -987,7 +1138,7 @@ var passThrough = (fn) => fn();
987
1138
  function createLogger(prefix, maybeCall = passThrough) {
988
1139
  return _createLogger(prefix, maybeCall, createConsole());
989
1140
  }
990
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
1141
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
991
1142
  var MOBILE = "Mobile";
992
1143
  var IOS = "iOS";
993
1144
  var ANDROID = "Android";
@@ -1030,6 +1181,7 @@ var DUCKDUCKGO = "DuckDuckGo";
1030
1181
  var PALE_MOON = "Pale Moon";
1031
1182
  var WATERFOX = "Waterfox";
1032
1183
  var BRAVE = "Brave";
1184
+ var GOOGLE_SEARCH_APP = "Google Search App";
1033
1185
  var BROWSER_VERSION_REGEX_SUFFIX = "(\\d+(\\.\\d+)?)";
1034
1186
  var DEFAULT_BROWSER_VERSION_REGEX = new RegExp("Version/" + BROWSER_VERSION_REGEX_SUFFIX);
1035
1187
  var XBOX_REGEX = new RegExp(XBOX, "i");
@@ -1117,6 +1269,9 @@ var versionRegexes = {
1117
1269
  [WATERFOX]: [
1118
1270
  new RegExp(WATERFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1119
1271
  ],
1272
+ [GOOGLE_SEARCH_APP]: [
1273
+ new RegExp("GSA\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1274
+ ],
1120
1275
  [INTERNET_EXPLORER]: [
1121
1276
  new RegExp("(rv:|MSIE )" + BROWSER_VERSION_REGEX_SUFFIX)
1122
1277
  ],
@@ -1276,8 +1431,15 @@ var osMatchers = [
1276
1431
  ]
1277
1432
  ];
1278
1433
 
1279
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/index.mjs
1434
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/index.mjs
1280
1435
  var STRING_FORMAT = "utf8";
1436
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1437
+ function isValidUUID(value) {
1438
+ return typeof value == "string" && UUID_REGEX.test(value);
1439
+ }
1440
+ function getEventUuid(uuid, generateUuid) {
1441
+ return isValidUUID(uuid) ? uuid : generateUuid();
1442
+ }
1281
1443
  function removeTrailingSlash(url) {
1282
1444
  return url?.replace(/\/+$/, "");
1283
1445
  }
@@ -1305,7 +1467,26 @@ function safeSetTimeout(fn, timeout) {
1305
1467
  t?.unref && t?.unref();
1306
1468
  return t;
1307
1469
  }
1308
- var isError = (x) => x instanceof Error;
1470
+ async function raceWithTimeout(promise, timeoutMs, onTimeout) {
1471
+ let timeoutHandle;
1472
+ try {
1473
+ return await Promise.race([
1474
+ promise,
1475
+ new Promise((resolve, reject) => {
1476
+ timeoutHandle = safeSetTimeout(() => {
1477
+ try {
1478
+ onTimeout?.();
1479
+ resolve();
1480
+ } catch (error) {
1481
+ reject(error);
1482
+ }
1483
+ }, timeoutMs);
1484
+ })
1485
+ ]);
1486
+ } finally {
1487
+ clearTimeout(timeoutHandle);
1488
+ }
1489
+ }
1309
1490
  function allSettled(promises) {
1310
1491
  return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({
1311
1492
  status: "fulfilled",
@@ -1316,7 +1497,7 @@ function allSettled(promises) {
1316
1497
  }))));
1317
1498
  }
1318
1499
 
1319
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/logs/logs-utils.mjs
1500
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/logs/logs-utils.mjs
1320
1501
  var OTLP_SEVERITY_MAP = {
1321
1502
  trace: {
1322
1503
  text: "TRACE",
@@ -1344,7 +1525,570 @@ var OTLP_SEVERITY_MAP = {
1344
1525
  }
1345
1526
  };
1346
1527
  var DEFAULT_OTLP_SEVERITY = OTLP_SEVERITY_MAP.info;
1347
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/eventemitter.mjs
1528
+ var INT64_RANGE_LIMIT = 9223372036854776000;
1529
+ var propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
1530
+ function newState() {
1531
+ return {
1532
+ ancestors: new WeakSet,
1533
+ remainingNodes: MAX_JSON_SAFE_VALUE_NODES
1534
+ };
1535
+ }
1536
+ function toOtlpKeyValueList(attrs, logger2) {
1537
+ try {
1538
+ return encodeKeyValueList(attrs, logger2, newState(), 0);
1539
+ } catch {
1540
+ return [];
1541
+ }
1542
+ }
1543
+ function encodeAnyValue(value, logger2, state, depth) {
1544
+ if (state.remainingNodes <= 0)
1545
+ return {
1546
+ stringValue: TRUNCATED_VALUE
1547
+ };
1548
+ state.remainingNodes--;
1549
+ if (isBoolean(value))
1550
+ return {
1551
+ boolValue: value
1552
+ };
1553
+ if (typeof value == "number") {
1554
+ if (!Number.isFinite(value))
1555
+ return {
1556
+ stringValue: String(value)
1557
+ };
1558
+ if (Number.isInteger(value)) {
1559
+ if (Number.isSafeInteger(value))
1560
+ return {
1561
+ intValue: String(value)
1562
+ };
1563
+ if (typeof BigInt == "undefined")
1564
+ return {
1565
+ stringValue: String(value)
1566
+ };
1567
+ const decimal = BigInt(value).toString();
1568
+ if (value >= INT64_RANGE_LIMIT || value < -INT64_RANGE_LIMIT) {
1569
+ logger2?.debug(`Attribute ${decimal} is outside the int64 range; encoding it as a string`);
1570
+ return {
1571
+ stringValue: decimal
1572
+ };
1573
+ }
1574
+ return {
1575
+ intValue: decimal
1576
+ };
1577
+ }
1578
+ return {
1579
+ doubleValue: value
1580
+ };
1581
+ }
1582
+ if (typeof value == "string")
1583
+ return {
1584
+ stringValue: sanitizeString(value)
1585
+ };
1586
+ if (typeof value == "function")
1587
+ return {
1588
+ stringValue: FUNCTION_VALUE
1589
+ };
1590
+ if (typeof value == "symbol")
1591
+ return {
1592
+ stringValue: String(value)
1593
+ };
1594
+ if (typeof value == "object" && value !== null) {
1595
+ if (state.ancestors.has(value))
1596
+ return {
1597
+ stringValue: CIRCULAR_VALUE
1598
+ };
1599
+ if (depth >= MAX_JSON_SAFE_VALUE_DEPTH)
1600
+ return {
1601
+ stringValue: TRUNCATED_VALUE
1602
+ };
1603
+ if (value instanceof Date) {
1604
+ const time = value.getTime();
1605
+ const iso = Number.isFinite(time) ? value.toISOString() : String(value);
1606
+ return {
1607
+ stringValue: typeof iso == "string" ? sanitizeString(iso) : String(iso)
1608
+ };
1609
+ }
1610
+ state.ancestors.add(value);
1611
+ try {
1612
+ try {
1613
+ const toJSON = value.toJSON;
1614
+ if (typeof toJSON == "function")
1615
+ return encodeAnyValue(toJSON.call(value), logger2, state, depth + 1);
1616
+ } catch {}
1617
+ if (isArray(value))
1618
+ return {
1619
+ arrayValue: {
1620
+ values: encodeArrayValues(value, logger2, state, depth + 1)
1621
+ }
1622
+ };
1623
+ return {
1624
+ kvlistValue: {
1625
+ values: encodeKeyValueList(value, logger2, state, depth + 1)
1626
+ }
1627
+ };
1628
+ } finally {
1629
+ state.ancestors.delete(value);
1630
+ }
1631
+ }
1632
+ return {
1633
+ stringValue: sanitizeString(String(value))
1634
+ };
1635
+ }
1636
+ function encodeArrayValues(values, logger2, state, depth) {
1637
+ const result = [];
1638
+ const itemCount = Math.min(values.length, MAX_JSON_SAFE_VALUE_ITEMS);
1639
+ let index = 0;
1640
+ for (;index < itemCount && state.remainingNodes > 0; index++)
1641
+ try {
1642
+ const element = index in values ? values[index] : undefined;
1643
+ if (isNullish(element))
1644
+ continue;
1645
+ result.push(encodeAnyValue(element, logger2, state, depth));
1646
+ } catch {
1647
+ result.push({
1648
+ stringValue: UNSERIALIZABLE_VALUE
1649
+ });
1650
+ }
1651
+ if (values.length > index)
1652
+ result.push({
1653
+ stringValue: TRUNCATED_VALUE
1654
+ });
1655
+ return result;
1656
+ }
1657
+ function encodeKeyValueList(attrs, logger2, state, depth) {
1658
+ const result = [];
1659
+ for (const key in attrs)
1660
+ if (propertyIsEnumerable.call(attrs, key)) {
1661
+ if (result.length >= MAX_JSON_SAFE_VALUE_ITEMS || state.remainingNodes <= 0) {
1662
+ logger2?.debug("Attributes truncated: the value exceeds the OTLP encoder budget");
1663
+ break;
1664
+ }
1665
+ try {
1666
+ const value = attrs[key];
1667
+ if (isNull(value) || isUndefined(value))
1668
+ continue;
1669
+ result.push({
1670
+ key: sanitizeString(key),
1671
+ value: encodeAnyValue(value, logger2, state, depth)
1672
+ });
1673
+ } catch {
1674
+ result.push({
1675
+ key: sanitizeString(key),
1676
+ value: {
1677
+ stringValue: UNSERIALIZABLE_VALUE
1678
+ }
1679
+ });
1680
+ }
1681
+ }
1682
+ return result;
1683
+ }
1684
+
1685
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/metrics-utils.mjs
1686
+ var DEFAULT_HISTOGRAM_BOUNDS = [
1687
+ 0,
1688
+ 5,
1689
+ 10,
1690
+ 25,
1691
+ 50,
1692
+ 75,
1693
+ 100,
1694
+ 250,
1695
+ 500,
1696
+ 750,
1697
+ 1000,
1698
+ 2500,
1699
+ 5000,
1700
+ 7500,
1701
+ 1e4
1702
+ ];
1703
+ function msToUnixNano(ms) {
1704
+ return String(ms) + "000000";
1705
+ }
1706
+ function seriesKey(type, name, unit, attributes) {
1707
+ let attrsKey = "";
1708
+ if (attributes) {
1709
+ const keys = Object.keys(attributes).sort();
1710
+ attrsKey = keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(attributes[k])}`).join(",");
1711
+ }
1712
+ return `${type}\x00${name}\x00${unit ?? ""}\x00${attrsKey}`;
1713
+ }
1714
+ function bucketIndexFor(value, bounds) {
1715
+ for (let i = 0;i < bounds.length; i++)
1716
+ if (value <= bounds[i])
1717
+ return i;
1718
+ return bounds.length;
1719
+ }
1720
+ function buildMetricsResourceAttributes(config, scopeName, scopeVersion) {
1721
+ return {
1722
+ ...config.resourceAttributes,
1723
+ "service.name": config.serviceName || "unknown_service",
1724
+ ...config.environment && {
1725
+ "deployment.environment": config.environment
1726
+ },
1727
+ ...config.serviceVersion && {
1728
+ "service.version": config.serviceVersion
1729
+ },
1730
+ "telemetry.sdk.name": scopeName,
1731
+ "telemetry.sdk.version": scopeVersion
1732
+ };
1733
+ }
1734
+ function buildOtlpMetricsPayload(metrics, resourceAttributes, scopeName, scopeVersion) {
1735
+ return {
1736
+ resourceMetrics: [
1737
+ {
1738
+ resource: {
1739
+ attributes: toOtlpKeyValueList(resourceAttributes)
1740
+ },
1741
+ scopeMetrics: [
1742
+ {
1743
+ scope: {
1744
+ name: scopeName,
1745
+ version: scopeVersion
1746
+ },
1747
+ metrics
1748
+ }
1749
+ ]
1750
+ }
1751
+ ]
1752
+ };
1753
+ }
1754
+
1755
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/config.mjs
1756
+ var DEFAULT_FLUSH_INTERVAL_MS = 1e4;
1757
+ var DEFAULT_MAX_SERIES_PER_FLUSH = 1000;
1758
+ function resolveMetricsConfig(config) {
1759
+ const resourceAttributes = config?.resourceAttributes;
1760
+ return {
1761
+ serviceName: resourceAttributes?.["service.name"] ?? config?.serviceName,
1762
+ serviceVersion: resourceAttributes?.["service.version"] ?? config?.serviceVersion,
1763
+ environment: resourceAttributes?.["deployment.environment"] ?? config?.environment,
1764
+ resourceAttributes,
1765
+ beforeSend: config?.beforeSend,
1766
+ flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
1767
+ maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH
1768
+ };
1769
+ }
1770
+
1771
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/index.mjs
1772
+ var OTLP_TEMPORALITY_DELTA = 1;
1773
+
1774
+ class PostHogMetrics {
1775
+ constructor(_instance, _config, _logger) {
1776
+ this._instance = _instance;
1777
+ this._config = _config;
1778
+ this._logger = _logger;
1779
+ this._series = new Map;
1780
+ this._flushPromise = null;
1781
+ this._seriesCapWarned = false;
1782
+ this._typeByName = new Map;
1783
+ this._typeCollisionWarned = new Set;
1784
+ this._generation = 0;
1785
+ }
1786
+ count(name, value = 1, options) {
1787
+ this._capture({
1788
+ name,
1789
+ type: "count",
1790
+ value,
1791
+ unit: options?.unit,
1792
+ attributes: options?.attributes
1793
+ });
1794
+ }
1795
+ gauge(name, value, options) {
1796
+ this._capture({
1797
+ name,
1798
+ type: "gauge",
1799
+ value,
1800
+ unit: options?.unit,
1801
+ attributes: options?.attributes
1802
+ });
1803
+ }
1804
+ histogram(name, value, options) {
1805
+ this._capture({
1806
+ name,
1807
+ type: "histogram",
1808
+ value,
1809
+ unit: options?.unit,
1810
+ attributes: options?.attributes
1811
+ });
1812
+ }
1813
+ flush() {
1814
+ const prev = this._flushPromise;
1815
+ const run = async () => {
1816
+ if (prev)
1817
+ await prev.catch(() => {});
1818
+ await this._doFlush();
1819
+ };
1820
+ const p = run().finally(() => {
1821
+ if (this._flushPromise === p)
1822
+ this._flushPromise = null;
1823
+ });
1824
+ this._flushPromise = p;
1825
+ return p;
1826
+ }
1827
+ drainWindow() {
1828
+ if (this._series.size === 0)
1829
+ return null;
1830
+ const window = this._series;
1831
+ this._series = new Map;
1832
+ this._seriesCapWarned = false;
1833
+ this._typeByName = new Map;
1834
+ this._typeCollisionWarned = new Set;
1835
+ return this._buildPayload(window);
1836
+ }
1837
+ reset() {
1838
+ this._generation++;
1839
+ this._clearFlushTimer();
1840
+ this._series = new Map;
1841
+ this._flushPromise = null;
1842
+ this._seriesCapWarned = false;
1843
+ this._typeByName = new Map;
1844
+ this._typeCollisionWarned = new Set;
1845
+ }
1846
+ _capture(sample) {
1847
+ if (this._instance.isDisabled || this._instance.optedOut)
1848
+ return;
1849
+ const filtered = this._runBeforeSend(sample);
1850
+ if (filtered === null)
1851
+ return;
1852
+ if (!filtered.name || typeof filtered.name != "string")
1853
+ return void this._logger.warn("Dropping metric with empty name");
1854
+ if (typeof filtered.value != "number" || !Number.isFinite(filtered.value))
1855
+ return void this._logger.warn(`Dropping metric '${filtered.name}': value must be a finite number`);
1856
+ if (filtered.type === "count" && filtered.value < 0)
1857
+ return void this._logger.warn(`Dropping count '${filtered.name}': counters are monotonic, value must be >= 0`);
1858
+ let attributes;
1859
+ let key;
1860
+ try {
1861
+ attributes = filtered.attributes ? {
1862
+ ...filtered.attributes
1863
+ } : undefined;
1864
+ key = seriesKey(filtered.type, filtered.name, filtered.unit, attributes);
1865
+ } catch (e) {
1866
+ this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e);
1867
+ return;
1868
+ }
1869
+ let state = this._series.get(key);
1870
+ if (!state) {
1871
+ if (!this._admitNewSeries())
1872
+ return;
1873
+ state = {
1874
+ name: filtered.name,
1875
+ type: filtered.type,
1876
+ unit: filtered.unit,
1877
+ attributes,
1878
+ windowStartMs: Date.now()
1879
+ };
1880
+ this._series.set(key, state);
1881
+ }
1882
+ const seenType = this._typeByName.get(filtered.name);
1883
+ if (seenType === undefined)
1884
+ this._typeByName.set(filtered.name, filtered.type);
1885
+ else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
1886
+ this._typeCollisionWarned.add(filtered.name);
1887
+ this._logger.warn(`Metric name '${filtered.name}' is already used as a ${seenType}; recording it as a ${filtered.type} too will blend both series in charts. Use a distinct name.`);
1888
+ }
1889
+ this._fold(state, filtered.value);
1890
+ this._armFlushTimer();
1891
+ }
1892
+ _admitNewSeries() {
1893
+ if (this._series.size < this._config.maxSeriesPerFlush)
1894
+ return true;
1895
+ if (!this._seriesCapWarned) {
1896
+ this._seriesCapWarned = true;
1897
+ this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
1898
+ }
1899
+ return false;
1900
+ }
1901
+ _fold(state, value) {
1902
+ switch (state.type) {
1903
+ case "count":
1904
+ state.total = (state.total ?? 0) + value;
1905
+ break;
1906
+ case "gauge":
1907
+ state.last = value;
1908
+ break;
1909
+ case "histogram": {
1910
+ if (!state.hist)
1911
+ state.hist = {
1912
+ count: 0,
1913
+ sum: 0,
1914
+ min: value,
1915
+ max: value,
1916
+ bucketCounts: new Array(DEFAULT_HISTOGRAM_BOUNDS.length + 1).fill(0)
1917
+ };
1918
+ const hist = state.hist;
1919
+ hist.count += 1;
1920
+ hist.sum += value;
1921
+ hist.min = Math.min(hist.min, value);
1922
+ hist.max = Math.max(hist.max, value);
1923
+ hist.bucketCounts[bucketIndexFor(value, DEFAULT_HISTOGRAM_BOUNDS)] += 1;
1924
+ break;
1925
+ }
1926
+ }
1927
+ }
1928
+ _runBeforeSend(sample) {
1929
+ const beforeSend = this._config.beforeSend;
1930
+ if (!beforeSend)
1931
+ return sample;
1932
+ const fns = isArray(beforeSend) ? beforeSend : [
1933
+ beforeSend
1934
+ ];
1935
+ let result = sample;
1936
+ for (const fn of fns)
1937
+ try {
1938
+ const next = fn(result);
1939
+ if (!next) {
1940
+ this._logger.info("Metric was rejected in beforeSend function");
1941
+ return null;
1942
+ }
1943
+ result = next;
1944
+ } catch (e) {
1945
+ this._logger.error("Error in beforeSend function for metric:", e);
1946
+ return null;
1947
+ }
1948
+ return result;
1949
+ }
1950
+ _armFlushTimer() {
1951
+ if (this._flushTimer)
1952
+ return;
1953
+ this._flushTimer = safeSetTimeout(() => {
1954
+ this._flushTimer = undefined;
1955
+ this.flush().catch((e) => {
1956
+ this._logger.error("Metrics flush failed:", e);
1957
+ });
1958
+ }, this._config.flushIntervalMs);
1959
+ }
1960
+ _clearFlushTimer() {
1961
+ if (this._flushTimer) {
1962
+ clearTimeout(this._flushTimer);
1963
+ this._flushTimer = undefined;
1964
+ }
1965
+ }
1966
+ async _doFlush() {
1967
+ if (this._series.size === 0)
1968
+ return;
1969
+ const window = this._series;
1970
+ this._series = new Map;
1971
+ this._seriesCapWarned = false;
1972
+ this._typeByName = new Map;
1973
+ this._typeCollisionWarned = new Set;
1974
+ const generation = this._generation;
1975
+ const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window));
1976
+ if (generation !== this._generation)
1977
+ return;
1978
+ switch (outcome.kind) {
1979
+ case "ok":
1980
+ return;
1981
+ case "retry-later":
1982
+ this._mergeWindowBack(window);
1983
+ this._armFlushTimer();
1984
+ return;
1985
+ case "too-large":
1986
+ this._logger.warn("Metrics batch exceeded the server size limit and was dropped");
1987
+ return;
1988
+ case "fatal":
1989
+ this._logger.error("Failed to send metrics batch:", outcome.error);
1990
+ return;
1991
+ }
1992
+ }
1993
+ _buildPayload(window) {
1994
+ return buildOtlpMetricsPayload(this._buildMetrics(window), buildMetricsResourceAttributes(this._config, this._instance.getLibraryId(), this._instance.getLibraryVersion()), this._instance.getLibraryId(), this._instance.getLibraryVersion());
1995
+ }
1996
+ _buildMetrics(window) {
1997
+ const nowNano = msToUnixNano(Date.now());
1998
+ const byMetric = new Map;
1999
+ for (const state of window.values()) {
2000
+ const metricKey = seriesKey(state.type, state.name, state.unit, undefined);
2001
+ let metric = byMetric.get(metricKey);
2002
+ if (!metric) {
2003
+ metric = {
2004
+ name: state.name,
2005
+ ...state.unit && {
2006
+ unit: state.unit
2007
+ }
2008
+ };
2009
+ if (state.type === "count")
2010
+ metric.sum = {
2011
+ aggregationTemporality: OTLP_TEMPORALITY_DELTA,
2012
+ isMonotonic: true,
2013
+ dataPoints: []
2014
+ };
2015
+ else if (state.type === "gauge")
2016
+ metric.gauge = {
2017
+ dataPoints: []
2018
+ };
2019
+ else
2020
+ metric.histogram = {
2021
+ aggregationTemporality: OTLP_TEMPORALITY_DELTA,
2022
+ dataPoints: []
2023
+ };
2024
+ byMetric.set(metricKey, metric);
2025
+ }
2026
+ const attributes = toOtlpKeyValueList(state.attributes ?? {}, this._logger);
2027
+ const startNano = msToUnixNano(state.windowStartMs);
2028
+ if (state.type === "count") {
2029
+ const dp = {
2030
+ attributes,
2031
+ startTimeUnixNano: startNano,
2032
+ timeUnixNano: nowNano,
2033
+ asDouble: state.total ?? 0
2034
+ };
2035
+ metric.sum.dataPoints.push(dp);
2036
+ } else if (state.type === "gauge") {
2037
+ const dp = {
2038
+ attributes,
2039
+ timeUnixNano: nowNano,
2040
+ asDouble: state.last ?? 0
2041
+ };
2042
+ metric.gauge.dataPoints.push(dp);
2043
+ } else if (state.hist) {
2044
+ const dp = {
2045
+ attributes,
2046
+ startTimeUnixNano: startNano,
2047
+ timeUnixNano: nowNano,
2048
+ count: state.hist.count,
2049
+ sum: state.hist.sum,
2050
+ min: state.hist.min,
2051
+ max: state.hist.max,
2052
+ bucketCounts: state.hist.bucketCounts,
2053
+ explicitBounds: DEFAULT_HISTOGRAM_BOUNDS
2054
+ };
2055
+ metric.histogram.dataPoints.push(dp);
2056
+ }
2057
+ }
2058
+ return Array.from(byMetric.values());
2059
+ }
2060
+ _mergeWindowBack(window) {
2061
+ for (const [key, old] of window) {
2062
+ const current = this._series.get(key);
2063
+ if (!current) {
2064
+ if (this._admitNewSeries())
2065
+ this._series.set(key, old);
2066
+ continue;
2067
+ }
2068
+ current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
2069
+ switch (current.type) {
2070
+ case "count":
2071
+ current.total = (current.total ?? 0) + (old.total ?? 0);
2072
+ break;
2073
+ case "gauge":
2074
+ break;
2075
+ case "histogram":
2076
+ if (old.hist)
2077
+ if (current.hist) {
2078
+ current.hist.count += old.hist.count;
2079
+ current.hist.sum += old.hist.sum;
2080
+ current.hist.min = Math.min(current.hist.min, old.hist.min);
2081
+ current.hist.max = Math.max(current.hist.max, old.hist.max);
2082
+ for (let i = 0;i < current.hist.bucketCounts.length; i++)
2083
+ current.hist.bucketCounts[i] += old.hist.bucketCounts[i];
2084
+ } else
2085
+ current.hist = old.hist;
2086
+ break;
2087
+ }
2088
+ }
2089
+ }
2090
+ }
2091
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/eventemitter.mjs
1348
2092
  class SimpleEventEmitter {
1349
2093
  constructor() {
1350
2094
  this.events = {};
@@ -1366,37 +2110,38 @@ class SimpleEventEmitter {
1366
2110
  }
1367
2111
  }
1368
2112
 
1369
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/index.mjs
2113
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/index.mjs
1370
2114
  var exports_error_tracking = {};
1371
2115
  __export(exports_error_tracking, {
1372
- winjsStackLineParser: () => winjsStackLineParser,
1373
- stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
1374
- reverseAndStripFrames: () => reverseAndStripFrames,
1375
- resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
1376
- opera11StackLineParser: () => opera11StackLineParser,
1377
- opera10StackLineParser: () => opera10StackLineParser,
1378
- nodeStackLineParser: () => nodeStackLineParser,
1379
- getUtf8ByteLength: () => getUtf8ByteLength,
1380
- geckoStackLineParser: () => geckoStackLineParser,
1381
- createStackParser: () => createStackParser,
1382
- createDefaultStackParser: () => createDefaultStackParser,
1383
- chromeStackLineParser: () => chromeStackLineParser,
1384
- StringCoercer: () => StringCoercer,
1385
- ReduceableCache: () => ReduceableCache,
1386
- PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
1387
- PrimitiveCoercer: () => PrimitiveCoercer,
1388
- ObjectCoercer: () => ObjectCoercer,
1389
- ExceptionStepsBuffer: () => ExceptionStepsBuffer,
1390
- EventCoercer: () => EventCoercer,
1391
- ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
1392
- ErrorEventCoercer: () => ErrorEventCoercer,
1393
- ErrorCoercer: () => ErrorCoercer,
1394
- EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2116
+ DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG,
1395
2117
  DOMExceptionCoercer: () => DOMExceptionCoercer,
1396
- DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG
2118
+ EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2119
+ ErrorCoercer: () => ErrorCoercer,
2120
+ ErrorEventCoercer: () => ErrorEventCoercer,
2121
+ ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
2122
+ EventCoercer: () => EventCoercer,
2123
+ ExceptionStepsBuffer: () => ExceptionStepsBuffer,
2124
+ ObjectCoercer: () => ObjectCoercer,
2125
+ PrimitiveCoercer: () => PrimitiveCoercer,
2126
+ PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
2127
+ ReduceableCache: () => ReduceableCache,
2128
+ StringCoercer: () => StringCoercer,
2129
+ chromeStackLineParser: () => chromeStackLineParser,
2130
+ createDefaultStackParser: () => createDefaultStackParser,
2131
+ createStackParser: () => createStackParser,
2132
+ geckoStackLineParser: () => geckoStackLineParser,
2133
+ getInjectedReleaseId: () => getInjectedReleaseId,
2134
+ getUtf8ByteLength: () => getUtf8ByteLength,
2135
+ nodeStackLineParser: () => nodeStackLineParser,
2136
+ opera10StackLineParser: () => opera10StackLineParser,
2137
+ opera11StackLineParser: () => opera11StackLineParser,
2138
+ resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
2139
+ reverseAndStripFrames: () => reverseAndStripFrames,
2140
+ stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
2141
+ winjsStackLineParser: () => winjsStackLineParser
1397
2142
  });
1398
2143
 
1399
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
2144
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
1400
2145
  var parsedStackResults;
1401
2146
  var lastKeysCount;
1402
2147
  var cachedFilenameChunkIds;
@@ -1435,7 +2180,7 @@ function getFilenameToChunkIdMap(stackParser) {
1435
2180
  return cachedFilenameChunkIds;
1436
2181
  }
1437
2182
 
1438
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
2183
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
1439
2184
  var MAX_CAUSE_RECURSION = 4;
1440
2185
 
1441
2186
  class ErrorPropertiesBuilder {
@@ -1557,14 +2302,16 @@ class ErrorPropertiesBuilder {
1557
2302
  return context;
1558
2303
  }
1559
2304
  }
1560
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
2305
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
1561
2306
  var UNKNOWN_FUNCTION = "?";
2307
+ var MASKED_URL_PREFIX = "webkit-masked-url://";
2308
+ var ANONYMOUS_FILENAME = "<anonymous>";
1562
2309
  function createFrame(platform, filename, func, lineno, colno) {
1563
2310
  const frame = {
1564
2311
  platform,
1565
2312
  filename,
1566
2313
  function: func === "<anonymous>" ? UNKNOWN_FUNCTION : func,
1567
- in_app: true
2314
+ in_app: !filename?.startsWith(MASKED_URL_PREFIX) && filename !== ANONYMOUS_FILENAME
1568
2315
  };
1569
2316
  if (!isUndefined(lineno))
1570
2317
  frame.lineno = lineno;
@@ -1573,7 +2320,7 @@ function createFrame(platform, filename, func, lineno, colno) {
1573
2320
  return frame;
1574
2321
  }
1575
2322
 
1576
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
2323
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
1577
2324
  var extractSafariExtensionDetails = (func, filename) => {
1578
2325
  const isSafariExtension = func.indexOf("safari-extension") !== -1;
1579
2326
  const isSafariWebExtension = func.indexOf("safari-web-extension") !== -1;
@@ -1586,7 +2333,7 @@ var extractSafariExtensionDetails = (func, filename) => {
1586
2333
  ];
1587
2334
  };
1588
2335
 
1589
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
2336
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
1590
2337
  var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
1591
2338
  var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
1592
2339
  var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
@@ -1612,7 +2359,7 @@ var chromeStackLineParser = (line, platform) => {
1612
2359
  }
1613
2360
  };
1614
2361
 
1615
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
2362
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
1616
2363
  var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
1617
2364
  var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
1618
2365
  var geckoStackLineParser = (line, platform) => {
@@ -1635,14 +2382,14 @@ var geckoStackLineParser = (line, platform) => {
1635
2382
  }
1636
2383
  };
1637
2384
 
1638
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
2385
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
1639
2386
  var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1640
2387
  var winjsStackLineParser = (line, platform) => {
1641
2388
  const parts = winjsRegex.exec(line);
1642
2389
  return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined) : undefined;
1643
2390
  };
1644
2391
 
1645
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
2392
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
1646
2393
  var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
1647
2394
  var opera10StackLineParser = (line, platform) => {
1648
2395
  const parts = opera10Regex.exec(line);
@@ -1654,9 +2401,12 @@ var opera11StackLineParser = (line, platform) => {
1654
2401
  return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
1655
2402
  };
1656
2403
 
1657
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
2404
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
1658
2405
  var FILENAME_MATCH = /^\s*[-]{4,}$/;
1659
2406
  var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
2407
+ var PROMISE_COMBINATOR = /^Promise\.(?:all|any)$/;
2408
+ var PROMISE_INDEX = /^index \d+$/;
2409
+ var PROMISE_FRAME_FILENAME = "node:internal/promise";
1660
2410
  var nodeStackLineParser = (line, platform) => {
1661
2411
  const lineMatch = line.match(FULL_MATCH);
1662
2412
  if (lineMatch) {
@@ -1699,6 +2449,8 @@ var nodeStackLineParser = (line, platform) => {
1699
2449
  filename = filename.slice(1);
1700
2450
  if (!filename && lineMatch[5] && !isNative)
1701
2451
  filename = lineMatch[5];
2452
+ if (PROMISE_COMBINATOR.test(functionName) && PROMISE_INDEX.test(filename || ""))
2453
+ filename = PROMISE_FRAME_FILENAME;
1702
2454
  return {
1703
2455
  filename: filename ? decodeURI(filename) : undefined,
1704
2456
  module: undefined,
@@ -1723,7 +2475,7 @@ function _parseIntOrUndefined(input) {
1723
2475
  return parseInt(input || "", 10) || undefined;
1724
2476
  }
1725
2477
 
1726
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
2478
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
1727
2479
  var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
1728
2480
  var STACKTRACE_FRAME_LIMIT = 50;
1729
2481
  function reverseAndStripFrames(stack) {
@@ -1768,7 +2520,7 @@ function createStackParser(platform, ...parsers) {
1768
2520
  return reverseAndStripFrames(frames);
1769
2521
  };
1770
2522
  }
1771
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
2523
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
1772
2524
  class DOMExceptionCoercer {
1773
2525
  match(err) {
1774
2526
  return this.isDOMException(err) || this.isDOMError(err);
@@ -1798,18 +2550,20 @@ class DOMExceptionCoercer {
1798
2550
  return isBuiltin(err, "DOMError");
1799
2551
  }
1800
2552
  }
1801
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
2553
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
1802
2554
  class ErrorCoercer {
1803
2555
  match(err) {
1804
- return isPlainError(err);
2556
+ return isError(err);
1805
2557
  }
1806
2558
  coerce(err, ctx) {
2559
+ const stack = this.getStack(err);
2560
+ const synthetic = stack === undefined;
1807
2561
  return {
1808
2562
  type: this.getType(err),
1809
2563
  value: this.getMessage(err, ctx),
1810
- stack: this.getStack(err),
2564
+ stack: stack ?? ctx.syntheticException?.stack,
1811
2565
  cause: err.cause ? ctx.next(err.cause) : undefined,
1812
- synthetic: false
2566
+ synthetic
1813
2567
  };
1814
2568
  }
1815
2569
  getType(err) {
@@ -1825,25 +2579,41 @@ class ErrorCoercer {
1825
2579
  return err.stacktrace || err.stack || undefined;
1826
2580
  }
1827
2581
  }
1828
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2582
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
1829
2583
  class ErrorEventCoercer {
1830
2584
  constructor() {}
1831
2585
  match(err) {
1832
- return isErrorEvent(err) && err.error != null;
2586
+ if (!isErrorEvent(err))
2587
+ return false;
2588
+ const errorEvent = err;
2589
+ return errorEvent.error != null || this._hasUsableMessage(errorEvent);
1833
2590
  }
1834
2591
  coerce(err, ctx) {
1835
- const exceptionLike = ctx.apply(err.error);
1836
- if (!exceptionLike)
1837
- return {
1838
- type: "ErrorEvent",
1839
- value: err.message,
1840
- stack: ctx.syntheticException?.stack,
1841
- synthetic: true
1842
- };
1843
- return exceptionLike;
2592
+ if (err.error != null)
2593
+ return ctx.apply(err.error);
2594
+ const exceptionLike = ctx.apply(err.message);
2595
+ return {
2596
+ ...exceptionLike,
2597
+ stack: this._buildLocationStack(err) ?? exceptionLike.stack,
2598
+ synthetic: true
2599
+ };
2600
+ }
2601
+ _hasUsableMessage(err) {
2602
+ return isString(err.message) && err.message.length > 0;
2603
+ }
2604
+ _buildLocationStack(err) {
2605
+ const location = err;
2606
+ const lineno = location.lineno ?? 0;
2607
+ const colno = location.colno ?? 0;
2608
+ if (!isString(location.filename) || location.filename.length === 0)
2609
+ return;
2610
+ if (lineno === 0)
2611
+ return;
2612
+ return `Error
2613
+ at ${location.filename}:${lineno}:${colno}`;
1844
2614
  }
1845
2615
  }
1846
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
2616
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
1847
2617
  var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
1848
2618
 
1849
2619
  class StringCoercer {
@@ -1873,7 +2643,7 @@ class StringCoercer {
1873
2643
  ];
1874
2644
  }
1875
2645
  }
1876
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/types.mjs
2646
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/types.mjs
1877
2647
  var severityLevels = [
1878
2648
  "fatal",
1879
2649
  "error",
@@ -1883,7 +2653,7 @@ var severityLevels = [
1883
2653
  "debug"
1884
2654
  ];
1885
2655
 
1886
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
2656
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
1887
2657
  function extractExceptionKeysForMessage(err, maxLength = 40) {
1888
2658
  const keys = Object.keys(err);
1889
2659
  keys.sort();
@@ -1900,7 +2670,7 @@ function extractExceptionKeysForMessage(err, maxLength = 40) {
1900
2670
  return "";
1901
2671
  }
1902
2672
 
1903
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
2673
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
1904
2674
  class ObjectCoercer {
1905
2675
  match(candidate) {
1906
2676
  return typeof candidate == "object" && candidate !== null;
@@ -1912,13 +2682,16 @@ class ObjectCoercer {
1912
2682
  return {
1913
2683
  type: this.getType(candidate),
1914
2684
  value: this.getValue(candidate),
1915
- stack: ctx.syntheticException?.stack,
2685
+ stack: this.getStack(candidate) ?? ctx.syntheticException?.stack,
1916
2686
  level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
1917
2687
  synthetic: true
1918
2688
  };
1919
2689
  }
1920
2690
  getType(err) {
1921
- return isEvent(err) ? err.constructor.name : "Error";
2691
+ if (isEvent(err))
2692
+ return err.constructor.name;
2693
+ const name = "name" in err ? err.name : undefined;
2694
+ return isString(name) && !isEmptyString(name) ? name : "Error";
1922
2695
  }
1923
2696
  getValue(err) {
1924
2697
  if ("name" in err && typeof err.name == "string") {
@@ -1936,6 +2709,15 @@ class ObjectCoercer {
1936
2709
  isSeverityLevel(x) {
1937
2710
  return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
1938
2711
  }
2712
+ getStack(candidate) {
2713
+ try {
2714
+ if (isString(candidate.stacktrace) && candidate.stacktrace.length > 0)
2715
+ return candidate.stacktrace;
2716
+ return isString(candidate.stack) && candidate.stack.length > 0 ? candidate.stack : undefined;
2717
+ } catch {
2718
+ return;
2719
+ }
2720
+ }
1939
2721
  getErrorPropertyFromObject(obj) {
1940
2722
  for (const prop in obj)
1941
2723
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
@@ -1953,7 +2735,7 @@ class ObjectCoercer {
1953
2735
  }
1954
2736
  }
1955
2737
  }
1956
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
2738
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
1957
2739
  class EventCoercer {
1958
2740
  match(err) {
1959
2741
  return isEvent(err);
@@ -1968,7 +2750,7 @@ class EventCoercer {
1968
2750
  };
1969
2751
  }
1970
2752
  }
1971
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
2753
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
1972
2754
  class PrimitiveCoercer {
1973
2755
  match(candidate) {
1974
2756
  return isPrimitive(candidate);
@@ -1982,7 +2764,7 @@ class PrimitiveCoercer {
1982
2764
  };
1983
2765
  }
1984
2766
  }
1985
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
2767
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
1986
2768
  class PromiseRejectionEventCoercer {
1987
2769
  match(err) {
1988
2770
  return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
@@ -2018,7 +2800,7 @@ class PromiseRejectionEventCoercer {
2018
2800
  return error;
2019
2801
  }
2020
2802
  }
2021
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/utils.mjs
2803
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/utils.mjs
2022
2804
  class ReduceableCache {
2023
2805
  constructor(_maxSize) {
2024
2806
  this._maxSize = _maxSize;
@@ -2043,7 +2825,7 @@ class ReduceableCache {
2043
2825
  }
2044
2826
  }
2045
2827
  }
2046
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2828
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2047
2829
  var EXCEPTION_STEP_INTERNAL_FIELDS = {
2048
2830
  MESSAGE: "$message",
2049
2831
  TIMESTAMP: "$timestamp"
@@ -2138,9 +2920,12 @@ function normalizePositiveInteger(input, fallback) {
2138
2920
  return normalized;
2139
2921
  }
2140
2922
  function normalizeAndSerializeStep(step) {
2141
- const json = safeStringify(step);
2142
- if (!json)
2923
+ let json;
2924
+ try {
2925
+ json = safeJsonStringify(step);
2926
+ } catch {
2143
2927
  return;
2928
+ }
2144
2929
  try {
2145
2930
  const parsed = JSON.parse(json);
2146
2931
  if (!isObject(parsed))
@@ -2160,33 +2945,6 @@ function normalizeAndSerializeStep(step) {
2160
2945
  return;
2161
2946
  }
2162
2947
  }
2163
- function safeStringify(value) {
2164
- const seen = new WeakSet;
2165
- try {
2166
- return JSON.stringify(value, (_key, replacementValue) => {
2167
- if (typeof replacementValue == "bigint")
2168
- return replacementValue.toString();
2169
- if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
2170
- return;
2171
- if (replacementValue instanceof Date)
2172
- return replacementValue.toISOString();
2173
- if (replacementValue instanceof Error)
2174
- return {
2175
- name: replacementValue.name,
2176
- message: replacementValue.message,
2177
- stack: replacementValue.stack
2178
- };
2179
- if (replacementValue && typeof replacementValue == "object") {
2180
- if (seen.has(replacementValue))
2181
- return "[Circular]";
2182
- seen.add(replacementValue);
2183
- }
2184
- return replacementValue;
2185
- });
2186
- } catch {
2187
- return;
2188
- }
2189
- }
2190
2948
  function getUtf8ByteLength(value) {
2191
2949
  if (typeof TextEncoder != "undefined")
2192
2950
  return new TextEncoder().encode(value).length;
@@ -2200,19 +2958,65 @@ function getUtf8ByteLength(value) {
2200
2958
  byteLength += 1;
2201
2959
  return byteLength;
2202
2960
  }
2203
- // ../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
2961
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/release.mjs
2962
+ function getInjectedReleaseId() {
2963
+ const injected = globalThis._posthogReleaseId;
2964
+ return typeof injected == "string" && injected.length > 0 ? injected : undefined;
2965
+ }
2966
+ // ../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
2204
2967
  class PostHogFetchHttpError extends Error {
2205
- constructor(response, reqByteLength) {
2206
- super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
2968
+ constructor(response, reqByteLength, responseBodyDeadline, abortController) {
2969
+ super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.responseBodyDeadline = responseBodyDeadline, this.abortController = abortController, this.name = "PostHogFetchHttpError", this._bodyReadTimedOut = false;
2207
2970
  }
2208
2971
  get status() {
2209
2972
  return this.response.status;
2210
2973
  }
2974
+ get bodyReadTimedOut() {
2975
+ return this._bodyReadTimedOut;
2976
+ }
2211
2977
  get text() {
2212
- return this.response.text();
2978
+ if (!this.responseBodyTextPromise)
2979
+ if (Date.now() >= this.responseBodyDeadline) {
2980
+ this._bodyReadTimedOut = true;
2981
+ const timeoutError = new Error("Response body read timed out");
2982
+ timeoutError.name = "AbortError";
2983
+ this.cancelResponseBody(timeoutError);
2984
+ this.responseBodyTextPromise = Promise.reject(timeoutError);
2985
+ } else {
2986
+ const responseBodyTimeout = new Promise((_resolve, reject) => {
2987
+ this.responseBodyTimer = safeSetTimeout(() => {
2988
+ this._bodyReadTimedOut = true;
2989
+ const timeoutError = new Error("Response body read timed out");
2990
+ timeoutError.name = "AbortError";
2991
+ reject(timeoutError);
2992
+ this.cancelResponseBody(timeoutError);
2993
+ }, this.responseBodyDeadline - Date.now());
2994
+ });
2995
+ let responseBodyText;
2996
+ try {
2997
+ responseBodyText = Promise.resolve(this.response.text());
2998
+ } catch (error) {
2999
+ responseBodyText = Promise.reject(error);
3000
+ }
3001
+ this.responseBodyTextPromise = Promise.race([
3002
+ responseBodyText,
3003
+ responseBodyTimeout
3004
+ ]).finally(() => clearTimeout(this.responseBodyTimer));
3005
+ }
3006
+ return this.responseBodyTextPromise;
2213
3007
  }
2214
3008
  get json() {
2215
- return this.response.json();
3009
+ return this.text.then((text) => JSON.parse(text));
3010
+ }
3011
+ cancelResponseBody(reason) {
3012
+ clearTimeout(this.responseBodyTimer);
3013
+ if (!this.abortController.signal.aborted)
3014
+ this.abortController.abort(reason);
3015
+ (async () => {
3016
+ try {
3017
+ await this.response.body?.cancel();
3018
+ } catch {}
3019
+ })();
2216
3020
  }
2217
3021
  }
2218
3022
 
@@ -2223,12 +3027,20 @@ class PostHogFetchNetworkError extends Error {
2223
3027
  } : {}), this.error = error, this.name = "PostHogFetchNetworkError";
2224
3028
  }
2225
3029
  }
3030
+ var applyCallerFeatureFlagOverrides = (target, callerProperties) => {
3031
+ for (const key of Object.keys(callerProperties))
3032
+ if (key.startsWith("$feature/") || key === "$active_feature_flags")
3033
+ target[key] = callerProperties[key];
3034
+ };
2226
3035
  async function logFlushError(err) {
2227
3036
  if (err instanceof PostHogFetchHttpError) {
2228
3037
  let text = "";
2229
3038
  try {
2230
3039
  text = await err.text;
2231
- } catch {}
3040
+ } catch {
3041
+ if (err.bodyReadTimedOut)
3042
+ text = "<response body read timed out>";
3043
+ }
2232
3044
  console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
2233
3045
  } else
2234
3046
  console.error("Error while flushing PostHog", err);
@@ -2240,9 +3052,28 @@ function isPostHogFetchError(err) {
2240
3052
  function isPostHogFetchNetworkError(err) {
2241
3053
  return err instanceof PostHogFetchNetworkError;
2242
3054
  }
3055
+ function isRetryableFlagsFetchError(err) {
3056
+ if (err instanceof PostHogFetchHttpError)
3057
+ return err.status === 502 || err.status === 504;
3058
+ if (!(err instanceof PostHogFetchNetworkError))
3059
+ return false;
3060
+ const cause = err.error;
3061
+ const code = cause?.code ?? cause?.cause?.code;
3062
+ return code !== "ECONNREFUSED";
3063
+ }
2243
3064
  function isPostHogFetchContentTooLargeError(err) {
2244
3065
  return typeof err == "object" && err instanceof PostHogFetchHttpError && err.status === 413;
2245
3066
  }
3067
+ function isPostHogFetchRetryableError(err) {
3068
+ if (err instanceof PostHogFetchHttpError)
3069
+ return err.status === 408 || err.status === 429 || err.status >= 500;
3070
+ return isPostHogFetchNetworkError(err);
3071
+ }
3072
+ function isPostHogEventProperties(value) {
3073
+ return value !== null && typeof value == "object" && !Array.isArray(value);
3074
+ }
3075
+ var DEFAULT_QUEUE_ROUTE = "default";
3076
+
2246
3077
  class PostHogCoreStateless {
2247
3078
  getErrorPropertiesBuilder() {
2248
3079
  if (!this._errorPropertiesBuilder)
@@ -2259,6 +3090,9 @@ class PostHogCoreStateless {
2259
3090
  }
2260
3091
  constructor(apiKey, options = {}) {
2261
3092
  this.flushPromise = null;
3093
+ this.pendingFlushPromise = null;
3094
+ this.flushPromises = new Set;
3095
+ this._dequeuedMessagesCount = 0;
2262
3096
  this.shutdownPromise = null;
2263
3097
  this.promiseQueue = new PromiseQueue;
2264
3098
  this._events = new SimpleEventEmitter;
@@ -2281,10 +3115,11 @@ class PostHogCoreStateless {
2281
3115
  this._retryOptions = {
2282
3116
  retryCount: options.fetchRetryCount ?? 3,
2283
3117
  retryDelay: options.fetchRetryDelay ?? 3000,
2284
- retryCheck: isPostHogFetchError
3118
+ retryCheck: isPostHogFetchRetryableError
2285
3119
  };
2286
3120
  this.requestTimeout = options.requestTimeout ?? 1e4;
2287
3121
  this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3000;
3122
+ this.featureFlagsRequestMaxRetries = options.featureFlagsRequestMaxRetries ?? 1;
2288
3123
  this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3000;
2289
3124
  this.disableGeoip = options.disableGeoip ?? true;
2290
3125
  this.disabled = (options.disabled ?? false) || missingApiKey;
@@ -2346,15 +3181,23 @@ class PostHogCoreStateless {
2346
3181
  return this.disabled;
2347
3182
  }
2348
3183
  buildPayload(payload) {
3184
+ const userProperties = payload.properties || {};
3185
+ let properties = {
3186
+ ...userProperties,
3187
+ ...this.getCommonEventProperties()
3188
+ };
3189
+ applyCallerFeatureFlagOverrides(properties, userProperties);
3190
+ if (payload.event === "$feature_flag_called" && properties.$feature_flag_has_experiment === false && this.isMinimalFlagCalledEventsEnabled())
3191
+ properties = minimizeFlagCalledEventProperties(properties);
2349
3192
  return {
2350
3193
  distinct_id: payload.distinct_id,
2351
3194
  event: payload.event,
2352
- properties: {
2353
- ...payload.properties || {},
2354
- ...this.getCommonEventProperties()
2355
- }
3195
+ properties
2356
3196
  };
2357
3197
  }
3198
+ isMinimalFlagCalledEventsEnabled() {
3199
+ return false;
3200
+ }
2358
3201
  addPendingPromise(promise) {
2359
3202
  return this.promiseQueue.add(promise);
2360
3203
  }
@@ -2439,6 +3282,19 @@ class PostHogCoreStateless {
2439
3282
  this.enqueue("capture", payload, options);
2440
3283
  });
2441
3284
  }
3285
+ async groupIdentifyStatelessImmediate(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
3286
+ const payload = this.buildPayload({
3287
+ distinct_id: distinctId || `$${groupType}_${groupKey}`,
3288
+ event: "$groupidentify",
3289
+ properties: {
3290
+ $group_type: groupType,
3291
+ $group_key: groupKey,
3292
+ $group_set: groupProperties || {},
3293
+ ...eventProperties || {}
3294
+ }
3295
+ });
3296
+ await this.sendImmediate("capture", payload, options);
3297
+ }
2442
3298
  async getRemoteConfig() {
2443
3299
  await this._initPromise;
2444
3300
  let host = this.host;
@@ -2455,8 +3311,11 @@ class PostHogCoreStateless {
2455
3311
  }
2456
3312
  };
2457
3313
  return this.fetchWithRetry(url, fetchOptions, {
3314
+ type: "required",
3315
+ consume: (response) => response.json()
3316
+ }, {
2458
3317
  retryCount: 0
2459
- }, this.remoteConfigRequestTimeoutMs).then((response) => response.json()).catch((error) => {
3318
+ }, this.remoteConfigRequestTimeoutMs).catch((error) => {
2460
3319
  this._logger.error("Remote config could not be loaded", error);
2461
3320
  this._events.emit("error", error);
2462
3321
  });
@@ -2487,8 +3346,12 @@ class PostHogCoreStateless {
2487
3346
  };
2488
3347
  this._logger.info("Flags URL", url);
2489
3348
  return this.fetchWithRetry(url, fetchOptions, {
2490
- retryCount: 0
2491
- }, this.featureFlagsRequestTimeoutMs).then((response) => response.json()).then((response) => ({
3349
+ type: "required",
3350
+ consume: (response) => response.json()
3351
+ }, {
3352
+ retryCount: this.featureFlagsRequestMaxRetries,
3353
+ retryCheck: isRetryableFlagsFetchError
3354
+ }, this.featureFlagsRequestTimeoutMs).then((response) => ({
2492
3355
  success: true,
2493
3356
  response: normalizeFlagsResponse(response)
2494
3357
  })).catch((error) => {
@@ -2588,9 +3451,9 @@ class PostHogCoreStateless {
2588
3451
  }
2589
3452
  async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2590
3453
  await this._initPromise;
2591
- const extraPayload = {};
2592
- if (disableGeoip ?? this.disableGeoip)
2593
- extraPayload["geoip_disable"] = true;
3454
+ const extraPayload = {
3455
+ geoip_disable: disableGeoip ?? this.disableGeoip
3456
+ };
2594
3457
  if (flagKeysToEvaluate)
2595
3458
  extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
2596
3459
  const result = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
@@ -2627,15 +3490,18 @@ class PostHogCoreStateless {
2627
3490
  "Content-Type": "application/json"
2628
3491
  }
2629
3492
  };
2630
- const response = await this.fetchWithRetry(url, fetchOptions).then((response2) => {
2631
- if (response2.status !== 200 || !response2.json) {
2632
- const msg = `Surveys API could not be loaded: ${response2.status}`;
2633
- const error = new Error(msg);
2634
- this._logger.error(error);
2635
- this._events.emit("error", new Error(msg));
2636
- return;
3493
+ const response = await this.fetchWithRetry(url, fetchOptions, {
3494
+ type: "required",
3495
+ consume: (response2) => {
3496
+ if (response2.status !== 200 || !response2.json) {
3497
+ const msg = `Surveys API could not be loaded: ${response2.status}`;
3498
+ const error = new Error(msg);
3499
+ this._logger.error(error);
3500
+ this._events.emit("error", new Error(msg));
3501
+ return Promise.resolve(undefined);
3502
+ }
3503
+ return response2.json();
2637
3504
  }
2638
- return response2.json();
2639
3505
  }).catch((error) => {
2640
3506
  this._logger.error("Surveys API could not be loaded", error);
2641
3507
  this._events.emit("error", error);
@@ -2672,23 +3538,39 @@ class PostHogCoreStateless {
2672
3538
  return message;
2673
3539
  }
2674
3540
  async flushStorage() {}
2675
- enqueue(type, _message, options) {
3541
+ getQueueRouteKey(_message) {
3542
+ return DEFAULT_QUEUE_ROUTE;
3543
+ }
3544
+ persistedQueueKeyForRoute(_route) {
3545
+ return types_PostHogPersistedProperty.Queue;
3546
+ }
3547
+ getActiveQueueRoutes() {
3548
+ return [
3549
+ DEFAULT_QUEUE_ROUTE
3550
+ ];
3551
+ }
3552
+ getRouteQueue(route) {
3553
+ return this.getPersistedProperty(this.persistedQueueKeyForRoute(route)) || [];
3554
+ }
3555
+ enqueue(type, _message, options, explicitRoute) {
2676
3556
  this.wrap(() => {
2677
3557
  if (this.optedOut)
2678
3558
  return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2679
- let message = this.prepareMessage(type, _message, options);
3559
+ let message = this.prepareMessage(_message, options);
2680
3560
  message = this.processBeforeEnqueue(message);
2681
3561
  if (message === null)
2682
3562
  return;
2683
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3563
+ message = this.normalizeMessage(message);
3564
+ const queueKey = this.persistedQueueKeyForRoute(explicitRoute ?? this.getQueueRouteKey(message));
3565
+ const queue = this.getPersistedProperty(queueKey) || [];
2684
3566
  if (queue.length >= this.maxQueueSize) {
2685
3567
  queue.shift();
2686
- this._logger.info("Queue is full, the oldest event is dropped.");
3568
+ this._logger.warn("Queue is full, the oldest event is dropped.");
2687
3569
  }
2688
3570
  queue.push({
2689
3571
  message
2690
3572
  });
2691
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, queue);
3573
+ this.setPersistedProperty(queueKey, queue);
2692
3574
  this._events.emit(type, message);
2693
3575
  if (queue.length >= this.flushAt)
2694
3576
  this.flushBackground();
@@ -2696,61 +3578,63 @@ class PostHogCoreStateless {
2696
3578
  this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
2697
3579
  });
2698
3580
  }
2699
- async sendImmediate(type, _message, options) {
3581
+ async sendImmediate(type, _message, options, explicitRoute) {
2700
3582
  if (this.disabled)
2701
3583
  return void this._logger.warn("The client is disabled");
2702
3584
  if (!this._isInitialized)
2703
3585
  await this._initPromise;
2704
3586
  if (this.optedOut)
2705
3587
  return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2706
- let message = this.prepareMessage(type, _message, options);
3588
+ let message = this.prepareMessage(_message, options);
2707
3589
  message = this.processBeforeEnqueue(message);
2708
3590
  if (message === null)
2709
3591
  return;
2710
- const data = {
2711
- api_key: this.apiKey,
2712
- batch: [
2713
- message
2714
- ],
2715
- sent_at: currentISOTime()
2716
- };
2717
- if (this.historicalMigration)
2718
- data.historical_migration = true;
2719
- const payload = JSON.stringify(data);
2720
- const url = `${this.host}/batch/`;
2721
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2722
- const fetchOptions = {
2723
- method: "POST",
2724
- headers: {
2725
- ...this.getCustomHeaders(),
2726
- "Content-Type": "application/json",
2727
- ...gzippedPayload !== null && {
2728
- "Content-Encoding": "gzip"
2729
- }
2730
- },
2731
- body: gzippedPayload || payload
2732
- };
3592
+ message = this.normalizeMessage(message);
2733
3593
  try {
2734
- const response = await this.fetchWithRetry(url, fetchOptions);
2735
- await response.body?.cancel()?.catch(() => {});
3594
+ await this.sendBatch([
3595
+ message
3596
+ ], undefined, explicitRoute ?? this.getQueueRouteKey(message));
2736
3597
  } catch (err) {
2737
3598
  this._events.emit("error", err);
2738
3599
  }
2739
3600
  }
2740
- prepareMessage(type, _message, options) {
3601
+ normalizeMessage(message) {
3602
+ const { type: _type, library, library_version, ...sanitizedMessage } = message;
3603
+ let properties = isPostHogEventProperties(sanitizedMessage.properties) ? sanitizedMessage.properties : undefined;
3604
+ if (library !== undefined && properties?.$lib === undefined)
3605
+ properties = {
3606
+ ...properties || {},
3607
+ $lib: library
3608
+ };
3609
+ if (library_version !== undefined && properties?.$lib_version === undefined)
3610
+ properties = {
3611
+ ...properties || {},
3612
+ $lib_version: library_version
3613
+ };
3614
+ if (properties)
3615
+ sanitizedMessage.properties = properties;
3616
+ sanitizedMessage.uuid = getEventUuid(sanitizedMessage.uuid, uuidv7);
3617
+ return sanitizedMessage;
3618
+ }
3619
+ normalizeTimestampForWire(timestamp) {
3620
+ const parsedTimestamp = timestamp instanceof Date ? timestamp : typeof timestamp == "string" ? new Date(timestamp) : null;
3621
+ if (!parsedTimestamp || Number.isNaN(parsedTimestamp.getTime()))
3622
+ return timestamp;
3623
+ const normalized = parsedTimestamp.toISOString();
3624
+ const fractionalSeconds = typeof timestamp == "string" ? timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1] : undefined;
3625
+ return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
3626
+ }
3627
+ prepareMessage(_message, options) {
2741
3628
  const message = {
2742
3629
  ..._message,
2743
- type,
2744
- library: this.getLibraryId(),
2745
- library_version: this.getLibraryVersion(),
2746
3630
  timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
2747
- uuid: options?.uuid ? options.uuid : uuidv7()
3631
+ uuid: getEventUuid(options?.uuid, uuidv7)
2748
3632
  };
2749
3633
  const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
2750
3634
  if (addGeoipDisableProperty) {
2751
- if (!message.properties)
3635
+ if (!isPostHogEventProperties(message.properties))
2752
3636
  message.properties = {};
2753
- message["properties"]["$geoip_disable"] = true;
3637
+ message.properties["$geoip_disable"] = true;
2754
3638
  }
2755
3639
  if (message.distinctId) {
2756
3640
  message.distinct_id = message.distinctId;
@@ -2765,21 +3649,64 @@ class PostHogCoreStateless {
2765
3649
  }
2766
3650
  }
2767
3651
  flushBackground() {
3652
+ if (this.pendingFlushPromise)
3653
+ return;
2768
3654
  this.flush().catch(async (err) => {
2769
3655
  await logFlushError(err);
2770
3656
  });
2771
3657
  }
2772
- async flush() {
3658
+ async waitForPendingPromises(maxPromiseId, ignoredPromises = []) {
3659
+ const ignoredPendingPromises = ignoredPromises.filter((promise) => !!promise);
3660
+ let iteration = 0;
3661
+ while (true) {
3662
+ const promises = this.promiseQueue.getPromises([
3663
+ ...ignoredPendingPromises,
3664
+ ...this.flushPromises
3665
+ ], maxPromiseId);
3666
+ if (promises.length === 0)
3667
+ return;
3668
+ if (iteration > 0)
3669
+ this._logger.debug(`flush() re-checking ${promises.length} pending promise(s) before flushing`);
3670
+ await Promise.all(promises.map((promise) => promise.catch(() => {})));
3671
+ iteration++;
3672
+ }
3673
+ }
3674
+ flushWithPendingPromises() {
3675
+ return this.flushInternal(true);
3676
+ }
3677
+ flush() {
3678
+ return this.flushInternal(false);
3679
+ }
3680
+ flushInternal(waitForPendingPromises) {
2773
3681
  if (this.disabled)
2774
- return;
2775
- const nextFlushPromise = allSettled([
2776
- this.flushPromise
2777
- ]).then(() => this._flush());
3682
+ return Promise.resolve();
3683
+ if (!waitForPendingPromises && this.pendingFlushPromise)
3684
+ return this.pendingFlushPromise;
3685
+ const previousFlushPromise = this.flushPromise;
3686
+ const maxPromiseId = this.promiseQueue.maxId;
3687
+ const nextFlushPromise = Promise.resolve().then(() => {
3688
+ if (waitForPendingPromises)
3689
+ return this.waitForPendingPromises(maxPromiseId, [
3690
+ previousFlushPromise,
3691
+ nextFlushPromise
3692
+ ]);
3693
+ }).then(() => allSettled([
3694
+ previousFlushPromise
3695
+ ])).then(() => {
3696
+ if (this.pendingFlushPromise === nextFlushPromise)
3697
+ this.pendingFlushPromise = null;
3698
+ return this._flush();
3699
+ });
3700
+ this.pendingFlushPromise = nextFlushPromise;
2778
3701
  this.flushPromise = nextFlushPromise;
3702
+ this.flushPromises.add(nextFlushPromise);
2779
3703
  this.addPendingPromise(nextFlushPromise);
2780
3704
  allSettled([
2781
3705
  nextFlushPromise
2782
3706
  ]).then(() => {
3707
+ this.flushPromises.delete(nextFlushPromise);
3708
+ if (this.pendingFlushPromise === nextFlushPromise)
3709
+ this.pendingFlushPromise = null;
2783
3710
  if (this.flushPromise === nextFlushPromise)
2784
3711
  this.flushPromise = null;
2785
3712
  });
@@ -2792,55 +3719,102 @@ class PostHogCoreStateless {
2792
3719
  headers["User-Agent"] = customUserAgent;
2793
3720
  return headers;
2794
3721
  }
3722
+ compressPayload(payload) {
3723
+ return gzipCompress(payload, this.isDebug);
3724
+ }
3725
+ getBatchEndpointPath(_route) {
3726
+ return "/batch/";
3727
+ }
3728
+ async sendBatch(batchMessages, retryOptions, route = DEFAULT_QUEUE_ROUTE) {
3729
+ const data = {
3730
+ api_key: this.apiKey,
3731
+ batch: batchMessages.map((message) => {
3732
+ if (!message)
3733
+ return message;
3734
+ const timestamp = this.normalizeTimestampForWire(message.timestamp);
3735
+ return timestamp === message.timestamp ? message : {
3736
+ ...message,
3737
+ timestamp
3738
+ };
3739
+ }),
3740
+ sent_at: currentISOTime()
3741
+ };
3742
+ if (this.historicalMigration)
3743
+ data.historical_migration = true;
3744
+ const payload = safeJsonStringify(data);
3745
+ const url = `${this.host}${this.getBatchEndpointPath(route)}`;
3746
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(payload);
3747
+ const fetchOptions = {
3748
+ method: "POST",
3749
+ headers: {
3750
+ ...this.getCustomHeaders(),
3751
+ "Content-Type": "application/json",
3752
+ ...gzippedPayload !== null && {
3753
+ "Content-Encoding": "gzip"
3754
+ }
3755
+ },
3756
+ body: gzippedPayload || payload
3757
+ };
3758
+ await this.fetchWithRetry(url, fetchOptions, {
3759
+ type: "successful-write"
3760
+ }, retryOptions);
3761
+ }
2795
3762
  async _flush() {
2796
3763
  this.clearFlushTimer();
2797
3764
  await this._initPromise;
2798
- let queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2799
- if (!queue.length)
3765
+ const routes = this.getActiveQueueRoutes();
3766
+ if (!routes.some((route) => this.getRouteQueue(route).length > 0))
2800
3767
  return;
2801
3768
  const sentMessages = [];
3769
+ let firstError;
3770
+ for (const route of routes)
3771
+ try {
3772
+ await this._flushRoute(route, sentMessages);
3773
+ } catch (err) {
3774
+ if (firstError === undefined)
3775
+ firstError = err;
3776
+ }
3777
+ if (firstError !== undefined)
3778
+ throw firstError;
3779
+ this._events.emit("flush", sentMessages);
3780
+ }
3781
+ async _flushRoute(route, sentMessages) {
3782
+ const queueKey = this.persistedQueueKeyForRoute(route);
3783
+ let queue = this.getPersistedProperty(queueKey) || [];
3784
+ if (!queue.length)
3785
+ return;
2802
3786
  const originalQueueLength = queue.length;
2803
- while (queue.length > 0 && sentMessages.length < originalQueueLength) {
3787
+ let sentFromRoute = 0;
3788
+ while (queue.length > 0 && sentFromRoute < originalQueueLength) {
2804
3789
  const batchItems = queue.slice(0, this.maxBatchSize);
2805
- const batchMessages = batchItems.map((item) => item.message);
3790
+ const batchMessages = batchItems.map((item) => item.message === undefined ? item.message : this.normalizeMessage(item.message));
2806
3791
  const persistQueueChange = async () => {
2807
- const refreshedQueue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2808
- const newQueue = refreshedQueue.slice(batchItems.length);
2809
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, newQueue);
3792
+ const refreshedQueue = this.getPersistedProperty(queueKey) || [];
3793
+ const remainingBatchItems = [
3794
+ ...batchItems
3795
+ ];
3796
+ const newQueue = refreshedQueue.filter((item) => {
3797
+ const itemUuid = item.message?.uuid;
3798
+ const batchItemIndex = remainingBatchItems.findIndex((batchItem) => batchItem === item || typeof itemUuid == "string" && itemUuid.length > 0 && batchItem.message?.uuid === itemUuid);
3799
+ if (batchItemIndex === -1)
3800
+ return true;
3801
+ remainingBatchItems.splice(batchItemIndex, 1);
3802
+ return false;
3803
+ });
3804
+ this.setPersistedProperty(queueKey, newQueue);
2810
3805
  queue = newQueue;
3806
+ this._dequeuedMessagesCount += batchItems.length;
2811
3807
  await this.flushStorage();
2812
3808
  };
2813
- const data = {
2814
- api_key: this.apiKey,
2815
- batch: batchMessages,
2816
- sent_at: currentISOTime()
2817
- };
2818
- if (this.historicalMigration)
2819
- data.historical_migration = true;
2820
- const payload = JSON.stringify(data);
2821
- const url = `${this.host}/batch/`;
2822
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2823
- const fetchOptions = {
2824
- method: "POST",
2825
- headers: {
2826
- ...this.getCustomHeaders(),
2827
- "Content-Type": "application/json",
2828
- ...gzippedPayload !== null && {
2829
- "Content-Encoding": "gzip"
2830
- }
2831
- },
2832
- body: gzippedPayload || payload
2833
- };
2834
3809
  const retryOptions = {
2835
3810
  retryCheck: (err) => {
2836
3811
  if (isPostHogFetchContentTooLargeError(err))
2837
3812
  return false;
2838
- return isPostHogFetchError(err);
3813
+ return isPostHogFetchRetryableError(err);
2839
3814
  }
2840
3815
  };
2841
3816
  try {
2842
- const response = await this.fetchWithRetry(url, fetchOptions, retryOptions);
2843
- await response.body?.cancel()?.catch(() => {});
3817
+ await this.sendBatch(batchMessages, retryOptions, route);
2844
3818
  } catch (err) {
2845
3819
  if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
2846
3820
  this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
@@ -2854,8 +3828,8 @@ class PostHogCoreStateless {
2854
3828
  }
2855
3829
  await persistQueueChange();
2856
3830
  sentMessages.push(...batchMessages);
3831
+ sentFromRoute += batchMessages.length;
2857
3832
  }
2858
- this._events.emit("flush", sentMessages);
2859
3833
  }
2860
3834
  async _sendLogsBatch(payload) {
2861
3835
  if (this.disabled)
@@ -2865,7 +3839,7 @@ class PostHogCoreStateless {
2865
3839
  };
2866
3840
  const serialized = JSON.stringify(payload);
2867
3841
  const url = `${this.host}/i/v1/logs?token=${encodeURIComponent(this.apiKey)}`;
2868
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(serialized, this.isDebug);
3842
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
2869
3843
  const fetchOptions = {
2870
3844
  method: "POST",
2871
3845
  headers: {
@@ -2879,10 +3853,12 @@ class PostHogCoreStateless {
2879
3853
  };
2880
3854
  try {
2881
3855
  await this.fetchWithRetry(url, fetchOptions, {
3856
+ type: "successful-write"
3857
+ }, {
2882
3858
  retryCheck: (err) => {
2883
3859
  if (isPostHogFetchContentTooLargeError(err))
2884
3860
  return false;
2885
- return isPostHogFetchError(err);
3861
+ return isPostHogFetchRetryableError(err);
2886
3862
  }
2887
3863
  });
2888
3864
  return {
@@ -2904,41 +3880,155 @@ class PostHogCoreStateless {
2904
3880
  };
2905
3881
  }
2906
3882
  }
2907
- async fetchWithRetry(url, options, retryOptions, requestTimeout) {
3883
+ async _sendMetricsBatch(payload) {
3884
+ if (this.disabled)
3885
+ return {
3886
+ kind: "fatal",
3887
+ error: new Error("The client is disabled")
3888
+ };
3889
+ const serialized = JSON.stringify(payload);
3890
+ const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`;
3891
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
3892
+ const fetchOptions = {
3893
+ method: "POST",
3894
+ headers: {
3895
+ ...this.getCustomHeaders(),
3896
+ "Content-Type": "application/json",
3897
+ ...gzippedPayload !== null && {
3898
+ "Content-Encoding": "gzip"
3899
+ }
3900
+ },
3901
+ body: gzippedPayload || serialized
3902
+ };
3903
+ try {
3904
+ await this.fetchWithRetry(url, fetchOptions, {
3905
+ type: "successful-write"
3906
+ }, {
3907
+ retryCheck: (err) => {
3908
+ if (isPostHogFetchContentTooLargeError(err))
3909
+ return false;
3910
+ return isPostHogFetchRetryableError(err);
3911
+ }
3912
+ });
3913
+ return {
3914
+ kind: "ok"
3915
+ };
3916
+ } catch (err) {
3917
+ if (isPostHogFetchContentTooLargeError(err))
3918
+ return {
3919
+ kind: "too-large"
3920
+ };
3921
+ if (isPostHogFetchRetryableError(err))
3922
+ return {
3923
+ kind: "retry-later",
3924
+ error: err
3925
+ };
3926
+ return {
3927
+ kind: "fatal",
3928
+ error: err
3929
+ };
3930
+ }
3931
+ }
3932
+ async fetchWithRetry(url, options, responseHandling, retryOptions, requestTimeout) {
2908
3933
  const body = options.body ? options.body : "";
2909
3934
  let reqByteLength = -1;
2910
3935
  try {
2911
- reqByteLength = body instanceof Blob ? body.size : Buffer.byteLength(body, STRING_FORMAT);
3936
+ reqByteLength = body instanceof Blob ? body.size : body instanceof Uint8Array ? body.byteLength : Buffer.byteLength(body, STRING_FORMAT);
2912
3937
  } catch {
2913
3938
  if (body instanceof Blob)
2914
3939
  reqByteLength = body.size;
3940
+ else if (body instanceof Uint8Array)
3941
+ reqByteLength = body.byteLength;
2915
3942
  else {
2916
3943
  const encoded = new TextEncoder().encode(body);
2917
3944
  reqByteLength = encoded.length;
2918
3945
  }
2919
3946
  }
3947
+ const retriableOptions = {
3948
+ ...this._retryOptions,
3949
+ ...retryOptions
3950
+ };
3951
+ let attempt = 0;
2920
3952
  return await retriable(async () => {
3953
+ attempt++;
2921
3954
  const ctrl = new AbortController;
2922
3955
  const timeoutMs = requestTimeout ?? this.requestTimeout;
2923
- const timer = safeSetTimeout(() => ctrl.abort(), timeoutMs);
2924
- let res = null;
3956
+ const requestDeadline = Date.now() + timeoutMs;
3957
+ let timer;
3958
+ const deadline = new Promise((_resolve, reject) => {
3959
+ timer = safeSetTimeout(() => {
3960
+ const timeoutError = new Error(`Request timed out after ${timeoutMs}ms`);
3961
+ timeoutError.name = "AbortError";
3962
+ reject(timeoutError);
3963
+ ctrl.abort(timeoutError);
3964
+ }, timeoutMs);
3965
+ });
3966
+ let res;
3967
+ let responseAccepted = false;
3968
+ let cancellation;
3969
+ const cancelBody = () => cancellation ??= (async () => {
3970
+ try {
3971
+ await res?.body?.cancel();
3972
+ } catch {}
3973
+ })();
2925
3974
  try {
2926
- res = await this.fetch(url, {
2927
- signal: ctrl.signal,
2928
- ...options
2929
- });
2930
- } catch (e) {
2931
- throw new PostHogFetchNetworkError(e);
3975
+ let fetchPromise;
3976
+ try {
3977
+ fetchPromise = this.fetch(url, {
3978
+ signal: ctrl.signal,
3979
+ ...options
3980
+ });
3981
+ } catch (e) {
3982
+ throw new PostHogFetchNetworkError(e);
3983
+ }
3984
+ fetchPromise.then((lateResponse) => {
3985
+ if (ctrl.signal.aborted && !responseAccepted)
3986
+ Promise.resolve(lateResponse.body?.cancel()).catch(() => {});
3987
+ }).catch(() => {});
3988
+ try {
3989
+ res = await Promise.race([
3990
+ fetchPromise,
3991
+ deadline
3992
+ ]);
3993
+ responseAccepted = true;
3994
+ } catch (e) {
3995
+ throw new PostHogFetchNetworkError(e);
3996
+ }
3997
+ const isNoCors = options.mode === "no-cors";
3998
+ if (!isNoCors && (res.status < 200 || res.status >= 400))
3999
+ throw new PostHogFetchHttpError(res, reqByteLength, requestDeadline, ctrl);
4000
+ if (responseHandling.type === "successful-write") {
4001
+ try {
4002
+ await Promise.race([
4003
+ cancelBody(),
4004
+ deadline
4005
+ ]);
4006
+ } catch {}
4007
+ return;
4008
+ }
4009
+ try {
4010
+ return await Promise.race([
4011
+ responseHandling.consume(res),
4012
+ deadline
4013
+ ]);
4014
+ } catch (e) {
4015
+ if (ctrl.signal.aborted)
4016
+ throw new PostHogFetchNetworkError(e);
4017
+ throw e;
4018
+ }
2932
4019
  } finally {
2933
4020
  clearTimeout(timer);
4021
+ if (ctrl.signal.aborted && res)
4022
+ cancelBody();
2934
4023
  }
2935
- const isNoCors = options.mode === "no-cors";
2936
- if (!isNoCors && (res.status < 200 || res.status >= 400))
2937
- throw new PostHogFetchHttpError(res, reqByteLength);
2938
- return res;
2939
4024
  }, {
2940
- ...this._retryOptions,
2941
- ...retryOptions
4025
+ ...retriableOptions,
4026
+ retryCheck: (error) => {
4027
+ const shouldRetry = retriableOptions.retryCheck(error);
4028
+ if (shouldRetry && attempt <= retriableOptions.retryCount && error instanceof PostHogFetchHttpError)
4029
+ error.cancelResponseBody();
4030
+ return shouldRetry;
4031
+ }
2942
4032
  });
2943
4033
  }
2944
4034
  async _shutdown(shutdownTimeoutMs = 30000) {
@@ -2951,12 +4041,17 @@ class PostHogCoreStateless {
2951
4041
  try {
2952
4042
  await this.promiseQueue.join();
2953
4043
  while (true) {
2954
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2955
- if (queue.length === 0)
4044
+ const hasQueuedEvents = this.getActiveQueueRoutes().some((route) => this.getRouteQueue(route).length > 0);
4045
+ if (!hasQueuedEvents)
2956
4046
  break;
4047
+ const dequeuedBeforeFlush = this._dequeuedMessagesCount;
2957
4048
  await this.flush();
2958
4049
  if (hasTimedOut)
2959
4050
  break;
4051
+ if (this._dequeuedMessagesCount === dequeuedBeforeFlush) {
4052
+ this._logger.warn("Shutdown flush completed but did not send any queued events. Stopping drain to avoid a loop.");
4053
+ break;
4054
+ }
2960
4055
  }
2961
4056
  } catch (e) {
2962
4057
  if (!isPostHogFetchError(e))
@@ -2964,21 +4059,12 @@ class PostHogCoreStateless {
2964
4059
  await logFlushError(e);
2965
4060
  }
2966
4061
  };
2967
- let timeoutHandle;
2968
- try {
2969
- return await Promise.race([
2970
- new Promise((_, reject) => {
2971
- timeoutHandle = safeSetTimeout(() => {
2972
- this._logger.error("Timed out while shutting down PostHog");
2973
- hasTimedOut = true;
2974
- reject("Timeout while shutting down PostHog. Some events may not have been sent.");
2975
- }, shutdownTimeoutMs);
2976
- }),
2977
- doShutdown()
2978
- ]);
2979
- } finally {
2980
- clearTimeout(timeoutHandle);
2981
- }
4062
+ return raceWithTimeout(doShutdown(), shutdownTimeoutMs, () => {
4063
+ this._logger.critical("Timeout while shutting down PostHog. Some events may not have been sent.", {
4064
+ shutdownTimeoutMs
4065
+ });
4066
+ hasTimedOut = true;
4067
+ });
2982
4068
  }
2983
4069
  async shutdown(shutdownTimeoutMs = 30000) {
2984
4070
  if (this.shutdownPromise)
@@ -2990,21 +4076,30 @@ class PostHogCoreStateless {
2990
4076
  return this.shutdownPromise;
2991
4077
  }
2992
4078
  }
2993
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
2994
- import { createReadStream } from "node:fs";
4079
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
4080
+ import { constants as constants2 } from "node:fs";
4081
+ import { open as promises_open } from "node:fs/promises";
4082
+ import { isAbsolute } from "node:path";
2995
4083
  import { createInterface } from "node:readline";
2996
4084
  var LRU_FILE_CONTENTS_CACHE = new exports_error_tracking.ReduceableCache(25);
2997
4085
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new exports_error_tracking.ReduceableCache(20);
2998
4086
  var DEFAULT_LINES_OF_CONTEXT = 7;
2999
4087
  var MAX_CONTEXTLINES_COLNO = 1000;
3000
4088
  var MAX_CONTEXTLINES_LINENO = 1e4;
3001
- async function addSourceContext(frames) {
4089
+ var MAX_CONTEXTLINES_FILE_SIZE = 10485760;
4090
+ async function addSourceContext(frames, openSourceFile = promises_open, logger2) {
3002
4091
  const filesToLines = {};
4092
+ let basePath;
4093
+ try {
4094
+ basePath = process.cwd();
4095
+ } catch {}
3003
4096
  for (let i = frames.length - 1;i >= 0; i--) {
3004
4097
  const frame = frames[i];
3005
4098
  const filename = frame?.filename;
3006
4099
  if (!frame || typeof filename != "string" || typeof frame.lineno != "number" || shouldSkipContextLinesForFile(filename) || shouldSkipContextLinesForFrame(frame))
3007
4100
  continue;
4101
+ if (!isAbsolute(filename) && basePath === undefined)
4102
+ continue;
3008
4103
  const filesToLinesOutput = filesToLines[filename];
3009
4104
  if (!filesToLinesOutput)
3010
4105
  filesToLines[filename] = [];
@@ -3015,50 +4110,98 @@ async function addSourceContext(frames) {
3015
4110
  return frames;
3016
4111
  const readlinePromises = [];
3017
4112
  for (const file of files) {
3018
- if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(file))
4113
+ const cacheKey = makeSourceCacheKey(file, basePath);
4114
+ if (cacheKey === undefined)
4115
+ continue;
4116
+ if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(cacheKey))
3019
4117
  continue;
3020
4118
  const filesToLineRanges = filesToLines[file];
3021
4119
  if (!filesToLineRanges)
3022
4120
  continue;
3023
4121
  filesToLineRanges.sort((a, b) => a - b);
3024
4122
  const ranges = makeLineReaderRanges(filesToLineRanges);
3025
- if (ranges.every((r) => rangeExistsInContentCache(file, r)))
4123
+ if (ranges.every((r) => rangeExistsInContentCache(cacheKey, r)))
3026
4124
  continue;
3027
- const cache = emplace(LRU_FILE_CONTENTS_CACHE, file, {});
3028
- readlinePromises.push(getContextLinesFromFile(file, ranges, cache));
4125
+ const cache = emplace(LRU_FILE_CONTENTS_CACHE, cacheKey, {});
4126
+ readlinePromises.push(getContextLinesFromFile(file, ranges, cache, cacheKey, openSourceFile, logger2));
3029
4127
  }
3030
4128
  await Promise.all(readlinePromises).catch(() => {});
3031
4129
  if (frames && frames.length > 0)
3032
- addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE);
4130
+ addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE, basePath);
3033
4131
  LRU_FILE_CONTENTS_CACHE.reduce();
3034
4132
  return frames;
3035
4133
  }
3036
- function getContextLinesFromFile(path2, ranges, output) {
4134
+ async function openRegularSourceFile(path2, openSourceFile, logger2) {
4135
+ let fileHandle;
4136
+ let isValid = false;
4137
+ try {
4138
+ fileHandle = await openSourceFile(path2, constants2.O_RDONLY | constants2.O_NONBLOCK);
4139
+ const fileStat = await fileHandle.stat();
4140
+ if (!fileStat.isFile())
4141
+ return;
4142
+ if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE)
4143
+ return void logger2?.debug(`Skipping source context for oversized file ${path2}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
4144
+ isValid = true;
4145
+ return fileHandle;
4146
+ } catch {
4147
+ return;
4148
+ } finally {
4149
+ if (fileHandle && !isValid)
4150
+ await fileHandle.close().catch(() => {});
4151
+ }
4152
+ }
4153
+ async function getContextLinesFromFile(path2, ranges, output, cacheKey, openSourceFile, logger2) {
4154
+ const fileHandle = await openRegularSourceFile(path2, openSourceFile, logger2);
4155
+ if (fileHandle === undefined)
4156
+ return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4157
+ const openedFileHandle = fileHandle;
3037
4158
  return new Promise((resolve) => {
3038
- const stream = createReadStream(path2);
3039
- const lineReaded = createInterface({
3040
- input: stream
3041
- });
3042
- function destroyStreamAndResolve() {
3043
- stream.destroy();
3044
- resolve();
4159
+ let finished = false;
4160
+ function destroyStreamAndResolve(stream2) {
4161
+ if (finished)
4162
+ return;
4163
+ finished = true;
4164
+ stream2?.destroy();
4165
+ openedFileHandle.close().then(resolve, resolve);
4166
+ }
4167
+ let stream;
4168
+ try {
4169
+ stream = openedFileHandle.createReadStream({
4170
+ autoClose: false,
4171
+ start: 0,
4172
+ end: MAX_CONTEXTLINES_FILE_SIZE - 1
4173
+ });
4174
+ } catch {
4175
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4176
+ destroyStreamAndResolve();
4177
+ return;
4178
+ }
4179
+ let lineReaded;
4180
+ try {
4181
+ lineReaded = createInterface({
4182
+ input: stream
4183
+ });
4184
+ } catch {
4185
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4186
+ destroyStreamAndResolve(stream);
4187
+ return;
3045
4188
  }
3046
4189
  let lineNumber = 0;
3047
4190
  let currentRangeIndex = 0;
3048
4191
  const range = ranges[currentRangeIndex];
3049
4192
  if (range === undefined)
3050
- return void destroyStreamAndResolve();
4193
+ return void destroyStreamAndResolve(stream);
3051
4194
  let rangeStart = range[0];
3052
4195
  let rangeEnd = range[1];
3053
4196
  function onStreamError() {
3054
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path2, 1);
4197
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
3055
4198
  lineReaded.close();
3056
4199
  lineReaded.removeAllListeners();
3057
- destroyStreamAndResolve();
4200
+ destroyStreamAndResolve(stream);
3058
4201
  }
3059
4202
  stream.on("error", onStreamError);
3060
4203
  lineReaded.on("error", onStreamError);
3061
- lineReaded.on("close", destroyStreamAndResolve);
4204
+ lineReaded.on("close", () => destroyStreamAndResolve(stream));
3062
4205
  lineReaded.on("line", (line) => {
3063
4206
  lineNumber++;
3064
4207
  if (lineNumber < rangeStart)
@@ -3083,10 +4226,11 @@ function getContextLinesFromFile(path2, ranges, output) {
3083
4226
  });
3084
4227
  });
3085
4228
  }
3086
- function addSourceContextToFrames(frames, cache) {
4229
+ function addSourceContextToFrames(frames, cache, basePath) {
3087
4230
  for (const frame of frames)
3088
4231
  if (frame.filename && frame.context_line === undefined && typeof frame.lineno == "number") {
3089
- const contents = cache.get(frame.filename);
4232
+ const cacheKey = makeSourceCacheKey(frame.filename, basePath);
4233
+ const contents = cacheKey === undefined ? undefined : cache.get(cacheKey);
3090
4234
  if (contents === undefined)
3091
4235
  continue;
3092
4236
  addContextToFrame(frame.lineno, frame, contents);
@@ -3129,8 +4273,19 @@ function shouldSkipContextLinesForFrame(frame) {
3129
4273
  return true;
3130
4274
  return false;
3131
4275
  }
3132
- function rangeExistsInContentCache(file, range) {
3133
- const contents = LRU_FILE_CONTENTS_CACHE.get(file);
4276
+ function makeSourceCacheKey(path2, basePath) {
4277
+ if (isAbsolute(path2))
4278
+ return JSON.stringify([
4279
+ null,
4280
+ path2
4281
+ ]);
4282
+ return basePath === undefined ? undefined : JSON.stringify([
4283
+ basePath,
4284
+ path2
4285
+ ]);
4286
+ }
4287
+ function rangeExistsInContentCache(cacheKey, range) {
4288
+ const contents = LRU_FILE_CONTENTS_CACHE.get(cacheKey);
3134
4289
  if (contents === undefined)
3135
4290
  return false;
3136
4291
  for (let i = range[0];i <= range[1]; i++)
@@ -3208,8 +4363,8 @@ function snipLine(line, colno) {
3208
4363
  return newLine;
3209
4364
  }
3210
4365
 
3211
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3212
- import { isAbsolute, relative, sep as sep2 } from "node:path";
4366
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
4367
+ import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "node:path";
3213
4368
  function createRelativePathModifier(basePath = process.cwd()) {
3214
4369
  const isWindows = sep2 === "\\";
3215
4370
  const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
@@ -3217,17 +4372,17 @@ function createRelativePathModifier(basePath = process.cwd()) {
3217
4372
  return async (frames) => {
3218
4373
  for (const frame of frames)
3219
4374
  if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3220
- if (isAbsolute(frame.filename))
4375
+ if (isAbsolute2(frame.filename))
3221
4376
  frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
3222
4377
  }
3223
4378
  return frames;
3224
4379
  };
3225
4380
  }
3226
4381
 
3227
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/version.mjs
3228
- var version = "5.35.12";
4382
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/version.mjs
4383
+ var version = "5.51.1";
3229
4384
 
3230
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/types.mjs
4385
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/types.mjs
3231
4386
  var FeatureFlagError2 = {
3232
4387
  ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
3233
4388
  FLAG_MISSING: "flag_missing",
@@ -3235,7 +4390,7 @@ var FeatureFlagError2 = {
3235
4390
  UNKNOWN_ERROR: "unknown_error"
3236
4391
  };
3237
4392
 
3238
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/feature-flag-evaluations.mjs
4393
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/feature-flag-evaluations.mjs
3239
4394
  class FeatureFlagEvaluations {
3240
4395
  constructor(init) {
3241
4396
  this._host = init.host;
@@ -3251,10 +4406,10 @@ class FeatureFlagEvaluations {
3251
4406
  this._accessed = init.accessed ?? new Set;
3252
4407
  this._isSlice = init.isSlice ?? false;
3253
4408
  }
3254
- isEnabled(key) {
4409
+ isEnabled(key, options = {}) {
3255
4410
  const flag = this._flags[key];
3256
4411
  this._recordAccess(key);
3257
- return flag?.enabled ?? false;
4412
+ return flag?.enabled ?? options.defaultValue ?? false;
3258
4413
  }
3259
4414
  getFlag(key) {
3260
4415
  const flag = this._flags[key];
@@ -3344,6 +4499,8 @@ class FeatureFlagEvaluations {
3344
4499
  $feature_flag_request_id: this._requestId,
3345
4500
  $feature_flag_evaluated_at: flag?.locallyEvaluated ? Date.now() : this._evaluatedAt
3346
4501
  };
4502
+ if (flag?.hasExperiment !== undefined)
4503
+ properties.$feature_flag_has_experiment = flag.hasExperiment;
3347
4504
  if (flag?.locallyEvaluated && this._flagDefinitionsLoadedAt !== undefined)
3348
4505
  properties.$feature_flag_definitions_loaded_at = this._flagDefinitionsLoadedAt;
3349
4506
  const errors = [];
@@ -3366,7 +4523,7 @@ class FeatureFlagEvaluations {
3366
4523
  }
3367
4524
  }
3368
4525
 
3369
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
4526
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
3370
4527
  async function hashSHA1(text) {
3371
4528
  const subtle = globalThis.crypto?.subtle;
3372
4529
  if (!subtle)
@@ -3376,7 +4533,7 @@ async function hashSHA1(text) {
3376
4533
  return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
3377
4534
  }
3378
4535
 
3379
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
4536
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
3380
4537
  var SIXTY_SECONDS = 60000;
3381
4538
  var LONG_SCALE = 1152921504606847000;
3382
4539
  var NULL_VALUES_ALLOWED_OPERATORS = [
@@ -3393,22 +4550,23 @@ class ClientError extends Error {
3393
4550
  Object.setPrototypeOf(this, ClientError.prototype);
3394
4551
  }
3395
4552
  }
4553
+ function setCustomErrorPrototype(error, constructor) {
4554
+ error.name = constructor.name;
4555
+ Error.captureStackTrace(error, constructor);
4556
+ Object.setPrototypeOf(error, constructor.prototype);
4557
+ }
3396
4558
 
3397
4559
  class InconclusiveMatchError extends Error {
3398
4560
  constructor(message) {
3399
4561
  super(message);
3400
- this.name = this.constructor.name;
3401
- Error.captureStackTrace(this, this.constructor);
3402
- Object.setPrototypeOf(this, InconclusiveMatchError.prototype);
4562
+ setCustomErrorPrototype(this, InconclusiveMatchError);
3403
4563
  }
3404
4564
  }
3405
4565
 
3406
4566
  class RequiresServerEvaluation extends Error {
3407
4567
  constructor(message) {
3408
4568
  super(message);
3409
- this.name = this.constructor.name;
3410
- Error.captureStackTrace(this, this.constructor);
3411
- Object.setPrototypeOf(this, RequiresServerEvaluation.prototype);
4569
+ setCustomErrorPrototype(this, RequiresServerEvaluation);
3412
4570
  }
3413
4571
  }
3414
4572
 
@@ -3417,6 +4575,7 @@ class FeatureFlagsPoller {
3417
4575
  this.debugMode = false;
3418
4576
  this.shouldBeginExponentialBackoff = false;
3419
4577
  this.backOffCount = 0;
4578
+ this.pollerStopped = false;
3420
4579
  this.pollingInterval = pollingInterval;
3421
4580
  this.personalApiKey = personalApiKey;
3422
4581
  this.featureFlags = [];
@@ -3432,6 +4591,7 @@ class FeatureFlagsPoller {
3432
4591
  this.onError = options.onError;
3433
4592
  this.customHeaders = customHeaders;
3434
4593
  this.onLoad = options.onLoad;
4594
+ this.onMinimalFlagCalledEvents = options.onMinimalFlagCalledEvents;
3435
4595
  this.cacheProvider = options.cacheProvider;
3436
4596
  this.strictLocalEvaluation = options.strictLocalEvaluation ?? false;
3437
4597
  this.loadFeatureFlags();
@@ -3629,6 +4789,7 @@ class FeatureFlagsPoller {
3629
4789
  const flagFilters = flag.filters || {};
3630
4790
  const flagConditions = flagFilters.groups || [];
3631
4791
  const flagAggregation = flagFilters.aggregation_group_type_index;
4792
+ const earlyExitEnabled = flagFilters.early_exit ?? false;
3632
4793
  const { groups, groupProperties } = evaluationContext;
3633
4794
  let isInconclusive = false;
3634
4795
  let result;
@@ -3652,12 +4813,15 @@ class FeatureFlagsPoller {
3652
4813
  effectiveBucketingValue = groups[groupName];
3653
4814
  }
3654
4815
  }
3655
- if (await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext)) {
4816
+ const matchResult = await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext);
4817
+ if (matchResult === "match") {
3656
4818
  const variantOverride = condition.variant;
3657
4819
  const flagVariants = flagFilters.multivariate?.variants || [];
3658
4820
  result = variantOverride && flagVariants.some((variant) => variant.key === variantOverride) ? variantOverride : await this.getMatchingVariant(flag, effectiveBucketingValue) || true;
3659
4821
  break;
3660
4822
  }
4823
+ if (earlyExitEnabled && matchResult === "out_of_rollout_bound")
4824
+ return false;
3661
4825
  } catch (e) {
3662
4826
  if (e instanceof RequiresServerEvaluation)
3663
4827
  throw e;
@@ -3681,16 +4845,20 @@ class FeatureFlagsPoller {
3681
4845
  for (const prop of condition.properties) {
3682
4846
  const propertyType = prop.type;
3683
4847
  let matches = false;
3684
- matches = propertyType === "cohort" ? await matchCohort(prop, properties, this.cohorts, this.debugMode, (depProp) => this.evaluateFlagDependency(depProp, properties, evaluationContext)) : propertyType === "flag" ? await this.evaluateFlagDependency(prop, properties, evaluationContext) : matchProperty(prop, properties, warnFunction);
4848
+ if (propertyType === "cohort") {
4849
+ const inCohort = await matchCohort(prop, properties, this.cohorts, this.debugMode, (depProp) => this.evaluateFlagDependency(depProp, properties, evaluationContext));
4850
+ matches = prop.operator === "not_in" ? !inCohort : inCohort;
4851
+ } else
4852
+ matches = propertyType === "flag" ? await this.evaluateFlagDependency(prop, properties, evaluationContext) : matchProperty(prop, properties, warnFunction);
3685
4853
  if (!matches)
3686
- return false;
4854
+ return "no_match";
3687
4855
  }
3688
4856
  if (rolloutPercentage == undefined)
3689
- return true;
4857
+ return "match";
3690
4858
  }
3691
4859
  if (rolloutPercentage != null && await _hash(flag.key, bucketingValue) > rolloutPercentage / 100)
3692
- return false;
3693
- return true;
4860
+ return "out_of_rollout_bound";
4861
+ return "match";
3694
4862
  }
3695
4863
  async getMatchingVariant(flag, bucketingValue) {
3696
4864
  const hashValue = await _hash(flag.key, bucketingValue, "variant");
@@ -3721,6 +4889,7 @@ class FeatureFlagsPoller {
3721
4889
  this.groupTypeMapping = flagData.groupTypeMapping;
3722
4890
  this.cohorts = flagData.cohorts;
3723
4891
  this.loadedSuccessfullyOnce = true;
4892
+ this.onMinimalFlagCalledEvents?.(flagData.minimalFlagCalledEvents === true);
3724
4893
  }
3725
4894
  warnAboutExperienceContinuityFlags(flags) {
3726
4895
  if (this.strictLocalEvaluation)
@@ -3784,7 +4953,6 @@ class FeatureFlagsPoller {
3784
4953
  clearTimeout(this.poller);
3785
4954
  this.poller = undefined;
3786
4955
  }
3787
- this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
3788
4956
  try {
3789
4957
  let shouldFetch = true;
3790
4958
  if (this.cacheProvider)
@@ -3812,17 +4980,18 @@ class FeatureFlagsPoller {
3812
4980
  return;
3813
4981
  case 401:
3814
4982
  this.beginBackoff();
3815
- throw new ClientError(`Your project key or personal API key is invalid. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
4983
+ throw new ClientError(`Your project key or secret key is invalid. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
3816
4984
  case 402:
3817
4985
  console.warn("[FEATURE FLAGS] Feature flags quota limit exceeded - unsetting all local flags. Learn more about billing limits at https://posthog.com/docs/billing/limits-alerts");
3818
4986
  this.featureFlags = [];
3819
4987
  this.featureFlagsByKey = {};
3820
4988
  this.groupTypeMapping = {};
3821
4989
  this.cohorts = {};
4990
+ this.onMinimalFlagCalledEvents?.(false);
3822
4991
  return;
3823
4992
  case 403:
3824
4993
  this.beginBackoff();
3825
- throw new ClientError(`Your personal API key does not have permission to fetch feature flag definitions for local evaluation. Setting next polling interval to ${this.getPollingInterval()}ms. Are you sure you're using the correct personal and Project API key pair? More information: https://posthog.com/docs/api/overview`);
4994
+ throw new ClientError(`Your secret key does not have permission to fetch feature flag definitions for local evaluation. Setting next polling interval to ${this.getPollingInterval()}ms. Are you sure you're using the correct secret and Project API key pair? More information: https://posthog.com/docs/api/overview`);
3826
4995
  case 429:
3827
4996
  this.beginBackoff();
3828
4997
  throw new ClientError(`You are being rate limited. Setting next polling interval to ${this.getPollingInterval()}ms. More information: https://posthog.com/docs/api#rate-limiting`);
@@ -3834,7 +5003,8 @@ class FeatureFlagsPoller {
3834
5003
  const flagData = {
3835
5004
  flags: responseJson.flags ?? [],
3836
5005
  groupTypeMapping: responseJson.group_type_mapping || {},
3837
- cohorts: responseJson.cohorts || {}
5006
+ cohorts: responseJson.cohorts || {},
5007
+ minimalFlagCalledEvents: responseJson.minimal_flag_called_events === true
3838
5008
  };
3839
5009
  this.updateFlagState(flagData);
3840
5010
  this.flagDefinitionsLoadedAt = Date.now();
@@ -3855,6 +5025,9 @@ class FeatureFlagsPoller {
3855
5025
  } catch (err) {
3856
5026
  if (err instanceof ClientError)
3857
5027
  this.onError?.(err);
5028
+ } finally {
5029
+ if (!this.pollerStopped)
5030
+ this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
3858
5031
  }
3859
5032
  }
3860
5033
  getPersonalApiKeyRequestOptions(method = "GET", etag) {
@@ -3870,7 +5043,7 @@ class FeatureFlagsPoller {
3870
5043
  headers
3871
5044
  };
3872
5045
  }
3873
- _requestFeatureFlagDefinitions() {
5046
+ async _requestFeatureFlagDefinitions() {
3874
5047
  const url = `${this.host}/flags/definitions?token=${this.projectApiKey}&send_cohorts`;
3875
5048
  const options = this.getPersonalApiKeyRequestOptions("GET", this.flagsEtag);
3876
5049
  let abortTimeout = null;
@@ -3881,23 +5054,49 @@ class FeatureFlagsPoller {
3881
5054
  }, this.timeout);
3882
5055
  options.signal = controller.signal;
3883
5056
  }
5057
+ const clearAbortTimeout = () => clearTimeout(abortTimeout);
3884
5058
  try {
3885
5059
  const fetch1 = this.fetch;
3886
- return fetch1(url, options);
3887
- } finally {
3888
- clearTimeout(abortTimeout);
5060
+ const res = await fetch1(url, options);
5061
+ if (res.status !== 200) {
5062
+ clearAbortTimeout();
5063
+ return res;
5064
+ }
5065
+ return {
5066
+ status: res.status,
5067
+ headers: res.headers,
5068
+ body: res.body,
5069
+ text: async () => {
5070
+ try {
5071
+ return await res.text();
5072
+ } finally {
5073
+ clearAbortTimeout();
5074
+ }
5075
+ },
5076
+ json: async () => {
5077
+ try {
5078
+ return await res.json();
5079
+ } finally {
5080
+ clearAbortTimeout();
5081
+ }
5082
+ }
5083
+ };
5084
+ } catch (err) {
5085
+ clearAbortTimeout();
5086
+ throw err;
3889
5087
  }
3890
5088
  }
3891
5089
  async stopPoller(timeoutMs = 30000) {
5090
+ this.pollerStopped = true;
3892
5091
  clearTimeout(this.poller);
5092
+ this.poller = undefined;
3893
5093
  if (this.cacheProvider)
3894
5094
  try {
3895
5095
  const shutdownResult = this.cacheProvider.shutdown();
3896
5096
  if (shutdownResult instanceof Promise)
3897
- await Promise.race([
3898
- shutdownResult,
3899
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Cache shutdown timeout after ${timeoutMs}ms`)), timeoutMs))
3900
- ]);
5097
+ await raceWithTimeout(shutdownResult, timeoutMs, () => {
5098
+ throw new Error(`Cache shutdown timeout after ${timeoutMs}ms`);
5099
+ });
3901
5100
  } catch (err) {
3902
5101
  this.onError?.(new Error(`Error during cache shutdown: ${err}`));
3903
5102
  }
@@ -3952,6 +5151,14 @@ function matchProperty(property, propertyValues, warnFunction) {
3952
5151
  return String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
3953
5152
  case "not_icontains":
3954
5153
  return !String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
5154
+ case "starts_with":
5155
+ return String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
5156
+ case "not_starts_with":
5157
+ return !String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
5158
+ case "ends_with":
5159
+ return String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
5160
+ case "not_ends_with":
5161
+ return !String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
3955
5162
  case "regex":
3956
5163
  return isValidRegex(String(value)) && String(overrideValue).match(String(value)) !== null;
3957
5164
  case "not_regex":
@@ -4278,19 +5485,75 @@ function relativeDateParseForFeatureFlagMatching(value) {
4278
5485
  }
4279
5486
  }
4280
5487
 
4281
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
5488
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
5489
+ var UNHANDLED_REJECTION_OPTION_NAMES = [
5490
+ "--unhandled-rejections",
5491
+ "--unhandled_rejections"
5492
+ ];
5493
+ var UNHANDLED_REJECTION_MODES = new Set([
5494
+ "throw",
5495
+ "strict",
5496
+ "warn",
5497
+ "warn-with-error-code",
5498
+ "none"
5499
+ ]);
5500
+ var STARTUP_EXEC_ARGV = [
5501
+ ...globalThis.process?.execArgv ?? []
5502
+ ];
5503
+ var STARTUP_NODE_OPTIONS = globalThis.process?.env?.NODE_OPTIONS;
5504
+ function splitNodeOptions(nodeOptions) {
5505
+ const args = [];
5506
+ let current = "";
5507
+ let isInString = false;
5508
+ for (let index = 0;index < nodeOptions.length; index++) {
5509
+ const character = nodeOptions[index];
5510
+ if (character === "\\" && isInString && index + 1 < nodeOptions.length)
5511
+ current += nodeOptions[++index];
5512
+ else if (character !== " " || isInString)
5513
+ if (character === '"')
5514
+ isInString = !isInString;
5515
+ else
5516
+ current += character;
5517
+ else if (current) {
5518
+ args.push(current);
5519
+ current = "";
5520
+ }
5521
+ }
5522
+ if (current)
5523
+ args.push(current);
5524
+ return args;
5525
+ }
5526
+ function findUnhandledRejectionMode(args) {
5527
+ let mode;
5528
+ for (let index = 0;index < args.length; index++) {
5529
+ const argument = args[index];
5530
+ const optionName = UNHANDLED_REJECTION_OPTION_NAMES.find((name) => argument === name || argument.startsWith(`${name}=`));
5531
+ if (!optionName)
5532
+ continue;
5533
+ const value = argument === optionName ? args[++index] : argument.slice(optionName.length + 1);
5534
+ if (UNHANDLED_REJECTION_MODES.has(value))
5535
+ mode = value;
5536
+ }
5537
+ return mode;
5538
+ }
5539
+ function getUnhandledRejectionMode(execArgv = STARTUP_EXEC_ARGV, nodeOptions = STARTUP_NODE_OPTIONS) {
5540
+ return findUnhandledRejectionMode(execArgv) ?? findUnhandledRejectionMode(splitNodeOptions(nodeOptions ?? "")) ?? "throw";
5541
+ }
5542
+ var STARTUP_UNHANDLED_REJECTION_MODE = getUnhandledRejectionMode();
5543
+ function captureUncaughtException(captureFn, error, origin) {
5544
+ captureFn(error, {
5545
+ mechanism: {
5546
+ type: origin === "unhandledRejection" ? "onunhandledrejection" : "onuncaughtexception",
5547
+ handled: false
5548
+ }
5549
+ });
5550
+ }
4282
5551
  function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
4283
5552
  let calledFatalError = false;
4284
- return Object.assign((error) => {
5553
+ return Object.assign((error, origin) => {
4285
5554
  const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => listener.name !== "domainUncaughtExceptionClear" && listener._posthogErrorHandler !== true).length;
4286
- const processWouldExit = userProvidedListenersCount === 0;
4287
- captureFn(error, {
4288
- mechanism: {
4289
- type: "onuncaughtexception",
4290
- handled: false
4291
- }
4292
- });
4293
- if (!calledFatalError && processWouldExit) {
5555
+ captureUncaughtException(captureFn, error, origin);
5556
+ if (!calledFatalError && userProvidedListenersCount === 0) {
4294
5557
  calledFatalError = true;
4295
5558
  onFatalFn(error);
4296
5559
  }
@@ -4298,29 +5561,38 @@ function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
4298
5561
  _posthogErrorHandler: true
4299
5562
  });
4300
5563
  }
4301
- function addUncaughtExceptionListener(captureFn, onFatalFn) {
4302
- globalThis.process?.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
5564
+ function addUncaughtExceptionListener(captureFn, onFatalFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
5565
+ const process2 = globalThis.process;
5566
+ if (!process2)
5567
+ return;
5568
+ if (mode === "strict")
5569
+ return void process2.on("uncaughtExceptionMonitor", (error, origin) => captureUncaughtException(captureFn, error, origin));
5570
+ process2.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
4303
5571
  }
4304
- function addUnhandledRejectionListener(captureFn) {
4305
- globalThis.process?.on("unhandledRejection", (reason) => captureFn(reason, {
4306
- mechanism: {
4307
- type: "onunhandledrejection",
4308
- handled: false
4309
- }
4310
- }));
5572
+ function addUnhandledRejectionListener(captureFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
5573
+ const process2 = globalThis.process;
5574
+ if (!process2 || mode === "throw" || mode === "strict" || mode === "warn-with-error-code")
5575
+ return;
5576
+ process2.on("unhandledRejection", (reason) => {
5577
+ captureFn(reason, {
5578
+ mechanism: {
5579
+ type: "onunhandledrejection",
5580
+ handled: false
5581
+ }
5582
+ });
5583
+ });
4311
5584
  }
4312
5585
 
4313
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
5586
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
4314
5587
  var SHUTDOWN_TIMEOUT = 2000;
4315
5588
 
4316
- class ErrorTracking {
5589
+ class error_tracking_ErrorTracking {
4317
5590
  constructor(client, options, _logger) {
4318
5591
  this.client = client;
4319
5592
  this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
4320
5593
  this._logger = _logger;
4321
5594
  this._rateLimiter = new BucketedRateLimiter({
4322
- refillRate: 1,
4323
- bucketSize: 10,
5595
+ ...resolveExceptionRateLimiterConfig(options),
4324
5596
  refillInterval: 1e4,
4325
5597
  _logger: this._logger
4326
5598
  });
@@ -4335,6 +5607,9 @@ class ErrorTracking {
4335
5607
  };
4336
5608
  const exceptionProperties = builder.buildFromUnknown(error, hint);
4337
5609
  exceptionProperties.$exception_list = await builder.modifyFrames(exceptionProperties.$exception_list);
5610
+ const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
5611
+ if (injectedReleaseId)
5612
+ properties.$release_id = injectedReleaseId;
4338
5613
  return {
4339
5614
  event: "$exception",
4340
5615
  distinctId,
@@ -4353,8 +5628,8 @@ class ErrorTracking {
4353
5628
  }
4354
5629
  onException(exception, hint) {
4355
5630
  this.client.addPendingPromise((async () => {
4356
- if (!ErrorTracking.isPreviouslyCapturedError(exception)) {
4357
- const eventMessage = await ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
5631
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(exception)) {
5632
+ const eventMessage = await error_tracking_ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
4358
5633
  const exceptionProperties = eventMessage.properties;
4359
5634
  const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
4360
5635
  const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
@@ -4362,14 +5637,14 @@ class ErrorTracking {
4362
5637
  return void this._logger.info("Skipping exception capture because of client rate limiting.", {
4363
5638
  exception: exceptionType
4364
5639
  });
4365
- return this.client.capture(eventMessage);
5640
+ return this.client._capturePreparedEvent(eventMessage, false);
4366
5641
  }
4367
5642
  })());
4368
5643
  }
4369
5644
  async onFatalError(exception) {
4370
5645
  console.error(exception);
4371
5646
  await this.client.shutdown(SHUTDOWN_TIMEOUT);
4372
- process.exit(1);
5647
+ globalThis.process.exit(1);
4373
5648
  }
4374
5649
  isEnabled() {
4375
5650
  return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
@@ -4379,7 +5654,7 @@ class ErrorTracking {
4379
5654
  }
4380
5655
  }
4381
5656
 
4382
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/storage-memory.mjs
5657
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/storage-memory.mjs
4383
5658
  class PostHogMemoryStorage {
4384
5659
  getProperty(key) {
4385
5660
  return this._memoryStorage[key];
@@ -4392,7 +5667,452 @@ class PostHogMemoryStorage {
4392
5667
  }
4393
5668
  }
4394
5669
 
4395
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/client.mjs
5670
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/config.mjs
5671
+ function isCaptureMode(value) {
5672
+ return value === "v0" || value === "v1";
5673
+ }
5674
+ function resolveCaptureMode() {
5675
+ const envMode = typeof process != "undefined" ? process.env?.POSTHOG_CAPTURE_MODE : undefined;
5676
+ return isCaptureMode(envMode) ? envMode : "v0";
5677
+ }
5678
+
5679
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/routing.mjs
5680
+ var AI_EVENT_PREFIX = "$ai_";
5681
+ var ANALYTICS_ROUTE = "analytics";
5682
+ var AI_ROUTE = "ai";
5683
+ function isLegacyOnlyEvent(message) {
5684
+ return typeof message.event == "string" && message.event.startsWith(AI_EVENT_PREFIX);
5685
+ }
5686
+
5687
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/errors.mjs
5688
+ class CaptureV1Error extends Error {
5689
+ constructor({ requestId, drops, retryExhausted, cause }) {
5690
+ super(CaptureV1Error.buildMessage(requestId, drops, retryExhausted, cause)), this.name = "CaptureV1Error";
5691
+ this.requestId = requestId;
5692
+ this.drops = drops;
5693
+ this.retryExhausted = retryExhausted;
5694
+ this.cause = cause;
5695
+ }
5696
+ static buildMessage(requestId, drops, retryExhausted, cause) {
5697
+ let message = `Capture V1 batch ${requestId} did not fully deliver: ${drops.length} dropped, ${retryExhausted.length} undelivered`;
5698
+ if (cause instanceof Error)
5699
+ message += ` (${cause.message})`;
5700
+ return message;
5701
+ }
5702
+ }
5703
+
5704
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/transform.mjs
5705
+ function coerceBool(value) {
5706
+ if (typeof value == "boolean")
5707
+ return value;
5708
+ if (typeof value == "number")
5709
+ return value !== 0;
5710
+ if (typeof value == "string") {
5711
+ const normalized = value.trim().toLowerCase();
5712
+ if (normalized === "true" || normalized === "1")
5713
+ return true;
5714
+ if (normalized === "false" || normalized === "0")
5715
+ return false;
5716
+ }
5717
+ }
5718
+ function coerceString(value) {
5719
+ return typeof value == "string" ? value : undefined;
5720
+ }
5721
+ var OPTION_SENTINELS = [
5722
+ {
5723
+ property: "$cookieless_mode",
5724
+ optionKey: "cookieless_mode",
5725
+ coerce: coerceBool
5726
+ },
5727
+ {
5728
+ property: "$ignore_sent_at",
5729
+ optionKey: "disable_skew_correction",
5730
+ coerce: coerceBool
5731
+ },
5732
+ {
5733
+ property: "$process_person_profile",
5734
+ optionKey: "process_person_profile",
5735
+ coerce: coerceBool
5736
+ },
5737
+ {
5738
+ property: "$product_tour_id",
5739
+ optionKey: "product_tour_id",
5740
+ coerce: coerceString
5741
+ }
5742
+ ];
5743
+ var TOPLEVEL_SENTINELS = [
5744
+ {
5745
+ property: "$session_id",
5746
+ field: "session_id"
5747
+ },
5748
+ {
5749
+ property: "$window_id",
5750
+ field: "window_id"
5751
+ }
5752
+ ];
5753
+ function isRecord2(value) {
5754
+ return typeof value == "object" && value !== null && !Array.isArray(value);
5755
+ }
5756
+ function toRfc3339(timestamp) {
5757
+ if (typeof timestamp == "string") {
5758
+ const asDate2 = new Date(timestamp);
5759
+ if (Number.isNaN(asDate2.getTime()))
5760
+ return new Date().toISOString();
5761
+ const normalized = asDate2.toISOString();
5762
+ const fractionalSeconds = timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1];
5763
+ return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
5764
+ }
5765
+ if (timestamp instanceof Date)
5766
+ return Number.isNaN(timestamp.getTime()) ? new Date().toISOString() : timestamp.toISOString();
5767
+ const asDate = timestamp == null ? new Date : new Date(timestamp);
5768
+ return Number.isNaN(asDate.getTime()) ? new Date().toISOString() : asDate.toISOString();
5769
+ }
5770
+ function relocateInto(properties, key, value) {
5771
+ if (value !== undefined && !(key in properties))
5772
+ properties[key] = value;
5773
+ }
5774
+ function buildV1Event(message) {
5775
+ const sourceProperties = isRecord2(message.properties) ? message.properties : {};
5776
+ const properties = {
5777
+ ...sourceProperties
5778
+ };
5779
+ const options = {};
5780
+ for (const { property, optionKey, coerce } of OPTION_SENTINELS)
5781
+ if (property in properties) {
5782
+ const coerced = coerce(properties[property]);
5783
+ if (coerced !== undefined)
5784
+ options[optionKey] = coerced;
5785
+ delete properties[property];
5786
+ }
5787
+ const topLevel = {};
5788
+ for (const { property, field } of TOPLEVEL_SENTINELS)
5789
+ if (property in properties) {
5790
+ const value = properties[property];
5791
+ if (typeof value == "string")
5792
+ topLevel[field] = value;
5793
+ delete properties[property];
5794
+ }
5795
+ delete properties.$lib;
5796
+ delete properties.$lib_version;
5797
+ relocateInto(properties, "$set", message.$set);
5798
+ relocateInto(properties, "$set_once", message.$set_once);
5799
+ return {
5800
+ event: String(message.event ?? ""),
5801
+ uuid: String(message.uuid ?? ""),
5802
+ distinct_id: String(message.distinct_id ?? ""),
5803
+ timestamp: toRfc3339(message.timestamp),
5804
+ ...topLevel,
5805
+ options,
5806
+ properties
5807
+ };
5808
+ }
5809
+ function buildV1Batch(messages, { createdAt, historicalMigration }) {
5810
+ const batch = {
5811
+ created_at: createdAt,
5812
+ batch: messages.map(buildV1Event)
5813
+ };
5814
+ if (historicalMigration)
5815
+ batch.historical_migration = true;
5816
+ return batch;
5817
+ }
5818
+
5819
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/sender.mjs
5820
+ var V1_ANALYTICS_PATH = "/i/v1/analytics/events";
5821
+ var DEFAULT_MAX_BACKOFF_MS = 30000;
5822
+ var RETRYABLE_STATUSES = new Set([
5823
+ 408,
5824
+ 500,
5825
+ 502,
5826
+ 503,
5827
+ 504
5828
+ ]);
5829
+
5830
+ class V1CaptureSender {
5831
+ constructor(config, hooks) {
5832
+ this.config = config;
5833
+ this.maxBackoffMs = config.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
5834
+ this.fetchFn = hooks.fetch;
5835
+ this.onError = hooks.onError;
5836
+ this.now = hooks.now ?? Date.now;
5837
+ this.sleep = hooks.sleep ?? ((ms) => new Promise((resolve) => safeSetTimeout(resolve, ms)));
5838
+ this.generateRequestId = hooks.generateRequestId ?? uuidv7;
5839
+ this.compress = hooks.compress ?? gzipCompress;
5840
+ }
5841
+ async sendV1Batch(messages) {
5842
+ if (messages.length === 0)
5843
+ return;
5844
+ const requestId = this.generateRequestId();
5845
+ const createdAt = new Date(this.now()).toISOString();
5846
+ const { batch } = buildV1Batch(messages, {
5847
+ createdAt,
5848
+ historicalMigration: this.config.historicalMigration
5849
+ });
5850
+ const url = `${this.config.host}${V1_ANALYTICS_PATH}`;
5851
+ const drops = [];
5852
+ let pending = batch;
5853
+ const maxAttempts = Math.max(1, this.config.maxAttempts);
5854
+ for (let attempt = 1;attempt <= maxAttempts; attempt++) {
5855
+ const isLastAttempt = attempt === maxAttempts;
5856
+ const payload = safeJsonStringify({
5857
+ created_at: createdAt,
5858
+ ...this.config.historicalMigration ? {
5859
+ historical_migration: true
5860
+ } : {},
5861
+ batch: pending
5862
+ });
5863
+ let captureAttempt;
5864
+ let retryDelayMs;
5865
+ try {
5866
+ captureAttempt = await this.sendOnce(url, payload, attempt, requestId);
5867
+ const { response, signal } = captureAttempt;
5868
+ const { status } = response;
5869
+ if (status < 200 || status >= 300)
5870
+ if (!isLastAttempt && RETRYABLE_STATUSES.has(status)) {
5871
+ const retryAfterMs = this.parseRetryAfter(response);
5872
+ await captureAttempt.waitFor(captureAttempt.cancelBody()).catch(() => {});
5873
+ retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
5874
+ } else {
5875
+ const httpError = await this.buildHttpError(response, status, captureAttempt.waitFor);
5876
+ return this.surfaceBatchFailure(requestId, drops, pending, httpError);
5877
+ }
5878
+ else {
5879
+ let parsed;
5880
+ try {
5881
+ parsed = await captureAttempt.waitFor(this.parseResponse(response));
5882
+ } catch (error) {
5883
+ if (signal.aborted)
5884
+ throw error;
5885
+ return this.surfaceBatchFailure(requestId, drops, pending, new Error(`Capture V1 returned an unparseable ${status} response body`));
5886
+ }
5887
+ const retryable = this.classify(pending, parsed, drops);
5888
+ if (retryable.length === 0)
5889
+ return this.surfacePartialDrops(requestId, drops);
5890
+ if (isLastAttempt)
5891
+ return void this.onError(new CaptureV1Error({
5892
+ requestId,
5893
+ drops,
5894
+ retryExhausted: retryable.map((event) => event.uuid)
5895
+ }));
5896
+ pending = retryable;
5897
+ const retryAfterMs = this.parseRetryAfter(response);
5898
+ retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
5899
+ }
5900
+ } catch (transportError) {
5901
+ if (captureAttempt && !captureAttempt.signal.aborted)
5902
+ throw transportError;
5903
+ if (isLastAttempt)
5904
+ return this.surfaceBatchFailure(requestId, drops, pending, transportError);
5905
+ retryDelayMs = this.backoffDelay(attempt);
5906
+ } finally {
5907
+ captureAttempt?.cleanup();
5908
+ }
5909
+ if (retryDelayMs !== undefined)
5910
+ await this.sleep(retryDelayMs);
5911
+ }
5912
+ }
5913
+ async sendOnce(url, payload, attempt, requestId) {
5914
+ const headers = this.buildHeaders(attempt, requestId);
5915
+ let body = payload;
5916
+ if (this.config.compressionEnabled) {
5917
+ const compressed = await this.compress(payload, this.config.isDebug);
5918
+ if (compressed !== null) {
5919
+ body = compressed;
5920
+ headers["Content-Encoding"] = "gzip";
5921
+ }
5922
+ }
5923
+ const controller = new AbortController;
5924
+ let timeoutPhase = "waiting for response headers";
5925
+ let timer;
5926
+ const deadline = new Promise((_resolve, reject) => {
5927
+ timer = safeSetTimeout(() => {
5928
+ const timeoutError = new Error(`Capture V1 request timed out ${timeoutPhase} after ${this.config.requestTimeoutMs}ms`);
5929
+ timeoutError.name = "AbortError";
5930
+ reject(timeoutError);
5931
+ controller.abort(timeoutError);
5932
+ }, this.config.requestTimeoutMs);
5933
+ });
5934
+ try {
5935
+ const fetchPromise = this.fetchFn(url, {
5936
+ method: "POST",
5937
+ headers,
5938
+ body,
5939
+ signal: controller.signal
5940
+ });
5941
+ let responseAccepted = false;
5942
+ fetchPromise.then((lateResponse) => {
5943
+ if (controller.signal.aborted && !responseAccepted)
5944
+ this.cancelBody(lateResponse);
5945
+ }).catch(() => {});
5946
+ const response = await Promise.race([
5947
+ fetchPromise,
5948
+ deadline
5949
+ ]);
5950
+ responseAccepted = true;
5951
+ timeoutPhase = "while reading the response body";
5952
+ let cleanedUp = false;
5953
+ let cancellation;
5954
+ const cancelBody = () => cancellation ??= this.cancelBody(response);
5955
+ return {
5956
+ response,
5957
+ signal: controller.signal,
5958
+ waitFor: (operation) => Promise.race([
5959
+ operation,
5960
+ deadline
5961
+ ]),
5962
+ cancelBody,
5963
+ cleanup: () => {
5964
+ if (cleanedUp)
5965
+ return;
5966
+ cleanedUp = true;
5967
+ clearTimeout(timer);
5968
+ if (controller.signal.aborted)
5969
+ cancelBody();
5970
+ }
5971
+ };
5972
+ } catch (error) {
5973
+ clearTimeout(timer);
5974
+ throw error;
5975
+ }
5976
+ }
5977
+ buildHeaders(attempt, requestId) {
5978
+ const sdkInfo = `${this.config.libraryId}/${this.config.libraryVersion}`;
5979
+ const headers = {
5980
+ "Content-Type": "application/json",
5981
+ Authorization: `Bearer ${this.config.apiKey}`,
5982
+ "PostHog-Sdk-Info": sdkInfo,
5983
+ "PostHog-Attempt": String(attempt),
5984
+ "PostHog-Request-Id": requestId,
5985
+ "PostHog-Request-Timestamp": new Date(this.now()).toISOString()
5986
+ };
5987
+ if (this.config.userAgent)
5988
+ headers["User-Agent"] = this.config.userAgent;
5989
+ return headers;
5990
+ }
5991
+ classify(pending, parsed, drops) {
5992
+ const results = parsed.results ?? {};
5993
+ const retryable = [];
5994
+ for (const event of pending) {
5995
+ const result = results[event.uuid];
5996
+ if (result) {
5997
+ if (result.result === "drop")
5998
+ drops.push({
5999
+ uuid: event.uuid,
6000
+ details: result.details ?? undefined
6001
+ });
6002
+ else if (result.result === "retry")
6003
+ retryable.push(event);
6004
+ }
6005
+ }
6006
+ return retryable;
6007
+ }
6008
+ backoffDelay(attempt, retryAfterMs) {
6009
+ const exponential = Math.min(this.config.initialRetryDelayMs * 2 ** (attempt - 1), this.maxBackoffMs);
6010
+ if (retryAfterMs === undefined)
6011
+ return exponential;
6012
+ return Math.max(exponential, Math.min(retryAfterMs, this.maxBackoffMs));
6013
+ }
6014
+ parseRetryAfter(response) {
6015
+ const raw = response.headers?.get("Retry-After");
6016
+ if (!raw)
6017
+ return;
6018
+ const trimmed = raw.trim();
6019
+ if (/^\d+$/.test(trimmed)) {
6020
+ const seconds = parseInt(trimmed, 10);
6021
+ return Number.isFinite(seconds) && seconds > 0 ? 1000 * seconds : undefined;
6022
+ }
6023
+ const dateMs = Date.parse(trimmed);
6024
+ if (Number.isNaN(dateMs))
6025
+ return;
6026
+ const delta = dateMs - this.now();
6027
+ return delta > 0 ? delta : undefined;
6028
+ }
6029
+ async parseResponse(response) {
6030
+ const text = await response.text();
6031
+ const parsed = JSON.parse(text);
6032
+ if (typeof parsed != "object" || parsed === null || Array.isArray(parsed))
6033
+ throw new Error("unexpected response shape");
6034
+ const results = parsed.results;
6035
+ if (results !== undefined && (typeof results != "object" || results === null || Array.isArray(results)))
6036
+ throw new Error("unexpected results shape");
6037
+ return {
6038
+ results: results ?? {}
6039
+ };
6040
+ }
6041
+ async buildHttpError(response, status, waitFor) {
6042
+ let bodyText = "";
6043
+ try {
6044
+ bodyText = (await waitFor(response.text())).slice(0, 512);
6045
+ } catch {}
6046
+ const suffix = bodyText ? `: ${bodyText}` : "";
6047
+ return new Error(`Capture V1 request failed with HTTP ${status}${suffix}`);
6048
+ }
6049
+ surfaceBatchFailure(requestId, drops, pending, cause) {
6050
+ this.onError(new CaptureV1Error({
6051
+ requestId,
6052
+ drops,
6053
+ retryExhausted: pending.map((event) => event.uuid),
6054
+ cause
6055
+ }));
6056
+ }
6057
+ surfacePartialDrops(requestId, drops) {
6058
+ if (drops.length > 0)
6059
+ this.onError(new CaptureV1Error({
6060
+ requestId,
6061
+ drops,
6062
+ retryExhausted: []
6063
+ }));
6064
+ }
6065
+ async cancelBody(response) {
6066
+ try {
6067
+ await response.body?.cancel();
6068
+ } catch {}
6069
+ }
6070
+ }
6071
+
6072
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/ai-capture/routing.mjs
6073
+ var AI_CAPTURE_ROUTE = "ai-capture";
6074
+ var AI_CAPTURE_ENDPOINT_PATH = "/i/v0/ai/batch/";
6075
+ var AI_MAX_EVENT_BYTES = 8388608;
6076
+ var AI_BATCH_TARGET_BYTES = 5242880;
6077
+
6078
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/ai-capture/batching.mjs
6079
+ var encoder = new TextEncoder;
6080
+ function eventByteSize(message) {
6081
+ return encoder.encode(safeJsonStringify(message)).length;
6082
+ }
6083
+ function partitionAiBatch(messages, maxEventBytes = AI_MAX_EVENT_BYTES, targetBatchBytes = AI_BATCH_TARGET_BYTES) {
6084
+ const batches = [];
6085
+ const dropped = [];
6086
+ let current = [];
6087
+ let currentBytes = 0;
6088
+ for (const message of messages) {
6089
+ if (message === undefined)
6090
+ continue;
6091
+ const bytes = eventByteSize(message);
6092
+ if (bytes > maxEventBytes) {
6093
+ dropped.push({
6094
+ event: typeof message.event == "string" ? message.event : "unknown",
6095
+ bytes
6096
+ });
6097
+ continue;
6098
+ }
6099
+ if (current.length > 0 && currentBytes + bytes > targetBatchBytes) {
6100
+ batches.push(current);
6101
+ current = [];
6102
+ currentBytes = 0;
6103
+ }
6104
+ current.push(message);
6105
+ currentBytes += bytes;
6106
+ }
6107
+ if (current.length > 0)
6108
+ batches.push(current);
6109
+ return {
6110
+ batches,
6111
+ dropped
6112
+ };
6113
+ }
6114
+
6115
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/client.mjs
4396
6116
  var MINIMUM_POLLING_INTERVAL = 100;
4397
6117
  var THIRTY_SECONDS = 30000;
4398
6118
  var MAX_CACHE_SIZE = 50000;
@@ -4417,6 +6137,12 @@ function normalizeHost(value) {
4417
6137
  const normalizedValue = typeof value == "string" ? value.trim() : "";
4418
6138
  return normalizedValue || DEFAULT_NODE_HOST;
4419
6139
  }
6140
+ function normalizeUnsetPersonProperties(value) {
6141
+ const propertyNames = Array.isArray(value) ? value : [
6142
+ value
6143
+ ];
6144
+ return propertyNames.filter((propertyName) => typeof propertyName == "string" && propertyName.trim().length > 0);
6145
+ }
4420
6146
  function buildFlagEventProperties(flagValues) {
4421
6147
  if (!flagValues)
4422
6148
  return {};
@@ -4434,11 +6160,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
4434
6160
  const normalizedApiKey = normalizeApiKey(apiKey);
4435
6161
  const normalizedOptions = {
4436
6162
  ...options,
6163
+ maxQueueSize: options.maxQueueSize ?? 1e4,
6164
+ flushInterval: options.flushInterval ?? 5000,
4437
6165
  host: normalizeHost(options.host),
4438
- personalApiKey: normalizePersonalApiKey(options.personalApiKey)
6166
+ personalApiKey: normalizePersonalApiKey(options.secretKey ?? options.personalApiKey)
4439
6167
  };
4440
- super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage;
6168
+ super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage, this._aiCaptureRouteActive = false, this._minimalFlagCalledEvents = false;
4441
6169
  this.options = normalizedOptions;
6170
+ this.captureMode = resolveCaptureMode();
6171
+ this.enableFullAiCapture = normalizedOptions.enableFullAiCapture === true;
4442
6172
  this.context = this.initializeContext();
4443
6173
  this.options.featureFlagsPollingInterval = typeof normalizedOptions.featureFlagsPollingInterval == "number" ? Math.max(normalizedOptions.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
4444
6174
  if (typeof normalizedOptions.waitUntilDebounceMs == "number")
@@ -4463,21 +6193,24 @@ class PostHogBackendClient extends PostHogCoreStateless {
4463
6193
  onLoad: (count) => {
4464
6194
  this._events.emit("localEvaluationFlagsLoaded", count);
4465
6195
  },
6196
+ onMinimalFlagCalledEvents: (enabled) => {
6197
+ this._minimalFlagCalledEvents = enabled;
6198
+ },
4466
6199
  customHeaders: this.getCustomHeaders(),
4467
6200
  cacheProvider: normalizedOptions.flagDefinitionCacheProvider,
4468
6201
  strictLocalEvaluation: normalizedOptions.strictLocalEvaluation
4469
6202
  });
4470
6203
  }
4471
- this.errorTracking = new ErrorTracking(this, normalizedOptions, this._logger);
6204
+ this.errorTracking = new error_tracking_ErrorTracking(this, normalizedOptions, this._logger);
4472
6205
  this.distinctIdHasSentFlagCalls = {};
4473
6206
  this.maxCacheSize = normalizedOptions.maxCacheSize || MAX_CACHE_SIZE;
4474
6207
  }
4475
- enqueue(type, message, options) {
4476
- super.enqueue(type, message, options);
6208
+ enqueue(type, message, options, explicitRoute) {
6209
+ super.enqueue(type, message, options, explicitRoute);
4477
6210
  this.scheduleDebouncedFlush();
4478
6211
  }
4479
6212
  async flush() {
4480
- const flushPromise = super.flush();
6213
+ const flushPromise = this.flushWithPendingPromises();
4481
6214
  const waitUntil = this.options.waitUntil;
4482
6215
  if (waitUntil && !this._waitUntilCycle)
4483
6216
  try {
@@ -4530,7 +6263,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4530
6263
  async resolveWaitUntilFlush() {
4531
6264
  const resolve = this._consumeWaitUntilCycle();
4532
6265
  try {
4533
- await super.flush();
6266
+ await this.flushWithPendingPromises();
4534
6267
  } catch {} finally {
4535
6268
  resolve?.();
4536
6269
  }
@@ -4544,12 +6277,103 @@ class PostHogBackendClient extends PostHogCoreStateless {
4544
6277
  fetch(url, options) {
4545
6278
  return this.options.fetch ? this.options.fetch(url, options) : fetch(url, options);
4546
6279
  }
6280
+ getQueueRouteKey(message) {
6281
+ return this.captureMode === "v1" && isLegacyOnlyEvent(message) ? AI_ROUTE : ANALYTICS_ROUTE;
6282
+ }
6283
+ persistedQueueKeyForRoute(route) {
6284
+ if (route === AI_CAPTURE_ROUTE)
6285
+ return types_PostHogPersistedProperty.AiCaptureQueue;
6286
+ return route === AI_ROUTE ? types_PostHogPersistedProperty.AiQueue : types_PostHogPersistedProperty.Queue;
6287
+ }
6288
+ getActiveQueueRoutes() {
6289
+ const routes = this.captureMode === "v1" ? [
6290
+ ANALYTICS_ROUTE,
6291
+ AI_ROUTE
6292
+ ] : [
6293
+ ANALYTICS_ROUTE
6294
+ ];
6295
+ if (this._aiCaptureRouteActive)
6296
+ routes.push(AI_CAPTURE_ROUTE);
6297
+ return routes;
6298
+ }
6299
+ getBatchEndpointPath(route) {
6300
+ return route === AI_CAPTURE_ROUTE ? AI_CAPTURE_ENDPOINT_PATH : super.getBatchEndpointPath(route);
6301
+ }
6302
+ async sendBatch(batchMessages, retryOptions, route = ANALYTICS_ROUTE) {
6303
+ if (route === AI_CAPTURE_ROUTE)
6304
+ return this.sendAiCaptureBatch(batchMessages, retryOptions);
6305
+ if (this.captureMode !== "v1" || route === AI_ROUTE)
6306
+ return super.sendBatch(batchMessages, retryOptions, route);
6307
+ const v1Events = batchMessages.filter((message) => message !== undefined);
6308
+ await this.getV1Sender().sendV1Batch(v1Events);
6309
+ }
6310
+ async sendAiCaptureBatch(batchMessages, retryOptions) {
6311
+ const { batches, dropped } = partitionAiBatch(batchMessages);
6312
+ for (const { event, bytes } of dropped) {
6313
+ const message = `Event ${event} (${bytes} bytes) exceeds the ${AI_MAX_EVENT_BYTES / 1048576}MiB limit for ${AI_CAPTURE_ENDPOINT_PATH}, dropping.`;
6314
+ this._logger.error(message);
6315
+ this._events.emit("error", new Error(message));
6316
+ }
6317
+ for (const batch of batches)
6318
+ await this.sendAiSubBatch(batch, retryOptions);
6319
+ }
6320
+ async sendAiSubBatch(batch, retryOptions) {
6321
+ try {
6322
+ await super.sendBatch(batch, retryOptions, AI_CAPTURE_ROUTE);
6323
+ } catch (err) {
6324
+ if (!isPostHogFetchContentTooLargeError(err))
6325
+ throw err;
6326
+ if (batch.length === 1) {
6327
+ const [event] = batch;
6328
+ const eventName = typeof event.event == "string" ? event.event : "unknown";
6329
+ const message = `Event ${eventName} (${eventByteSize(event)} bytes) was rejected with 413 by ${AI_CAPTURE_ENDPOINT_PATH} on its own, dropping.`;
6330
+ this._logger.error(message);
6331
+ this._events.emit("error", new Error(message));
6332
+ return;
6333
+ }
6334
+ const mid = Math.ceil(batch.length / 2);
6335
+ await this.sendAiSubBatch(batch.slice(0, mid), retryOptions);
6336
+ await this.sendAiSubBatch(batch.slice(mid), retryOptions);
6337
+ }
6338
+ }
6339
+ getV1Sender() {
6340
+ if (!this._v1Sender)
6341
+ this._v1Sender = new V1CaptureSender({
6342
+ host: this.host,
6343
+ apiKey: this.apiKey,
6344
+ libraryId: this.getLibraryId(),
6345
+ libraryVersion: this.getLibraryVersion(),
6346
+ userAgent: this.getCustomUserAgent() || undefined,
6347
+ historicalMigration: this.historicalMigration,
6348
+ compressionEnabled: !this.disableCompression,
6349
+ requestTimeoutMs: this.requestTimeout,
6350
+ maxAttempts: (this.options.fetchRetryCount ?? 3) + 1,
6351
+ initialRetryDelayMs: this.options.fetchRetryDelay ?? 3000,
6352
+ isDebug: this.isDebug
6353
+ }, {
6354
+ fetch: (url, fetchOptions) => this.fetch(url, fetchOptions),
6355
+ onError: (error) => this._events.emit("error", error),
6356
+ compress: (payload) => this.compressPayload(payload)
6357
+ });
6358
+ return this._v1Sender;
6359
+ }
4547
6360
  getLibraryVersion() {
4548
6361
  return version;
4549
6362
  }
6363
+ get metrics() {
6364
+ if (!this._metrics)
6365
+ this._metrics = new PostHogMetrics(this, resolveMetricsConfig(this.options.metrics), this._logger);
6366
+ return this._metrics;
6367
+ }
4550
6368
  getCustomUserAgent() {
4551
6369
  return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
4552
6370
  }
6371
+ getCommonEventProperties() {
6372
+ const commonProperties = super.getCommonEventProperties();
6373
+ if (this.options.isServer ?? true)
6374
+ commonProperties.$is_server = true;
6375
+ return commonProperties;
6376
+ }
4553
6377
  enable() {
4554
6378
  return super.optIn();
4555
6379
  }
@@ -4560,33 +6384,69 @@ class PostHogBackendClient extends PostHogCoreStateless {
4560
6384
  super.debug(enabled);
4561
6385
  this.featureFlagsPoller?.debug(enabled);
4562
6386
  }
4563
- capture(props) {
6387
+ _warnIfInvalidCapture(props, stringArgumentWarning, exceptionCaptureWarning) {
4564
6388
  if (typeof props == "string")
4565
- this._logger.warn("Called capture() with a string as the first argument when an object was expected.");
6389
+ this._logger.warn(stringArgumentWarning);
4566
6390
  if (props.event === "$exception" && !props._originatedFromCaptureException)
4567
- this._logger.warn("Using `posthog.capture('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureException(error)` instead, which attaches required metadata automatically.");
4568
- this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStateless(distinctId, event, properties, {
4569
- timestamp: options.timestamp,
4570
- disableGeoip: options.disableGeoip,
4571
- uuid: options.uuid
4572
- })).catch((err) => {
6391
+ this._logger.warn(exceptionCaptureWarning);
6392
+ }
6393
+ _sendPreparedEvent(type, props, immediate, prepareOptions, explicitRoute) {
6394
+ return this.addPendingPromise(this._prepareEventMessage(props, prepareOptions).then(({ distinctId, event, properties, options }) => {
6395
+ const captureOptions = {
6396
+ timestamp: options.timestamp,
6397
+ disableGeoip: options.disableGeoip,
6398
+ uuid: options.uuid
6399
+ };
6400
+ const message = {
6401
+ distinctId,
6402
+ event,
6403
+ properties: {
6404
+ ...properties,
6405
+ ...this.getCommonEventProperties()
6406
+ }
6407
+ };
6408
+ return immediate ? this.sendImmediate(type, message, captureOptions, explicitRoute) : this.enqueue(type, message, captureOptions, explicitRoute);
6409
+ }).catch((err) => {
4573
6410
  if (err)
4574
6411
  console.error(err);
4575
6412
  }));
4576
6413
  }
6414
+ _capturePreparedEvent(props, immediate) {
6415
+ return this._sendPreparedEvent("capture", props, immediate);
6416
+ }
6417
+ capture(props) {
6418
+ this._warnIfInvalidCapture(props, "Called capture() with a string as the first argument when an object was expected.", "Using `posthog.capture('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureException(error)` instead, which attaches required metadata automatically.");
6419
+ this._capturePreparedEvent(props, false);
6420
+ }
4577
6421
  async captureImmediate(props) {
4578
- if (typeof props == "string")
4579
- this._logger.warn("Called captureImmediate() with a string as the first argument when an object was expected.");
4580
- if (props.event === "$exception" && !props._originatedFromCaptureException)
4581
- this._logger.warn("Capturing a `$exception` event via `posthog.captureImmediate('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureExceptionImmediate(error)` instead, which attaches this metadata by default.");
4582
- return this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStatelessImmediate(distinctId, event, properties, {
4583
- timestamp: options.timestamp,
4584
- disableGeoip: options.disableGeoip,
4585
- uuid: options.uuid
4586
- })).catch((err) => {
4587
- if (err)
4588
- console.error(err);
4589
- }));
6422
+ this._warnIfInvalidCapture(props, "Called captureImmediate() with a string as the first argument when an object was expected.", "Capturing a `$exception` event via `posthog.captureImmediate('$exception')` is unreliable because it does not attach required metadata. Use `posthog.captureExceptionImmediate(error)` instead, which attaches this metadata by default.");
6423
+ return this._capturePreparedEvent(props, true);
6424
+ }
6425
+ captureAi(props) {
6426
+ if (this.disabled)
6427
+ return;
6428
+ const uuid = getEventUuid(props.uuid, uuidv7);
6429
+ this._sendPreparedAiEvent({
6430
+ ...props,
6431
+ uuid
6432
+ }, false);
6433
+ return uuid;
6434
+ }
6435
+ async captureAiImmediate(props) {
6436
+ if (this.disabled)
6437
+ return;
6438
+ const uuid = getEventUuid(props.uuid, uuidv7);
6439
+ await this._sendPreparedAiEvent({
6440
+ ...props,
6441
+ uuid
6442
+ }, true);
6443
+ return uuid;
6444
+ }
6445
+ _sendPreparedAiEvent(props, immediate) {
6446
+ if (typeof props?.event == "string" && !props.event.startsWith("$ai_"))
6447
+ this._logger.debug(`captureAi called with non-AI event ${props.event}; routing it to the AI endpoint anyway.`);
6448
+ this._aiCaptureRouteActive = true;
6449
+ return this._sendPreparedEvent("capture", props, immediate, undefined, AI_CAPTURE_ROUTE);
4590
6450
  }
4591
6451
  identify({ distinctId, properties = {}, disableGeoip }) {
4592
6452
  const { $set, $set_once, $anon_distinct_id, ...rest } = properties;
@@ -4597,8 +6457,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
4597
6457
  $set_once: setOnceProps,
4598
6458
  $anon_distinct_id: $anon_distinct_id ?? undefined
4599
6459
  };
4600
- super.identifyStateless(distinctId, eventProperties, {
6460
+ this._sendPreparedEvent("identify", {
6461
+ distinctId,
6462
+ event: "$identify",
6463
+ properties: eventProperties,
4601
6464
  disableGeoip
6465
+ }, false, {
6466
+ includeContextProperties: false
4602
6467
  });
4603
6468
  }
4604
6469
  async identifyImmediate({ distinctId, properties = {}, disableGeoip }) {
@@ -4610,18 +6475,65 @@ class PostHogBackendClient extends PostHogCoreStateless {
4610
6475
  $set_once: setOnceProps,
4611
6476
  $anon_distinct_id: $anon_distinct_id ?? undefined
4612
6477
  };
4613
- await super.identifyStatelessImmediate(distinctId, eventProperties, {
6478
+ await this._sendPreparedEvent("identify", {
6479
+ distinctId,
6480
+ event: "$identify",
6481
+ properties: eventProperties,
4614
6482
  disableGeoip
6483
+ }, true, {
6484
+ includeContextProperties: false
6485
+ });
6486
+ }
6487
+ setPersonProperties({ distinctId, properties = {}, propertiesOnce = {} }) {
6488
+ if (Object.keys(properties).length === 0 && Object.keys(propertiesOnce).length === 0)
6489
+ return;
6490
+ const eventProperties = {};
6491
+ if (Object.keys(properties).length > 0)
6492
+ eventProperties.$set = properties;
6493
+ if (Object.keys(propertiesOnce).length > 0)
6494
+ eventProperties.$set_once = propertiesOnce;
6495
+ this.capture({
6496
+ distinctId,
6497
+ event: "$set",
6498
+ properties: eventProperties
6499
+ });
6500
+ }
6501
+ unsetPersonProperties({ distinctId, properties }) {
6502
+ const propertyNames = normalizeUnsetPersonProperties(properties);
6503
+ if (propertyNames.length === 0)
6504
+ return;
6505
+ this.capture({
6506
+ distinctId,
6507
+ event: "$set",
6508
+ properties: {
6509
+ $unset: propertyNames
6510
+ }
4615
6511
  });
4616
6512
  }
4617
6513
  alias(data) {
4618
- super.aliasStateless(data.alias, data.distinctId, undefined, {
6514
+ this._sendPreparedEvent("alias", {
6515
+ distinctId: data.distinctId,
6516
+ event: "$create_alias",
6517
+ properties: {
6518
+ distinct_id: data.distinctId,
6519
+ alias: data.alias
6520
+ },
4619
6521
  disableGeoip: data.disableGeoip
6522
+ }, false, {
6523
+ includeContextProperties: false
4620
6524
  });
4621
6525
  }
4622
6526
  async aliasImmediate(data) {
4623
- await super.aliasStatelessImmediate(data.alias, data.distinctId, undefined, {
6527
+ await this._sendPreparedEvent("alias", {
6528
+ distinctId: data.distinctId,
6529
+ event: "$create_alias",
6530
+ properties: {
6531
+ distinct_id: data.distinctId,
6532
+ alias: data.alias
6533
+ },
4624
6534
  disableGeoip: data.disableGeoip
6535
+ }, true, {
6536
+ includeContextProperties: false
4625
6537
  });
4626
6538
  }
4627
6539
  isLocalEvaluationReady() {
@@ -4676,7 +6588,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4676
6588
  const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
4677
6589
  personProperties = adjustedProperties.allPersonProperties;
4678
6590
  groupProperties = adjustedProperties.allGroupProperties;
4679
- const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties);
6591
+ const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, this.personPropertiesForLocalEvaluation(distinctId, personProperties), groupProperties);
4680
6592
  if (onlyEvaluateLocally == undefined)
4681
6593
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
4682
6594
  let result;
@@ -4687,6 +6599,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4687
6599
  let flagId;
4688
6600
  let flagVersion;
4689
6601
  let flagReason;
6602
+ let flagHasExperiment;
4690
6603
  const localEvaluationEnabled = this.featureFlagsPoller !== undefined;
4691
6604
  if (localEvaluationEnabled) {
4692
6605
  await this.featureFlagsPoller?.loadFeatureFlags();
@@ -4701,6 +6614,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4701
6614
  const value = localResult.value;
4702
6615
  flagId = flag.id;
4703
6616
  flagReason = "Evaluated locally";
6617
+ flagHasExperiment = flag.has_experiment;
4704
6618
  result = {
4705
6619
  key,
4706
6620
  enabled: value !== false,
@@ -4716,12 +6630,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
4716
6630
  }
4717
6631
  }
4718
6632
  if (!flagWasLocallyEvaluated && !onlyEvaluateLocally) {
4719
- const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, [
6633
+ const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, [
4720
6634
  key
4721
6635
  ]);
4722
6636
  if (flagsResponse === undefined)
4723
6637
  featureFlagError = FeatureFlagError2.UNKNOWN_ERROR;
4724
6638
  else {
6639
+ this._minimalFlagCalledEvents = flagsResponse.minimalFlagCalledEvents === true;
4725
6640
  requestId = flagsResponse.requestId;
4726
6641
  evaluatedAt = flagsResponse.evaluatedAt;
4727
6642
  const errors = [];
@@ -4736,6 +6651,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4736
6651
  flagId = flagDetail.metadata?.id;
4737
6652
  flagVersion = flagDetail.metadata?.version;
4738
6653
  flagReason = flagDetail.reason?.description ?? flagDetail.reason?.code;
6654
+ flagHasExperiment = flagDetail.metadata?.has_experiment;
4739
6655
  let parsedPayload;
4740
6656
  if (flagDetail.metadata?.payload !== undefined)
4741
6657
  try {
@@ -4746,7 +6662,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4746
6662
  result = {
4747
6663
  key,
4748
6664
  enabled: flagDetail.enabled,
4749
- variant: flagDetail.variant,
6665
+ variant: flagDetail.variant ?? undefined,
4750
6666
  payload: parsedPayload
4751
6667
  };
4752
6668
  }
@@ -4767,6 +6683,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
4767
6683
  $feature_flag_request_id: requestId,
4768
6684
  $feature_flag_evaluated_at: flagWasLocallyEvaluated ? Date.now() : evaluatedAt
4769
6685
  };
6686
+ if (flagHasExperiment !== undefined)
6687
+ properties.$feature_flag_has_experiment = flagHasExperiment;
4770
6688
  if (flagWasLocallyEvaluated && this.featureFlagsPoller) {
4771
6689
  const flagDefinitionsLoadedAt = this.featureFlagsPoller.getFlagDefinitionsLoadedAt();
4772
6690
  if (flagDefinitionsLoadedAt !== undefined)
@@ -4881,7 +6799,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4881
6799
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
4882
6800
  personProperties = adjustedProperties.allPersonProperties;
4883
6801
  groupProperties = adjustedProperties.allGroupProperties;
4884
- const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
6802
+ const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
4885
6803
  if (onlyEvaluateLocally == undefined)
4886
6804
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
4887
6805
  const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(evaluationContext, flagKeys);
@@ -4894,7 +6812,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4894
6812
  fallbackToFlags = localEvaluationResult.fallbackToFlags;
4895
6813
  }
4896
6814
  if (fallbackToFlags && !onlyEvaluateLocally) {
4897
- const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, flagKeys);
6815
+ const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
4898
6816
  featureFlags = {
4899
6817
  ...featureFlags,
4900
6818
  ...remoteEvaluationResult.flags || {}
@@ -4942,9 +6860,10 @@ class PostHogBackendClient extends PostHogCoreStateless {
4942
6860
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
4943
6861
  personProperties = adjustedProperties.allPersonProperties;
4944
6862
  groupProperties = adjustedProperties.allGroupProperties;
4945
- const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
6863
+ const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
4946
6864
  if (onlyEvaluateLocally == undefined)
4947
6865
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
6866
+ const requestedFlagKeys = flagKeys ? new Set(flagKeys) : undefined;
4948
6867
  const records = {};
4949
6868
  let requestId;
4950
6869
  let evaluatedAt;
@@ -4963,14 +6882,17 @@ class PostHogBackendClient extends PostHogCoreStateless {
4963
6882
  id: flagDef?.id,
4964
6883
  version: undefined,
4965
6884
  reason: "Evaluated locally",
4966
- locallyEvaluated: true
6885
+ locallyEvaluated: true,
6886
+ hasExperiment: flagDef?.has_experiment
4967
6887
  };
4968
6888
  locallyEvaluatedKeys.add(key);
4969
6889
  }
4970
- const fallbackToFlags = localResult ? localResult.fallbackToFlags : true;
6890
+ const requestedFlagMissingLocally = requestedFlagKeys !== undefined && Array.from(requestedFlagKeys).some((key) => this.featureFlagsPoller?.featureFlagsByKey[key] === undefined);
6891
+ const fallbackToFlags = localResult ? localResult.fallbackToFlags || requestedFlagMissingLocally : true;
4971
6892
  if (fallbackToFlags && !onlyEvaluateLocally) {
4972
- const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, flagKeys);
6893
+ const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
4973
6894
  if (details) {
6895
+ this._minimalFlagCalledEvents = details.minimalFlagCalledEvents === true;
4974
6896
  requestId = details.requestId;
4975
6897
  evaluatedAt = details.evaluatedAt;
4976
6898
  errorsWhileComputing = Boolean(details.errorsWhileComputingFlags);
@@ -4993,7 +6915,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
4993
6915
  id: detail.metadata?.id,
4994
6916
  version: detail.metadata?.version,
4995
6917
  reason: detail.reason?.description ?? detail.reason?.code,
4996
- locallyEvaluated: false
6918
+ locallyEvaluated: false,
6919
+ hasExperiment: detail.metadata?.has_experiment
4997
6920
  };
4998
6921
  }
4999
6922
  }
@@ -5013,7 +6936,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
5013
6936
  id: existing?.id,
5014
6937
  version: existing?.version,
5015
6938
  reason: existing?.reason,
5016
- locallyEvaluated: existing?.locallyEvaluated ?? false
6939
+ locallyEvaluated: existing?.locallyEvaluated ?? false,
6940
+ hasExperiment: existing?.hasExperiment
5017
6941
  };
5018
6942
  }
5019
6943
  if (this._payloadOverrides !== undefined)
@@ -5025,6 +6949,11 @@ class PostHogBackendClient extends PostHogCoreStateless {
5025
6949
  payload
5026
6950
  };
5027
6951
  }
6952
+ if (requestedFlagKeys !== undefined) {
6953
+ for (const key of Object.keys(records))
6954
+ if (!requestedFlagKeys.has(key))
6955
+ delete records[key];
6956
+ }
5028
6957
  return new FeatureFlagEvaluations({
5029
6958
  host: this._getFeatureFlagEvaluationsHost(),
5030
6959
  distinctId: resolvedDistinctId,
@@ -5038,6 +6967,9 @@ class PostHogBackendClient extends PostHogCoreStateless {
5038
6967
  quotaLimited
5039
6968
  });
5040
6969
  }
6970
+ _shouldSendMinimalFlagCalledEvent(event, properties) {
6971
+ return event === "$feature_flag_called" && this._minimalFlagCalledEvents && properties.$feature_flag_has_experiment === false;
6972
+ }
5041
6973
  _captureFlagCalledEventIfNeeded(params) {
5042
6974
  const { distinctId, key, response, groups, disableGeoip, properties } = params;
5043
6975
  const groupSuffix = groups && Object.keys(groups).length > 0 ? `_${JSON.stringify(Object.entries(groups).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0))}` : "";
@@ -5072,9 +7004,32 @@ class PostHogBackendClient extends PostHogCoreStateless {
5072
7004
  return this._featureFlagEvaluationsHost;
5073
7005
  }
5074
7006
  groupIdentify({ groupType, groupKey, properties, distinctId, disableGeoip }) {
5075
- super.groupIdentifyStateless(groupType, groupKey, properties, {
7007
+ this._sendPreparedEvent("capture", {
7008
+ distinctId: distinctId || `$${groupType}_${groupKey}`,
7009
+ event: "$groupidentify",
7010
+ properties: {
7011
+ $group_type: groupType,
7012
+ $group_key: groupKey,
7013
+ $group_set: properties || {}
7014
+ },
7015
+ disableGeoip
7016
+ }, false, {
7017
+ includeContextProperties: false
7018
+ });
7019
+ }
7020
+ async groupIdentifyImmediate({ groupType, groupKey, properties, distinctId, disableGeoip }) {
7021
+ await this._sendPreparedEvent("capture", {
7022
+ distinctId: distinctId || `$${groupType}_${groupKey}`,
7023
+ event: "$groupidentify",
7024
+ properties: {
7025
+ $group_type: groupType,
7026
+ $group_key: groupKey,
7027
+ $group_set: properties || {}
7028
+ },
5076
7029
  disableGeoip
5077
- }, distinctId);
7030
+ }, true, {
7031
+ includeContextProperties: false
7032
+ });
5078
7033
  }
5079
7034
  async reloadFeatureFlags() {
5080
7035
  await this.featureFlagsPoller?.loadFeatureFlags(true);
@@ -5146,12 +7101,18 @@ class PostHogBackendClient extends PostHogCoreStateless {
5146
7101
  this.context?.enter(data, options);
5147
7102
  }
5148
7103
  async _shutdown(shutdownTimeoutMs) {
7104
+ const shutdownDeadlineMs = Date.now() + (shutdownTimeoutMs ?? 30000);
5149
7105
  const resolve = this._consumeWaitUntilCycle();
5150
7106
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
5151
7107
  this.errorTracking.shutdown();
7108
+ if (this._metrics) {
7109
+ await raceWithTimeout(this._metrics.flush().catch(() => {}), Math.max(0, shutdownDeadlineMs - Date.now()));
7110
+ this._metrics.reset();
7111
+ }
5152
7112
  try {
5153
- return await super._shutdown(shutdownTimeoutMs);
7113
+ return await super._shutdown(Math.max(0, shutdownDeadlineMs - Date.now()));
5154
7114
  } finally {
7115
+ this.distinctIdHasSentFlagCalls = {};
5155
7116
  resolve?.();
5156
7117
  }
5157
7118
  }
@@ -5246,7 +7207,6 @@ class PostHogBackendClient extends PostHogCoreStateless {
5246
7207
  }
5247
7208
  addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties) {
5248
7209
  const allPersonProperties = {
5249
- distinct_id: distinctId,
5250
7210
  ...personProperties || {}
5251
7211
  };
5252
7212
  const allGroupProperties = {};
@@ -5261,6 +7221,12 @@ class PostHogBackendClient extends PostHogCoreStateless {
5261
7221
  allGroupProperties
5262
7222
  };
5263
7223
  }
7224
+ personPropertiesForLocalEvaluation(distinctId, personProperties) {
7225
+ return {
7226
+ distinct_id: distinctId,
7227
+ ...personProperties || {}
7228
+ };
7229
+ }
5264
7230
  createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties) {
5265
7231
  return {
5266
7232
  distinctId,
@@ -5271,21 +7237,21 @@ class PostHogBackendClient extends PostHogCoreStateless {
5271
7237
  };
5272
7238
  }
5273
7239
  captureException(error, distinctId, additionalProperties, uuid, flags) {
5274
- if (!ErrorTracking.isPreviouslyCapturedError(error)) {
7240
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
5275
7241
  const syntheticException = new Error("PostHog syntheticException");
5276
- this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
7242
+ this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5277
7243
  syntheticException
5278
- }, distinctId, additionalProperties).then((msg) => this.capture({
7244
+ }, distinctId, additionalProperties).then((msg) => this._capturePreparedEvent({
5279
7245
  ...msg,
5280
7246
  uuid,
5281
7247
  flags
5282
- })));
7248
+ }, false)));
5283
7249
  }
5284
7250
  }
5285
7251
  async captureExceptionImmediate(error, distinctId, additionalProperties, flags) {
5286
- if (!ErrorTracking.isPreviouslyCapturedError(error)) {
7252
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
5287
7253
  const syntheticException = new Error("PostHog syntheticException");
5288
- return this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
7254
+ return this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5289
7255
  syntheticException
5290
7256
  }, distinctId, additionalProperties).then((msg) => this.captureImmediate({
5291
7257
  ...msg,
@@ -5294,24 +7260,31 @@ class PostHogBackendClient extends PostHogCoreStateless {
5294
7260
  }
5295
7261
  }
5296
7262
  async prepareEventMessage(props) {
7263
+ return this._prepareEventMessage(props);
7264
+ }
7265
+ async _prepareEventMessage(props, options = {}) {
5297
7266
  const { distinctId, event, properties, groups, flags, sendFeatureFlags, timestamp, disableGeoip, uuid } = props;
5298
7267
  const contextData = this.context?.get();
7268
+ const includeContextProperties = options.includeContextProperties ?? true;
5299
7269
  let mergedDistinctId = distinctId || contextData?.distinctId;
5300
- const mergedProperties = {
7270
+ const mergedProperties = includeContextProperties ? {
5301
7271
  ...this.props,
5302
7272
  ...contextData?.properties || {},
5303
7273
  ...properties || {}
7274
+ } : {
7275
+ ...properties || {}
5304
7276
  };
5305
7277
  if (!mergedDistinctId) {
5306
7278
  mergedDistinctId = uuidv7();
5307
7279
  mergedProperties.$process_person_profile = false;
5308
7280
  }
5309
- if (contextData?.sessionId && !mergedProperties.$session_id)
7281
+ if (includeContextProperties && contextData?.sessionId && !mergedProperties.$session_id)
5310
7282
  mergedProperties.$session_id = contextData.sessionId;
7283
+ const finalProperties = this._shouldSendMinimalFlagCalledEvent(event, mergedProperties) ? minimizeFlagCalledEventProperties(mergedProperties) : mergedProperties;
5311
7284
  const eventMessage = this._runBeforeSend({
5312
7285
  distinctId: mergedDistinctId,
5313
7286
  event,
5314
- properties: mergedProperties,
7287
+ properties: finalProperties,
5315
7288
  groups,
5316
7289
  flags,
5317
7290
  sendFeatureFlags,
@@ -5335,12 +7308,14 @@ class PostHogBackendClient extends PostHogCoreStateless {
5335
7308
  }
5336
7309
  return {};
5337
7310
  }).catch(() => ({})).then((additionalProperties) => {
5338
- const props2 = {
7311
+ const resolvedGroups = eventMessage.groups || groups;
7312
+ return {
5339
7313
  ...additionalProperties,
5340
7314
  ...eventMessage.properties || {},
5341
- $groups: eventMessage.groups || groups
7315
+ ...resolvedGroups !== undefined && Object.keys(resolvedGroups).length > 0 ? {
7316
+ $groups: resolvedGroups
7317
+ } : {}
5342
7318
  };
5343
- return props2;
5344
7319
  });
5345
7320
  if (eventMessage.event === "$pageview" && this.options.__preview_capture_bot_pageviews && typeof eventProperties.$raw_user_agent == "string") {
5346
7321
  if (isBlockedUA(eventProperties.$raw_user_agent, this.options.custom_blocked_useragents || [])) {
@@ -5367,22 +7342,26 @@ class PostHogBackendClient extends PostHogCoreStateless {
5367
7342
  beforeSend
5368
7343
  ];
5369
7344
  let result = eventMessage;
5370
- for (const fn of fns) {
5371
- result = fn(result);
5372
- if (!result) {
5373
- this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
7345
+ for (const fn of fns)
7346
+ try {
7347
+ result = fn(result);
7348
+ if (!result) {
7349
+ this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
7350
+ return null;
7351
+ }
7352
+ if (!result.properties || Object.keys(result.properties).length === 0) {
7353
+ const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
7354
+ this._logger.warn(message);
7355
+ }
7356
+ } catch (error) {
7357
+ this._logger.error(`Error in before_send function for event '${eventMessage.event}':`, error);
5374
7358
  return null;
5375
7359
  }
5376
- if (!result.properties || Object.keys(result.properties).length === 0) {
5377
- const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
5378
- this._logger.warn(message);
5379
- }
5380
- }
5381
7360
  return result;
5382
7361
  }
5383
7362
  }
5384
7363
 
5385
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/context/context.mjs
7364
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/context/context.mjs
5386
7365
  import { AsyncLocalStorage } from "node:async_hooks";
5387
7366
 
5388
7367
  class PostHogContext {
@@ -5413,7 +7392,22 @@ class PostHogContext {
5413
7392
  }
5414
7393
  }
5415
7394
 
5416
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
7395
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/gzip.node.mjs
7396
+ import { gzip } from "node:zlib";
7397
+ import { promisify } from "node:util";
7398
+ var gzipAsync = promisify(gzip);
7399
+ async function gzipCompress2(input, isDebug = true) {
7400
+ try {
7401
+ const compressed = await gzipAsync(input);
7402
+ return new Uint8Array(compressed);
7403
+ } catch (error) {
7404
+ if (isDebug)
7405
+ console.error("Failed to gzip compress data", error);
7406
+ return null;
7407
+ }
7408
+ }
7409
+
7410
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
5417
7411
  var NAME = "posthog-node";
5418
7412
  function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
5419
7413
  "error"
@@ -5453,6 +7447,9 @@ function createEventProcessor(_posthog, { organization, projectId, prefix, sever
5453
7447
  $sentry_exception_type: exceptions[0]?.type,
5454
7448
  $sentry_tags: event.tags
5455
7449
  };
7450
+ const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
7451
+ if (injectedReleaseId)
7452
+ properties.$release_id = injectedReleaseId;
5456
7453
  if (organization && projectId)
5457
7454
  properties["$sentry_url"] = (prefix || "https://sentry.io/organizations/") + organization + "/issues/?project=" + projectId + "&query=" + event.event_id;
5458
7455
  if (sendExceptionsToPostHog)
@@ -5481,11 +7478,14 @@ class PostHogSentryIntegration {
5481
7478
  };
5482
7479
  }
5483
7480
  }
5484
- // ../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/entrypoints/index.node.mjs
7481
+ // ../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/entrypoints/index.node.mjs
5485
7482
  class PostHog extends PostHogBackendClient {
5486
7483
  getLibraryId() {
5487
7484
  return "posthog-node";
5488
7485
  }
7486
+ compressPayload(payload) {
7487
+ return gzipCompress2(payload, this.isDebug);
7488
+ }
5489
7489
  initializeContext() {
5490
7490
  return new PostHogContext;
5491
7491
  }
@@ -5498,12 +7498,22 @@ class PostHog extends PostHogBackendClient {
5498
7498
  new exports_error_tracking.PrimitiveCoercer
5499
7499
  ], exports_error_tracking.createStackParser("node:javascript", exports_error_tracking.nodeStackLineParser), [
5500
7500
  createModulerModifier(),
5501
- addSourceContext,
7501
+ (frames) => addSourceContext(frames, undefined, this._logger),
5502
7502
  createRelativePathModifier()
5503
7503
  ]);
5504
7504
  }
5505
7505
  }
5506
7506
 
7507
+ // ../../telemetry-core/src/machine-id.ts
7508
+ import { createHash } from "node:crypto";
7509
+ import os2 from "node:os";
7510
+ function getDefaultTelemetryOsProvider() {
7511
+ return os2;
7512
+ }
7513
+ function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
7514
+ return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
7515
+ }
7516
+
5507
7517
  // ../../telemetry-core/src/posthog-client.ts
5508
7518
  var NO_OP_CLIENT = {
5509
7519
  enabled: false,
@@ -5538,7 +7548,7 @@ function createDefaultPostHogTransport(apiKey, options) {
5538
7548
  }
5539
7549
  function isTelemetryClientEnabled(input) {
5540
7550
  const env = input.env ?? process.env;
5541
- return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && getTelemetryApiKey(env, input.product.defaultApiKey).length > 0;
7551
+ return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && hasTelemetryApiKey(env, input.product.defaultApiKey);
5542
7552
  }
5543
7553
  function createTelemetryClient(input) {
5544
7554
  if (!isTelemetryClientEnabled(input)) {
@@ -5604,7 +7614,8 @@ function createTransport(input) {
5604
7614
  flushAt: 1,
5605
7615
  flushInterval: 0,
5606
7616
  host: getTelemetryHost(env, input.product.defaultHost),
5607
- disableGeoip: false
7617
+ disableGeoip: input.product.disableGeoip ?? false,
7618
+ ...input.product.transportOptions
5608
7619
  });
5609
7620
  } catch (error) {
5610
7621
  input.diagnostics?.({
@@ -5872,12 +7883,12 @@ function parseHookInput(raw) {
5872
7883
  }
5873
7884
  }
5874
7885
  function isCodexSessionStartInput(value) {
5875
- return isRecord2(value) && value["hook_event_name"] === "SessionStart" && typeof value["session_id"] === "string" && isStringOrNull(value["transcript_path"]) && typeof value["cwd"] === "string" && typeof value["model"] === "string" && typeof value["permission_mode"] === "string" && typeof value["source"] === "string";
7886
+ return isRecord3(value) && value["hook_event_name"] === "SessionStart" && typeof value["session_id"] === "string" && isStringOrNull(value["transcript_path"]) && typeof value["cwd"] === "string" && typeof value["model"] === "string" && typeof value["permission_mode"] === "string" && typeof value["source"] === "string";
5876
7887
  }
5877
7888
  function isStringOrNull(value) {
5878
7889
  return typeof value === "string" || value === null;
5879
7890
  }
5880
- function isRecord2(value) {
7891
+ function isRecord3(value) {
5881
7892
  return typeof value === "object" && value !== null && !Array.isArray(value);
5882
7893
  }
5883
7894
  function readStdin() {