oh-my-opencode 5.0.0-beta.3 → 5.0.0-beta.31

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 (639) 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/config-manager/parse-opencode-config-file.d.ts +2 -1
  22. package/dist/cli/doctor/checks/system-plugin.d.ts +4 -3
  23. package/dist/cli/fallback-lane-policy.d.ts +1 -0
  24. package/dist/cli/index.js +22601 -20302
  25. package/dist/cli/install-codex/install-codex-test-fixtures.d.ts +1 -1
  26. package/dist/cli/run/on-complete-hook.d.ts +2 -0
  27. package/dist/cli/runtime-commands.d.ts +1 -1
  28. package/dist/cli/worktree-sweep/classify.d.ts +16 -0
  29. package/dist/cli/worktree-sweep/format.d.ts +8 -0
  30. package/dist/cli/worktree-sweep/git.d.ts +19 -0
  31. package/dist/cli/worktree-sweep/index.d.ts +7 -0
  32. package/dist/cli/worktree-sweep/options.d.ts +2 -0
  33. package/dist/cli/worktree-sweep/parse-worktree-list.d.ts +8 -0
  34. package/dist/cli/worktree-sweep/sweep.d.ts +2 -0
  35. package/dist/cli/worktree-sweep/types.d.ts +65 -0
  36. package/dist/cli/worktree-sweep/worktree-sweep.d.ts +2 -0
  37. package/dist/cli-node/index.js +22219 -19897
  38. package/dist/config/schema/background-task.d.ts +1 -0
  39. package/dist/config/schema/commands.d.ts +1 -1
  40. package/dist/config/schema/hooks.d.ts +1 -1
  41. package/dist/config/schema/oh-my-opencode-config.d.ts +5 -1
  42. package/dist/config/schema/ulw-execute.d.ts +5 -0
  43. package/dist/config/validate.d.ts +2 -0
  44. package/dist/create-hooks.d.ts +3 -1
  45. package/dist/features/background-agent/constants.d.ts +0 -7
  46. package/dist/features/background-agent/manager.d.ts +2 -1
  47. package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +0 -1
  48. package/dist/features/background-agent/subagent-spawn-limits.d.ts +8 -0
  49. package/dist/features/btw-side/btw-command-draft.d.ts +7 -0
  50. package/dist/features/btw-side/context-injector.d.ts +15 -0
  51. package/dist/features/btw-side/index.d.ts +8 -0
  52. package/dist/features/btw-side/metadata.d.ts +15 -0
  53. package/dist/features/btw-side/parent-context-budget.d.ts +9 -0
  54. package/dist/features/btw-side/server-session-registry.d.ts +8 -0
  55. package/dist/features/btw-side/tui-adoption-cache.d.ts +13 -0
  56. package/dist/features/btw-side/tui-adoption-guard.d.ts +5 -0
  57. package/dist/features/btw-side/tui-controller-types.d.ts +68 -0
  58. package/dist/features/btw-side/tui-controller.d.ts +19 -0
  59. package/dist/features/btw-side/tui-escape-return.d.ts +12 -0
  60. package/dist/features/btw-side/tui-keymap.d.ts +17 -0
  61. package/dist/features/btw-side/tui-parent-validator.d.ts +6 -0
  62. package/dist/features/btw-side/tui-picker-options.d.ts +20 -0
  63. package/dist/features/btw-side/tui-picker.d.ts +9 -0
  64. package/dist/features/btw-side/tui-prompt-queue.d.ts +8 -0
  65. package/dist/features/btw-side/tui-session-bridge.d.ts +11 -0
  66. package/dist/features/btw-side/tui-session-catalog.d.ts +35 -0
  67. package/dist/features/btw-side/tui-side-removal.d.ts +11 -0
  68. package/dist/features/btw-side/tui-side-start.d.ts +9 -0
  69. package/dist/features/btw-side/tui-wiring.d.ts +8 -0
  70. package/dist/features/builtin-commands/templates/ulw-execute.d.ts +1 -0
  71. package/dist/features/builtin-commands/types.d.ts +1 -1
  72. package/dist/features/opengateway-provider/index.d.ts +13 -0
  73. package/dist/features/task-toast-manager/manager.d.ts +0 -24
  74. package/dist/features/team-mode/tools/messaging-fallback-wake.d.ts +15 -0
  75. package/dist/hooks/anthropic-context-window-limit-recovery/message-storage-directory.d.ts +0 -3
  76. package/dist/hooks/anthropic-context-window-limit-recovery/state.d.ts +1 -0
  77. package/dist/hooks/anthropic-context-window-limit-recovery/storage/empty-messages.d.ts +0 -1
  78. package/dist/hooks/atlas/atlas-hook.d.ts +1 -0
  79. package/dist/hooks/atlas/atlas-lifecycle-store.d.ts +50 -0
  80. package/dist/hooks/atlas/event-handler.d.ts +1 -0
  81. package/dist/hooks/atlas/final-wave-approval-gate.test-support.d.ts +50 -0
  82. package/dist/hooks/atlas/system-reminder-templates.d.ts +0 -1
  83. package/dist/hooks/atlas/tool-execute-before.d.ts +3 -0
  84. package/dist/hooks/atlas/types.d.ts +1 -0
  85. package/dist/hooks/claude-code-hooks/session-hook-state.d.ts +1 -0
  86. package/dist/hooks/claude-code-hooks/stop.d.ts +2 -0
  87. package/dist/hooks/claude-code-hooks/todo.d.ts +0 -1
  88. package/dist/hooks/claude-code-hooks/transcript.d.ts +2 -0
  89. package/dist/hooks/fsync-skip-warning/index.d.ts +4 -0
  90. package/dist/hooks/hashline-edit-diff-enhancer/hook.d.ts +1 -0
  91. package/dist/hooks/hashline-edit-diff-enhancer/pending-captures.d.ts +13 -0
  92. package/dist/hooks/index.d.ts +1 -1
  93. package/dist/hooks/keyword-detector/hook.d.ts +7 -0
  94. package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +0 -1
  95. package/dist/hooks/model-fallback/hook.d.ts +1 -1
  96. package/dist/hooks/prometheus-md-only/agent-resolution.d.ts +2 -2
  97. package/dist/hooks/runtime-fallback/chat-message-handler.d.ts +2 -0
  98. package/dist/hooks/runtime-fallback/retry-model-payload.d.ts +1 -0
  99. package/dist/hooks/runtime-fallback/runtime-model-settings.d.ts +6 -0
  100. package/dist/hooks/runtime-fallback/session-status-handler.d.ts +1 -1
  101. package/dist/hooks/runtime-fallback/types.d.ts +3 -1
  102. package/dist/hooks/sisyphus-junior-notepad/constants.d.ts +1 -1
  103. package/dist/hooks/todo-continuation-enforcer/types.d.ts +1 -0
  104. package/dist/hooks/{start-work → ulw-execute}/context-info-builder.d.ts +1 -1
  105. package/dist/hooks/{start-work → ulw-execute}/index.d.ts +1 -1
  106. package/dist/hooks/ulw-execute/ulw-execute-hook.d.ts +23 -0
  107. package/dist/index.js +12989 -7152
  108. package/dist/oh-my-opencode.schema.json +20 -2
  109. package/dist/plugin/chat-message/types.d.ts +3 -3
  110. package/dist/plugin/chat-message/ulw-execute-message.d.ts +5 -0
  111. package/dist/plugin/event-session-lifecycle.d.ts +1 -0
  112. package/dist/plugin/hooks/create-core-hooks.d.ts +2 -1
  113. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -2
  114. package/dist/plugin/hooks/create-transform-hooks.d.ts +2 -0
  115. package/dist/plugin/messages-transform.d.ts +1 -0
  116. package/dist/plugin-dispose.d.ts +3 -0
  117. package/dist/shared/agent-tool-restrictions.d.ts +0 -1
  118. package/dist/shared/index.d.ts +2 -0
  119. package/dist/shared/legacy-plugin-warning.d.ts +2 -1
  120. package/dist/shared/normalize-sdk-response.d.ts +1 -0
  121. package/dist/shared/plugin-entry-migrator.d.ts +4 -3
  122. package/dist/shared/plugin-entry-shape.d.ts +6 -0
  123. package/dist/shared/runtime-fallback-retry-marker.d.ts +16 -0
  124. package/dist/shared/shell-env.d.ts +1 -1
  125. package/dist/skills/ast-grep/AGENTS.md +51 -0
  126. package/dist/skills/coding-agent-sessions/AGENTS.md +62 -0
  127. package/dist/skills/coding-agent-sessions/SKILL.md +3 -2
  128. package/dist/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  129. package/dist/skills/coding-agent-sessions/references/senpi.md +4 -4
  130. package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  131. package/dist/skills/data-scientist/SKILL.md +99 -239
  132. package/dist/skills/data-scientist/references/execution-surfaces.md +91 -0
  133. package/dist/skills/data-scientist/references/placement.md +74 -0
  134. package/dist/skills/data-scientist/references/polars-lane.md +95 -0
  135. package/dist/skills/data-scientist/references/uv-setup.md +1 -1
  136. package/dist/skills/data-scientist/references/visualization.md +64 -0
  137. package/dist/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  138. package/dist/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  139. package/dist/skills/debugging/SKILL.md +2 -0
  140. package/dist/skills/debugging/references/methodology/00-setup.md +12 -0
  141. package/dist/skills/debugging/references/methodology/02-investigate.md +21 -0
  142. package/dist/skills/debugging/references/runtimes/go.md +15 -1
  143. package/dist/skills/debugging/references/runtimes/native-binary.md +38 -0
  144. package/dist/skills/debugging/references/runtimes/node.md +25 -0
  145. package/dist/skills/debugging/references/runtimes/python.md +13 -0
  146. package/dist/skills/debugging/references/runtimes/rust.md +41 -0
  147. package/dist/skills/debugging/references/scripts/dap.mjs +267 -0
  148. package/dist/skills/debugging/references/scripts/dap.test.ts +86 -0
  149. package/dist/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  150. package/dist/skills/debugging/references/tools/dap.md +103 -0
  151. package/dist/skills/debugging/references/tools/frida.md +193 -0
  152. package/dist/skills/frontend/SKILL.md +11 -7
  153. package/dist/skills/frontend/references/design/_INDEX.md +1 -0
  154. package/dist/skills/frontend/references/design/print-paged-media.md +76 -0
  155. package/dist/skills/frontend/references/design/stylegallery.md +80 -0
  156. package/dist/skills/frontend/references/designpowers/README.md +1 -1
  157. package/dist/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  158. package/dist/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  159. package/dist/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  160. package/dist/skills/frontend/references/designpowers/orchestration.md +1 -1
  161. package/dist/skills/frontend/references/designpowers/routing.md +5 -5
  162. package/dist/skills/review-work/SKILL.md +3 -3
  163. package/dist/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  164. package/dist/skills/ultimate-browsing/SKILL.md +2 -0
  165. package/dist/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  166. package/dist/skills/ultimate-browsing/engine/templates/package.json +1 -1
  167. package/dist/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  168. package/dist/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  169. package/dist/skills/ulw-plan/SKILL.md +6 -6
  170. package/dist/skills/ulw-plan/references/full-workflow.md +31 -7
  171. package/dist/skills/ulw-plan/references/intent-clear.md +2 -1
  172. package/dist/skills/ulw-plan/references/intent-unclear.md +5 -5
  173. package/dist/skills/ulw-research/SKILL.md +4 -2
  174. package/dist/skills/visual-qa/AGENTS.md +58 -0
  175. package/dist/skills/visual-qa/SKILL.md +3 -2
  176. package/dist/tools/delegate-task/builtin-categories.d.ts +1 -0
  177. package/dist/tools/delegate-task/builtin-category-definition.d.ts +1 -0
  178. package/dist/tools/delegate-task/sync-session-cleanup.d.ts +3 -0
  179. package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
  180. package/dist/tools/delegate-task/tool-description.d.ts +3 -1
  181. package/dist/tools/delegate-task/types.d.ts +4 -0
  182. package/dist/tui.d.ts +12 -0
  183. package/dist/tui.js +11522 -11501
  184. package/package.json +42 -36
  185. package/packages/git-bash-mcp/dist/cli.js +6 -1
  186. package/packages/git-bash-mcp/package.json +1 -1
  187. package/packages/lsp-core/src/index.ts +1 -0
  188. package/packages/lsp-core/src/lsp/client-diagnostics-concurrency.integration.test.ts +44 -0
  189. package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +0 -28
  190. package/packages/lsp-core/src/lsp/client-wrapper-outside-cwd.test.ts +78 -0
  191. package/packages/lsp-core/src/lsp/client-wrapper.test.ts +163 -13
  192. package/packages/lsp-core/src/lsp/client-wrapper.ts +110 -23
  193. package/packages/lsp-core/src/lsp/client.ts +26 -0
  194. package/packages/lsp-core/src/lsp/connection.ts +16 -0
  195. package/packages/lsp-core/src/lsp/constants.ts +6 -0
  196. package/packages/lsp-core/src/lsp/errors.ts +15 -0
  197. package/packages/lsp-core/src/lsp/format-document.test.ts +143 -0
  198. package/packages/lsp-core/src/lsp/format-document.ts +90 -0
  199. package/packages/lsp-core/src/lsp/manager-lifecycle.test.ts +262 -0
  200. package/packages/lsp-core/src/lsp/manager-max-clients.test.ts +151 -0
  201. package/packages/lsp-core/src/lsp/manager.ts +138 -12
  202. package/packages/lsp-core/src/lsp/outside-context-workspace.ts +33 -0
  203. package/packages/lsp-core/src/lsp/server-definitions.ts +29 -0
  204. package/packages/lsp-core/src/lsp/server-installation.test.ts +376 -0
  205. package/packages/lsp-core/src/lsp/server-installation.ts +200 -27
  206. package/packages/lsp-core/src/lsp/server-resolution-local-binary.test.ts +170 -0
  207. package/packages/lsp-core/src/lsp/server-resolution.ts +18 -5
  208. package/packages/lsp-core/src/lsp/transport.ts +9 -0
  209. package/packages/lsp-core/src/lsp/types.ts +8 -0
  210. package/packages/lsp-core/src/lsp/workspace-edit-adversarial.test.ts +20 -1
  211. package/packages/lsp-core/src/lsp/workspace-markers.ts +18 -0
  212. package/packages/lsp-core/src/mcp.ts +3 -0
  213. package/packages/lsp-core/src/request-context.test.ts +29 -0
  214. package/packages/lsp-core/src/request-context.ts +1 -1
  215. package/packages/lsp-core/src/tool-surface.test.ts +13 -1
  216. package/packages/lsp-core/src/tools/definitions.ts +14 -0
  217. package/packages/lsp-core/src/tools/diagnostics.ts +3 -3
  218. package/packages/lsp-core/src/tools/format.test.ts +56 -0
  219. package/packages/lsp-core/src/tools/format.ts +56 -0
  220. package/packages/lsp-core/src/tools/index.ts +1 -0
  221. package/packages/lsp-core/src/tools/navigation.ts +4 -2
  222. package/packages/lsp-core/src/tools/rename.ts +4 -2
  223. package/packages/lsp-core/src/tools/symbols.ts +1 -1
  224. package/packages/lsp-core/src/tools/types.ts +10 -0
  225. package/packages/lsp-daemon/dist/cli.js +752 -307
  226. package/packages/lsp-daemon/dist/client.d.ts +10 -0
  227. package/packages/lsp-daemon/dist/client.js +712 -264
  228. package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -0
  229. package/packages/lsp-daemon/dist/daemon-client.js +3 -0
  230. package/packages/lsp-daemon/dist/ensure-daemon.js +1 -0
  231. package/packages/lsp-daemon/dist/index.js +716 -273
  232. package/packages/lsp-daemon/dist/proxy.js +3 -0
  233. package/packages/lsp-daemon/dist/version-reap.js +1 -1
  234. package/packages/lsp-daemon/package.json +1 -1
  235. package/packages/lsp-tools-mcp/dist/cli.js +671 -228
  236. package/packages/lsp-tools-mcp/dist/lsp/manager.js +207 -103
  237. package/packages/lsp-tools-mcp/dist/mcp.js +673 -230
  238. package/packages/lsp-tools-mcp/dist/request-context.js +12 -13
  239. package/packages/lsp-tools-mcp/dist/tools.js +677 -238
  240. package/packages/omo-codex/THIRD-PARTY-NOTICES.md +4 -4
  241. package/packages/omo-codex/plugin/.codex-plugin/plugin.json +4 -4
  242. package/packages/omo-codex/plugin/AGENTS.md +47 -0
  243. package/packages/omo-codex/plugin/README.md +1 -1
  244. package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +34 -33
  245. package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
  246. package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
  247. package/packages/omo-codex/plugin/components/bootstrap/src/hook.ts +1 -0
  248. package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +323 -117
  249. package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +275 -85
  250. package/packages/omo-codex/plugin/components/codegraph/package.json +4 -4
  251. package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +1 -0
  252. package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +12 -0
  253. package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +1 -0
  254. package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +47 -0
  255. package/packages/omo-codex/plugin/components/comment-checker/AGENTS.md +9 -0
  256. package/packages/omo-codex/plugin/components/comment-checker/biome.json +2 -2
  257. package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +2 -1
  258. package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
  259. package/packages/omo-codex/plugin/components/comment-checker/package.json +5 -5
  260. package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +2 -8
  261. package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +1 -2
  262. package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
  263. package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +1 -0
  264. package/packages/omo-codex/plugin/components/git-bash/AGENTS.md +1 -1
  265. package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
  266. package/packages/omo-codex/plugin/components/git-bash/package.json +3 -4
  267. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +2 -2
  268. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +1 -5
  269. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +1 -5
  270. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
  271. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +5 -5
  272. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +1 -5
  273. package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +4 -21
  274. package/packages/omo-codex/plugin/components/lsp/AGENTS.md +30 -15
  275. package/packages/omo-codex/plugin/components/lsp/biome.json +2 -2
  276. package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +4 -4
  277. package/packages/omo-codex/plugin/components/lsp/dist/cli.js +702 -278
  278. package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +1 -1
  279. package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
  280. package/packages/omo-codex/plugin/components/lsp/package.json +5 -5
  281. package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
  282. package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +1 -1
  283. package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +1 -5
  284. package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +6 -7
  285. package/packages/omo-codex/plugin/components/lsp/test/codex-hook.test.ts +1 -2
  286. package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +11 -1
  287. package/packages/omo-codex/plugin/components/rules/AGENTS.md +12 -0
  288. package/packages/omo-codex/plugin/components/rules/biome.json +2 -2
  289. package/packages/omo-codex/plugin/components/rules/dist/cli.js +60 -45
  290. package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
  291. package/packages/omo-codex/plugin/components/rules/package.json +7 -7
  292. package/packages/omo-codex/plugin/components/rules/src/config.ts +1 -2
  293. package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -2
  294. package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +9 -5
  295. package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +1 -4
  296. package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -9
  297. package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +11 -16
  298. package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +17 -25
  299. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +9 -7
  300. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +0 -6
  301. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +6 -4
  302. package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +12 -9
  303. package/packages/omo-codex/plugin/components/rules/test/codex-hook.test.ts +28 -37
  304. package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -2
  305. package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +7 -4
  306. package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -3
  307. package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +39 -72
  308. package/packages/omo-codex/plugin/components/rules/test/hephaestus-model-variant.test.ts +1 -2
  309. package/packages/omo-codex/plugin/components/rules/test/hook-output.test.ts +2 -3
  310. package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -3
  311. package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +1 -1
  312. package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -2
  313. package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +5 -6
  314. package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +3 -6
  315. package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -2
  316. package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +2 -5
  317. package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +2 -17
  318. package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
  319. package/packages/omo-codex/plugin/components/teammode/package.json +5 -5
  320. package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +3 -9
  321. package/packages/omo-codex/plugin/components/telemetry/AGENTS.md +8 -0
  322. package/packages/omo-codex/plugin/components/telemetry/biome.json +2 -2
  323. package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +2463 -437
  324. package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +2467 -441
  325. package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
  326. package/packages/omo-codex/plugin/components/telemetry/package.json +5 -5
  327. package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +1 -4
  328. package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +4 -14
  329. package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +1 -1
  330. package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +2 -5
  331. package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +5 -0
  332. package/packages/omo-codex/plugin/components/ultrawork/biome.json +2 -2
  333. package/packages/omo-codex/plugin/components/ultrawork/directive.md +13 -1
  334. package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
  335. package/packages/omo-codex/plugin/components/ultrawork/package.json +5 -5
  336. package/packages/omo-codex/plugin/components/ultrawork/skills/ultrawork/SKILL.md +13 -1
  337. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -6
  338. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +31 -7
  339. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -1
  340. package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +5 -5
  341. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +9 -1
  342. package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +0 -136
  343. package/packages/omo-codex/plugin/components/ultrawork/test/skill-pointer.test.ts +0 -2
  344. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/AGENTS.md +5 -4
  345. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/NOTICE +1 -1
  346. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/README.md +5 -5
  347. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/biome.json +2 -2
  348. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/directive.md +6 -6
  349. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/dist/cli.js +12 -12
  350. package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +28 -0
  351. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/package.json +12 -12
  352. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/boulder-reader.ts +1 -1
  353. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/cli.ts +1 -1
  354. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/codex-hook.ts +3 -3
  355. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/directive.ts +1 -1
  356. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/index.ts +1 -1
  357. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/boulder-reader.test.ts +3 -3
  358. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/cli.test.ts +1 -4
  359. package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/codex-hook.test.ts +8 -22
  360. package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +17 -0
  361. package/packages/omo-codex/plugin/components/ulw-loop/CHANGELOG.md +1 -1
  362. package/packages/omo-codex/plugin/components/ulw-loop/biome.json +2 -2
  363. package/packages/omo-codex/plugin/components/ulw-loop/directive.md +13 -1
  364. package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +2 -0
  365. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +5 -1
  366. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +2 -1
  367. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +11 -1
  368. package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +124 -68
  369. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +2 -0
  370. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +9 -6
  371. package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +1 -1
  372. package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +1 -1
  373. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +4 -2
  374. package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +7 -10
  375. package/packages/omo-codex/plugin/components/ulw-loop/dist/spawn-guard.js +3 -2
  376. package/packages/omo-codex/plugin/components/ulw-loop/dist/stop-resume-hook.js +3 -3
  377. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.d.ts +15 -0
  378. package/packages/omo-codex/plugin/components/ulw-loop/dist/surface.js +50 -0
  379. package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
  380. package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -5
  381. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +3 -2
  382. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/define-goal.md +108 -0
  383. package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +1 -0
  384. package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +2 -0
  385. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +5 -1
  386. package/packages/omo-codex/plugin/components/ulw-loop/src/cli-output.ts +13 -1
  387. package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +3 -5
  388. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +16 -5
  389. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-snapshot.ts +3 -1
  390. package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +3 -1
  391. package/packages/omo-codex/plugin/components/ulw-loop/src/paths.ts +1 -1
  392. package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +11 -14
  393. package/packages/omo-codex/plugin/components/ulw-loop/src/spawn-guard.ts +3 -2
  394. package/packages/omo-codex/plugin/components/ulw-loop/src/stop-resume-hook.ts +3 -3
  395. package/packages/omo-codex/plugin/components/ulw-loop/src/surface.ts +73 -0
  396. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-continuation.test.ts +0 -1
  397. package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +44 -1
  398. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +25 -0
  399. package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +26 -2
  400. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +27 -2
  401. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-snapshot.test.ts +18 -0
  402. package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +0 -3
  403. package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +7 -3
  404. package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +5 -37
  405. package/packages/omo-codex/plugin/components/ulw-loop/test/paths.test.ts +9 -0
  406. package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +45 -2
  407. package/packages/omo-codex/plugin/components/ulw-loop/test/spawn-guard.test.ts +20 -0
  408. package/packages/omo-codex/plugin/components/ulw-loop/test/steering.test.ts +8 -5
  409. package/packages/omo-codex/plugin/components/ulw-loop/test/stop-resume-hook.test.ts +1 -1
  410. package/packages/omo-codex/plugin/components/ulw-loop/test/surface.test.ts +74 -0
  411. package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +4 -5
  412. package/packages/omo-codex/plugin/components/ulw-loop/vitest.config.ts +1 -0
  413. package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
  414. package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
  415. package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
  416. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +1 -1
  417. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
  418. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
  419. package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
  420. package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
  421. package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
  422. package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
  423. package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
  424. package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
  425. package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
  426. package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +1 -1
  427. package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
  428. package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
  429. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +17 -0
  430. package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
  431. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +17 -0
  432. package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
  433. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
  434. package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
  435. package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
  436. package/packages/omo-codex/plugin/model-catalog.json +3 -3
  437. package/packages/omo-codex/plugin/package-lock.json +681 -395
  438. package/packages/omo-codex/plugin/package.json +2 -2
  439. package/packages/omo-codex/plugin/scripts/AGENTS.md +40 -0
  440. package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +1 -1
  441. package/packages/omo-codex/plugin/scripts/migrate-codex-config/catalog.mjs +3 -3
  442. package/packages/omo-codex/plugin/scripts/sync-skills.mjs +11 -11
  443. package/packages/omo-codex/plugin/shared/package.json +3 -4
  444. package/packages/omo-codex/plugin/skills/ast-grep/AGENTS.md +51 -0
  445. package/packages/omo-codex/plugin/skills/coding-agent-sessions/AGENTS.md +62 -0
  446. package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +3 -2
  447. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  448. package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +4 -4
  449. package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  450. package/packages/omo-codex/plugin/skills/data-scientist/SKILL.md +99 -239
  451. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-surfaces.md +91 -0
  452. package/packages/omo-codex/plugin/skills/data-scientist/references/placement.md +74 -0
  453. package/packages/omo-codex/plugin/skills/data-scientist/references/polars-lane.md +95 -0
  454. package/packages/omo-codex/plugin/skills/data-scientist/references/uv-setup.md +1 -1
  455. package/packages/omo-codex/plugin/skills/data-scientist/references/visualization.md +64 -0
  456. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  457. package/packages/omo-codex/plugin/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  458. package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -0
  459. package/packages/omo-codex/plugin/skills/debugging/references/methodology/00-setup.md +12 -0
  460. package/packages/omo-codex/plugin/skills/debugging/references/methodology/02-investigate.md +21 -0
  461. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/go.md +15 -1
  462. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/native-binary.md +38 -0
  463. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/node.md +25 -0
  464. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/python.md +13 -0
  465. package/packages/omo-codex/plugin/skills/debugging/references/runtimes/rust.md +41 -0
  466. package/packages/omo-codex/plugin/skills/debugging/references/scripts/dap.mjs +267 -0
  467. package/packages/omo-codex/plugin/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  468. package/packages/omo-codex/plugin/skills/debugging/references/tools/dap.md +103 -0
  469. package/packages/omo-codex/plugin/skills/debugging/references/tools/frida.md +193 -0
  470. package/packages/omo-codex/plugin/skills/frontend/SKILL.md +11 -7
  471. package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +1 -0
  472. package/packages/omo-codex/plugin/skills/frontend/references/design/print-paged-media.md +76 -0
  473. package/packages/omo-codex/plugin/skills/frontend/references/design/stylegallery.md +80 -0
  474. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +1 -1
  475. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  476. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  477. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  478. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +1 -1
  479. package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +5 -5
  480. package/packages/omo-codex/plugin/skills/review-work/SKILL.md +4 -4
  481. package/packages/omo-codex/plugin/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  482. package/packages/omo-codex/plugin/skills/ultimate-browsing/SKILL.md +2 -0
  483. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  484. package/packages/omo-codex/plugin/skills/ultimate-browsing/engine/templates/package.json +1 -1
  485. package/packages/omo-codex/plugin/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  486. package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +13 -1
  487. package/packages/omo-codex/plugin/skills/{start-work → ulw-execute}/SKILL.md +12 -11
  488. package/packages/omo-codex/plugin/skills/ulw-execute/agents/openai.yaml +2 -0
  489. package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +3 -2
  490. package/packages/omo-codex/plugin/skills/ulw-loop/references/define-goal.md +108 -0
  491. package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +1 -0
  492. package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -6
  493. package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +31 -7
  494. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -1
  495. package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +5 -5
  496. package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +4 -2
  497. package/packages/omo-codex/plugin/skills/visual-qa/AGENTS.md +58 -0
  498. package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +3 -2
  499. package/packages/omo-codex/plugin/test/AGENTS.md +47 -0
  500. package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +19 -173
  501. package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +8 -28
  502. package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -1
  503. package/packages/omo-codex/plugin/test/aggregate-model-catalog.test.mjs +1 -1
  504. package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +175 -13
  505. package/packages/omo-codex/plugin/test/aggregate.test.mjs +78 -2
  506. package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +19 -33
  507. package/packages/omo-codex/plugin/test/auto-update.test.mjs +2 -2
  508. package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +2 -2
  509. package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +1 -1
  510. package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +2 -2
  511. package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +4 -4
  512. package/packages/omo-codex/plugin/test/lcx-contribute-bug-fix-template.test.mjs +21 -27
  513. package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +8 -8
  514. package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +0 -36
  515. package/packages/omo-codex/plugin/test/sync-skills-codex-compatibility.test.mjs +101 -0
  516. package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +12 -12
  517. package/packages/omo-codex/plugin/test/sync-skills.test.mjs +1 -119
  518. package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +0 -40
  519. package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +6 -62
  520. package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +3 -36
  521. package/packages/omo-codex/plugin/test/teammode-transport.test.mjs +0 -44
  522. package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +2 -6
  523. package/packages/omo-codex/plugin/test/ultrawork-skill-pointer.test.mjs +0 -3
  524. package/packages/omo-codex/plugin/test/ulw-plan-review-state-contract.test.mjs +0 -3
  525. package/packages/omo-codex/scripts/AGENTS.md +36 -0
  526. package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +2 -2
  527. package/packages/omo-codex/scripts/install-dist/install-local.mjs +2637 -549
  528. package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +7 -2
  529. package/packages/shared-skills/skills/ast-grep/AGENTS.md +51 -0
  530. package/packages/shared-skills/skills/coding-agent-sessions/AGENTS.md +62 -0
  531. package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +3 -2
  532. package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +1 -1
  533. package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +4 -4
  534. package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +1 -1
  535. package/packages/shared-skills/skills/data-scientist/SKILL.md +99 -239
  536. package/packages/shared-skills/skills/data-scientist/references/execution-surfaces.md +91 -0
  537. package/packages/shared-skills/skills/data-scientist/references/placement.md +74 -0
  538. package/packages/shared-skills/skills/data-scientist/references/polars-lane.md +95 -0
  539. package/packages/shared-skills/skills/data-scientist/references/uv-setup.md +1 -1
  540. package/packages/shared-skills/skills/data-scientist/references/visualization.md +64 -0
  541. package/packages/shared-skills/skills/data-scientist/scripts/ensure-js-deps.sh +28 -0
  542. package/packages/shared-skills/skills/data-scientist/scripts/ensure-py-deps.sh +37 -0
  543. package/packages/shared-skills/skills/debugging/SKILL.md +2 -0
  544. package/packages/shared-skills/skills/debugging/references/methodology/00-setup.md +12 -0
  545. package/packages/shared-skills/skills/debugging/references/methodology/02-investigate.md +21 -0
  546. package/packages/shared-skills/skills/debugging/references/runtimes/go.md +15 -1
  547. package/packages/shared-skills/skills/debugging/references/runtimes/native-binary.md +38 -0
  548. package/packages/shared-skills/skills/debugging/references/runtimes/node.md +25 -0
  549. package/packages/shared-skills/skills/debugging/references/runtimes/python.md +13 -0
  550. package/packages/shared-skills/skills/debugging/references/runtimes/rust.md +41 -0
  551. package/packages/shared-skills/skills/debugging/references/scripts/dap.mjs +267 -0
  552. package/packages/shared-skills/skills/debugging/references/scripts/dap.test.ts +86 -0
  553. package/packages/shared-skills/skills/debugging/references/scripts/fixture-adapter.mjs +59 -0
  554. package/packages/shared-skills/skills/debugging/references/tools/dap.md +103 -0
  555. package/packages/shared-skills/skills/debugging/references/tools/frida.md +193 -0
  556. package/packages/shared-skills/skills/frontend/SKILL.md +11 -7
  557. package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +1 -0
  558. package/packages/shared-skills/skills/frontend/references/design/print-paged-media.md +76 -0
  559. package/packages/shared-skills/skills/frontend/references/design/stylegallery.md +80 -0
  560. package/packages/shared-skills/skills/frontend/references/designpowers/README.md +1 -1
  561. package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +1 -1
  562. package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +11 -11
  563. package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +3 -3
  564. package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +1 -1
  565. package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +5 -5
  566. package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
  567. package/packages/shared-skills/skills/ultimate-browsing/ATTRIBUTION.md +37 -10
  568. package/packages/shared-skills/skills/ultimate-browsing/SKILL.md +2 -0
  569. package/packages/shared-skills/skills/ultimate-browsing/engine/AGENTS.md +179 -0
  570. package/packages/shared-skills/skills/ultimate-browsing/engine/templates/package.json +1 -1
  571. package/packages/shared-skills/skills/ultimate-browsing/references/chrome-stealth.md +13 -11
  572. package/packages/shared-skills/skills/{start-work → ulw-execute}/SKILL.md +9 -8
  573. package/packages/shared-skills/skills/ulw-plan/SKILL.md +6 -6
  574. package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +31 -7
  575. package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -1
  576. package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +5 -5
  577. package/packages/shared-skills/skills/ulw-research/SKILL.md +4 -2
  578. package/packages/shared-skills/skills/visual-qa/AGENTS.md +58 -0
  579. package/packages/shared-skills/skills/visual-qa/SKILL.md +3 -2
  580. package/script/qa/web-terminal-visual-qa.mjs +2 -0
  581. package/script/qa/xterm-live-terminal.mjs +18 -2
  582. package/dist/config/schema/start-work.d.ts +0 -5
  583. package/dist/features/builtin-commands/templates/start-work.d.ts +0 -1
  584. package/dist/hooks/ralph-loop/completion-promise-detector-test-input.d.ts +0 -11
  585. package/dist/hooks/ralph-loop/loop-session-recovery.d.ts +0 -7
  586. package/dist/hooks/start-work/start-work-hook.d.ts +0 -23
  587. package/dist/plugin/chat-message/start-work-message.d.ts +0 -5
  588. package/dist/skills/data-scientist/references/common-scenarios.md +0 -176
  589. package/dist/skills/data-scientist/references/execution-templates.md +0 -197
  590. package/dist/skills/data-scientist/references/integration-patterns.md +0 -153
  591. package/dist/skills/data-scientist/references/performance-benchmarks.md +0 -37
  592. package/dist/tools/call-omo-agent/background-agent-executor.d.ts +0 -5
  593. package/dist/tools/call-omo-agent/message-storage-directory.d.ts +0 -1
  594. package/dist/tools/delegate-task/model-string-parser.d.ts +0 -1
  595. package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +0 -1
  596. package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +0 -1
  597. package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +0 -1
  598. package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +0 -1
  599. package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +0 -1
  600. package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +0 -28
  601. package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +0 -17
  602. package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +0 -17
  603. package/packages/omo-codex/plugin/skills/data-scientist/references/common-scenarios.md +0 -176
  604. package/packages/omo-codex/plugin/skills/data-scientist/references/execution-templates.md +0 -197
  605. package/packages/omo-codex/plugin/skills/data-scientist/references/integration-patterns.md +0 -153
  606. package/packages/omo-codex/plugin/skills/data-scientist/references/performance-benchmarks.md +0 -37
  607. package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +0 -2
  608. package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +0 -92
  609. package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +0 -314
  610. package/packages/omo-codex/plugin/test/ulw-plan-scope-contract.test.mjs +0 -24
  611. package/packages/shared-skills/skills/data-scientist/references/common-scenarios.md +0 -176
  612. package/packages/shared-skills/skills/data-scientist/references/execution-templates.md +0 -197
  613. package/packages/shared-skills/skills/data-scientist/references/integration-patterns.md +0 -153
  614. package/packages/shared-skills/skills/data-scientist/references/performance-benchmarks.md +0 -37
  615. /package/dist/hooks/{start-work → ulw-execute}/context-info-formatters.d.ts +0 -0
  616. /package/dist/hooks/{start-work → ulw-execute}/explicit-plan-context.d.ts +0 -0
  617. /package/dist/hooks/{start-work → ulw-execute}/notepad-scaffold.d.ts +0 -0
  618. /package/dist/hooks/{start-work → ulw-execute}/parse-user-request.d.ts +0 -0
  619. /package/dist/hooks/{start-work → ulw-execute}/plan-discovery-context.d.ts +0 -0
  620. /package/dist/hooks/{start-work → ulw-execute}/plan-selection.d.ts +0 -0
  621. /package/dist/hooks/{start-work → ulw-execute}/session-plan-affinity.d.ts +0 -0
  622. /package/dist/hooks/{start-work → ulw-execute}/work-initializer.d.ts +0 -0
  623. /package/dist/hooks/{start-work → ulw-execute}/worktree-block.d.ts +0 -0
  624. /package/dist/hooks/{start-work → ulw-execute}/worktree-detector.d.ts +0 -0
  625. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/.gitattributes +0 -0
  626. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/CHANGELOG.md +0 -0
  627. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/LICENSE +0 -0
  628. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/plan-checklist.ts +0 -0
  629. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/src/types.ts +0 -0
  630. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-completed.json +0 -0
  631. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-mixed-platforms.json +0 -0
  632. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/boulder-single-codex-work.json +0 -0
  633. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-all-done.md +0 -0
  634. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-scaffold.md +0 -0
  635. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-nested-checkboxes.md +0 -0
  636. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/test/fixtures/plan-with-unchecked.md +0 -0
  637. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.build.json +0 -0
  638. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/tsconfig.json +0 -0
  639. /package/packages/omo-codex/plugin/components/{start-work-continuation → ulw-execute-continuation}/vitest.config.ts +0 -0
@@ -23,9 +23,12 @@ import {
23
23
  fsyncSync,
24
24
  openSync,
25
25
  renameSync,
26
+ rmSync,
26
27
  unlinkSync,
27
28
  writeFileSync
28
29
  } from "node:fs";
30
+ import { randomUUID } from "node:crypto";
31
+ import { dirname } from "node:path";
29
32
  var TOLERATED_FSYNC_CODES = new Set([
30
33
  "EPERM",
31
34
  "EACCES",
@@ -47,24 +50,36 @@ function tolerantFsyncSync(fileDescriptor, fsyncImpl) {
47
50
  }
48
51
  }
49
52
  function writeFileAtomically(filePath, content, options = {}) {
50
- const tempPath = `${filePath}.tmp`;
51
- writeFileSync(tempPath, content, "utf-8");
52
- const tempFileDescriptor = openSync(tempPath, "r+");
53
+ const platform = options.platform ?? process.platform;
54
+ const fsyncImpl = options.fsyncSync ?? fsyncSync;
55
+ const tempPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
53
56
  try {
54
- tolerantFsyncSync(tempFileDescriptor, options.fsyncSync ?? fsyncSync);
55
- } finally {
56
- closeSync(tempFileDescriptor);
57
- }
58
- try {
59
- renameSync(tempPath, filePath);
60
- } catch (error) {
61
- const isPermissionError = error instanceof Error && (error.message.includes("EPERM") || error.message.includes("EACCES"));
62
- if ((options.platform ?? process.platform) === "win32" && isPermissionError) {
57
+ writeFileSync(tempPath, content, "utf-8");
58
+ const tempFileDescriptor = openSync(tempPath, "r+");
59
+ try {
60
+ tolerantFsyncSync(tempFileDescriptor, fsyncImpl);
61
+ } finally {
62
+ closeSync(tempFileDescriptor);
63
+ }
64
+ try {
65
+ renameSync(tempPath, filePath);
66
+ } catch (error) {
67
+ const isPermissionError = error instanceof Error && (error.message.includes("EPERM") || error.message.includes("EACCES"));
68
+ if (platform !== "win32" || !isPermissionError)
69
+ throw error;
63
70
  unlinkSync(filePath);
64
71
  renameSync(tempPath, filePath);
72
+ }
73
+ if (platform === "win32")
65
74
  return;
75
+ const directoryFileDescriptor = openSync(dirname(filePath), "r");
76
+ try {
77
+ tolerantFsyncSync(directoryFileDescriptor, fsyncImpl);
78
+ } finally {
79
+ closeSync(directoryFileDescriptor);
66
80
  }
67
- throw error;
81
+ } finally {
82
+ rmSync(tempPath, { force: true });
68
83
  }
69
84
  }
70
85
 
@@ -170,6 +185,7 @@ function writePostHogActivityState(stateDir, nextState, diagnostics) {
170
185
  // ../../../../telemetry-core/src/constants.ts
171
186
  var DEFAULT_POSTHOG_HOST = "https://us.i.posthog.com";
172
187
  var DEFAULT_POSTHOG_API_KEY = "phc_CFJhj5HyvA62QPhvyaUCtaq23aUfznnijg5VaaGkNk74";
188
+ var UNCONFIGURED_POSTHOG_API_KEY = "phc_REPLACE_ME_OMO_NATIVE";
173
189
 
174
190
  // ../../../../telemetry-core/src/diagnostics.ts
175
191
  import { appendFileSync, existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2 } from "node:fs";
@@ -306,6 +322,9 @@ function shouldDisableTelemetry(input) {
306
322
  const env = input.env ?? process.env;
307
323
  const globalPrefix = input.globalEnvPrefix ?? "OMO";
308
324
  const prefixes = Array.from(new Set([globalPrefix, input.productEnvPrefix]));
325
+ if (isDisableFlag(env["DO_NOT_TRACK"])) {
326
+ return true;
327
+ }
309
328
  for (const prefix of prefixes) {
310
329
  if (isDisableFlag(env[`${prefix}_DISABLE_POSTHOG`])) {
311
330
  return true;
@@ -319,22 +338,19 @@ function shouldDisableTelemetry(input) {
319
338
  function getTelemetryApiKey(env = process.env, defaultApiKey = DEFAULT_POSTHOG_API_KEY) {
320
339
  return env["POSTHOG_API_KEY"]?.trim() ?? defaultApiKey;
321
340
  }
322
- function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
323
- return env["POSTHOG_HOST"]?.trim() || defaultHost;
341
+ function isConfiguredTelemetryApiKey(apiKey) {
342
+ const normalized = apiKey.trim();
343
+ return normalized.length > 0 && normalized !== UNCONFIGURED_POSTHOG_API_KEY;
324
344
  }
325
-
326
- // ../../../../telemetry-core/src/machine-id.ts
327
- import { createHash } from "node:crypto";
328
- import os2 from "node:os";
329
- function getDefaultTelemetryOsProvider() {
330
- return os2;
345
+ function hasTelemetryApiKey(env, defaultApiKey) {
346
+ return isConfiguredTelemetryApiKey(getTelemetryApiKey(env, defaultApiKey));
331
347
  }
332
- function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
333
- return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
348
+ function getTelemetryHost(env = process.env, defaultHost = DEFAULT_POSTHOG_HOST) {
349
+ return env["POSTHOG_HOST"]?.trim() || defaultHost;
334
350
  }
335
351
 
336
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
337
- import { dirname, posix, sep } from "path";
352
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
353
+ import { dirname as dirname2, posix, sep } from "path";
338
354
  function createModulerModifier() {
339
355
  const getModuleFromFileName = createGetModuleFromFilename();
340
356
  return async (frames) => {
@@ -343,7 +359,7 @@ function createModulerModifier() {
343
359
  return frames;
344
360
  };
345
361
  }
346
- function createGetModuleFromFilename(basePath = process.argv[1] ? dirname(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
362
+ function createGetModuleFromFilename(basePath = process.argv[1] ? dirname2(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
347
363
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
348
364
  return (filename) => {
349
365
  if (!filename)
@@ -369,7 +385,7 @@ function normalizeWindowsPath(path2) {
369
385
  return path2.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
370
386
  }
371
387
 
372
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/featureFlagUtils.mjs
388
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/featureFlagUtils.mjs
373
389
  var normalizeFlagsResponse = (flagsResponse) => {
374
390
  if ("flags" in flagsResponse) {
375
391
  const featureFlags = getFlagValuesFromFlags(flagsResponse.flags);
@@ -439,8 +455,69 @@ var parsePayload = (response) => {
439
455
  return response;
440
456
  }
441
457
  };
458
+ var MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES = [
459
+ "utm_source",
460
+ "utm_medium",
461
+ "utm_campaign",
462
+ "utm_content",
463
+ "utm_term",
464
+ "gad_source",
465
+ "mc_cid",
466
+ "gclid",
467
+ "gclsrc",
468
+ "dclid",
469
+ "gbraid",
470
+ "wbraid",
471
+ "fbclid",
472
+ "msclkid",
473
+ "twclid",
474
+ "li_fat_id",
475
+ "igshid",
476
+ "ttclid",
477
+ "rdt_cid",
478
+ "epik",
479
+ "qclid",
480
+ "sccid",
481
+ "irclid",
482
+ "_kx"
483
+ ];
484
+ var MINIMAL_FLAG_CALLED_EVENT_PROPERTIES = [
485
+ "$feature_flag",
486
+ "$feature_flag_response",
487
+ "$feature_flag_has_experiment",
488
+ "$feature_flag_id",
489
+ "$feature_flag_version",
490
+ "$feature_flag_reason",
491
+ "$feature_flag_request_id",
492
+ "$feature_flag_evaluated_at",
493
+ "$feature_flag_error",
494
+ "locally_evaluated",
495
+ "$groups",
496
+ "$process_person_profile",
497
+ "$geoip_disable",
498
+ "$current_url",
499
+ "$pathname",
500
+ "$referring_domain",
501
+ ...MINIMAL_FLAG_CALLED_EVENT_CAMPAIGN_PROPERTIES,
502
+ "$session_id",
503
+ "$window_id",
504
+ "$lib",
505
+ "$lib_version",
506
+ "$device_id",
507
+ "$is_server"
508
+ ];
509
+ var minimizeFlagCalledEventProperties = (properties, transportKeys = []) => {
510
+ const minimal = {};
511
+ const copyKey = (key) => {
512
+ if (properties[key] !== undefined)
513
+ minimal[key] = properties[key];
514
+ };
515
+ MINIMAL_FLAG_CALLED_EVENT_PROPERTIES.forEach(copyKey);
516
+ transportKeys.forEach(copyKey);
517
+ return minimal;
518
+ };
442
519
 
443
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/types.mjs
520
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/types.mjs
444
521
  var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedProperty) {
445
522
  PostHogPersistedProperty["AnonymousId"] = "anonymous_id";
446
523
  PostHogPersistedProperty["DistinctId"] = "distinct_id";
@@ -455,6 +532,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
455
532
  PostHogPersistedProperty["BootstrapFeatureFlagPayloads"] = "bootstrap_feature_flag_payloads";
456
533
  PostHogPersistedProperty["OverrideFeatureFlags"] = "override_feature_flags";
457
534
  PostHogPersistedProperty["Queue"] = "queue";
535
+ PostHogPersistedProperty["AiQueue"] = "ai_queue";
536
+ PostHogPersistedProperty["AiCaptureQueue"] = "ai_capture_queue";
458
537
  PostHogPersistedProperty["LogsQueue"] = "logs_queue";
459
538
  PostHogPersistedProperty["OptedOut"] = "opted_out";
460
539
  PostHogPersistedProperty["SessionId"] = "session_id";
@@ -465,6 +544,8 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
465
544
  PostHogPersistedProperty["InstalledAppBuild"] = "installed_app_build";
466
545
  PostHogPersistedProperty["InstalledAppVersion"] = "installed_app_version";
467
546
  PostHogPersistedProperty["SessionReplay"] = "session_replay";
547
+ PostHogPersistedProperty["PushRegistered"] = "push_registered";
548
+ PostHogPersistedProperty["SessionReplayEventTriggerActivatedSession"] = "session_replay_event_trigger_activated_session";
468
549
  PostHogPersistedProperty["SurveyLastSeenDate"] = "survey_last_seen_date";
469
550
  PostHogPersistedProperty["SurveysSeen"] = "surveys_seen";
470
551
  PostHogPersistedProperty["Surveys"] = "surveys";
@@ -474,7 +555,7 @@ var types_PostHogPersistedProperty = /* @__PURE__ */ function(PostHogPersistedPr
474
555
  return PostHogPersistedProperty;
475
556
  }({});
476
557
 
477
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/gzip.mjs
558
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/gzip.mjs
478
559
  function isGzipSupported() {
479
560
  return "CompressionStream" in globalThis && "TextEncoder" in globalThis && "Response" in globalThis && typeof Response.prototype.blob == "function";
480
561
  }
@@ -524,7 +605,7 @@ var validateNativeGzip = async (compressed, inputBytes) => {
524
605
  async function gzipCompress(input, isDebug = true, options) {
525
606
  try {
526
607
  const inputBytes = new TextEncoder().encode(input);
527
- const compressedStream = new CompressionStream("gzip");
608
+ const compressedStream = new globalThis.CompressionStream("gzip");
528
609
  const writer = compressedStream.writable.getWriter();
529
610
  const writePromise = writer.write(inputBytes).then(() => writer.close()).catch(async (err) => {
530
611
  try {
@@ -548,7 +629,34 @@ async function gzipCompress(input, isDebug = true, options) {
548
629
  }
549
630
  }
550
631
 
551
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/bot-detection.mjs
632
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/json-utils.mjs
633
+ var MAX_JSON_SAFE_VALUE_DEPTH = 20;
634
+ var MAX_JSON_SAFE_VALUE_ITEMS = 1000;
635
+ var MAX_JSON_SAFE_VALUE_NODES = 1e4;
636
+ var CIRCULAR_VALUE = "[Circular]";
637
+ var TRUNCATED_VALUE = "[Truncated]";
638
+ var UNSERIALIZABLE_VALUE = "[Unserializable]";
639
+ var FUNCTION_VALUE = "[Function]";
640
+ var dateGetTime = Date.prototype.getTime;
641
+ var dateToISOString = Date.prototype.toISOString;
642
+ function sanitizeString(value) {
643
+ let output = "";
644
+ for (let index = 0;index < value.length; index++) {
645
+ const codeUnit = value.charCodeAt(index);
646
+ if (codeUnit >= 55296 && codeUnit <= 56319) {
647
+ const nextCodeUnit = value.charCodeAt(index + 1);
648
+ if (nextCodeUnit >= 56320 && nextCodeUnit <= 57343) {
649
+ output += value[index] + value[index + 1];
650
+ index++;
651
+ } else
652
+ output += "�";
653
+ } else
654
+ output += codeUnit >= 56320 && codeUnit <= 57343 ? "�" : value[index];
655
+ }
656
+ return output;
657
+ }
658
+
659
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/bot-detection.mjs
552
660
  var DEFAULT_BLOCKED_UA_STRS = [
553
661
  "amazonbot",
554
662
  "amazonproductbot",
@@ -637,7 +745,31 @@ var isBlockedUA = function(ua, customBlockedUserAgents = []) {
637
745
  return uaLower.indexOf(blockedUaLower) !== -1;
638
746
  });
639
747
  };
640
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/type-utils.mjs
748
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/string-utils.mjs
749
+ function safeJsonStringify(value) {
750
+ const ancestors = [];
751
+ return JSON.stringify(value, function(_key, replacementValue) {
752
+ if (typeof replacementValue == "bigint")
753
+ return replacementValue.toString();
754
+ if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
755
+ return;
756
+ if (replacementValue instanceof Error)
757
+ return {
758
+ name: replacementValue.name,
759
+ message: replacementValue.message,
760
+ stack: replacementValue.stack
761
+ };
762
+ if (replacementValue && typeof replacementValue == "object") {
763
+ while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this)
764
+ ancestors.pop();
765
+ if (ancestors.includes(replacementValue))
766
+ return "[Circular]";
767
+ ancestors.push(replacementValue);
768
+ }
769
+ return replacementValue;
770
+ }) ?? "null";
771
+ }
772
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/type-utils.mjs
641
773
  var nativeIsArray = Array.isArray;
642
774
  var ObjProto = Object.prototype;
643
775
  var type_utils_hasOwnProperty = ObjProto.hasOwnProperty;
@@ -649,14 +781,28 @@ var isObject = (x) => x === Object(x) && !isArray(x);
649
781
  var isUndefined = (x) => x === undefined;
650
782
  var isString = (x) => type_utils_toString.call(x) == "[object String]";
651
783
  var isEmptyString = (x) => isString(x) && x.trim().length === 0;
784
+ var isNull = (x) => x === null;
785
+ var isNullish = (x) => isUndefined(x) || isNull(x);
652
786
  var isNumber = (x) => type_utils_toString.call(x) == "[object Number]" && x === x;
653
- var isPlainError = (x) => x instanceof Error;
787
+ var isBoolean = (x) => type_utils_toString.call(x) === "[object Boolean]";
654
788
  function isPrimitive(value) {
655
789
  return value === null || typeof value != "object";
656
790
  }
657
791
  function isBuiltin(candidate, className) {
658
792
  return Object.prototype.toString.call(candidate) === `[object ${className}]`;
659
793
  }
794
+ function isError(candidate) {
795
+ switch (Object.prototype.toString.call(candidate)) {
796
+ case "[object Error]":
797
+ case "[object Exception]":
798
+ case "[object DOMException]":
799
+ case "[object DOMError]":
800
+ case "[object WebAssembly.Exception]":
801
+ return true;
802
+ default:
803
+ return isInstanceOf(candidate, Error);
804
+ }
805
+ }
660
806
  function isErrorEvent(event) {
661
807
  return isBuiltin(event, "ErrorEvent");
662
808
  }
@@ -674,7 +820,7 @@ function isInstanceOf(candidate, base) {
674
820
  }
675
821
  }
676
822
 
677
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/number-utils.mjs
823
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/number-utils.mjs
678
824
  function clampToRange(value, min, max, logger, fallbackValue) {
679
825
  if (min > max) {
680
826
  logger.warn("min cannot be greater than max.");
@@ -694,8 +840,16 @@ function clampToRange(value, min, max, logger, fallbackValue) {
694
840
  return clampToRange(fallbackValue || max, min, max, logger);
695
841
  }
696
842
 
697
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
843
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/bucketed-rate-limiter.mjs
698
844
  var ONE_DAY_IN_MS = 86400000;
845
+ var DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE = 1;
846
+ var DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE = 10;
847
+ function resolveExceptionRateLimiterConfig(config = {}) {
848
+ return {
849
+ refillRate: config.exceptionRateLimiterRefillRate ?? config.__exceptionRateLimiterRefillRate ?? DEFAULT_EXCEPTION_RATE_LIMITER_REFILL_RATE,
850
+ bucketSize: config.exceptionRateLimiterBucketSize ?? config.__exceptionRateLimiterBucketSize ?? DEFAULT_EXCEPTION_RATE_LIMITER_BUCKET_SIZE
851
+ };
852
+ }
699
853
 
700
854
  class BucketedRateLimiter {
701
855
  constructor(options) {
@@ -738,7 +892,7 @@ class BucketedRateLimiter {
738
892
  this._buckets = {};
739
893
  }
740
894
  }
741
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
895
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/vendor/uuidv7.mjs
742
896
  /*! For license information please see uuidv7.mjs.LICENSE.txt */
743
897
  var DIGITS = "0123456789abcdef";
744
898
 
@@ -916,33 +1070,45 @@ var defaultGenerator;
916
1070
  var uuidv7 = () => uuidv7obj().toString();
917
1071
  var uuidv7obj = () => (defaultGenerator || (defaultGenerator = new V7Generator)).generate();
918
1072
 
919
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/promise-queue.mjs
1073
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/promise-queue.mjs
920
1074
  class PromiseQueue {
921
1075
  add(promise) {
922
1076
  const promiseUUID = uuidv7();
923
- this.promiseByIds[promiseUUID] = promise;
1077
+ const id = ++this.nextId;
1078
+ this.promiseByIds[promiseUUID] = {
1079
+ id,
1080
+ promise
1081
+ };
924
1082
  promise.catch(() => {}).finally(() => {
925
1083
  delete this.promiseByIds[promiseUUID];
926
1084
  });
927
1085
  return promise;
928
1086
  }
929
1087
  async join() {
930
- let promises = Object.values(this.promiseByIds);
1088
+ let promises = Object.values(this.promiseByIds).map((item) => item.promise);
931
1089
  let length = promises.length;
932
1090
  while (length > 0) {
933
1091
  await Promise.all(promises);
934
- promises = Object.values(this.promiseByIds);
1092
+ promises = Object.values(this.promiseByIds).map((item) => item.promise);
935
1093
  length = promises.length;
936
1094
  }
937
1095
  }
1096
+ getPromises(ignoredPromises = [], maxId = this.nextId) {
1097
+ const ignoredPromiseSet = new Set(ignoredPromises);
1098
+ return Object.values(this.promiseByIds).filter((item) => item.id <= maxId && !ignoredPromiseSet.has(item.promise)).map((item) => item.promise);
1099
+ }
1100
+ get maxId() {
1101
+ return this.nextId;
1102
+ }
938
1103
  get length() {
939
1104
  return Object.keys(this.promiseByIds).length;
940
1105
  }
941
1106
  constructor() {
942
1107
  this.promiseByIds = {};
1108
+ this.nextId = 0;
943
1109
  }
944
1110
  }
945
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/logger.mjs
1111
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/logger.mjs
946
1112
  function createConsole(consoleLike = console) {
947
1113
  const lockedMethods = {
948
1114
  log: consoleLike.log.bind(consoleLike),
@@ -983,7 +1149,7 @@ var passThrough = (fn) => fn();
983
1149
  function createLogger(prefix, maybeCall = passThrough) {
984
1150
  return _createLogger(prefix, maybeCall, createConsole());
985
1151
  }
986
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
1152
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/user-agent-utils.mjs
987
1153
  var MOBILE = "Mobile";
988
1154
  var IOS = "iOS";
989
1155
  var ANDROID = "Android";
@@ -1026,6 +1192,7 @@ var DUCKDUCKGO = "DuckDuckGo";
1026
1192
  var PALE_MOON = "Pale Moon";
1027
1193
  var WATERFOX = "Waterfox";
1028
1194
  var BRAVE = "Brave";
1195
+ var GOOGLE_SEARCH_APP = "Google Search App";
1029
1196
  var BROWSER_VERSION_REGEX_SUFFIX = "(\\d+(\\.\\d+)?)";
1030
1197
  var DEFAULT_BROWSER_VERSION_REGEX = new RegExp("Version/" + BROWSER_VERSION_REGEX_SUFFIX);
1031
1198
  var XBOX_REGEX = new RegExp(XBOX, "i");
@@ -1113,6 +1280,9 @@ var versionRegexes = {
1113
1280
  [WATERFOX]: [
1114
1281
  new RegExp(WATERFOX + "\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1115
1282
  ],
1283
+ [GOOGLE_SEARCH_APP]: [
1284
+ new RegExp("GSA\\/" + BROWSER_VERSION_REGEX_SUFFIX)
1285
+ ],
1116
1286
  [INTERNET_EXPLORER]: [
1117
1287
  new RegExp("(rv:|MSIE )" + BROWSER_VERSION_REGEX_SUFFIX)
1118
1288
  ],
@@ -1272,8 +1442,15 @@ var osMatchers = [
1272
1442
  ]
1273
1443
  ];
1274
1444
 
1275
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/utils/index.mjs
1445
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/utils/index.mjs
1276
1446
  var STRING_FORMAT = "utf8";
1447
+ var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1448
+ function isValidUUID(value) {
1449
+ return typeof value == "string" && UUID_REGEX.test(value);
1450
+ }
1451
+ function getEventUuid(uuid, generateUuid) {
1452
+ return isValidUUID(uuid) ? uuid : generateUuid();
1453
+ }
1277
1454
  function removeTrailingSlash(url) {
1278
1455
  return url?.replace(/\/+$/, "");
1279
1456
  }
@@ -1301,7 +1478,26 @@ function safeSetTimeout(fn, timeout) {
1301
1478
  t?.unref && t?.unref();
1302
1479
  return t;
1303
1480
  }
1304
- var isError = (x) => x instanceof Error;
1481
+ async function raceWithTimeout(promise, timeoutMs, onTimeout) {
1482
+ let timeoutHandle;
1483
+ try {
1484
+ return await Promise.race([
1485
+ promise,
1486
+ new Promise((resolve, reject) => {
1487
+ timeoutHandle = safeSetTimeout(() => {
1488
+ try {
1489
+ onTimeout?.();
1490
+ resolve();
1491
+ } catch (error) {
1492
+ reject(error);
1493
+ }
1494
+ }, timeoutMs);
1495
+ })
1496
+ ]);
1497
+ } finally {
1498
+ clearTimeout(timeoutHandle);
1499
+ }
1500
+ }
1305
1501
  function allSettled(promises) {
1306
1502
  return Promise.all(promises.map((p) => (p ?? Promise.resolve()).then((value) => ({
1307
1503
  status: "fulfilled",
@@ -1312,7 +1508,7 @@ function allSettled(promises) {
1312
1508
  }))));
1313
1509
  }
1314
1510
 
1315
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/logs/logs-utils.mjs
1511
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/logs/logs-utils.mjs
1316
1512
  var OTLP_SEVERITY_MAP = {
1317
1513
  trace: {
1318
1514
  text: "TRACE",
@@ -1340,7 +1536,570 @@ var OTLP_SEVERITY_MAP = {
1340
1536
  }
1341
1537
  };
1342
1538
  var DEFAULT_OTLP_SEVERITY = OTLP_SEVERITY_MAP.info;
1343
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/eventemitter.mjs
1539
+ var INT64_RANGE_LIMIT = 9223372036854776000;
1540
+ var propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
1541
+ function newState() {
1542
+ return {
1543
+ ancestors: new WeakSet,
1544
+ remainingNodes: MAX_JSON_SAFE_VALUE_NODES
1545
+ };
1546
+ }
1547
+ function toOtlpKeyValueList(attrs, logger2) {
1548
+ try {
1549
+ return encodeKeyValueList(attrs, logger2, newState(), 0);
1550
+ } catch {
1551
+ return [];
1552
+ }
1553
+ }
1554
+ function encodeAnyValue(value, logger2, state, depth) {
1555
+ if (state.remainingNodes <= 0)
1556
+ return {
1557
+ stringValue: TRUNCATED_VALUE
1558
+ };
1559
+ state.remainingNodes--;
1560
+ if (isBoolean(value))
1561
+ return {
1562
+ boolValue: value
1563
+ };
1564
+ if (typeof value == "number") {
1565
+ if (!Number.isFinite(value))
1566
+ return {
1567
+ stringValue: String(value)
1568
+ };
1569
+ if (Number.isInteger(value)) {
1570
+ if (Number.isSafeInteger(value))
1571
+ return {
1572
+ intValue: String(value)
1573
+ };
1574
+ if (typeof BigInt == "undefined")
1575
+ return {
1576
+ stringValue: String(value)
1577
+ };
1578
+ const decimal = BigInt(value).toString();
1579
+ if (value >= INT64_RANGE_LIMIT || value < -INT64_RANGE_LIMIT) {
1580
+ logger2?.debug(`Attribute ${decimal} is outside the int64 range; encoding it as a string`);
1581
+ return {
1582
+ stringValue: decimal
1583
+ };
1584
+ }
1585
+ return {
1586
+ intValue: decimal
1587
+ };
1588
+ }
1589
+ return {
1590
+ doubleValue: value
1591
+ };
1592
+ }
1593
+ if (typeof value == "string")
1594
+ return {
1595
+ stringValue: sanitizeString(value)
1596
+ };
1597
+ if (typeof value == "function")
1598
+ return {
1599
+ stringValue: FUNCTION_VALUE
1600
+ };
1601
+ if (typeof value == "symbol")
1602
+ return {
1603
+ stringValue: String(value)
1604
+ };
1605
+ if (typeof value == "object" && value !== null) {
1606
+ if (state.ancestors.has(value))
1607
+ return {
1608
+ stringValue: CIRCULAR_VALUE
1609
+ };
1610
+ if (depth >= MAX_JSON_SAFE_VALUE_DEPTH)
1611
+ return {
1612
+ stringValue: TRUNCATED_VALUE
1613
+ };
1614
+ if (value instanceof Date) {
1615
+ const time = value.getTime();
1616
+ const iso = Number.isFinite(time) ? value.toISOString() : String(value);
1617
+ return {
1618
+ stringValue: typeof iso == "string" ? sanitizeString(iso) : String(iso)
1619
+ };
1620
+ }
1621
+ state.ancestors.add(value);
1622
+ try {
1623
+ try {
1624
+ const toJSON = value.toJSON;
1625
+ if (typeof toJSON == "function")
1626
+ return encodeAnyValue(toJSON.call(value), logger2, state, depth + 1);
1627
+ } catch {}
1628
+ if (isArray(value))
1629
+ return {
1630
+ arrayValue: {
1631
+ values: encodeArrayValues(value, logger2, state, depth + 1)
1632
+ }
1633
+ };
1634
+ return {
1635
+ kvlistValue: {
1636
+ values: encodeKeyValueList(value, logger2, state, depth + 1)
1637
+ }
1638
+ };
1639
+ } finally {
1640
+ state.ancestors.delete(value);
1641
+ }
1642
+ }
1643
+ return {
1644
+ stringValue: sanitizeString(String(value))
1645
+ };
1646
+ }
1647
+ function encodeArrayValues(values, logger2, state, depth) {
1648
+ const result = [];
1649
+ const itemCount = Math.min(values.length, MAX_JSON_SAFE_VALUE_ITEMS);
1650
+ let index = 0;
1651
+ for (;index < itemCount && state.remainingNodes > 0; index++)
1652
+ try {
1653
+ const element = index in values ? values[index] : undefined;
1654
+ if (isNullish(element))
1655
+ continue;
1656
+ result.push(encodeAnyValue(element, logger2, state, depth));
1657
+ } catch {
1658
+ result.push({
1659
+ stringValue: UNSERIALIZABLE_VALUE
1660
+ });
1661
+ }
1662
+ if (values.length > index)
1663
+ result.push({
1664
+ stringValue: TRUNCATED_VALUE
1665
+ });
1666
+ return result;
1667
+ }
1668
+ function encodeKeyValueList(attrs, logger2, state, depth) {
1669
+ const result = [];
1670
+ for (const key in attrs)
1671
+ if (propertyIsEnumerable.call(attrs, key)) {
1672
+ if (result.length >= MAX_JSON_SAFE_VALUE_ITEMS || state.remainingNodes <= 0) {
1673
+ logger2?.debug("Attributes truncated: the value exceeds the OTLP encoder budget");
1674
+ break;
1675
+ }
1676
+ try {
1677
+ const value = attrs[key];
1678
+ if (isNull(value) || isUndefined(value))
1679
+ continue;
1680
+ result.push({
1681
+ key: sanitizeString(key),
1682
+ value: encodeAnyValue(value, logger2, state, depth)
1683
+ });
1684
+ } catch {
1685
+ result.push({
1686
+ key: sanitizeString(key),
1687
+ value: {
1688
+ stringValue: UNSERIALIZABLE_VALUE
1689
+ }
1690
+ });
1691
+ }
1692
+ }
1693
+ return result;
1694
+ }
1695
+
1696
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/metrics-utils.mjs
1697
+ var DEFAULT_HISTOGRAM_BOUNDS = [
1698
+ 0,
1699
+ 5,
1700
+ 10,
1701
+ 25,
1702
+ 50,
1703
+ 75,
1704
+ 100,
1705
+ 250,
1706
+ 500,
1707
+ 750,
1708
+ 1000,
1709
+ 2500,
1710
+ 5000,
1711
+ 7500,
1712
+ 1e4
1713
+ ];
1714
+ function msToUnixNano(ms) {
1715
+ return String(ms) + "000000";
1716
+ }
1717
+ function seriesKey(type, name, unit, attributes) {
1718
+ let attrsKey = "";
1719
+ if (attributes) {
1720
+ const keys = Object.keys(attributes).sort();
1721
+ attrsKey = keys.map((k) => `${JSON.stringify(k)}:${JSON.stringify(attributes[k])}`).join(",");
1722
+ }
1723
+ return `${type}\x00${name}\x00${unit ?? ""}\x00${attrsKey}`;
1724
+ }
1725
+ function bucketIndexFor(value, bounds) {
1726
+ for (let i = 0;i < bounds.length; i++)
1727
+ if (value <= bounds[i])
1728
+ return i;
1729
+ return bounds.length;
1730
+ }
1731
+ function buildMetricsResourceAttributes(config, scopeName, scopeVersion) {
1732
+ return {
1733
+ ...config.resourceAttributes,
1734
+ "service.name": config.serviceName || "unknown_service",
1735
+ ...config.environment && {
1736
+ "deployment.environment": config.environment
1737
+ },
1738
+ ...config.serviceVersion && {
1739
+ "service.version": config.serviceVersion
1740
+ },
1741
+ "telemetry.sdk.name": scopeName,
1742
+ "telemetry.sdk.version": scopeVersion
1743
+ };
1744
+ }
1745
+ function buildOtlpMetricsPayload(metrics, resourceAttributes, scopeName, scopeVersion) {
1746
+ return {
1747
+ resourceMetrics: [
1748
+ {
1749
+ resource: {
1750
+ attributes: toOtlpKeyValueList(resourceAttributes)
1751
+ },
1752
+ scopeMetrics: [
1753
+ {
1754
+ scope: {
1755
+ name: scopeName,
1756
+ version: scopeVersion
1757
+ },
1758
+ metrics
1759
+ }
1760
+ ]
1761
+ }
1762
+ ]
1763
+ };
1764
+ }
1765
+
1766
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/config.mjs
1767
+ var DEFAULT_FLUSH_INTERVAL_MS = 1e4;
1768
+ var DEFAULT_MAX_SERIES_PER_FLUSH = 1000;
1769
+ function resolveMetricsConfig(config) {
1770
+ const resourceAttributes = config?.resourceAttributes;
1771
+ return {
1772
+ serviceName: resourceAttributes?.["service.name"] ?? config?.serviceName,
1773
+ serviceVersion: resourceAttributes?.["service.version"] ?? config?.serviceVersion,
1774
+ environment: resourceAttributes?.["deployment.environment"] ?? config?.environment,
1775
+ resourceAttributes,
1776
+ beforeSend: config?.beforeSend,
1777
+ flushIntervalMs: config?.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS,
1778
+ maxSeriesPerFlush: config?.maxSeriesPerFlush ?? DEFAULT_MAX_SERIES_PER_FLUSH
1779
+ };
1780
+ }
1781
+
1782
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/metrics/index.mjs
1783
+ var OTLP_TEMPORALITY_DELTA = 1;
1784
+
1785
+ class PostHogMetrics {
1786
+ constructor(_instance, _config, _logger) {
1787
+ this._instance = _instance;
1788
+ this._config = _config;
1789
+ this._logger = _logger;
1790
+ this._series = new Map;
1791
+ this._flushPromise = null;
1792
+ this._seriesCapWarned = false;
1793
+ this._typeByName = new Map;
1794
+ this._typeCollisionWarned = new Set;
1795
+ this._generation = 0;
1796
+ }
1797
+ count(name, value = 1, options) {
1798
+ this._capture({
1799
+ name,
1800
+ type: "count",
1801
+ value,
1802
+ unit: options?.unit,
1803
+ attributes: options?.attributes
1804
+ });
1805
+ }
1806
+ gauge(name, value, options) {
1807
+ this._capture({
1808
+ name,
1809
+ type: "gauge",
1810
+ value,
1811
+ unit: options?.unit,
1812
+ attributes: options?.attributes
1813
+ });
1814
+ }
1815
+ histogram(name, value, options) {
1816
+ this._capture({
1817
+ name,
1818
+ type: "histogram",
1819
+ value,
1820
+ unit: options?.unit,
1821
+ attributes: options?.attributes
1822
+ });
1823
+ }
1824
+ flush() {
1825
+ const prev = this._flushPromise;
1826
+ const run = async () => {
1827
+ if (prev)
1828
+ await prev.catch(() => {});
1829
+ await this._doFlush();
1830
+ };
1831
+ const p = run().finally(() => {
1832
+ if (this._flushPromise === p)
1833
+ this._flushPromise = null;
1834
+ });
1835
+ this._flushPromise = p;
1836
+ return p;
1837
+ }
1838
+ drainWindow() {
1839
+ if (this._series.size === 0)
1840
+ return null;
1841
+ const window = this._series;
1842
+ this._series = new Map;
1843
+ this._seriesCapWarned = false;
1844
+ this._typeByName = new Map;
1845
+ this._typeCollisionWarned = new Set;
1846
+ return this._buildPayload(window);
1847
+ }
1848
+ reset() {
1849
+ this._generation++;
1850
+ this._clearFlushTimer();
1851
+ this._series = new Map;
1852
+ this._flushPromise = null;
1853
+ this._seriesCapWarned = false;
1854
+ this._typeByName = new Map;
1855
+ this._typeCollisionWarned = new Set;
1856
+ }
1857
+ _capture(sample) {
1858
+ if (this._instance.isDisabled || this._instance.optedOut)
1859
+ return;
1860
+ const filtered = this._runBeforeSend(sample);
1861
+ if (filtered === null)
1862
+ return;
1863
+ if (!filtered.name || typeof filtered.name != "string")
1864
+ return void this._logger.warn("Dropping metric with empty name");
1865
+ if (typeof filtered.value != "number" || !Number.isFinite(filtered.value))
1866
+ return void this._logger.warn(`Dropping metric '${filtered.name}': value must be a finite number`);
1867
+ if (filtered.type === "count" && filtered.value < 0)
1868
+ return void this._logger.warn(`Dropping count '${filtered.name}': counters are monotonic, value must be >= 0`);
1869
+ let attributes;
1870
+ let key;
1871
+ try {
1872
+ attributes = filtered.attributes ? {
1873
+ ...filtered.attributes
1874
+ } : undefined;
1875
+ key = seriesKey(filtered.type, filtered.name, filtered.unit, attributes);
1876
+ } catch (e) {
1877
+ this._logger.warn(`Dropping metric '${filtered.name}': attributes could not be serialized`, e);
1878
+ return;
1879
+ }
1880
+ let state = this._series.get(key);
1881
+ if (!state) {
1882
+ if (!this._admitNewSeries())
1883
+ return;
1884
+ state = {
1885
+ name: filtered.name,
1886
+ type: filtered.type,
1887
+ unit: filtered.unit,
1888
+ attributes,
1889
+ windowStartMs: Date.now()
1890
+ };
1891
+ this._series.set(key, state);
1892
+ }
1893
+ const seenType = this._typeByName.get(filtered.name);
1894
+ if (seenType === undefined)
1895
+ this._typeByName.set(filtered.name, filtered.type);
1896
+ else if (seenType !== filtered.type && !this._typeCollisionWarned.has(filtered.name)) {
1897
+ this._typeCollisionWarned.add(filtered.name);
1898
+ 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.`);
1899
+ }
1900
+ this._fold(state, filtered.value);
1901
+ this._armFlushTimer();
1902
+ }
1903
+ _admitNewSeries() {
1904
+ if (this._series.size < this._config.maxSeriesPerFlush)
1905
+ return true;
1906
+ if (!this._seriesCapWarned) {
1907
+ this._seriesCapWarned = true;
1908
+ this._logger.warn(`Metric series cap reached (${this._config.maxSeriesPerFlush} per flush window); dropping new series until the next flush. Reduce attribute cardinality.`);
1909
+ }
1910
+ return false;
1911
+ }
1912
+ _fold(state, value) {
1913
+ switch (state.type) {
1914
+ case "count":
1915
+ state.total = (state.total ?? 0) + value;
1916
+ break;
1917
+ case "gauge":
1918
+ state.last = value;
1919
+ break;
1920
+ case "histogram": {
1921
+ if (!state.hist)
1922
+ state.hist = {
1923
+ count: 0,
1924
+ sum: 0,
1925
+ min: value,
1926
+ max: value,
1927
+ bucketCounts: new Array(DEFAULT_HISTOGRAM_BOUNDS.length + 1).fill(0)
1928
+ };
1929
+ const hist = state.hist;
1930
+ hist.count += 1;
1931
+ hist.sum += value;
1932
+ hist.min = Math.min(hist.min, value);
1933
+ hist.max = Math.max(hist.max, value);
1934
+ hist.bucketCounts[bucketIndexFor(value, DEFAULT_HISTOGRAM_BOUNDS)] += 1;
1935
+ break;
1936
+ }
1937
+ }
1938
+ }
1939
+ _runBeforeSend(sample) {
1940
+ const beforeSend = this._config.beforeSend;
1941
+ if (!beforeSend)
1942
+ return sample;
1943
+ const fns = isArray(beforeSend) ? beforeSend : [
1944
+ beforeSend
1945
+ ];
1946
+ let result = sample;
1947
+ for (const fn of fns)
1948
+ try {
1949
+ const next = fn(result);
1950
+ if (!next) {
1951
+ this._logger.info("Metric was rejected in beforeSend function");
1952
+ return null;
1953
+ }
1954
+ result = next;
1955
+ } catch (e) {
1956
+ this._logger.error("Error in beforeSend function for metric:", e);
1957
+ return null;
1958
+ }
1959
+ return result;
1960
+ }
1961
+ _armFlushTimer() {
1962
+ if (this._flushTimer)
1963
+ return;
1964
+ this._flushTimer = safeSetTimeout(() => {
1965
+ this._flushTimer = undefined;
1966
+ this.flush().catch((e) => {
1967
+ this._logger.error("Metrics flush failed:", e);
1968
+ });
1969
+ }, this._config.flushIntervalMs);
1970
+ }
1971
+ _clearFlushTimer() {
1972
+ if (this._flushTimer) {
1973
+ clearTimeout(this._flushTimer);
1974
+ this._flushTimer = undefined;
1975
+ }
1976
+ }
1977
+ async _doFlush() {
1978
+ if (this._series.size === 0)
1979
+ return;
1980
+ const window = this._series;
1981
+ this._series = new Map;
1982
+ this._seriesCapWarned = false;
1983
+ this._typeByName = new Map;
1984
+ this._typeCollisionWarned = new Set;
1985
+ const generation = this._generation;
1986
+ const outcome = await this._instance._sendMetricsBatch(this._buildPayload(window));
1987
+ if (generation !== this._generation)
1988
+ return;
1989
+ switch (outcome.kind) {
1990
+ case "ok":
1991
+ return;
1992
+ case "retry-later":
1993
+ this._mergeWindowBack(window);
1994
+ this._armFlushTimer();
1995
+ return;
1996
+ case "too-large":
1997
+ this._logger.warn("Metrics batch exceeded the server size limit and was dropped");
1998
+ return;
1999
+ case "fatal":
2000
+ this._logger.error("Failed to send metrics batch:", outcome.error);
2001
+ return;
2002
+ }
2003
+ }
2004
+ _buildPayload(window) {
2005
+ return buildOtlpMetricsPayload(this._buildMetrics(window), buildMetricsResourceAttributes(this._config, this._instance.getLibraryId(), this._instance.getLibraryVersion()), this._instance.getLibraryId(), this._instance.getLibraryVersion());
2006
+ }
2007
+ _buildMetrics(window) {
2008
+ const nowNano = msToUnixNano(Date.now());
2009
+ const byMetric = new Map;
2010
+ for (const state of window.values()) {
2011
+ const metricKey = seriesKey(state.type, state.name, state.unit, undefined);
2012
+ let metric = byMetric.get(metricKey);
2013
+ if (!metric) {
2014
+ metric = {
2015
+ name: state.name,
2016
+ ...state.unit && {
2017
+ unit: state.unit
2018
+ }
2019
+ };
2020
+ if (state.type === "count")
2021
+ metric.sum = {
2022
+ aggregationTemporality: OTLP_TEMPORALITY_DELTA,
2023
+ isMonotonic: true,
2024
+ dataPoints: []
2025
+ };
2026
+ else if (state.type === "gauge")
2027
+ metric.gauge = {
2028
+ dataPoints: []
2029
+ };
2030
+ else
2031
+ metric.histogram = {
2032
+ aggregationTemporality: OTLP_TEMPORALITY_DELTA,
2033
+ dataPoints: []
2034
+ };
2035
+ byMetric.set(metricKey, metric);
2036
+ }
2037
+ const attributes = toOtlpKeyValueList(state.attributes ?? {}, this._logger);
2038
+ const startNano = msToUnixNano(state.windowStartMs);
2039
+ if (state.type === "count") {
2040
+ const dp = {
2041
+ attributes,
2042
+ startTimeUnixNano: startNano,
2043
+ timeUnixNano: nowNano,
2044
+ asDouble: state.total ?? 0
2045
+ };
2046
+ metric.sum.dataPoints.push(dp);
2047
+ } else if (state.type === "gauge") {
2048
+ const dp = {
2049
+ attributes,
2050
+ timeUnixNano: nowNano,
2051
+ asDouble: state.last ?? 0
2052
+ };
2053
+ metric.gauge.dataPoints.push(dp);
2054
+ } else if (state.hist) {
2055
+ const dp = {
2056
+ attributes,
2057
+ startTimeUnixNano: startNano,
2058
+ timeUnixNano: nowNano,
2059
+ count: state.hist.count,
2060
+ sum: state.hist.sum,
2061
+ min: state.hist.min,
2062
+ max: state.hist.max,
2063
+ bucketCounts: state.hist.bucketCounts,
2064
+ explicitBounds: DEFAULT_HISTOGRAM_BOUNDS
2065
+ };
2066
+ metric.histogram.dataPoints.push(dp);
2067
+ }
2068
+ }
2069
+ return Array.from(byMetric.values());
2070
+ }
2071
+ _mergeWindowBack(window) {
2072
+ for (const [key, old] of window) {
2073
+ const current = this._series.get(key);
2074
+ if (!current) {
2075
+ if (this._admitNewSeries())
2076
+ this._series.set(key, old);
2077
+ continue;
2078
+ }
2079
+ current.windowStartMs = Math.min(current.windowStartMs, old.windowStartMs);
2080
+ switch (current.type) {
2081
+ case "count":
2082
+ current.total = (current.total ?? 0) + (old.total ?? 0);
2083
+ break;
2084
+ case "gauge":
2085
+ break;
2086
+ case "histogram":
2087
+ if (old.hist)
2088
+ if (current.hist) {
2089
+ current.hist.count += old.hist.count;
2090
+ current.hist.sum += old.hist.sum;
2091
+ current.hist.min = Math.min(current.hist.min, old.hist.min);
2092
+ current.hist.max = Math.max(current.hist.max, old.hist.max);
2093
+ for (let i = 0;i < current.hist.bucketCounts.length; i++)
2094
+ current.hist.bucketCounts[i] += old.hist.bucketCounts[i];
2095
+ } else
2096
+ current.hist = old.hist;
2097
+ break;
2098
+ }
2099
+ }
2100
+ }
2101
+ }
2102
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/eventemitter.mjs
1344
2103
  class SimpleEventEmitter {
1345
2104
  constructor() {
1346
2105
  this.events = {};
@@ -1362,37 +2121,38 @@ class SimpleEventEmitter {
1362
2121
  }
1363
2122
  }
1364
2123
 
1365
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/index.mjs
2124
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/index.mjs
1366
2125
  var exports_error_tracking = {};
1367
2126
  __export(exports_error_tracking, {
1368
- winjsStackLineParser: () => winjsStackLineParser,
1369
- stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
1370
- reverseAndStripFrames: () => reverseAndStripFrames,
1371
- resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
1372
- opera11StackLineParser: () => opera11StackLineParser,
1373
- opera10StackLineParser: () => opera10StackLineParser,
1374
- nodeStackLineParser: () => nodeStackLineParser,
1375
- getUtf8ByteLength: () => getUtf8ByteLength,
1376
- geckoStackLineParser: () => geckoStackLineParser,
1377
- createStackParser: () => createStackParser,
1378
- createDefaultStackParser: () => createDefaultStackParser,
1379
- chromeStackLineParser: () => chromeStackLineParser,
1380
- StringCoercer: () => StringCoercer,
1381
- ReduceableCache: () => ReduceableCache,
1382
- PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
1383
- PrimitiveCoercer: () => PrimitiveCoercer,
1384
- ObjectCoercer: () => ObjectCoercer,
1385
- ExceptionStepsBuffer: () => ExceptionStepsBuffer,
1386
- EventCoercer: () => EventCoercer,
1387
- ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
1388
- ErrorEventCoercer: () => ErrorEventCoercer,
1389
- ErrorCoercer: () => ErrorCoercer,
1390
- EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2127
+ DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG,
1391
2128
  DOMExceptionCoercer: () => DOMExceptionCoercer,
1392
- DEFAULT_EXCEPTION_STEPS_CONFIG: () => DEFAULT_EXCEPTION_STEPS_CONFIG
2129
+ EXCEPTION_STEP_INTERNAL_FIELDS: () => EXCEPTION_STEP_INTERNAL_FIELDS,
2130
+ ErrorCoercer: () => ErrorCoercer,
2131
+ ErrorEventCoercer: () => ErrorEventCoercer,
2132
+ ErrorPropertiesBuilder: () => ErrorPropertiesBuilder,
2133
+ EventCoercer: () => EventCoercer,
2134
+ ExceptionStepsBuffer: () => ExceptionStepsBuffer,
2135
+ ObjectCoercer: () => ObjectCoercer,
2136
+ PrimitiveCoercer: () => PrimitiveCoercer,
2137
+ PromiseRejectionEventCoercer: () => PromiseRejectionEventCoercer,
2138
+ ReduceableCache: () => ReduceableCache,
2139
+ StringCoercer: () => StringCoercer,
2140
+ chromeStackLineParser: () => chromeStackLineParser,
2141
+ createDefaultStackParser: () => createDefaultStackParser,
2142
+ createStackParser: () => createStackParser,
2143
+ geckoStackLineParser: () => geckoStackLineParser,
2144
+ getInjectedReleaseId: () => getInjectedReleaseId,
2145
+ getUtf8ByteLength: () => getUtf8ByteLength,
2146
+ nodeStackLineParser: () => nodeStackLineParser,
2147
+ opera10StackLineParser: () => opera10StackLineParser,
2148
+ opera11StackLineParser: () => opera11StackLineParser,
2149
+ resolveExceptionStepsConfig: () => resolveExceptionStepsConfig,
2150
+ reverseAndStripFrames: () => reverseAndStripFrames,
2151
+ stripReservedExceptionStepFields: () => stripReservedExceptionStepFields,
2152
+ winjsStackLineParser: () => winjsStackLineParser
1393
2153
  });
1394
2154
 
1395
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
2155
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/chunk-ids.mjs
1396
2156
  var parsedStackResults;
1397
2157
  var lastKeysCount;
1398
2158
  var cachedFilenameChunkIds;
@@ -1431,7 +2191,7 @@ function getFilenameToChunkIdMap(stackParser) {
1431
2191
  return cachedFilenameChunkIds;
1432
2192
  }
1433
2193
 
1434
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
2194
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/error-properties-builder.mjs
1435
2195
  var MAX_CAUSE_RECURSION = 4;
1436
2196
 
1437
2197
  class ErrorPropertiesBuilder {
@@ -1553,14 +2313,16 @@ class ErrorPropertiesBuilder {
1553
2313
  return context;
1554
2314
  }
1555
2315
  }
1556
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
2316
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/base.mjs
1557
2317
  var UNKNOWN_FUNCTION = "?";
2318
+ var MASKED_URL_PREFIX = "webkit-masked-url://";
2319
+ var ANONYMOUS_FILENAME = "<anonymous>";
1558
2320
  function createFrame(platform, filename, func, lineno, colno) {
1559
2321
  const frame = {
1560
2322
  platform,
1561
2323
  filename,
1562
2324
  function: func === "<anonymous>" ? UNKNOWN_FUNCTION : func,
1563
- in_app: true
2325
+ in_app: !filename?.startsWith(MASKED_URL_PREFIX) && filename !== ANONYMOUS_FILENAME
1564
2326
  };
1565
2327
  if (!isUndefined(lineno))
1566
2328
  frame.lineno = lineno;
@@ -1569,7 +2331,7 @@ function createFrame(platform, filename, func, lineno, colno) {
1569
2331
  return frame;
1570
2332
  }
1571
2333
 
1572
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
2334
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/safari.mjs
1573
2335
  var extractSafariExtensionDetails = (func, filename) => {
1574
2336
  const isSafariExtension = func.indexOf("safari-extension") !== -1;
1575
2337
  const isSafariWebExtension = func.indexOf("safari-web-extension") !== -1;
@@ -1582,7 +2344,7 @@ var extractSafariExtensionDetails = (func, filename) => {
1582
2344
  ];
1583
2345
  };
1584
2346
 
1585
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
2347
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/chrome.mjs
1586
2348
  var chromeRegexNoFnName = /^\s*at (\S+?)(?::(\d+))(?::(\d+))\s*$/i;
1587
2349
  var chromeRegex = /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
1588
2350
  var chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
@@ -1608,7 +2370,7 @@ var chromeStackLineParser = (line, platform) => {
1608
2370
  }
1609
2371
  };
1610
2372
 
1611
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
2373
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/gecko.mjs
1612
2374
  var geckoREgex = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
1613
2375
  var geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
1614
2376
  var geckoStackLineParser = (line, platform) => {
@@ -1631,14 +2393,14 @@ var geckoStackLineParser = (line, platform) => {
1631
2393
  }
1632
2394
  };
1633
2395
 
1634
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
2396
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/winjs.mjs
1635
2397
  var winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
1636
2398
  var winjsStackLineParser = (line, platform) => {
1637
2399
  const parts = winjsRegex.exec(line);
1638
2400
  return parts ? createFrame(platform, parts[2], parts[1] || UNKNOWN_FUNCTION, +parts[3], parts[4] ? +parts[4] : undefined) : undefined;
1639
2401
  };
1640
2402
 
1641
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
2403
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/opera.mjs
1642
2404
  var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i;
1643
2405
  var opera10StackLineParser = (line, platform) => {
1644
2406
  const parts = opera10Regex.exec(line);
@@ -1650,9 +2412,12 @@ var opera11StackLineParser = (line, platform) => {
1650
2412
  return parts ? createFrame(platform, parts[5], parts[3] || parts[4] || UNKNOWN_FUNCTION, +parts[1], +parts[2]) : undefined;
1651
2413
  };
1652
2414
 
1653
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
2415
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/node.mjs
1654
2416
  var FILENAME_MATCH = /^\s*[-]{4,}$/;
1655
2417
  var FULL_MATCH = /at (?:async )?(?:(.+?)\s+\()?(?:(.+):(\d+):(\d+)?|([^)]+))\)?/;
2418
+ var PROMISE_COMBINATOR = /^Promise\.(?:all|any)$/;
2419
+ var PROMISE_INDEX = /^index \d+$/;
2420
+ var PROMISE_FRAME_FILENAME = "node:internal/promise";
1656
2421
  var nodeStackLineParser = (line, platform) => {
1657
2422
  const lineMatch = line.match(FULL_MATCH);
1658
2423
  if (lineMatch) {
@@ -1695,6 +2460,8 @@ var nodeStackLineParser = (line, platform) => {
1695
2460
  filename = filename.slice(1);
1696
2461
  if (!filename && lineMatch[5] && !isNative)
1697
2462
  filename = lineMatch[5];
2463
+ if (PROMISE_COMBINATOR.test(functionName) && PROMISE_INDEX.test(filename || ""))
2464
+ filename = PROMISE_FRAME_FILENAME;
1698
2465
  return {
1699
2466
  filename: filename ? decodeURI(filename) : undefined,
1700
2467
  module: undefined,
@@ -1719,7 +2486,7 @@ function _parseIntOrUndefined(input) {
1719
2486
  return parseInt(input || "", 10) || undefined;
1720
2487
  }
1721
2488
 
1722
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
2489
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/parsers/index.mjs
1723
2490
  var WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
1724
2491
  var STACKTRACE_FRAME_LIMIT = 50;
1725
2492
  function reverseAndStripFrames(stack) {
@@ -1764,7 +2531,7 @@ function createStackParser(platform, ...parsers) {
1764
2531
  return reverseAndStripFrames(frames);
1765
2532
  };
1766
2533
  }
1767
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
2534
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/dom-exception-coercer.mjs
1768
2535
  class DOMExceptionCoercer {
1769
2536
  match(err) {
1770
2537
  return this.isDOMException(err) || this.isDOMError(err);
@@ -1794,18 +2561,20 @@ class DOMExceptionCoercer {
1794
2561
  return isBuiltin(err, "DOMError");
1795
2562
  }
1796
2563
  }
1797
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
2564
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/error-coercer.mjs
1798
2565
  class ErrorCoercer {
1799
2566
  match(err) {
1800
- return isPlainError(err);
2567
+ return isError(err);
1801
2568
  }
1802
2569
  coerce(err, ctx) {
2570
+ const stack = this.getStack(err);
2571
+ const synthetic = stack === undefined;
1803
2572
  return {
1804
2573
  type: this.getType(err),
1805
2574
  value: this.getMessage(err, ctx),
1806
- stack: this.getStack(err),
2575
+ stack: stack ?? ctx.syntheticException?.stack,
1807
2576
  cause: err.cause ? ctx.next(err.cause) : undefined,
1808
- synthetic: false
2577
+ synthetic
1809
2578
  };
1810
2579
  }
1811
2580
  getType(err) {
@@ -1821,25 +2590,41 @@ class ErrorCoercer {
1821
2590
  return err.stacktrace || err.stack || undefined;
1822
2591
  }
1823
2592
  }
1824
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
2593
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/error-event-coercer.mjs
1825
2594
  class ErrorEventCoercer {
1826
2595
  constructor() {}
1827
2596
  match(err) {
1828
- return isErrorEvent(err) && err.error != null;
2597
+ if (!isErrorEvent(err))
2598
+ return false;
2599
+ const errorEvent = err;
2600
+ return errorEvent.error != null || this._hasUsableMessage(errorEvent);
1829
2601
  }
1830
2602
  coerce(err, ctx) {
1831
- const exceptionLike = ctx.apply(err.error);
1832
- if (!exceptionLike)
1833
- return {
1834
- type: "ErrorEvent",
1835
- value: err.message,
1836
- stack: ctx.syntheticException?.stack,
1837
- synthetic: true
1838
- };
1839
- return exceptionLike;
2603
+ if (err.error != null)
2604
+ return ctx.apply(err.error);
2605
+ const exceptionLike = ctx.apply(err.message);
2606
+ return {
2607
+ ...exceptionLike,
2608
+ stack: this._buildLocationStack(err) ?? exceptionLike.stack,
2609
+ synthetic: true
2610
+ };
2611
+ }
2612
+ _hasUsableMessage(err) {
2613
+ return isString(err.message) && err.message.length > 0;
2614
+ }
2615
+ _buildLocationStack(err) {
2616
+ const location = err;
2617
+ const lineno = location.lineno ?? 0;
2618
+ const colno = location.colno ?? 0;
2619
+ if (!isString(location.filename) || location.filename.length === 0)
2620
+ return;
2621
+ if (lineno === 0)
2622
+ return;
2623
+ return `Error
2624
+ at ${location.filename}:${lineno}:${colno}`;
1840
2625
  }
1841
2626
  }
1842
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
2627
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/string-coercer.mjs
1843
2628
  var ERROR_TYPES_PATTERN = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/i;
1844
2629
 
1845
2630
  class StringCoercer {
@@ -1869,7 +2654,7 @@ class StringCoercer {
1869
2654
  ];
1870
2655
  }
1871
2656
  }
1872
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/types.mjs
2657
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/types.mjs
1873
2658
  var severityLevels = [
1874
2659
  "fatal",
1875
2660
  "error",
@@ -1879,7 +2664,7 @@ var severityLevels = [
1879
2664
  "debug"
1880
2665
  ];
1881
2666
 
1882
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
2667
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/utils.mjs
1883
2668
  function extractExceptionKeysForMessage(err, maxLength = 40) {
1884
2669
  const keys = Object.keys(err);
1885
2670
  keys.sort();
@@ -1896,7 +2681,7 @@ function extractExceptionKeysForMessage(err, maxLength = 40) {
1896
2681
  return "";
1897
2682
  }
1898
2683
 
1899
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
2684
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/object-coercer.mjs
1900
2685
  class ObjectCoercer {
1901
2686
  match(candidate) {
1902
2687
  return typeof candidate == "object" && candidate !== null;
@@ -1908,13 +2693,16 @@ class ObjectCoercer {
1908
2693
  return {
1909
2694
  type: this.getType(candidate),
1910
2695
  value: this.getValue(candidate),
1911
- stack: ctx.syntheticException?.stack,
2696
+ stack: this.getStack(candidate) ?? ctx.syntheticException?.stack,
1912
2697
  level: this.isSeverityLevel(candidate.level) ? candidate.level : "error",
1913
2698
  synthetic: true
1914
2699
  };
1915
2700
  }
1916
2701
  getType(err) {
1917
- return isEvent(err) ? err.constructor.name : "Error";
2702
+ if (isEvent(err))
2703
+ return err.constructor.name;
2704
+ const name = "name" in err ? err.name : undefined;
2705
+ return isString(name) && !isEmptyString(name) ? name : "Error";
1918
2706
  }
1919
2707
  getValue(err) {
1920
2708
  if ("name" in err && typeof err.name == "string") {
@@ -1932,6 +2720,15 @@ class ObjectCoercer {
1932
2720
  isSeverityLevel(x) {
1933
2721
  return isString(x) && !isEmptyString(x) && severityLevels.indexOf(x) >= 0;
1934
2722
  }
2723
+ getStack(candidate) {
2724
+ try {
2725
+ if (isString(candidate.stacktrace) && candidate.stacktrace.length > 0)
2726
+ return candidate.stacktrace;
2727
+ return isString(candidate.stack) && candidate.stack.length > 0 ? candidate.stack : undefined;
2728
+ } catch {
2729
+ return;
2730
+ }
2731
+ }
1935
2732
  getErrorPropertyFromObject(obj) {
1936
2733
  for (const prop in obj)
1937
2734
  if (Object.prototype.hasOwnProperty.call(obj, prop)) {
@@ -1949,7 +2746,7 @@ class ObjectCoercer {
1949
2746
  }
1950
2747
  }
1951
2748
  }
1952
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
2749
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/event-coercer.mjs
1953
2750
  class EventCoercer {
1954
2751
  match(err) {
1955
2752
  return isEvent(err);
@@ -1964,7 +2761,7 @@ class EventCoercer {
1964
2761
  };
1965
2762
  }
1966
2763
  }
1967
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
2764
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/primitive-coercer.mjs
1968
2765
  class PrimitiveCoercer {
1969
2766
  match(candidate) {
1970
2767
  return isPrimitive(candidate);
@@ -1978,7 +2775,7 @@ class PrimitiveCoercer {
1978
2775
  };
1979
2776
  }
1980
2777
  }
1981
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
2778
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/coercers/promise-rejection-event.mjs
1982
2779
  class PromiseRejectionEventCoercer {
1983
2780
  match(err) {
1984
2781
  return isBuiltin(err, "PromiseRejectionEvent") || this.isCustomEventWrappingRejection(err);
@@ -2014,7 +2811,7 @@ class PromiseRejectionEventCoercer {
2014
2811
  return error;
2015
2812
  }
2016
2813
  }
2017
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/utils.mjs
2814
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/utils.mjs
2018
2815
  class ReduceableCache {
2019
2816
  constructor(_maxSize) {
2020
2817
  this._maxSize = _maxSize;
@@ -2039,7 +2836,7 @@ class ReduceableCache {
2039
2836
  }
2040
2837
  }
2041
2838
  }
2042
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2839
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/exception-steps.mjs
2043
2840
  var EXCEPTION_STEP_INTERNAL_FIELDS = {
2044
2841
  MESSAGE: "$message",
2045
2842
  TIMESTAMP: "$timestamp"
@@ -2134,9 +2931,12 @@ function normalizePositiveInteger(input, fallback) {
2134
2931
  return normalized;
2135
2932
  }
2136
2933
  function normalizeAndSerializeStep(step) {
2137
- const json = safeStringify(step);
2138
- if (!json)
2934
+ let json;
2935
+ try {
2936
+ json = safeJsonStringify(step);
2937
+ } catch {
2139
2938
  return;
2939
+ }
2140
2940
  try {
2141
2941
  const parsed = JSON.parse(json);
2142
2942
  if (!isObject(parsed))
@@ -2156,33 +2956,6 @@ function normalizeAndSerializeStep(step) {
2156
2956
  return;
2157
2957
  }
2158
2958
  }
2159
- function safeStringify(value) {
2160
- const seen = new WeakSet;
2161
- try {
2162
- return JSON.stringify(value, (_key, replacementValue) => {
2163
- if (typeof replacementValue == "bigint")
2164
- return replacementValue.toString();
2165
- if (typeof replacementValue == "function" || typeof replacementValue == "symbol")
2166
- return;
2167
- if (replacementValue instanceof Date)
2168
- return replacementValue.toISOString();
2169
- if (replacementValue instanceof Error)
2170
- return {
2171
- name: replacementValue.name,
2172
- message: replacementValue.message,
2173
- stack: replacementValue.stack
2174
- };
2175
- if (replacementValue && typeof replacementValue == "object") {
2176
- if (seen.has(replacementValue))
2177
- return "[Circular]";
2178
- seen.add(replacementValue);
2179
- }
2180
- return replacementValue;
2181
- });
2182
- } catch {
2183
- return;
2184
- }
2185
- }
2186
2959
  function getUtf8ByteLength(value) {
2187
2960
  if (typeof TextEncoder != "undefined")
2188
2961
  return new TextEncoder().encode(value).length;
@@ -2196,19 +2969,65 @@ function getUtf8ByteLength(value) {
2196
2969
  byteLength += 1;
2197
2970
  return byteLength;
2198
2971
  }
2199
- // ../../../../../node_modules/.bun/@posthog+core@1.30.3/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
2972
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/error-tracking/release.mjs
2973
+ function getInjectedReleaseId() {
2974
+ const injected = globalThis._posthogReleaseId;
2975
+ return typeof injected == "string" && injected.length > 0 ? injected : undefined;
2976
+ }
2977
+ // ../../../../../node_modules/.bun/@posthog+core@1.48.9/node_modules/@posthog/core/dist/posthog-core-stateless.mjs
2200
2978
  class PostHogFetchHttpError extends Error {
2201
- constructor(response, reqByteLength) {
2202
- super("HTTP error while fetching PostHog: status=" + response.status + ", reqByteLength=" + reqByteLength), this.response = response, this.reqByteLength = reqByteLength, this.name = "PostHogFetchHttpError";
2979
+ constructor(response, reqByteLength, responseBodyDeadline, abortController) {
2980
+ 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;
2203
2981
  }
2204
2982
  get status() {
2205
2983
  return this.response.status;
2206
2984
  }
2985
+ get bodyReadTimedOut() {
2986
+ return this._bodyReadTimedOut;
2987
+ }
2207
2988
  get text() {
2208
- return this.response.text();
2989
+ if (!this.responseBodyTextPromise)
2990
+ if (Date.now() >= this.responseBodyDeadline) {
2991
+ this._bodyReadTimedOut = true;
2992
+ const timeoutError = new Error("Response body read timed out");
2993
+ timeoutError.name = "AbortError";
2994
+ this.cancelResponseBody(timeoutError);
2995
+ this.responseBodyTextPromise = Promise.reject(timeoutError);
2996
+ } else {
2997
+ const responseBodyTimeout = new Promise((_resolve, reject) => {
2998
+ this.responseBodyTimer = safeSetTimeout(() => {
2999
+ this._bodyReadTimedOut = true;
3000
+ const timeoutError = new Error("Response body read timed out");
3001
+ timeoutError.name = "AbortError";
3002
+ reject(timeoutError);
3003
+ this.cancelResponseBody(timeoutError);
3004
+ }, this.responseBodyDeadline - Date.now());
3005
+ });
3006
+ let responseBodyText;
3007
+ try {
3008
+ responseBodyText = Promise.resolve(this.response.text());
3009
+ } catch (error) {
3010
+ responseBodyText = Promise.reject(error);
3011
+ }
3012
+ this.responseBodyTextPromise = Promise.race([
3013
+ responseBodyText,
3014
+ responseBodyTimeout
3015
+ ]).finally(() => clearTimeout(this.responseBodyTimer));
3016
+ }
3017
+ return this.responseBodyTextPromise;
2209
3018
  }
2210
3019
  get json() {
2211
- return this.response.json();
3020
+ return this.text.then((text) => JSON.parse(text));
3021
+ }
3022
+ cancelResponseBody(reason) {
3023
+ clearTimeout(this.responseBodyTimer);
3024
+ if (!this.abortController.signal.aborted)
3025
+ this.abortController.abort(reason);
3026
+ (async () => {
3027
+ try {
3028
+ await this.response.body?.cancel();
3029
+ } catch {}
3030
+ })();
2212
3031
  }
2213
3032
  }
2214
3033
 
@@ -2219,12 +3038,20 @@ class PostHogFetchNetworkError extends Error {
2219
3038
  } : {}), this.error = error, this.name = "PostHogFetchNetworkError";
2220
3039
  }
2221
3040
  }
3041
+ var applyCallerFeatureFlagOverrides = (target, callerProperties) => {
3042
+ for (const key of Object.keys(callerProperties))
3043
+ if (key.startsWith("$feature/") || key === "$active_feature_flags")
3044
+ target[key] = callerProperties[key];
3045
+ };
2222
3046
  async function logFlushError(err) {
2223
3047
  if (err instanceof PostHogFetchHttpError) {
2224
3048
  let text = "";
2225
3049
  try {
2226
3050
  text = await err.text;
2227
- } catch {}
3051
+ } catch {
3052
+ if (err.bodyReadTimedOut)
3053
+ text = "<response body read timed out>";
3054
+ }
2228
3055
  console.error(`Error while flushing PostHog: message=${err.message}, response body=${text}`, err);
2229
3056
  } else
2230
3057
  console.error("Error while flushing PostHog", err);
@@ -2236,9 +3063,28 @@ function isPostHogFetchError(err) {
2236
3063
  function isPostHogFetchNetworkError(err) {
2237
3064
  return err instanceof PostHogFetchNetworkError;
2238
3065
  }
3066
+ function isRetryableFlagsFetchError(err) {
3067
+ if (err instanceof PostHogFetchHttpError)
3068
+ return err.status === 502 || err.status === 504;
3069
+ if (!(err instanceof PostHogFetchNetworkError))
3070
+ return false;
3071
+ const cause = err.error;
3072
+ const code = cause?.code ?? cause?.cause?.code;
3073
+ return code !== "ECONNREFUSED";
3074
+ }
2239
3075
  function isPostHogFetchContentTooLargeError(err) {
2240
3076
  return typeof err == "object" && err instanceof PostHogFetchHttpError && err.status === 413;
2241
3077
  }
3078
+ function isPostHogFetchRetryableError(err) {
3079
+ if (err instanceof PostHogFetchHttpError)
3080
+ return err.status === 408 || err.status === 429 || err.status >= 500;
3081
+ return isPostHogFetchNetworkError(err);
3082
+ }
3083
+ function isPostHogEventProperties(value) {
3084
+ return value !== null && typeof value == "object" && !Array.isArray(value);
3085
+ }
3086
+ var DEFAULT_QUEUE_ROUTE = "default";
3087
+
2242
3088
  class PostHogCoreStateless {
2243
3089
  getErrorPropertiesBuilder() {
2244
3090
  if (!this._errorPropertiesBuilder)
@@ -2255,6 +3101,9 @@ class PostHogCoreStateless {
2255
3101
  }
2256
3102
  constructor(apiKey, options = {}) {
2257
3103
  this.flushPromise = null;
3104
+ this.pendingFlushPromise = null;
3105
+ this.flushPromises = new Set;
3106
+ this._dequeuedMessagesCount = 0;
2258
3107
  this.shutdownPromise = null;
2259
3108
  this.promiseQueue = new PromiseQueue;
2260
3109
  this._events = new SimpleEventEmitter;
@@ -2277,10 +3126,11 @@ class PostHogCoreStateless {
2277
3126
  this._retryOptions = {
2278
3127
  retryCount: options.fetchRetryCount ?? 3,
2279
3128
  retryDelay: options.fetchRetryDelay ?? 3000,
2280
- retryCheck: isPostHogFetchError
3129
+ retryCheck: isPostHogFetchRetryableError
2281
3130
  };
2282
3131
  this.requestTimeout = options.requestTimeout ?? 1e4;
2283
3132
  this.featureFlagsRequestTimeoutMs = options.featureFlagsRequestTimeoutMs ?? 3000;
3133
+ this.featureFlagsRequestMaxRetries = options.featureFlagsRequestMaxRetries ?? 1;
2284
3134
  this.remoteConfigRequestTimeoutMs = options.remoteConfigRequestTimeoutMs ?? 3000;
2285
3135
  this.disableGeoip = options.disableGeoip ?? true;
2286
3136
  this.disabled = (options.disabled ?? false) || missingApiKey;
@@ -2342,15 +3192,23 @@ class PostHogCoreStateless {
2342
3192
  return this.disabled;
2343
3193
  }
2344
3194
  buildPayload(payload) {
3195
+ const userProperties = payload.properties || {};
3196
+ let properties = {
3197
+ ...userProperties,
3198
+ ...this.getCommonEventProperties()
3199
+ };
3200
+ applyCallerFeatureFlagOverrides(properties, userProperties);
3201
+ if (payload.event === "$feature_flag_called" && properties.$feature_flag_has_experiment === false && this.isMinimalFlagCalledEventsEnabled())
3202
+ properties = minimizeFlagCalledEventProperties(properties);
2345
3203
  return {
2346
3204
  distinct_id: payload.distinct_id,
2347
3205
  event: payload.event,
2348
- properties: {
2349
- ...payload.properties || {},
2350
- ...this.getCommonEventProperties()
2351
- }
3206
+ properties
2352
3207
  };
2353
3208
  }
3209
+ isMinimalFlagCalledEventsEnabled() {
3210
+ return false;
3211
+ }
2354
3212
  addPendingPromise(promise) {
2355
3213
  return this.promiseQueue.add(promise);
2356
3214
  }
@@ -2435,6 +3293,19 @@ class PostHogCoreStateless {
2435
3293
  this.enqueue("capture", payload, options);
2436
3294
  });
2437
3295
  }
3296
+ async groupIdentifyStatelessImmediate(groupType, groupKey, groupProperties, options, distinctId, eventProperties) {
3297
+ const payload = this.buildPayload({
3298
+ distinct_id: distinctId || `$${groupType}_${groupKey}`,
3299
+ event: "$groupidentify",
3300
+ properties: {
3301
+ $group_type: groupType,
3302
+ $group_key: groupKey,
3303
+ $group_set: groupProperties || {},
3304
+ ...eventProperties || {}
3305
+ }
3306
+ });
3307
+ await this.sendImmediate("capture", payload, options);
3308
+ }
2438
3309
  async getRemoteConfig() {
2439
3310
  await this._initPromise;
2440
3311
  let host = this.host;
@@ -2451,8 +3322,11 @@ class PostHogCoreStateless {
2451
3322
  }
2452
3323
  };
2453
3324
  return this.fetchWithRetry(url, fetchOptions, {
3325
+ type: "required",
3326
+ consume: (response) => response.json()
3327
+ }, {
2454
3328
  retryCount: 0
2455
- }, this.remoteConfigRequestTimeoutMs).then((response) => response.json()).catch((error) => {
3329
+ }, this.remoteConfigRequestTimeoutMs).catch((error) => {
2456
3330
  this._logger.error("Remote config could not be loaded", error);
2457
3331
  this._events.emit("error", error);
2458
3332
  });
@@ -2483,8 +3357,12 @@ class PostHogCoreStateless {
2483
3357
  };
2484
3358
  this._logger.info("Flags URL", url);
2485
3359
  return this.fetchWithRetry(url, fetchOptions, {
2486
- retryCount: 0
2487
- }, this.featureFlagsRequestTimeoutMs).then((response) => response.json()).then((response) => ({
3360
+ type: "required",
3361
+ consume: (response) => response.json()
3362
+ }, {
3363
+ retryCount: this.featureFlagsRequestMaxRetries,
3364
+ retryCheck: isRetryableFlagsFetchError
3365
+ }, this.featureFlagsRequestTimeoutMs).then((response) => ({
2488
3366
  success: true,
2489
3367
  response: normalizeFlagsResponse(response)
2490
3368
  })).catch((error) => {
@@ -2584,9 +3462,9 @@ class PostHogCoreStateless {
2584
3462
  }
2585
3463
  async getFeatureFlagDetailsStateless(distinctId, groups = {}, personProperties = {}, groupProperties = {}, disableGeoip, flagKeysToEvaluate) {
2586
3464
  await this._initPromise;
2587
- const extraPayload = {};
2588
- if (disableGeoip ?? this.disableGeoip)
2589
- extraPayload["geoip_disable"] = true;
3465
+ const extraPayload = {
3466
+ geoip_disable: disableGeoip ?? this.disableGeoip
3467
+ };
2590
3468
  if (flagKeysToEvaluate)
2591
3469
  extraPayload["flag_keys_to_evaluate"] = flagKeysToEvaluate;
2592
3470
  const result = await this.getFlags(distinctId, groups, personProperties, groupProperties, extraPayload);
@@ -2623,15 +3501,18 @@ class PostHogCoreStateless {
2623
3501
  "Content-Type": "application/json"
2624
3502
  }
2625
3503
  };
2626
- const response = await this.fetchWithRetry(url, fetchOptions).then((response2) => {
2627
- if (response2.status !== 200 || !response2.json) {
2628
- const msg = `Surveys API could not be loaded: ${response2.status}`;
2629
- const error = new Error(msg);
2630
- this._logger.error(error);
2631
- this._events.emit("error", new Error(msg));
2632
- return;
3504
+ const response = await this.fetchWithRetry(url, fetchOptions, {
3505
+ type: "required",
3506
+ consume: (response2) => {
3507
+ if (response2.status !== 200 || !response2.json) {
3508
+ const msg = `Surveys API could not be loaded: ${response2.status}`;
3509
+ const error = new Error(msg);
3510
+ this._logger.error(error);
3511
+ this._events.emit("error", new Error(msg));
3512
+ return Promise.resolve(undefined);
3513
+ }
3514
+ return response2.json();
2633
3515
  }
2634
- return response2.json();
2635
3516
  }).catch((error) => {
2636
3517
  this._logger.error("Surveys API could not be loaded", error);
2637
3518
  this._events.emit("error", error);
@@ -2668,23 +3549,39 @@ class PostHogCoreStateless {
2668
3549
  return message;
2669
3550
  }
2670
3551
  async flushStorage() {}
2671
- enqueue(type, _message, options) {
3552
+ getQueueRouteKey(_message) {
3553
+ return DEFAULT_QUEUE_ROUTE;
3554
+ }
3555
+ persistedQueueKeyForRoute(_route) {
3556
+ return types_PostHogPersistedProperty.Queue;
3557
+ }
3558
+ getActiveQueueRoutes() {
3559
+ return [
3560
+ DEFAULT_QUEUE_ROUTE
3561
+ ];
3562
+ }
3563
+ getRouteQueue(route) {
3564
+ return this.getPersistedProperty(this.persistedQueueKeyForRoute(route)) || [];
3565
+ }
3566
+ enqueue(type, _message, options, explicitRoute) {
2672
3567
  this.wrap(() => {
2673
3568
  if (this.optedOut)
2674
3569
  return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2675
- let message = this.prepareMessage(type, _message, options);
3570
+ let message = this.prepareMessage(_message, options);
2676
3571
  message = this.processBeforeEnqueue(message);
2677
3572
  if (message === null)
2678
3573
  return;
2679
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
3574
+ message = this.normalizeMessage(message);
3575
+ const queueKey = this.persistedQueueKeyForRoute(explicitRoute ?? this.getQueueRouteKey(message));
3576
+ const queue = this.getPersistedProperty(queueKey) || [];
2680
3577
  if (queue.length >= this.maxQueueSize) {
2681
3578
  queue.shift();
2682
- this._logger.info("Queue is full, the oldest event is dropped.");
3579
+ this._logger.warn("Queue is full, the oldest event is dropped.");
2683
3580
  }
2684
3581
  queue.push({
2685
3582
  message
2686
3583
  });
2687
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, queue);
3584
+ this.setPersistedProperty(queueKey, queue);
2688
3585
  this._events.emit(type, message);
2689
3586
  if (queue.length >= this.flushAt)
2690
3587
  this.flushBackground();
@@ -2692,61 +3589,63 @@ class PostHogCoreStateless {
2692
3589
  this._flushTimer = safeSetTimeout(() => this.flushBackground(), this.flushInterval);
2693
3590
  });
2694
3591
  }
2695
- async sendImmediate(type, _message, options) {
3592
+ async sendImmediate(type, _message, options, explicitRoute) {
2696
3593
  if (this.disabled)
2697
3594
  return void this._logger.warn("The client is disabled");
2698
3595
  if (!this._isInitialized)
2699
3596
  await this._initPromise;
2700
3597
  if (this.optedOut)
2701
3598
  return void this._events.emit(type, "Library is disabled. Not sending event. To re-enable, call posthog.optIn()");
2702
- let message = this.prepareMessage(type, _message, options);
3599
+ let message = this.prepareMessage(_message, options);
2703
3600
  message = this.processBeforeEnqueue(message);
2704
3601
  if (message === null)
2705
3602
  return;
2706
- const data = {
2707
- api_key: this.apiKey,
2708
- batch: [
2709
- message
2710
- ],
2711
- sent_at: currentISOTime()
2712
- };
2713
- if (this.historicalMigration)
2714
- data.historical_migration = true;
2715
- const payload = JSON.stringify(data);
2716
- const url = `${this.host}/batch/`;
2717
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2718
- const fetchOptions = {
2719
- method: "POST",
2720
- headers: {
2721
- ...this.getCustomHeaders(),
2722
- "Content-Type": "application/json",
2723
- ...gzippedPayload !== null && {
2724
- "Content-Encoding": "gzip"
2725
- }
2726
- },
2727
- body: gzippedPayload || payload
2728
- };
3603
+ message = this.normalizeMessage(message);
2729
3604
  try {
2730
- const response = await this.fetchWithRetry(url, fetchOptions);
2731
- await response.body?.cancel()?.catch(() => {});
3605
+ await this.sendBatch([
3606
+ message
3607
+ ], undefined, explicitRoute ?? this.getQueueRouteKey(message));
2732
3608
  } catch (err) {
2733
3609
  this._events.emit("error", err);
2734
3610
  }
2735
3611
  }
2736
- prepareMessage(type, _message, options) {
3612
+ normalizeMessage(message) {
3613
+ const { type: _type, library, library_version, ...sanitizedMessage } = message;
3614
+ let properties = isPostHogEventProperties(sanitizedMessage.properties) ? sanitizedMessage.properties : undefined;
3615
+ if (library !== undefined && properties?.$lib === undefined)
3616
+ properties = {
3617
+ ...properties || {},
3618
+ $lib: library
3619
+ };
3620
+ if (library_version !== undefined && properties?.$lib_version === undefined)
3621
+ properties = {
3622
+ ...properties || {},
3623
+ $lib_version: library_version
3624
+ };
3625
+ if (properties)
3626
+ sanitizedMessage.properties = properties;
3627
+ sanitizedMessage.uuid = getEventUuid(sanitizedMessage.uuid, uuidv7);
3628
+ return sanitizedMessage;
3629
+ }
3630
+ normalizeTimestampForWire(timestamp) {
3631
+ const parsedTimestamp = timestamp instanceof Date ? timestamp : typeof timestamp == "string" ? new Date(timestamp) : null;
3632
+ if (!parsedTimestamp || Number.isNaN(parsedTimestamp.getTime()))
3633
+ return timestamp;
3634
+ const normalized = parsedTimestamp.toISOString();
3635
+ const fractionalSeconds = typeof timestamp == "string" ? timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1] : undefined;
3636
+ return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
3637
+ }
3638
+ prepareMessage(_message, options) {
2737
3639
  const message = {
2738
3640
  ..._message,
2739
- type,
2740
- library: this.getLibraryId(),
2741
- library_version: this.getLibraryVersion(),
2742
3641
  timestamp: options?.timestamp ? options?.timestamp : currentISOTime(),
2743
- uuid: options?.uuid ? options.uuid : uuidv7()
3642
+ uuid: getEventUuid(options?.uuid, uuidv7)
2744
3643
  };
2745
3644
  const addGeoipDisableProperty = options?.disableGeoip ?? this.disableGeoip;
2746
3645
  if (addGeoipDisableProperty) {
2747
- if (!message.properties)
3646
+ if (!isPostHogEventProperties(message.properties))
2748
3647
  message.properties = {};
2749
- message["properties"]["$geoip_disable"] = true;
3648
+ message.properties["$geoip_disable"] = true;
2750
3649
  }
2751
3650
  if (message.distinctId) {
2752
3651
  message.distinct_id = message.distinctId;
@@ -2761,21 +3660,64 @@ class PostHogCoreStateless {
2761
3660
  }
2762
3661
  }
2763
3662
  flushBackground() {
3663
+ if (this.pendingFlushPromise)
3664
+ return;
2764
3665
  this.flush().catch(async (err) => {
2765
3666
  await logFlushError(err);
2766
3667
  });
2767
3668
  }
2768
- async flush() {
3669
+ async waitForPendingPromises(maxPromiseId, ignoredPromises = []) {
3670
+ const ignoredPendingPromises = ignoredPromises.filter((promise) => !!promise);
3671
+ let iteration = 0;
3672
+ while (true) {
3673
+ const promises = this.promiseQueue.getPromises([
3674
+ ...ignoredPendingPromises,
3675
+ ...this.flushPromises
3676
+ ], maxPromiseId);
3677
+ if (promises.length === 0)
3678
+ return;
3679
+ if (iteration > 0)
3680
+ this._logger.debug(`flush() re-checking ${promises.length} pending promise(s) before flushing`);
3681
+ await Promise.all(promises.map((promise) => promise.catch(() => {})));
3682
+ iteration++;
3683
+ }
3684
+ }
3685
+ flushWithPendingPromises() {
3686
+ return this.flushInternal(true);
3687
+ }
3688
+ flush() {
3689
+ return this.flushInternal(false);
3690
+ }
3691
+ flushInternal(waitForPendingPromises) {
2769
3692
  if (this.disabled)
2770
- return;
2771
- const nextFlushPromise = allSettled([
2772
- this.flushPromise
2773
- ]).then(() => this._flush());
3693
+ return Promise.resolve();
3694
+ if (!waitForPendingPromises && this.pendingFlushPromise)
3695
+ return this.pendingFlushPromise;
3696
+ const previousFlushPromise = this.flushPromise;
3697
+ const maxPromiseId = this.promiseQueue.maxId;
3698
+ const nextFlushPromise = Promise.resolve().then(() => {
3699
+ if (waitForPendingPromises)
3700
+ return this.waitForPendingPromises(maxPromiseId, [
3701
+ previousFlushPromise,
3702
+ nextFlushPromise
3703
+ ]);
3704
+ }).then(() => allSettled([
3705
+ previousFlushPromise
3706
+ ])).then(() => {
3707
+ if (this.pendingFlushPromise === nextFlushPromise)
3708
+ this.pendingFlushPromise = null;
3709
+ return this._flush();
3710
+ });
3711
+ this.pendingFlushPromise = nextFlushPromise;
2774
3712
  this.flushPromise = nextFlushPromise;
3713
+ this.flushPromises.add(nextFlushPromise);
2775
3714
  this.addPendingPromise(nextFlushPromise);
2776
3715
  allSettled([
2777
3716
  nextFlushPromise
2778
3717
  ]).then(() => {
3718
+ this.flushPromises.delete(nextFlushPromise);
3719
+ if (this.pendingFlushPromise === nextFlushPromise)
3720
+ this.pendingFlushPromise = null;
2779
3721
  if (this.flushPromise === nextFlushPromise)
2780
3722
  this.flushPromise = null;
2781
3723
  });
@@ -2788,55 +3730,102 @@ class PostHogCoreStateless {
2788
3730
  headers["User-Agent"] = customUserAgent;
2789
3731
  return headers;
2790
3732
  }
3733
+ compressPayload(payload) {
3734
+ return gzipCompress(payload, this.isDebug);
3735
+ }
3736
+ getBatchEndpointPath(_route) {
3737
+ return "/batch/";
3738
+ }
3739
+ async sendBatch(batchMessages, retryOptions, route = DEFAULT_QUEUE_ROUTE) {
3740
+ const data = {
3741
+ api_key: this.apiKey,
3742
+ batch: batchMessages.map((message) => {
3743
+ if (!message)
3744
+ return message;
3745
+ const timestamp = this.normalizeTimestampForWire(message.timestamp);
3746
+ return timestamp === message.timestamp ? message : {
3747
+ ...message,
3748
+ timestamp
3749
+ };
3750
+ }),
3751
+ sent_at: currentISOTime()
3752
+ };
3753
+ if (this.historicalMigration)
3754
+ data.historical_migration = true;
3755
+ const payload = safeJsonStringify(data);
3756
+ const url = `${this.host}${this.getBatchEndpointPath(route)}`;
3757
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(payload);
3758
+ const fetchOptions = {
3759
+ method: "POST",
3760
+ headers: {
3761
+ ...this.getCustomHeaders(),
3762
+ "Content-Type": "application/json",
3763
+ ...gzippedPayload !== null && {
3764
+ "Content-Encoding": "gzip"
3765
+ }
3766
+ },
3767
+ body: gzippedPayload || payload
3768
+ };
3769
+ await this.fetchWithRetry(url, fetchOptions, {
3770
+ type: "successful-write"
3771
+ }, retryOptions);
3772
+ }
2791
3773
  async _flush() {
2792
3774
  this.clearFlushTimer();
2793
3775
  await this._initPromise;
2794
- let queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2795
- if (!queue.length)
3776
+ const routes = this.getActiveQueueRoutes();
3777
+ if (!routes.some((route) => this.getRouteQueue(route).length > 0))
2796
3778
  return;
2797
3779
  const sentMessages = [];
3780
+ let firstError;
3781
+ for (const route of routes)
3782
+ try {
3783
+ await this._flushRoute(route, sentMessages);
3784
+ } catch (err) {
3785
+ if (firstError === undefined)
3786
+ firstError = err;
3787
+ }
3788
+ if (firstError !== undefined)
3789
+ throw firstError;
3790
+ this._events.emit("flush", sentMessages);
3791
+ }
3792
+ async _flushRoute(route, sentMessages) {
3793
+ const queueKey = this.persistedQueueKeyForRoute(route);
3794
+ let queue = this.getPersistedProperty(queueKey) || [];
3795
+ if (!queue.length)
3796
+ return;
2798
3797
  const originalQueueLength = queue.length;
2799
- while (queue.length > 0 && sentMessages.length < originalQueueLength) {
3798
+ let sentFromRoute = 0;
3799
+ while (queue.length > 0 && sentFromRoute < originalQueueLength) {
2800
3800
  const batchItems = queue.slice(0, this.maxBatchSize);
2801
- const batchMessages = batchItems.map((item) => item.message);
3801
+ const batchMessages = batchItems.map((item) => item.message === undefined ? item.message : this.normalizeMessage(item.message));
2802
3802
  const persistQueueChange = async () => {
2803
- const refreshedQueue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2804
- const newQueue = refreshedQueue.slice(batchItems.length);
2805
- this.setPersistedProperty(types_PostHogPersistedProperty.Queue, newQueue);
3803
+ const refreshedQueue = this.getPersistedProperty(queueKey) || [];
3804
+ const remainingBatchItems = [
3805
+ ...batchItems
3806
+ ];
3807
+ const newQueue = refreshedQueue.filter((item) => {
3808
+ const itemUuid = item.message?.uuid;
3809
+ const batchItemIndex = remainingBatchItems.findIndex((batchItem) => batchItem === item || typeof itemUuid == "string" && itemUuid.length > 0 && batchItem.message?.uuid === itemUuid);
3810
+ if (batchItemIndex === -1)
3811
+ return true;
3812
+ remainingBatchItems.splice(batchItemIndex, 1);
3813
+ return false;
3814
+ });
3815
+ this.setPersistedProperty(queueKey, newQueue);
2806
3816
  queue = newQueue;
3817
+ this._dequeuedMessagesCount += batchItems.length;
2807
3818
  await this.flushStorage();
2808
3819
  };
2809
- const data = {
2810
- api_key: this.apiKey,
2811
- batch: batchMessages,
2812
- sent_at: currentISOTime()
2813
- };
2814
- if (this.historicalMigration)
2815
- data.historical_migration = true;
2816
- const payload = JSON.stringify(data);
2817
- const url = `${this.host}/batch/`;
2818
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(payload, this.isDebug);
2819
- const fetchOptions = {
2820
- method: "POST",
2821
- headers: {
2822
- ...this.getCustomHeaders(),
2823
- "Content-Type": "application/json",
2824
- ...gzippedPayload !== null && {
2825
- "Content-Encoding": "gzip"
2826
- }
2827
- },
2828
- body: gzippedPayload || payload
2829
- };
2830
3820
  const retryOptions = {
2831
3821
  retryCheck: (err) => {
2832
3822
  if (isPostHogFetchContentTooLargeError(err))
2833
3823
  return false;
2834
- return isPostHogFetchError(err);
3824
+ return isPostHogFetchRetryableError(err);
2835
3825
  }
2836
3826
  };
2837
3827
  try {
2838
- const response = await this.fetchWithRetry(url, fetchOptions, retryOptions);
2839
- await response.body?.cancel()?.catch(() => {});
3828
+ await this.sendBatch(batchMessages, retryOptions, route);
2840
3829
  } catch (err) {
2841
3830
  if (isPostHogFetchContentTooLargeError(err) && batchMessages.length > 1) {
2842
3831
  this.maxBatchSize = Math.max(1, Math.floor(batchMessages.length / 2));
@@ -2850,8 +3839,8 @@ class PostHogCoreStateless {
2850
3839
  }
2851
3840
  await persistQueueChange();
2852
3841
  sentMessages.push(...batchMessages);
3842
+ sentFromRoute += batchMessages.length;
2853
3843
  }
2854
- this._events.emit("flush", sentMessages);
2855
3844
  }
2856
3845
  async _sendLogsBatch(payload) {
2857
3846
  if (this.disabled)
@@ -2861,7 +3850,7 @@ class PostHogCoreStateless {
2861
3850
  };
2862
3851
  const serialized = JSON.stringify(payload);
2863
3852
  const url = `${this.host}/i/v1/logs?token=${encodeURIComponent(this.apiKey)}`;
2864
- const gzippedPayload = this.disableCompression ? null : await gzipCompress(serialized, this.isDebug);
3853
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
2865
3854
  const fetchOptions = {
2866
3855
  method: "POST",
2867
3856
  headers: {
@@ -2875,10 +3864,12 @@ class PostHogCoreStateless {
2875
3864
  };
2876
3865
  try {
2877
3866
  await this.fetchWithRetry(url, fetchOptions, {
3867
+ type: "successful-write"
3868
+ }, {
2878
3869
  retryCheck: (err) => {
2879
3870
  if (isPostHogFetchContentTooLargeError(err))
2880
3871
  return false;
2881
- return isPostHogFetchError(err);
3872
+ return isPostHogFetchRetryableError(err);
2882
3873
  }
2883
3874
  });
2884
3875
  return {
@@ -2900,41 +3891,155 @@ class PostHogCoreStateless {
2900
3891
  };
2901
3892
  }
2902
3893
  }
2903
- async fetchWithRetry(url, options, retryOptions, requestTimeout) {
3894
+ async _sendMetricsBatch(payload) {
3895
+ if (this.disabled)
3896
+ return {
3897
+ kind: "fatal",
3898
+ error: new Error("The client is disabled")
3899
+ };
3900
+ const serialized = JSON.stringify(payload);
3901
+ const url = `${this.host}/i/v1/metrics?token=${encodeURIComponent(this.apiKey)}`;
3902
+ const gzippedPayload = this.disableCompression ? null : await this.compressPayload(serialized);
3903
+ const fetchOptions = {
3904
+ method: "POST",
3905
+ headers: {
3906
+ ...this.getCustomHeaders(),
3907
+ "Content-Type": "application/json",
3908
+ ...gzippedPayload !== null && {
3909
+ "Content-Encoding": "gzip"
3910
+ }
3911
+ },
3912
+ body: gzippedPayload || serialized
3913
+ };
3914
+ try {
3915
+ await this.fetchWithRetry(url, fetchOptions, {
3916
+ type: "successful-write"
3917
+ }, {
3918
+ retryCheck: (err) => {
3919
+ if (isPostHogFetchContentTooLargeError(err))
3920
+ return false;
3921
+ return isPostHogFetchRetryableError(err);
3922
+ }
3923
+ });
3924
+ return {
3925
+ kind: "ok"
3926
+ };
3927
+ } catch (err) {
3928
+ if (isPostHogFetchContentTooLargeError(err))
3929
+ return {
3930
+ kind: "too-large"
3931
+ };
3932
+ if (isPostHogFetchRetryableError(err))
3933
+ return {
3934
+ kind: "retry-later",
3935
+ error: err
3936
+ };
3937
+ return {
3938
+ kind: "fatal",
3939
+ error: err
3940
+ };
3941
+ }
3942
+ }
3943
+ async fetchWithRetry(url, options, responseHandling, retryOptions, requestTimeout) {
2904
3944
  const body = options.body ? options.body : "";
2905
3945
  let reqByteLength = -1;
2906
3946
  try {
2907
- reqByteLength = body instanceof Blob ? body.size : Buffer.byteLength(body, STRING_FORMAT);
3947
+ reqByteLength = body instanceof Blob ? body.size : body instanceof Uint8Array ? body.byteLength : Buffer.byteLength(body, STRING_FORMAT);
2908
3948
  } catch {
2909
3949
  if (body instanceof Blob)
2910
3950
  reqByteLength = body.size;
3951
+ else if (body instanceof Uint8Array)
3952
+ reqByteLength = body.byteLength;
2911
3953
  else {
2912
3954
  const encoded = new TextEncoder().encode(body);
2913
3955
  reqByteLength = encoded.length;
2914
3956
  }
2915
3957
  }
3958
+ const retriableOptions = {
3959
+ ...this._retryOptions,
3960
+ ...retryOptions
3961
+ };
3962
+ let attempt = 0;
2916
3963
  return await retriable(async () => {
3964
+ attempt++;
2917
3965
  const ctrl = new AbortController;
2918
3966
  const timeoutMs = requestTimeout ?? this.requestTimeout;
2919
- const timer = safeSetTimeout(() => ctrl.abort(), timeoutMs);
2920
- let res = null;
3967
+ const requestDeadline = Date.now() + timeoutMs;
3968
+ let timer;
3969
+ const deadline = new Promise((_resolve, reject) => {
3970
+ timer = safeSetTimeout(() => {
3971
+ const timeoutError = new Error(`Request timed out after ${timeoutMs}ms`);
3972
+ timeoutError.name = "AbortError";
3973
+ reject(timeoutError);
3974
+ ctrl.abort(timeoutError);
3975
+ }, timeoutMs);
3976
+ });
3977
+ let res;
3978
+ let responseAccepted = false;
3979
+ let cancellation;
3980
+ const cancelBody = () => cancellation ??= (async () => {
3981
+ try {
3982
+ await res?.body?.cancel();
3983
+ } catch {}
3984
+ })();
2921
3985
  try {
2922
- res = await this.fetch(url, {
2923
- signal: ctrl.signal,
2924
- ...options
2925
- });
2926
- } catch (e) {
2927
- throw new PostHogFetchNetworkError(e);
3986
+ let fetchPromise;
3987
+ try {
3988
+ fetchPromise = this.fetch(url, {
3989
+ signal: ctrl.signal,
3990
+ ...options
3991
+ });
3992
+ } catch (e) {
3993
+ throw new PostHogFetchNetworkError(e);
3994
+ }
3995
+ fetchPromise.then((lateResponse) => {
3996
+ if (ctrl.signal.aborted && !responseAccepted)
3997
+ Promise.resolve(lateResponse.body?.cancel()).catch(() => {});
3998
+ }).catch(() => {});
3999
+ try {
4000
+ res = await Promise.race([
4001
+ fetchPromise,
4002
+ deadline
4003
+ ]);
4004
+ responseAccepted = true;
4005
+ } catch (e) {
4006
+ throw new PostHogFetchNetworkError(e);
4007
+ }
4008
+ const isNoCors = options.mode === "no-cors";
4009
+ if (!isNoCors && (res.status < 200 || res.status >= 400))
4010
+ throw new PostHogFetchHttpError(res, reqByteLength, requestDeadline, ctrl);
4011
+ if (responseHandling.type === "successful-write") {
4012
+ try {
4013
+ await Promise.race([
4014
+ cancelBody(),
4015
+ deadline
4016
+ ]);
4017
+ } catch {}
4018
+ return;
4019
+ }
4020
+ try {
4021
+ return await Promise.race([
4022
+ responseHandling.consume(res),
4023
+ deadline
4024
+ ]);
4025
+ } catch (e) {
4026
+ if (ctrl.signal.aborted)
4027
+ throw new PostHogFetchNetworkError(e);
4028
+ throw e;
4029
+ }
2928
4030
  } finally {
2929
4031
  clearTimeout(timer);
4032
+ if (ctrl.signal.aborted && res)
4033
+ cancelBody();
2930
4034
  }
2931
- const isNoCors = options.mode === "no-cors";
2932
- if (!isNoCors && (res.status < 200 || res.status >= 400))
2933
- throw new PostHogFetchHttpError(res, reqByteLength);
2934
- return res;
2935
4035
  }, {
2936
- ...this._retryOptions,
2937
- ...retryOptions
4036
+ ...retriableOptions,
4037
+ retryCheck: (error) => {
4038
+ const shouldRetry = retriableOptions.retryCheck(error);
4039
+ if (shouldRetry && attempt <= retriableOptions.retryCount && error instanceof PostHogFetchHttpError)
4040
+ error.cancelResponseBody();
4041
+ return shouldRetry;
4042
+ }
2938
4043
  });
2939
4044
  }
2940
4045
  async _shutdown(shutdownTimeoutMs = 30000) {
@@ -2947,12 +4052,17 @@ class PostHogCoreStateless {
2947
4052
  try {
2948
4053
  await this.promiseQueue.join();
2949
4054
  while (true) {
2950
- const queue = this.getPersistedProperty(types_PostHogPersistedProperty.Queue) || [];
2951
- if (queue.length === 0)
4055
+ const hasQueuedEvents = this.getActiveQueueRoutes().some((route) => this.getRouteQueue(route).length > 0);
4056
+ if (!hasQueuedEvents)
2952
4057
  break;
4058
+ const dequeuedBeforeFlush = this._dequeuedMessagesCount;
2953
4059
  await this.flush();
2954
4060
  if (hasTimedOut)
2955
4061
  break;
4062
+ if (this._dequeuedMessagesCount === dequeuedBeforeFlush) {
4063
+ this._logger.warn("Shutdown flush completed but did not send any queued events. Stopping drain to avoid a loop.");
4064
+ break;
4065
+ }
2956
4066
  }
2957
4067
  } catch (e) {
2958
4068
  if (!isPostHogFetchError(e))
@@ -2960,21 +4070,12 @@ class PostHogCoreStateless {
2960
4070
  await logFlushError(e);
2961
4071
  }
2962
4072
  };
2963
- let timeoutHandle;
2964
- try {
2965
- return await Promise.race([
2966
- new Promise((_, reject) => {
2967
- timeoutHandle = safeSetTimeout(() => {
2968
- this._logger.error("Timed out while shutting down PostHog");
2969
- hasTimedOut = true;
2970
- reject("Timeout while shutting down PostHog. Some events may not have been sent.");
2971
- }, shutdownTimeoutMs);
2972
- }),
2973
- doShutdown()
2974
- ]);
2975
- } finally {
2976
- clearTimeout(timeoutHandle);
2977
- }
4073
+ return raceWithTimeout(doShutdown(), shutdownTimeoutMs, () => {
4074
+ this._logger.critical("Timeout while shutting down PostHog. Some events may not have been sent.", {
4075
+ shutdownTimeoutMs
4076
+ });
4077
+ hasTimedOut = true;
4078
+ });
2978
4079
  }
2979
4080
  async shutdown(shutdownTimeoutMs = 30000) {
2980
4081
  if (this.shutdownPromise)
@@ -2986,21 +4087,30 @@ class PostHogCoreStateless {
2986
4087
  return this.shutdownPromise;
2987
4088
  }
2988
4089
  }
2989
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
2990
- import { createReadStream } from "node:fs";
4090
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
4091
+ import { constants as constants2 } from "node:fs";
4092
+ import { open as promises_open } from "node:fs/promises";
4093
+ import { isAbsolute } from "node:path";
2991
4094
  import { createInterface } from "node:readline";
2992
4095
  var LRU_FILE_CONTENTS_CACHE = new exports_error_tracking.ReduceableCache(25);
2993
4096
  var LRU_FILE_CONTENTS_FS_READ_FAILED = new exports_error_tracking.ReduceableCache(20);
2994
4097
  var DEFAULT_LINES_OF_CONTEXT = 7;
2995
4098
  var MAX_CONTEXTLINES_COLNO = 1000;
2996
4099
  var MAX_CONTEXTLINES_LINENO = 1e4;
2997
- async function addSourceContext(frames) {
4100
+ var MAX_CONTEXTLINES_FILE_SIZE = 10485760;
4101
+ async function addSourceContext(frames, openSourceFile = promises_open, logger2) {
2998
4102
  const filesToLines = {};
4103
+ let basePath;
4104
+ try {
4105
+ basePath = process.cwd();
4106
+ } catch {}
2999
4107
  for (let i = frames.length - 1;i >= 0; i--) {
3000
4108
  const frame = frames[i];
3001
4109
  const filename = frame?.filename;
3002
4110
  if (!frame || typeof filename != "string" || typeof frame.lineno != "number" || shouldSkipContextLinesForFile(filename) || shouldSkipContextLinesForFrame(frame))
3003
4111
  continue;
4112
+ if (!isAbsolute(filename) && basePath === undefined)
4113
+ continue;
3004
4114
  const filesToLinesOutput = filesToLines[filename];
3005
4115
  if (!filesToLinesOutput)
3006
4116
  filesToLines[filename] = [];
@@ -3011,50 +4121,98 @@ async function addSourceContext(frames) {
3011
4121
  return frames;
3012
4122
  const readlinePromises = [];
3013
4123
  for (const file of files) {
3014
- if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(file))
4124
+ const cacheKey = makeSourceCacheKey(file, basePath);
4125
+ if (cacheKey === undefined)
4126
+ continue;
4127
+ if (LRU_FILE_CONTENTS_FS_READ_FAILED.get(cacheKey))
3015
4128
  continue;
3016
4129
  const filesToLineRanges = filesToLines[file];
3017
4130
  if (!filesToLineRanges)
3018
4131
  continue;
3019
4132
  filesToLineRanges.sort((a, b) => a - b);
3020
4133
  const ranges = makeLineReaderRanges(filesToLineRanges);
3021
- if (ranges.every((r) => rangeExistsInContentCache(file, r)))
4134
+ if (ranges.every((r) => rangeExistsInContentCache(cacheKey, r)))
3022
4135
  continue;
3023
- const cache = emplace(LRU_FILE_CONTENTS_CACHE, file, {});
3024
- readlinePromises.push(getContextLinesFromFile(file, ranges, cache));
4136
+ const cache = emplace(LRU_FILE_CONTENTS_CACHE, cacheKey, {});
4137
+ readlinePromises.push(getContextLinesFromFile(file, ranges, cache, cacheKey, openSourceFile, logger2));
3025
4138
  }
3026
4139
  await Promise.all(readlinePromises).catch(() => {});
3027
4140
  if (frames && frames.length > 0)
3028
- addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE);
4141
+ addSourceContextToFrames(frames, LRU_FILE_CONTENTS_CACHE, basePath);
3029
4142
  LRU_FILE_CONTENTS_CACHE.reduce();
3030
4143
  return frames;
3031
4144
  }
3032
- function getContextLinesFromFile(path2, ranges, output) {
4145
+ async function openRegularSourceFile(path2, openSourceFile, logger2) {
4146
+ let fileHandle;
4147
+ let isValid = false;
4148
+ try {
4149
+ fileHandle = await openSourceFile(path2, constants2.O_RDONLY | constants2.O_NONBLOCK);
4150
+ const fileStat = await fileHandle.stat();
4151
+ if (!fileStat.isFile())
4152
+ return;
4153
+ if (fileStat.size > MAX_CONTEXTLINES_FILE_SIZE)
4154
+ return void logger2?.debug(`Skipping source context for oversized file ${path2}: ${fileStat.size} bytes exceeds ${MAX_CONTEXTLINES_FILE_SIZE}`);
4155
+ isValid = true;
4156
+ return fileHandle;
4157
+ } catch {
4158
+ return;
4159
+ } finally {
4160
+ if (fileHandle && !isValid)
4161
+ await fileHandle.close().catch(() => {});
4162
+ }
4163
+ }
4164
+ async function getContextLinesFromFile(path2, ranges, output, cacheKey, openSourceFile, logger2) {
4165
+ const fileHandle = await openRegularSourceFile(path2, openSourceFile, logger2);
4166
+ if (fileHandle === undefined)
4167
+ return void LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4168
+ const openedFileHandle = fileHandle;
3033
4169
  return new Promise((resolve) => {
3034
- const stream = createReadStream(path2);
3035
- const lineReaded = createInterface({
3036
- input: stream
3037
- });
3038
- function destroyStreamAndResolve() {
3039
- stream.destroy();
3040
- resolve();
4170
+ let finished = false;
4171
+ function destroyStreamAndResolve(stream2) {
4172
+ if (finished)
4173
+ return;
4174
+ finished = true;
4175
+ stream2?.destroy();
4176
+ openedFileHandle.close().then(resolve, resolve);
4177
+ }
4178
+ let stream;
4179
+ try {
4180
+ stream = openedFileHandle.createReadStream({
4181
+ autoClose: false,
4182
+ start: 0,
4183
+ end: MAX_CONTEXTLINES_FILE_SIZE - 1
4184
+ });
4185
+ } catch {
4186
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4187
+ destroyStreamAndResolve();
4188
+ return;
4189
+ }
4190
+ let lineReaded;
4191
+ try {
4192
+ lineReaded = createInterface({
4193
+ input: stream
4194
+ });
4195
+ } catch {
4196
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
4197
+ destroyStreamAndResolve(stream);
4198
+ return;
3041
4199
  }
3042
4200
  let lineNumber = 0;
3043
4201
  let currentRangeIndex = 0;
3044
4202
  const range = ranges[currentRangeIndex];
3045
4203
  if (range === undefined)
3046
- return void destroyStreamAndResolve();
4204
+ return void destroyStreamAndResolve(stream);
3047
4205
  let rangeStart = range[0];
3048
4206
  let rangeEnd = range[1];
3049
4207
  function onStreamError() {
3050
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path2, 1);
4208
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(cacheKey, 1);
3051
4209
  lineReaded.close();
3052
4210
  lineReaded.removeAllListeners();
3053
- destroyStreamAndResolve();
4211
+ destroyStreamAndResolve(stream);
3054
4212
  }
3055
4213
  stream.on("error", onStreamError);
3056
4214
  lineReaded.on("error", onStreamError);
3057
- lineReaded.on("close", destroyStreamAndResolve);
4215
+ lineReaded.on("close", () => destroyStreamAndResolve(stream));
3058
4216
  lineReaded.on("line", (line) => {
3059
4217
  lineNumber++;
3060
4218
  if (lineNumber < rangeStart)
@@ -3079,10 +4237,11 @@ function getContextLinesFromFile(path2, ranges, output) {
3079
4237
  });
3080
4238
  });
3081
4239
  }
3082
- function addSourceContextToFrames(frames, cache) {
4240
+ function addSourceContextToFrames(frames, cache, basePath) {
3083
4241
  for (const frame of frames)
3084
4242
  if (frame.filename && frame.context_line === undefined && typeof frame.lineno == "number") {
3085
- const contents = cache.get(frame.filename);
4243
+ const cacheKey = makeSourceCacheKey(frame.filename, basePath);
4244
+ const contents = cacheKey === undefined ? undefined : cache.get(cacheKey);
3086
4245
  if (contents === undefined)
3087
4246
  continue;
3088
4247
  addContextToFrame(frame.lineno, frame, contents);
@@ -3125,8 +4284,19 @@ function shouldSkipContextLinesForFrame(frame) {
3125
4284
  return true;
3126
4285
  return false;
3127
4286
  }
3128
- function rangeExistsInContentCache(file, range) {
3129
- const contents = LRU_FILE_CONTENTS_CACHE.get(file);
4287
+ function makeSourceCacheKey(path2, basePath) {
4288
+ if (isAbsolute(path2))
4289
+ return JSON.stringify([
4290
+ null,
4291
+ path2
4292
+ ]);
4293
+ return basePath === undefined ? undefined : JSON.stringify([
4294
+ basePath,
4295
+ path2
4296
+ ]);
4297
+ }
4298
+ function rangeExistsInContentCache(cacheKey, range) {
4299
+ const contents = LRU_FILE_CONTENTS_CACHE.get(cacheKey);
3130
4300
  if (contents === undefined)
3131
4301
  return false;
3132
4302
  for (let i = range[0];i <= range[1]; i++)
@@ -3204,8 +4374,8 @@ function snipLine(line, colno) {
3204
4374
  return newLine;
3205
4375
  }
3206
4376
 
3207
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
3208
- import { isAbsolute, relative, sep as sep2 } from "path";
4377
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/modifiers/relative-path.node.mjs
4378
+ import { isAbsolute as isAbsolute2, relative, sep as sep2 } from "path";
3209
4379
  function createRelativePathModifier(basePath = process.cwd()) {
3210
4380
  const isWindows = sep2 === "\\";
3211
4381
  const toUnix = (p) => isWindows ? p.replace(/\\/g, "/") : p;
@@ -3213,17 +4383,17 @@ function createRelativePathModifier(basePath = process.cwd()) {
3213
4383
  return async (frames) => {
3214
4384
  for (const frame of frames)
3215
4385
  if (!(!frame.filename || frame.filename.startsWith("node:") || frame.filename.startsWith("data:"))) {
3216
- if (isAbsolute(frame.filename))
4386
+ if (isAbsolute2(frame.filename))
3217
4387
  frame.filename = toUnix(relative(normalizedBase, toUnix(frame.filename)));
3218
4388
  }
3219
4389
  return frames;
3220
4390
  };
3221
4391
  }
3222
4392
 
3223
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/version.mjs
3224
- var version = "5.35.12";
4393
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/version.mjs
4394
+ var version = "5.51.1";
3225
4395
 
3226
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/types.mjs
4396
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/types.mjs
3227
4397
  var FeatureFlagError2 = {
3228
4398
  ERRORS_WHILE_COMPUTING: "errors_while_computing_flags",
3229
4399
  FLAG_MISSING: "flag_missing",
@@ -3231,7 +4401,7 @@ var FeatureFlagError2 = {
3231
4401
  UNKNOWN_ERROR: "unknown_error"
3232
4402
  };
3233
4403
 
3234
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/feature-flag-evaluations.mjs
4404
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/feature-flag-evaluations.mjs
3235
4405
  class FeatureFlagEvaluations {
3236
4406
  constructor(init) {
3237
4407
  this._host = init.host;
@@ -3247,10 +4417,10 @@ class FeatureFlagEvaluations {
3247
4417
  this._accessed = init.accessed ?? new Set;
3248
4418
  this._isSlice = init.isSlice ?? false;
3249
4419
  }
3250
- isEnabled(key) {
4420
+ isEnabled(key, options = {}) {
3251
4421
  const flag = this._flags[key];
3252
4422
  this._recordAccess(key);
3253
- return flag?.enabled ?? false;
4423
+ return flag?.enabled ?? options.defaultValue ?? false;
3254
4424
  }
3255
4425
  getFlag(key) {
3256
4426
  const flag = this._flags[key];
@@ -3340,6 +4510,8 @@ class FeatureFlagEvaluations {
3340
4510
  $feature_flag_request_id: this._requestId,
3341
4511
  $feature_flag_evaluated_at: flag?.locallyEvaluated ? Date.now() : this._evaluatedAt
3342
4512
  };
4513
+ if (flag?.hasExperiment !== undefined)
4514
+ properties.$feature_flag_has_experiment = flag.hasExperiment;
3343
4515
  if (flag?.locallyEvaluated && this._flagDefinitionsLoadedAt !== undefined)
3344
4516
  properties.$feature_flag_definitions_loaded_at = this._flagDefinitionsLoadedAt;
3345
4517
  const errors = [];
@@ -3362,7 +4534,7 @@ class FeatureFlagEvaluations {
3362
4534
  }
3363
4535
  }
3364
4536
 
3365
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
4537
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/feature-flags/crypto.mjs
3366
4538
  async function hashSHA1(text) {
3367
4539
  const subtle = globalThis.crypto?.subtle;
3368
4540
  if (!subtle)
@@ -3372,7 +4544,7 @@ async function hashSHA1(text) {
3372
4544
  return hashArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
3373
4545
  }
3374
4546
 
3375
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
4547
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/feature-flags/feature-flags.mjs
3376
4548
  var SIXTY_SECONDS = 60000;
3377
4549
  var LONG_SCALE = 1152921504606847000;
3378
4550
  var NULL_VALUES_ALLOWED_OPERATORS = [
@@ -3389,22 +4561,23 @@ class ClientError extends Error {
3389
4561
  Object.setPrototypeOf(this, ClientError.prototype);
3390
4562
  }
3391
4563
  }
4564
+ function setCustomErrorPrototype(error, constructor) {
4565
+ error.name = constructor.name;
4566
+ Error.captureStackTrace(error, constructor);
4567
+ Object.setPrototypeOf(error, constructor.prototype);
4568
+ }
3392
4569
 
3393
4570
  class InconclusiveMatchError extends Error {
3394
4571
  constructor(message) {
3395
4572
  super(message);
3396
- this.name = this.constructor.name;
3397
- Error.captureStackTrace(this, this.constructor);
3398
- Object.setPrototypeOf(this, InconclusiveMatchError.prototype);
4573
+ setCustomErrorPrototype(this, InconclusiveMatchError);
3399
4574
  }
3400
4575
  }
3401
4576
 
3402
4577
  class RequiresServerEvaluation extends Error {
3403
4578
  constructor(message) {
3404
4579
  super(message);
3405
- this.name = this.constructor.name;
3406
- Error.captureStackTrace(this, this.constructor);
3407
- Object.setPrototypeOf(this, RequiresServerEvaluation.prototype);
4580
+ setCustomErrorPrototype(this, RequiresServerEvaluation);
3408
4581
  }
3409
4582
  }
3410
4583
 
@@ -3413,6 +4586,7 @@ class FeatureFlagsPoller {
3413
4586
  this.debugMode = false;
3414
4587
  this.shouldBeginExponentialBackoff = false;
3415
4588
  this.backOffCount = 0;
4589
+ this.pollerStopped = false;
3416
4590
  this.pollingInterval = pollingInterval;
3417
4591
  this.personalApiKey = personalApiKey;
3418
4592
  this.featureFlags = [];
@@ -3428,6 +4602,7 @@ class FeatureFlagsPoller {
3428
4602
  this.onError = options.onError;
3429
4603
  this.customHeaders = customHeaders;
3430
4604
  this.onLoad = options.onLoad;
4605
+ this.onMinimalFlagCalledEvents = options.onMinimalFlagCalledEvents;
3431
4606
  this.cacheProvider = options.cacheProvider;
3432
4607
  this.strictLocalEvaluation = options.strictLocalEvaluation ?? false;
3433
4608
  this.loadFeatureFlags();
@@ -3625,6 +4800,7 @@ class FeatureFlagsPoller {
3625
4800
  const flagFilters = flag.filters || {};
3626
4801
  const flagConditions = flagFilters.groups || [];
3627
4802
  const flagAggregation = flagFilters.aggregation_group_type_index;
4803
+ const earlyExitEnabled = flagFilters.early_exit ?? false;
3628
4804
  const { groups, groupProperties } = evaluationContext;
3629
4805
  let isInconclusive = false;
3630
4806
  let result;
@@ -3648,12 +4824,15 @@ class FeatureFlagsPoller {
3648
4824
  effectiveBucketingValue = groups[groupName];
3649
4825
  }
3650
4826
  }
3651
- if (await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext)) {
4827
+ const matchResult = await this.isConditionMatch(flag, effectiveBucketingValue, condition, effectiveProperties, evaluationContext);
4828
+ if (matchResult === "match") {
3652
4829
  const variantOverride = condition.variant;
3653
4830
  const flagVariants = flagFilters.multivariate?.variants || [];
3654
4831
  result = variantOverride && flagVariants.some((variant) => variant.key === variantOverride) ? variantOverride : await this.getMatchingVariant(flag, effectiveBucketingValue) || true;
3655
4832
  break;
3656
4833
  }
4834
+ if (earlyExitEnabled && matchResult === "out_of_rollout_bound")
4835
+ return false;
3657
4836
  } catch (e) {
3658
4837
  if (e instanceof RequiresServerEvaluation)
3659
4838
  throw e;
@@ -3677,16 +4856,20 @@ class FeatureFlagsPoller {
3677
4856
  for (const prop of condition.properties) {
3678
4857
  const propertyType = prop.type;
3679
4858
  let matches = false;
3680
- 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);
4859
+ if (propertyType === "cohort") {
4860
+ const inCohort = await matchCohort(prop, properties, this.cohorts, this.debugMode, (depProp) => this.evaluateFlagDependency(depProp, properties, evaluationContext));
4861
+ matches = prop.operator === "not_in" ? !inCohort : inCohort;
4862
+ } else
4863
+ matches = propertyType === "flag" ? await this.evaluateFlagDependency(prop, properties, evaluationContext) : matchProperty(prop, properties, warnFunction);
3681
4864
  if (!matches)
3682
- return false;
4865
+ return "no_match";
3683
4866
  }
3684
4867
  if (rolloutPercentage == undefined)
3685
- return true;
4868
+ return "match";
3686
4869
  }
3687
4870
  if (rolloutPercentage != null && await _hash(flag.key, bucketingValue) > rolloutPercentage / 100)
3688
- return false;
3689
- return true;
4871
+ return "out_of_rollout_bound";
4872
+ return "match";
3690
4873
  }
3691
4874
  async getMatchingVariant(flag, bucketingValue) {
3692
4875
  const hashValue = await _hash(flag.key, bucketingValue, "variant");
@@ -3717,6 +4900,7 @@ class FeatureFlagsPoller {
3717
4900
  this.groupTypeMapping = flagData.groupTypeMapping;
3718
4901
  this.cohorts = flagData.cohorts;
3719
4902
  this.loadedSuccessfullyOnce = true;
4903
+ this.onMinimalFlagCalledEvents?.(flagData.minimalFlagCalledEvents === true);
3720
4904
  }
3721
4905
  warnAboutExperienceContinuityFlags(flags) {
3722
4906
  if (this.strictLocalEvaluation)
@@ -3780,7 +4964,6 @@ class FeatureFlagsPoller {
3780
4964
  clearTimeout(this.poller);
3781
4965
  this.poller = undefined;
3782
4966
  }
3783
- this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
3784
4967
  try {
3785
4968
  let shouldFetch = true;
3786
4969
  if (this.cacheProvider)
@@ -3808,17 +4991,18 @@ class FeatureFlagsPoller {
3808
4991
  return;
3809
4992
  case 401:
3810
4993
  this.beginBackoff();
3811
- 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`);
4994
+ 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`);
3812
4995
  case 402:
3813
4996
  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");
3814
4997
  this.featureFlags = [];
3815
4998
  this.featureFlagsByKey = {};
3816
4999
  this.groupTypeMapping = {};
3817
5000
  this.cohorts = {};
5001
+ this.onMinimalFlagCalledEvents?.(false);
3818
5002
  return;
3819
5003
  case 403:
3820
5004
  this.beginBackoff();
3821
- 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`);
5005
+ 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`);
3822
5006
  case 429:
3823
5007
  this.beginBackoff();
3824
5008
  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`);
@@ -3830,7 +5014,8 @@ class FeatureFlagsPoller {
3830
5014
  const flagData = {
3831
5015
  flags: responseJson.flags ?? [],
3832
5016
  groupTypeMapping: responseJson.group_type_mapping || {},
3833
- cohorts: responseJson.cohorts || {}
5017
+ cohorts: responseJson.cohorts || {},
5018
+ minimalFlagCalledEvents: responseJson.minimal_flag_called_events === true
3834
5019
  };
3835
5020
  this.updateFlagState(flagData);
3836
5021
  this.flagDefinitionsLoadedAt = Date.now();
@@ -3851,6 +5036,9 @@ class FeatureFlagsPoller {
3851
5036
  } catch (err) {
3852
5037
  if (err instanceof ClientError)
3853
5038
  this.onError?.(err);
5039
+ } finally {
5040
+ if (!this.pollerStopped)
5041
+ this.poller = setTimeout(() => this.loadFeatureFlags(true), this.getPollingInterval());
3854
5042
  }
3855
5043
  }
3856
5044
  getPersonalApiKeyRequestOptions(method = "GET", etag) {
@@ -3866,7 +5054,7 @@ class FeatureFlagsPoller {
3866
5054
  headers
3867
5055
  };
3868
5056
  }
3869
- _requestFeatureFlagDefinitions() {
5057
+ async _requestFeatureFlagDefinitions() {
3870
5058
  const url = `${this.host}/flags/definitions?token=${this.projectApiKey}&send_cohorts`;
3871
5059
  const options = this.getPersonalApiKeyRequestOptions("GET", this.flagsEtag);
3872
5060
  let abortTimeout = null;
@@ -3877,23 +5065,49 @@ class FeatureFlagsPoller {
3877
5065
  }, this.timeout);
3878
5066
  options.signal = controller.signal;
3879
5067
  }
5068
+ const clearAbortTimeout = () => clearTimeout(abortTimeout);
3880
5069
  try {
3881
5070
  const fetch1 = this.fetch;
3882
- return fetch1(url, options);
3883
- } finally {
3884
- clearTimeout(abortTimeout);
5071
+ const res = await fetch1(url, options);
5072
+ if (res.status !== 200) {
5073
+ clearAbortTimeout();
5074
+ return res;
5075
+ }
5076
+ return {
5077
+ status: res.status,
5078
+ headers: res.headers,
5079
+ body: res.body,
5080
+ text: async () => {
5081
+ try {
5082
+ return await res.text();
5083
+ } finally {
5084
+ clearAbortTimeout();
5085
+ }
5086
+ },
5087
+ json: async () => {
5088
+ try {
5089
+ return await res.json();
5090
+ } finally {
5091
+ clearAbortTimeout();
5092
+ }
5093
+ }
5094
+ };
5095
+ } catch (err) {
5096
+ clearAbortTimeout();
5097
+ throw err;
3885
5098
  }
3886
5099
  }
3887
5100
  async stopPoller(timeoutMs = 30000) {
5101
+ this.pollerStopped = true;
3888
5102
  clearTimeout(this.poller);
5103
+ this.poller = undefined;
3889
5104
  if (this.cacheProvider)
3890
5105
  try {
3891
5106
  const shutdownResult = this.cacheProvider.shutdown();
3892
5107
  if (shutdownResult instanceof Promise)
3893
- await Promise.race([
3894
- shutdownResult,
3895
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Cache shutdown timeout after ${timeoutMs}ms`)), timeoutMs))
3896
- ]);
5108
+ await raceWithTimeout(shutdownResult, timeoutMs, () => {
5109
+ throw new Error(`Cache shutdown timeout after ${timeoutMs}ms`);
5110
+ });
3897
5111
  } catch (err) {
3898
5112
  this.onError?.(new Error(`Error during cache shutdown: ${err}`));
3899
5113
  }
@@ -3948,6 +5162,14 @@ function matchProperty(property, propertyValues, warnFunction) {
3948
5162
  return String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
3949
5163
  case "not_icontains":
3950
5164
  return !String(overrideValue).toLowerCase().includes(String(value).toLowerCase());
5165
+ case "starts_with":
5166
+ return String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
5167
+ case "not_starts_with":
5168
+ return !String(overrideValue).toLowerCase().startsWith(String(value).toLowerCase());
5169
+ case "ends_with":
5170
+ return String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
5171
+ case "not_ends_with":
5172
+ return !String(overrideValue).toLowerCase().endsWith(String(value).toLowerCase());
3951
5173
  case "regex":
3952
5174
  return isValidRegex(String(value)) && String(overrideValue).match(String(value)) !== null;
3953
5175
  case "not_regex":
@@ -4274,19 +5496,75 @@ function relativeDateParseForFeatureFlagMatching(value) {
4274
5496
  }
4275
5497
  }
4276
5498
 
4277
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
5499
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/autocapture.mjs
5500
+ var UNHANDLED_REJECTION_OPTION_NAMES = [
5501
+ "--unhandled-rejections",
5502
+ "--unhandled_rejections"
5503
+ ];
5504
+ var UNHANDLED_REJECTION_MODES = new Set([
5505
+ "throw",
5506
+ "strict",
5507
+ "warn",
5508
+ "warn-with-error-code",
5509
+ "none"
5510
+ ]);
5511
+ var STARTUP_EXEC_ARGV = [
5512
+ ...globalThis.process?.execArgv ?? []
5513
+ ];
5514
+ var STARTUP_NODE_OPTIONS = globalThis.process?.env?.NODE_OPTIONS;
5515
+ function splitNodeOptions(nodeOptions) {
5516
+ const args = [];
5517
+ let current = "";
5518
+ let isInString = false;
5519
+ for (let index = 0;index < nodeOptions.length; index++) {
5520
+ const character = nodeOptions[index];
5521
+ if (character === "\\" && isInString && index + 1 < nodeOptions.length)
5522
+ current += nodeOptions[++index];
5523
+ else if (character !== " " || isInString)
5524
+ if (character === '"')
5525
+ isInString = !isInString;
5526
+ else
5527
+ current += character;
5528
+ else if (current) {
5529
+ args.push(current);
5530
+ current = "";
5531
+ }
5532
+ }
5533
+ if (current)
5534
+ args.push(current);
5535
+ return args;
5536
+ }
5537
+ function findUnhandledRejectionMode(args) {
5538
+ let mode;
5539
+ for (let index = 0;index < args.length; index++) {
5540
+ const argument = args[index];
5541
+ const optionName = UNHANDLED_REJECTION_OPTION_NAMES.find((name) => argument === name || argument.startsWith(`${name}=`));
5542
+ if (!optionName)
5543
+ continue;
5544
+ const value = argument === optionName ? args[++index] : argument.slice(optionName.length + 1);
5545
+ if (UNHANDLED_REJECTION_MODES.has(value))
5546
+ mode = value;
5547
+ }
5548
+ return mode;
5549
+ }
5550
+ function getUnhandledRejectionMode(execArgv = STARTUP_EXEC_ARGV, nodeOptions = STARTUP_NODE_OPTIONS) {
5551
+ return findUnhandledRejectionMode(execArgv) ?? findUnhandledRejectionMode(splitNodeOptions(nodeOptions ?? "")) ?? "throw";
5552
+ }
5553
+ var STARTUP_UNHANDLED_REJECTION_MODE = getUnhandledRejectionMode();
5554
+ function captureUncaughtException(captureFn, error, origin) {
5555
+ captureFn(error, {
5556
+ mechanism: {
5557
+ type: origin === "unhandledRejection" ? "onunhandledrejection" : "onuncaughtexception",
5558
+ handled: false
5559
+ }
5560
+ });
5561
+ }
4278
5562
  function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
4279
5563
  let calledFatalError = false;
4280
- return Object.assign((error) => {
5564
+ return Object.assign((error, origin) => {
4281
5565
  const userProvidedListenersCount = global.process.listeners("uncaughtException").filter((listener) => listener.name !== "domainUncaughtExceptionClear" && listener._posthogErrorHandler !== true).length;
4282
- const processWouldExit = userProvidedListenersCount === 0;
4283
- captureFn(error, {
4284
- mechanism: {
4285
- type: "onuncaughtexception",
4286
- handled: false
4287
- }
4288
- });
4289
- if (!calledFatalError && processWouldExit) {
5566
+ captureUncaughtException(captureFn, error, origin);
5567
+ if (!calledFatalError && userProvidedListenersCount === 0) {
4290
5568
  calledFatalError = true;
4291
5569
  onFatalFn(error);
4292
5570
  }
@@ -4294,29 +5572,38 @@ function makeUncaughtExceptionHandler(captureFn, onFatalFn) {
4294
5572
  _posthogErrorHandler: true
4295
5573
  });
4296
5574
  }
4297
- function addUncaughtExceptionListener(captureFn, onFatalFn) {
4298
- globalThis.process?.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
5575
+ function addUncaughtExceptionListener(captureFn, onFatalFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
5576
+ const process2 = globalThis.process;
5577
+ if (!process2)
5578
+ return;
5579
+ if (mode === "strict")
5580
+ return void process2.on("uncaughtExceptionMonitor", (error, origin) => captureUncaughtException(captureFn, error, origin));
5581
+ process2.on("uncaughtException", makeUncaughtExceptionHandler(captureFn, onFatalFn));
4299
5582
  }
4300
- function addUnhandledRejectionListener(captureFn) {
4301
- globalThis.process?.on("unhandledRejection", (reason) => captureFn(reason, {
4302
- mechanism: {
4303
- type: "onunhandledrejection",
4304
- handled: false
4305
- }
4306
- }));
5583
+ function addUnhandledRejectionListener(captureFn, mode = STARTUP_UNHANDLED_REJECTION_MODE) {
5584
+ const process2 = globalThis.process;
5585
+ if (!process2 || mode === "throw" || mode === "strict" || mode === "warn-with-error-code")
5586
+ return;
5587
+ process2.on("unhandledRejection", (reason) => {
5588
+ captureFn(reason, {
5589
+ mechanism: {
5590
+ type: "onunhandledrejection",
5591
+ handled: false
5592
+ }
5593
+ });
5594
+ });
4307
5595
  }
4308
5596
 
4309
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
5597
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/error-tracking/index.mjs
4310
5598
  var SHUTDOWN_TIMEOUT = 2000;
4311
5599
 
4312
- class ErrorTracking {
5600
+ class error_tracking_ErrorTracking {
4313
5601
  constructor(client, options, _logger) {
4314
5602
  this.client = client;
4315
5603
  this._exceptionAutocaptureEnabled = options.enableExceptionAutocapture || false;
4316
5604
  this._logger = _logger;
4317
5605
  this._rateLimiter = new BucketedRateLimiter({
4318
- refillRate: 1,
4319
- bucketSize: 10,
5606
+ ...resolveExceptionRateLimiterConfig(options),
4320
5607
  refillInterval: 1e4,
4321
5608
  _logger: this._logger
4322
5609
  });
@@ -4331,6 +5618,9 @@ class ErrorTracking {
4331
5618
  };
4332
5619
  const exceptionProperties = builder.buildFromUnknown(error, hint);
4333
5620
  exceptionProperties.$exception_list = await builder.modifyFrames(exceptionProperties.$exception_list);
5621
+ const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
5622
+ if (injectedReleaseId)
5623
+ properties.$release_id = injectedReleaseId;
4334
5624
  return {
4335
5625
  event: "$exception",
4336
5626
  distinctId,
@@ -4349,8 +5639,8 @@ class ErrorTracking {
4349
5639
  }
4350
5640
  onException(exception, hint) {
4351
5641
  this.client.addPendingPromise((async () => {
4352
- if (!ErrorTracking.isPreviouslyCapturedError(exception)) {
4353
- const eventMessage = await ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
5642
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(exception)) {
5643
+ const eventMessage = await error_tracking_ErrorTracking.buildEventMessage(this.client.getErrorPropertiesBuilder(), exception, hint);
4354
5644
  const exceptionProperties = eventMessage.properties;
4355
5645
  const exceptionType = exceptionProperties?.$exception_list[0]?.type ?? "Exception";
4356
5646
  const isRateLimited = this._rateLimiter.consumeRateLimit(exceptionType);
@@ -4358,14 +5648,14 @@ class ErrorTracking {
4358
5648
  return void this._logger.info("Skipping exception capture because of client rate limiting.", {
4359
5649
  exception: exceptionType
4360
5650
  });
4361
- return this.client.capture(eventMessage);
5651
+ return this.client._capturePreparedEvent(eventMessage, false);
4362
5652
  }
4363
5653
  })());
4364
5654
  }
4365
5655
  async onFatalError(exception) {
4366
5656
  console.error(exception);
4367
5657
  await this.client.shutdown(SHUTDOWN_TIMEOUT);
4368
- process.exit(1);
5658
+ globalThis.process.exit(1);
4369
5659
  }
4370
5660
  isEnabled() {
4371
5661
  return !this.client.isDisabled && this._exceptionAutocaptureEnabled;
@@ -4375,7 +5665,7 @@ class ErrorTracking {
4375
5665
  }
4376
5666
  }
4377
5667
 
4378
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/storage-memory.mjs
5668
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/storage-memory.mjs
4379
5669
  class PostHogMemoryStorage {
4380
5670
  getProperty(key) {
4381
5671
  return this._memoryStorage[key];
@@ -4388,7 +5678,452 @@ class PostHogMemoryStorage {
4388
5678
  }
4389
5679
  }
4390
5680
 
4391
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/client.mjs
5681
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/config.mjs
5682
+ function isCaptureMode(value) {
5683
+ return value === "v0" || value === "v1";
5684
+ }
5685
+ function resolveCaptureMode() {
5686
+ const envMode = typeof process != "undefined" ? process.env?.POSTHOG_CAPTURE_MODE : undefined;
5687
+ return isCaptureMode(envMode) ? envMode : "v0";
5688
+ }
5689
+
5690
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/routing.mjs
5691
+ var AI_EVENT_PREFIX = "$ai_";
5692
+ var ANALYTICS_ROUTE = "analytics";
5693
+ var AI_ROUTE = "ai";
5694
+ function isLegacyOnlyEvent(message) {
5695
+ return typeof message.event == "string" && message.event.startsWith(AI_EVENT_PREFIX);
5696
+ }
5697
+
5698
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/errors.mjs
5699
+ class CaptureV1Error extends Error {
5700
+ constructor({ requestId, drops, retryExhausted, cause }) {
5701
+ super(CaptureV1Error.buildMessage(requestId, drops, retryExhausted, cause)), this.name = "CaptureV1Error";
5702
+ this.requestId = requestId;
5703
+ this.drops = drops;
5704
+ this.retryExhausted = retryExhausted;
5705
+ this.cause = cause;
5706
+ }
5707
+ static buildMessage(requestId, drops, retryExhausted, cause) {
5708
+ let message = `Capture V1 batch ${requestId} did not fully deliver: ${drops.length} dropped, ${retryExhausted.length} undelivered`;
5709
+ if (cause instanceof Error)
5710
+ message += ` (${cause.message})`;
5711
+ return message;
5712
+ }
5713
+ }
5714
+
5715
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/transform.mjs
5716
+ function coerceBool(value) {
5717
+ if (typeof value == "boolean")
5718
+ return value;
5719
+ if (typeof value == "number")
5720
+ return value !== 0;
5721
+ if (typeof value == "string") {
5722
+ const normalized = value.trim().toLowerCase();
5723
+ if (normalized === "true" || normalized === "1")
5724
+ return true;
5725
+ if (normalized === "false" || normalized === "0")
5726
+ return false;
5727
+ }
5728
+ }
5729
+ function coerceString(value) {
5730
+ return typeof value == "string" ? value : undefined;
5731
+ }
5732
+ var OPTION_SENTINELS = [
5733
+ {
5734
+ property: "$cookieless_mode",
5735
+ optionKey: "cookieless_mode",
5736
+ coerce: coerceBool
5737
+ },
5738
+ {
5739
+ property: "$ignore_sent_at",
5740
+ optionKey: "disable_skew_correction",
5741
+ coerce: coerceBool
5742
+ },
5743
+ {
5744
+ property: "$process_person_profile",
5745
+ optionKey: "process_person_profile",
5746
+ coerce: coerceBool
5747
+ },
5748
+ {
5749
+ property: "$product_tour_id",
5750
+ optionKey: "product_tour_id",
5751
+ coerce: coerceString
5752
+ }
5753
+ ];
5754
+ var TOPLEVEL_SENTINELS = [
5755
+ {
5756
+ property: "$session_id",
5757
+ field: "session_id"
5758
+ },
5759
+ {
5760
+ property: "$window_id",
5761
+ field: "window_id"
5762
+ }
5763
+ ];
5764
+ function isRecord2(value) {
5765
+ return typeof value == "object" && value !== null && !Array.isArray(value);
5766
+ }
5767
+ function toRfc3339(timestamp) {
5768
+ if (typeof timestamp == "string") {
5769
+ const asDate2 = new Date(timestamp);
5770
+ if (Number.isNaN(asDate2.getTime()))
5771
+ return new Date().toISOString();
5772
+ const normalized = asDate2.toISOString();
5773
+ const fractionalSeconds = timestamp.match(/\.(\d+)(?:Z|[+-]\d{2}:?\d{2})?$/i)?.[1];
5774
+ return fractionalSeconds && fractionalSeconds.length > 3 ? normalized.replace(/\.\d{3}Z$/, `.${fractionalSeconds}Z`) : normalized;
5775
+ }
5776
+ if (timestamp instanceof Date)
5777
+ return Number.isNaN(timestamp.getTime()) ? new Date().toISOString() : timestamp.toISOString();
5778
+ const asDate = timestamp == null ? new Date : new Date(timestamp);
5779
+ return Number.isNaN(asDate.getTime()) ? new Date().toISOString() : asDate.toISOString();
5780
+ }
5781
+ function relocateInto(properties, key, value) {
5782
+ if (value !== undefined && !(key in properties))
5783
+ properties[key] = value;
5784
+ }
5785
+ function buildV1Event(message) {
5786
+ const sourceProperties = isRecord2(message.properties) ? message.properties : {};
5787
+ const properties = {
5788
+ ...sourceProperties
5789
+ };
5790
+ const options = {};
5791
+ for (const { property, optionKey, coerce } of OPTION_SENTINELS)
5792
+ if (property in properties) {
5793
+ const coerced = coerce(properties[property]);
5794
+ if (coerced !== undefined)
5795
+ options[optionKey] = coerced;
5796
+ delete properties[property];
5797
+ }
5798
+ const topLevel = {};
5799
+ for (const { property, field } of TOPLEVEL_SENTINELS)
5800
+ if (property in properties) {
5801
+ const value = properties[property];
5802
+ if (typeof value == "string")
5803
+ topLevel[field] = value;
5804
+ delete properties[property];
5805
+ }
5806
+ delete properties.$lib;
5807
+ delete properties.$lib_version;
5808
+ relocateInto(properties, "$set", message.$set);
5809
+ relocateInto(properties, "$set_once", message.$set_once);
5810
+ return {
5811
+ event: String(message.event ?? ""),
5812
+ uuid: String(message.uuid ?? ""),
5813
+ distinct_id: String(message.distinct_id ?? ""),
5814
+ timestamp: toRfc3339(message.timestamp),
5815
+ ...topLevel,
5816
+ options,
5817
+ properties
5818
+ };
5819
+ }
5820
+ function buildV1Batch(messages, { createdAt, historicalMigration }) {
5821
+ const batch = {
5822
+ created_at: createdAt,
5823
+ batch: messages.map(buildV1Event)
5824
+ };
5825
+ if (historicalMigration)
5826
+ batch.historical_migration = true;
5827
+ return batch;
5828
+ }
5829
+
5830
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/capture-v1/sender.mjs
5831
+ var V1_ANALYTICS_PATH = "/i/v1/analytics/events";
5832
+ var DEFAULT_MAX_BACKOFF_MS = 30000;
5833
+ var RETRYABLE_STATUSES = new Set([
5834
+ 408,
5835
+ 500,
5836
+ 502,
5837
+ 503,
5838
+ 504
5839
+ ]);
5840
+
5841
+ class V1CaptureSender {
5842
+ constructor(config, hooks) {
5843
+ this.config = config;
5844
+ this.maxBackoffMs = config.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
5845
+ this.fetchFn = hooks.fetch;
5846
+ this.onError = hooks.onError;
5847
+ this.now = hooks.now ?? Date.now;
5848
+ this.sleep = hooks.sleep ?? ((ms) => new Promise((resolve) => safeSetTimeout(resolve, ms)));
5849
+ this.generateRequestId = hooks.generateRequestId ?? uuidv7;
5850
+ this.compress = hooks.compress ?? gzipCompress;
5851
+ }
5852
+ async sendV1Batch(messages) {
5853
+ if (messages.length === 0)
5854
+ return;
5855
+ const requestId = this.generateRequestId();
5856
+ const createdAt = new Date(this.now()).toISOString();
5857
+ const { batch } = buildV1Batch(messages, {
5858
+ createdAt,
5859
+ historicalMigration: this.config.historicalMigration
5860
+ });
5861
+ const url = `${this.config.host}${V1_ANALYTICS_PATH}`;
5862
+ const drops = [];
5863
+ let pending = batch;
5864
+ const maxAttempts = Math.max(1, this.config.maxAttempts);
5865
+ for (let attempt = 1;attempt <= maxAttempts; attempt++) {
5866
+ const isLastAttempt = attempt === maxAttempts;
5867
+ const payload = safeJsonStringify({
5868
+ created_at: createdAt,
5869
+ ...this.config.historicalMigration ? {
5870
+ historical_migration: true
5871
+ } : {},
5872
+ batch: pending
5873
+ });
5874
+ let captureAttempt;
5875
+ let retryDelayMs;
5876
+ try {
5877
+ captureAttempt = await this.sendOnce(url, payload, attempt, requestId);
5878
+ const { response, signal } = captureAttempt;
5879
+ const { status } = response;
5880
+ if (status < 200 || status >= 300)
5881
+ if (!isLastAttempt && RETRYABLE_STATUSES.has(status)) {
5882
+ const retryAfterMs = this.parseRetryAfter(response);
5883
+ await captureAttempt.waitFor(captureAttempt.cancelBody()).catch(() => {});
5884
+ retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
5885
+ } else {
5886
+ const httpError = await this.buildHttpError(response, status, captureAttempt.waitFor);
5887
+ return this.surfaceBatchFailure(requestId, drops, pending, httpError);
5888
+ }
5889
+ else {
5890
+ let parsed;
5891
+ try {
5892
+ parsed = await captureAttempt.waitFor(this.parseResponse(response));
5893
+ } catch (error) {
5894
+ if (signal.aborted)
5895
+ throw error;
5896
+ return this.surfaceBatchFailure(requestId, drops, pending, new Error(`Capture V1 returned an unparseable ${status} response body`));
5897
+ }
5898
+ const retryable = this.classify(pending, parsed, drops);
5899
+ if (retryable.length === 0)
5900
+ return this.surfacePartialDrops(requestId, drops);
5901
+ if (isLastAttempt)
5902
+ return void this.onError(new CaptureV1Error({
5903
+ requestId,
5904
+ drops,
5905
+ retryExhausted: retryable.map((event) => event.uuid)
5906
+ }));
5907
+ pending = retryable;
5908
+ const retryAfterMs = this.parseRetryAfter(response);
5909
+ retryDelayMs = this.backoffDelay(attempt, retryAfterMs);
5910
+ }
5911
+ } catch (transportError) {
5912
+ if (captureAttempt && !captureAttempt.signal.aborted)
5913
+ throw transportError;
5914
+ if (isLastAttempt)
5915
+ return this.surfaceBatchFailure(requestId, drops, pending, transportError);
5916
+ retryDelayMs = this.backoffDelay(attempt);
5917
+ } finally {
5918
+ captureAttempt?.cleanup();
5919
+ }
5920
+ if (retryDelayMs !== undefined)
5921
+ await this.sleep(retryDelayMs);
5922
+ }
5923
+ }
5924
+ async sendOnce(url, payload, attempt, requestId) {
5925
+ const headers = this.buildHeaders(attempt, requestId);
5926
+ let body = payload;
5927
+ if (this.config.compressionEnabled) {
5928
+ const compressed = await this.compress(payload, this.config.isDebug);
5929
+ if (compressed !== null) {
5930
+ body = compressed;
5931
+ headers["Content-Encoding"] = "gzip";
5932
+ }
5933
+ }
5934
+ const controller = new AbortController;
5935
+ let timeoutPhase = "waiting for response headers";
5936
+ let timer;
5937
+ const deadline = new Promise((_resolve, reject) => {
5938
+ timer = safeSetTimeout(() => {
5939
+ const timeoutError = new Error(`Capture V1 request timed out ${timeoutPhase} after ${this.config.requestTimeoutMs}ms`);
5940
+ timeoutError.name = "AbortError";
5941
+ reject(timeoutError);
5942
+ controller.abort(timeoutError);
5943
+ }, this.config.requestTimeoutMs);
5944
+ });
5945
+ try {
5946
+ const fetchPromise = this.fetchFn(url, {
5947
+ method: "POST",
5948
+ headers,
5949
+ body,
5950
+ signal: controller.signal
5951
+ });
5952
+ let responseAccepted = false;
5953
+ fetchPromise.then((lateResponse) => {
5954
+ if (controller.signal.aborted && !responseAccepted)
5955
+ this.cancelBody(lateResponse);
5956
+ }).catch(() => {});
5957
+ const response = await Promise.race([
5958
+ fetchPromise,
5959
+ deadline
5960
+ ]);
5961
+ responseAccepted = true;
5962
+ timeoutPhase = "while reading the response body";
5963
+ let cleanedUp = false;
5964
+ let cancellation;
5965
+ const cancelBody = () => cancellation ??= this.cancelBody(response);
5966
+ return {
5967
+ response,
5968
+ signal: controller.signal,
5969
+ waitFor: (operation) => Promise.race([
5970
+ operation,
5971
+ deadline
5972
+ ]),
5973
+ cancelBody,
5974
+ cleanup: () => {
5975
+ if (cleanedUp)
5976
+ return;
5977
+ cleanedUp = true;
5978
+ clearTimeout(timer);
5979
+ if (controller.signal.aborted)
5980
+ cancelBody();
5981
+ }
5982
+ };
5983
+ } catch (error) {
5984
+ clearTimeout(timer);
5985
+ throw error;
5986
+ }
5987
+ }
5988
+ buildHeaders(attempt, requestId) {
5989
+ const sdkInfo = `${this.config.libraryId}/${this.config.libraryVersion}`;
5990
+ const headers = {
5991
+ "Content-Type": "application/json",
5992
+ Authorization: `Bearer ${this.config.apiKey}`,
5993
+ "PostHog-Sdk-Info": sdkInfo,
5994
+ "PostHog-Attempt": String(attempt),
5995
+ "PostHog-Request-Id": requestId,
5996
+ "PostHog-Request-Timestamp": new Date(this.now()).toISOString()
5997
+ };
5998
+ if (this.config.userAgent)
5999
+ headers["User-Agent"] = this.config.userAgent;
6000
+ return headers;
6001
+ }
6002
+ classify(pending, parsed, drops) {
6003
+ const results = parsed.results ?? {};
6004
+ const retryable = [];
6005
+ for (const event of pending) {
6006
+ const result = results[event.uuid];
6007
+ if (result) {
6008
+ if (result.result === "drop")
6009
+ drops.push({
6010
+ uuid: event.uuid,
6011
+ details: result.details ?? undefined
6012
+ });
6013
+ else if (result.result === "retry")
6014
+ retryable.push(event);
6015
+ }
6016
+ }
6017
+ return retryable;
6018
+ }
6019
+ backoffDelay(attempt, retryAfterMs) {
6020
+ const exponential = Math.min(this.config.initialRetryDelayMs * 2 ** (attempt - 1), this.maxBackoffMs);
6021
+ if (retryAfterMs === undefined)
6022
+ return exponential;
6023
+ return Math.max(exponential, Math.min(retryAfterMs, this.maxBackoffMs));
6024
+ }
6025
+ parseRetryAfter(response) {
6026
+ const raw = response.headers?.get("Retry-After");
6027
+ if (!raw)
6028
+ return;
6029
+ const trimmed = raw.trim();
6030
+ if (/^\d+$/.test(trimmed)) {
6031
+ const seconds = parseInt(trimmed, 10);
6032
+ return Number.isFinite(seconds) && seconds > 0 ? 1000 * seconds : undefined;
6033
+ }
6034
+ const dateMs = Date.parse(trimmed);
6035
+ if (Number.isNaN(dateMs))
6036
+ return;
6037
+ const delta = dateMs - this.now();
6038
+ return delta > 0 ? delta : undefined;
6039
+ }
6040
+ async parseResponse(response) {
6041
+ const text = await response.text();
6042
+ const parsed = JSON.parse(text);
6043
+ if (typeof parsed != "object" || parsed === null || Array.isArray(parsed))
6044
+ throw new Error("unexpected response shape");
6045
+ const results = parsed.results;
6046
+ if (results !== undefined && (typeof results != "object" || results === null || Array.isArray(results)))
6047
+ throw new Error("unexpected results shape");
6048
+ return {
6049
+ results: results ?? {}
6050
+ };
6051
+ }
6052
+ async buildHttpError(response, status, waitFor) {
6053
+ let bodyText = "";
6054
+ try {
6055
+ bodyText = (await waitFor(response.text())).slice(0, 512);
6056
+ } catch {}
6057
+ const suffix = bodyText ? `: ${bodyText}` : "";
6058
+ return new Error(`Capture V1 request failed with HTTP ${status}${suffix}`);
6059
+ }
6060
+ surfaceBatchFailure(requestId, drops, pending, cause) {
6061
+ this.onError(new CaptureV1Error({
6062
+ requestId,
6063
+ drops,
6064
+ retryExhausted: pending.map((event) => event.uuid),
6065
+ cause
6066
+ }));
6067
+ }
6068
+ surfacePartialDrops(requestId, drops) {
6069
+ if (drops.length > 0)
6070
+ this.onError(new CaptureV1Error({
6071
+ requestId,
6072
+ drops,
6073
+ retryExhausted: []
6074
+ }));
6075
+ }
6076
+ async cancelBody(response) {
6077
+ try {
6078
+ await response.body?.cancel();
6079
+ } catch {}
6080
+ }
6081
+ }
6082
+
6083
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/ai-capture/routing.mjs
6084
+ var AI_CAPTURE_ROUTE = "ai-capture";
6085
+ var AI_CAPTURE_ENDPOINT_PATH = "/i/v0/ai/batch/";
6086
+ var AI_MAX_EVENT_BYTES = 8388608;
6087
+ var AI_BATCH_TARGET_BYTES = 5242880;
6088
+
6089
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/ai-capture/batching.mjs
6090
+ var encoder = new TextEncoder;
6091
+ function eventByteSize(message) {
6092
+ return encoder.encode(safeJsonStringify(message)).length;
6093
+ }
6094
+ function partitionAiBatch(messages, maxEventBytes = AI_MAX_EVENT_BYTES, targetBatchBytes = AI_BATCH_TARGET_BYTES) {
6095
+ const batches = [];
6096
+ const dropped = [];
6097
+ let current = [];
6098
+ let currentBytes = 0;
6099
+ for (const message of messages) {
6100
+ if (message === undefined)
6101
+ continue;
6102
+ const bytes = eventByteSize(message);
6103
+ if (bytes > maxEventBytes) {
6104
+ dropped.push({
6105
+ event: typeof message.event == "string" ? message.event : "unknown",
6106
+ bytes
6107
+ });
6108
+ continue;
6109
+ }
6110
+ if (current.length > 0 && currentBytes + bytes > targetBatchBytes) {
6111
+ batches.push(current);
6112
+ current = [];
6113
+ currentBytes = 0;
6114
+ }
6115
+ current.push(message);
6116
+ currentBytes += bytes;
6117
+ }
6118
+ if (current.length > 0)
6119
+ batches.push(current);
6120
+ return {
6121
+ batches,
6122
+ dropped
6123
+ };
6124
+ }
6125
+
6126
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/client.mjs
4392
6127
  var MINIMUM_POLLING_INTERVAL = 100;
4393
6128
  var THIRTY_SECONDS = 30000;
4394
6129
  var MAX_CACHE_SIZE = 50000;
@@ -4413,6 +6148,12 @@ function normalizeHost(value) {
4413
6148
  const normalizedValue = typeof value == "string" ? value.trim() : "";
4414
6149
  return normalizedValue || DEFAULT_NODE_HOST;
4415
6150
  }
6151
+ function normalizeUnsetPersonProperties(value) {
6152
+ const propertyNames = Array.isArray(value) ? value : [
6153
+ value
6154
+ ];
6155
+ return propertyNames.filter((propertyName) => typeof propertyName == "string" && propertyName.trim().length > 0);
6156
+ }
4416
6157
  function buildFlagEventProperties(flagValues) {
4417
6158
  if (!flagValues)
4418
6159
  return {};
@@ -4430,11 +6171,15 @@ class PostHogBackendClient extends PostHogCoreStateless {
4430
6171
  const normalizedApiKey = normalizeApiKey(apiKey);
4431
6172
  const normalizedOptions = {
4432
6173
  ...options,
6174
+ maxQueueSize: options.maxQueueSize ?? 1e4,
6175
+ flushInterval: options.flushInterval ?? 5000,
4433
6176
  host: normalizeHost(options.host),
4434
- personalApiKey: normalizePersonalApiKey(options.personalApiKey)
6177
+ personalApiKey: normalizePersonalApiKey(options.secretKey ?? options.personalApiKey)
4435
6178
  };
4436
- super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage;
6179
+ super(normalizedApiKey, normalizedOptions), this._memoryStorage = new PostHogMemoryStorage, this._aiCaptureRouteActive = false, this._minimalFlagCalledEvents = false;
4437
6180
  this.options = normalizedOptions;
6181
+ this.captureMode = resolveCaptureMode();
6182
+ this.enableFullAiCapture = normalizedOptions.enableFullAiCapture === true;
4438
6183
  this.context = this.initializeContext();
4439
6184
  this.options.featureFlagsPollingInterval = typeof normalizedOptions.featureFlagsPollingInterval == "number" ? Math.max(normalizedOptions.featureFlagsPollingInterval, MINIMUM_POLLING_INTERVAL) : THIRTY_SECONDS;
4440
6185
  if (typeof normalizedOptions.waitUntilDebounceMs == "number")
@@ -4459,21 +6204,24 @@ class PostHogBackendClient extends PostHogCoreStateless {
4459
6204
  onLoad: (count) => {
4460
6205
  this._events.emit("localEvaluationFlagsLoaded", count);
4461
6206
  },
6207
+ onMinimalFlagCalledEvents: (enabled) => {
6208
+ this._minimalFlagCalledEvents = enabled;
6209
+ },
4462
6210
  customHeaders: this.getCustomHeaders(),
4463
6211
  cacheProvider: normalizedOptions.flagDefinitionCacheProvider,
4464
6212
  strictLocalEvaluation: normalizedOptions.strictLocalEvaluation
4465
6213
  });
4466
6214
  }
4467
- this.errorTracking = new ErrorTracking(this, normalizedOptions, this._logger);
6215
+ this.errorTracking = new error_tracking_ErrorTracking(this, normalizedOptions, this._logger);
4468
6216
  this.distinctIdHasSentFlagCalls = {};
4469
6217
  this.maxCacheSize = normalizedOptions.maxCacheSize || MAX_CACHE_SIZE;
4470
6218
  }
4471
- enqueue(type, message, options) {
4472
- super.enqueue(type, message, options);
6219
+ enqueue(type, message, options, explicitRoute) {
6220
+ super.enqueue(type, message, options, explicitRoute);
4473
6221
  this.scheduleDebouncedFlush();
4474
6222
  }
4475
6223
  async flush() {
4476
- const flushPromise = super.flush();
6224
+ const flushPromise = this.flushWithPendingPromises();
4477
6225
  const waitUntil = this.options.waitUntil;
4478
6226
  if (waitUntil && !this._waitUntilCycle)
4479
6227
  try {
@@ -4526,7 +6274,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4526
6274
  async resolveWaitUntilFlush() {
4527
6275
  const resolve = this._consumeWaitUntilCycle();
4528
6276
  try {
4529
- await super.flush();
6277
+ await this.flushWithPendingPromises();
4530
6278
  } catch {} finally {
4531
6279
  resolve?.();
4532
6280
  }
@@ -4540,12 +6288,103 @@ class PostHogBackendClient extends PostHogCoreStateless {
4540
6288
  fetch(url, options) {
4541
6289
  return this.options.fetch ? this.options.fetch(url, options) : fetch(url, options);
4542
6290
  }
6291
+ getQueueRouteKey(message) {
6292
+ return this.captureMode === "v1" && isLegacyOnlyEvent(message) ? AI_ROUTE : ANALYTICS_ROUTE;
6293
+ }
6294
+ persistedQueueKeyForRoute(route) {
6295
+ if (route === AI_CAPTURE_ROUTE)
6296
+ return types_PostHogPersistedProperty.AiCaptureQueue;
6297
+ return route === AI_ROUTE ? types_PostHogPersistedProperty.AiQueue : types_PostHogPersistedProperty.Queue;
6298
+ }
6299
+ getActiveQueueRoutes() {
6300
+ const routes = this.captureMode === "v1" ? [
6301
+ ANALYTICS_ROUTE,
6302
+ AI_ROUTE
6303
+ ] : [
6304
+ ANALYTICS_ROUTE
6305
+ ];
6306
+ if (this._aiCaptureRouteActive)
6307
+ routes.push(AI_CAPTURE_ROUTE);
6308
+ return routes;
6309
+ }
6310
+ getBatchEndpointPath(route) {
6311
+ return route === AI_CAPTURE_ROUTE ? AI_CAPTURE_ENDPOINT_PATH : super.getBatchEndpointPath(route);
6312
+ }
6313
+ async sendBatch(batchMessages, retryOptions, route = ANALYTICS_ROUTE) {
6314
+ if (route === AI_CAPTURE_ROUTE)
6315
+ return this.sendAiCaptureBatch(batchMessages, retryOptions);
6316
+ if (this.captureMode !== "v1" || route === AI_ROUTE)
6317
+ return super.sendBatch(batchMessages, retryOptions, route);
6318
+ const v1Events = batchMessages.filter((message) => message !== undefined);
6319
+ await this.getV1Sender().sendV1Batch(v1Events);
6320
+ }
6321
+ async sendAiCaptureBatch(batchMessages, retryOptions) {
6322
+ const { batches, dropped } = partitionAiBatch(batchMessages);
6323
+ for (const { event, bytes } of dropped) {
6324
+ const message = `Event ${event} (${bytes} bytes) exceeds the ${AI_MAX_EVENT_BYTES / 1048576}MiB limit for ${AI_CAPTURE_ENDPOINT_PATH}, dropping.`;
6325
+ this._logger.error(message);
6326
+ this._events.emit("error", new Error(message));
6327
+ }
6328
+ for (const batch of batches)
6329
+ await this.sendAiSubBatch(batch, retryOptions);
6330
+ }
6331
+ async sendAiSubBatch(batch, retryOptions) {
6332
+ try {
6333
+ await super.sendBatch(batch, retryOptions, AI_CAPTURE_ROUTE);
6334
+ } catch (err) {
6335
+ if (!isPostHogFetchContentTooLargeError(err))
6336
+ throw err;
6337
+ if (batch.length === 1) {
6338
+ const [event] = batch;
6339
+ const eventName = typeof event.event == "string" ? event.event : "unknown";
6340
+ const message = `Event ${eventName} (${eventByteSize(event)} bytes) was rejected with 413 by ${AI_CAPTURE_ENDPOINT_PATH} on its own, dropping.`;
6341
+ this._logger.error(message);
6342
+ this._events.emit("error", new Error(message));
6343
+ return;
6344
+ }
6345
+ const mid = Math.ceil(batch.length / 2);
6346
+ await this.sendAiSubBatch(batch.slice(0, mid), retryOptions);
6347
+ await this.sendAiSubBatch(batch.slice(mid), retryOptions);
6348
+ }
6349
+ }
6350
+ getV1Sender() {
6351
+ if (!this._v1Sender)
6352
+ this._v1Sender = new V1CaptureSender({
6353
+ host: this.host,
6354
+ apiKey: this.apiKey,
6355
+ libraryId: this.getLibraryId(),
6356
+ libraryVersion: this.getLibraryVersion(),
6357
+ userAgent: this.getCustomUserAgent() || undefined,
6358
+ historicalMigration: this.historicalMigration,
6359
+ compressionEnabled: !this.disableCompression,
6360
+ requestTimeoutMs: this.requestTimeout,
6361
+ maxAttempts: (this.options.fetchRetryCount ?? 3) + 1,
6362
+ initialRetryDelayMs: this.options.fetchRetryDelay ?? 3000,
6363
+ isDebug: this.isDebug
6364
+ }, {
6365
+ fetch: (url, fetchOptions) => this.fetch(url, fetchOptions),
6366
+ onError: (error) => this._events.emit("error", error),
6367
+ compress: (payload) => this.compressPayload(payload)
6368
+ });
6369
+ return this._v1Sender;
6370
+ }
4543
6371
  getLibraryVersion() {
4544
6372
  return version;
4545
6373
  }
6374
+ get metrics() {
6375
+ if (!this._metrics)
6376
+ this._metrics = new PostHogMetrics(this, resolveMetricsConfig(this.options.metrics), this._logger);
6377
+ return this._metrics;
6378
+ }
4546
6379
  getCustomUserAgent() {
4547
6380
  return `${this.getLibraryId()}/${this.getLibraryVersion()}`;
4548
6381
  }
6382
+ getCommonEventProperties() {
6383
+ const commonProperties = super.getCommonEventProperties();
6384
+ if (this.options.isServer ?? true)
6385
+ commonProperties.$is_server = true;
6386
+ return commonProperties;
6387
+ }
4549
6388
  enable() {
4550
6389
  return super.optIn();
4551
6390
  }
@@ -4556,33 +6395,69 @@ class PostHogBackendClient extends PostHogCoreStateless {
4556
6395
  super.debug(enabled);
4557
6396
  this.featureFlagsPoller?.debug(enabled);
4558
6397
  }
4559
- capture(props) {
6398
+ _warnIfInvalidCapture(props, stringArgumentWarning, exceptionCaptureWarning) {
4560
6399
  if (typeof props == "string")
4561
- this._logger.warn("Called capture() with a string as the first argument when an object was expected.");
6400
+ this._logger.warn(stringArgumentWarning);
4562
6401
  if (props.event === "$exception" && !props._originatedFromCaptureException)
4563
- 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.");
4564
- this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStateless(distinctId, event, properties, {
4565
- timestamp: options.timestamp,
4566
- disableGeoip: options.disableGeoip,
4567
- uuid: options.uuid
4568
- })).catch((err) => {
6402
+ this._logger.warn(exceptionCaptureWarning);
6403
+ }
6404
+ _sendPreparedEvent(type, props, immediate, prepareOptions, explicitRoute) {
6405
+ return this.addPendingPromise(this._prepareEventMessage(props, prepareOptions).then(({ distinctId, event, properties, options }) => {
6406
+ const captureOptions = {
6407
+ timestamp: options.timestamp,
6408
+ disableGeoip: options.disableGeoip,
6409
+ uuid: options.uuid
6410
+ };
6411
+ const message = {
6412
+ distinctId,
6413
+ event,
6414
+ properties: {
6415
+ ...properties,
6416
+ ...this.getCommonEventProperties()
6417
+ }
6418
+ };
6419
+ return immediate ? this.sendImmediate(type, message, captureOptions, explicitRoute) : this.enqueue(type, message, captureOptions, explicitRoute);
6420
+ }).catch((err) => {
4569
6421
  if (err)
4570
6422
  console.error(err);
4571
6423
  }));
4572
6424
  }
6425
+ _capturePreparedEvent(props, immediate) {
6426
+ return this._sendPreparedEvent("capture", props, immediate);
6427
+ }
6428
+ capture(props) {
6429
+ 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.");
6430
+ this._capturePreparedEvent(props, false);
6431
+ }
4573
6432
  async captureImmediate(props) {
4574
- if (typeof props == "string")
4575
- this._logger.warn("Called captureImmediate() with a string as the first argument when an object was expected.");
4576
- if (props.event === "$exception" && !props._originatedFromCaptureException)
4577
- 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.");
4578
- return this.addPendingPromise(this.prepareEventMessage(props).then(({ distinctId, event, properties, options }) => super.captureStatelessImmediate(distinctId, event, properties, {
4579
- timestamp: options.timestamp,
4580
- disableGeoip: options.disableGeoip,
4581
- uuid: options.uuid
4582
- })).catch((err) => {
4583
- if (err)
4584
- console.error(err);
4585
- }));
6433
+ 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.");
6434
+ return this._capturePreparedEvent(props, true);
6435
+ }
6436
+ captureAi(props) {
6437
+ if (this.disabled)
6438
+ return;
6439
+ const uuid = getEventUuid(props.uuid, uuidv7);
6440
+ this._sendPreparedAiEvent({
6441
+ ...props,
6442
+ uuid
6443
+ }, false);
6444
+ return uuid;
6445
+ }
6446
+ async captureAiImmediate(props) {
6447
+ if (this.disabled)
6448
+ return;
6449
+ const uuid = getEventUuid(props.uuid, uuidv7);
6450
+ await this._sendPreparedAiEvent({
6451
+ ...props,
6452
+ uuid
6453
+ }, true);
6454
+ return uuid;
6455
+ }
6456
+ _sendPreparedAiEvent(props, immediate) {
6457
+ if (typeof props?.event == "string" && !props.event.startsWith("$ai_"))
6458
+ this._logger.debug(`captureAi called with non-AI event ${props.event}; routing it to the AI endpoint anyway.`);
6459
+ this._aiCaptureRouteActive = true;
6460
+ return this._sendPreparedEvent("capture", props, immediate, undefined, AI_CAPTURE_ROUTE);
4586
6461
  }
4587
6462
  identify({ distinctId, properties = {}, disableGeoip }) {
4588
6463
  const { $set, $set_once, $anon_distinct_id, ...rest } = properties;
@@ -4593,8 +6468,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
4593
6468
  $set_once: setOnceProps,
4594
6469
  $anon_distinct_id: $anon_distinct_id ?? undefined
4595
6470
  };
4596
- super.identifyStateless(distinctId, eventProperties, {
6471
+ this._sendPreparedEvent("identify", {
6472
+ distinctId,
6473
+ event: "$identify",
6474
+ properties: eventProperties,
4597
6475
  disableGeoip
6476
+ }, false, {
6477
+ includeContextProperties: false
4598
6478
  });
4599
6479
  }
4600
6480
  async identifyImmediate({ distinctId, properties = {}, disableGeoip }) {
@@ -4606,18 +6486,65 @@ class PostHogBackendClient extends PostHogCoreStateless {
4606
6486
  $set_once: setOnceProps,
4607
6487
  $anon_distinct_id: $anon_distinct_id ?? undefined
4608
6488
  };
4609
- await super.identifyStatelessImmediate(distinctId, eventProperties, {
6489
+ await this._sendPreparedEvent("identify", {
6490
+ distinctId,
6491
+ event: "$identify",
6492
+ properties: eventProperties,
4610
6493
  disableGeoip
6494
+ }, true, {
6495
+ includeContextProperties: false
6496
+ });
6497
+ }
6498
+ setPersonProperties({ distinctId, properties = {}, propertiesOnce = {} }) {
6499
+ if (Object.keys(properties).length === 0 && Object.keys(propertiesOnce).length === 0)
6500
+ return;
6501
+ const eventProperties = {};
6502
+ if (Object.keys(properties).length > 0)
6503
+ eventProperties.$set = properties;
6504
+ if (Object.keys(propertiesOnce).length > 0)
6505
+ eventProperties.$set_once = propertiesOnce;
6506
+ this.capture({
6507
+ distinctId,
6508
+ event: "$set",
6509
+ properties: eventProperties
6510
+ });
6511
+ }
6512
+ unsetPersonProperties({ distinctId, properties }) {
6513
+ const propertyNames = normalizeUnsetPersonProperties(properties);
6514
+ if (propertyNames.length === 0)
6515
+ return;
6516
+ this.capture({
6517
+ distinctId,
6518
+ event: "$set",
6519
+ properties: {
6520
+ $unset: propertyNames
6521
+ }
4611
6522
  });
4612
6523
  }
4613
6524
  alias(data) {
4614
- super.aliasStateless(data.alias, data.distinctId, undefined, {
6525
+ this._sendPreparedEvent("alias", {
6526
+ distinctId: data.distinctId,
6527
+ event: "$create_alias",
6528
+ properties: {
6529
+ distinct_id: data.distinctId,
6530
+ alias: data.alias
6531
+ },
4615
6532
  disableGeoip: data.disableGeoip
6533
+ }, false, {
6534
+ includeContextProperties: false
4616
6535
  });
4617
6536
  }
4618
6537
  async aliasImmediate(data) {
4619
- await super.aliasStatelessImmediate(data.alias, data.distinctId, undefined, {
6538
+ await this._sendPreparedEvent("alias", {
6539
+ distinctId: data.distinctId,
6540
+ event: "$create_alias",
6541
+ properties: {
6542
+ distinct_id: data.distinctId,
6543
+ alias: data.alias
6544
+ },
4620
6545
  disableGeoip: data.disableGeoip
6546
+ }, true, {
6547
+ includeContextProperties: false
4621
6548
  });
4622
6549
  }
4623
6550
  isLocalEvaluationReady() {
@@ -4672,7 +6599,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4672
6599
  const adjustedProperties = this.addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties);
4673
6600
  personProperties = adjustedProperties.allPersonProperties;
4674
6601
  groupProperties = adjustedProperties.allGroupProperties;
4675
- const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties);
6602
+ const evaluationContext = this.createFeatureFlagEvaluationContext(distinctId, groups, this.personPropertiesForLocalEvaluation(distinctId, personProperties), groupProperties);
4676
6603
  if (onlyEvaluateLocally == undefined)
4677
6604
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
4678
6605
  let result;
@@ -4683,6 +6610,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4683
6610
  let flagId;
4684
6611
  let flagVersion;
4685
6612
  let flagReason;
6613
+ let flagHasExperiment;
4686
6614
  const localEvaluationEnabled = this.featureFlagsPoller !== undefined;
4687
6615
  if (localEvaluationEnabled) {
4688
6616
  await this.featureFlagsPoller?.loadFeatureFlags();
@@ -4697,6 +6625,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4697
6625
  const value = localResult.value;
4698
6626
  flagId = flag.id;
4699
6627
  flagReason = "Evaluated locally";
6628
+ flagHasExperiment = flag.has_experiment;
4700
6629
  result = {
4701
6630
  key,
4702
6631
  enabled: value !== false,
@@ -4712,12 +6641,13 @@ class PostHogBackendClient extends PostHogCoreStateless {
4712
6641
  }
4713
6642
  }
4714
6643
  if (!flagWasLocallyEvaluated && !onlyEvaluateLocally) {
4715
- const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, [
6644
+ const flagsResponse = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, [
4716
6645
  key
4717
6646
  ]);
4718
6647
  if (flagsResponse === undefined)
4719
6648
  featureFlagError = FeatureFlagError2.UNKNOWN_ERROR;
4720
6649
  else {
6650
+ this._minimalFlagCalledEvents = flagsResponse.minimalFlagCalledEvents === true;
4721
6651
  requestId = flagsResponse.requestId;
4722
6652
  evaluatedAt = flagsResponse.evaluatedAt;
4723
6653
  const errors = [];
@@ -4732,6 +6662,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4732
6662
  flagId = flagDetail.metadata?.id;
4733
6663
  flagVersion = flagDetail.metadata?.version;
4734
6664
  flagReason = flagDetail.reason?.description ?? flagDetail.reason?.code;
6665
+ flagHasExperiment = flagDetail.metadata?.has_experiment;
4735
6666
  let parsedPayload;
4736
6667
  if (flagDetail.metadata?.payload !== undefined)
4737
6668
  try {
@@ -4742,7 +6673,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4742
6673
  result = {
4743
6674
  key,
4744
6675
  enabled: flagDetail.enabled,
4745
- variant: flagDetail.variant,
6676
+ variant: flagDetail.variant ?? undefined,
4746
6677
  payload: parsedPayload
4747
6678
  };
4748
6679
  }
@@ -4763,6 +6694,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
4763
6694
  $feature_flag_request_id: requestId,
4764
6695
  $feature_flag_evaluated_at: flagWasLocallyEvaluated ? Date.now() : evaluatedAt
4765
6696
  };
6697
+ if (flagHasExperiment !== undefined)
6698
+ properties.$feature_flag_has_experiment = flagHasExperiment;
4766
6699
  if (flagWasLocallyEvaluated && this.featureFlagsPoller) {
4767
6700
  const flagDefinitionsLoadedAt = this.featureFlagsPoller.getFlagDefinitionsLoadedAt();
4768
6701
  if (flagDefinitionsLoadedAt !== undefined)
@@ -4877,7 +6810,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4877
6810
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
4878
6811
  personProperties = adjustedProperties.allPersonProperties;
4879
6812
  groupProperties = adjustedProperties.allGroupProperties;
4880
- const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
6813
+ const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
4881
6814
  if (onlyEvaluateLocally == undefined)
4882
6815
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
4883
6816
  const localEvaluationResult = await this.featureFlagsPoller?.getAllFlagsAndPayloads(evaluationContext, flagKeys);
@@ -4890,7 +6823,7 @@ class PostHogBackendClient extends PostHogCoreStateless {
4890
6823
  fallbackToFlags = localEvaluationResult.fallbackToFlags;
4891
6824
  }
4892
6825
  if (fallbackToFlags && !onlyEvaluateLocally) {
4893
- const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, flagKeys);
6826
+ const remoteEvaluationResult = await super.getFeatureFlagsAndPayloadsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
4894
6827
  featureFlags = {
4895
6828
  ...featureFlags,
4896
6829
  ...remoteEvaluationResult.flags || {}
@@ -4938,9 +6871,10 @@ class PostHogBackendClient extends PostHogCoreStateless {
4938
6871
  const adjustedProperties = this.addLocalPersonAndGroupProperties(resolvedDistinctId, groups, personProperties, groupProperties);
4939
6872
  personProperties = adjustedProperties.allPersonProperties;
4940
6873
  groupProperties = adjustedProperties.allGroupProperties;
4941
- const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, personProperties, groupProperties);
6874
+ const evaluationContext = this.createFeatureFlagEvaluationContext(resolvedDistinctId, groups, this.personPropertiesForLocalEvaluation(resolvedDistinctId, personProperties), groupProperties);
4942
6875
  if (onlyEvaluateLocally == undefined)
4943
6876
  onlyEvaluateLocally = this.options.strictLocalEvaluation ?? false;
6877
+ const requestedFlagKeys = flagKeys ? new Set(flagKeys) : undefined;
4944
6878
  const records = {};
4945
6879
  let requestId;
4946
6880
  let evaluatedAt;
@@ -4959,14 +6893,17 @@ class PostHogBackendClient extends PostHogCoreStateless {
4959
6893
  id: flagDef?.id,
4960
6894
  version: undefined,
4961
6895
  reason: "Evaluated locally",
4962
- locallyEvaluated: true
6896
+ locallyEvaluated: true,
6897
+ hasExperiment: flagDef?.has_experiment
4963
6898
  };
4964
6899
  locallyEvaluatedKeys.add(key);
4965
6900
  }
4966
- const fallbackToFlags = localResult ? localResult.fallbackToFlags : true;
6901
+ const requestedFlagMissingLocally = requestedFlagKeys !== undefined && Array.from(requestedFlagKeys).some((key) => this.featureFlagsPoller?.featureFlagsByKey[key] === undefined);
6902
+ const fallbackToFlags = localResult ? localResult.fallbackToFlags || requestedFlagMissingLocally : true;
4967
6903
  if (fallbackToFlags && !onlyEvaluateLocally) {
4968
- const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, evaluationContext.personProperties, evaluationContext.groupProperties, disableGeoip, flagKeys);
6904
+ const details = await super.getFeatureFlagDetailsStateless(evaluationContext.distinctId, evaluationContext.groups, personProperties, groupProperties, disableGeoip, flagKeys);
4969
6905
  if (details) {
6906
+ this._minimalFlagCalledEvents = details.minimalFlagCalledEvents === true;
4970
6907
  requestId = details.requestId;
4971
6908
  evaluatedAt = details.evaluatedAt;
4972
6909
  errorsWhileComputing = Boolean(details.errorsWhileComputingFlags);
@@ -4989,7 +6926,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
4989
6926
  id: detail.metadata?.id,
4990
6927
  version: detail.metadata?.version,
4991
6928
  reason: detail.reason?.description ?? detail.reason?.code,
4992
- locallyEvaluated: false
6929
+ locallyEvaluated: false,
6930
+ hasExperiment: detail.metadata?.has_experiment
4993
6931
  };
4994
6932
  }
4995
6933
  }
@@ -5009,7 +6947,8 @@ class PostHogBackendClient extends PostHogCoreStateless {
5009
6947
  id: existing?.id,
5010
6948
  version: existing?.version,
5011
6949
  reason: existing?.reason,
5012
- locallyEvaluated: existing?.locallyEvaluated ?? false
6950
+ locallyEvaluated: existing?.locallyEvaluated ?? false,
6951
+ hasExperiment: existing?.hasExperiment
5013
6952
  };
5014
6953
  }
5015
6954
  if (this._payloadOverrides !== undefined)
@@ -5021,6 +6960,11 @@ class PostHogBackendClient extends PostHogCoreStateless {
5021
6960
  payload
5022
6961
  };
5023
6962
  }
6963
+ if (requestedFlagKeys !== undefined) {
6964
+ for (const key of Object.keys(records))
6965
+ if (!requestedFlagKeys.has(key))
6966
+ delete records[key];
6967
+ }
5024
6968
  return new FeatureFlagEvaluations({
5025
6969
  host: this._getFeatureFlagEvaluationsHost(),
5026
6970
  distinctId: resolvedDistinctId,
@@ -5034,6 +6978,9 @@ class PostHogBackendClient extends PostHogCoreStateless {
5034
6978
  quotaLimited
5035
6979
  });
5036
6980
  }
6981
+ _shouldSendMinimalFlagCalledEvent(event, properties) {
6982
+ return event === "$feature_flag_called" && this._minimalFlagCalledEvents && properties.$feature_flag_has_experiment === false;
6983
+ }
5037
6984
  _captureFlagCalledEventIfNeeded(params) {
5038
6985
  const { distinctId, key, response, groups, disableGeoip, properties } = params;
5039
6986
  const groupSuffix = groups && Object.keys(groups).length > 0 ? `_${JSON.stringify(Object.entries(groups).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0))}` : "";
@@ -5068,9 +7015,32 @@ class PostHogBackendClient extends PostHogCoreStateless {
5068
7015
  return this._featureFlagEvaluationsHost;
5069
7016
  }
5070
7017
  groupIdentify({ groupType, groupKey, properties, distinctId, disableGeoip }) {
5071
- super.groupIdentifyStateless(groupType, groupKey, properties, {
7018
+ this._sendPreparedEvent("capture", {
7019
+ distinctId: distinctId || `$${groupType}_${groupKey}`,
7020
+ event: "$groupidentify",
7021
+ properties: {
7022
+ $group_type: groupType,
7023
+ $group_key: groupKey,
7024
+ $group_set: properties || {}
7025
+ },
7026
+ disableGeoip
7027
+ }, false, {
7028
+ includeContextProperties: false
7029
+ });
7030
+ }
7031
+ async groupIdentifyImmediate({ groupType, groupKey, properties, distinctId, disableGeoip }) {
7032
+ await this._sendPreparedEvent("capture", {
7033
+ distinctId: distinctId || `$${groupType}_${groupKey}`,
7034
+ event: "$groupidentify",
7035
+ properties: {
7036
+ $group_type: groupType,
7037
+ $group_key: groupKey,
7038
+ $group_set: properties || {}
7039
+ },
5072
7040
  disableGeoip
5073
- }, distinctId);
7041
+ }, true, {
7042
+ includeContextProperties: false
7043
+ });
5074
7044
  }
5075
7045
  async reloadFeatureFlags() {
5076
7046
  await this.featureFlagsPoller?.loadFeatureFlags(true);
@@ -5142,12 +7112,18 @@ class PostHogBackendClient extends PostHogCoreStateless {
5142
7112
  this.context?.enter(data, options);
5143
7113
  }
5144
7114
  async _shutdown(shutdownTimeoutMs) {
7115
+ const shutdownDeadlineMs = Date.now() + (shutdownTimeoutMs ?? 30000);
5145
7116
  const resolve = this._consumeWaitUntilCycle();
5146
7117
  await this.featureFlagsPoller?.stopPoller(shutdownTimeoutMs);
5147
7118
  this.errorTracking.shutdown();
7119
+ if (this._metrics) {
7120
+ await raceWithTimeout(this._metrics.flush().catch(() => {}), Math.max(0, shutdownDeadlineMs - Date.now()));
7121
+ this._metrics.reset();
7122
+ }
5148
7123
  try {
5149
- return await super._shutdown(shutdownTimeoutMs);
7124
+ return await super._shutdown(Math.max(0, shutdownDeadlineMs - Date.now()));
5150
7125
  } finally {
7126
+ this.distinctIdHasSentFlagCalls = {};
5151
7127
  resolve?.();
5152
7128
  }
5153
7129
  }
@@ -5242,7 +7218,6 @@ class PostHogBackendClient extends PostHogCoreStateless {
5242
7218
  }
5243
7219
  addLocalPersonAndGroupProperties(distinctId, groups, personProperties, groupProperties) {
5244
7220
  const allPersonProperties = {
5245
- distinct_id: distinctId,
5246
7221
  ...personProperties || {}
5247
7222
  };
5248
7223
  const allGroupProperties = {};
@@ -5257,6 +7232,12 @@ class PostHogBackendClient extends PostHogCoreStateless {
5257
7232
  allGroupProperties
5258
7233
  };
5259
7234
  }
7235
+ personPropertiesForLocalEvaluation(distinctId, personProperties) {
7236
+ return {
7237
+ distinct_id: distinctId,
7238
+ ...personProperties || {}
7239
+ };
7240
+ }
5260
7241
  createFeatureFlagEvaluationContext(distinctId, groups, personProperties, groupProperties) {
5261
7242
  return {
5262
7243
  distinctId,
@@ -5267,21 +7248,21 @@ class PostHogBackendClient extends PostHogCoreStateless {
5267
7248
  };
5268
7249
  }
5269
7250
  captureException(error, distinctId, additionalProperties, uuid, flags) {
5270
- if (!ErrorTracking.isPreviouslyCapturedError(error)) {
7251
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
5271
7252
  const syntheticException = new Error("PostHog syntheticException");
5272
- this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
7253
+ this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5273
7254
  syntheticException
5274
- }, distinctId, additionalProperties).then((msg) => this.capture({
7255
+ }, distinctId, additionalProperties).then((msg) => this._capturePreparedEvent({
5275
7256
  ...msg,
5276
7257
  uuid,
5277
7258
  flags
5278
- })));
7259
+ }, false)));
5279
7260
  }
5280
7261
  }
5281
7262
  async captureExceptionImmediate(error, distinctId, additionalProperties, flags) {
5282
- if (!ErrorTracking.isPreviouslyCapturedError(error)) {
7263
+ if (!error_tracking_ErrorTracking.isPreviouslyCapturedError(error)) {
5283
7264
  const syntheticException = new Error("PostHog syntheticException");
5284
- return this.addPendingPromise(ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
7265
+ return this.addPendingPromise(error_tracking_ErrorTracking.buildEventMessage(this.getErrorPropertiesBuilder(), error, {
5285
7266
  syntheticException
5286
7267
  }, distinctId, additionalProperties).then((msg) => this.captureImmediate({
5287
7268
  ...msg,
@@ -5290,24 +7271,31 @@ class PostHogBackendClient extends PostHogCoreStateless {
5290
7271
  }
5291
7272
  }
5292
7273
  async prepareEventMessage(props) {
7274
+ return this._prepareEventMessage(props);
7275
+ }
7276
+ async _prepareEventMessage(props, options = {}) {
5293
7277
  const { distinctId, event, properties, groups, flags, sendFeatureFlags, timestamp, disableGeoip, uuid } = props;
5294
7278
  const contextData = this.context?.get();
7279
+ const includeContextProperties = options.includeContextProperties ?? true;
5295
7280
  let mergedDistinctId = distinctId || contextData?.distinctId;
5296
- const mergedProperties = {
7281
+ const mergedProperties = includeContextProperties ? {
5297
7282
  ...this.props,
5298
7283
  ...contextData?.properties || {},
5299
7284
  ...properties || {}
7285
+ } : {
7286
+ ...properties || {}
5300
7287
  };
5301
7288
  if (!mergedDistinctId) {
5302
7289
  mergedDistinctId = uuidv7();
5303
7290
  mergedProperties.$process_person_profile = false;
5304
7291
  }
5305
- if (contextData?.sessionId && !mergedProperties.$session_id)
7292
+ if (includeContextProperties && contextData?.sessionId && !mergedProperties.$session_id)
5306
7293
  mergedProperties.$session_id = contextData.sessionId;
7294
+ const finalProperties = this._shouldSendMinimalFlagCalledEvent(event, mergedProperties) ? minimizeFlagCalledEventProperties(mergedProperties) : mergedProperties;
5307
7295
  const eventMessage = this._runBeforeSend({
5308
7296
  distinctId: mergedDistinctId,
5309
7297
  event,
5310
- properties: mergedProperties,
7298
+ properties: finalProperties,
5311
7299
  groups,
5312
7300
  flags,
5313
7301
  sendFeatureFlags,
@@ -5331,12 +7319,14 @@ class PostHogBackendClient extends PostHogCoreStateless {
5331
7319
  }
5332
7320
  return {};
5333
7321
  }).catch(() => ({})).then((additionalProperties) => {
5334
- const props2 = {
7322
+ const resolvedGroups = eventMessage.groups || groups;
7323
+ return {
5335
7324
  ...additionalProperties,
5336
7325
  ...eventMessage.properties || {},
5337
- $groups: eventMessage.groups || groups
7326
+ ...resolvedGroups !== undefined && Object.keys(resolvedGroups).length > 0 ? {
7327
+ $groups: resolvedGroups
7328
+ } : {}
5338
7329
  };
5339
- return props2;
5340
7330
  });
5341
7331
  if (eventMessage.event === "$pageview" && this.options.__preview_capture_bot_pageviews && typeof eventProperties.$raw_user_agent == "string") {
5342
7332
  if (isBlockedUA(eventProperties.$raw_user_agent, this.options.custom_blocked_useragents || [])) {
@@ -5363,22 +7353,26 @@ class PostHogBackendClient extends PostHogCoreStateless {
5363
7353
  beforeSend
5364
7354
  ];
5365
7355
  let result = eventMessage;
5366
- for (const fn of fns) {
5367
- result = fn(result);
5368
- if (!result) {
5369
- this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
7356
+ for (const fn of fns)
7357
+ try {
7358
+ result = fn(result);
7359
+ if (!result) {
7360
+ this._logger.info(`Event '${eventMessage.event}' was rejected in beforeSend function`);
7361
+ return null;
7362
+ }
7363
+ if (!result.properties || Object.keys(result.properties).length === 0) {
7364
+ const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
7365
+ this._logger.warn(message);
7366
+ }
7367
+ } catch (error) {
7368
+ this._logger.error(`Error in before_send function for event '${eventMessage.event}':`, error);
5370
7369
  return null;
5371
7370
  }
5372
- if (!result.properties || Object.keys(result.properties).length === 0) {
5373
- const message = `Event '${result.event}' has no properties after beforeSend function, this is likely an error.`;
5374
- this._logger.warn(message);
5375
- }
5376
- }
5377
7371
  return result;
5378
7372
  }
5379
7373
  }
5380
7374
 
5381
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/context/context.mjs
7375
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/context/context.mjs
5382
7376
  import { AsyncLocalStorage } from "node:async_hooks";
5383
7377
 
5384
7378
  class PostHogContext {
@@ -5409,7 +7403,22 @@ class PostHogContext {
5409
7403
  }
5410
7404
  }
5411
7405
 
5412
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
7406
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/gzip.node.mjs
7407
+ import { gzip } from "node:zlib";
7408
+ import { promisify } from "node:util";
7409
+ var gzipAsync = promisify(gzip);
7410
+ async function gzipCompress2(input, isDebug = true) {
7411
+ try {
7412
+ const compressed = await gzipAsync(input);
7413
+ return new Uint8Array(compressed);
7414
+ } catch (error) {
7415
+ if (isDebug)
7416
+ console.error("Failed to gzip compress data", error);
7417
+ return null;
7418
+ }
7419
+ }
7420
+
7421
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/extensions/sentry-integration.mjs
5413
7422
  var NAME = "posthog-node";
5414
7423
  function createEventProcessor(_posthog, { organization, projectId, prefix, severityAllowList = [
5415
7424
  "error"
@@ -5449,6 +7458,9 @@ function createEventProcessor(_posthog, { organization, projectId, prefix, sever
5449
7458
  $sentry_exception_type: exceptions[0]?.type,
5450
7459
  $sentry_tags: event.tags
5451
7460
  };
7461
+ const injectedReleaseId = exports_error_tracking.getInjectedReleaseId();
7462
+ if (injectedReleaseId)
7463
+ properties.$release_id = injectedReleaseId;
5452
7464
  if (organization && projectId)
5453
7465
  properties["$sentry_url"] = (prefix || "https://sentry.io/organizations/") + organization + "/issues/?project=" + projectId + "&query=" + event.event_id;
5454
7466
  if (sendExceptionsToPostHog)
@@ -5477,11 +7489,14 @@ class PostHogSentryIntegration {
5477
7489
  };
5478
7490
  }
5479
7491
  }
5480
- // ../../../../../node_modules/.bun/posthog-node@5.35.12/node_modules/posthog-node/dist/entrypoints/index.node.mjs
7492
+ // ../../../../../node_modules/.bun/posthog-node@5.51.1/node_modules/posthog-node/dist/entrypoints/index.node.mjs
5481
7493
  class PostHog extends PostHogBackendClient {
5482
7494
  getLibraryId() {
5483
7495
  return "posthog-node";
5484
7496
  }
7497
+ compressPayload(payload) {
7498
+ return gzipCompress2(payload, this.isDebug);
7499
+ }
5485
7500
  initializeContext() {
5486
7501
  return new PostHogContext;
5487
7502
  }
@@ -5494,12 +7509,22 @@ class PostHog extends PostHogBackendClient {
5494
7509
  new exports_error_tracking.PrimitiveCoercer
5495
7510
  ], exports_error_tracking.createStackParser("node:javascript", exports_error_tracking.nodeStackLineParser), [
5496
7511
  createModulerModifier(),
5497
- addSourceContext,
7512
+ (frames) => addSourceContext(frames, undefined, this._logger),
5498
7513
  createRelativePathModifier()
5499
7514
  ]);
5500
7515
  }
5501
7516
  }
5502
7517
 
7518
+ // ../../../../telemetry-core/src/machine-id.ts
7519
+ import { createHash } from "node:crypto";
7520
+ import os2 from "node:os";
7521
+ function getDefaultTelemetryOsProvider() {
7522
+ return os2;
7523
+ }
7524
+ function getTelemetryDistinctId(machineIdPrefix, osProvider = getDefaultTelemetryOsProvider()) {
7525
+ return createHash("sha256").update(`${machineIdPrefix}${osProvider.hostname()}`).digest("hex");
7526
+ }
7527
+
5503
7528
  // ../../../../telemetry-core/src/posthog-client.ts
5504
7529
  var NO_OP_CLIENT = {
5505
7530
  enabled: false,
@@ -5534,7 +7559,7 @@ function createDefaultPostHogTransport(apiKey, options) {
5534
7559
  }
5535
7560
  function isTelemetryClientEnabled(input) {
5536
7561
  const env = input.env ?? process.env;
5537
- return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && getTelemetryApiKey(env, input.product.defaultApiKey).length > 0;
7562
+ return !shouldDisableTelemetry({ env, productEnvPrefix: input.product.productEnvPrefix }) && hasTelemetryApiKey(env, input.product.defaultApiKey);
5538
7563
  }
5539
7564
  function createTelemetryClient(input) {
5540
7565
  if (!isTelemetryClientEnabled(input)) {
@@ -5600,7 +7625,8 @@ function createTransport(input) {
5600
7625
  flushAt: 1,
5601
7626
  flushInterval: 0,
5602
7627
  host: getTelemetryHost(env, input.product.defaultHost),
5603
- disableGeoip: false
7628
+ disableGeoip: input.product.disableGeoip ?? false,
7629
+ ...input.product.transportOptions
5604
7630
  });
5605
7631
  } catch (error) {
5606
7632
  input.diagnostics?.({
@@ -5804,11 +7830,11 @@ function getPostHogDistinctIdForTesting(osProvider) {
5804
7830
  return getTelemetryDistinctId(MACHINE_ID_PREFIX, osProvider);
5805
7831
  }
5806
7832
  export {
5807
- getPostHogDistinctIdForTesting,
5808
- getPostHogDistinctId,
5809
- getComponentVersion,
5810
- createPluginPostHog,
5811
- __createPluginPostHogForTesting,
7833
+ DEFAULT_POSTHOG_API_KEY,
5812
7834
  DEFAULT_POSTHOG_HOST,
5813
- DEFAULT_POSTHOG_API_KEY
7835
+ __createPluginPostHogForTesting,
7836
+ createPluginPostHog,
7837
+ getComponentVersion,
7838
+ getPostHogDistinctId,
7839
+ getPostHogDistinctIdForTesting
5814
7840
  };