opensentinel 3.6.1 → 3.7.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 (197) hide show
  1. package/README.md +12 -0
  2. package/dist/{agent-manager-7N7REQZQ.js → agent-manager-JZ4IM7XI.js} +8 -8
  3. package/dist/{agent-processor-I23VWQY3.js → agent-processor-DDDHC2SO.js} +22 -21
  4. package/dist/{agent-processor-I23VWQY3.js.map → agent-processor-DDDHC2SO.js.map} +1 -1
  5. package/dist/{alerting-4I37GG4U.js → alerting-LK7VVYTX.js} +4 -4
  6. package/dist/alerting-LK7VVYTX.js.map +1 -0
  7. package/dist/analyzer-OTWE3ARE.js +22 -0
  8. package/dist/{archiver-XLRIIXPY.js → archiver-FPGKRP6P.js} +16 -85
  9. package/dist/archiver-FPGKRP6P.js.map +1 -0
  10. package/dist/{audit-logger-AU3TMWKI.js → audit-logger-CI4WZQPD.js} +5 -5
  11. package/dist/bot-VDHBGUVI.js +47 -0
  12. package/dist/{brain-SLA474EU.js → brain-6QTXN4QP.js} +18 -17
  13. package/dist/{chunk-AR34B6XR.js → chunk-2I5QHYG6.js} +3 -3
  14. package/dist/chunk-2I5QHYG6.js.map +1 -0
  15. package/dist/chunk-3AWAWRWB.js +143 -0
  16. package/dist/chunk-3AWAWRWB.js.map +1 -0
  17. package/dist/{chunk-PUNIMPMY.js → chunk-4KIHDIXZ.js} +13 -2
  18. package/dist/chunk-4KIHDIXZ.js.map +1 -0
  19. package/dist/{chunk-GUKKW7JI.js → chunk-4WH6MFEW.js} +2 -2
  20. package/dist/chunk-4WH6MFEW.js.map +1 -0
  21. package/dist/{chunk-M7YLQHFP.js → chunk-56UJS2LA.js} +6 -6
  22. package/dist/{chunk-S4NJJS5C.js → chunk-5BTVJR7R.js} +3 -3
  23. package/dist/{chunk-HKOPRRDJ.js → chunk-5JJTLWOR.js} +3 -3
  24. package/dist/chunk-5JJTLWOR.js.map +1 -0
  25. package/dist/chunk-66SAOZPU.js +236 -0
  26. package/dist/chunk-66SAOZPU.js.map +1 -0
  27. package/dist/chunk-6HGMRR4J.js +113 -0
  28. package/dist/chunk-6HGMRR4J.js.map +1 -0
  29. package/dist/{chunk-BMOUYXLX.js → chunk-6ZNCY2GI.js} +5 -5
  30. package/dist/chunk-7BNFELEK.js +31 -0
  31. package/dist/chunk-7BNFELEK.js.map +1 -0
  32. package/dist/{chunk-KABG5PG3.js → chunk-BBN4VCNK.js} +4 -4
  33. package/dist/chunk-BBN4VCNK.js.map +1 -0
  34. package/dist/{chunk-4YJRBMMA.js → chunk-BNZHWAZC.js} +2 -2
  35. package/dist/{chunk-TAAZB5KN.js → chunk-CWT6CAE5.js} +2 -2
  36. package/dist/{chunk-UWUIJTT4.js → chunk-CZTMGHUC.js} +1 -1
  37. package/dist/chunk-CZTMGHUC.js.map +1 -0
  38. package/dist/chunk-DTISLIMB.js +89 -0
  39. package/dist/chunk-DTISLIMB.js.map +1 -0
  40. package/dist/{chunk-VKMFUIVA.js → chunk-GBVJTRXS.js} +2 -2
  41. package/dist/{chunk-MFK34XSY.js → chunk-GJETKBOY.js} +15 -15
  42. package/dist/chunk-GJETKBOY.js.map +1 -0
  43. package/dist/{chunk-HTF2GIQC.js → chunk-GW6V4D43.js} +2 -2
  44. package/dist/chunk-GW6V4D43.js.map +1 -0
  45. package/dist/{chunk-2RGPWU77.js → chunk-HJSEEFO3.js} +2 -2
  46. package/dist/{chunk-JOA5A3G3.js → chunk-HQZQFEAX.js} +5 -5
  47. package/dist/{chunk-45YXODSB.js → chunk-J4JW73TT.js} +2 -2
  48. package/dist/{chunk-KT7NLIXP.js → chunk-JHYYFPKX.js} +2 -2
  49. package/dist/{chunk-XMCVRVTF.js → chunk-P64EV4YY.js} +1 -1
  50. package/dist/chunk-P64EV4YY.js.map +1 -0
  51. package/dist/chunk-PBOCSGNL.js +84 -0
  52. package/dist/chunk-PBOCSGNL.js.map +1 -0
  53. package/dist/{chunk-H3BOLSTS.js → chunk-PD3CTDO6.js} +2 -2
  54. package/dist/{chunk-6UZPE35A.js → chunk-QPY3WRVM.js} +10 -87
  55. package/dist/chunk-QPY3WRVM.js.map +1 -0
  56. package/dist/{chunk-AD6YEH6U.js → chunk-S2EOIVF4.js} +590 -91
  57. package/dist/chunk-S2EOIVF4.js.map +1 -0
  58. package/dist/chunk-SDLOMKCW.js +213 -0
  59. package/dist/chunk-SDLOMKCW.js.map +1 -0
  60. package/dist/{chunk-7MZN73J2.js → chunk-TKBVW7ZJ.js} +4 -4
  61. package/dist/{chunk-A24GPVLY.js → chunk-V3OKHQUX.js} +5 -5
  62. package/dist/{chunk-NMSHVO5O.js → chunk-WMDVOWN6.js} +4 -4
  63. package/dist/{chunk-643M3AP5.js → chunk-WMFYI7XC.js} +7 -7
  64. package/dist/{chunk-6LTLIYAQ.js → chunk-YEDEAX6Y.js} +3 -3
  65. package/dist/{chunk-NYVBXUGD.js → chunk-ZIBRVA3Y.js} +60 -1
  66. package/dist/chunk-ZIBRVA3Y.js.map +1 -0
  67. package/dist/{chunk-6JY4HNUH.js → chunk-ZMML6T63.js} +361 -24
  68. package/dist/chunk-ZMML6T63.js.map +1 -0
  69. package/dist/{chunk-FFV2SXFD.js → chunk-ZVHG4KF2.js} +4 -4
  70. package/dist/cli.js.map +1 -1
  71. package/dist/commands/setup.js +1 -1
  72. package/dist/commands/start.js +2 -2
  73. package/dist/commands/status.js +1 -1
  74. package/dist/commands/stop.js +1 -1
  75. package/dist/commands/utils.js +1 -1
  76. package/dist/{cost-tracker-EMOIOYH7.js → cost-tracker-KZQSTSE2.js} +2 -2
  77. package/dist/{db-LRIOKQBO.js → db-I7MNG6CL.js} +10 -4
  78. package/dist/{discord-NKR3X4AV.js → discord-6UQHCN27.js} +24 -23
  79. package/dist/{documents-EYIYLZK2.js → documents-PFHSK7SZ.js} +19 -19
  80. package/dist/{email-EAQNULVD.js → email-6OIN4SYL.js} +22 -21
  81. package/dist/email-6OIN4SYL.js.map +1 -0
  82. package/dist/{enhanced-retrieval-OGHT6TS5.js → enhanced-retrieval-JWX2HWU4.js} +7 -6
  83. package/dist/{enhanced-retrieval-OGHT6TS5.js.map → enhanced-retrieval-JWX2HWU4.js.map} +1 -1
  84. package/dist/enrichment-pipeline-7FE5R5ZI.js +14 -0
  85. package/dist/{entity-resolution-4X4JU43O.js → entity-resolution-7Z6STVXX.js} +5 -5
  86. package/dist/{env-CHOFICED.js → env-GN5VHI43.js} +2 -2
  87. package/dist/{error-tracker-SVQSDQDW.js → error-tracker-64DEH3D7.js} +6 -6
  88. package/dist/{github-KGNILDWJ.js → github-DUWSXCNP.js} +4 -4
  89. package/dist/graph-client-NB475AK5.js +17 -0
  90. package/dist/{imessage-V2XNDDHT.js → imessage-DSGSGUZS.js} +19 -18
  91. package/dist/{inbox-summarizer-DKKRYXDR.js → inbox-summarizer-F2KAU72V.js} +19 -18
  92. package/dist/{incident-response-ZTIKUWEO.js → incident-response-E3UGMX5G.js} +5 -5
  93. package/dist/incident-response-E3UGMX5G.js.map +1 -0
  94. package/dist/{knowledge-base-J7PJ7MZ3.js → knowledge-base-5SMMOGQJ.js} +5 -5
  95. package/dist/lib.d.ts +21 -0
  96. package/dist/lib.js +64 -57
  97. package/dist/lib.js.map +1 -1
  98. package/dist/{matrix-XHTR53VQ.js → matrix-WYGEOZL5.js} +18 -17
  99. package/dist/{matrix-XHTR53VQ.js.map → matrix-WYGEOZL5.js.map} +1 -1
  100. package/dist/{mcp-3C2TN67D.js → mcp-DJ2QDA6A.js} +2 -2
  101. package/dist/{metrics-VJDWQWU7.js → metrics-BH3ZLGEV.js} +5 -5
  102. package/dist/{multi-user-S56GUD6L.js → multi-user-XAEMB244.js} +4 -4
  103. package/dist/oauth-UPJYFOVU.js +34 -0
  104. package/dist/{ocr-LGUIPKVZ.js → ocr-UONKTQU7.js} +4 -4
  105. package/dist/{presentations-HXTAMGHT.js → presentations-UOET2FVZ.js} +2 -2
  106. package/dist/{providers-H6YIC3MG.js → providers-2YQ6E3IF.js} +3 -3
  107. package/dist/{scheduler-CA5UNHZV.js → scheduler-6PLLAQI7.js} +21 -20
  108. package/dist/{schema-ALJ67YVG.js → schema-ETY7L2VA.js} +8 -2
  109. package/dist/sharepoint-V5P4Q62L.js +30 -0
  110. package/dist/{signal-X7IQJGRQ.js → signal-7D5EPGVL.js} +19 -18
  111. package/dist/{slack-P2LFUJUQ.js → slack-KSS6YK5Z.js} +23 -22
  112. package/dist/slack-KSS6YK5Z.js.map +1 -0
  113. package/dist/{sms-4VME2HUL.js → sms-CSUCC7HL.js} +3 -3
  114. package/dist/sms-CSUCC7HL.js.map +1 -0
  115. package/dist/{src-S5KX4YEV.js → src-GO7GGW7O.js} +48 -41
  116. package/dist/{src-S5KX4YEV.js.map → src-GO7GGW7O.js.map} +1 -1
  117. package/dist/token-store-SEWRX6RE.js +20 -0
  118. package/dist/token-store-SEWRX6RE.js.map +1 -0
  119. package/dist/{tools-FGPN522P.js → tools-PJZ6RI4P.js} +18 -17
  120. package/dist/tools-PJZ6RI4P.js.map +1 -0
  121. package/dist/{whatsapp-KRPQ4YUX.js → whatsapp-DWXK25V2.js} +19 -18
  122. package/dist/whatsapp-DWXK25V2.js.map +1 -0
  123. package/dist/{word-document-D6N2C47N.js → word-document-AV3YB4L2.js} +2 -2
  124. package/dist/{workflow-store-ZYAYE5P6.js → workflow-store-5Y56GUP7.js} +4 -4
  125. package/drizzle/0002_mushy_master_mold.sql +139 -139
  126. package/drizzle/0003_overjoyed_rhodey.sql +46 -0
  127. package/drizzle/meta/0002_snapshot.json +3636 -3636
  128. package/drizzle/meta/0003_snapshot.json +3946 -0
  129. package/drizzle/meta/_journal.json +7 -0
  130. package/package.json +110 -110
  131. package/dist/alerting-4I37GG4U.js.map +0 -1
  132. package/dist/archiver-XLRIIXPY.js.map +0 -1
  133. package/dist/bot-MU2TJQ3Y.js +0 -46
  134. package/dist/chunk-6JY4HNUH.js.map +0 -1
  135. package/dist/chunk-6UZPE35A.js.map +0 -1
  136. package/dist/chunk-AD6YEH6U.js.map +0 -1
  137. package/dist/chunk-AR34B6XR.js.map +0 -1
  138. package/dist/chunk-GUKKW7JI.js.map +0 -1
  139. package/dist/chunk-HKOPRRDJ.js.map +0 -1
  140. package/dist/chunk-HTF2GIQC.js.map +0 -1
  141. package/dist/chunk-KABG5PG3.js.map +0 -1
  142. package/dist/chunk-MFK34XSY.js.map +0 -1
  143. package/dist/chunk-NYVBXUGD.js.map +0 -1
  144. package/dist/chunk-PUNIMPMY.js.map +0 -1
  145. package/dist/chunk-UWUIJTT4.js.map +0 -1
  146. package/dist/chunk-XMCVRVTF.js.map +0 -1
  147. package/dist/email-EAQNULVD.js.map +0 -1
  148. package/dist/enrichment-pipeline-CMUVBDC7.js +0 -14
  149. package/dist/incident-response-ZTIKUWEO.js.map +0 -1
  150. /package/dist/{agent-manager-7N7REQZQ.js.map → agent-manager-JZ4IM7XI.js.map} +0 -0
  151. /package/dist/{audit-logger-AU3TMWKI.js.map → analyzer-OTWE3ARE.js.map} +0 -0
  152. /package/dist/{bot-MU2TJQ3Y.js.map → audit-logger-CI4WZQPD.js.map} +0 -0
  153. /package/dist/{brain-SLA474EU.js.map → bot-VDHBGUVI.js.map} +0 -0
  154. /package/dist/{cost-tracker-EMOIOYH7.js.map → brain-6QTXN4QP.js.map} +0 -0
  155. /package/dist/{chunk-M7YLQHFP.js.map → chunk-56UJS2LA.js.map} +0 -0
  156. /package/dist/{chunk-S4NJJS5C.js.map → chunk-5BTVJR7R.js.map} +0 -0
  157. /package/dist/{chunk-BMOUYXLX.js.map → chunk-6ZNCY2GI.js.map} +0 -0
  158. /package/dist/{chunk-4YJRBMMA.js.map → chunk-BNZHWAZC.js.map} +0 -0
  159. /package/dist/{chunk-TAAZB5KN.js.map → chunk-CWT6CAE5.js.map} +0 -0
  160. /package/dist/{chunk-VKMFUIVA.js.map → chunk-GBVJTRXS.js.map} +0 -0
  161. /package/dist/{chunk-2RGPWU77.js.map → chunk-HJSEEFO3.js.map} +0 -0
  162. /package/dist/{chunk-JOA5A3G3.js.map → chunk-HQZQFEAX.js.map} +0 -0
  163. /package/dist/{chunk-45YXODSB.js.map → chunk-J4JW73TT.js.map} +0 -0
  164. /package/dist/{chunk-KT7NLIXP.js.map → chunk-JHYYFPKX.js.map} +0 -0
  165. /package/dist/{chunk-H3BOLSTS.js.map → chunk-PD3CTDO6.js.map} +0 -0
  166. /package/dist/{chunk-7MZN73J2.js.map → chunk-TKBVW7ZJ.js.map} +0 -0
  167. /package/dist/{chunk-A24GPVLY.js.map → chunk-V3OKHQUX.js.map} +0 -0
  168. /package/dist/{chunk-NMSHVO5O.js.map → chunk-WMDVOWN6.js.map} +0 -0
  169. /package/dist/{chunk-643M3AP5.js.map → chunk-WMFYI7XC.js.map} +0 -0
  170. /package/dist/{chunk-6LTLIYAQ.js.map → chunk-YEDEAX6Y.js.map} +0 -0
  171. /package/dist/{chunk-FFV2SXFD.js.map → chunk-ZVHG4KF2.js.map} +0 -0
  172. /package/dist/{db-LRIOKQBO.js.map → cost-tracker-KZQSTSE2.js.map} +0 -0
  173. /package/dist/{discord-NKR3X4AV.js.map → db-I7MNG6CL.js.map} +0 -0
  174. /package/dist/{enrichment-pipeline-CMUVBDC7.js.map → discord-6UQHCN27.js.map} +0 -0
  175. /package/dist/{documents-EYIYLZK2.js.map → documents-PFHSK7SZ.js.map} +0 -0
  176. /package/dist/{entity-resolution-4X4JU43O.js.map → enrichment-pipeline-7FE5R5ZI.js.map} +0 -0
  177. /package/dist/{env-CHOFICED.js.map → entity-resolution-7Z6STVXX.js.map} +0 -0
  178. /package/dist/{error-tracker-SVQSDQDW.js.map → env-GN5VHI43.js.map} +0 -0
  179. /package/dist/{imessage-V2XNDDHT.js.map → error-tracker-64DEH3D7.js.map} +0 -0
  180. /package/dist/{github-KGNILDWJ.js.map → github-DUWSXCNP.js.map} +0 -0
  181. /package/dist/{inbox-summarizer-DKKRYXDR.js.map → graph-client-NB475AK5.js.map} +0 -0
  182. /package/dist/{knowledge-base-J7PJ7MZ3.js.map → imessage-DSGSGUZS.js.map} +0 -0
  183. /package/dist/{mcp-3C2TN67D.js.map → inbox-summarizer-F2KAU72V.js.map} +0 -0
  184. /package/dist/{metrics-VJDWQWU7.js.map → knowledge-base-5SMMOGQJ.js.map} +0 -0
  185. /package/dist/{ocr-LGUIPKVZ.js.map → mcp-DJ2QDA6A.js.map} +0 -0
  186. /package/dist/{providers-H6YIC3MG.js.map → metrics-BH3ZLGEV.js.map} +0 -0
  187. /package/dist/{multi-user-S56GUD6L.js.map → multi-user-XAEMB244.js.map} +0 -0
  188. /package/dist/{scheduler-CA5UNHZV.js.map → oauth-UPJYFOVU.js.map} +0 -0
  189. /package/dist/{schema-ALJ67YVG.js.map → ocr-UONKTQU7.js.map} +0 -0
  190. /package/dist/{presentations-HXTAMGHT.js.map → presentations-UOET2FVZ.js.map} +0 -0
  191. /package/dist/{signal-X7IQJGRQ.js.map → providers-2YQ6E3IF.js.map} +0 -0
  192. /package/dist/{slack-P2LFUJUQ.js.map → scheduler-6PLLAQI7.js.map} +0 -0
  193. /package/dist/{sms-4VME2HUL.js.map → schema-ETY7L2VA.js.map} +0 -0
  194. /package/dist/{tools-FGPN522P.js.map → sharepoint-V5P4Q62L.js.map} +0 -0
  195. /package/dist/{whatsapp-KRPQ4YUX.js.map → signal-7D5EPGVL.js.map} +0 -0
  196. /package/dist/{word-document-D6N2C47N.js.map → word-document-AV3YB4L2.js.map} +0 -0
  197. /package/dist/{workflow-store-ZYAYE5P6.js.map → workflow-store-5Y56GUP7.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/db/schema.ts"],"sourcesContent":["import {\n pgTable,\n text,\n timestamp,\n uuid,\n integer,\n jsonb,\n boolean,\n vector,\n index,\n customType,\n} from \"drizzle-orm/pg-core\";\n\n// Custom tsvector type for full-text search\nconst tsvector = customType<{ data: string }>({\n dataType() {\n return \"tsvector\";\n },\n});\n\n// Users table\nexport const users = pgTable(\"users\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n telegramId: text(\"telegram_id\").unique(),\n name: text(\"name\"),\n preferences: jsonb(\"preferences\").$type<{\n timezone?: string;\n language?: string;\n verbosity?: \"terse\" | \"normal\" | \"detailed\";\n persona?: \"formal\" | \"casual\" | \"snarky\";\n }>(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n});\n\n// Conversations table\nexport const conversations = pgTable(\"conversations\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n title: text(\"title\"),\n source: text(\"source\").notNull().default(\"telegram\"), // telegram, web, api\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n});\n\n// Messages table\nexport const messages = pgTable(\n \"messages\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n conversationId: uuid(\"conversation_id\")\n .references(() => conversations.id)\n .notNull(),\n role: text(\"role\").notNull().$type<\"user\" | \"assistant\" | \"system\">(),\n content: text(\"content\").notNull(),\n tokenCount: integer(\"token_count\"),\n metadata: jsonb(\"metadata\"),\n encrypted: boolean(\"encrypted\").default(false).notNull(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"messages_conversation_idx\").on(table.conversationId)]\n);\n\n// Memories table with vector embeddings for RAG\nexport const memories = pgTable(\n \"memories\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n type: text(\"type\")\n .notNull()\n .$type<\"episodic\" | \"semantic\" | \"procedural\">(),\n content: text(\"content\").notNull(),\n embedding: vector(\"embedding\", { dimensions: 1536 }), // OpenAI embedding size\n searchVector: tsvector(\"search_vector\"), // Full-text search vector (GIN indexed)\n importance: integer(\"importance\").default(5), // 1-10 scale\n source: text(\"source\"), // Where this memory came from\n provenance: text(\"provenance\"), // Origin tracking: \"conversation:id\", \"api:manual\", \"extraction:auto\"\n metadata: jsonb(\"metadata\"),\n encrypted: boolean(\"encrypted\").default(false).notNull(),\n lastAccessed: timestamp(\"last_accessed\").defaultNow(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"memories_user_idx\").on(table.userId)]\n);\n\n// Scheduled tasks table\nexport const scheduledTasks = pgTable(\"scheduled_tasks\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n cronExpression: text(\"cron_expression\"),\n nextRunAt: timestamp(\"next_run_at\"),\n lastRunAt: timestamp(\"last_run_at\"),\n enabled: boolean(\"enabled\").default(true),\n action: jsonb(\"action\").$type<{\n type: \"message\" | \"command\" | \"webhook\";\n payload: Record<string, unknown>;\n }>(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n});\n\n// Tool execution logs\nexport const toolLogs = pgTable(\n \"tool_logs\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n conversationId: uuid(\"conversation_id\").references(() => conversations.id),\n toolName: text(\"tool_name\").notNull(),\n input: jsonb(\"input\"),\n output: jsonb(\"output\"),\n success: boolean(\"success\").notNull(),\n durationMs: integer(\"duration_ms\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"tool_logs_conversation_idx\").on(table.conversationId)]\n);\n\n// ============================================\n// SECURITY TABLES (Phase 1)\n// ============================================\n\n// Sessions table for session management\nexport const sessions = pgTable(\n \"sessions\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n token: text(\"token\").notNull().unique(),\n deviceInfo: jsonb(\"device_info\").$type<{\n userAgent?: string;\n platform?: string;\n browser?: string;\n }>(),\n ipAddress: text(\"ip_address\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n expiresAt: timestamp(\"expires_at\").notNull(),\n lastActiveAt: timestamp(\"last_active_at\").defaultNow(),\n },\n (table) => [index(\"sessions_user_idx\").on(table.userId)]\n);\n\n// Audit logs table for tracking all actions\nexport const auditLogs = pgTable(\n \"audit_logs\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n sessionId: uuid(\"session_id\").references(() => sessions.id),\n action: text(\"action\").notNull(), // 'tool_use', 'login', 'settings_change', etc.\n resource: text(\"resource\"), // 'shell', 'file', 'memory', etc.\n resourceId: text(\"resource_id\"), // ID of the affected resource\n details: jsonb(\"details\"),\n ipAddress: text(\"ip_address\"),\n userAgent: text(\"user_agent\"),\n success: boolean(\"success\").default(true),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n // Tamper-proof chain fields (SOC 2)\n sequenceNumber: integer(\"sequence_number\"),\n entryHash: text(\"entry_hash\"),\n previousHash: text(\"previous_hash\"),\n },\n (table) => [\n index(\"audit_logs_user_idx\").on(table.userId),\n index(\"audit_logs_action_idx\").on(table.action),\n index(\"audit_logs_created_idx\").on(table.createdAt),\n index(\"audit_logs_sequence_idx\").on(table.sequenceNumber),\n ]\n);\n\n// API keys table for programmatic access\nexport const apiKeys = pgTable(\n \"api_keys\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n name: text(\"name\").notNull(),\n keyHash: text(\"key_hash\").notNull(), // bcrypt hash of the key\n keyPrefix: text(\"key_prefix\").notNull(), // First 8 chars for identification (e.g., \"mb_live_\")\n permissions: jsonb(\"permissions\").$type<string[]>(), // ['chat:basic', 'tools:shell', etc.]\n lastUsedAt: timestamp(\"last_used_at\"),\n expiresAt: timestamp(\"expires_at\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n revokedAt: timestamp(\"revoked_at\"),\n },\n (table) => [index(\"api_keys_user_idx\").on(table.userId)]\n);\n\n// Rate limits table for tracking request rates\nexport const rateLimits = pgTable(\n \"rate_limits\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n identifier: text(\"identifier\").notNull(), // userId, IP, or API key prefix\n endpoint: text(\"endpoint\").notNull(), // 'api/chat', 'tool/shell', etc.\n windowStart: timestamp(\"window_start\").notNull(),\n requestCount: integer(\"request_count\").default(0),\n lastRequest: timestamp(\"last_request\"),\n },\n (table) => [\n index(\"rate_limits_identifier_endpoint_idx\").on(\n table.identifier,\n table.endpoint\n ),\n ]\n);\n\n// ============================================\n// OBSERVABILITY TABLES (Phase 1)\n// ============================================\n\n// Metrics table for performance tracking\nexport const metrics = pgTable(\n \"metrics\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n name: text(\"name\").notNull(), // 'response_latency', 'token_usage', 'tool_duration', etc.\n value: integer(\"value\").notNull(),\n unit: text(\"unit\"), // 'ms', 'tokens', 'bytes', etc.\n tags: jsonb(\"tags\").$type<Record<string, string>>(), // { tool: 'shell', status: 'success' }\n timestamp: timestamp(\"timestamp\").defaultNow().notNull(),\n },\n (table) => [\n index(\"metrics_name_timestamp_idx\").on(table.name, table.timestamp),\n ]\n);\n\n// Error logs table for centralized error tracking\nexport const errorLogs = pgTable(\n \"error_logs\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n source: text(\"source\").notNull(), // 'brain', 'tool', 'telegram', 'api', 'scheduler'\n errorType: text(\"error_type\").notNull(), // 'ApiError', 'ValidationError', etc.\n errorCode: text(\"error_code\"), // Application-specific error codes\n message: text(\"message\").notNull(),\n stack: text(\"stack\"),\n context: jsonb(\"context\"), // Additional context like request data\n userId: uuid(\"user_id\").references(() => users.id),\n conversationId: uuid(\"conversation_id\").references(() => conversations.id),\n resolved: boolean(\"resolved\").default(false),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"error_logs_source_idx\").on(table.source),\n index(\"error_logs_created_idx\").on(table.createdAt),\n ]\n);\n\n// ============================================\n// EVOLUTION SYSTEM TABLES (Phase 2)\n// ============================================\n\n// Usage patterns for evolution tracking\nexport const usagePatterns = pgTable(\n \"usage_patterns\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n patternType: text(\"pattern_type\").notNull(), // 'tool_usage', 'topic', 'time_of_day', 'complexity'\n patternKey: text(\"pattern_key\").notNull(), // e.g., 'shell', 'morning', 'coding'\n patternData: jsonb(\"pattern_data\"),\n confidence: integer(\"confidence\").default(0), // 0-100\n firstSeen: timestamp(\"first_seen\").defaultNow().notNull(),\n lastSeen: timestamp(\"last_seen\").defaultNow(),\n occurrences: integer(\"occurrences\").default(1),\n },\n (table) => [\n index(\"usage_patterns_user_idx\").on(table.userId),\n index(\"usage_patterns_type_idx\").on(table.patternType),\n ]\n);\n\n// Achievements definitions\nexport const achievements = pgTable(\"achievements\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n code: text(\"code\").notNull().unique(), // 'first_tool_use', 'power_user', 'researcher'\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n iconEmoji: text(\"icon_emoji\"), // Emoji to display\n category: text(\"category\"), // 'exploration', 'productivity', 'mastery'\n criteria: jsonb(\"criteria\").$type<{\n type: string; // 'count', 'streak', 'threshold'\n metric: string; // 'tool_uses', 'conversations', 'memories'\n threshold: number;\n conditions?: Record<string, unknown>;\n }>(),\n points: integer(\"points\").default(10),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n});\n\n// User achievements (unlocked)\nexport const userAchievements = pgTable(\n \"user_achievements\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n achievementId: uuid(\"achievement_id\")\n .references(() => achievements.id)\n .notNull(),\n unlockedAt: timestamp(\"unlocked_at\").defaultNow().notNull(),\n progress: integer(\"progress\").default(100), // For progressive achievements\n notified: boolean(\"notified\").default(false),\n },\n (table) => [index(\"user_achievements_user_idx\").on(table.userId)]\n);\n\n// Evolution transformation modes\nexport const evolutionModes = pgTable(\n \"molt_modes\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n mode: text(\"mode\")\n .notNull()\n .$type<\"productivity\" | \"creative\" | \"research\" | \"learning\">(),\n activatedAt: timestamp(\"activated_at\").defaultNow().notNull(),\n deactivatedAt: timestamp(\"deactivated_at\"),\n metadata: jsonb(\"metadata\"),\n },\n (table) => [index(\"molt_modes_user_idx\").on(table.userId)]\n);\n\n// Archived memories (for memory shedding)\nexport const archivedMemories = pgTable(\n \"archived_memories\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n originalMemoryId: uuid(\"original_memory_id\").notNull(),\n userId: uuid(\"user_id\").references(() => users.id),\n type: text(\"type\")\n .notNull()\n .$type<\"episodic\" | \"semantic\" | \"procedural\">(),\n content: text(\"content\").notNull(),\n reason: text(\"reason\"), // 'stale', 'duplicate', 'low_importance', 'user_request'\n originalCreatedAt: timestamp(\"original_created_at\"),\n archivedAt: timestamp(\"archived_at\").defaultNow().notNull(),\n },\n (table) => [index(\"archived_memories_user_idx\").on(table.userId)]\n);\n\n// ============================================\n// CALENDAR & TRIGGERS TABLES (Phase 3)\n// ============================================\n\nexport const calendarTriggers = pgTable(\n \"calendar_triggers\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n name: text(\"name\").notNull(),\n calendarSource: text(\"calendar_source\").notNull(), // 'google', 'outlook', 'ical'\n calendarId: text(\"calendar_id\"),\n triggerType: text(\"trigger_type\").notNull(), // 'event_start', 'event_end', 'daily_briefing'\n offsetMinutes: integer(\"offset_minutes\").default(0), // Trigger X minutes before/after\n action: jsonb(\"action\").$type<{\n type: \"message\" | \"tool\" | \"webhook\";\n payload: Record<string, unknown>;\n }>(),\n enabled: boolean(\"enabled\").default(true),\n lastTriggered: timestamp(\"last_triggered\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"calendar_triggers_user_idx\").on(table.userId)]\n);\n\n// ============================================\n// SUB-AGENT TABLES (Phase 4)\n// ============================================\n\nexport const subAgents = pgTable(\n \"sub_agents\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n parentConversationId: uuid(\"parent_conversation_id\").references(\n () => conversations.id\n ),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n type: text(\"type\")\n .notNull()\n .$type<\"research\" | \"coding\" | \"writing\" | \"analysis\">(),\n name: text(\"name\").notNull(),\n status: text(\"status\")\n .notNull()\n .$type<\"pending\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\">(),\n objective: text(\"objective\").notNull(),\n context: jsonb(\"context\"),\n result: jsonb(\"result\"),\n tokenBudget: integer(\"token_budget\").default(50000),\n tokensUsed: integer(\"tokens_used\").default(0),\n timeBudgetMs: integer(\"time_budget_ms\").default(3600000), // 1 hour default\n startedAt: timestamp(\"started_at\"),\n completedAt: timestamp(\"completed_at\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"sub_agents_user_idx\").on(table.userId),\n index(\"sub_agents_status_idx\").on(table.status),\n ]\n);\n\nexport const agentMessages = pgTable(\n \"agent_messages\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n agentId: uuid(\"agent_id\")\n .references(() => subAgents.id)\n .notNull(),\n role: text(\"role\")\n .notNull()\n .$type<\"user\" | \"assistant\" | \"system\" | \"tool_result\">(),\n content: text(\"content\").notNull(),\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"agent_messages_agent_idx\").on(table.agentId)]\n);\n\nexport const agentProgress = pgTable(\n \"agent_progress\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n agentId: uuid(\"agent_id\")\n .references(() => subAgents.id)\n .notNull(),\n step: integer(\"step\").notNull(),\n description: text(\"description\").notNull(),\n status: text(\"status\")\n .notNull()\n .$type<\"pending\" | \"running\" | \"completed\" | \"failed\">(),\n output: jsonb(\"output\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"agent_progress_agent_idx\").on(table.agentId)]\n);\n\n// ============================================\n// PERSONALITY TABLES (Phase 5)\n// ============================================\n\nexport const personas = pgTable(\n \"personas\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id), // null = system persona\n name: text(\"name\").notNull(),\n description: text(\"description\"),\n basePrompt: text(\"base_prompt\").notNull(),\n isDefault: boolean(\"is_default\").default(false),\n isSystem: boolean(\"is_system\").default(false), // Built-in personas\n settings: jsonb(\"settings\").$type<{\n verbosity: \"terse\" | \"normal\" | \"detailed\";\n humor: \"off\" | \"subtle\" | \"full\";\n formality: \"formal\" | \"casual\" | \"professional\";\n emoji: boolean;\n proactivity: \"minimal\" | \"moderate\" | \"proactive\";\n }>(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"personas_user_idx\").on(table.userId)]\n);\n\n// ============================================\n// ENTERPRISE TABLES (Phase 6)\n// ============================================\n\nexport const organizations = pgTable(\"organizations\", {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n name: text(\"name\").notNull(),\n slug: text(\"slug\").unique(),\n settings: jsonb(\"settings\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow(),\n});\n\nexport const organizationMembers = pgTable(\n \"organization_members\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n organizationId: uuid(\"organization_id\")\n .references(() => organizations.id)\n .notNull(),\n userId: uuid(\"user_id\")\n .references(() => users.id)\n .notNull(),\n role: text(\"role\").notNull().$type<\"owner\" | \"admin\" | \"member\" | \"viewer\">(),\n joinedAt: timestamp(\"joined_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"org_members_org_idx\").on(table.organizationId),\n index(\"org_members_user_idx\").on(table.userId),\n ]\n);\n\nexport const sharedMemories = pgTable(\n \"shared_memories\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n organizationId: uuid(\"organization_id\")\n .references(() => organizations.id)\n .notNull(),\n memoryId: uuid(\"memory_id\")\n .references(() => memories.id)\n .notNull(),\n sharedBy: uuid(\"shared_by\")\n .references(() => users.id)\n .notNull(),\n sharedAt: timestamp(\"shared_at\").defaultNow().notNull(),\n },\n (table) => [index(\"shared_memories_org_idx\").on(table.organizationId)]\n);\n\nexport const usageQuotas = pgTable(\n \"usage_quotas\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n organizationId: uuid(\"organization_id\").references(() => organizations.id),\n quotaType: text(\"quota_type\").notNull(), // 'tokens_daily', 'tokens_monthly', 'agents_concurrent'\n limitValue: integer(\"limit_value\").notNull(),\n currentValue: integer(\"current_value\").default(0),\n resetAt: timestamp(\"reset_at\"),\n updatedAt: timestamp(\"updated_at\").defaultNow(),\n },\n (table) => [\n index(\"usage_quotas_user_idx\").on(table.userId),\n index(\"usage_quotas_org_idx\").on(table.organizationId),\n ]\n);\n\n// ============================================\n// KNOWLEDGE GRAPH TABLES\n// ============================================\n\n// Graph entities — people, projects, topics, events, organizations, locations\nexport const graphEntities = pgTable(\n \"graph_entities\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\").references(() => users.id),\n type: text(\"type\")\n .notNull()\n .$type<\"person\" | \"project\" | \"topic\" | \"event\" | \"organization\" | \"location\">(),\n name: text(\"name\").notNull(),\n aliases: jsonb(\"aliases\").$type<string[]>().default([]),\n description: text(\"description\"),\n attributes: jsonb(\"attributes\").$type<Record<string, unknown>>().default({}),\n importance: integer(\"importance\").default(50), // 0-100\n mentionCount: integer(\"mention_count\").default(1),\n embedding: vector(\"embedding\", { dimensions: 1536 }),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"graph_entities_user_idx\").on(table.userId),\n index(\"graph_entities_type_idx\").on(table.type),\n index(\"graph_entities_name_idx\").on(table.name),\n ]\n);\n\n// Graph relationships — connections between entities\nexport const graphRelationships = pgTable(\n \"graph_relationships\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n sourceEntityId: uuid(\"source_entity_id\")\n .references(() => graphEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n targetEntityId: uuid(\"target_entity_id\")\n .references(() => graphEntities.id, { onDelete: \"cascade\" })\n .notNull(),\n type: text(\"type\")\n .notNull()\n .$type<\n | \"knows\" | \"works_with\" | \"works_on\" | \"family\" | \"friend\"\n | \"colleague\" | \"manages\" | \"reports_to\" | \"belongs_to\"\n | \"related_to\" | \"located_in\" | \"interested_in\" | \"expert_in\"\n | \"mentioned_in\" | \"participates_in\"\n >(),\n strength: integer(\"strength\").default(50), // 0-100\n bidirectional: boolean(\"bidirectional\").default(false),\n context: text(\"context\"),\n attributes: jsonb(\"attributes\").$type<Record<string, unknown>>().default({}),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"graph_rel_source_idx\").on(table.sourceEntityId),\n index(\"graph_rel_target_idx\").on(table.targetEntityId),\n index(\"graph_rel_type_idx\").on(table.type),\n ]\n);\n\n// ============================================\n// DOCUMENT KNOWLEDGE BASE TABLES\n// ============================================\n\nexport const documents = pgTable(\n \"documents\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n name: text(\"name\").notNull(),\n filename: text(\"filename\"),\n mimeType: text(\"mime_type\"),\n fileSize: integer(\"file_size\"),\n source: text(\"source\"), // 'upload', 'url', 'api'\n sourceUrl: text(\"source_url\"),\n metadata: jsonb(\"metadata\"),\n status: text(\"status\")\n .notNull()\n .$type<\"pending\" | \"processing\" | \"completed\" | \"failed\">()\n .default(\"pending\"),\n errorMessage: text(\"error_message\"),\n chunkCount: integer(\"chunk_count\").default(0),\n totalTokens: integer(\"total_tokens\").default(0),\n userId: uuid(\"user_id\").references(() => users.id),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n processedAt: timestamp(\"processed_at\"),\n },\n (table) => [\n index(\"documents_user_idx\").on(table.userId),\n index(\"documents_status_idx\").on(table.status),\n ]\n);\n\nexport const documentChunks = pgTable(\n \"document_chunks\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n documentId: uuid(\"document_id\")\n .references(() => documents.id, { onDelete: \"cascade\" })\n .notNull(),\n chunkIndex: integer(\"chunk_index\").notNull(),\n content: text(\"content\").notNull(),\n embedding: vector(\"embedding\", { dimensions: 1536 }),\n tokenCount: integer(\"token_count\"),\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"document_chunks_document_idx\").on(table.documentId),\n ]\n);\n\n// ============================================\n// TYPE EXPORTS\n// ============================================\n\nexport type User = typeof users.$inferSelect;\nexport type NewUser = typeof users.$inferInsert;\nexport type Conversation = typeof conversations.$inferSelect;\nexport type NewConversation = typeof conversations.$inferInsert;\nexport type Message = typeof messages.$inferSelect;\nexport type NewMessage = typeof messages.$inferInsert;\nexport type Memory = typeof memories.$inferSelect;\nexport type NewMemory = typeof memories.$inferInsert;\n\n// Security types\nexport type Session = typeof sessions.$inferSelect;\nexport type NewSession = typeof sessions.$inferInsert;\nexport type AuditLog = typeof auditLogs.$inferSelect;\nexport type NewAuditLog = typeof auditLogs.$inferInsert;\nexport type ApiKey = typeof apiKeys.$inferSelect;\nexport type NewApiKey = typeof apiKeys.$inferInsert;\n\n// Observability types\nexport type Metric = typeof metrics.$inferSelect;\nexport type NewMetric = typeof metrics.$inferInsert;\nexport type ErrorLog = typeof errorLogs.$inferSelect;\nexport type NewErrorLog = typeof errorLogs.$inferInsert;\n\n// Evolution system types\nexport type UsagePattern = typeof usagePatterns.$inferSelect;\nexport type NewUsagePattern = typeof usagePatterns.$inferInsert;\nexport type Achievement = typeof achievements.$inferSelect;\nexport type NewAchievement = typeof achievements.$inferInsert;\nexport type UserAchievement = typeof userAchievements.$inferSelect;\nexport type EvolutionMode = typeof evolutionModes.$inferSelect;\nexport type NewEvolutionMode = typeof evolutionModes.$inferInsert;\n\n// Sub-agent types\nexport type SubAgent = typeof subAgents.$inferSelect;\nexport type NewSubAgent = typeof subAgents.$inferInsert;\nexport type AgentMessage = typeof agentMessages.$inferSelect;\nexport type AgentProgress = typeof agentProgress.$inferSelect;\n\n// Personality types\nexport type Persona = typeof personas.$inferSelect;\nexport type NewPersona = typeof personas.$inferInsert;\n\n// Enterprise types\nexport type Organization = typeof organizations.$inferSelect;\nexport type NewOrganization = typeof organizations.$inferInsert;\nexport type OrganizationMember = typeof organizationMembers.$inferSelect;\n\n// Knowledge graph types\nexport type GraphEntity = typeof graphEntities.$inferSelect;\nexport type NewGraphEntity = typeof graphEntities.$inferInsert;\nexport type GraphRelationship = typeof graphRelationships.$inferSelect;\nexport type NewGraphRelationship = typeof graphRelationships.$inferInsert;\n\n// Document knowledge base types\nexport type Document = typeof documents.$inferSelect;\nexport type NewDocument = typeof documents.$inferInsert;\nexport type DocumentChunk = typeof documentChunks.$inferSelect;\nexport type NewDocumentChunk = typeof documentChunks.$inferInsert;\n\n// ============================================\n// SOC 2 COMPLIANCE TABLES\n// ============================================\n\n// Two-factor authentication (persisted, encrypted secrets)\nexport const twoFactorAuth = pgTable(\n \"two_factor_auth\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n userId: uuid(\"user_id\")\n .references(() => users.id, { onDelete: \"cascade\" })\n .notNull()\n .unique(),\n secretEncrypted: text(\"secret_encrypted\").notNull(),\n recoveryCodes: jsonb(\"recovery_codes\").$type<string[]>().notNull(),\n enabledAt: timestamp(\"enabled_at\").notNull(),\n lastVerifiedAt: timestamp(\"last_verified_at\"),\n keyVersion: integer(\"key_version\").default(1).notNull(),\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n },\n (table) => [index(\"two_factor_auth_user_idx\").on(table.userId)]\n);\n\n// Security incidents tracking\nexport const securityIncidents = pgTable(\n \"security_incidents\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n incidentNumber: text(\"incident_number\").notNull().unique(),\n title: text(\"title\").notNull(),\n description: text(\"description\").notNull(),\n type: text(\"type\")\n .notNull()\n .$type<\n | \"brute_force\"\n | \"unauthorized_access\"\n | \"data_breach\"\n | \"suspicious_activity\"\n | \"system_compromise\"\n | \"policy_violation\"\n >(),\n severity: text(\"severity\")\n .notNull()\n .$type<\"low\" | \"medium\" | \"high\" | \"critical\">(),\n status: text(\"status\")\n .notNull()\n .$type<\"open\" | \"investigating\" | \"contained\" | \"resolved\" | \"closed\">()\n .default(\"open\"),\n userId: uuid(\"user_id\").references(() => users.id),\n assignedTo: uuid(\"assigned_to\").references(() => users.id),\n source: text(\"source\").notNull(),\n sourceData: jsonb(\"source_data\"),\n impactAssessment: text(\"impact_assessment\"),\n containmentActions: jsonb(\"containment_actions\"),\n resolutionNotes: text(\"resolution_notes\"),\n relatedIncidents: jsonb(\"related_incidents\").$type<string[]>(),\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n investigatedAt: timestamp(\"investigated_at\"),\n containedAt: timestamp(\"contained_at\"),\n resolvedAt: timestamp(\"resolved_at\"),\n closedAt: timestamp(\"closed_at\"),\n },\n (table) => [\n index(\"security_incidents_status_idx\").on(table.status),\n index(\"security_incidents_severity_idx\").on(table.severity),\n index(\"security_incidents_created_idx\").on(table.createdAt),\n ]\n);\n\n// Incident timeline events\nexport const incidentTimeline = pgTable(\n \"incident_timeline\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n incidentId: uuid(\"incident_id\")\n .references(() => securityIncidents.id, { onDelete: \"cascade\" })\n .notNull(),\n eventType: text(\"event_type\")\n .notNull()\n .$type<\n | \"created\"\n | \"status_change\"\n | \"assignment\"\n | \"comment\"\n | \"action_taken\"\n | \"escalation\"\n | \"resolution\"\n >(),\n description: text(\"description\").notNull(),\n performedBy: uuid(\"performed_by\").references(() => users.id),\n metadata: jsonb(\"metadata\"),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [index(\"incident_timeline_incident_idx\").on(table.incidentId)]\n);\n\n// SOC 2 types\nexport type TwoFactorAuthRecord = typeof twoFactorAuth.$inferSelect;\nexport type NewTwoFactorAuthRecord = typeof twoFactorAuth.$inferInsert;\nexport type SecurityIncident = typeof securityIncidents.$inferSelect;\nexport type NewSecurityIncident = typeof securityIncidents.$inferInsert;\nexport type IncidentTimelineEvent = typeof incidentTimeline.$inferSelect;\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config/env.ts"],"sourcesContent":["import { z } from \"zod\";\r\n\r\nconst envSchema = z.object({\r\n // Claude API\r\n CLAUDE_API_KEY: z.string().min(1, \"CLAUDE_API_KEY is required\"),\r\n\r\n // Telegram\r\n TELEGRAM_BOT_TOKEN: z.string().optional().default(\"\"),\r\n TELEGRAM_CHAT_ID: z.string().optional().default(\"\"),\r\n\r\n // OpenAI (Whisper STT)\r\n OPENAI_API_KEY: z.string().optional().default(\"\"),\r\n\r\n // ElevenLabs TTS\r\n ELEVENLABS_API_KEY: z.string().optional().default(\"\"),\r\n ELEVENLABS_VOICE_ID: z.string().optional().default(\"\"),\r\n\r\n // Database\r\n DATABASE_URL: z\r\n .string()\r\n .default(\"\"),\r\n\r\n // Redis\r\n REDIS_URL: z.string().default(\"redis://localhost:6379\"),\r\n\r\n // Discord (optional)\r\n DISCORD_BOT_TOKEN: z.string().optional(),\r\n DISCORD_CLIENT_ID: z.string().optional(),\r\n DISCORD_GUILD_ID: z.string().optional(),\r\n DISCORD_ALLOWED_USER_IDS: z.string().optional(), // Comma-separated list\r\n DISCORD_ALLOWED_ROLE_IDS: z.string().optional(), // Comma-separated list\r\n\r\n // Slack (optional)\r\n SLACK_BOT_TOKEN: z.string().optional(),\r\n SLACK_SIGNING_SECRET: z.string().optional(),\r\n SLACK_APP_TOKEN: z.string().optional(),\r\n SLACK_SOCKET_MODE: z.coerce.boolean().optional().default(false),\r\n SLACK_PORT: z.coerce.number().optional().default(3000),\r\n SLACK_ALLOWED_USER_IDS: z.string().optional(), // Comma-separated list\r\n SLACK_ALLOWED_CHANNEL_IDS: z.string().optional(), // Comma-separated list\r\n\r\n // Notion (optional)\r\n NOTION_API_KEY: z.string().optional(),\r\n NOTION_ROOT_PAGE_ID: z.string().optional(),\r\n\r\n // Email (optional)\r\n EMAIL_IMAP_HOST: z.string().optional(),\r\n EMAIL_IMAP_PORT: z.coerce.number().optional().default(993),\r\n EMAIL_IMAP_SECURE: z.coerce.boolean().optional().default(true),\r\n EMAIL_SMTP_HOST: z.string().optional(),\r\n EMAIL_SMTP_PORT: z.coerce.number().optional().default(587),\r\n EMAIL_SMTP_SECURE: z.coerce.boolean().optional().default(false),\r\n EMAIL_USER: z.string().optional(),\r\n EMAIL_PASSWORD: z.string().optional(),\r\n EMAIL_PROVIDER: z.enum([\"gmail\", \"outlook\", \"yahoo\", \"custom\"]).optional(),\r\n\r\n // Local Mail Server (Dovecot master user for multi-account access)\r\n EMAIL_MASTER_USER: z.string().optional(),\r\n EMAIL_MASTER_PASSWORD: z.string().optional(),\r\n EMAIL_LOCAL_IMAP_HOST: z.string().optional().default(\"127.0.0.1\"),\r\n EMAIL_LOCAL_IMAP_PORT: z.coerce.number().optional().default(993),\r\n EMAIL_LOCAL_SMTP_HOST: z.string().optional().default(\"127.0.0.1\"),\r\n EMAIL_LOCAL_SMTP_PORT: z.coerce.number().optional().default(25),\r\n\r\n // GitHub (optional)\r\n GITHUB_TOKEN: z.string().optional(),\r\n GITHUB_WEBHOOK_SECRET: z.string().optional(),\r\n\r\n // Google Services (unified OAuth2 — optional, falls back to service-specific)\r\n GOOGLE_CLIENT_ID: z.string().optional(),\r\n GOOGLE_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_REDIRECT_URI: z.string().optional(),\r\n GOOGLE_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Google Drive (optional)\r\n GOOGLE_DRIVE_CLIENT_ID: z.string().optional(),\r\n GOOGLE_DRIVE_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_DRIVE_REDIRECT_URI: z.string().optional(),\r\n GOOGLE_DRIVE_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Dropbox (optional)\r\n DROPBOX_APP_KEY: z.string().optional(),\r\n DROPBOX_APP_SECRET: z.string().optional(),\r\n DROPBOX_ACCESS_TOKEN: z.string().optional(),\r\n DROPBOX_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // GIF Search (optional)\r\n TENOR_API_KEY: z.string().optional(),\r\n GIPHY_API_KEY: z.string().optional(),\r\n\r\n // Finance (optional)\r\n ALPHA_VANTAGE_API_KEY: z.string().optional(),\r\n FRED_API_KEY: z.string().optional(), // Federal Reserve Economic Data\r\n FINNHUB_API_KEY: z.string().optional(), // Finnhub financial market data\r\n\r\n // Exchange Trading (optional)\r\n COINBASE_API_KEY: z.string().optional(),\r\n COINBASE_PRIVATE_KEY: z.string().optional(),\r\n BINANCE_API_KEY: z.string().optional(),\r\n BINANCE_API_SECRET: z.string().optional(),\r\n BINANCE_TESTNET: z.coerce.boolean().optional().default(false),\r\n EXCHANGE_REQUIRE_CONFIRMATION: z.coerce.boolean().optional().default(true),\r\n EXCHANGE_MAX_TRADE_SIZE: z.coerce.number().optional().default(100),\r\n EXCHANGE_MAX_DAILY_SPEND: z.coerce.number().optional().default(500),\r\n EXCHANGE_MAX_TRADES_PER_HOUR: z.coerce.number().optional().default(5),\r\n EXCHANGE_AGENT_TRADING_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // DeFi (optional)\r\n DEFILLAMA_API_KEY: z.string().optional(), // Pro tier\r\n\r\n // On-Chain Analytics (optional)\r\n ETHERSCAN_API_KEY: z.string().optional(),\r\n ALCHEMY_API_KEY: z.string().optional(),\r\n ALCHEMY_NETWORK: z.string().optional().default(\"eth-mainnet\"),\r\n\r\n // Optional\r\n HUGGINGFACE_ACCESS_TOKEN: z.string().optional(),\r\n TWILIO_ACCOUNT_SID: z.string().optional(),\r\n TWILIO_AUTH_TOKEN: z.string().optional(),\r\n TWILIO_PHONE_NUMBER: z.string().optional(),\r\n\r\n // Home Assistant (optional)\r\n HOME_ASSISTANT_URL: z.string().url().optional(),\r\n HOME_ASSISTANT_TOKEN: z.string().optional(),\r\n\r\n // Spotify (optional)\r\n SPOTIFY_CLIENT_ID: z.string().optional(),\r\n SPOTIFY_CLIENT_SECRET: z.string().optional(),\r\n SPOTIFY_REDIRECT_URI: z.string().optional(),\r\n SPOTIFY_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Google Calendar (optional)\r\n GOOGLE_CALENDAR_CLIENT_ID: z.string().optional(),\r\n GOOGLE_CALENDAR_CLIENT_SECRET: z.string().optional(),\r\n GOOGLE_CALENDAR_REDIRECT_URI: z.string().url().optional(),\r\n GOOGLE_CALENDAR_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Outlook Calendar (optional)\r\n OUTLOOK_CLIENT_ID: z.string().optional(),\r\n OUTLOOK_CLIENT_SECRET: z.string().optional(),\r\n OUTLOOK_REDIRECT_URI: z.string().url().optional(),\r\n OUTLOOK_REFRESH_TOKEN: z.string().optional(),\r\n\r\n // Dropbox (additional OAuth fields)\r\n DROPBOX_CLIENT_ID: z.string().optional(),\r\n DROPBOX_CLIENT_SECRET: z.string().optional(),\r\n DROPBOX_REDIRECT_URI: z.string().url().optional(),\r\n\r\n // MCP (Model Context Protocol)\r\n MCP_ENABLED: z.coerce.boolean().optional().default(true),\r\n MCP_CONFIG_PATH: z.string().optional().default(\"./mcp.json\"),\r\n\r\n // Multi-Provider LLM\r\n LLM_PROVIDER: z.string().optional().default(\"anthropic\"),\r\n OPENROUTER_API_KEY: z.string().optional(),\r\n OPENROUTER_BASE_URL: z.string().optional(),\r\n GROQ_API_KEY: z.string().optional(),\r\n MISTRAL_API_KEY: z.string().optional(),\r\n OPENAI_LLM_ENABLED: z.coerce.boolean().optional().default(false),\r\n OPENAI_COMPATIBLE_API_KEY: z.string().optional(),\r\n OPENAI_COMPATIBLE_BASE_URL: z.string().optional(),\r\n OPENAI_COMPATIBLE_MODEL: z.string().optional(),\r\n\r\n // xAI (Grok)\r\n XAI_API_KEY: z.string().optional(),\r\n XAI_DEFAULT_MODEL: z.string().optional().default(\"grok-2\"),\r\n\r\n // Google Gemini (optional)\r\n GEMINI_API_KEY: z.string().optional(),\r\n GEMINI_DEFAULT_MODEL: z.string().optional().default(\"gemini-2.0-flash\"),\r\n\r\n // Ollama (local models)\r\n OLLAMA_ENABLED: z.coerce.boolean().optional().default(false),\r\n OLLAMA_BASE_URL: z.string().optional().default(\"http://localhost:11434\"),\r\n OLLAMA_DEFAULT_MODEL: z.string().optional().default(\"llama3.1\"),\r\n\r\n // Model Routing\r\n MODEL_ROUTING_ENABLED: z.coerce.boolean().optional().default(true),\r\n MODEL_OPUS_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Context Compaction\r\n COMPACTION_ENABLED: z.coerce.boolean().optional().default(true),\r\n COMPACTION_TOKEN_THRESHOLD: z.coerce.number().optional().default(80000),\r\n COMPACTION_PRESERVE_RECENT: z.coerce.number().optional().default(6),\r\n\r\n // Security (OWASP Agentic)\r\n PROMPT_GUARD_ENABLED: z.coerce.boolean().optional().default(true),\r\n PROMPT_GUARD_THRESHOLD: z.coerce.number().optional().default(0.7),\r\n CIRCUIT_BREAKER_ENABLED: z.coerce.boolean().optional().default(true),\r\n TOOL_SANDBOX_ENABLED: z.coerce.boolean().optional().default(true),\r\n\r\n // Observability\r\n COST_TRACKING_ENABLED: z.coerce.boolean().optional().default(true),\r\n QUALITY_SCORING_ENABLED: z.coerce.boolean().optional().default(true),\r\n REQUEST_TRACING_ENABLED: z.coerce.boolean().optional().default(true),\r\n\r\n // Intent Parser & Gateway\r\n LOCAL_INTENT_PARSER_ENABLED: z.coerce.boolean().optional().default(true),\r\n UNIFIED_GATEWAY_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // WhatsApp (optional)\r\n WHATSAPP_ENABLED: z.coerce.boolean().optional().default(false),\r\n WHATSAPP_AUTH_DIR: z.string().optional().default(\"./whatsapp-auth\"),\r\n WHATSAPP_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // Signal (optional)\r\n SIGNAL_ENABLED: z.coerce.boolean().optional().default(false),\r\n SIGNAL_PHONE_NUMBER: z.string().optional(),\r\n SIGNAL_CLI_PATH: z.string().optional().default(\"signal-cli\"),\r\n SIGNAL_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // iMessage (optional, macOS only)\r\n IMESSAGE_ENABLED: z.coerce.boolean().optional().default(false),\r\n IMESSAGE_MODE: z.enum([\"bluebubbles\", \"applescript\"]).optional().default(\"applescript\"),\r\n IMESSAGE_BLUEBUBBLES_URL: z.string().optional(),\r\n IMESSAGE_BLUEBUBBLES_PASSWORD: z.string().optional(),\r\n IMESSAGE_ALLOWED_NUMBERS: z.string().optional(), // Comma-separated\r\n\r\n // Tunnel Support\r\n TUNNEL_ENABLED: z.coerce.boolean().optional().default(false),\r\n TUNNEL_PROVIDER: z.enum([\"cloudflare\", \"ngrok\", \"localtunnel\"]).optional().default(\"cloudflare\"),\r\n TUNNEL_SUBDOMAIN: z.string().optional(),\r\n TUNNEL_AUTH_TOKEN: z.string().optional(),\r\n\r\n // Autonomy Levels\r\n AUTONOMY_LEVEL: z.enum([\"readonly\", \"supervised\", \"autonomous\"]).optional().default(\"autonomous\"),\r\n\r\n // Prometheus/OpenTelemetry\r\n PROMETHEUS_ENABLED: z.coerce.boolean().optional().default(false),\r\n PROMETHEUS_PATH: z.string().optional().default(\"/metrics\"),\r\n\r\n // Device Pairing\r\n PAIRING_ENABLED: z.coerce.boolean().optional().default(false),\r\n PAIRING_CODE_LIFETIME_MINUTES: z.coerce.number().optional().default(5),\r\n\r\n // Gateway Authentication (OpenClaw-style)\r\n // If set, web UI and API requests require this token. Unset = open access (localhost-friendly).\r\n GATEWAY_TOKEN: z.string().optional(),\r\n\r\n // Matrix (optional)\r\n MATRIX_ENABLED: z.coerce.boolean().optional().default(false),\r\n MATRIX_HOMESERVER_URL: z.string().optional(),\r\n MATRIX_ACCESS_TOKEN: z.string().optional(),\r\n MATRIX_USER_ID: z.string().optional(),\r\n MATRIX_ALLOWED_ROOM_IDS: z.string().optional(), // Comma-separated\r\n MATRIX_AUTO_JOIN: z.coerce.boolean().optional().default(true),\r\n MATRIX_E2E_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Neo4j (OSINT graph database)\r\n NEO4J_URI: z.string().optional().default(\"bolt://localhost:7687\"),\r\n NEO4J_USER: z.string().optional().default(\"neo4j\"),\r\n NEO4J_PASSWORD: z.string().optional().default(\"\"),\r\n NEO4J_DATABASE: z.string().optional().default(\"neo4j\"),\r\n\r\n // OSINT API Keys\r\n FEC_API_KEY: z.string().optional().default(\"\"),\r\n OPENCORPORATES_API_TOKEN: z.string().optional().default(\"\"),\r\n SEC_EDGAR_USER_AGENT: z.string().optional().default(\"OpenSentinel/2.1 (contact@opensentinel.ai)\"),\r\n\r\n // OSINT Feature Toggle\r\n OSINT_ENABLED: z.coerce.boolean().optional().default(false),\r\n OSINT_RATE_LIMIT_BUFFER_MS: z.coerce.number().optional().default(200),\r\n\r\n // Embedding Provider\r\n EMBEDDING_PROVIDER: z.enum([\"openai\", \"huggingface\", \"tfidf\"]).optional().default(\"openai\"),\r\n EMBEDDING_MODEL: z.string().optional(),\r\n EMBEDDING_DIMENSIONS: z.coerce.number().optional(),\r\n EMBEDDING_DB_DIMENSIONS: z.coerce.number().optional().default(1536),\r\n EMBEDDING_BATCH_SIZE: z.coerce.number().optional().default(32),\r\n\r\n // Advanced RAG\r\n HYDE_ENABLED: z.coerce.boolean().optional().default(false),\r\n RERANK_ENABLED: z.coerce.boolean().optional().default(false),\r\n RERANK_MIN_SCORE: z.coerce.number().optional().default(3),\r\n MULTISTEP_RAG_ENABLED: z.coerce.boolean().optional().default(false),\r\n MULTISTEP_MAX_STEPS: z.coerce.number().optional().default(2),\r\n RETRIEVAL_CACHE_ENABLED: z.coerce.boolean().optional().default(false),\r\n CONTEXTUAL_QUERY_ENABLED: z.coerce.boolean().optional().default(false),\r\n\r\n // Agentic RAG Pipeline\r\n TOOL_CLASSIFIER_ENABLED: z.coerce.boolean().optional().default(false),\r\n TOOL_CLASSIFIER_TIMEOUT_MS: z.coerce.number().optional().default(5000),\r\n TOOL_CLASSIFIER_MAX_CATEGORIES: z.coerce.number().optional().default(3),\r\n\r\n // AI Memory (auto-extract/search)\r\n AUTO_MEMORY_EXTRACT_ENABLED: z.coerce.boolean().optional().default(false),\r\n AUTO_MEMORY_EXTRACT_DEDUP_THRESHOLD: z.coerce.number().optional().default(0.9),\r\n AUTO_MEMORY_SEARCH_THRESHOLD: z.coerce.number().optional().default(0.3),\r\n\r\n // Agentic Pipeline Orchestrator\r\n AGENTIC_PIPELINE_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENTIC_PRE_EXECUTION_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENTIC_PRE_EXECUTION_TIMEOUT_MS: z.coerce.number().optional().default(8000),\r\n\r\n // Agent Processor\r\n AGENT_PROCESSOR_ENABLED: z.coerce.boolean().optional().default(false),\r\n AGENT_PROCESSOR_CONCURRENCY: z.coerce.number().optional().default(1),\r\n AGENT_MAX_TURNS: z.coerce.number().optional().default(20),\r\n\r\n // SOC 2 Encryption & Audit\r\n ENCRYPTION_MASTER_KEY: z.string().optional(), // 32-byte base64 key for field encryption\r\n AUDIT_SIGNING_KEY: z.string().optional(), // HMAC key for tamper-proof audit logs\r\n\r\n // Server\r\n PORT: z.coerce.number().default(8030),\r\n NODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\r\n});\r\n\r\nexport type Env = z.infer<typeof envSchema>;\r\n\r\n// Internal mutable store\r\nlet _env: Env | null = null;\r\n\r\n/**\r\n * Programmatic configuration for library use.\r\n * Call this before any module accesses `env`.\r\n * Config values are merged with process.env (config takes precedence).\r\n */\r\nlet _providerInitPromise: Promise<void> | null = null;\r\n\r\nexport function configure(config: Partial<Env> & { CLAUDE_API_KEY: string }): Env {\r\n const merged = { ...process.env, ...config };\r\n const result = envSchema.safeParse(merged);\r\n\r\n if (!result.success) {\r\n const errors = result.error.errors.map(\r\n (e) => `${e.path.join(\".\")}: ${e.message}`\r\n );\r\n throw new Error(\r\n `OpenSentinel configuration validation failed:\\n ${errors.join(\"\\n \")}`\r\n );\r\n }\r\n\r\n _env = result.data;\r\n\r\n // Auto-initialize LLM providers after configuration\r\n _providerInitPromise = import(\"../core/providers\").then((m) => m.initializeProviders()).catch(() => {});\r\n\r\n return _env;\r\n}\r\n\r\n/**\r\n * Wait for provider initialization to complete.\r\n * Call after configure() if you need providers ready before first API call.\r\n */\r\nexport async function ready(): Promise<void> {\r\n if (_providerInitPromise) await _providerInitPromise;\r\n}\r\n\r\n/**\r\n * Load config from process.env.\r\n * Called lazily on first access if configure() was not called.\r\n *\r\n * When used as a library, env vars may not be set at import time\r\n * (module-level singletons trigger this during static initialization).\r\n * In that case, we populate with defaults and partial values rather\r\n * than throwing — services will fail with clear errors when actually used.\r\n */\r\nfunction loadFromProcessEnv(): Env {\r\n const result = envSchema.safeParse(process.env);\r\n\r\n if (!result.success) {\r\n // If running as CLI (not library), throw so the user sees the error immediately\r\n if (process.env.__OPENSENTINEL_CLI__) {\r\n const errors = result.error.errors.map(\r\n (e) => `${e.path.join(\".\")}: ${e.message}`\r\n );\r\n throw new Error(\r\n `Environment validation failed:\\n ${errors.join(\"\\n \")}`\r\n );\r\n }\r\n\r\n // For library use: populate with whatever we have, fill missing with defaults\r\n // Services will fail individually when they try to use undefined API keys\r\n const lenientSchema = envSchema.extend({\r\n CLAUDE_API_KEY: z.string().default(\"\"),\r\n });\r\n const lenientResult = lenientSchema.safeParse(process.env);\r\n _env = (lenientResult.success ? lenientResult.data : {}) as Env;\r\n return _env;\r\n }\r\n\r\n _env = result.data;\r\n return _env;\r\n}\r\n\r\n/**\r\n * The env accessor. Lazy — loads from process.env on first access\r\n * if configure() was not called first.\r\n *\r\n * All 37+ consumer files keep using `env.SOME_PROP` unchanged.\r\n */\r\nexport const env: Env = new Proxy({} as Env, {\r\n get(_target, prop: string) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return (_env as any)[prop];\r\n },\r\n has(_target, prop: string) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return prop in (_env as any);\r\n },\r\n ownKeys() {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return Reflect.ownKeys(_env as any);\r\n },\r\n getOwnPropertyDescriptor(_target, prop) {\r\n if (!_env) {\r\n loadFromProcessEnv();\r\n }\r\n return Object.getOwnPropertyDescriptor(_env as any, prop);\r\n },\r\n});\r\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/mcp/client.ts","../src/core/mcp/registry.ts","../src/core/mcp/tool-bridge.ts"],"sourcesContent":["/**\n * MCP Client - Handles communication with MCP servers\n * Supports STDIO and HTTP+SSE transports\n */\n\nimport { spawn, type ChildProcess } from \"node:child_process\";\nimport { nanoid } from \"nanoid\";\nimport type {\n MCPServerConfig,\n MCPServerState,\n MCPTool,\n MCPInitializeParams,\n MCPInitializeResult,\n MCPToolListResult,\n MCPToolCallParams,\n MCPToolCallResult,\n MCPToolResult,\n JsonRpcRequest,\n JsonRpcResponse,\n} from \"./types\";\n\nconst MCP_PROTOCOL_VERSION = \"2024-11-05\";\n\nexport class MCPClient {\n private config: MCPServerConfig;\n private state: MCPServerState;\n private process: ChildProcess | null = null;\n private pendingRequests: Map<string | number, {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n timeout: Timer;\n }> = new Map();\n private messageBuffer = \"\";\n private requestTimeout: number;\n\n constructor(config: MCPServerConfig, timeout = 30000) {\n this.config = config;\n this.requestTimeout = timeout;\n this.state = {\n config,\n status: \"disconnected\",\n tools: [],\n };\n }\n\n get id(): string {\n return this.config.id;\n }\n\n get name(): string {\n return this.config.name;\n }\n\n get status(): MCPServerState[\"status\"] {\n return this.state.status;\n }\n\n get tools(): MCPTool[] {\n return this.state.tools;\n }\n\n get serverInfo() {\n return this.state.serverInfo;\n }\n\n // ============================================\n // CONNECTION MANAGEMENT\n // ============================================\n\n async connect(): Promise<void> {\n if (this.state.status === \"connected\") {\n return;\n }\n\n this.state.status = \"connecting\";\n\n try {\n if (this.config.transport === \"stdio\") {\n await this.connectStdio();\n } else if (this.config.transport === \"http+sse\") {\n await this.connectHttpSse();\n } else {\n throw new Error(`Unsupported transport: ${this.config.transport}`);\n }\n\n // Initialize MCP connection\n const initResult = await this.initialize();\n this.state.capabilities = initResult.capabilities;\n this.state.serverInfo = initResult.serverInfo;\n\n // Fetch available tools\n await this.refreshTools();\n\n this.state.status = \"connected\";\n this.state.lastActivity = new Date();\n\n console.log(`[MCP] Connected to ${this.name} (${this.state.tools.length} tools)`);\n } catch (error) {\n this.state.status = \"error\";\n this.state.lastError = error instanceof Error ? error.message : \"Unknown error\";\n throw error;\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.state.status === \"disconnected\") {\n return;\n }\n\n // Cancel pending requests\n for (const [, pending] of this.pendingRequests) {\n clearTimeout(pending.timeout);\n pending.reject(new Error(\"Connection closed\"));\n }\n this.pendingRequests.clear();\n\n // Kill subprocess if STDIO\n if (this.process) {\n this.process.kill();\n this.process = null;\n }\n\n this.state.status = \"disconnected\";\n this.state.tools = [];\n console.log(`[MCP] Disconnected from ${this.name}`);\n }\n\n // ============================================\n // STDIO TRANSPORT\n // ============================================\n\n private async connectStdio(): Promise<void> {\n if (!this.config.command) {\n throw new Error(\"STDIO transport requires a command\");\n }\n\n const env: Record<string, string> = {\n ...process.env as Record<string, string>,\n ...this.config.env,\n };\n\n this.process = spawn(\n this.config.command,\n this.config.args || [],\n {\n cwd: this.config.cwd || process.cwd(),\n env,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n }\n );\n\n // Start reading stdout in background\n this.readStdout();\n\n // Start reading stderr in background\n this.readStderr();\n\n // Give the process a moment to start\n await new Promise((resolve) => setTimeout(resolve, 500));\n }\n\n private readStdout(): void {\n if (!this.process?.stdout) return;\n\n this.process.stdout.on(\"data\", (chunk: Buffer) => {\n this.messageBuffer += chunk.toString();\n this.processMessageBuffer();\n });\n\n this.process.stdout.on(\"error\", (error) => {\n if (this.state.status === \"connected\" || this.state.status === \"connecting\") {\n console.error(`[MCP] ${this.name} stdout error:`, error);\n }\n });\n }\n\n private readStderr(): void {\n if (!this.process?.stderr) return;\n\n this.process.stderr.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n if (text.trim()) {\n console.log(`[MCP] ${this.name} stderr: ${text.trim()}`);\n }\n });\n }\n\n private processMessageBuffer(): void {\n // JSON-RPC messages are newline-delimited\n const lines = this.messageBuffer.split(\"\\n\");\n this.messageBuffer = lines.pop() || \"\";\n\n for (const line of lines) {\n if (!line.trim()) continue;\n\n try {\n const message = JSON.parse(line) as JsonRpcResponse;\n this.handleResponse(message);\n } catch {\n console.warn(`[MCP] ${this.name} failed to parse message: ${line.slice(0, 100)}`);\n }\n }\n }\n\n private handleResponse(response: JsonRpcResponse): void {\n if (response.id === undefined || response.id === null) {\n // Notification from server, ignore for now\n return;\n }\n\n const pending = this.pendingRequests.get(response.id);\n if (!pending) {\n console.warn(`[MCP] ${this.name} received response for unknown request: ${response.id}`);\n return;\n }\n\n clearTimeout(pending.timeout);\n this.pendingRequests.delete(response.id);\n\n if (response.error) {\n pending.reject(new Error(response.error.message));\n } else {\n pending.resolve(response.result);\n }\n }\n\n private async sendRequest(method: string, params?: unknown): Promise<unknown> {\n if (!this.process?.stdin) {\n throw new Error(\"Not connected\");\n }\n\n const id = nanoid();\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id,\n method,\n params,\n };\n\n const promise = new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request timeout: ${method}`));\n }, this.requestTimeout);\n\n this.pendingRequests.set(id, { resolve, reject, timeout });\n });\n\n // Write request to stdin\n const data = JSON.stringify(request) + \"\\n\";\n this.process.stdin.write(data);\n\n return promise;\n }\n\n // ============================================\n // HTTP+SSE TRANSPORT\n // ============================================\n\n private async connectHttpSse(): Promise<void> {\n if (!this.config.url) {\n throw new Error(\"HTTP+SSE transport requires a URL\");\n }\n\n // For HTTP+SSE, we don't maintain a persistent connection\n // Each request is a separate HTTP call\n // SSE is used for streaming responses (not implemented yet)\n\n // Just verify the server is reachable\n try {\n const response = await fetch(`${this.config.url}/health`, {\n headers: this.config.headers,\n });\n\n if (!response.ok) {\n throw new Error(`Server health check failed: ${response.status}`);\n }\n } catch (error) {\n // Health endpoint might not exist, try main endpoint\n const response = await fetch(this.config.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.config.headers,\n },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: \"ping\",\n method: \"ping\",\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Server connection failed: ${response.status}`);\n }\n }\n }\n\n private async sendHttpRequest(method: string, params?: unknown): Promise<unknown> {\n if (!this.config.url) {\n throw new Error(\"HTTP+SSE transport requires a URL\");\n }\n\n const request: JsonRpcRequest = {\n jsonrpc: \"2.0\",\n id: nanoid(),\n method,\n params,\n };\n\n const response = await fetch(this.config.url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.config.headers,\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP request failed: ${response.status}`);\n }\n\n const result = await response.json() as JsonRpcResponse;\n\n if (result.error) {\n throw new Error(result.error.message);\n }\n\n return result.result;\n }\n\n // ============================================\n // MCP PROTOCOL METHODS\n // ============================================\n\n private async initialize(): Promise<MCPInitializeResult> {\n const params: MCPInitializeParams = {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: {\n roots: { listChanged: true },\n },\n clientInfo: {\n name: \"OpenSentinel\",\n version: \"3.0.0\",\n },\n };\n\n const result = await this.request(\"initialize\", params) as MCPInitializeResult;\n\n // Send initialized notification\n await this.notify(\"notifications/initialized\", {});\n\n return result;\n }\n\n async refreshTools(): Promise<MCPTool[]> {\n const result = await this.request(\"tools/list\", {}) as MCPToolListResult;\n this.state.tools = result.tools || [];\n return this.state.tools;\n }\n\n async callTool(name: string, args?: Record<string, unknown>): Promise<MCPToolResult> {\n const params: MCPToolCallParams = {\n name,\n arguments: args,\n };\n\n try {\n const result = await this.request(\"tools/call\", params) as MCPToolCallResult;\n this.state.lastActivity = new Date();\n\n // Extract text content from result\n const textContent = result.content\n .filter((c) => c.type === \"text\" && c.text)\n .map((c) => c.text)\n .join(\"\\n\");\n\n return {\n success: !result.isError,\n output: textContent || JSON.stringify(result.content),\n isError: result.isError,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n }\n\n // ============================================\n // GENERIC REQUEST/NOTIFY\n // ============================================\n\n private async request(method: string, params?: unknown): Promise<unknown> {\n if (this.config.transport === \"stdio\") {\n return this.sendRequest(method, params);\n } else {\n return this.sendHttpRequest(method, params);\n }\n }\n\n private async notify(method: string, params?: unknown): Promise<void> {\n if (this.config.transport === \"stdio\" && this.process?.stdin) {\n const notification = {\n jsonrpc: \"2.0\",\n method,\n params,\n };\n this.process.stdin.write(JSON.stringify(notification) + \"\\n\");\n }\n // HTTP+SSE notifications are not typically supported\n }\n\n // ============================================\n // STATE ACCESS\n // ============================================\n\n getState(): MCPServerState {\n return { ...this.state };\n }\n}\n","/**\n * MCP Registry - Manages multiple MCP server connections\n * Aggregates tools from all connected servers\n */\n\nimport { MCPClient } from \"./client\";\nimport type {\n MCPConfig,\n MCPServerConfig,\n MCPServerState,\n MCPTool,\n MCPToolResult,\n} from \"./types\";\n\nexport class MCPRegistry {\n private clients: Map<string, MCPClient> = new Map();\n private config: MCPConfig;\n private defaultTimeout: number;\n\n constructor(config: MCPConfig) {\n this.config = config;\n this.defaultTimeout = config.settings?.timeout || 30000;\n }\n\n // ============================================\n // INITIALIZATION\n // ============================================\n\n /**\n * Connect to all enabled MCP servers\n */\n async initialize(): Promise<void> {\n const enabledServers = this.config.servers.filter((s) => s.enabled);\n\n console.log(`[MCP] Initializing ${enabledServers.length} server(s)...`);\n\n const withTimeout = (promise: Promise<void>, name: string, ms = 15000) =>\n Promise.race([\n promise,\n new Promise<void>((_, reject) =>\n setTimeout(() => reject(new Error(`${name} timed out after ${ms / 1000}s`)), ms)\n ),\n ]);\n\n const results = await Promise.allSettled(\n enabledServers.map((config) => withTimeout(this.connectServer(config), config.name))\n );\n\n // Log any failures\n results.forEach((result, index) => {\n if (result.status === \"rejected\") {\n console.error(\n `[MCP] Failed to connect to ${enabledServers[index].name}:`,\n result.reason\n );\n }\n });\n\n const connected = results.filter((r) => r.status === \"fulfilled\").length;\n console.log(`[MCP] Connected to ${connected}/${enabledServers.length} servers`);\n }\n\n /**\n * Connect to a single MCP server\n */\n async connectServer(config: MCPServerConfig): Promise<void> {\n if (this.clients.has(config.id)) {\n throw new Error(`Server ${config.id} already connected`);\n }\n\n const client = new MCPClient(config, this.defaultTimeout);\n await client.connect();\n this.clients.set(config.id, client);\n }\n\n /**\n * Disconnect from a specific server\n */\n async disconnectServer(id: string): Promise<void> {\n const client = this.clients.get(id);\n if (client) {\n await client.disconnect();\n this.clients.delete(id);\n }\n }\n\n /**\n * Disconnect from all servers\n */\n async shutdown(): Promise<void> {\n console.log(\"[MCP] Shutting down all connections...\");\n await Promise.all(\n Array.from(this.clients.values()).map((client) => client.disconnect())\n );\n this.clients.clear();\n }\n\n // ============================================\n // TOOL MANAGEMENT\n // ============================================\n\n /**\n * Get all tools from all connected servers\n * Tools are prefixed with \"mcp_{serverId}_\" for routing\n */\n getAllTools(): Array<{ serverId: string; tool: MCPTool }> {\n const tools: Array<{ serverId: string; tool: MCPTool }> = [];\n\n for (const [serverId, client] of this.clients) {\n if (client.status === \"connected\") {\n for (const tool of client.tools) {\n tools.push({ serverId, tool });\n }\n }\n }\n\n return tools;\n }\n\n /**\n * Get tools from a specific server\n */\n getServerTools(serverId: string): MCPTool[] {\n const client = this.clients.get(serverId);\n return client?.tools || [];\n }\n\n /**\n * Call a tool on a specific server\n */\n async callTool(\n serverId: string,\n toolName: string,\n args?: Record<string, unknown>\n ): Promise<MCPToolResult> {\n const client = this.clients.get(serverId);\n\n if (!client) {\n return {\n success: false,\n error: `MCP server not found: ${serverId}`,\n };\n }\n\n if (client.status !== \"connected\") {\n return {\n success: false,\n error: `MCP server not connected: ${serverId}`,\n };\n }\n\n console.log(`[MCP] Calling ${serverId}:${toolName}`);\n return client.callTool(toolName, args);\n }\n\n // ============================================\n // SERVER MANAGEMENT\n // ============================================\n\n /**\n * Get status of all servers\n */\n getServerStates(): MCPServerState[] {\n return Array.from(this.clients.values()).map((client) => client.getState());\n }\n\n /**\n * Get status of a specific server\n */\n getServerState(serverId: string): MCPServerState | undefined {\n return this.clients.get(serverId)?.getState();\n }\n\n /**\n * Check if a server is connected\n */\n isConnected(serverId: string): boolean {\n const client = this.clients.get(serverId);\n return client?.status === \"connected\";\n }\n\n /**\n * Refresh tools from all connected servers\n */\n async refreshAllTools(): Promise<void> {\n await Promise.all(\n Array.from(this.clients.values())\n .filter((client) => client.status === \"connected\")\n .map((client) => client.refreshTools())\n );\n }\n\n /**\n * Add a new server configuration and optionally connect\n */\n async addServer(config: MCPServerConfig, connect = true): Promise<void> {\n if (this.clients.has(config.id)) {\n throw new Error(`Server ${config.id} already exists`);\n }\n\n this.config.servers.push(config);\n\n if (connect && config.enabled) {\n await this.connectServer(config);\n }\n }\n\n /**\n * Remove a server\n */\n async removeServer(serverId: string): Promise<void> {\n await this.disconnectServer(serverId);\n this.config.servers = this.config.servers.filter((s) => s.id !== serverId);\n }\n\n /**\n * Get the current configuration\n */\n getConfig(): MCPConfig {\n return { ...this.config };\n }\n\n /**\n * Get count of connected servers\n */\n get connectedCount(): number {\n return Array.from(this.clients.values()).filter(\n (c) => c.status === \"connected\"\n ).length;\n }\n\n /**\n * Get total tool count across all servers\n */\n get totalToolCount(): number {\n return this.getAllTools().length;\n }\n}\n\n// ============================================\n// HELPER FUNCTIONS\n// ============================================\n\n/**\n * Load MCP configuration from a file\n */\nexport async function loadMCPConfig(path: string): Promise<MCPConfig> {\n try {\n const { readFile, access } = await import(\"node:fs/promises\");\n try {\n await access(path);\n } catch {\n console.log(`[MCP] Config file not found: ${path}, using empty config`);\n return { servers: [] };\n }\n\n const content = await readFile(path, \"utf-8\");\n const config = JSON.parse(content) as MCPConfig;\n\n // Validate config\n if (!Array.isArray(config.servers)) {\n console.warn(\"[MCP] Invalid config: servers must be an array\");\n return { servers: [] };\n }\n\n return config;\n } catch (error) {\n console.error(\"[MCP] Failed to load config:\", error);\n return { servers: [] };\n }\n}\n\n/**\n * Create and initialize an MCP registry from a config file\n */\nexport async function initMCPRegistry(configPath: string): Promise<MCPRegistry> {\n const config = await loadMCPConfig(configPath);\n const registry = new MCPRegistry(config);\n await registry.initialize();\n return registry;\n}\n","/**\n * MCP Tool Bridge - Converts MCP tools to Anthropic format\n * Handles tool routing between native and MCP tools\n */\n\nimport type { Tool } from \"@anthropic-ai/sdk/resources/messages\";\nimport type { MCPRegistry } from \"./registry\";\nimport type { MCPTool, MCPToolProperty, MCPToolResult } from \"./types\";\n\n// MCP tool prefix format: mcp_{serverId}_{toolName}\nconst MCP_TOOL_PREFIX = \"mcp_\";\n\n// ============================================\n// TOOL NAME UTILITIES\n// ============================================\n\n/**\n * Create a prefixed tool name for routing\n */\nexport function createMCPToolName(serverId: string, toolName: string): string {\n // Sanitize serverId and toolName to be safe for use as identifiers\n const safeServerId = serverId.replace(/[^a-zA-Z0-9_]/g, \"_\");\n const safeToolName = toolName.replace(/[^a-zA-Z0-9_]/g, \"_\");\n return `${MCP_TOOL_PREFIX}${safeServerId}__${safeToolName}`;\n}\n\n/**\n * Check if a tool name is an MCP tool\n */\nexport function isMCPTool(name: string): boolean {\n return name.startsWith(MCP_TOOL_PREFIX);\n}\n\n/**\n * Parse an MCP tool name to get serverId and original tool name\n */\nexport function parseMCPToolName(name: string): { serverId: string; toolName: string } | null {\n if (!isMCPTool(name)) {\n return null;\n }\n\n const withoutPrefix = name.slice(MCP_TOOL_PREFIX.length);\n const separatorIndex = withoutPrefix.indexOf(\"__\");\n\n if (separatorIndex === -1) {\n return null;\n }\n\n return {\n serverId: withoutPrefix.slice(0, separatorIndex),\n toolName: withoutPrefix.slice(separatorIndex + 2),\n };\n}\n\n// ============================================\n// SCHEMA CONVERSION\n// ============================================\n\n/**\n * Convert MCP tool property to JSON Schema format\n */\nfunction convertProperty(prop: MCPToolProperty): Record<string, unknown> {\n const result: Record<string, unknown> = {\n type: prop.type,\n };\n\n if (prop.description) {\n result.description = prop.description;\n }\n\n if (prop.enum) {\n result.enum = prop.enum;\n }\n\n if (prop.items) {\n result.items = convertProperty(prop.items);\n }\n\n if (prop.properties) {\n result.properties = Object.fromEntries(\n Object.entries(prop.properties).map(([key, value]) => [\n key,\n convertProperty(value),\n ])\n );\n }\n\n if (prop.required) {\n result.required = prop.required;\n }\n\n return result;\n}\n\n/**\n * Convert MCP tool to Anthropic Tool format\n */\nexport function mcpToolToAnthropicTool(\n serverId: string,\n serverName: string,\n tool: MCPTool\n): Tool {\n const properties: Record<string, Record<string, unknown>> = {};\n\n if (tool.inputSchema.properties) {\n for (const [key, value] of Object.entries(tool.inputSchema.properties)) {\n properties[key] = convertProperty(value);\n }\n }\n\n const inputSchema: Tool.InputSchema = {\n type: \"object\",\n properties,\n required: tool.inputSchema.required || [],\n };\n\n // Create a unique name and add server context to description\n const name = createMCPToolName(serverId, tool.name);\n const description = tool.description\n ? `[${serverName}] ${tool.description}`\n : `[${serverName}] ${tool.name}`;\n\n return {\n name,\n description,\n input_schema: inputSchema,\n };\n}\n\n/**\n * Convert all tools from an MCP registry to Anthropic format\n */\nexport function mcpToolsToAnthropicTools(registry: MCPRegistry): Tool[] {\n const tools: Tool[] = [];\n const serverStates = registry.getServerStates();\n\n for (const state of serverStates) {\n if (state.status !== \"connected\") continue;\n\n const serverName = state.serverInfo?.name || state.config.name;\n\n for (const tool of state.tools) {\n tools.push(mcpToolToAnthropicTool(state.config.id, serverName, tool));\n }\n }\n\n return tools;\n}\n\n// ============================================\n// TOOL EXECUTION\n// ============================================\n\n/**\n * Execute an MCP tool call through the registry\n */\nexport async function executeMCPTool(\n registry: MCPRegistry,\n toolName: string,\n args: Record<string, unknown>\n): Promise<MCPToolResult> {\n const parsed = parseMCPToolName(toolName);\n\n if (!parsed) {\n return {\n success: false,\n error: `Invalid MCP tool name: ${toolName}`,\n };\n }\n\n return registry.callTool(parsed.serverId, parsed.toolName, args);\n}\n\n// ============================================\n// TOOL DISCOVERY\n// ============================================\n\n/**\n * Get a summary of available MCP tools for logging/display\n */\nexport function getMCPToolSummary(registry: MCPRegistry): string {\n const states = registry.getServerStates();\n const lines: string[] = [];\n\n for (const state of states) {\n const status = state.status === \"connected\" ? \"✓\" : \"✗\";\n const serverName = state.serverInfo?.name || state.config.name;\n const toolCount = state.tools.length;\n\n lines.push(` ${status} ${serverName}: ${toolCount} tools`);\n\n if (state.status === \"connected\" && state.tools.length > 0) {\n const toolNames = state.tools.map((t) => t.name).join(\", \");\n lines.push(` Tools: ${toolNames}`);\n } else if (state.lastError) {\n lines.push(` Error: ${state.lastError}`);\n }\n }\n\n if (lines.length === 0) {\n return \" No MCP servers configured\";\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * Find an MCP tool by its original name (searches all servers)\n */\nexport function findMCPTool(\n registry: MCPRegistry,\n toolName: string\n): { serverId: string; tool: MCPTool } | null {\n const allTools = registry.getAllTools();\n\n for (const { serverId, tool } of allTools) {\n if (tool.name === toolName) {\n return { serverId, tool };\n }\n }\n\n return null;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/commands/utils.ts"],"sourcesContent":["/**\n * Shared CLI utilities for OpenSentinel commands.\n */\n\nimport { createInterface } from \"node:readline\";\nimport { exec as execCb } from \"node:child_process\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { existsSync, mkdirSync, readFileSync } from \"node:fs\";\n\n// ── Colors (ANSI escape codes) ───────────────────────────────────────────────\n\nexport const colors = {\n reset: \"\\x1b[0m\",\n bold: \"\\x1b[1m\",\n dim: \"\\x1b[2m\",\n green: \"\\x1b[32m\",\n cyan: \"\\x1b[36m\",\n yellow: \"\\x1b[33m\",\n red: \"\\x1b[31m\",\n magenta: \"\\x1b[35m\",\n};\n\n// ── Interactive prompts ──────────────────────────────────────────────────────\n\nexport async function prompt(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nexport async function confirm(question: string, defaultYes = true): Promise<boolean> {\n const hint = defaultYes ? \"[Y/n]\" : \"[y/N]\";\n const answer = await prompt(`${question} ${hint} `);\n if (answer === \"\") return defaultYes;\n return answer.toLowerCase().startsWith(\"y\");\n}\n\nexport async function promptSecret(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n // Disable echo for secret input\n if (process.stdin.isTTY) {\n process.stdin.setRawMode?.(false);\n }\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n// ── Shell execution ──────────────────────────────────────────────────────────\n\nexport interface ExecResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function exec(cmd: string, opts?: { throws?: boolean; input?: string }): Promise<ExecResult> {\n return new Promise((resolve, reject) => {\n const child = execCb(cmd, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {\n const exitCode = error?.code ?? 0;\n const result = { stdout: stdout.toString(), stderr: stderr.toString(), exitCode: typeof exitCode === \"number\" ? exitCode : 1 };\n if (error && opts?.throws !== false) {\n reject(Object.assign(error, result));\n } else {\n resolve(result);\n }\n });\n if (opts?.input) {\n child.stdin?.write(opts.input);\n child.stdin?.end();\n }\n });\n}\n\nexport async function which(binary: string): Promise<string | null> {\n try {\n const result = await exec(`which ${binary}`, { throws: false });\n return result.stdout.trim() || null;\n } catch {\n return null;\n }\n}\n\n// ── Platform detection ───────────────────────────────────────────────────────\n\nexport interface Platform {\n os: \"linux\" | \"darwin\" | \"other\";\n distro: string;\n packageManager: \"apt\" | \"brew\" | \"dnf\" | \"pacman\" | \"unknown\";\n}\n\nexport function detectPlatform(): Platform {\n const os = process.platform === \"linux\" ? \"linux\"\n : process.platform === \"darwin\" ? \"darwin\"\n : \"other\" as const;\n\n let distro = \"unknown\";\n let packageManager: Platform[\"packageManager\"] = \"unknown\";\n\n if (os === \"linux\") {\n try {\n const osRelease = readFileSync(\"/etc/os-release\", \"utf-8\");\n const idMatch = osRelease.match(/^ID=(.+)$/m);\n const idLikeMatch = osRelease.match(/^ID_LIKE=(.+)$/m);\n distro = idMatch?.[1]?.replace(/\"/g, \"\") || \"unknown\";\n const idLike = idLikeMatch?.[1]?.replace(/\"/g, \"\") || \"\";\n\n if (distro === \"ubuntu\" || distro === \"debian\" || idLike.includes(\"debian\")) {\n packageManager = \"apt\";\n } else if (distro === \"fedora\" || idLike.includes(\"fedora\") || idLike.includes(\"rhel\")) {\n packageManager = \"dnf\";\n } else if (distro === \"arch\" || idLike.includes(\"arch\")) {\n packageManager = \"pacman\";\n }\n } catch {}\n } else if (os === \"darwin\") {\n packageManager = \"brew\";\n distro = \"macos\";\n }\n\n return { os, distro, packageManager };\n}\n\n// ── Config directory ─────────────────────────────────────────────────────────\n\nexport function getConfigDir(): string {\n const dir = process.env.OPENSENTINEL_HOME || join(homedir(), \".opensentinel\");\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n return dir;\n}\n\nexport function getPackageRoot(): string {\n // When running from source: import.meta.dirname is src/commands/\n // When installed globally: import.meta.dirname is dist/commands/ or dist/\n // Go up to find package.json\n let dir = import.meta.dirname || __dirname;\n for (let i = 0; i < 5; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n dir = join(dir, \"..\");\n }\n return process.cwd();\n}\n\nexport function getMigrationsDir(): string {\n return join(getPackageRoot(), \"drizzle\");\n}\n\n// ── Port and service checks ──────────────────────────────────────────────────\n\nexport async function checkPort(port: number): Promise<boolean> {\n try {\n const result = await exec(`ss -tlnp 2>/dev/null | grep :${port} || netstat -tlnp 2>/dev/null | grep :${port}`, { throws: false });\n return result.stdout.trim().length > 0;\n } catch {\n return false;\n }\n}\n\nexport async function checkPostgres(): Promise<{ installed: boolean; running: boolean; port: number }> {\n const installed = !!(await which(\"psql\"));\n let running = false;\n let port = 5432;\n\n if (installed) {\n const result = await exec(\"pg_isready -q 2>/dev/null\", { throws: false });\n running = result.exitCode === 0;\n }\n\n // Also check if running on non-standard port\n if (!running) {\n const port5445 = await checkPort(5445);\n if (port5445) {\n running = true;\n port = 5445;\n }\n }\n\n return { installed, running, port };\n}\n\nexport async function checkRedis(): Promise<{ installed: boolean; running: boolean; port: number }> {\n const installed = !!(await which(\"redis-cli\"));\n let running = false;\n let port = 6379;\n\n if (installed) {\n const result = await exec(\"redis-cli ping 2>/dev/null\", { throws: false });\n running = result.stdout.trim() === \"PONG\";\n }\n\n // Check alternate ports\n if (!running) {\n for (const p of [6384, 6380]) {\n const result = await exec(`redis-cli -p ${p} ping 2>/dev/null`, { throws: false });\n if (result.stdout.trim() === \"PONG\") {\n running = true;\n port = p;\n break;\n }\n }\n }\n\n return { installed, running, port };\n}\n\n// ── Banner ───────────────────────────────────────────────────────────────────\n\nexport function printBanner() {\n console.log(`\n${colors.cyan}${colors.bold}╔══════════════════════════════════════════╗\n║ OPENSENTINEL v3.0.0 ║\n║ Your Personal AI Assistant ║\n╚══════════════════════════════════════════╝${colors.reset}\n`);\n}\n\n// ── .env file loading ────────────────────────────────────────────────────────\n\nexport function loadEnvFile(): string | null {\n const candidates = [\n process.env.OPENSENTINEL_HOME && join(process.env.OPENSENTINEL_HOME, \".env\"),\n join(homedir(), \".opensentinel\", \".env\"),\n join(process.cwd(), \".env\"),\n ].filter(Boolean) as string[];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) {\n const content = readFileSync(candidate, \"utf-8\");\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n const value = trimmed.slice(eqIndex + 1).trim();\n // Don't override existing env vars\n if (!process.env[key]) {\n process.env[key] = value;\n }\n }\n return candidate;\n }\n }\n return null;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/integrations/email/index.ts"],"sourcesContent":["// IMAP Client - Reading emails\nexport {\n ImapClient,\n createImapClient,\n type EmailConfig,\n type EmailMessage,\n type EmailAddress,\n type EmailAttachment,\n type SearchOptions,\n type FolderInfo,\n} from \"./imap-client\";\n\n// SMTP Client - Sending emails\nexport {\n SmtpClient,\n createSmtpClient,\n type SmtpConfig,\n type EmailRecipient,\n type EmailAttachment as SmtpEmailAttachment,\n type SendEmailOptions,\n type ReplyOptions,\n type SendResult,\n} from \"./smtp-client\";\n\n// Email Parser - Content parsing and threading\nexport {\n parseEmail,\n parseAttachment,\n groupIntoThreads,\n cleanSubject,\n parseEmailBody,\n extractEmailAddresses,\n extractUrls,\n extractPhoneNumbers,\n getEmailSummary,\n calculateEmailSize,\n matchesFilter,\n type ParsedEmail,\n type ThreadInfo,\n type ParsedAttachment,\n type EmailMetadata,\n type EmailThread,\n type QuotedSection,\n type EmailBodyParts,\n} from \"./email-parser\";\n\n// Inbox Summarizer - AI-powered analysis\nexport {\n categorizeEmail,\n extractActionItems,\n summarizeThread,\n summarizeInbox,\n generateDailyDigest,\n suggestReplies,\n analyzeSentiment,\n type InboxSummary,\n type CategorySummary,\n type UrgentItem,\n type ActionItem,\n type EmailCategorization,\n type ThreadSummary,\n} from \"./inbox-summarizer\";\n\n/**\n * Email Integration for OpenSentinel\n *\n * This module provides comprehensive email functionality:\n *\n * ## Reading Emails (IMAP)\n * ```typescript\n * import { createImapClient } from './integrations/email';\n *\n * const imap = createImapClient('gmail', {\n * user: 'your@gmail.com',\n * password: 'your-app-password'\n * });\n *\n * await imap.connect();\n * const emails = await imap.fetchEmails('INBOX', { limit: 20 });\n * const unread = await imap.getUnreadCount();\n * await imap.disconnect();\n * ```\n *\n * ## Sending Emails (SMTP)\n * ```typescript\n * import { createSmtpClient } from './integrations/email';\n *\n * const smtp = createSmtpClient('gmail', {\n * user: 'your@gmail.com',\n * password: 'your-app-password'\n * });\n *\n * await smtp.send({\n * to: 'recipient@example.com',\n * subject: 'Hello',\n * text: 'This is a test email'\n * });\n * ```\n *\n * ## Parsing Emails\n * ```typescript\n * import { parseEmail, groupIntoThreads } from './integrations/email';\n *\n * const parsed = parseEmail(rawEmail);\n * const threads = groupIntoThreads(emails);\n * ```\n *\n * ## AI-Powered Features\n * ```typescript\n * import { summarizeInbox, extractActionItems } from './integrations/email';\n *\n * const summary = await summarizeInbox(emails);\n * const actions = await extractActionItems(email);\n * ```\n */\n\n// Convenience class that combines IMAP and SMTP\nexport class EmailClient {\n private imapClient: InstanceType<typeof import(\"./imap-client\").ImapClient>;\n private smtpClient: InstanceType<typeof import(\"./smtp-client\").SmtpClient>;\n\n constructor(config: {\n imap: import(\"./imap-client\").EmailConfig;\n smtp: import(\"./smtp-client\").SmtpConfig;\n }) {\n const { ImapClient } = require(\"./imap-client\");\n const { SmtpClient } = require(\"./smtp-client\");\n\n this.imapClient = new ImapClient(config.imap);\n this.smtpClient = new SmtpClient(config.smtp);\n }\n\n /**\n * Connect to the email server\n */\n async connect(): Promise<void> {\n await this.imapClient.connect();\n await this.smtpClient.verify();\n }\n\n /**\n * Disconnect from the email server\n */\n async disconnect(): Promise<void> {\n await this.imapClient.disconnect();\n await this.smtpClient.close();\n }\n\n /**\n * Get the IMAP client for reading emails\n */\n get imap() {\n return this.imapClient;\n }\n\n /**\n * Get the SMTP client for sending emails\n */\n get smtp() {\n return this.smtpClient;\n }\n\n /**\n * Fetch recent emails\n */\n async fetchRecent(limit: number = 20): Promise<import(\"./imap-client\").EmailMessage[]> {\n return this.imapClient.fetchEmails(\"INBOX\", { limit });\n }\n\n /**\n * Get unread count\n */\n async getUnreadCount(): Promise<number> {\n return this.imapClient.getUnreadCount();\n }\n\n /**\n * Send a simple text email\n */\n async sendText(\n to: string | string[],\n subject: string,\n text: string\n ): Promise<import(\"./smtp-client\").SendResult> {\n return this.smtpClient.sendText(to, subject, text);\n }\n\n /**\n * Send an HTML email\n */\n async sendHtml(\n to: string | string[],\n subject: string,\n html: string,\n text?: string\n ): Promise<import(\"./smtp-client\").SendResult> {\n return this.smtpClient.sendHtml(to, subject, html, text);\n }\n\n /**\n * Reply to an email\n */\n async reply(\n originalEmail: import(\"./imap-client\").EmailMessage,\n options: import(\"./smtp-client\").ReplyOptions\n ): Promise<import(\"./smtp-client\").SendResult> {\n return this.smtpClient.reply(originalEmail, options);\n }\n\n /**\n * Search for emails\n */\n async search(\n options: import(\"./imap-client\").SearchOptions\n ): Promise<import(\"./imap-client\").EmailMessage[]> {\n return this.imapClient.searchEmails(options);\n }\n\n /**\n * Get inbox summary using AI\n */\n async getInboxSummary(): Promise<import(\"./inbox-summarizer\").InboxSummary> {\n const { summarizeInbox } = await import(\"./inbox-summarizer\");\n const emails = await this.fetchRecent(100);\n return summarizeInbox(emails);\n }\n\n /**\n * Get action items from recent emails\n */\n async getActionItems(): Promise<import(\"./inbox-summarizer\").ActionItem[]> {\n const { extractActionItems, categorizeEmail } = await import(\"./inbox-summarizer\");\n const emails = await this.fetchRecent(50);\n\n const allActions: import(\"./inbox-summarizer\").ActionItem[] = [];\n\n for (const email of emails) {\n const category = await categorizeEmail(email);\n if (category.category === \"action_required\" || category.category === \"urgent\") {\n const actions = await extractActionItems(email);\n allActions.push(...actions);\n }\n }\n\n return allActions;\n }\n\n /**\n * Generate daily digest\n */\n async generateDigest(): Promise<string> {\n const { generateDailyDigest } = await import(\"./inbox-summarizer\");\n const emails = await this.fetchRecent(100);\n return generateDailyDigest(emails);\n }\n}\n\n/**\n * Create an email client with common provider presets\n */\nexport function createEmailClient(\n provider: \"gmail\" | \"outlook\" | \"yahoo\" | \"custom\",\n credentials: { user: string; password: string },\n customConfig?: {\n imap?: Partial<import(\"./imap-client\").EmailConfig>;\n smtp?: Partial<import(\"./smtp-client\").SmtpConfig>;\n }\n): EmailClient {\n const configs: Record<string, { imap: import(\"./imap-client\").EmailConfig; smtp: import(\"./smtp-client\").SmtpConfig }> = {\n gmail: {\n imap: {\n host: \"imap.gmail.com\",\n port: 993,\n secure: true,\n user: credentials.user,\n password: credentials.password,\n },\n smtp: {\n host: \"smtp.gmail.com\",\n port: 465,\n secure: true,\n auth: { user: credentials.user, pass: credentials.password },\n },\n },\n outlook: {\n imap: {\n host: \"outlook.office365.com\",\n port: 993,\n secure: true,\n user: credentials.user,\n password: credentials.password,\n },\n smtp: {\n host: \"smtp-mail.outlook.com\",\n port: 587,\n secure: false,\n auth: { user: credentials.user, pass: credentials.password },\n },\n },\n yahoo: {\n imap: {\n host: \"imap.mail.yahoo.com\",\n port: 993,\n secure: true,\n user: credentials.user,\n password: credentials.password,\n },\n smtp: {\n host: \"smtp.mail.yahoo.com\",\n port: 465,\n secure: true,\n auth: { user: credentials.user, pass: credentials.password },\n },\n },\n custom: {\n imap: {\n host: customConfig?.imap?.host || \"localhost\",\n port: customConfig?.imap?.port || 993,\n secure: customConfig?.imap?.secure ?? true,\n user: credentials.user,\n password: credentials.password,\n ...customConfig?.imap,\n },\n smtp: {\n host: customConfig?.smtp?.host || \"localhost\",\n port: customConfig?.smtp?.port || 587,\n secure: customConfig?.smtp?.secure ?? false,\n auth: { user: credentials.user, pass: credentials.password },\n ...customConfig?.smtp,\n },\n },\n };\n\n return new EmailClient(configs[provider]);\n}\n\n// Import factory functions for default export\nimport { createImapClient as _createImapClient } from \"./imap-client\";\nimport { createSmtpClient as _createSmtpClient } from \"./smtp-client\";\n\nexport default {\n EmailClient,\n createEmailClient,\n createImapClient: _createImapClient,\n createSmtpClient: _createSmtpClient,\n};\n"],"mappings":"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","names":["ImapClient","SmtpClient","summarizeInbox","extractActionItems","categorizeEmail","generateDailyDigest"]}
@@ -1,14 +0,0 @@
1
- import {
2
- batchEnrich,
3
- enrichEntity
4
- } from "./chunk-A24GPVLY.js";
5
- import "./chunk-AR34B6XR.js";
6
- import "./chunk-S4NJJS5C.js";
7
- import "./chunk-PUNIMPMY.js";
8
- import "./chunk-NYVBXUGD.js";
9
- import "./chunk-UP2VWCW5.js";
10
- export {
11
- batchEnrich,
12
- enrichEntity
13
- };
14
- //# sourceMappingURL=enrichment-pipeline-CMUVBDC7.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/core/security/incident-response.ts"],"sourcesContent":["// SOC 2 Incident Response System\n// Manages security incident lifecycle: creation, investigation, containment, resolution\n\nimport { db } from \"../../db\";\nimport { securityIncidents, incidentTimeline, users } from \"../../db/schema\";\nimport { eq, or, desc } from \"drizzle-orm\";\nimport { logAudit } from \"./audit-logger\";\n\n// ---------------------------------------------------------------------------\n// Type aliases (matching the schema column types)\n// ---------------------------------------------------------------------------\n\ntype IncidentType =\n | \"brute_force\"\n | \"unauthorized_access\"\n | \"data_breach\"\n | \"suspicious_activity\"\n | \"system_compromise\"\n | \"policy_violation\";\n\ntype IncidentSeverity = \"low\" | \"medium\" | \"high\" | \"critical\";\n\ntype IncidentStatus =\n | \"open\"\n | \"investigating\"\n | \"contained\"\n | \"resolved\"\n | \"closed\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a unique incident number in the format INC-YYYYMMDD-XXXX\n * where XXXX is 4 random uppercase alphanumeric characters.\n */\nexport function generateIncidentNumber(): string {\n const now = new Date();\n const yyyy = now.getFullYear().toString();\n const mm = (now.getMonth() + 1).toString().padStart(2, \"0\");\n const dd = now.getDate().toString().padStart(2, \"0\");\n const chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n let suffix = \"\";\n for (let i = 0; i < 4; i++) {\n suffix += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return `INC-${yyyy}${mm}${dd}-${suffix}`;\n}\n\n/**\n * Map an anomaly type string (from AuthMonitor) to the corresponding\n * incident type and severity.\n */\nexport function mapAnomalyToIncident(anomalyType: string): {\n type: IncidentType;\n severity: IncidentSeverity;\n} {\n switch (anomalyType) {\n case \"brute_force\":\n return { type: \"brute_force\", severity: \"critical\" };\n case \"impossible_travel\":\n return { type: \"unauthorized_access\", severity: \"high\" };\n case \"new_device\":\n return { type: \"suspicious_activity\", severity: \"medium\" };\n case \"new_ip\":\n return { type: \"suspicious_activity\", severity: \"low\" };\n case \"rapid_session_switching\":\n return { type: \"suspicious_activity\", severity: \"medium\" };\n case \"unusual_time\":\n return { type: \"suspicious_activity\", severity: \"low\" };\n default:\n return { type: \"suspicious_activity\", severity: \"medium\" };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Core CRUD\n// ---------------------------------------------------------------------------\n\n/**\n * Create a new security incident, add the initial \"created\" timeline event,\n * and emit an audit log entry.\n */\nexport async function createIncident(params: {\n title: string;\n description: string;\n type: IncidentType;\n severity: IncidentSeverity;\n userId?: string;\n source: string;\n sourceData?: unknown;\n assignedTo?: string;\n}) {\n const incidentNumber = generateIncidentNumber();\n\n const [incident] = await db\n .insert(securityIncidents)\n .values({\n incidentNumber,\n title: params.title,\n description: params.description,\n type: params.type,\n severity: params.severity,\n status: \"open\",\n userId: params.userId,\n assignedTo: params.assignedTo,\n source: params.source,\n sourceData: params.sourceData as any,\n })\n .returning();\n\n // Add \"created\" timeline event\n await addTimelineEvent({\n incidentId: incident.id,\n eventType: \"created\",\n description: `Incident ${incidentNumber} created: ${params.title}`,\n performedBy: params.userId,\n metadata: {\n type: params.type,\n severity: params.severity,\n source: params.source,\n },\n });\n\n // Audit log\n try {\n await logAudit({\n userId: params.userId,\n action: \"tool_use\" as any,\n resource: \"tool\" as any,\n resourceId: incident.id,\n details: {\n event: \"incident_created\",\n incidentNumber,\n type: params.type,\n severity: params.severity,\n source: params.source,\n },\n });\n } catch {\n // Audit logging should not block incident creation\n }\n\n return incident;\n}\n\n/**\n * Create an incident automatically from an AuthMonitor anomaly.\n */\nexport async function createIncidentFromAnomaly(\n userId: string,\n anomaly: {\n type: string;\n level: string;\n message: string;\n details?: unknown;\n timestamp: Date;\n }\n) {\n const { type, severity } = mapAnomalyToIncident(anomaly.type);\n\n return createIncident({\n title: `[Auto] ${anomaly.message}`,\n description: `Automatically created from ${anomaly.type} anomaly detected at ${anomaly.timestamp.toISOString()}.\\n\\nLevel: ${anomaly.level}\\nMessage: ${anomaly.message}`,\n type,\n severity,\n userId,\n source: \"auth_monitor\",\n sourceData: {\n anomalyType: anomaly.type,\n anomalyLevel: anomaly.level,\n details: anomaly.details,\n detectedAt: anomaly.timestamp.toISOString(),\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Status management\n// ---------------------------------------------------------------------------\n\n/**\n * Transition an incident to a new status, updating the appropriate timestamp\n * field and recording a timeline event.\n */\nexport async function updateIncidentStatus(\n incidentId: string,\n newStatus: IncidentStatus,\n performedBy?: string,\n notes?: string\n) {\n const updateData: Record<string, unknown> = {\n status: newStatus,\n updatedAt: new Date(),\n };\n\n switch (newStatus) {\n case \"investigating\":\n updateData.investigatedAt = new Date();\n break;\n case \"contained\":\n updateData.containedAt = new Date();\n break;\n case \"resolved\":\n updateData.resolvedAt = new Date();\n if (notes) {\n updateData.resolutionNotes = notes;\n }\n break;\n case \"closed\":\n updateData.closedAt = new Date();\n break;\n }\n\n const [updated] = await db\n .update(securityIncidents)\n .set(updateData)\n .where(eq(securityIncidents.id, incidentId))\n .returning();\n\n // Timeline event\n await addTimelineEvent({\n incidentId,\n eventType: \"status_change\",\n description: `Status changed to ${newStatus}${notes ? `: ${notes}` : \"\"}`,\n performedBy,\n metadata: { newStatus, notes },\n });\n\n return updated;\n}\n\n/**\n * Assign an incident to a user and record the assignment in the timeline.\n */\nexport async function assignIncident(\n incidentId: string,\n assignedTo: string,\n performedBy?: string\n) {\n const [updated] = await db\n .update(securityIncidents)\n .set({ assignedTo, updatedAt: new Date() })\n .where(eq(securityIncidents.id, incidentId))\n .returning();\n\n await addTimelineEvent({\n incidentId,\n eventType: \"assignment\",\n description: `Incident assigned to ${assignedTo}`,\n performedBy,\n metadata: { assignedTo },\n });\n\n return updated;\n}\n\n/**\n * Add a timeline event to an incident.\n */\nexport async function addTimelineEvent(params: {\n incidentId: string;\n eventType: string;\n description: string;\n performedBy?: string;\n metadata?: unknown;\n}) {\n const [event] = await db\n .insert(incidentTimeline)\n .values({\n incidentId: params.incidentId,\n eventType: params.eventType as any,\n description: params.description,\n performedBy: params.performedBy,\n metadata: params.metadata as any,\n })\n .returning();\n\n return event;\n}\n\n/**\n * Convenience wrapper to resolve an incident with notes.\n */\nexport async function resolveIncident(\n incidentId: string,\n notes: string,\n performedBy?: string\n) {\n return updateIncidentStatus(incidentId, \"resolved\", performedBy, notes);\n}\n\n// ---------------------------------------------------------------------------\n// Queries\n// ---------------------------------------------------------------------------\n\n/**\n * Retrieve open incidents (status = open | investigating | contained),\n * optionally filtered by severity, type, userId, and limited.\n */\nexport async function getOpenIncidents(\n options: {\n severity?: IncidentSeverity;\n type?: IncidentType;\n userId?: string;\n limit?: number;\n } = {}\n) {\n const { severity, type, userId, limit = 50 } = options;\n\n let results = await db\n .select()\n .from(securityIncidents)\n .where(\n or(\n eq(securityIncidents.status, \"open\"),\n eq(securityIncidents.status, \"investigating\"),\n eq(securityIncidents.status, \"contained\")\n )\n )\n .orderBy(desc(securityIncidents.createdAt))\n .limit(limit);\n\n // Post-filter by optional criteria\n if (severity) {\n results = results.filter((inc) => inc.severity === severity);\n }\n if (type) {\n results = results.filter((inc) => inc.type === type);\n }\n if (userId) {\n results = results.filter((inc) => inc.userId === userId);\n }\n\n return results;\n}\n\n/**\n * Retrieve the full timeline for a specific incident, ordered chronologically.\n */\nexport async function getIncidentTimeline(incidentId: string) {\n return db\n .select()\n .from(incidentTimeline)\n .where(eq(incidentTimeline.incidentId, incidentId))\n .orderBy(desc(incidentTimeline.createdAt));\n}\n\n// ---------------------------------------------------------------------------\n// Reporting\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a structured incident report with a markdown-formatted summary.\n */\nexport async function generateIncidentReport(incidentId: string) {\n const [incident] = await db\n .select()\n .from(securityIncidents)\n .where(eq(securityIncidents.id, incidentId))\n .limit(1);\n\n if (!incident) {\n throw new Error(`Incident not found: ${incidentId}`);\n }\n\n const timeline = await getIncidentTimeline(incidentId);\n\n const timelineEntries = timeline\n .map(\n (e) =>\n `- **${e.createdAt.toISOString()}** [${e.eventType}] ${e.description}`\n )\n .join(\"\\n\");\n\n const summary = `# Incident Report: ${incident.incidentNumber}\n\n## Overview\n- **Title**: ${incident.title}\n- **Type**: ${incident.type}\n- **Severity**: ${incident.severity}\n- **Status**: ${incident.status}\n- **Source**: ${incident.source}\n- **Created**: ${incident.createdAt.toISOString()}\n- **Updated**: ${incident.updatedAt.toISOString()}\n\n## Description\n${incident.description}\n\n## Impact Assessment\n${incident.impactAssessment ?? \"Not yet assessed.\"}\n\n## Resolution\n${incident.resolutionNotes ?? \"Not yet resolved.\"}\n\n## Timeline\n${timelineEntries || \"No timeline events recorded.\"}\n`;\n\n return { incident, timeline, summary };\n}\n\n// ---------------------------------------------------------------------------\n// Integration with AuthMonitor\n// ---------------------------------------------------------------------------\n\n/**\n * Wire the incident response system into an AuthMonitor instance so that\n * warning-level and critical-level anomalies automatically create incidents.\n */\nexport function wireIncidentResponseToAuthMonitor(authMonitor: {\n onAlert: (\n cb: (userId: string, anomaly: any) => void | Promise<void>\n ) => void;\n}) {\n authMonitor.onAlert(async (userId: string, anomaly: any) => {\n // Only create incidents for warning and critical anomalies\n if (anomaly.level === \"warning\" || anomaly.level === \"critical\") {\n try {\n await createIncidentFromAnomaly(userId, anomaly);\n } catch {\n // Incident creation failure should not crash the auth flow\n }\n }\n });\n}\n"],"mappings":"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","names":[]}