@danieljvdm/dev-kit 1.0.1 → 2.0.0

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 (330) hide show
  1. package/README.md +6 -6
  2. package/package.json +1 -1
  3. package/skill-sources.jsonc +6 -29
  4. package/skill-sources.lock.json +23 -109
  5. package/skills/animate/LICENSE +21 -0
  6. package/skills/animate/NOTICE +10 -0
  7. package/skills/animate/SKILL.md +34 -0
  8. package/skills/animate/references/gestures.md +27 -0
  9. package/skills/animate/references/glossary.md +136 -0
  10. package/skills/animate/references/implementation.md +22 -0
  11. package/skills/animate/references/opportunities.md +18 -0
  12. package/skills/animate/references/principles.md +48 -0
  13. package/skills/animate/references/review.md +19 -0
  14. package/skills/cloudflare-workers/LICENSE +202 -0
  15. package/skills/cloudflare-workers/NOTICE +9 -0
  16. package/skills/cloudflare-workers/SKILL.md +26 -0
  17. package/skills/cloudflare-workers/references/durable-objects.md +68 -0
  18. package/skills/cloudflare-workers/references/sandbox.md +48 -0
  19. package/skills/cloudflare-workers/references/workers.md +63 -0
  20. package/skills/cloudflare-workers/references/wrangler.md +56 -0
  21. package/skills/design-ui/LICENSE +21 -0
  22. package/skills/design-ui/NOTICE +8 -0
  23. package/skills/design-ui/SKILL.md +29 -0
  24. package/skills/design-ui/references/appearance.md +22 -0
  25. package/skills/design-ui/references/components.md +33 -0
  26. package/skills/design-ui/references/exploration.md +50 -0
  27. package/skills/design-ui/references/libraries.md +39 -0
  28. package/skills/design-ui/references/themes.md +23 -0
  29. package/skills/dev-kit/SKILL.md +19 -38
  30. package/skills/dev-kit/references/cloudflare-worker-api.md +1 -1
  31. package/skills/dev-kit/references/skills.md +2 -2
  32. package/skills/effect-development/SKILL.md +27 -0
  33. package/skills/effect-development/agents/openai.yaml +4 -0
  34. package/skills/effect-development/references/api/index.md +32 -0
  35. package/skills/effect-development/references/api/schema-codecs.md +15 -0
  36. package/skills/{build-effect-apis/references → effect-development/references/api}/verification.md +10 -5
  37. package/skills/{effect-architecture-audit/SKILL.md → effect-development/references/architecture/index.md} +1 -6
  38. package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-client.md +8 -6
  39. package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-testing.md +7 -2
  40. package/skills/effect-development/references/atom/index.md +40 -0
  41. package/skills/{build-effect-clis/references → effect-development/references/cli}/entrypoints-and-testing.md +6 -2
  42. package/skills/effect-development/references/cli/index.md +39 -0
  43. package/skills/effect-development/references/setup.md +15 -0
  44. package/skills/open-pull-request/SKILL.md +11 -115
  45. package/skills/open-pull-request/agents/openai.yaml +3 -3
  46. package/skills/open-pull-request/references/evidence.md +22 -0
  47. package/skills/open-pull-request/references/explanation.md +21 -0
  48. package/skills/open-pull-request/references/publication.md +21 -0
  49. package/skills/sentry/LICENSE +202 -0
  50. package/skills/sentry/LICENSE-UPSTREAM +21 -0
  51. package/skills/sentry/NOTICE +14 -0
  52. package/skills/sentry/SKILL.md +33 -0
  53. package/skills/sentry/references/alert-payloads.md +105 -0
  54. package/skills/sentry/references/alerts.md +17 -0
  55. package/skills/sentry/references/artifacts.md +25 -0
  56. package/skills/sentry/references/auth-token.md +65 -0
  57. package/skills/sentry/references/concepts/ai-monitoring.md +131 -0
  58. package/skills/sentry/references/concepts/choosing-a-signal.md +78 -0
  59. package/skills/sentry/references/concepts/crons.md +50 -0
  60. package/skills/sentry/references/concepts/data-scrubbing.md +43 -0
  61. package/skills/sentry/references/concepts/errors.md +40 -0
  62. package/skills/sentry/references/concepts/logging.md +85 -0
  63. package/skills/sentry/references/concepts/metrics.md +49 -0
  64. package/skills/sentry/references/concepts/monitors.md +78 -0
  65. package/skills/sentry/references/concepts/profiling.md +38 -0
  66. package/skills/sentry/references/concepts/reduce-volume.md +49 -0
  67. package/skills/sentry/references/concepts/releases.md +43 -0
  68. package/skills/sentry/references/concepts/session-replay.md +35 -0
  69. package/skills/sentry/references/concepts/tracing.md +54 -0
  70. package/skills/sentry/references/concepts/user-feedback.md +36 -0
  71. package/skills/sentry/references/debug-artifacts/android.md +68 -0
  72. package/skills/sentry/references/debug-artifacts/apple.md +96 -0
  73. package/skills/sentry/references/debug-artifacts/dotnet.md +70 -0
  74. package/skills/sentry/references/debug-artifacts/flutter.md +65 -0
  75. package/skills/sentry/references/debug-artifacts/index.md +75 -0
  76. package/skills/sentry/references/debug-artifacts/javascript.md +94 -0
  77. package/skills/sentry/references/debug-artifacts/matching.md +73 -0
  78. package/skills/sentry/references/debug-artifacts/react-native.md +75 -0
  79. package/skills/sentry/references/first-error-setup.md +25 -0
  80. package/skills/sentry/references/instrumentation.md +30 -0
  81. package/skills/sentry/references/issues.md +32 -0
  82. package/skills/sentry/references/new-project.md +17 -0
  83. package/skills/sentry/references/otel-exporter.md +30 -0
  84. package/skills/sentry/references/release-workflow.md +31 -0
  85. package/skills/sentry/references/releases/ci-pipeline.md +214 -0
  86. package/skills/sentry/references/releases/index.md +93 -0
  87. package/skills/sentry/references/releases/suspect-commits.md +155 -0
  88. package/skills/sentry/references/releases/tagging.md +131 -0
  89. package/skills/sentry/references/releases/troubleshooting.md +67 -0
  90. package/skills/sentry/references/sdks/android/crons.md +305 -0
  91. package/skills/sentry/references/sdks/android/error-monitoring.md +800 -0
  92. package/skills/sentry/references/sdks/android/index.md +748 -0
  93. package/skills/sentry/references/sdks/android/integrations.md +48 -0
  94. package/skills/sentry/references/sdks/android/logging.md +374 -0
  95. package/skills/sentry/references/sdks/android/metrics.md +288 -0
  96. package/skills/sentry/references/sdks/android/profiling.md +397 -0
  97. package/skills/sentry/references/sdks/android/session-replay.md +406 -0
  98. package/skills/sentry/references/sdks/android/tracing.md +861 -0
  99. package/skills/sentry/references/sdks/browser/error-monitoring.md +861 -0
  100. package/skills/sentry/references/sdks/browser/index.md +714 -0
  101. package/skills/sentry/references/sdks/browser/logging.md +315 -0
  102. package/skills/sentry/references/sdks/browser/profiling.md +236 -0
  103. package/skills/sentry/references/sdks/browser/session-replay.md +586 -0
  104. package/skills/sentry/references/sdks/browser/tracing.md +561 -0
  105. package/skills/sentry/references/sdks/browser/user-feedback.md +354 -0
  106. package/skills/sentry/references/sdks/cloudflare/ai-monitoring.md +661 -0
  107. package/skills/sentry/references/sdks/cloudflare/crons.md +231 -0
  108. package/skills/sentry/references/sdks/cloudflare/durable-objects.md +381 -0
  109. package/skills/sentry/references/sdks/cloudflare/error-monitoring.md +329 -0
  110. package/skills/sentry/references/sdks/cloudflare/index.md +698 -0
  111. package/skills/sentry/references/sdks/cloudflare/logging.md +169 -0
  112. package/skills/sentry/references/sdks/cloudflare/nodejs-compat.md +134 -0
  113. package/skills/sentry/references/sdks/cloudflare/tracing.md +475 -0
  114. package/skills/sentry/references/sdks/cocoa/error-monitoring.md +394 -0
  115. package/skills/sentry/references/sdks/cocoa/index.md +497 -0
  116. package/skills/sentry/references/sdks/cocoa/logging.md +209 -0
  117. package/skills/sentry/references/sdks/cocoa/metrics.md +136 -0
  118. package/skills/sentry/references/sdks/cocoa/profiling.md +223 -0
  119. package/skills/sentry/references/sdks/cocoa/session-replay.md +257 -0
  120. package/skills/sentry/references/sdks/cocoa/tracing.md +524 -0
  121. package/skills/sentry/references/sdks/cocoa/user-feedback.md +310 -0
  122. package/skills/sentry/references/sdks/dotnet/crons.md +465 -0
  123. package/skills/sentry/references/sdks/dotnet/error-monitoring.md +1100 -0
  124. package/skills/sentry/references/sdks/dotnet/index.md +614 -0
  125. package/skills/sentry/references/sdks/dotnet/logging.md +556 -0
  126. package/skills/sentry/references/sdks/dotnet/metrics.md +229 -0
  127. package/skills/sentry/references/sdks/dotnet/profiling.md +296 -0
  128. package/skills/sentry/references/sdks/dotnet/tracing.md +897 -0
  129. package/skills/sentry/references/sdks/elixir/crons.md +371 -0
  130. package/skills/sentry/references/sdks/elixir/error-monitoring.md +335 -0
  131. package/skills/sentry/references/sdks/elixir/index.md +383 -0
  132. package/skills/sentry/references/sdks/elixir/logging.md +239 -0
  133. package/skills/sentry/references/sdks/elixir/tracing.md +233 -0
  134. package/skills/sentry/references/sdks/flutter/ecosystem-integrations.md +70 -0
  135. package/skills/sentry/references/sdks/flutter/error-monitoring.md +312 -0
  136. package/skills/sentry/references/sdks/flutter/index.md +728 -0
  137. package/skills/sentry/references/sdks/flutter/logging.md +387 -0
  138. package/skills/sentry/references/sdks/flutter/metrics.md +310 -0
  139. package/skills/sentry/references/sdks/flutter/profiling.md +214 -0
  140. package/skills/sentry/references/sdks/flutter/session-replay.md +308 -0
  141. package/skills/sentry/references/sdks/flutter/tracing.md +502 -0
  142. package/skills/sentry/references/sdks/go/crons.md +270 -0
  143. package/skills/sentry/references/sdks/go/error-monitoring.md +361 -0
  144. package/skills/sentry/references/sdks/go/index.md +324 -0
  145. package/skills/sentry/references/sdks/go/logging.md +354 -0
  146. package/skills/sentry/references/sdks/go/metrics.md +273 -0
  147. package/skills/sentry/references/sdks/go/profiling.md +46 -0
  148. package/skills/sentry/references/sdks/go/tracing.md +366 -0
  149. package/skills/sentry/references/sdks/index.md +41 -0
  150. package/skills/sentry/references/sdks/nestjs/ai-monitoring.md +410 -0
  151. package/skills/sentry/references/sdks/nestjs/crons.md +268 -0
  152. package/skills/sentry/references/sdks/nestjs/error-monitoring.md +729 -0
  153. package/skills/sentry/references/sdks/nestjs/index.md +699 -0
  154. package/skills/sentry/references/sdks/nestjs/logging.md +174 -0
  155. package/skills/sentry/references/sdks/nestjs/metrics.md +243 -0
  156. package/skills/sentry/references/sdks/nestjs/profiling.md +127 -0
  157. package/skills/sentry/references/sdks/nestjs/tracing.md +762 -0
  158. package/skills/sentry/references/sdks/nextjs/ai-monitoring.md +494 -0
  159. package/skills/sentry/references/sdks/nextjs/crons.md +383 -0
  160. package/skills/sentry/references/sdks/nextjs/error-monitoring.md +974 -0
  161. package/skills/sentry/references/sdks/nextjs/index.md +491 -0
  162. package/skills/sentry/references/sdks/nextjs/logging.md +381 -0
  163. package/skills/sentry/references/sdks/nextjs/metrics.md +411 -0
  164. package/skills/sentry/references/sdks/nextjs/profiling.md +403 -0
  165. package/skills/sentry/references/sdks/nextjs/session-replay.md +462 -0
  166. package/skills/sentry/references/sdks/nextjs/tracing.md +628 -0
  167. package/skills/sentry/references/sdks/node/ai-monitoring.md +303 -0
  168. package/skills/sentry/references/sdks/node/crons.md +432 -0
  169. package/skills/sentry/references/sdks/node/error-monitoring.md +1125 -0
  170. package/skills/sentry/references/sdks/node/index.md +942 -0
  171. package/skills/sentry/references/sdks/node/logging.md +380 -0
  172. package/skills/sentry/references/sdks/node/metrics.md +278 -0
  173. package/skills/sentry/references/sdks/node/profiling.md +373 -0
  174. package/skills/sentry/references/sdks/node/tracing.md +878 -0
  175. package/skills/sentry/references/sdks/php/ai-monitoring.md +310 -0
  176. package/skills/sentry/references/sdks/php/crons.md +265 -0
  177. package/skills/sentry/references/sdks/php/error-monitoring.md +626 -0
  178. package/skills/sentry/references/sdks/php/index.md +362 -0
  179. package/skills/sentry/references/sdks/php/laravel.md +542 -0
  180. package/skills/sentry/references/sdks/php/logging.md +242 -0
  181. package/skills/sentry/references/sdks/php/metrics.md +193 -0
  182. package/skills/sentry/references/sdks/php/profiling.md +115 -0
  183. package/skills/sentry/references/sdks/php/symfony.md +552 -0
  184. package/skills/sentry/references/sdks/php/tracing.md +516 -0
  185. package/skills/sentry/references/sdks/python/ai-monitoring.md +351 -0
  186. package/skills/sentry/references/sdks/python/crons.md +218 -0
  187. package/skills/sentry/references/sdks/python/error-monitoring.md +292 -0
  188. package/skills/sentry/references/sdks/python/index.md +361 -0
  189. package/skills/sentry/references/sdks/python/logging.md +234 -0
  190. package/skills/sentry/references/sdks/python/metrics.md +154 -0
  191. package/skills/sentry/references/sdks/python/profiling.md +120 -0
  192. package/skills/sentry/references/sdks/python/tracing.md +364 -0
  193. package/skills/sentry/references/sdks/react/error-monitoring.md +1607 -0
  194. package/skills/sentry/references/sdks/react/index.md +492 -0
  195. package/skills/sentry/references/sdks/react/logging.md +364 -0
  196. package/skills/sentry/references/sdks/react/profiling.md +322 -0
  197. package/skills/sentry/references/sdks/react/react-features.md +1272 -0
  198. package/skills/sentry/references/sdks/react/session-replay.md +1193 -0
  199. package/skills/sentry/references/sdks/react/tracing.md +1415 -0
  200. package/skills/sentry/references/sdks/react-native/error-monitoring.md +1481 -0
  201. package/skills/sentry/references/sdks/react-native/expo-config-plugin.md +45 -0
  202. package/skills/sentry/references/sdks/react-native/index.md +1030 -0
  203. package/skills/sentry/references/sdks/react-native/logging.md +444 -0
  204. package/skills/sentry/references/sdks/react-native/profiling.md +386 -0
  205. package/skills/sentry/references/sdks/react-native/session-replay.md +704 -0
  206. package/skills/sentry/references/sdks/react-native/tracing.md +1086 -0
  207. package/skills/sentry/references/sdks/react-native/user-feedback.md +815 -0
  208. package/skills/sentry/references/sdks/react-router-framework/error-monitoring.md +127 -0
  209. package/skills/sentry/references/sdks/react-router-framework/index.md +411 -0
  210. package/skills/sentry/references/sdks/react-router-framework/logging.md +66 -0
  211. package/skills/sentry/references/sdks/react-router-framework/profiling.md +57 -0
  212. package/skills/sentry/references/sdks/react-router-framework/react-router-framework-features.md +110 -0
  213. package/skills/sentry/references/sdks/react-router-framework/session-replay.md +67 -0
  214. package/skills/sentry/references/sdks/react-router-framework/tracing.md +96 -0
  215. package/skills/sentry/references/sdks/react-router-framework/user-feedback.md +71 -0
  216. package/skills/sentry/references/sdks/ruby/crons.md +184 -0
  217. package/skills/sentry/references/sdks/ruby/error-monitoring.md +248 -0
  218. package/skills/sentry/references/sdks/ruby/index.md +297 -0
  219. package/skills/sentry/references/sdks/ruby/logging.md +168 -0
  220. package/skills/sentry/references/sdks/ruby/metrics.md +196 -0
  221. package/skills/sentry/references/sdks/ruby/migration.md +321 -0
  222. package/skills/sentry/references/sdks/ruby/profiling.md +107 -0
  223. package/skills/sentry/references/sdks/ruby/tracing.md +388 -0
  224. package/skills/sentry/references/sdks/svelte/error-monitoring.md +456 -0
  225. package/skills/sentry/references/sdks/svelte/index.md +467 -0
  226. package/skills/sentry/references/sdks/svelte/logging.md +344 -0
  227. package/skills/sentry/references/sdks/svelte/session-replay.md +369 -0
  228. package/skills/sentry/references/sdks/svelte/tracing.md +406 -0
  229. package/skills/sentry/references/sdks/tanstack-start/error-monitoring.md +149 -0
  230. package/skills/sentry/references/sdks/tanstack-start/index.md +381 -0
  231. package/skills/sentry/references/sdks/tanstack-start/logging.md +74 -0
  232. package/skills/sentry/references/sdks/tanstack-start/session-replay.md +76 -0
  233. package/skills/sentry/references/sdks/tanstack-start/tanstackstart-features.md +128 -0
  234. package/skills/sentry/references/sdks/tanstack-start/tracing.md +123 -0
  235. package/skills/sentry/references/sdks/tanstack-start/user-feedback.md +81 -0
  236. package/skills/sentry/references/search-query-language.md +226 -0
  237. package/skills/sentry/references/semantics/angular.md +7 -0
  238. package/skills/sentry/references/semantics/app.md +28 -0
  239. package/skills/sentry/references/semantics/art.md +17 -0
  240. package/skills/sentry/references/semantics/aws.md +43 -0
  241. package/skills/sentry/references/semantics/browser.md +34 -0
  242. package/skills/sentry/references/semantics/cache.md +12 -0
  243. package/skills/sentry/references/semantics/client.md +8 -0
  244. package/skills/sentry/references/semantics/cloud.md +12 -0
  245. package/skills/sentry/references/semantics/cloudflare.md +23 -0
  246. package/skills/sentry/references/semantics/code.md +11 -0
  247. package/skills/sentry/references/semantics/culture.md +11 -0
  248. package/skills/sentry/references/semantics/db.md +21 -0
  249. package/skills/sentry/references/semantics/device.md +43 -0
  250. package/skills/sentry/references/semantics/error.md +7 -0
  251. package/skills/sentry/references/semantics/event.md +8 -0
  252. package/skills/sentry/references/semantics/exception.md +10 -0
  253. package/skills/sentry/references/semantics/faas.md +19 -0
  254. package/skills/sentry/references/semantics/file.md +8 -0
  255. package/skills/sentry/references/semantics/flag.md +7 -0
  256. package/skills/sentry/references/semantics/gcp.md +16 -0
  257. package/skills/sentry/references/semantics/gen_ai.md +53 -0
  258. package/skills/sentry/references/semantics/general.md +11 -0
  259. package/skills/sentry/references/semantics/graphql.md +9 -0
  260. package/skills/sentry/references/semantics/grpc.md +19 -0
  261. package/skills/sentry/references/semantics/http.md +34 -0
  262. package/skills/sentry/references/semantics/index.md +63 -0
  263. package/skills/sentry/references/semantics/jsonrpc.md +8 -0
  264. package/skills/sentry/references/semantics/jvm.md +12 -0
  265. package/skills/sentry/references/semantics/koa.md +7 -0
  266. package/skills/sentry/references/semantics/logger.md +7 -0
  267. package/skills/sentry/references/semantics/mcp.md +37 -0
  268. package/skills/sentry/references/semantics/mdc.md +7 -0
  269. package/skills/sentry/references/semantics/messaging.md +23 -0
  270. package/skills/sentry/references/semantics/middleware.md +7 -0
  271. package/skills/sentry/references/semantics/navigation.md +9 -0
  272. package/skills/sentry/references/semantics/nel.md +11 -0
  273. package/skills/sentry/references/semantics/network.md +17 -0
  274. package/skills/sentry/references/semantics/os.md +15 -0
  275. package/skills/sentry/references/semantics/otel.md +10 -0
  276. package/skills/sentry/references/semantics/params.md +7 -0
  277. package/skills/sentry/references/semantics/process.md +14 -0
  278. package/skills/sentry/references/semantics/react.md +7 -0
  279. package/skills/sentry/references/semantics/remix.md +7 -0
  280. package/skills/sentry/references/semantics/resource.md +7 -0
  281. package/skills/sentry/references/semantics/rpc.md +10 -0
  282. package/skills/sentry/references/semantics/score.md +10 -0
  283. package/skills/sentry/references/semantics/sentry.md +69 -0
  284. package/skills/sentry/references/semantics/server.md +8 -0
  285. package/skills/sentry/references/semantics/service.md +8 -0
  286. package/skills/sentry/references/semantics/session.md +7 -0
  287. package/skills/sentry/references/semantics/state.md +7 -0
  288. package/skills/sentry/references/semantics/thread.md +8 -0
  289. package/skills/sentry/references/semantics/timber.md +7 -0
  290. package/skills/sentry/references/semantics/trpc.md +8 -0
  291. package/skills/sentry/references/semantics/ui.md +18 -0
  292. package/skills/sentry/references/semantics/url.md +15 -0
  293. package/skills/sentry/references/semantics/user.md +17 -0
  294. package/skills/sentry/references/semantics/user_agent.md +7 -0
  295. package/skills/sentry/references/semantics/vercel.md +42 -0
  296. package/skills/sentry/references/setup-verification.md +39 -0
  297. package/skills/sentry/references/snapshots/github-actions-fanout.md +206 -0
  298. package/skills/sentry/references/snapshots/github-actions-simple.md +102 -0
  299. package/skills/sentry/references/snapshots/github-actions-swift-snapshot-testing.md +118 -0
  300. package/skills/sentry/references/snapshots/index.md +19 -0
  301. package/skills/sentry/references/snapshots/snapshot-previews.md +100 -0
  302. package/skills/sentry/references/snapshots/snapshots.md +123 -0
  303. package/skills/sentry/references/snapshots/wizard-setup.md +134 -0
  304. package/skills/testing/LICENSE +21 -0
  305. package/skills/testing/NOTICE +7 -0
  306. package/skills/testing/SKILL.md +13 -19
  307. package/skills/testing/agents/openai.yaml +1 -2
  308. package/skills/testing/references/selection.md +23 -0
  309. package/skills/testing/references/tdd.md +19 -0
  310. package/skills/testing/references/test-design.md +17 -0
  311. package/src/catalog.ts +1 -7
  312. package/skills/build-effect-apis/SKILL.md +0 -81
  313. package/skills/build-effect-apis/agents/openai.yaml +0 -4
  314. package/skills/build-effect-clis/SKILL.md +0 -92
  315. package/skills/build-effect-clis/agents/openai.yaml +0 -4
  316. package/skills/effect-architecture-audit/agents/openai.yaml +0 -4
  317. package/skills/effect-atom-state/SKILL.md +0 -97
  318. package/skills/effect-atom-state/agents/openai.yaml +0 -4
  319. package/skills/effect-ts/SKILL.md +0 -35
  320. package/skills/effect-ts/agents/openai.yaml +0 -4
  321. /package/skills/{build-effect-apis/references → effect-development/references/api}/cloudflare-workers.md +0 -0
  322. /package/skills/{build-effect-apis/references → effect-development/references/api}/runtime-assembly.md +0 -0
  323. /package/skills/{build-effect-apis/references → effect-development/references/api}/server-and-middleware.md +0 -0
  324. /package/skills/{build-effect-apis/references → effect-development/references/api}/shared-contracts.md +0 -0
  325. /package/skills/{effect-architecture-audit/references → effect-development/references/architecture}/service-and-boundary-audit.md +0 -0
  326. /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-lifecycle.md +0 -0
  327. /package/skills/{effect-atom-state/references → effect-development/references/atom}/effect-atom-workflows.md +0 -0
  328. /package/skills/{effect-atom-state/references → effect-development/references/atom}/tanstack-start.md +0 -0
  329. /package/skills/{build-effect-clis/references → effect-development/references/cli}/command-design.md +0 -0
  330. /package/skills/{build-effect-clis/references → effect-development/references/cli}/processes-and-platform.md +0 -0
@@ -0,0 +1,1125 @@
1
+ # Error Monitoring — Sentry Node.js SDK
2
+
3
+ > Minimum SDK: `@sentry/node` ≥8.0.0\
4
+ > NestJS integration: `@sentry/nestjs` ≥8.0.0\
5
+ > Bun integration: `@sentry/bun` ≥8.0.0 (thin wrapper over `@sentry/node`)\
6
+ > Deno integration: `npm:@sentry/deno` (Deno 2+)
7
+
8
+ ---
9
+
10
+ ## The Instrument-First Rule
11
+
12
+ `@sentry/node` patches modules at import time via OpenTelemetry.
13
+ The instrument file **must be loaded before everything else** — before your framework,
14
+ before your database driver, before any HTTP client.
15
+
16
+ ```javascript
17
+ // instrument.js — loaded first
18
+ const Sentry = require("@sentry/node");
19
+
20
+ Sentry.init({
21
+ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
22
+ release: "my-app@1.2.3",
23
+ environment: process.env.NODE_ENV ?? "production",
24
+ tracesSampleRate: 1.0,
25
+ dataCollection: {
26
+ // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
27
+ // https://docs.sentry.io/platforms/javascript/guides/node/configuration/options/#dataCollection
28
+ // userInfo: false,
29
+ // httpBodies: [],
30
+ },
31
+ });
32
+ ```
33
+
34
+ ```javascript
35
+ // app.js
36
+ require("./instrument"); // MUST be line 1
37
+ const express = require("express");
38
+ // ...
39
+ ```
40
+
41
+ **ESM (Node 18.19+ / 19.9+):**
42
+
43
+ ```javascript
44
+ // instrument.mjs
45
+ import * as Sentry from "@sentry/node";
46
+ Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
47
+ ```
48
+
49
+ ```bash
50
+ # Launch with --import
51
+ node --import ./instrument.mjs app.mjs
52
+ # or:
53
+ NODE_OPTIONS="--import ./instrument.mjs" npm start
54
+ ```
55
+
56
+ ---
57
+
58
+ ## What Is Captured Automatically
59
+
60
+ | Error Type | Captured? | Mechanism |
61
+ | ------------------------------------------------------- | --------- | ------------------------------------- |
62
+ | Uncaught exceptions | ✅ Yes | `process.on("uncaughtException")` |
63
+ | Unhandled promise rejections | ✅ Yes | `process.on("unhandledRejection")` |
64
+ | Framework errors (Express, Fastify, Koa, Hapi, Connect) | ✅ Yes | Error handler middleware (see below) |
65
+ | NestJS non-HttpExceptions | ✅ Yes | `SentryGlobalFilter` |
66
+ | Caught + re-thrown errors | ✅ Yes | Bubbles to global handler |
67
+ | Caught + swallowed errors | ❌ No | Must call `captureException` manually |
68
+ | `HttpException` in NestJS (4xx) | ❌ No | Treated as control flow by design |
69
+
70
+ ### The Core Rule
71
+
72
+ > **“If you catch an error and don’t re-throw it, Sentry never sees it.”**
73
+
74
+ ```javascript
75
+ // ✅ Auto-captured — unhandled, bubbles up
76
+ throw new Error("Unhandled");
77
+
78
+ // ✅ Auto-captured — re-thrown
79
+ try {
80
+ await doSomething();
81
+ } catch (err) {
82
+ throw err;
83
+ }
84
+
85
+ // ❌ NOT captured — swallowed by graceful return
86
+ try {
87
+ await doSomething();
88
+ } catch (err) {
89
+ return res.status(500).json({ error: "Failed" }); // ← add captureException!
90
+ }
91
+
92
+ // ✅ Manually captured
93
+ try {
94
+ await doSomething();
95
+ } catch (err) {
96
+ Sentry.captureException(err);
97
+ return res.status(500).json({ error: "Failed" });
98
+ }
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Framework Error Handler Placement
104
+
105
+ **Critical: placement rules differ per framework.
106
+ Getting this wrong silently misses errors.**
107
+
108
+ | Framework | Function | Placement | Async? |
109
+ | --------- | ----------------------------------------------- | -------------------- | ---------------------- |
110
+ | Express | `setupExpressErrorHandler(app)` | **AFTER routes** | No |
111
+ | Fastify | `setupFastifyErrorHandler(app)` | **BEFORE routes** | No |
112
+ | Koa | `setupKoaErrorHandler(app)` | **FIRST middleware** | No |
113
+ | Hapi | `setupHapiErrorHandler(server)` | Before routes | **YES — must `await`** |
114
+ | Connect | `setupConnectErrorHandler(app)` | **BEFORE routes** | No |
115
+ | NestJS | `SentryGlobalFilter` + `SentryModule.forRoot()` | AppModule providers | No |
116
+
117
+ ---
118
+
119
+ ## Express
120
+
121
+ Error handler goes **after all routes**, before your own error handler.
122
+
123
+ ```javascript
124
+ require("./instrument");
125
+ const express = require("express");
126
+ const Sentry = require("@sentry/node");
127
+
128
+ const app = express();
129
+ app.use(express.json());
130
+
131
+ // ── Routes ──────────────────────────────────────────────────────
132
+ app.get("/", (req, res) => res.json({ ok: true }));
133
+ app.post("/orders", async (req, res, next) => {
134
+ try {
135
+ const result = await processOrder(req.body.orderId);
136
+ res.json(result);
137
+ } catch (err) {
138
+ next(err); // pass to error handlers
139
+ }
140
+ });
141
+
142
+ // ↓ Sentry AFTER routes, BEFORE your error handler
143
+ Sentry.setupExpressErrorHandler(app);
144
+
145
+ // Optional: capture only specific status codes
146
+ // Sentry.setupExpressErrorHandler(app, {
147
+ // shouldHandleError(error) {
148
+ // return !error.status || parseInt(String(error.status)) >= 500;
149
+ // },
150
+ // });
151
+
152
+ // ── Your error handler (runs after Sentry) ──────────────────────
153
+ app.use((err, req, res, next) => {
154
+ res.status(err.status || 500).json({ error: "Internal Server Error" });
155
+ });
156
+
157
+ app.listen(3000);
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Fastify
163
+
164
+ Error handler goes **before routes**. Internally registers a Fastify plugin using
165
+ `onError` lifecycle hook.
166
+
167
+ ```javascript
168
+ require("./instrument");
169
+ const Fastify = require("fastify");
170
+ const Sentry = require("@sentry/node");
171
+
172
+ const app = Fastify({ logger: true });
173
+
174
+ // ↓ Sentry BEFORE routes
175
+ Sentry.setupFastifyErrorHandler(app);
176
+
177
+ // Optional: customize which errors are captured
178
+ // Sentry.setupFastifyErrorHandler(app, {
179
+ // shouldHandleError(error, request, reply) {
180
+ // return reply.statusCode >= 500;
181
+ // },
182
+ // });
183
+
184
+ app.get("/", async (request, reply) => ({ hello: "world" }));
185
+ app.get("/debug-sentry", async () => {
186
+ throw new Error("Test Fastify error!");
187
+ });
188
+
189
+ app.listen({ port: 3000 });
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Koa
195
+
196
+ Error handler goes as the **first `app.use()` call**, before any route.
197
+
198
+ ```javascript
199
+ require("./instrument");
200
+ const Koa = require("koa");
201
+ const Router = require("@koa/router");
202
+ const Sentry = require("@sentry/node");
203
+
204
+ const app = new Koa();
205
+ const router = new Router();
206
+
207
+ // ↓ Sentry FIRST middleware
208
+ Sentry.setupKoaErrorHandler(app);
209
+
210
+ router.get("/", async (ctx) => {
211
+ ctx.body = { ok: true };
212
+ });
213
+ router.get("/debug-sentry", async () => {
214
+ throw new Error("Test Koa error!");
215
+ });
216
+
217
+ app.use(router.routes());
218
+ app.use(router.allowedMethods());
219
+ app.listen(3000);
220
+ ```
221
+
222
+ > **Note:** `setupKoaErrorHandler` has no `shouldHandleError` option — it captures all
223
+ > errors.
224
+
225
+ ---
226
+
227
+ ## Hapi
228
+
229
+ `setupHapiErrorHandler` is **async** — you must `await` it.
230
+ Internally registers a Hapi lifecycle extension on `onPreResponse`.
231
+
232
+ ```javascript
233
+ require("./instrument");
234
+ const Sentry = require("@sentry/node");
235
+ const Hapi = require("@hapi/hapi");
236
+
237
+ const init = async () => {
238
+ const server = Hapi.server({ port: 3000, host: "localhost" });
239
+
240
+ // ↓ MUST be awaited!
241
+ await Sentry.setupHapiErrorHandler(server);
242
+
243
+ server.route({
244
+ method: "GET",
245
+ path: "/debug-sentry",
246
+ handler: () => {
247
+ throw new Error("Test Hapi error!");
248
+ },
249
+ });
250
+
251
+ await server.start();
252
+ console.log("Server running on %s", server.info.uri);
253
+ };
254
+
255
+ init();
256
+ ```
257
+
258
+ > **Caution:** Forgetting `await` silently skips Sentry registration.
259
+ > No error is thrown.
260
+
261
+ ---
262
+
263
+ ## Connect
264
+
265
+ Error handler goes **before routes**.
266
+
267
+ ```javascript
268
+ require("./instrument");
269
+ const connect = require("connect");
270
+ const Sentry = require("@sentry/node");
271
+
272
+ const app = connect();
273
+
274
+ // ↓ Sentry BEFORE routes
275
+ Sentry.setupConnectErrorHandler(app);
276
+
277
+ app.use("/", (req, res, next) => {
278
+ res.setHeader("Content-Type", "application/json");
279
+ res.end(JSON.stringify({ hello: "world" }));
280
+ });
281
+
282
+ app.use("/debug-sentry", (req, res, next) => {
283
+ throw new Error("Test Connect error!");
284
+ });
285
+
286
+ // Your own error handler (after Sentry)
287
+ app.use((err, req, res, next) => {
288
+ res.statusCode = err.status || 500;
289
+ res.end("Internal Server Error");
290
+ });
291
+
292
+ require("http").createServer(app).listen(3000);
293
+ ```
294
+
295
+ ---
296
+
297
+ ## NestJS
298
+
299
+ > **NestJS has a dedicated skill: [`nestjs`](../nestjs/index.md)**
300
+ >
301
+ > NestJS uses a separate package (`@sentry/nestjs`) with NestJS-native error handling
302
+ > via `SentryGlobalFilter`, `SentryModule.forRoot()`, `@SentryExceptionCaptured`
303
+ > decorator, and GraphQL/Microservices support.
304
+ > Load that skill for complete NestJS error monitoring setup including `HttpException`
305
+ > filtering, custom filters, and background job isolation.
306
+
307
+ ---
308
+
309
+ ## Vanilla Node.js (`http` Module)
310
+
311
+ No framework integration needed — rely on the global `uncaughtException` /
312
+ `unhandledRejection` handlers plus manual `captureException` for caught errors.
313
+
314
+ ```javascript
315
+ require("./instrument");
316
+ const http = require("http");
317
+ const Sentry = require("@sentry/node");
318
+
319
+ const server = http.createServer(async (req, res) => {
320
+ try {
321
+ const data = await handleRequest(req);
322
+ res.writeHead(200, { "Content-Type": "application/json" });
323
+ res.end(JSON.stringify(data));
324
+ } catch (err) {
325
+ Sentry.captureException(err, {
326
+ tags: { path: req.url, method: req.method },
327
+ });
328
+ res.writeHead(500, { "Content-Type": "application/json" });
329
+ res.end(JSON.stringify({ error: "Internal Server Error" }));
330
+ }
331
+ });
332
+
333
+ server.listen(3000);
334
+ ```
335
+
336
+ ---
337
+
338
+ ## `captureException` — Full API
339
+
340
+ ```typescript
341
+ function captureException(
342
+ exception: unknown,
343
+ captureContext?: CaptureContext | ((scope: Scope) => Scope),
344
+ ): string; // returns EventId
345
+
346
+ type CaptureContext = Scope | Partial<ScopeContext> | ((scope: Scope) => Scope);
347
+
348
+ interface ScopeContext {
349
+ user?: User;
350
+ level?: "fatal" | "error" | "warning" | "log" | "info" | "debug";
351
+ extra?: Record<string, unknown>;
352
+ tags?: Record<string, Primitive>;
353
+ contexts?: Record<string, Record<string, unknown>>;
354
+ fingerprint?: string[];
355
+ }
356
+ ```
357
+
358
+ ```javascript
359
+ // Basic
360
+ Sentry.captureException(new Error("Something broke"));
361
+
362
+ // With inline CaptureContext
363
+ Sentry.captureException(error, {
364
+ level: "fatal",
365
+ tags: { order_id: orderId, payment_method: "stripe" },
366
+ user: { id: req.user.id, email: req.user.email },
367
+ extra: { requestBody: req.body, retryCount: 3 },
368
+ fingerprint: ["order-processing-failure", orderId],
369
+ contexts: {
370
+ order: { id: orderId, total: 99.99, currency: "USD" },
371
+ },
372
+ });
373
+
374
+ // Scope callback form — most flexible
375
+ Sentry.captureException(error, (scope) => {
376
+ scope.setTag("component", "payment");
377
+ scope.setLevel("error");
378
+ scope.setTransactionName("POST /orders");
379
+ return scope; // must return scope
380
+ });
381
+
382
+ // Non-Error values are accepted (but stack traces may be synthetic)
383
+ Sentry.captureException("something broke");
384
+ Sentry.captureException({ code: "AUTH_FAILED", userId: 42 });
385
+
386
+ // Capture and use the returned event ID
387
+ const eventId = Sentry.captureException(err);
388
+ res.status(500).json({ error: "Something went wrong", eventId });
389
+ ```
390
+
391
+ ---
392
+
393
+ ## `captureMessage`
394
+
395
+ ```typescript
396
+ function captureMessage(message: string, captureContext?: CaptureContext | SeverityLevel): string; // returns EventId
397
+
398
+ type SeverityLevel = "fatal" | "error" | "warning" | "log" | "info" | "debug";
399
+ ```
400
+
401
+ ```javascript
402
+ // Basic
403
+ Sentry.captureMessage("Payment gateway timeout");
404
+
405
+ // With severity level shorthand
406
+ Sentry.captureMessage("Disk usage above 90%", "warning");
407
+ Sentry.captureMessage("Cache miss rate critical", "fatal");
408
+ Sentry.captureMessage("User signed up", "info");
409
+
410
+ // With full context
411
+ Sentry.captureMessage("Rate limit exceeded", {
412
+ level: "warning",
413
+ tags: { service: "api-gateway", region: "us-east-1" },
414
+ user: { id: req.user.id },
415
+ extra: { requestsPerMinute: 1500, limit: 1000 },
416
+ fingerprint: ["rate-limit", req.headers["x-client-id"]],
417
+ });
418
+ ```
419
+
420
+ ---
421
+
422
+ ## Scope Management (v8+ — Hub Removed)
423
+
424
+ In SDK v8, `Hub` is removed.
425
+ Use the three scope types directly.
426
+
427
+ | Scope | Accessor | Lifetime | Use For |
428
+ | ------------- | ---------------------------- | ------------------------------ | ------------------------------- |
429
+ | **Global** | `Sentry.getGlobalScope()` | Process lifetime | App version, region, build ID |
430
+ | **Isolation** | `Sentry.getIsolationScope()` | Per HTTP request (auto-forked) | User identity, request metadata |
431
+ | **Current** | `Sentry.getCurrentScope()` | Narrow/temporary | Per-operation context |
432
+
433
+ **Priority (current wins):** Current > Isolation > Global
434
+
435
+ ```javascript
436
+ // All Sentry.setXXX() top-level methods write to the ISOLATION scope
437
+ Sentry.setTag("key", "value");
438
+ // identical to:
439
+ Sentry.getIsolationScope().setTag("key", "value");
440
+
441
+ // Global scope — survives the lifetime of the process
442
+ Sentry.getGlobalScope().setTag("server_region", "eu-west-1");
443
+ Sentry.getGlobalScope().setContext("runtime", {
444
+ name: "node",
445
+ version: process.version,
446
+ });
447
+ ```
448
+
449
+ ### `withScope` — Temporary Per-Capture Context
450
+
451
+ Primary tool for adding context to a single capture without contaminating other events.
452
+
453
+ ```javascript
454
+ Sentry.withScope((scope) => {
455
+ scope.setTag("payment_method", "stripe");
456
+ scope.setFingerprint(["stripe-payment-error"]);
457
+ scope.setLevel("error");
458
+ scope.setUser({ id: req.user.id });
459
+ scope.setContext("cart", { items: req.body.items.length });
460
+ scope.addBreadcrumb({ category: "payment", message: "Attempt #3", level: "info" });
461
+ Sentry.captureException(stripeError);
462
+ // All above ONLY applies to this one capture
463
+ });
464
+ ```
465
+
466
+ ### `withIsolationScope` — Full Isolation (Background Jobs)
467
+
468
+ Use for background jobs, workers, and queue processors where you need a completely clean
469
+ scope.
470
+
471
+ ```javascript
472
+ Sentry.withIsolationScope(async (scope) => {
473
+ scope.setUser({ id: job.userId });
474
+ scope.setTag("job_type", job.type);
475
+ scope.setTag("job_id", job.id);
476
+ await processJob(job); // all events inside are fully isolated from other jobs
477
+ });
478
+ ```
479
+
480
+ ### Scope Decision Guide
481
+
482
+ | Goal | API |
483
+ | ------------------------------------------ | ------------------------------------------------------ |
484
+ | Data on ALL events (app version, build ID) | `Sentry.getGlobalScope().setTag(...)` |
485
+ | Current request data | `Sentry.setTag(...)` (writes to isolation scope) |
486
+ | One specific capture only | `Sentry.withScope((scope) => { ... })` |
487
+ | Background job / worker | `Sentry.withIsolationScope(async (scope) => { ... })` |
488
+ | Inline on a single event | Second arg to `captureException(err, { tags: {...} })` |
489
+
490
+ ---
491
+
492
+ ## Context Enrichment
493
+
494
+ ### `setTag` / `setTags` — Indexed, Searchable
495
+
496
+ Tags are **indexed** — use them for filtering, grouping, and alerting.
497
+ Key: max 32 chars, `[a-zA-Z0-9_.:−]`. Value: max 200 chars.
498
+
499
+ ```javascript
500
+ Sentry.setTag("db_region", "us-east-1");
501
+ Sentry.setTag("feature_flag_new_ui", true);
502
+ Sentry.setTags({
503
+ service: "checkout",
504
+ version: "2.1.4",
505
+ region: "eu",
506
+ });
507
+ ```
508
+
509
+ ### `setContext` — Structured, Non-Searchable
510
+
511
+ Attaches structured data visible in the issue detail view.
512
+ Not indexed. Normalized to 3 levels deep.
513
+ The `type` key is reserved — don’t use it.
514
+
515
+ ```javascript
516
+ Sentry.setContext("order", {
517
+ id: orderId,
518
+ total: 99.99,
519
+ currency: "USD",
520
+ coupon: "SAVE20",
521
+ });
522
+ Sentry.setContext("database", {
523
+ host: "postgres.internal",
524
+ query_duration_ms: 4523,
525
+ active_connections: 19,
526
+ });
527
+ Sentry.setContext("order", null); // clear it
528
+ ```
529
+
530
+ ### `setUser` — User Identity
531
+
532
+ ```javascript
533
+ // On login (writes to isolation scope — safe per-request)
534
+ Sentry.setUser({
535
+ id: user.id,
536
+ email: user.email,
537
+ username: user.displayName,
538
+ subscription_tier: "pro", // custom fields accepted
539
+ });
540
+
541
+ // On logout
542
+ Sentry.setUser(null);
543
+
544
+ // Express middleware pattern — set per-request
545
+ app.use((req, res, next) => {
546
+ if (req.user) {
547
+ Sentry.setUser({ id: req.user.id, email: req.user.email });
548
+ }
549
+ next();
550
+ });
551
+ ```
552
+
553
+ ### `setExtra` / `setExtras` — Arbitrary Data
554
+
555
+ Non-indexed supplementary data.
556
+ Prefer `setContext` for structured objects.
557
+
558
+ ```javascript
559
+ Sentry.setExtra("server_memory_mb", process.memoryUsage().heapUsed / 1024 / 1024);
560
+ Sentry.setExtras({
561
+ uptime: process.uptime(),
562
+ node_version: process.version,
563
+ });
564
+ ```
565
+
566
+ ### Tags vs Context vs Extra
567
+
568
+ | Feature | Searchable? | Indexed? | Best For |
569
+ | ----------- | ------------ | -------- | -------------------------------------- |
570
+ | **Tags** | ✅ Yes | ✅ Yes | Filtering, grouping, alerting |
571
+ | **Context** | ❌ No | ❌ No | Structured debug info (nested objects) |
572
+ | **Extra** | ❌ No | ❌ No | Arbitrary debug values |
573
+ | **User** | ✅ Partially | ✅ Yes | User attribution and filtering |
574
+
575
+ ---
576
+
577
+ ## Breadcrumbs
578
+
579
+ ### Automatic Breadcrumbs (Zero Config)
580
+
581
+ | Type | What’s Captured |
582
+ | --------- | ------------------------------------------------- |
583
+ | `http` | Outgoing HTTP requests (URL, method, status code) |
584
+ | `console` | `console.log`, `warn`, `error` calls |
585
+ | `db` | Database queries (via OTel auto-instrumentation) |
586
+
587
+ ### Manual Breadcrumbs
588
+
589
+ ```javascript
590
+ Sentry.addBreadcrumb({
591
+ category: "auth",
592
+ message: `User ${user.email} authenticated`,
593
+ level: "info",
594
+ data: { method: "oauth2", provider: "google" },
595
+ });
596
+
597
+ Sentry.addBreadcrumb({
598
+ type: "http",
599
+ category: "http",
600
+ data: {
601
+ method: "POST",
602
+ url: "https://api.stripe.com/v1/charges",
603
+ status_code: 402,
604
+ },
605
+ level: "warning",
606
+ });
607
+
608
+ Sentry.addBreadcrumb({
609
+ type: "query",
610
+ category: "db.query",
611
+ message: "SELECT * FROM orders WHERE user_id = ?",
612
+ data: { db: "postgres", duration_ms: 42 },
613
+ });
614
+ ```
615
+
616
+ ### Breadcrumb Properties
617
+
618
+ | Key | Type | Values |
619
+ | ----------- | ------ | ------------------------------------------------------------------------------------------------------------------ |
620
+ | `type` | string | `"default"` \| `"debug"` \| `"error"` \| `"info"` \| `"http"` \| `"navigation"` \| `"query"` \| `"ui"` \| `"user"` |
621
+ | `category` | string | Dot-notation: `"auth"`, `"db.query"`, `"job.start"` |
622
+ | `message` | string | Human-readable description |
623
+ | `level` | string | `"fatal"` \| `"error"` \| `"warning"` \| `"log"` \| `"info"` \| `"debug"` |
624
+ | `timestamp` | number | Unix timestamp (auto-set if omitted) |
625
+ | `data` | object | Arbitrary key/value data |
626
+
627
+ ---
628
+
629
+ ## `beforeSend` and Filtering Hooks
630
+
631
+ ### `beforeSend` — Modify or Drop Error Events
632
+
633
+ Last chance to modify or drop events.
634
+ Runs after all event processors.
635
+ Return `null` to drop.
636
+ **Only one `beforeSend` is allowed** — use `addEventProcessor` for multiple processors.
637
+
638
+ ```javascript
639
+ Sentry.init({
640
+ beforeSend(event, hint) {
641
+ const err = hint.originalException;
642
+
643
+ // Drop in development
644
+ if (process.env.NODE_ENV === "development") return null;
645
+
646
+ // Drop specific error types
647
+ if (err instanceof ConnectionResetError) return null;
648
+ if (err?.message?.includes("ECONNRESET")) return null;
649
+
650
+ // Scrub PII from user object
651
+ if (event.user) {
652
+ delete event.user.email;
653
+ delete event.user.ip_address;
654
+ }
655
+
656
+ // Scrub sensitive keys from request body
657
+ if (event.request?.data) {
658
+ try {
659
+ const body = JSON.parse(event.request.data as string);
660
+ delete body.password;
661
+ delete body.token;
662
+ event.request.data = JSON.stringify(body);
663
+ } catch {}
664
+ }
665
+
666
+ // Custom fingerprint from error properties
667
+ if (err instanceof ApiError) {
668
+ event.fingerprint = ["api-error", String(err.statusCode), err.endpoint];
669
+ }
670
+
671
+ // Filter noisy breadcrumbs
672
+ if (event.breadcrumbs?.values) {
673
+ event.breadcrumbs.values = event.breadcrumbs.values.filter(
674
+ (bc) => !bc.data?.url?.includes("/health")
675
+ );
676
+ }
677
+
678
+ return event;
679
+ },
680
+
681
+ // Drop specific transaction/span events
682
+ beforeSendTransaction(event) {
683
+ if (event.transaction === "GET /health") return null;
684
+ if (event.transaction === "GET /ping") return null;
685
+ return event;
686
+ },
687
+ });
688
+ ```
689
+
690
+ ### `beforeBreadcrumb` — Filter or Mutate Breadcrumbs
691
+
692
+ ```javascript
693
+ Sentry.init({
694
+ beforeBreadcrumb(breadcrumb, hint) {
695
+ // Drop health-check HTTP requests
696
+ if (breadcrumb.type === "http" && breadcrumb.data?.url?.includes("/health")) {
697
+ return null;
698
+ }
699
+
700
+ // Redact auth tokens from URLs
701
+ if (breadcrumb.type === "http" && breadcrumb.data?.url) {
702
+ try {
703
+ const url = new URL(breadcrumb.data.url);
704
+ url.searchParams.delete("token");
705
+ url.searchParams.delete("api_key");
706
+ breadcrumb.data.url = url.toString();
707
+ } catch {}
708
+ }
709
+
710
+ return breadcrumb;
711
+ },
712
+ maxBreadcrumbs: 50, // default: 100
713
+ });
714
+ ```
715
+
716
+ ### `ignoreErrors` — Pattern-Based Filtering
717
+
718
+ ```javascript
719
+ Sentry.init({
720
+ ignoreErrors: ["Non-Error exception captured", /^ECONNRESET/, /^ETIMEDOUT/, /^socket hang up/],
721
+ ignoreTransactions: ["GET /health", "GET /ping", "GET /metrics", /^GET \/internal\//],
722
+ });
723
+ ```
724
+
725
+ ---
726
+
727
+ ## Fingerprinting and Custom Grouping
728
+
729
+ All events have a `fingerprint` array.
730
+ Events with the same fingerprint group into the same Sentry issue.
731
+
732
+ ### Per-Capture Fingerprinting
733
+
734
+ ```javascript
735
+ Sentry.captureException(error, {
736
+ fingerprint: ["payment-declined", req.body.payment_method],
737
+ });
738
+ ```
739
+
740
+ ### `withScope` Fingerprinting
741
+
742
+ ```javascript
743
+ Sentry.withScope((scope) => {
744
+ scope.setFingerprint([req.method, req.path, String(err.statusCode)]);
745
+ Sentry.captureException(err);
746
+ });
747
+ ```
748
+
749
+ ### `beforeSend` Fingerprinting (Global Rules)
750
+
751
+ ```javascript
752
+ Sentry.init({
753
+ beforeSend(event, hint) {
754
+ const err = hint.originalException;
755
+
756
+ // All DB connection errors → one group
757
+ if (err instanceof DatabaseConnectionError) {
758
+ event.fingerprint = ["database-connection-error"];
759
+ }
760
+
761
+ // Group ApiErrors by status + endpoint
762
+ if (err instanceof ApiError) {
763
+ event.fingerprint = ["api-error", String(err.statusCode), err.endpoint];
764
+ }
765
+
766
+ // Extend Sentry's default algorithm (keep stack-trace hash + add dimension)
767
+ if (err?.code) {
768
+ event.fingerprint = ["{{ default }}", err.code];
769
+ }
770
+
771
+ return event;
772
+ },
773
+ });
774
+ ```
775
+
776
+ ### Template Variables
777
+
778
+ | Variable | Description |
779
+ | ------------------- | ------------------------------------------------------------ |
780
+ | `{{ default }}` | Sentry’s normally computed hash — extend rather than replace |
781
+ | `{{ transaction }}` | Current transaction name |
782
+ | `{{ function }}` | Top function in stack trace |
783
+ | `{{ type }}` | Exception type name |
784
+
785
+ ---
786
+
787
+ ## Event Processors
788
+
789
+ Unlike `beforeSend` (one allowed), multiple event processors can be registered.
790
+ Order is not guaranteed.
791
+ `beforeSend` always runs last.
792
+
793
+ ```javascript
794
+ // Runs on every event — enrich with deploy metadata
795
+ Sentry.addEventProcessor((event, hint) => {
796
+ event.tags = {
797
+ ...event.tags,
798
+ git_sha: process.env.GIT_SHA ?? "unknown",
799
+ deployed_by: process.env.DEPLOY_USER ?? "unknown",
800
+ };
801
+ return event;
802
+ });
803
+
804
+ // Drop events with a custom ignore flag
805
+ Sentry.addEventProcessor((event, hint) => {
806
+ if ((hint.originalException as any)?.ignore_in_sentry === true) return null;
807
+ return event;
808
+ });
809
+
810
+ // Scope-level processor (only inside withScope callback)
811
+ Sentry.withScope((scope) => {
812
+ scope.addEventProcessor((event) => {
813
+ event.tags = { ...event.tags, batch_job: "true" };
814
+ return event;
815
+ });
816
+ Sentry.captureException(new Error("job failed"));
817
+ });
818
+ ```
819
+
820
+ **`addEventProcessor` vs `beforeSend`:**
821
+
822
+ | | `addEventProcessor` | `beforeSend` |
823
+ | ----------- | ------------------------------- | ------------- |
824
+ | Count | Unlimited | One only |
825
+ | Order | Undefined (before `beforeSend`) | Always last |
826
+ | Async | ✅ Yes | ✅ Yes |
827
+ | Drop events | Return `null` | Return `null` |
828
+
829
+ ---
830
+
831
+ ## `requestDataIntegration` — Per-Request Data
832
+
833
+ Auto-enabled. Attaches HTTP request data to all events during a request.
834
+ Each framework auto-forks an isolation scope per request via OpenTelemetry
835
+ `AsyncLocalStorage` — concurrent requests stay separate.
836
+
837
+ | Field | Captured | Notes |
838
+ | -------------- | ------------- | ---------------------------------------------------------------------- |
839
+ | `url` | ✅ Always | Full request URL |
840
+ | `method` | ✅ Always | GET, POST, etc. |
841
+ | `headers` | ✅ Always | Auth header scrubbed automatically |
842
+ | `query_string` | ✅ Always | URL query params |
843
+ | `data` (body) | ✅ Default on | Controlled by `dataCollection` (`httpBodies`); set to `[]` to opt out |
844
+ | `cookies` | ✅ Default on | Controlled by `dataCollection` (`cookies`); set to `false` to opt out |
845
+ | `ip_address` | ✅ Default on | Controlled by `dataCollection` (`userInfo`); set to `false` to opt out |
846
+
847
+ ```javascript
848
+ Sentry.init({
849
+ dataCollection: {
850
+ // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
851
+ // https://docs.sentry.io/platforms/javascript/guides/node/configuration/options/#dataCollection
852
+ // userInfo: false,
853
+ // httpBodies: [],
854
+ },
855
+ integrations: [
856
+ Sentry.requestDataIntegration({
857
+ include: {
858
+ cookies: true,
859
+ data: true, // request body
860
+ headers: true,
861
+ ip: true,
862
+ query_string: true,
863
+ url: true,
864
+ user: { id: true, username: true, email: false },
865
+ },
866
+ }),
867
+ ],
868
+ });
869
+ ```
870
+
871
+ ---
872
+
873
+ ## Error Chains
874
+
875
+ `linkedErrorsIntegration` is auto-enabled and follows the standard `Error.cause` chain.
876
+
877
+ ```javascript
878
+ // Standard Error.cause — captured automatically
879
+ try {
880
+ await connectToDatabase();
881
+ } catch (dbError) {
882
+ throw new Error("Failed to process order", { cause: dbError });
883
+ // Sentry captures BOTH errors as a chain
884
+ }
885
+
886
+ // Configure depth (default: 5)
887
+ Sentry.init({
888
+ integrations: [Sentry.linkedErrorsIntegration({ key: "cause", limit: 5 })],
889
+ });
890
+ ```
891
+
892
+ ### `extraErrorDataIntegration` — Custom Error Properties
893
+
894
+ Captures non-standard properties on Error subclasses:
895
+
896
+ ```javascript
897
+ Sentry.init({
898
+ integrations: [Sentry.extraErrorDataIntegration({ depth: 3 })],
899
+ });
900
+
901
+ class HttpError extends Error {
902
+ constructor(message, response) {
903
+ super(message);
904
+ this.statusCode = response.status; // captured in extras
905
+ this.responseBody = response.body; // captured in extras
906
+ this.endpoint = response.url; // captured in extras
907
+ }
908
+ }
909
+ ```
910
+
911
+ ---
912
+
913
+ ## Lifecycle: Flush Before Shutdown
914
+
915
+ `@sentry/node` batches events and sends asynchronously.
916
+ Always flush before process exit to avoid losing the last events.
917
+
918
+ ```javascript
919
+ // Graceful shutdown — HTTP server
920
+ process.on("SIGTERM", async () => {
921
+ server.close(async () => {
922
+ await Sentry.flush(2000); // wait up to 2s for queue to drain
923
+ process.exit(0);
924
+ });
925
+ });
926
+
927
+ // Serverless (Lambda, Cloud Functions) — close disables SDK after flush
928
+ export const handler = async (event) => {
929
+ try {
930
+ return await processEvent(event);
931
+ } catch (err) {
932
+ Sentry.captureException(err);
933
+ await Sentry.close(2000); // flush + disable before function freezes
934
+ throw err;
935
+ }
936
+ };
937
+ ```
938
+
939
+ ---
940
+
941
+ ## `Sentry.init()` — Error-Relevant Options
942
+
943
+ ```typescript
944
+ Sentry.init({
945
+ // Identity
946
+ dsn?: string; // also: SENTRY_DSN env var
947
+ release?: string; // "my-app@1.2.3+abc123"
948
+ environment?: string; // default: "production"
949
+ serverName?: string; // hostname
950
+ enabled?: boolean; // default: true
951
+
952
+ // Sampling
953
+ sampleRate?: number; // 0.0–1.0 error event sample rate
954
+ tracesSampleRate?: number; // 0.0–1.0 transaction sample rate
955
+
956
+ // Data limits
957
+ maxBreadcrumbs?: number; // default: 100
958
+ maxValueLength?: number; // truncate long strings
959
+ normalizeDepth?: number; // default: 3
960
+
961
+ // Privacy
962
+ dataCollection?: DataCollectionOptions; // omitted => falls back to sendDefaultPii (conservative); pass an object (even {}) to enable permissive collection, then opt out per category
963
+
964
+ // Filtering
965
+ ignoreErrors?: Array<string | RegExp>;
966
+ ignoreTransactions?: Array<string | RegExp>;
967
+
968
+ // Hooks
969
+ beforeSend?: (event: Event, hint: EventHint) => Event | null;
970
+ beforeSendTransaction?: (event: Event, hint: EventHint) => Event | null;
971
+ beforeBreadcrumb?: (breadcrumb: Breadcrumb, hint?: BreadcrumbHint) => Breadcrumb | null;
972
+
973
+ // Node-specific
974
+ enableLogs?: boolean; // default: false — Sentry.logger.*
975
+ attachStacktrace?: boolean; // add stack traces to captureMessage
976
+ includeLocalVariables?: boolean; // include local vars in stack frames
977
+ onFatalError?: (error: Error) => void;
978
+ shutdownTimeout?: number; // default: 2000ms
979
+ });
980
+ ```
981
+
982
+ ---
983
+
984
+ ## Bun
985
+
986
+ `@sentry/bun` is a thin wrapper over `@sentry/node`. The API is identical — use
987
+ `--preload` instead of `require("./instrument")` first.
988
+
989
+ ```typescript
990
+ // instrument.ts
991
+ import * as Sentry from "@sentry/bun";
992
+
993
+ Sentry.init({
994
+ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
995
+ tracesSampleRate: 1.0,
996
+ dataCollection: {
997
+ // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit:
998
+ // https://docs.sentry.io/platforms/javascript/guides/node/configuration/options/#dataCollection
999
+ // userInfo: false,
1000
+ // httpBodies: [],
1001
+ },
1002
+ });
1003
+ ```
1004
+
1005
+ ```bash
1006
+ bun --preload ./instrument.ts server.ts
1007
+ ```
1008
+
1009
+ For `Bun.serve()`:
1010
+
1011
+ ```typescript
1012
+ import * as Sentry from "@sentry/bun";
1013
+
1014
+ const server = Bun.serve({
1015
+ port: 3000,
1016
+ fetch(request) {
1017
+ return new Response("Hello from Bun!");
1018
+ },
1019
+ error(error) {
1020
+ Sentry.captureException(error); // manual — no setupErrorHandler for Bun.serve
1021
+ return new Response("Internal Server Error", { status: 500 });
1022
+ },
1023
+ });
1024
+ ```
1025
+
1026
+ > **Profiling:** `@sentry/profiling-node` uses a native addon — incompatible with Bun’s
1027
+ > runtime. Omit `nodeProfilingIntegration()` in Bun apps.
1028
+
1029
+ ---
1030
+
1031
+ ## Deno
1032
+
1033
+ ```typescript
1034
+ // instrument.ts
1035
+ import * as Sentry from "npm:@sentry/deno";
1036
+
1037
+ Sentry.init({
1038
+ dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
1039
+ tracesSampleRate: 1.0,
1040
+ });
1041
+ ```
1042
+
1043
+ ```typescript
1044
+ // server.ts
1045
+ import "../instrument.ts";
1046
+ import * as Sentry from "npm:@sentry/deno";
1047
+
1048
+ Deno.serve({ port: 3000 }, async (request) => {
1049
+ try {
1050
+ return new Response("Hello from Deno!");
1051
+ } catch (error) {
1052
+ Sentry.captureException(error);
1053
+ return new Response("Internal Server Error", { status: 500 });
1054
+ }
1055
+ });
1056
+ ```
1057
+
1058
+ > **Requirements:** Deno 2+. Run with `--allow-net --allow-env --allow-read`. No
1059
+ > `setupExpressErrorHandler` equivalent — use `try/catch` + `captureException`.
1060
+
1061
+ ---
1062
+
1063
+ ## Quick Reference
1064
+
1065
+ ```javascript
1066
+ // Init
1067
+ Sentry.init({ dsn: "...", tracesSampleRate: 1.0 });
1068
+
1069
+ // Capture
1070
+ Sentry.captureException(new Error("oops"));
1071
+ Sentry.captureException(err, { tags: { source: "api" }, level: "fatal" });
1072
+ Sentry.captureMessage("Something happened", "warning");
1073
+
1074
+ // Context (→ isolation scope, auto-forked per request)
1075
+ Sentry.setUser({ id: 1, email: "user@example.com" });
1076
+ Sentry.setTag("region", "us-east");
1077
+ Sentry.setTags({ service: "checkout", version: "2.0" });
1078
+ Sentry.setContext("cart", { items: 3, total: 49.99 });
1079
+ Sentry.addBreadcrumb({ category: "auth", message: "login", level: "info" });
1080
+
1081
+ // Scoped capture (temporary context, one event only)
1082
+ Sentry.withScope((scope) => {
1083
+ scope.setTag("temp_tag", "only-this-event");
1084
+ scope.setFingerprint(["my-custom-group"]);
1085
+ scope.setLevel("warning");
1086
+ Sentry.captureException(err);
1087
+ });
1088
+
1089
+ // Background job isolation
1090
+ await Sentry.withIsolationScope(async (scope) => {
1091
+ scope.setUser({ id: job.userId });
1092
+ await processJob(job);
1093
+ });
1094
+
1095
+ // Global (all events, process lifetime)
1096
+ Sentry.getGlobalScope().setTag("app", "my-api");
1097
+
1098
+ // Framework error handlers — placement matters!
1099
+ Sentry.setupExpressErrorHandler(app); // Express: AFTER routes
1100
+ Sentry.setupFastifyErrorHandler(app); // Fastify: BEFORE routes
1101
+ Sentry.setupKoaErrorHandler(app); // Koa: FIRST middleware
1102
+ await Sentry.setupHapiErrorHandler(server); // Hapi: BEFORE routes, MUST await
1103
+ Sentry.setupConnectErrorHandler(app); // Connect: BEFORE routes
1104
+
1105
+ // Shutdown
1106
+ await Sentry.flush(2000);
1107
+ ```
1108
+
1109
+ ---
1110
+
1111
+ ## Troubleshooting
1112
+
1113
+ | Issue | Cause | Solution |
1114
+ | ----------------------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
1115
+ | Errors not appearing in Sentry | `instrument.js` loaded too late | Ensure it’s the first `require()` or loaded via `--import` / `--preload` before app code |
1116
+ | Express errors not captured | `setupExpressErrorHandler` placed before routes | Move it **after** all route definitions |
1117
+ | Fastify errors not captured | `setupFastifyErrorHandler` placed after routes | Move it **before** route definitions (opposite of Express) |
1118
+ | Hapi error handler silently fails | `setupHapiErrorHandler` not awaited | Must `await Sentry.setupHapiErrorHandler(server)` — it’s the only async handler |
1119
+ | NestJS `HttpException` not captured | Intentional — `SentryGlobalFilter` skips control flow exceptions | Create a custom filter extending `SentryGlobalFilter` and override `catch()` to capture `HttpException` if desired |
1120
+ | `setUser()` leaks between requests | Using global scope for user data | Use `Sentry.setUser()` (isolation scope) — it’s auto-forked per request by framework integrations |
1121
+ | `withScope` changes persisting | Wrong scope layer | `withScope` creates a temporary current scope — changes don’t survive the callback. Use `setTag()` for request-lifetime data |
1122
+ | `beforeSend` returning wrong type | Not returning `event` or `null` | `beforeSend` must return the event object or `null` to drop — `undefined` causes silent failures |
1123
+ | Breadcrumbs not showing | `maxBreadcrumbs: 0` | Check init config — default is 100; set to desired max |
1124
+ | Duplicate error events | Multiple capture paths | Ensure only one handler captures each error — e.g., don’t both re-throw and call `captureException` |
1125
+ | Stack traces show minified code | Source maps not uploaded | Configure `@sentry/cli` sourcemap upload in your build pipeline |