{"_id":"@aditya_kbr01/incidentwatch-sdk","_rev":"2-926c00ab581bcbda835219efb0043ae1","name":"@aditya_kbr01/incidentwatch-sdk","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@aditya_kbr01/incidentwatch-sdk","version":"1.0.0","keywords":["monitoring","logging","error-tracking","nodejs","incident","sdk","observability","debugging"],"author":{"name":"Aditya"},"license":"MIT","_id":"@aditya_kbr01/incidentwatch-sdk@1.0.0","maintainers":[{"name":"aditya_kbr01","email":"aditykbr01@gmail.com"}],"dist":{"shasum":"50ee8aa5ab2cfed11da2570e8b66943468fefb2a","tarball":"https://registry.npmjs.org/@aditya_kbr01/incidentwatch-sdk/-/incidentwatch-sdk-1.0.0.tgz","fileCount":21,"integrity":"sha512-mfhegzd1YOt5fG2K17IyZwxff3/fmOcEcNxaVOrzEbgRNN9KA/+oquX0q8b5LswXMSpnBTLZCn2bYMa53l04Nw==","signatures":[{"sig":"MEQCIFxrnJsL3yno6J5yVJBwFvh97nUVMOM8/YT0WGxuGXNYAiA+pStXIxM74VTb4fzB+bD8PK6fuVLo4IkAEdF5jd3TEA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98941},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.mjs","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"86d61804827d06e28b97b00a2561f2a5113f01c6","scripts":{"dev":"bun run --hot src/index.ts","build":"bun run build:js && bun run build:types","build:js":"bun build ./src/index.ts --outfile ./dist/index.mjs --target node --format esm --minify --external express --external axios --external morgan --external winston --external p-queue --external uuid && bun build ./src/index.ts --outfile ./dist/index.cjs --target node --format cjs --minify --external express --external axios --external morgan --external winston --external p-queue --external uuid","build:types":"tsc --emitDeclarationOnly","link:global":"npm run build && npm link","prepare:local":"npm run build && npm pack","prepublishOnly":"npm run build"},"_npmUser":{"name":"aditya_kbr01","email":"aditykbr01@gmail.com"},"_npmVersion":"11.9.0","description":"One-line setup. Zero manual try/catch. Full incident coverage for Node.js apps.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"uuid":"^9.0.0","axios":"^1.6.0","morgan":"^1.10.0","p-queue":"^7.3.4","winston":"^3.11.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.2","@types/bun":"latest","typescript":"^5.0.0","@types/node":"^20.0.0","@types/uuid":"9","@types/morgan":"^1.9.10"},"peerDependencies":{"express":">=4.0.0"},"peerDependenciesMeta":{"express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/incidentwatch-sdk_1.0.0_1777795128034_0.7134881697824556","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aditya_kbr01/incidentwatch-sdk","version":"1.0.1","description":"One-line setup. Zero manual try/catch. Full incident coverage for Node.js apps.","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.ts","type":"module","exports":{".":{"import":"./dist/index.mjs","require":"./dist/index.cjs","types":"./dist/index.d.ts"}},"scripts":{"dev":"bun run --hot src/index.ts","build":"bun run build:js && bun run build:types","build:js":"bun build ./src/index.ts --outfile ./dist/index.mjs --target node --format esm --minify --external express --external axios --external morgan --external winston --external p-queue --external uuid && bun build ./src/index.ts --outfile ./dist/index.cjs --target node --format cjs --minify --external express --external axios --external morgan --external winston --external p-queue --external uuid","build:types":"tsc --emitDeclarationOnly","prepare:local":"npm run build && npm pack","link:global":"npm run build && npm link","prepublishOnly":"npm run build"},"keywords":["monitoring","logging","error-tracking","nodejs","incident","sdk","observability","debugging"],"author":{"name":"Aditya"},"license":"MIT","dependencies":{"axios":"^1.6.0","morgan":"^1.10.0","p-queue":"^7.3.4","uuid":"^9.0.0","winston":"^3.11.0"},"devDependencies":{"@types/bun":"latest","@types/morgan":"^1.9.10","@types/node":"^20.0.0","@types/uuid":"9","express":"^4.18.2","typescript":"^5.9.3"},"peerDependencies":{"express":">=4.0.0"},"peerDependenciesMeta":{"express":{"optional":true}},"engines":{"node":">=18"},"publishConfig":{"access":"public"},"gitHead":"08f006f8ab36ac0c2aefe8911ef697a9f4f89a71","_id":"@aditya_kbr01/incidentwatch-sdk@1.0.1","_nodeVersion":"24.14.0","_npmVersion":"11.9.0","dist":{"integrity":"sha512-XH/pNXt6GNI9pS3YmqQ5jS3RidlFh+zFiRz1RNdc6eeVi/5cfkhDsupJb1vYFlBnjdHPQvXJ4+T48V96j0vA6Q==","shasum":"bc17f728f42da4681f0ce3e4fbe2dd46c7b68fef","tarball":"https://registry.npmjs.org/@aditya_kbr01/incidentwatch-sdk/-/incidentwatch-sdk-1.0.1.tgz","fileCount":21,"unpackedSize":99365,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIF6jd2pynDxcgg91CzSMc72K4r3AiHufOVN6KwILEA7LAiBpyeGL2Sp8SkFhbkNwiijyr3Dd9JBlWNfaEaCbXOFNmg=="}]},"_npmUser":{"name":"aditya_kbr01","email":"aditykbr01@gmail.com"},"directories":{},"maintainers":[{"name":"aditya_kbr01","email":"aditykbr01@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/incidentwatch-sdk_1.0.1_1777801474679_0.246007973958289"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-03T07:58:47.964Z","modified":"2026-05-03T09:44:34.946Z","1.0.0":"2026-05-03T07:58:48.186Z","1.0.1":"2026-05-03T09:44:34.825Z"},"author":{"name":"Aditya"},"license":"MIT","keywords":["monitoring","logging","error-tracking","nodejs","incident","sdk","observability","debugging"],"description":"One-line setup. Zero manual try/catch. Full incident coverage for Node.js apps.","maintainers":[{"name":"aditya_kbr01","email":"aditykbr01@gmail.com"}],"readme":"# @incidentwatch/sdk\r\n\r\n**One-line setup. Zero manual try/catch. Full incident coverage for Node.js apps.**\r\n\r\nIncidentWatch SDK automatically captures crashes, errors, performance issues, and sends detailed incident reports to your platform. No need for `try-catch` everywhere.\r\n\r\n---\r\n\r\n## 🚀 Quick Start (30 seconds)\r\n\r\n### 1. Install\r\n\r\n```bash\r\nnpm install @incidentwatch/sdk\r\n# or\r\nbun add @incidentwatch/sdk\r\n```\r\n\r\n### 2. Initialize (top of your entry file)\r\n\r\n```javascript\r\nconst { init } = require(\"@incidentwatch/sdk\");\r\n\r\nconst iw = init({\r\n  apiKey: \"iw_xxxxx\", // Get from https://app.incidentwatch.io\r\n  serverId: \"prod-api-1\", // Your server identifier\r\n});\r\n```\r\n\r\n**Done!** Your entire Express app is now monitored.\r\n\r\n---\r\n\r\n## 📋 Configuration\r\n\r\nAll options (required + optional):\r\n\r\n| Property              | Type                    | Default                                                       | Description                              |\r\n| --------------------- | ----------------------- | ------------------------------------------------------------- | ---------------------------------------- |\r\n| `apiKey`              | `string`                | **Required**                                                  | Your API key                             |\r\n| `serverId`            | `string`                | **Required**                                                  | Server name (e.g. `prod-api-1`)          |\r\n| `platformUrl`         | `string`                | `http://localhost:8000/api/v1/sdk`                            | Custom platform URL                      |\r\n| `environment`         | `string`                | `NODE_ENV`                                                    | `production`, `staging`, etc.            |\r\n| `debug`               | `boolean`               | `false`                                                       | Enable verbose SDK logs                  |\r\n| `slowThresholdMs`     | `number`                | `5000`                                                        | Alert threshold for slow operations (ms) |\r\n| `breadcrumbLimit`     | `number`                | `50`                                                          | Max breadcrumbs per incident             |\r\n| `heartbeatIntervalMs` | `number`                | `5000`                                                        | Heartbeat frequency (ms)                 |\r\n| `ignoreErrors`        | `Array<string\\|RegExp>` | `[ECONNRESET, ...]`                                           | Errors to skip                           |\r\n| `integrations`        | `object`                | `{ express: true, axios: true, fetch: true, console: false }` | Toggle integrations                      |\r\n| `logger`              | `object`                | `{ level: 'info', prettyPrint: true, filePath: null }`        | Winston logger config                    |\r\n| `transport`           | `object`                | `{ timeout: 8000, retries: 3, retryDelay: 1000 }`             | HTTP transport config                    |\r\n\r\n### Nested Config\r\n\r\n```javascript\r\ninit({\r\n  apiKey: \"iw_xxxxx\",\r\n  serverId: \"prod-1\",\r\n  integrations: {\r\n    express: true,\r\n    axios: true,\r\n    fetch: true,\r\n    console: true, // Capture console.error as incidents\r\n  },\r\n  logger: {\r\n    level: \"debug\",\r\n    prettyPrint: true,\r\n    filePath: \"/var/log/incidentwatch.log\", // Optional file output\r\n  },\r\n  transport: {\r\n    timeout: 5000,\r\n    retries: 5,\r\n    retryDelay: 2000,\r\n  },\r\n});\r\n```\r\n\r\n---\r\n\r\n## 🛠️ How It Works\r\n\r\n### 1. Auto-Patching (The \"Magic\")\r\n\r\nSDK monkey-patches popular libraries so you don't write any extra code:\r\n\r\n- **Express**: Intercepts `app.listen()` to auto-inject error middleware + Morgan logger. Catches sync throws, async route failures, and `next(err)` calls (5xx only).\r\n- **Axios & Fetch**: Tracks all outgoing HTTP calls. Network errors → SEV2 incident. 5xx responses → SEV2 incident. Slow calls → warning log.\r\n\r\n### 2. Global Hooks (System-Level Safety)\r\n\r\n| Hook                          | Severity | Behavior                                |\r\n| ----------------------------- | -------- | --------------------------------------- |\r\n| `uncaughtException`           | SEV1     | Captures error, then exits process      |\r\n| `unhandledRejection`          | SEV2     | Captures error, process continues       |\r\n| `SIGTERM` / `SIGINT`          | —        | Flushes pending incidents, clean exit   |\r\n| `MaxListenersExceededWarning` | SEV3     | Captures as incident (memory leak risk) |\r\n\r\n### 3. Breadcrumbs\r\n\r\nEvery incident includes the last 50 events leading up to it:\r\n\r\n| Breadcrumb                          | When                     |\r\n| ----------------------------------- | ------------------------ |\r\n| `http.request`                      | Incoming Express request |\r\n| `http.error`                        | Express error (5xx)      |\r\n| `http.outgoing` / `http.response`   | Axios call               |\r\n| `fetch.outgoing` / `fetch.response` | Fetch call               |\r\n| `timer.start` / `timer.end`         | `startTimer()` call      |\r\n| `async.start` / `async.error`       | `wrapAsync()` call       |\r\n\r\n### 4. Circuit Breaker\r\n\r\nIf the platform is unreachable for 5+ consecutive attempts, the SDK opens its circuit breaker to prevent blocking your app. Resets after 60 seconds.\r\n\r\n---\r\n\r\n## 💡 DX Features (Developer Experience)\r\n\r\n### captureMessage() — Log non-error incidents\r\n\r\n```javascript\r\nawait iw.captureMessage(\"Database pool running low\", {\r\n  severity: \"SEV2\",\r\n  tags: [\"database\", \"pool\"],\r\n  context: { poolSize: 10, active: 9 },\r\n});\r\n```\r\n\r\n### setTag() / setContext() / setUser() — Global metadata\r\n\r\nThese apply to **all subsequent incidents**:\r\n\r\n```javascript\r\niw.setTag(\"team\", \"backend\");\r\niw.setTag(\"version\", \"2.1.0\");\r\niw.setContext(\"region\", \"us-east-1\");\r\niw.setUser({ id: \"user-123\", email: \"dev@test.com\" });\r\n```\r\n\r\n### withScope() — Isolated context for one operation\r\n\r\n```javascript\r\nawait iw.withScope(\r\n  {\r\n    tags: [\"checkout-flow\"],\r\n    context: { cartId: \"cart-456\" },\r\n    user: { id: \"buyer-789\" },\r\n  },\r\n  async () => {\r\n    await processPayment(); // Any incidents here get checkout context\r\n  },\r\n);\r\n// Scope resets after fn completes\r\n```\r\n\r\n### wrapAsync() — Auto-catch non-Express async functions\r\n\r\n```javascript\r\nconst sendEmail = iw.wrapAsync(async (to, body) => {\r\n  await mailer.send(to, body); // If this throws → SDK captures it\r\n}, \"sendEmail\");\r\n\r\nawait sendEmail(\"user@test.com\", { subject: \"Hello\" });\r\n```\r\n\r\n### startTimer() — Performance monitoring\r\n\r\n```javascript\r\nconst done = iw.startTimer(\"database-query\", { table: \"users\" });\r\nconst results = await db.query(\"SELECT * FROM users\");\r\ndone(); // If > slowThresholdMs → SEV3 incident auto-created\r\n```\r\n\r\n### runWithRequestId() — Correlate incidents to requests\r\n\r\n```javascript\r\napp.use((req, res, next) => {\r\n  iw.runWithRequestId(req.headers[\"x-request-id\"] || uuid(), next);\r\n});\r\n\r\n// All incidents during this request will have requestId in context\r\n```\r\n\r\n### getStatus() — SDK health check\r\n\r\n```javascript\r\nconst status = iw.getStatus();\r\n// Returns:\r\n// {\r\n//   initialized: true,\r\n//   version: '1.0.0',\r\n//   integrations: { express: true, axios: true, fetch: true, console: false },\r\n//   circuitBreakerOpen: false,\r\n//   config: { environment: 'production', serverId: 'prod-1', ... },\r\n// }\r\n```\r\n\r\n### shutdown() — Graceful cleanup\r\n\r\n```javascript\r\n// In your shutdown handler\r\nprocess.on(\"SIGTERM\", async () => {\r\n  await require(\"@incidentwatch/sdk\").shutdown();\r\n  process.exit(0);\r\n});\r\n```\r\n\r\n### Integration Toggles\r\n\r\n```javascript\r\n// Runtime toggle\r\niw.disableIntegration(\"console\"); // Stop capturing console.error\r\niw.enableIntegration(\"console\"); // Re-enable\r\n\r\n// All at once\r\niw.disableAllIntegrations();\r\niw.enableAllIntegrations();\r\n```\r\n\r\n### clearScope() — Reset global tags/context\r\n\r\n```javascript\r\niw.clearScope(); // Removes all global tags, context, and user\r\n```\r\n\r\n---\r\n\r\n## 📊 Severity Levels\r\n\r\n| Level  | Meaning  | Used For                                  |\r\n| ------ | -------- | ----------------------------------------- |\r\n| `SEV1` | Critical | Process crashes, uncaught exceptions      |\r\n| `SEV2` | High     | Unhandled rejections, network errors, 5xx |\r\n| `SEV3` | Medium   | Slow operations, warnings, manual alerts  |\r\n\r\n---\r\n\r\n## 📦 Exports\r\n\r\n```javascript\r\nconst {\r\n  init,              // (config) => IncidentWatchSDK\r\n  getInstance,       // () => IncidentWatchSDK (throws if not initialized)\r\n  isInitialized,     // () => boolean\r\n  shutdown,          // () => Promise<void>\r\n  expressMiddleware, // () => Express middleware (for manual use)\r\n  IncidentWatchSDK,  // Class (for TypeScript)\r\n} = require('@incidentwatch/sdk');\r\n\r\n// Types (TypeScript)\r\nimport type {\r\n  UserConfig, IncidentData, CaptureErrorOptions,\r\n  Severity, UserInfo, Scope, SDKStatus,\r\n  Breadcrumb, Incident,\r\n} from '@incidentwatch/sdk';\r\n```\r\n\r\n---\r\n\r\n## 🔍 Breadcrumb Types\r\n\r\nSDK automatically tracks:\r\n\r\n| Category                                    | Trigger                  |\r\n| ------------------------------------------- | ------------------------ |\r\n| `http.request`                              | Incoming Express request |\r\n| `http.error`                                | Express 5xx error        |\r\n| `http.outgoing` / `http.response`           | Axios request/response   |\r\n| `fetch.outgoing` / `fetch.response`         | Fetch request/response   |\r\n| `timer.start` / `timer.end`                 | `startTimer()`           |\r\n| `async.start` / `async.end` / `async.error` | `wrapAsync()`            |\r\n\r\n### Manual Breadcrumbs\r\n\r\n```javascript\r\niw.addBreadcrumb(\"user.login\", { email: \"dev@test.com\" }, \"info\");\r\niw.addBreadcrumb(\r\n  \"payment.failed\",\r\n  { amount: 100, reason: \"card_declined\" },\r\n  \"error\",\r\n);\r\n```\r\n\r\n---\r\n\r\n## 🚦 Expected Flow\r\n\r\n1. **Error Trigger**: Crash, slow operation, or manual capture\r\n2. **Auto Capture**: SDK gathers stack trace, memory, breadcrumbs, context\r\n3. **Queue**: Incident queued with retry logic\r\n4. **Send**: HTTP POST to platform with exponential backoff\r\n5. **Circuit Breaker**: Opens after 5 failures, resets after 60s\r\n\r\n---\r\n\r\n## 📂 Project Structure\r\n\r\n```\r\nsrc/\r\n├── index.ts              # Entry point (init, getInstance, shutdown)\r\n├── sdk.ts                # Main SDK class\r\n├── global-hooks.ts       # uncaughtException, unhandledRejection, signals\r\n├── core/\r\n│   ├── transport.ts       # HTTP transport with queue + circuit breaker\r\n│   ├── incident-builder.ts # Incident payload construction\r\n│   ├── breadcrumb-manager.ts # Breadcrumb storage (FIFO, limit enforced)\r\n│   ├── memory-monitor.ts   # Heap/RSS monitoring (30s interval)\r\n│   └── heartbeat-manager.ts # Platform heartbeat with log streaming\r\n├── integrations/\r\n│   ├── express.ts         # Express auto-registration + error middleware\r\n│   ├── axios.ts           # Axios interceptor (request + response)\r\n│   └── fetch.ts           # global fetch wrapper\r\n├── utils/\r\n│   ├── config.ts          # Config validation + defaults\r\n│   └── logger.ts          # Winston logger (dev/prod formats)\r\n└── types/\r\n    └── index.ts           # All TypeScript interfaces\r\n```\r\n\r\n---\r\n\r\n## 🧪 Testing\r\n\r\nA comprehensive test app is included:\r\n\r\n```bash\r\ncd packages/sdk\r\nbun run build\r\n\r\ncd test-app\r\nnpm install\r\n\r\n# Terminal 1\r\nnode mock-platform.js   # Mock platform on port 5000\r\n\r\n# Terminal 2\r\nnode test-app.js        # Test app on port 4000\r\n```\r\n\r\nThen test all routes:\r\n\r\n```bash\r\n# See all endpoints\r\ncurl http://localhost:4000/help\r\n\r\n# Test various endpoints\r\ncurl http://localhost:4000/health                    # Normal request\r\ncurl http://localhost:4000/error-sync              # Sync error → SEV2\r\ncurl http://localhost:4000/capture-message        # Non-error incident\r\ncurl http://localhost:4000/slow-operation       # Slow op → SEV3\r\ncurl http://localhost:4000/manual-incident -X POST  # Manual incident\r\n\r\n# Check captured incidents\r\ncurl http://localhost:5000/api/incidents\r\n```\r\n\r\n---\r\n\r\n## 📺 Terminal Logs — What You See\r\n\r\nWhen you run your app with the SDK, here's what the logs look like:\r\n\r\n### 1. SDK Initialization\r\n\r\n```\r\n14:02:15 [IW] info: IncidentWatch SDK initializing... {\"serverId\":\"prod-api-1\",\"environment\":\"development\",\"release\":\"unknown\",\"node\":\"v20.10.0\"}\r\n14:02:15 [IW] debug: [IW] Global hooks attached\r\n14:02:15 [IW] debug: [IW] Memory monitor started\r\n14:02:15 [IW] debug: [IW] Heartbeat manager started (5000ms interval)\r\n14:02:15 [IW] debug: [IW] Axios global instance patched\r\n14:02:15 [IW] debug: [IW] global fetch patched\r\n14:02:15 [IW] debug: [IW] Express auto-registration set up — will activate on app.listen()\r\n14:02:15 [IW] info: IncidentWatch SDK ready ✓\r\n```\r\n\r\n### 2. Sync Route Error (Express)\r\n\r\n```\r\n14:02:20 [IW] debug: [IW] Express error middleware caught: Synchronous route crash - /error-sync\r\n14:02:20 [IW] error: [IW] Incident captured: Synchronous route crash - /error-sync {\"incidentId\":\"abc-123\",\"severity\":\"SEV2\"}\r\n14:02:20 [IW] debug: [IW] Incident sent: abc-123\r\n```\r\n\r\n**Platform receives:**\r\n\r\n```json\r\n{\r\n  \"id\": \"abc-123\",\r\n  \"title\": \"[Error] Synchronous route crash - /error-sync\",\r\n  \"severity\": \"SEV2\",\r\n  \"source\": \"sdk-auto\",\r\n  \"tags\": [\"express\", \"http-error\", \"status-500\"],\r\n  \"breadcrumbs\": [\r\n    {\r\n      \"category\": \"http.request\",\r\n      \"data\": { \"method\": \"GET\", \"url\": \"/error-sync\" }\r\n    }\r\n  ],\r\n  \"context\": { \"method\": \"GET\", \"url\": \"/error-sync\", \"status\": 500 },\r\n  \"runtime\": { \"node\": \"v20.10.0\", \"platform\": \"linux\", \"pid\": 12345 }\r\n}\r\n```\r\n\r\n### 3. Async Route Error (Uncaught Promise)\r\n\r\n```\r\n14:02:25 [IW] error: [IW] unhandledRejection {\"error\":\"Asynchronous route failure\",\"stack\":\"...\"}\r\n14:02:25 [IW] error: [IW] Incident captured: Asynchronous route failure {\"incidentId\":\"def-456\",\"severity\":\"SEV2\"}\r\n14:02:25 [IW] debug: [IW] Incident sent: def-456\r\n```\r\n\r\n### 4. Slow Operation\r\n\r\n```\r\n14:02:35 [IW] warn: [IW] Slow operation: heavy-database-query took 2014ms\r\n14:02:35 [IW] debug: [IW] Incident captured: Slow: heavy-database-query (2014ms > 1000ms) {\"incidentId\":\"ghi-789\",\"severity\":\"SEV3\"}\r\n14:02:35 [IW] debug: [IW] Incident sent: ghi-789\r\n```\r\n\r\n### 5. Manual Incident with captureMessage\r\n\r\n```javascript\r\nawait iw.captureMessage(\"Database connection pool running low\", {\r\n  severity: \"SEV2\",\r\n  tags: [\"database\", \"pool-warning\"],\r\n  context: { poolSize: 10, active: 9 },\r\n});\r\n```\r\n\r\n**Terminal:**\r\n\r\n```\r\n14:02:40 [IW] debug: [IW] Incident captured: Database connection pool running low {\"incidentId\":\"jkl-012\",\"severity\":\"SEV2\"}\r\n14:02:40 [IW] debug: [IW] Incident sent: jkl-012\r\n```\r\n\r\n**Platform receives:**\r\n\r\n```json\r\n{\r\n  \"id\": \"jkl-012\",\r\n  \"title\": \"Database connection pool running low\",\r\n  \"severity\": \"SEV2\",\r\n  \"source\": \"sdk-manual\",\r\n  \"tags\": [\"database\", \"pool-warning\", \"app:test-app\", \"team:backend\"],\r\n  \"context\": {\"poolSize\": 10, \"active\": 9, \"user\": {\"id\": \"test-user-1\"}},\r\n  \"breadcrumbs\": [...],\r\n  \"timestamp\": \"2026-05-01T14:02:40.000Z\"\r\n}\r\n```\r\n\r\n### 6. wrapAsync — Auto-catch non-Express errors\r\n\r\n```javascript\r\nconst sendEmail = iw.wrapAsync(async (to, body) => {\r\n  if (Math.random() > 0.5) throw new Error(\"SMTP failed\");\r\n  return { sent: true };\r\n}, \"sendEmail\");\r\n\r\nawait sendEmail(\"user@test.com\", { subject: \"Hello\" });\r\n```\r\n\r\n**Terminal when error occurs:**\r\n\r\n```\r\n14:02:45 [IW] debug: [IW] async.start.sendEmail {\"argsCount\":1}\r\n14:02:45 [IW] debug: [IW] async.error.sendEmail {\"error\":\"SMTP failed\"}\r\n14:02:45 [IW] error: [IW] Incident captured: SMTP failed {\"incidentId\":\"mno-345\",\"severity\":\"SEV2\"}\r\n14:02:45 [IW] debug: [IW] Incident sent: mno-345\r\n```\r\n\r\n### 7. withScope — Isolated context\r\n\r\n```javascript\r\nawait iw.withScope(\r\n  {\r\n    tags: [\"checkout-flow\"],\r\n    context: { cartId: \"cart-456\" },\r\n    user: { id: \"buyer-789\", email: \"buyer@test.com\" },\r\n  },\r\n  async () => {\r\n    await processPayment();\r\n    await iw.captureMessage(\"Payment processed\", { severity: \"SEV3\" });\r\n  },\r\n);\r\n```\r\n\r\n**Platform receives (note scoped tags and user):**\r\n\r\n```json\r\n{\r\n  \"title\": \"Payment processed\",\r\n  \"severity\": \"SEV3\",\r\n  \"tags\": [\"checkout-flow\", \"app:test-app\", \"team:backend\"],\r\n  \"context\": {\r\n    \"cartId\": \"cart-456\",\r\n    \"user\": { \"id\": \"buyer-789\", \"email\": \"buyer@test.com\" }\r\n  }\r\n}\r\n```\r\n\r\n### 8. Global Hooks — Process Crash\r\n\r\n```\r\n14:03:00 [IW] error: [IW] uncaughtException — process will exit {\"error\":\"CRITICAL FAILURE\",\"origin\":\"uncaughtException\"}\r\n14:03:00 [IW] error: [IW] Incident captured: CRITICAL FAILURE {\"incidentId\":\"pqr-678\",\"severity\":\"SEV1\"}\r\n14:03:00 [IW] debug: [IW] Incident sent: pqr-678\r\n14:03:00 [IW] info: [IW] Flush complete. Shutting down.\r\nProcess exited with code 1\r\n```\r\n\r\n### 9. Circuit Breaker\r\n\r\nIf platform is unreachable:\r\n\r\n```\r\n14:03:10 [IW] warn: [IW] Failed to send incident after 3 retries {\"incidentId\":\"stu-901\",\"error\":\"ECONNREFUSED\"}\r\n14:03:10 [IW] warn: [IW] Failed to send incident after 3 retries {\"incidentId\":\"vwx-234\",\"error\":\"ECONNREFUSED\"}\r\n14:03:10 [IW] warn: [IW] Failed to send incident after 3 retries {\"incidentId\":\"yza-567\",\"error\":\"ECONNREFUSED\"}\r\n14:03:10 [IW] warn: [IW] Failed to send incident after 3 retries {\"incidentId\":\"bcd-890\",\"error\":\"ECONNREFUSED\"}\r\n14:03:10 [IW] warn: [IW] Failed to send incident after 3 retries {\"incidentId\":\"efg-123\",\"error\":\"ECONNREFUSED\"}\r\n14:03:10 [IW] error: [IW] Circuit breaker tripped — platform unreachable. Will retry in 60s\r\n# After 60 seconds:\r\n14:04:10 [IW] info: [IW] Circuit breaker reset — retrying platform connection\r\n```\r\n\r\n### 10. Status Check\r\n\r\n```javascript\r\nconst status = iw.getStatus();\r\nconsole.log(status);\r\n```\r\n\r\n**Output:**\r\n\r\n```json\r\n{\r\n  \"initialized\": true,\r\n  \"version\": \"1.0.0\",\r\n  \"integrations\": {\r\n    \"express\": true,\r\n    \"axios\": true,\r\n    \"fetch\": true,\r\n    \"console\": true\r\n  },\r\n  \"memoryMonitor\": true,\r\n  \"heartbeat\": true,\r\n  \"circuitBreakerOpen\": false,\r\n  \"config\": {\r\n    \"environment\": \"production\",\r\n    \"serverId\": \"prod-api-1\",\r\n    \"appName\": \"my-app\",\r\n    \"slowThresholdMs\": 5000,\r\n    \"debug\": false\r\n  }\r\n}\r\n```\r\n\r\n---\r\n\r\n## ⚠️ Important Notes\r\n\r\n- Call `init()` **once** at your app's entry point. Duplicate calls are ignored with a warning.\r\n- The Express integration only activates on `app.listen()`. Routes added after `listen()` are also covered.\r\n- `console.error` integration is **off by default** — enable it with `integrations: { console: true }`.\r\n- The SDK ignores common network errors (`ECONNRESET`, `EPIPE`, etc.) by default. Override with `ignoreErrors: []`.\r\n- `shutdown()` is called automatically on `SIGTERM`/`SIGINT`, but you should call it manually if you have custom shutdown logic.\r\n\r\n---\r\n\r\n**Happy Coding!** Report issues at https://github.com/Adityakbr01/incidentWatch/tree/main/packages/sdk\r\n","readmeFilename":"README.md"}