@a-company/paradigm 5.10.0 → 5.21.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 (409) hide show
  1. package/dist/accept-orchestration-IUAWQZUN.js +18 -0
  2. package/dist/add-P76GEMGF.js +8 -0
  3. package/dist/agent-UUTYOFTH.js +33 -0
  4. package/dist/agent-loader-EPXURMO7.js +2 -0
  5. package/dist/agent-loader-PYGPX6D2.js +2 -0
  6. package/dist/agent-state-KSQ3S7OB.js +2 -0
  7. package/dist/agents-suggest-HYTFMQD3.js +10 -0
  8. package/dist/aggregate-W66DM3GA.js +10 -0
  9. package/dist/ambient-HYZR42NX.js +35 -0
  10. package/dist/assess-UFPYEJKP.js +9 -0
  11. package/dist/auto-RHJXOZFL.js +14 -0
  12. package/dist/beacon-5QVYV5DF.js +13 -0
  13. package/dist/calibration-OLJYB5HN.js +7 -0
  14. package/dist/check-THVGY4R5.js +14 -0
  15. package/dist/chunk-22ISTMKI.js +31 -0
  16. package/dist/chunk-2QO33NYK.js +3 -0
  17. package/dist/chunk-33LKBMVK.js +134 -0
  18. package/dist/chunk-4QADCWPU.js +7 -0
  19. package/dist/chunk-4TXOVRWD.js +3 -0
  20. package/dist/chunk-4UJ4NIEQ.js +4 -0
  21. package/dist/chunk-4ZGGWZ32.js +3 -0
  22. package/dist/chunk-5TAVYPOV.js +2 -0
  23. package/dist/chunk-6EX37L4Q.js +8 -0
  24. package/dist/chunk-AD5TAD2A.js +5 -0
  25. package/dist/chunk-AGVAHVUA.js +2 -0
  26. package/dist/chunk-AO7ZSRME.js +13 -0
  27. package/dist/chunk-BFD3GFRK.js +2 -0
  28. package/dist/chunk-D34YFK4M.js +6 -0
  29. package/dist/chunk-DVZWCXB6.js +2 -0
  30. package/dist/chunk-EKZDFEJW.js +2 -0
  31. package/dist/chunk-ET5XJTSX.js +2 -0
  32. package/dist/chunk-FYDRENK7.js +3 -0
  33. package/dist/chunk-HMQ5BHP2.js +743 -0
  34. package/dist/chunk-HXKWL3VK.js +29 -0
  35. package/dist/chunk-IZSBGW6E.js +2 -0
  36. package/dist/chunk-J32OPJEX.js +2 -0
  37. package/dist/chunk-JBDMCRPP.js +7 -0
  38. package/dist/chunk-JIXHEBGK.js +7 -0
  39. package/dist/chunk-JNSJVCTU.js +2 -0
  40. package/dist/chunk-JQKKVAAN.js +2 -0
  41. package/dist/chunk-KLBH26PA.js +429 -0
  42. package/dist/chunk-L6K5HNDL.js +24 -0
  43. package/dist/chunk-LKAT7IAK.js +2 -0
  44. package/dist/chunk-M4UMM6DC.js +5 -0
  45. package/dist/chunk-NKYNHSA5.js +424 -0
  46. package/dist/chunk-NW6OKHE6.js +5 -0
  47. package/dist/chunk-NXRVR37G.js +60 -0
  48. package/dist/chunk-ODVKPZZ4.js +2 -0
  49. package/dist/chunk-PUBB7LIT.js +5 -0
  50. package/dist/chunk-Q2J542ST.js +2 -0
  51. package/dist/chunk-QGZRM6ZB.js +2 -0
  52. package/dist/chunk-QNZEG7IT.js +13 -0
  53. package/dist/chunk-QT2LKB3P.js +7 -0
  54. package/dist/chunk-RVRARWSY.js +9 -0
  55. package/dist/chunk-T6IDXUUA.js +2 -0
  56. package/dist/chunk-TYWB5IQJ.js +3 -0
  57. package/dist/chunk-UIKLE3WD.js +2 -0
  58. package/dist/chunk-V7K6CQVX.js +111 -0
  59. package/dist/chunk-VCKKJDLP.js +8 -0
  60. package/dist/chunk-VG7FN2TU.js +4 -0
  61. package/dist/chunk-W5IWDW4Y.js +16 -0
  62. package/dist/chunk-W7C6FFMO.js +8 -0
  63. package/dist/chunk-WESTEMIM.js +10 -0
  64. package/dist/chunk-WR6D3SC6.js +5 -0
  65. package/dist/chunk-WS2N27RX.js +3 -0
  66. package/dist/chunk-XMAV5AG6.js +2 -0
  67. package/dist/chunk-XROULIQN.js +2 -0
  68. package/dist/chunk-XUFYOXOU.js +3 -0
  69. package/dist/chunk-Y4XFVDZC.js +3 -0
  70. package/dist/chunk-Y6KXTQBG.js +2 -0
  71. package/dist/{chunk-GTR2TBIJ.js → chunk-Z2UZUCY6.js} +237 -1047
  72. package/dist/chunk-Z34K6GY2.js +8 -0
  73. package/dist/claude-4LR3LJQZ.js +13 -0
  74. package/dist/claude-cli-UP6HGH7C.js +6 -0
  75. package/dist/claude-code-RLJ4GX77.js +11 -0
  76. package/dist/claude-code-teams-R37HJY3Y.js +29 -0
  77. package/dist/commands-LMUD5L6R.js +455 -0
  78. package/dist/compliance-GZ7UAOG3.js +6 -0
  79. package/dist/conductor-Y5IXELTL.js +4 -0
  80. package/dist/config-schema-HR7LDEQ6.js +2 -0
  81. package/dist/constellation-CG7C4WFE.js +13 -0
  82. package/dist/context-audit-RSSRX6XC.js +6 -0
  83. package/dist/cost-IDNVMAEV.js +10 -0
  84. package/dist/cost-PK4KIF7R.js +2 -0
  85. package/dist/cursor-cli-QKF7Z6M2.js +4 -0
  86. package/dist/cursorrules-U5O4G5T4.js +14 -0
  87. package/dist/decision-loader-2XPZE4EZ.js +2 -0
  88. package/dist/delete-P5VULXR4.js +14 -0
  89. package/dist/diff-RTFUKJHF.js +9 -0
  90. package/dist/discipline-H7LDI6NT.js +2 -0
  91. package/dist/dist-3ZCH25SG.js +2 -0
  92. package/dist/dist-KGRCLBJP-2QAPFYNF.js +39 -0
  93. package/dist/dist-R3RWD35F.js +2 -0
  94. package/dist/dist-VGFSP3XM.js +2 -0
  95. package/dist/dist-VXCZWVVJ.js +2 -0
  96. package/dist/dist-W3XCATBJ.js +2 -0
  97. package/dist/docs-EDQ2STFK.js +2 -0
  98. package/dist/docs-RXPN6CK7.js +12 -0
  99. package/dist/doctor-2T2QL6VM.js +2 -0
  100. package/dist/drift-ILZE5BFJ.js +13 -0
  101. package/dist/echo-UPTQUEDU.js +46 -0
  102. package/dist/edit-GUU3HBVW.js +9 -0
  103. package/dist/event-Y3VXC2RV.js +3 -0
  104. package/dist/explain-files-3GPZUETV.js +4 -0
  105. package/dist/export-CV5KCTPS.js +2 -0
  106. package/dist/flow-S3RQ4YPY.js +11 -0
  107. package/dist/global-C44FW4G2.js +13 -0
  108. package/dist/graduate-3BBSC27A.js +5 -0
  109. package/dist/graph-CNDE5TAT.js +2 -0
  110. package/dist/graph-server-COZR5C3Z.js +14 -0
  111. package/dist/habits-4J2KRYUL.js +42 -0
  112. package/dist/history-UW454SDP.js +12 -0
  113. package/dist/hooks-XH52VGOU.js +2 -0
  114. package/dist/index.js +15 -1039
  115. package/dist/init-24MAQJFM.js +2 -0
  116. package/dist/integrity-UYDOOJDP.js +7 -0
  117. package/dist/integrity-checker-DHGMZQDG.js +2 -0
  118. package/dist/journal-loader-GLH7XFTK.js +2 -0
  119. package/dist/lint-IGKE6UPS.js +26 -0
  120. package/dist/list-5IUGP3ZB.js +7 -0
  121. package/dist/list-YKIQNKGB.js +6 -0
  122. package/dist/lore-loader-RVQI5GXL.js +2 -0
  123. package/dist/lore-loader-XY5MZRR2.js +2 -0
  124. package/dist/lore-server-FC2GMDLT.js +14 -0
  125. package/dist/manual-RXSPSFLL.js +20 -0
  126. package/dist/mcp.js +93 -20484
  127. package/dist/migrate-X5OMAFAQ.js +59 -0
  128. package/dist/migrate-assessments-GEI5WMI2.js +4 -0
  129. package/dist/model-discovery-HMB3YI4L.js +2 -0
  130. package/dist/nomination-engine-XF7TWPAP.js +2 -0
  131. package/dist/notebook-PE3JSYZI.js +11 -0
  132. package/dist/notebook-loader-CENTDDUJ.js +2 -0
  133. package/dist/orchestrate-35HBQ3O3.js +8 -0
  134. package/dist/peers-P2KXU7ZK.js +5 -0
  135. package/dist/persona-STQWZH5P.js +29 -0
  136. package/dist/pipeline-MZUITRVN.js +4 -0
  137. package/dist/platform-server-2KXHGHFV.js +25 -0
  138. package/dist/plugin-update-checker-M7PW434O.js +2 -0
  139. package/dist/portal-check-3JVNLOEP.js +8 -0
  140. package/dist/portal-compliance-2UG4VKWH.js +2 -0
  141. package/dist/probe-5L5BQDGE.js +6 -0
  142. package/dist/project-type-SURTOIG7.js +2 -0
  143. package/dist/promote-NJQDZBZA.js +8 -0
  144. package/dist/providers-4PXMWA7V.js +8 -0
  145. package/dist/quiz-FE5UGAY2.js +10 -0
  146. package/dist/record-YXPB34MY.js +6 -0
  147. package/dist/reindex-PGDQSM42.js +2 -0
  148. package/dist/remember-MJRNTXYS.js +14 -0
  149. package/dist/retag-N5XF3KXP.js +6 -0
  150. package/dist/review-6UAH6V3R.js +11 -0
  151. package/dist/review-77QI6VOC.js +6 -0
  152. package/dist/ripple-ZGDITCGB.js +10 -0
  153. package/dist/roster-FLRZ5J42.js +2 -0
  154. package/dist/sentinel-HYAZ3CO5.js +19 -0
  155. package/dist/sentinel-bridge-VR357PKL.js +2 -0
  156. package/dist/sentinel-mcp.js +38 -3808
  157. package/dist/sentinel.js +1 -34
  158. package/dist/serve-JE6UF5P2.js +8 -0
  159. package/dist/serve-L52ZUTU6.js +10 -0
  160. package/dist/serve-OY6XYL7F.js +12 -0
  161. package/dist/server-2MNROHF6.js +7 -0
  162. package/dist/server-4YNUIK4W.js +8 -0
  163. package/dist/session-tracker-SKOMBDOW.js +2 -0
  164. package/dist/session-work-log-3MNUDEZ6.js +2 -0
  165. package/dist/session-work-log-J2H5OZBR.js +2 -0
  166. package/dist/setup-3F5IK7MO.js +31 -0
  167. package/dist/setup-KPIMRZ4Q.js +2 -0
  168. package/dist/shift-6GCNH666.js +11 -0
  169. package/dist/show-BOAVWZPZ.js +7 -0
  170. package/dist/show-PJ5LFLIL.js +5 -0
  171. package/dist/snapshot-L2G56RPL.js +8 -0
  172. package/dist/spawn-UH5RENSE.js +12 -0
  173. package/dist/status-77M3SDIF.js +8 -0
  174. package/dist/status-A37ECYNJ.js +6 -0
  175. package/dist/summary-ZJLQ6KHB.js +7 -0
  176. package/dist/sweep-HU74OPVW.js +17 -0
  177. package/dist/switch-CTW4PDGI.js +17 -0
  178. package/dist/symphony-3QMBGCZY.js +2 -0
  179. package/dist/symphony-QI63XL62.js +53 -0
  180. package/dist/symphony-loader-XACVV2E3.js +2 -0
  181. package/dist/symphony-peers-U4KHMKGI.js +2 -0
  182. package/dist/symphony-peers-X5NGWXFP.js +2 -0
  183. package/dist/symphony-relay-5GY5JIPT.js +3 -0
  184. package/dist/sync-QRDSFETO.js +2 -0
  185. package/dist/sync-llms-HL5PPW3M.js +15 -0
  186. package/dist/task-loader-NZFDTUQ5.js +2 -0
  187. package/dist/team-WGERKGNP.js +2 -0
  188. package/dist/test-BQJMS4Y2.js +111 -0
  189. package/dist/thread-HFXK65D4.js +41 -0
  190. package/dist/timeline-K3ZFKJ3R.js +6 -0
  191. package/dist/triage-FCWOZASE.js +18 -0
  192. package/dist/tutorial-UC6YQMNN.js +305 -0
  193. package/dist/university-content/courses/.purpose +74 -5
  194. package/dist/university-content/courses/para-701.json +807 -0
  195. package/dist/university-content/plsat/.purpose +3 -2
  196. package/dist/university-ui/assets/{index-BjewBB6s.js → index-CGFJczb1.js} +2 -2
  197. package/dist/university-ui/assets/{index-BjewBB6s.js.map → index-CGFJczb1.js.map} +1 -1
  198. package/dist/university-ui/index.html +1 -1
  199. package/dist/upgrade-B4IOLZYK.js +53 -0
  200. package/dist/validate-C6SMKGYD.js +9 -0
  201. package/dist/validate-LSCDOLBO.js +13 -0
  202. package/dist/validate-VZXTJHGO.js +6 -0
  203. package/dist/watch-LRM5XD46.js +8 -0
  204. package/dist/watch-PZCCUP6K.js +9 -0
  205. package/dist/wisdom-XZ3QKPNP.js +7 -0
  206. package/dist/work-log-loader-DL5GZ2BQ.js +2 -0
  207. package/dist/workspace-2ODL5WLY.js +2 -0
  208. package/package.json +1 -1
  209. package/platform-ui/dist/assets/AmbientSection-DqQ2mfCO.js +1 -0
  210. package/platform-ui/dist/assets/{CanvasSection-DwPTRdIN.js → CanvasSection-DLW0s-Bu.js} +1 -1
  211. package/platform-ui/dist/assets/{DocsSection-BJc_ws4I.js → DocsSection-BQ9Hi51g.js} +1 -1
  212. package/platform-ui/dist/assets/{GitSection-DhqBo1xc.js → GitSection-QQeUX6o3.js} +1 -1
  213. package/platform-ui/dist/assets/{GraphSection-D9fhVnZ0.js → GraphSection-0c9C-w7K.js} +2 -2
  214. package/platform-ui/dist/assets/{GraphSection-BlgXTl53.css → GraphSection-Bbs2a8sC.css} +1 -1
  215. package/platform-ui/dist/assets/LoreSection--t56kCj2.js +1 -0
  216. package/platform-ui/dist/assets/LoreSection-qnmm3o4y.css +1 -0
  217. package/platform-ui/dist/assets/SentinelSection-C4OoME9U.js +1 -0
  218. package/platform-ui/dist/assets/{SymphonySection-BRoBaUSS.js → SymphonySection-B-rvsLxq.js} +1 -1
  219. package/platform-ui/dist/assets/TeamSection-CBFmNEEo.js +1 -0
  220. package/platform-ui/dist/assets/index-Bxp0TVaf.css +1 -0
  221. package/platform-ui/dist/assets/index-DPpOdAtC.js +57 -0
  222. package/platform-ui/dist/index.html +2 -2
  223. package/dist/accept-orchestration-UQLM7PTQ.js +0 -189
  224. package/dist/add-FZRKEGH4.js +0 -81
  225. package/dist/agent-WERIO2XV.js +0 -523
  226. package/dist/agent-loader-TFIANSF4.js +0 -44
  227. package/dist/agent-state-S5DAWPTF.js +0 -24
  228. package/dist/agents-suggest-DNSYJ6IA.js +0 -83
  229. package/dist/aggregate-H57K7PNV.js +0 -88
  230. package/dist/assess-4WVXZLZQ.js +0 -68
  231. package/dist/auto-QFS5NHQU.js +0 -504
  232. package/dist/beacon-KXZXYQHX.js +0 -251
  233. package/dist/calibration-V46G7JTY.js +0 -135
  234. package/dist/check-OWAIWV23.js +0 -175
  235. package/dist/chunk-2IO7JAG2.js +0 -148
  236. package/dist/chunk-2T6BTYBN.js +0 -712
  237. package/dist/chunk-36TKPM5Z.js +0 -400
  238. package/dist/chunk-45MUDW6E.js +0 -804
  239. package/dist/chunk-4BLYIB7J.js +0 -5701
  240. package/dist/chunk-4L3UTYQX.js +0 -677
  241. package/dist/chunk-4NCFWYGG.js +0 -110
  242. package/dist/chunk-54LTTQBH.js +0 -138
  243. package/dist/chunk-5EWAQHFY.js +0 -269
  244. package/dist/chunk-5JGJACDU.js +0 -37
  245. package/dist/chunk-5OUOLN6M.js +0 -659
  246. package/dist/chunk-5VKJBNJL.js +0 -444
  247. package/dist/chunk-6N3JTACN.js +0 -2260
  248. package/dist/chunk-6QC3YGB6.js +0 -114
  249. package/dist/chunk-7N7GSU6K.js +0 -34
  250. package/dist/chunk-ABVQGRF7.js +0 -268
  251. package/dist/chunk-CL7JSK52.js +0 -129
  252. package/dist/chunk-CSD7IHSN.js +0 -152
  253. package/dist/chunk-EDOAWN7J.js +0 -717
  254. package/dist/chunk-EKGMAM62.js +0 -525
  255. package/dist/chunk-EZ3GOCYC.js +0 -132
  256. package/dist/chunk-F3BCHPYT.js +0 -143
  257. package/dist/chunk-FKJUBQU3.js +0 -3081
  258. package/dist/chunk-GT5QGC2H.js +0 -253
  259. package/dist/chunk-GZDFVP2N.js +0 -540
  260. package/dist/chunk-IRKUEJVW.js +0 -405
  261. package/dist/chunk-J2JEQRT3.js +0 -164
  262. package/dist/chunk-JASGXLK3.js +0 -679
  263. package/dist/chunk-KVDYJLTC.js +0 -121
  264. package/dist/chunk-L27I3CPZ.js +0 -357
  265. package/dist/chunk-LHLIAYQ3.js +0 -185
  266. package/dist/chunk-MCMOGQMU.js +0 -145
  267. package/dist/chunk-NQKQG45G.js +0 -688
  268. package/dist/chunk-PBHIFAL4.js +0 -259
  269. package/dist/chunk-PDX44BCA.js +0 -11
  270. package/dist/chunk-PMXRGPRQ.js +0 -305
  271. package/dist/chunk-RAB5IKPR.js +0 -487
  272. package/dist/chunk-RJE5G7WO.js +0 -590
  273. package/dist/chunk-RTHA3XRE.js +0 -880
  274. package/dist/chunk-S2HO5MLR.js +0 -621
  275. package/dist/chunk-S3ORKP3V.js +0 -716
  276. package/dist/chunk-TAIJOFOE.js +0 -124
  277. package/dist/chunk-TXESEO7Y.js +0 -245
  278. package/dist/chunk-UPLDI7CN.js +0 -1334
  279. package/dist/chunk-VL67H5IC.js +0 -506
  280. package/dist/chunk-VPPK3SY4.js +0 -1136
  281. package/dist/chunk-YMDLDELF.js +0 -314
  282. package/dist/chunk-YO6DVTL7.js +0 -99
  283. package/dist/chunk-YRZ5RPEB.js +0 -1561
  284. package/dist/chunk-ZDHLG5VP.js +0 -5676
  285. package/dist/chunk-ZGUAAVMA.js +0 -756
  286. package/dist/chunk-ZSYVKSY6.js +0 -2602
  287. package/dist/claude-FRRWJSTJ.js +0 -362
  288. package/dist/claude-cli-XJLK2X4L.js +0 -276
  289. package/dist/claude-code-HTBA4XRB.js +0 -126
  290. package/dist/claude-code-teams-T4SP24MD.js +0 -199
  291. package/dist/commands-5N4ILTPH.js +0 -5859
  292. package/dist/conductor-CQVGTEQN.js +0 -161
  293. package/dist/config-schema-EA4XALGG.js +0 -154
  294. package/dist/constellation-A26CCGQS.js +0 -225
  295. package/dist/context-audit-RLO3ETRP.js +0 -682
  296. package/dist/cost-BGM32XJU.js +0 -93
  297. package/dist/cost-VI46A4XL.js +0 -174
  298. package/dist/cursor-cli-JVEZGHWQ.js +0 -269
  299. package/dist/cursorrules-HLIKJJZT.js +0 -84
  300. package/dist/decision-loader-WWCLIQPJ.js +0 -20
  301. package/dist/delete-KBRPQLPC.js +0 -56
  302. package/dist/diff-D4X53HAC.js +0 -126
  303. package/dist/discipline-FA4OZXIS.js +0 -24
  304. package/dist/dist-34NA5RS5.js +0 -74
  305. package/dist/dist-5QE2BB2B-5S3T6Y3T.js +0 -6919
  306. package/dist/dist-77JDTVAY.js +0 -62
  307. package/dist/dist-OGTSAZ55.js +0 -1358
  308. package/dist/dist-QK4SQAK7.js +0 -64
  309. package/dist/dist-TA6LSC2Q.js +0 -20
  310. package/dist/docs-PBZB7LYP.js +0 -89
  311. package/dist/docs-QIYKO3BR.js +0 -155
  312. package/dist/doctor-ULBOHEIC.js +0 -11
  313. package/dist/drift-R5NRKFHI.js +0 -251
  314. package/dist/echo-O2LY7CC2.js +0 -248
  315. package/dist/edit-R2HNLMOG.js +0 -63
  316. package/dist/event-25OJKDCE.js +0 -31
  317. package/dist/export-IWVL7XLF.js +0 -38
  318. package/dist/flow-CRRVV3O3.js +0 -185
  319. package/dist/global-3NG5JXUB.js +0 -136
  320. package/dist/graduate-USAWGBJM.js +0 -160
  321. package/dist/graph-VHUMAAS6.js +0 -12
  322. package/dist/graph-server-YL22VBBN.js +0 -116
  323. package/dist/habits-OL5NGPXO.js +0 -1405
  324. package/dist/history-WOWC573W.js +0 -277
  325. package/dist/hooks-HFWSCGPV.js +0 -12
  326. package/dist/integrity-IHO4FZTS.js +0 -194
  327. package/dist/integrity-checker-PSKJA5SB.js +0 -12
  328. package/dist/journal-loader-5EYSBFFY.js +0 -18
  329. package/dist/lint-K6CJGGPH.js +0 -456
  330. package/dist/list-4YK7QKFF.js +0 -57
  331. package/dist/list-ENR7Q4CR.js +0 -56
  332. package/dist/lore-loader-7NO6N6FT.js +0 -26
  333. package/dist/lore-server-UNJY5KC3.js +0 -118
  334. package/dist/manual-G6FISID5.js +0 -204
  335. package/dist/migrate-LS45DNEV.js +0 -889
  336. package/dist/migrate-assessments-RGH4O6IX.js +0 -97
  337. package/dist/model-discovery-D2H3VBGC.js +0 -8
  338. package/dist/nomination-engine-RV5CNO5B.js +0 -42
  339. package/dist/notebook-YWIYGEHV.js +0 -155
  340. package/dist/orchestrate-JLILBBJE.js +0 -324
  341. package/dist/peers-DEOUIZM6.js +0 -82
  342. package/dist/persona-UHAHIVST.js +0 -390
  343. package/dist/pipeline-L4HCSBGN.js +0 -263
  344. package/dist/platform-server-H5YO3DQD.js +0 -1475
  345. package/dist/plugin-update-checker-KRRSGXMV.js +0 -12
  346. package/dist/portal-check-NPYGII2D.js +0 -42
  347. package/dist/portal-compliance-J7DGAPFX.js +0 -18
  348. package/dist/probe-MHL5HQZ2.js +0 -167
  349. package/dist/promote-F6ZYZZAL.js +0 -182
  350. package/dist/providers-GK7PB2OL.js +0 -104
  351. package/dist/quiz-M66SC7F7.js +0 -99
  352. package/dist/record-RA4WR2BO.js +0 -49
  353. package/dist/reindex-5LTD53ZC.js +0 -16
  354. package/dist/remember-HBWJ655S.js +0 -77
  355. package/dist/retag-3OLCVDEQ.js +0 -62
  356. package/dist/review-27ATYTD2.js +0 -33
  357. package/dist/review-57QMURZV.js +0 -334
  358. package/dist/ripple-JPBXP5I3.js +0 -215
  359. package/dist/sentinel-4XIG4STA.js +0 -63
  360. package/dist/sentinel-bridge-MDUXTQRL.js +0 -109
  361. package/dist/serve-CAH3PHE7.js +0 -33
  362. package/dist/serve-INL7SNBK.js +0 -36
  363. package/dist/serve-KBSE36PL.js +0 -49
  364. package/dist/server-54SKYFFY.js +0 -1647
  365. package/dist/server-XUOIO7E6.js +0 -338
  366. package/dist/session-tracker-C4BMD5WG.js +0 -13
  367. package/dist/session-work-log-MZ47OAPB.js +0 -20
  368. package/dist/setup-EDS27WUR.js +0 -25
  369. package/dist/setup-KO5AFC4K.js +0 -296
  370. package/dist/shift-D2JOHHBF.js +0 -668
  371. package/dist/show-5PV5KFJE.js +0 -176
  372. package/dist/show-NQKYX6WQ.js +0 -82
  373. package/dist/snapshot-BK4RBPCG.js +0 -62
  374. package/dist/spawn-RCHNXDHE.js +0 -196
  375. package/dist/status-WGIAQODY.js +0 -71
  376. package/dist/summary-NIRABMF5.js +0 -140
  377. package/dist/sweep-QMHNSIY5.js +0 -934
  378. package/dist/switch-6EJPZDIA.js +0 -232
  379. package/dist/symphony-4OCY36AI.js +0 -791
  380. package/dist/symphony-B75X2MME.js +0 -326
  381. package/dist/symphony-loader-UZGON56V.js +0 -90
  382. package/dist/symphony-peers-2ZQYLRNI.js +0 -34
  383. package/dist/symphony-peers-OL7F6M5S.js +0 -121
  384. package/dist/symphony-relay-UJYUXN65.js +0 -710
  385. package/dist/sync-VEHUH4OA.js +0 -11
  386. package/dist/sync-llms-YHCFIE6X.js +0 -166
  387. package/dist/task-loader-LDYWQSLM.js +0 -20
  388. package/dist/team-O5MIIFMA.js +0 -34
  389. package/dist/test-566CP5KC.js +0 -1017
  390. package/dist/thread-N754I4D5.js +0 -274
  391. package/dist/timeline-M3CICQFE.js +0 -112
  392. package/dist/triage-HHYGT3HY.js +0 -671
  393. package/dist/tutorial-KD22SUNO.js +0 -666
  394. package/dist/upgrade-H5PF32BW.js +0 -551
  395. package/dist/validate-CNKEKO6A.js +0 -134
  396. package/dist/validate-MB5ULIHS.js +0 -39
  397. package/dist/validate-QH3LADM6.js +0 -64
  398. package/dist/watch-2TKP5PVL.js +0 -199
  399. package/dist/watch-ZF4ML6CD.js +0 -111
  400. package/dist/wisdom-AATMGNFA.js +0 -319
  401. package/dist/work-log-loader-5L45XNYZ.js +0 -14
  402. package/dist/workspace-6E6OSRNU.js +0 -21
  403. package/platform-ui/dist/assets/AmbientSection-WtHfNedO.js +0 -1
  404. package/platform-ui/dist/assets/LoreSection-C3EixkjW.css +0 -1
  405. package/platform-ui/dist/assets/LoreSection-CwDDHrz9.js +0 -1
  406. package/platform-ui/dist/assets/SentinelSection-Cl7e5oZ6.js +0 -1
  407. package/platform-ui/dist/assets/TeamSection-CqSIMrKz.js +0 -1
  408. package/platform-ui/dist/assets/index-CfpZFjea.css +0 -1
  409. package/platform-ui/dist/assets/index-F0KL9xrN.js +0 -57
@@ -1,3081 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ../sentinel/dist/chunk-OKYYIAML.js
4
- import initSqlJs from "sql.js";
5
- import { v4 as uuidv4 } from "uuid";
6
- import * as path from "path";
7
- import * as fs from "fs";
8
- import * as fs2 from "fs";
9
- import * as path2 from "path";
10
- var SCHEMA_VERSION = 5;
11
- var DEFAULT_CONFIDENCE = {
12
- score: 50,
13
- timesMatched: 0,
14
- timesResolved: 0,
15
- timesRecurred: 0
16
- };
17
- var SQL = null;
18
- var SentinelStorage = class {
19
- db = null;
20
- dbPath;
21
- incidentCounter = 0;
22
- initialized = false;
23
- constructor(dbPath) {
24
- this.dbPath = dbPath || this.getDefaultDbPath();
25
- }
26
- getDefaultDbPath() {
27
- const dataDir = process.env.SENTINEL_DATA_DIR || process.env.PARADIGM_DATA_DIR || path.join(process.cwd(), ".paradigm", "sentinel");
28
- return path.join(dataDir, "sentinel.db");
29
- }
30
- createSchema() {
31
- if (!this.db) return;
32
- this.db.run(`
33
- -- Metadata table for schema versioning
34
- CREATE TABLE IF NOT EXISTS metadata (
35
- key TEXT PRIMARY KEY,
36
- value TEXT NOT NULL
37
- );
38
-
39
- -- Incidents table
40
- CREATE TABLE IF NOT EXISTS incidents (
41
- id TEXT PRIMARY KEY,
42
- timestamp TEXT NOT NULL,
43
- status TEXT NOT NULL DEFAULT 'open',
44
- error_message TEXT NOT NULL,
45
- error_stack TEXT,
46
- error_code TEXT,
47
- error_type TEXT,
48
- symbols TEXT NOT NULL,
49
- flow_position TEXT,
50
- environment TEXT NOT NULL,
51
- service TEXT,
52
- version TEXT,
53
- user_id TEXT,
54
- request_id TEXT,
55
- group_id TEXT,
56
- notes TEXT DEFAULT '[]',
57
- related_incidents TEXT DEFAULT '[]',
58
- resolved_at TEXT,
59
- resolved_by TEXT,
60
- resolution TEXT,
61
- created_at TEXT NOT NULL,
62
- updated_at TEXT NOT NULL
63
- );
64
-
65
- -- Patterns table
66
- CREATE TABLE IF NOT EXISTS patterns (
67
- id TEXT PRIMARY KEY,
68
- name TEXT NOT NULL,
69
- description TEXT,
70
- pattern TEXT NOT NULL,
71
- resolution TEXT NOT NULL,
72
- confidence TEXT NOT NULL,
73
- source TEXT NOT NULL DEFAULT 'manual',
74
- private INTEGER NOT NULL DEFAULT 0,
75
- tags TEXT DEFAULT '[]',
76
- created_at TEXT NOT NULL,
77
- updated_at TEXT NOT NULL
78
- );
79
-
80
- -- Incident groups
81
- CREATE TABLE IF NOT EXISTS groups (
82
- id TEXT PRIMARY KEY,
83
- name TEXT,
84
- common_symbols TEXT,
85
- common_error_patterns TEXT,
86
- suggested_pattern_id TEXT,
87
- first_seen TEXT NOT NULL,
88
- last_seen TEXT NOT NULL,
89
- created_at TEXT NOT NULL,
90
- updated_at TEXT NOT NULL
91
- );
92
-
93
- -- Group members
94
- CREATE TABLE IF NOT EXISTS group_members (
95
- group_id TEXT NOT NULL,
96
- incident_id TEXT NOT NULL,
97
- added_at TEXT NOT NULL,
98
- PRIMARY KEY (group_id, incident_id)
99
- );
100
-
101
- -- Resolutions history
102
- CREATE TABLE IF NOT EXISTS resolutions (
103
- id TEXT PRIMARY KEY,
104
- incident_id TEXT NOT NULL,
105
- pattern_id TEXT,
106
- commit_hash TEXT,
107
- pr_url TEXT,
108
- notes TEXT,
109
- resolved_at TEXT NOT NULL,
110
- recurred INTEGER DEFAULT 0
111
- );
112
-
113
- -- Practice events (habits system)
114
- CREATE TABLE IF NOT EXISTS practice_events (
115
- id TEXT PRIMARY KEY,
116
- timestamp TEXT NOT NULL,
117
- habit_id TEXT NOT NULL,
118
- habit_category TEXT NOT NULL,
119
- result TEXT NOT NULL CHECK (result IN ('followed', 'skipped', 'partial')),
120
- engineer TEXT NOT NULL,
121
- session_id TEXT NOT NULL,
122
- lore_entry_id TEXT,
123
- task_description TEXT,
124
- symbols_touched TEXT DEFAULT '[]',
125
- files_modified TEXT DEFAULT '[]',
126
- related_incident_id TEXT,
127
- notes TEXT
128
- );
129
-
130
- -- Structured logs table
131
- CREATE TABLE IF NOT EXISTS logs (
132
- id TEXT PRIMARY KEY,
133
- timestamp TEXT NOT NULL,
134
- level TEXT NOT NULL CHECK (level IN ('debug','info','warn','error')),
135
- symbol TEXT NOT NULL,
136
- symbol_type TEXT NOT NULL DEFAULT 'raw',
137
- message TEXT NOT NULL,
138
- data_json TEXT,
139
- service TEXT NOT NULL,
140
- session_id TEXT,
141
- correlation_id TEXT,
142
- duration_ms REAL,
143
- environment TEXT
144
- );
145
-
146
- -- Service registry
147
- CREATE TABLE IF NOT EXISTS services (
148
- name TEXT PRIMARY KEY,
149
- version TEXT,
150
- pid INTEGER,
151
- started_at TEXT NOT NULL,
152
- last_seen_at TEXT NOT NULL,
153
- environment TEXT,
154
- metadata_json TEXT
155
- );
156
-
157
- -- Live app state snapshots (latest-wins per service+session)
158
- CREATE TABLE IF NOT EXISTS app_state (
159
- service TEXT NOT NULL,
160
- session_id TEXT NOT NULL,
161
- timestamp TEXT NOT NULL,
162
- state_json TEXT NOT NULL,
163
- active_flows_json TEXT,
164
- active_gates_json TEXT,
165
- PRIMARY KEY (service, session_id)
166
- );
167
-
168
- -- Metrics table
169
- CREATE TABLE IF NOT EXISTS metrics (
170
- id TEXT PRIMARY KEY,
171
- timestamp TEXT NOT NULL,
172
- name TEXT NOT NULL,
173
- type TEXT NOT NULL CHECK (type IN ('counter','gauge','histogram')),
174
- value REAL NOT NULL,
175
- tags_json TEXT DEFAULT '{}',
176
- service TEXT NOT NULL,
177
- environment TEXT
178
- );
179
-
180
- -- Traces table
181
- CREATE TABLE IF NOT EXISTS traces (
182
- trace_id TEXT NOT NULL,
183
- span_id TEXT PRIMARY KEY,
184
- parent_span_id TEXT,
185
- service TEXT NOT NULL,
186
- symbol TEXT NOT NULL,
187
- operation TEXT NOT NULL,
188
- start_time TEXT NOT NULL,
189
- end_time TEXT,
190
- duration_ms REAL,
191
- status TEXT NOT NULL DEFAULT 'ok',
192
- tags_json TEXT DEFAULT '{}',
193
- log_ids_json TEXT DEFAULT '[]'
194
- );
195
-
196
- -- Indexes
197
- CREATE INDEX IF NOT EXISTS idx_incidents_timestamp ON incidents(timestamp);
198
- CREATE INDEX IF NOT EXISTS idx_incidents_status ON incidents(status);
199
- CREATE INDEX IF NOT EXISTS idx_incidents_environment ON incidents(environment);
200
- CREATE INDEX IF NOT EXISTS idx_patterns_source ON patterns(source);
201
- CREATE INDEX IF NOT EXISTS idx_practice_events_timestamp ON practice_events(timestamp);
202
- CREATE INDEX IF NOT EXISTS idx_practice_events_habit_id ON practice_events(habit_id);
203
- CREATE INDEX IF NOT EXISTS idx_practice_events_engineer ON practice_events(engineer);
204
- CREATE INDEX IF NOT EXISTS idx_practice_events_session_id ON practice_events(session_id);
205
- CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp);
206
- CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level);
207
- CREATE INDEX IF NOT EXISTS idx_logs_symbol ON logs(symbol);
208
- CREATE INDEX IF NOT EXISTS idx_logs_service ON logs(service);
209
- CREATE INDEX IF NOT EXISTS idx_logs_session_id ON logs(session_id);
210
- CREATE INDEX IF NOT EXISTS idx_logs_correlation_id ON logs(correlation_id);
211
- CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(timestamp);
212
- CREATE INDEX IF NOT EXISTS idx_metrics_name ON metrics(name);
213
- CREATE INDEX IF NOT EXISTS idx_metrics_service ON metrics(service);
214
- CREATE INDEX IF NOT EXISTS idx_traces_trace_id ON traces(trace_id);
215
- CREATE INDEX IF NOT EXISTS idx_traces_service ON traces(service);
216
- CREATE INDEX IF NOT EXISTS idx_traces_start_time ON traces(start_time);
217
- `);
218
- this.db.run(
219
- "INSERT OR REPLACE INTO metadata (key, value) VALUES ('schema_version', ?)",
220
- [String(SCHEMA_VERSION)]
221
- );
222
- }
223
- save() {
224
- if (!this.db) return;
225
- const data = this.db.export();
226
- const buffer = Buffer.from(data);
227
- fs.writeFileSync(this.dbPath, buffer);
228
- }
229
- // ─── Incidents ───────────────────────────────────────────────────
230
- recordIncident(input) {
231
- const db = this.db;
232
- if (!db) {
233
- this.initializeSync();
234
- }
235
- this.incidentCounter++;
236
- const id = `INC-${String(this.incidentCounter).padStart(3, "0")}`;
237
- const now = (/* @__PURE__ */ new Date()).toISOString();
238
- this.db.run(
239
- `INSERT INTO incidents (
240
- id, timestamp, status, error_message, error_stack, error_code, error_type,
241
- symbols, flow_position, environment, service, version, user_id, request_id,
242
- group_id, notes, related_incidents, resolved_at, resolved_by, resolution,
243
- created_at, updated_at
244
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
245
- [
246
- id,
247
- input.timestamp || now,
248
- input.status || "open",
249
- input.error.message,
250
- input.error.stack || null,
251
- input.error.code || null,
252
- input.error.type || null,
253
- JSON.stringify(input.symbols),
254
- input.flowPosition ? JSON.stringify(input.flowPosition) : null,
255
- input.environment,
256
- input.service || null,
257
- input.version || null,
258
- input.userId || null,
259
- input.requestId || null,
260
- input.groupId || null,
261
- "[]",
262
- "[]",
263
- input.resolvedAt || null,
264
- input.resolvedBy || null,
265
- input.resolution ? JSON.stringify(input.resolution) : null,
266
- now,
267
- now
268
- ]
269
- );
270
- this.save();
271
- return id;
272
- }
273
- initializeSync() {
274
- if (this.initialized && this.db) return;
275
- if (!this.db && SQL) {
276
- const dir = path.dirname(this.dbPath);
277
- if (!fs.existsSync(dir)) {
278
- fs.mkdirSync(dir, { recursive: true });
279
- }
280
- if (fs.existsSync(this.dbPath)) {
281
- const fileData = fs.readFileSync(this.dbPath);
282
- this.db = new SQL.Database(fileData);
283
- } else {
284
- this.db = new SQL.Database();
285
- this.createSchema();
286
- }
287
- try {
288
- const result = this.db.exec(
289
- "SELECT MAX(CAST(SUBSTR(id, 5) AS INTEGER)) as max FROM incidents"
290
- );
291
- if (result.length > 0 && result[0].values.length > 0 && result[0].values[0][0]) {
292
- this.incidentCounter = result[0].values[0][0];
293
- }
294
- } catch {
295
- this.incidentCounter = 0;
296
- }
297
- this.migrateSchema();
298
- this.initialized = true;
299
- this.save();
300
- }
301
- }
302
- /**
303
- * Run schema migrations from older versions
304
- */
305
- migrateSchema() {
306
- if (!this.db) return;
307
- let currentVersion = 1;
308
- try {
309
- const result = this.db.exec(
310
- "SELECT value FROM metadata WHERE key = 'schema_version'"
311
- );
312
- if (result.length > 0 && result[0].values.length > 0) {
313
- currentVersion = parseInt(result[0].values[0][0], 10) || 1;
314
- }
315
- } catch {
316
- }
317
- if (currentVersion < 2) {
318
- try {
319
- this.db.run(`
320
- CREATE TABLE IF NOT EXISTS practice_events (
321
- id TEXT PRIMARY KEY,
322
- timestamp TEXT NOT NULL,
323
- habit_id TEXT NOT NULL,
324
- habit_category TEXT NOT NULL,
325
- result TEXT NOT NULL CHECK (result IN ('followed', 'skipped', 'partial')),
326
- engineer TEXT NOT NULL,
327
- session_id TEXT NOT NULL,
328
- lore_entry_id TEXT,
329
- task_description TEXT,
330
- symbols_touched TEXT DEFAULT '[]',
331
- files_modified TEXT DEFAULT '[]',
332
- related_incident_id TEXT,
333
- notes TEXT
334
- );
335
-
336
- CREATE INDEX IF NOT EXISTS idx_practice_events_timestamp ON practice_events(timestamp);
337
- CREATE INDEX IF NOT EXISTS idx_practice_events_habit_id ON practice_events(habit_id);
338
- CREATE INDEX IF NOT EXISTS idx_practice_events_engineer ON practice_events(engineer);
339
- CREATE INDEX IF NOT EXISTS idx_practice_events_session_id ON practice_events(session_id);
340
- `);
341
- } catch {
342
- }
343
- this.db.run(
344
- "INSERT OR REPLACE INTO metadata (key, value) VALUES ('schema_version', '2')"
345
- );
346
- currentVersion = 2;
347
- }
348
- if (currentVersion < 3) {
349
- try {
350
- this.db.run(`
351
- CREATE TABLE IF NOT EXISTS logs (
352
- id TEXT PRIMARY KEY,
353
- timestamp TEXT NOT NULL,
354
- level TEXT NOT NULL CHECK (level IN ('debug','info','warn','error')),
355
- symbol TEXT NOT NULL,
356
- symbol_type TEXT NOT NULL DEFAULT 'raw',
357
- message TEXT NOT NULL,
358
- data_json TEXT,
359
- service TEXT NOT NULL,
360
- session_id TEXT,
361
- correlation_id TEXT,
362
- duration_ms REAL,
363
- environment TEXT
364
- );
365
-
366
- CREATE TABLE IF NOT EXISTS services (
367
- name TEXT PRIMARY KEY,
368
- version TEXT,
369
- pid INTEGER,
370
- started_at TEXT NOT NULL,
371
- last_seen_at TEXT NOT NULL,
372
- environment TEXT,
373
- metadata_json TEXT
374
- );
375
-
376
- CREATE TABLE IF NOT EXISTS app_state (
377
- service TEXT NOT NULL,
378
- session_id TEXT NOT NULL,
379
- timestamp TEXT NOT NULL,
380
- state_json TEXT NOT NULL,
381
- active_flows_json TEXT,
382
- active_gates_json TEXT,
383
- PRIMARY KEY (service, session_id)
384
- );
385
-
386
- CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp);
387
- CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level);
388
- CREATE INDEX IF NOT EXISTS idx_logs_symbol ON logs(symbol);
389
- CREATE INDEX IF NOT EXISTS idx_logs_service ON logs(service);
390
- CREATE INDEX IF NOT EXISTS idx_logs_session_id ON logs(session_id);
391
- CREATE INDEX IF NOT EXISTS idx_logs_correlation_id ON logs(correlation_id);
392
- `);
393
- } catch {
394
- }
395
- this.db.run(
396
- "INSERT OR REPLACE INTO metadata (key, value) VALUES ('schema_version', '3')"
397
- );
398
- currentVersion = 3;
399
- }
400
- if (currentVersion < 4) {
401
- try {
402
- this.db.run(`
403
- CREATE TABLE IF NOT EXISTS metrics (
404
- id TEXT PRIMARY KEY,
405
- timestamp TEXT NOT NULL,
406
- name TEXT NOT NULL,
407
- type TEXT NOT NULL CHECK (type IN ('counter','gauge','histogram')),
408
- value REAL NOT NULL,
409
- tags_json TEXT DEFAULT '{}',
410
- service TEXT NOT NULL,
411
- environment TEXT
412
- );
413
-
414
- CREATE TABLE IF NOT EXISTS traces (
415
- trace_id TEXT NOT NULL,
416
- span_id TEXT PRIMARY KEY,
417
- parent_span_id TEXT,
418
- service TEXT NOT NULL,
419
- symbol TEXT NOT NULL,
420
- operation TEXT NOT NULL,
421
- start_time TEXT NOT NULL,
422
- end_time TEXT,
423
- duration_ms REAL,
424
- status TEXT NOT NULL DEFAULT 'ok',
425
- tags_json TEXT DEFAULT '{}',
426
- log_ids_json TEXT DEFAULT '[]'
427
- );
428
-
429
- CREATE INDEX IF NOT EXISTS idx_metrics_timestamp ON metrics(timestamp);
430
- CREATE INDEX IF NOT EXISTS idx_metrics_name ON metrics(name);
431
- CREATE INDEX IF NOT EXISTS idx_metrics_service ON metrics(service);
432
- CREATE INDEX IF NOT EXISTS idx_traces_trace_id ON traces(trace_id);
433
- CREATE INDEX IF NOT EXISTS idx_traces_service ON traces(service);
434
- CREATE INDEX IF NOT EXISTS idx_traces_start_time ON traces(start_time);
435
- `);
436
- } catch {
437
- }
438
- this.db.run(
439
- "INSERT OR REPLACE INTO metadata (key, value) VALUES ('schema_version', '4')"
440
- );
441
- currentVersion = 4;
442
- }
443
- if (currentVersion < 5) {
444
- try {
445
- this.db.run(`
446
- CREATE TABLE IF NOT EXISTS schemas (
447
- id TEXT PRIMARY KEY,
448
- version TEXT NOT NULL,
449
- name TEXT NOT NULL,
450
- description TEXT,
451
- scope_json TEXT NOT NULL,
452
- event_types_json TEXT NOT NULL,
453
- causality_json TEXT,
454
- visualization_json TEXT,
455
- tags_json TEXT DEFAULT '[]',
456
- registered_at TEXT NOT NULL,
457
- updated_at TEXT NOT NULL
458
- );
459
-
460
- CREATE TABLE IF NOT EXISTS events (
461
- id TEXT PRIMARY KEY,
462
- schema_id TEXT NOT NULL,
463
- event_type TEXT NOT NULL,
464
- category TEXT NOT NULL,
465
- timestamp TEXT NOT NULL,
466
- scope_value TEXT,
467
- scope_ordinal INTEGER,
468
- session_id TEXT,
469
- service TEXT NOT NULL,
470
- data_json TEXT,
471
- severity TEXT DEFAULT 'info',
472
- parent_event_id TEXT,
473
- depth INTEGER DEFAULT 0
474
- );
475
-
476
- CREATE INDEX IF NOT EXISTS idx_events_schema ON events(schema_id);
477
- CREATE INDEX IF NOT EXISTS idx_events_type ON events(event_type);
478
- CREATE INDEX IF NOT EXISTS idx_events_scope ON events(schema_id, scope_value);
479
- CREATE INDEX IF NOT EXISTS idx_events_scope_ord ON events(schema_id, scope_ordinal);
480
- CREATE INDEX IF NOT EXISTS idx_events_session ON events(session_id);
481
- CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);
482
- CREATE INDEX IF NOT EXISTS idx_events_service ON events(service);
483
- `);
484
- } catch {
485
- }
486
- this.db.run(
487
- "INSERT OR REPLACE INTO metadata (key, value) VALUES ('schema_version', '5')"
488
- );
489
- }
490
- }
491
- /**
492
- * Ensure the storage is ready for use. Must be called once before using storage methods.
493
- */
494
- async ensureReady() {
495
- if (!SQL) {
496
- SQL = await initSqlJs();
497
- }
498
- this.initializeSync();
499
- }
500
- getIncident(id) {
501
- this.initializeSync();
502
- const result = this.db.exec("SELECT * FROM incidents WHERE id = ?", [id]);
503
- if (result.length === 0 || result[0].values.length === 0) return null;
504
- return this.rowToIncident(result[0].columns, result[0].values[0]);
505
- }
506
- getRecentIncidents(options = {}) {
507
- this.initializeSync();
508
- const { limit = 50, offset = 0 } = options;
509
- const conditions = [];
510
- const params = [];
511
- if (options.status && options.status !== "all") {
512
- conditions.push("status = ?");
513
- params.push(options.status);
514
- }
515
- if (options.environment) {
516
- conditions.push("environment = ?");
517
- params.push(options.environment);
518
- }
519
- if (options.symbol) {
520
- conditions.push("symbols LIKE ?");
521
- params.push(`%${options.symbol}%`);
522
- }
523
- if (options.search) {
524
- conditions.push("(error_message LIKE ? OR notes LIKE ?)");
525
- params.push(`%${options.search}%`, `%${options.search}%`);
526
- }
527
- if (options.dateFrom) {
528
- conditions.push("timestamp >= ?");
529
- params.push(options.dateFrom);
530
- }
531
- if (options.dateTo) {
532
- conditions.push("timestamp <= ?");
533
- params.push(options.dateTo);
534
- }
535
- if (options.groupId) {
536
- conditions.push("group_id = ?");
537
- params.push(options.groupId);
538
- }
539
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
540
- const result = this.db.exec(
541
- `SELECT * FROM incidents ${whereClause} ORDER BY timestamp DESC LIMIT ? OFFSET ?`,
542
- [...params, limit, offset]
543
- );
544
- if (result.length === 0) return [];
545
- return result[0].values.map(
546
- (row) => this.rowToIncident(result[0].columns, row)
547
- );
548
- }
549
- updateIncident(id, updates) {
550
- this.initializeSync();
551
- const now = (/* @__PURE__ */ new Date()).toISOString();
552
- const setClauses = ["updated_at = ?"];
553
- const params = [now];
554
- if (updates.status !== void 0) {
555
- setClauses.push("status = ?");
556
- params.push(updates.status);
557
- }
558
- if (updates.error !== void 0) {
559
- setClauses.push("error_message = ?");
560
- params.push(updates.error.message);
561
- if (updates.error.stack !== void 0) {
562
- setClauses.push("error_stack = ?");
563
- params.push(updates.error.stack || null);
564
- }
565
- }
566
- if (updates.symbols !== void 0) {
567
- setClauses.push("symbols = ?");
568
- params.push(JSON.stringify(updates.symbols));
569
- }
570
- if (updates.flowPosition !== void 0) {
571
- setClauses.push("flow_position = ?");
572
- params.push(
573
- updates.flowPosition ? JSON.stringify(updates.flowPosition) : null
574
- );
575
- }
576
- if (updates.groupId !== void 0) {
577
- setClauses.push("group_id = ?");
578
- params.push(updates.groupId || null);
579
- }
580
- if (updates.resolvedAt !== void 0) {
581
- setClauses.push("resolved_at = ?");
582
- params.push(updates.resolvedAt || null);
583
- }
584
- if (updates.resolvedBy !== void 0) {
585
- setClauses.push("resolved_by = ?");
586
- params.push(updates.resolvedBy || null);
587
- }
588
- if (updates.resolution !== void 0) {
589
- setClauses.push("resolution = ?");
590
- params.push(
591
- updates.resolution ? JSON.stringify(updates.resolution) : null
592
- );
593
- }
594
- params.push(id);
595
- this.db.run(
596
- `UPDATE incidents SET ${setClauses.join(", ")} WHERE id = ?`,
597
- params
598
- );
599
- this.save();
600
- }
601
- resolveIncident(id, options) {
602
- this.updateIncident(id, {
603
- status: "resolved",
604
- resolvedAt: (/* @__PURE__ */ new Date()).toISOString()
605
- });
606
- if (options?.notes) {
607
- this.addIncidentNote(id, {
608
- author: "system",
609
- content: options.notes,
610
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
611
- });
612
- }
613
- }
614
- addIncidentNote(incidentId, note) {
615
- this.initializeSync();
616
- const incident = this.getIncident(incidentId);
617
- if (!incident) return;
618
- const newNote = {
619
- id: uuidv4(),
620
- ...note
621
- };
622
- const notes = [...incident.notes, newNote];
623
- this.db.run(
624
- "UPDATE incidents SET notes = ?, updated_at = ? WHERE id = ?",
625
- [JSON.stringify(notes), (/* @__PURE__ */ new Date()).toISOString(), incidentId]
626
- );
627
- this.save();
628
- }
629
- linkIncidents(incidentId, relatedId) {
630
- this.initializeSync();
631
- const incident = this.getIncident(incidentId);
632
- if (!incident) return;
633
- if (!incident.relatedIncidents.includes(relatedId)) {
634
- const related = [...incident.relatedIncidents, relatedId];
635
- this.db.run(
636
- "UPDATE incidents SET related_incidents = ?, updated_at = ? WHERE id = ?",
637
- [JSON.stringify(related), (/* @__PURE__ */ new Date()).toISOString(), incidentId]
638
- );
639
- }
640
- const relatedIncident = this.getIncident(relatedId);
641
- if (relatedIncident && !relatedIncident.relatedIncidents.includes(incidentId)) {
642
- const related = [...relatedIncident.relatedIncidents, incidentId];
643
- this.db.run(
644
- "UPDATE incidents SET related_incidents = ?, updated_at = ? WHERE id = ?",
645
- [JSON.stringify(related), (/* @__PURE__ */ new Date()).toISOString(), relatedId]
646
- );
647
- }
648
- this.save();
649
- }
650
- getIncidentCount(options = {}) {
651
- this.initializeSync();
652
- const conditions = [];
653
- const params = [];
654
- if (options.status && options.status !== "all") {
655
- conditions.push("status = ?");
656
- params.push(options.status);
657
- }
658
- if (options.environment) {
659
- conditions.push("environment = ?");
660
- params.push(options.environment);
661
- }
662
- if (options.dateFrom) {
663
- conditions.push("timestamp >= ?");
664
- params.push(options.dateFrom);
665
- }
666
- if (options.dateTo) {
667
- conditions.push("timestamp <= ?");
668
- params.push(options.dateTo);
669
- }
670
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
671
- const result = this.db.exec(
672
- `SELECT COUNT(*) as count FROM incidents ${whereClause}`,
673
- params
674
- );
675
- if (result.length === 0 || result[0].values.length === 0) return 0;
676
- return result[0].values[0][0];
677
- }
678
- // ─── Patterns ────────────────────────────────────────────────────
679
- addPattern(input) {
680
- this.initializeSync();
681
- const now = (/* @__PURE__ */ new Date()).toISOString();
682
- const confidence = {
683
- ...DEFAULT_CONFIDENCE,
684
- ...input.confidence
685
- };
686
- this.db.run(
687
- `INSERT INTO patterns (
688
- id, name, description, pattern, resolution, confidence,
689
- source, private, tags, created_at, updated_at
690
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
691
- [
692
- input.id,
693
- input.name,
694
- input.description || null,
695
- JSON.stringify(input.pattern),
696
- JSON.stringify(input.resolution),
697
- JSON.stringify(confidence),
698
- input.source,
699
- input.private ? 1 : 0,
700
- JSON.stringify(input.tags || []),
701
- now,
702
- now
703
- ]
704
- );
705
- this.save();
706
- return input.id;
707
- }
708
- getPattern(id) {
709
- this.initializeSync();
710
- const result = this.db.exec("SELECT * FROM patterns WHERE id = ?", [id]);
711
- if (result.length === 0 || result[0].values.length === 0) return null;
712
- return this.rowToPattern(result[0].columns, result[0].values[0]);
713
- }
714
- getAllPatterns(options = {}) {
715
- this.initializeSync();
716
- const conditions = [];
717
- const params = [];
718
- if (options.source) {
719
- conditions.push("source = ?");
720
- params.push(options.source);
721
- }
722
- if (options.minConfidence !== void 0) {
723
- conditions.push("json_extract(confidence, '$.score') >= ?");
724
- params.push(options.minConfidence);
725
- }
726
- if (!options.includePrivate) {
727
- conditions.push("private = 0");
728
- }
729
- if (options.tags && options.tags.length > 0) {
730
- const tagConditions = options.tags.map(() => "tags LIKE ?");
731
- conditions.push(`(${tagConditions.join(" OR ")})`);
732
- params.push(...options.tags.map((tag) => `%"${tag}"%`));
733
- }
734
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
735
- const result = this.db.exec(
736
- `SELECT * FROM patterns ${whereClause} ORDER BY json_extract(confidence, '$.score') DESC`,
737
- params
738
- );
739
- if (result.length === 0) return [];
740
- return result[0].values.map(
741
- (row) => this.rowToPattern(result[0].columns, row)
742
- );
743
- }
744
- updatePattern(id, updates) {
745
- this.initializeSync();
746
- const now = (/* @__PURE__ */ new Date()).toISOString();
747
- const setClauses = ["updated_at = ?"];
748
- const params = [now];
749
- if (updates.name !== void 0) {
750
- setClauses.push("name = ?");
751
- params.push(updates.name);
752
- }
753
- if (updates.description !== void 0) {
754
- setClauses.push("description = ?");
755
- params.push(updates.description || null);
756
- }
757
- if (updates.pattern !== void 0) {
758
- setClauses.push("pattern = ?");
759
- params.push(JSON.stringify(updates.pattern));
760
- }
761
- if (updates.resolution !== void 0) {
762
- setClauses.push("resolution = ?");
763
- params.push(JSON.stringify(updates.resolution));
764
- }
765
- if (updates.confidence !== void 0) {
766
- setClauses.push("confidence = ?");
767
- params.push(JSON.stringify(updates.confidence));
768
- }
769
- if (updates.source !== void 0) {
770
- setClauses.push("source = ?");
771
- params.push(updates.source);
772
- }
773
- if (updates.private !== void 0) {
774
- setClauses.push("private = ?");
775
- params.push(updates.private ? 1 : 0);
776
- }
777
- if (updates.tags !== void 0) {
778
- setClauses.push("tags = ?");
779
- params.push(JSON.stringify(updates.tags));
780
- }
781
- params.push(id);
782
- this.db.run(
783
- `UPDATE patterns SET ${setClauses.join(", ")} WHERE id = ?`,
784
- params
785
- );
786
- this.save();
787
- }
788
- deletePattern(id) {
789
- this.initializeSync();
790
- this.db.run("DELETE FROM patterns WHERE id = ?", [id]);
791
- this.save();
792
- }
793
- updatePatternConfidence(patternId, event) {
794
- const pattern = this.getPattern(patternId);
795
- if (!pattern) return;
796
- const now = (/* @__PURE__ */ new Date()).toISOString();
797
- const confidence = { ...pattern.confidence };
798
- switch (event) {
799
- case "matched":
800
- confidence.timesMatched++;
801
- confidence.lastMatched = now;
802
- break;
803
- case "resolved":
804
- confidence.timesResolved++;
805
- confidence.lastResolved = now;
806
- confidence.score = Math.min(100, confidence.score + 2);
807
- break;
808
- case "recurred":
809
- confidence.timesRecurred++;
810
- confidence.score = Math.max(10, confidence.score - 5);
811
- break;
812
- }
813
- this.updatePattern(patternId, { confidence });
814
- }
815
- // ─── Groups ──────────────────────────────────────────────────────
816
- createGroup(input) {
817
- this.initializeSync();
818
- const id = `GRP-${uuidv4().substring(0, 8)}`;
819
- const now = (/* @__PURE__ */ new Date()).toISOString();
820
- this.db.run(
821
- `INSERT INTO groups (
822
- id, name, common_symbols, common_error_patterns,
823
- suggested_pattern_id, first_seen, last_seen, created_at, updated_at
824
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
825
- [
826
- id,
827
- input.name || null,
828
- JSON.stringify(input.commonSymbols),
829
- JSON.stringify(input.commonErrorPatterns),
830
- input.suggestedPattern?.id || null,
831
- input.firstSeen,
832
- input.lastSeen,
833
- now,
834
- now
835
- ]
836
- );
837
- for (const incidentId of input.incidents) {
838
- this.addToGroup(id, incidentId);
839
- }
840
- this.save();
841
- return id;
842
- }
843
- getGroup(id) {
844
- this.initializeSync();
845
- const result = this.db.exec("SELECT * FROM groups WHERE id = ?", [id]);
846
- if (result.length === 0 || result[0].values.length === 0) return null;
847
- return this.rowToGroup(result[0].columns, result[0].values[0]);
848
- }
849
- getGroups(options = {}) {
850
- this.initializeSync();
851
- const limit = options.limit || 100;
852
- const result = this.db.exec(
853
- "SELECT * FROM groups ORDER BY last_seen DESC LIMIT ?",
854
- [limit]
855
- );
856
- if (result.length === 0) return [];
857
- return result[0].values.map(
858
- (row) => this.rowToGroup(result[0].columns, row)
859
- );
860
- }
861
- addToGroup(groupId, incidentId) {
862
- this.initializeSync();
863
- const now = (/* @__PURE__ */ new Date()).toISOString();
864
- this.db.run(
865
- "INSERT OR IGNORE INTO group_members (group_id, incident_id, added_at) VALUES (?, ?, ?)",
866
- [groupId, incidentId, now]
867
- );
868
- this.db.run("UPDATE incidents SET group_id = ? WHERE id = ?", [
869
- groupId,
870
- incidentId
871
- ]);
872
- this.db.run(
873
- "UPDATE groups SET last_seen = ?, updated_at = ? WHERE id = ?",
874
- [now, now, groupId]
875
- );
876
- this.save();
877
- }
878
- // ─── Resolutions ─────────────────────────────────────────────────
879
- recordResolution(resolution) {
880
- this.initializeSync();
881
- const id = uuidv4();
882
- const now = (/* @__PURE__ */ new Date()).toISOString();
883
- this.db.run(
884
- `INSERT INTO resolutions (id, incident_id, pattern_id, commit_hash, pr_url, notes, resolved_at)
885
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
886
- [
887
- id,
888
- resolution.incidentId,
889
- resolution.patternId || null,
890
- resolution.commitHash || null,
891
- resolution.prUrl || null,
892
- resolution.notes || null,
893
- now
894
- ]
895
- );
896
- this.updateIncident(resolution.incidentId, {
897
- status: "resolved",
898
- resolvedAt: now,
899
- resolvedBy: resolution.patternId || "manual",
900
- resolution: {
901
- patternId: resolution.patternId,
902
- commitHash: resolution.commitHash,
903
- prUrl: resolution.prUrl,
904
- notes: resolution.notes
905
- }
906
- });
907
- if (resolution.patternId) {
908
- this.updatePatternConfidence(resolution.patternId, "resolved");
909
- }
910
- this.save();
911
- }
912
- markRecurred(incidentId) {
913
- this.initializeSync();
914
- this.db.run(
915
- "UPDATE resolutions SET recurred = 1 WHERE incident_id = ?",
916
- [incidentId]
917
- );
918
- const result = this.db.exec(
919
- "SELECT pattern_id FROM resolutions WHERE incident_id = ?",
920
- [incidentId]
921
- );
922
- if (result.length > 0 && result[0].values.length > 0 && result[0].values[0][0]) {
923
- this.updatePatternConfidence(result[0].values[0][0], "recurred");
924
- }
925
- this.save();
926
- }
927
- getResolutionHistory(options = {}) {
928
- this.initializeSync();
929
- const conditions = [];
930
- const params = [];
931
- if (options.patternId) {
932
- conditions.push("pattern_id = ?");
933
- params.push(options.patternId);
934
- }
935
- if (options.symbol) {
936
- conditions.push(`incident_id IN (
937
- SELECT id FROM incidents WHERE symbols LIKE ?
938
- )`);
939
- params.push(`%${options.symbol}%`);
940
- }
941
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
942
- const limit = options.limit || 100;
943
- const result = this.db.exec(
944
- `SELECT * FROM resolutions ${whereClause} ORDER BY resolved_at DESC LIMIT ?`,
945
- [...params, limit]
946
- );
947
- if (result.length === 0) return [];
948
- const columns = result[0].columns;
949
- return result[0].values.map((row) => {
950
- const obj = {};
951
- columns.forEach((col, i) => {
952
- obj[col] = row[i];
953
- });
954
- return {
955
- id: obj.id,
956
- incidentId: obj.incident_id,
957
- patternId: obj.pattern_id || void 0,
958
- commitHash: obj.commit_hash || void 0,
959
- prUrl: obj.pr_url || void 0,
960
- notes: obj.notes || void 0,
961
- resolvedAt: obj.resolved_at,
962
- recurred: obj.recurred === 1
963
- };
964
- });
965
- }
966
- // ─── Stats ───────────────────────────────────────────────────────
967
- getStats(period) {
968
- this.initializeSync();
969
- const { start, end } = period;
970
- const total = this.getIncidentCount({ dateFrom: start, dateTo: end });
971
- const open = this.getIncidentCount({
972
- dateFrom: start,
973
- dateTo: end,
974
- status: "open"
975
- });
976
- const resolved = this.getIncidentCount({
977
- dateFrom: start,
978
- dateTo: end,
979
- status: "resolved"
980
- });
981
- const envResult = this.db.exec(
982
- `SELECT environment, COUNT(*) as count
983
- FROM incidents
984
- WHERE timestamp >= ? AND timestamp <= ?
985
- GROUP BY environment`,
986
- [start, end]
987
- );
988
- const byEnvironment = {};
989
- if (envResult.length > 0) {
990
- for (const row of envResult[0].values) {
991
- byEnvironment[row[0]] = row[1];
992
- }
993
- }
994
- const dayResult = this.db.exec(
995
- `SELECT DATE(timestamp) as date, COUNT(*) as count
996
- FROM incidents
997
- WHERE timestamp >= ? AND timestamp <= ?
998
- GROUP BY DATE(timestamp)
999
- ORDER BY date`,
1000
- [start, end]
1001
- );
1002
- const byDay = [];
1003
- if (dayResult.length > 0) {
1004
- for (const row of dayResult[0].values) {
1005
- byDay.push({ date: row[0], count: row[1] });
1006
- }
1007
- }
1008
- const patterns = this.getAllPatterns({ includePrivate: true });
1009
- const avgConfidence = patterns.length > 0 ? patterns.reduce((sum, p) => sum + p.confidence.score, 0) / patterns.length : 0;
1010
- const mostEffective = patterns.sort((a, b) => b.confidence.timesResolved - a.confidence.timesResolved).slice(0, 5).map((p) => ({ patternId: p.id, resolvedCount: p.confidence.timesResolved }));
1011
- const leastEffective = patterns.filter((p) => p.confidence.timesMatched > 0).map((p) => ({
1012
- patternId: p.id,
1013
- recurrenceRate: p.confidence.timesRecurred / Math.max(1, p.confidence.timesResolved)
1014
- })).sort((a, b) => b.recurrenceRate - a.recurrenceRate).slice(0, 5);
1015
- const symbolCounts = /* @__PURE__ */ new Map();
1016
- const incidents = this.getRecentIncidents({
1017
- dateFrom: start,
1018
- dateTo: end,
1019
- limit: 1e3
1020
- });
1021
- for (const incident of incidents) {
1022
- for (const [, value] of Object.entries(incident.symbols)) {
1023
- if (value) {
1024
- symbolCounts.set(value, (symbolCounts.get(value) || 0) + 1);
1025
- }
1026
- }
1027
- }
1028
- const mostIncidents = Array.from(symbolCounts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([symbol, count]) => ({ symbol, count }));
1029
- const resolutions = this.getResolutionHistory({ limit: 1e3 });
1030
- const periodResolutions = resolutions.filter(
1031
- (r) => r.resolvedAt >= start && r.resolvedAt <= end
1032
- );
1033
- const resolvedWithPattern = periodResolutions.filter(
1034
- (r) => r.patternId
1035
- ).length;
1036
- const resolvedManually = periodResolutions.length - resolvedWithPattern;
1037
- return {
1038
- period: { start, end },
1039
- incidents: {
1040
- total,
1041
- open,
1042
- resolved,
1043
- byEnvironment,
1044
- byDay
1045
- },
1046
- patterns: {
1047
- total: patterns.length,
1048
- avgConfidence: Math.round(avgConfidence),
1049
- mostEffective,
1050
- leastEffective
1051
- },
1052
- symbols: {
1053
- mostIncidents,
1054
- mostResolved: [],
1055
- hotspots: mostIncidents.slice(0, 5).map((s) => ({
1056
- symbol: s.symbol,
1057
- incidentRate: s.count / Math.max(1, total)
1058
- }))
1059
- },
1060
- resolution: {
1061
- avgTimeToResolve: 0,
1062
- resolvedWithPattern,
1063
- resolvedManually,
1064
- resolutionRate: total > 0 ? resolved / total * 100 : 0
1065
- }
1066
- };
1067
- }
1068
- getSymbolHealth(symbol) {
1069
- const incidents = this.getRecentIncidents({ symbol, limit: 1e3 });
1070
- const incidentCount = incidents.length;
1071
- const patternCounts = /* @__PURE__ */ new Map();
1072
- for (const incident of incidents) {
1073
- if (incident.resolution?.patternId) {
1074
- const count = patternCounts.get(incident.resolution.patternId) || 0;
1075
- patternCounts.set(incident.resolution.patternId, count + 1);
1076
- }
1077
- }
1078
- const topPatterns = Array.from(patternCounts.entries()).sort((a, b) => b[1] - a[1]).slice(0, 5).map(([patternId, count]) => ({ patternId, count }));
1079
- return {
1080
- incidentCount,
1081
- avgTimeToResolve: 0,
1082
- topPatterns
1083
- };
1084
- }
1085
- // ─── Import/Export ───────────────────────────────────────────────
1086
- exportPatterns(options = {}) {
1087
- const patterns = this.getAllPatterns({
1088
- includePrivate: options.includePrivate
1089
- });
1090
- return {
1091
- version: "1.0.0",
1092
- exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
1093
- patterns
1094
- };
1095
- }
1096
- importPatterns(data, options = {}) {
1097
- let imported = 0;
1098
- let skipped = 0;
1099
- for (const pattern of data.patterns) {
1100
- const existing = this.getPattern(pattern.id);
1101
- if (existing && !options.overwrite) {
1102
- skipped++;
1103
- continue;
1104
- }
1105
- if (existing) {
1106
- this.updatePattern(pattern.id, pattern);
1107
- } else {
1108
- this.addPattern({
1109
- ...pattern,
1110
- source: "imported"
1111
- });
1112
- }
1113
- imported++;
1114
- }
1115
- return { imported, skipped };
1116
- }
1117
- exportBackup() {
1118
- const incidents = this.getRecentIncidents({ limit: 1e5 });
1119
- const patterns = this.getAllPatterns({ includePrivate: true });
1120
- const groups = this.getGroups({ limit: 1e4 });
1121
- return {
1122
- version: "1.0.0",
1123
- exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
1124
- incidents,
1125
- patterns,
1126
- groups
1127
- };
1128
- }
1129
- importBackup(data) {
1130
- this.initializeSync();
1131
- this.db.run("DELETE FROM group_members");
1132
- this.db.run("DELETE FROM resolutions");
1133
- this.db.run("DELETE FROM groups");
1134
- this.db.run("DELETE FROM incidents");
1135
- this.db.run("DELETE FROM patterns");
1136
- for (const pattern of data.patterns) {
1137
- this.addPattern(pattern);
1138
- }
1139
- for (const incident of data.incidents) {
1140
- const now2 = incident.timestamp;
1141
- this.db.run(
1142
- `INSERT INTO incidents (
1143
- id, timestamp, status, error_message, error_stack, error_code, error_type,
1144
- symbols, flow_position, environment, service, version, user_id, request_id,
1145
- group_id, notes, related_incidents, resolved_at, resolved_by, resolution,
1146
- created_at, updated_at
1147
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1148
- [
1149
- incident.id,
1150
- incident.timestamp,
1151
- incident.status,
1152
- incident.error.message,
1153
- incident.error.stack || null,
1154
- incident.error.code || null,
1155
- incident.error.type || null,
1156
- JSON.stringify(incident.symbols),
1157
- incident.flowPosition ? JSON.stringify(incident.flowPosition) : null,
1158
- incident.environment,
1159
- incident.service || null,
1160
- incident.version || null,
1161
- incident.userId || null,
1162
- incident.requestId || null,
1163
- incident.groupId || null,
1164
- JSON.stringify(incident.notes),
1165
- JSON.stringify(incident.relatedIncidents),
1166
- incident.resolvedAt || null,
1167
- incident.resolvedBy || null,
1168
- incident.resolution ? JSON.stringify(incident.resolution) : null,
1169
- now2,
1170
- now2
1171
- ]
1172
- );
1173
- }
1174
- const result = this.db.exec(
1175
- "SELECT MAX(CAST(SUBSTR(id, 5) AS INTEGER)) as max FROM incidents"
1176
- );
1177
- if (result.length > 0 && result[0].values.length > 0 && result[0].values[0][0]) {
1178
- this.incidentCounter = result[0].values[0][0];
1179
- }
1180
- const now = (/* @__PURE__ */ new Date()).toISOString();
1181
- for (const group of data.groups) {
1182
- this.db.run(
1183
- `INSERT INTO groups (
1184
- id, name, common_symbols, common_error_patterns,
1185
- suggested_pattern_id, first_seen, last_seen, created_at, updated_at
1186
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1187
- [
1188
- group.id,
1189
- group.name || null,
1190
- JSON.stringify(group.commonSymbols),
1191
- JSON.stringify(group.commonErrorPatterns),
1192
- group.suggestedPattern?.id || null,
1193
- group.firstSeen,
1194
- group.lastSeen,
1195
- now,
1196
- now
1197
- ]
1198
- );
1199
- for (const incidentId of group.incidents) {
1200
- this.db.run(
1201
- "INSERT OR IGNORE INTO group_members (group_id, incident_id, added_at) VALUES (?, ?, ?)",
1202
- [group.id, incidentId, now]
1203
- );
1204
- }
1205
- }
1206
- this.save();
1207
- }
1208
- // ─── Helper Methods ──────────────────────────────────────────────
1209
- rowToIncident(columns, row) {
1210
- const obj = {};
1211
- columns.forEach((col, i) => {
1212
- obj[col] = row[i];
1213
- });
1214
- return {
1215
- id: obj.id,
1216
- timestamp: obj.timestamp,
1217
- status: obj.status,
1218
- error: {
1219
- message: obj.error_message,
1220
- stack: obj.error_stack || void 0,
1221
- code: obj.error_code || void 0,
1222
- type: obj.error_type || void 0
1223
- },
1224
- symbols: JSON.parse(obj.symbols || "{}"),
1225
- flowPosition: obj.flow_position ? JSON.parse(obj.flow_position) : void 0,
1226
- environment: obj.environment,
1227
- service: obj.service || void 0,
1228
- version: obj.version || void 0,
1229
- userId: obj.user_id || void 0,
1230
- requestId: obj.request_id || void 0,
1231
- groupId: obj.group_id || void 0,
1232
- notes: JSON.parse(obj.notes || "[]"),
1233
- relatedIncidents: JSON.parse(obj.related_incidents || "[]"),
1234
- resolvedAt: obj.resolved_at || void 0,
1235
- resolvedBy: obj.resolved_by || void 0,
1236
- resolution: obj.resolution ? JSON.parse(obj.resolution) : void 0
1237
- };
1238
- }
1239
- rowToPattern(columns, row) {
1240
- const obj = {};
1241
- columns.forEach((col, i) => {
1242
- obj[col] = row[i];
1243
- });
1244
- return {
1245
- id: obj.id,
1246
- name: obj.name,
1247
- description: obj.description || "",
1248
- pattern: JSON.parse(obj.pattern),
1249
- resolution: JSON.parse(obj.resolution),
1250
- confidence: JSON.parse(obj.confidence),
1251
- source: obj.source,
1252
- private: obj.private === 1,
1253
- tags: JSON.parse(obj.tags || "[]"),
1254
- createdAt: obj.created_at,
1255
- updatedAt: obj.updated_at
1256
- };
1257
- }
1258
- rowToGroup(columns, row) {
1259
- const obj = {};
1260
- columns.forEach((col, i) => {
1261
- obj[col] = row[i];
1262
- });
1263
- const membersResult = this.db.exec(
1264
- "SELECT incident_id FROM group_members WHERE group_id = ?",
1265
- [obj.id]
1266
- );
1267
- const incidents = [];
1268
- if (membersResult.length > 0) {
1269
- for (const r of membersResult[0].values) {
1270
- incidents.push(r[0]);
1271
- }
1272
- }
1273
- const envResult = this.db.exec(
1274
- `SELECT DISTINCT environment FROM incidents
1275
- WHERE id IN (SELECT incident_id FROM group_members WHERE group_id = ?)`,
1276
- [obj.id]
1277
- );
1278
- const environments = [];
1279
- if (envResult.length > 0) {
1280
- for (const r of envResult[0].values) {
1281
- environments.push(r[0]);
1282
- }
1283
- }
1284
- return {
1285
- id: obj.id,
1286
- name: obj.name || void 0,
1287
- incidents,
1288
- commonSymbols: JSON.parse(obj.common_symbols || "{}"),
1289
- commonErrorPatterns: JSON.parse(
1290
- obj.common_error_patterns || "[]"
1291
- ),
1292
- count: incidents.length,
1293
- firstSeen: obj.first_seen,
1294
- lastSeen: obj.last_seen,
1295
- environments,
1296
- suggestedPattern: obj.suggested_pattern_id ? this.getPattern(obj.suggested_pattern_id) || void 0 : void 0
1297
- };
1298
- }
1299
- // ─── Practice Events ─────────────────────────────────────────────
1300
- recordPracticeEvent(input) {
1301
- this.initializeSync();
1302
- const id = `PE-${uuidv4().substring(0, 8)}`;
1303
- const now = (/* @__PURE__ */ new Date()).toISOString();
1304
- this.db.run(
1305
- `INSERT INTO practice_events (
1306
- id, timestamp, habit_id, habit_category, result,
1307
- engineer, session_id, lore_entry_id, task_description,
1308
- symbols_touched, files_modified, related_incident_id, notes
1309
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1310
- [
1311
- id,
1312
- now,
1313
- input.habitId,
1314
- input.habitCategory,
1315
- input.result,
1316
- input.engineer,
1317
- input.sessionId,
1318
- input.loreEntryId || null,
1319
- input.taskDescription || null,
1320
- JSON.stringify(input.symbolsTouched || []),
1321
- JSON.stringify(input.filesModified || []),
1322
- input.relatedIncidentId || null,
1323
- input.notes || null
1324
- ]
1325
- );
1326
- this.save();
1327
- return id;
1328
- }
1329
- getPracticeEvents(options = {}) {
1330
- this.initializeSync();
1331
- const { limit = 100, offset = 0 } = options;
1332
- const conditions = [];
1333
- const params = [];
1334
- if (options.habitId) {
1335
- conditions.push("habit_id = ?");
1336
- params.push(options.habitId);
1337
- }
1338
- if (options.habitCategory) {
1339
- conditions.push("habit_category = ?");
1340
- params.push(options.habitCategory);
1341
- }
1342
- if (options.result) {
1343
- conditions.push("result = ?");
1344
- params.push(options.result);
1345
- }
1346
- if (options.engineer) {
1347
- conditions.push("engineer = ?");
1348
- params.push(options.engineer);
1349
- }
1350
- if (options.sessionId) {
1351
- conditions.push("session_id = ?");
1352
- params.push(options.sessionId);
1353
- }
1354
- if (options.dateFrom) {
1355
- conditions.push("timestamp >= ?");
1356
- params.push(options.dateFrom);
1357
- }
1358
- if (options.dateTo) {
1359
- conditions.push("timestamp <= ?");
1360
- params.push(options.dateTo);
1361
- }
1362
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1363
- const result = this.db.exec(
1364
- `SELECT * FROM practice_events ${whereClause} ORDER BY timestamp DESC LIMIT ? OFFSET ?`,
1365
- [...params, limit, offset]
1366
- );
1367
- if (result.length === 0) return [];
1368
- return result[0].values.map(
1369
- (row) => this.rowToPracticeEvent(result[0].columns, row)
1370
- );
1371
- }
1372
- getPracticeEventCount(options = {}) {
1373
- this.initializeSync();
1374
- const conditions = [];
1375
- const params = [];
1376
- if (options.habitId) {
1377
- conditions.push("habit_id = ?");
1378
- params.push(options.habitId);
1379
- }
1380
- if (options.habitCategory) {
1381
- conditions.push("habit_category = ?");
1382
- params.push(options.habitCategory);
1383
- }
1384
- if (options.result) {
1385
- conditions.push("result = ?");
1386
- params.push(options.result);
1387
- }
1388
- if (options.engineer) {
1389
- conditions.push("engineer = ?");
1390
- params.push(options.engineer);
1391
- }
1392
- if (options.dateFrom) {
1393
- conditions.push("timestamp >= ?");
1394
- params.push(options.dateFrom);
1395
- }
1396
- if (options.dateTo) {
1397
- conditions.push("timestamp <= ?");
1398
- params.push(options.dateTo);
1399
- }
1400
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1401
- const result = this.db.exec(
1402
- `SELECT COUNT(*) as count FROM practice_events ${whereClause}`,
1403
- params
1404
- );
1405
- if (result.length === 0 || result[0].values.length === 0) return 0;
1406
- return result[0].values[0][0];
1407
- }
1408
- getComplianceRate(options = {}) {
1409
- this.initializeSync();
1410
- const conditions = [];
1411
- const params = [];
1412
- if (options.habitId) {
1413
- conditions.push("habit_id = ?");
1414
- params.push(options.habitId);
1415
- }
1416
- if (options.habitCategory) {
1417
- conditions.push("habit_category = ?");
1418
- params.push(options.habitCategory);
1419
- }
1420
- if (options.engineer) {
1421
- conditions.push("engineer = ?");
1422
- params.push(options.engineer);
1423
- }
1424
- if (options.dateFrom) {
1425
- conditions.push("timestamp >= ?");
1426
- params.push(options.dateFrom);
1427
- }
1428
- if (options.dateTo) {
1429
- conditions.push("timestamp <= ?");
1430
- params.push(options.dateTo);
1431
- }
1432
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1433
- const result = this.db.exec(
1434
- `SELECT result, COUNT(*) as count
1435
- FROM practice_events ${whereClause}
1436
- GROUP BY result`,
1437
- params
1438
- );
1439
- let followed = 0;
1440
- let skipped = 0;
1441
- let partial = 0;
1442
- if (result.length > 0) {
1443
- for (const row of result[0].values) {
1444
- const r = row[0];
1445
- const count = row[1];
1446
- if (r === "followed") followed = count;
1447
- else if (r === "skipped") skipped = count;
1448
- else if (r === "partial") partial = count;
1449
- }
1450
- }
1451
- const total = followed + skipped + partial;
1452
- const rate = total > 0 ? (followed + partial * 0.5) / total * 100 : 100;
1453
- return { total, followed, skipped, partial, rate: Math.round(rate) };
1454
- }
1455
- rowToPracticeEvent(columns, row) {
1456
- const obj = {};
1457
- columns.forEach((col, i) => {
1458
- obj[col] = row[i];
1459
- });
1460
- return {
1461
- id: obj.id,
1462
- timestamp: obj.timestamp,
1463
- habitId: obj.habit_id,
1464
- habitCategory: obj.habit_category,
1465
- result: obj.result,
1466
- engineer: obj.engineer,
1467
- sessionId: obj.session_id,
1468
- loreEntryId: obj.lore_entry_id || void 0,
1469
- taskDescription: obj.task_description || void 0,
1470
- symbolsTouched: JSON.parse(obj.symbols_touched || "[]"),
1471
- filesModified: JSON.parse(obj.files_modified || "[]"),
1472
- relatedIncidentId: obj.related_incident_id || void 0,
1473
- notes: obj.notes || void 0
1474
- };
1475
- }
1476
- // ─── Structured Logs ─────────────────────────────────────────────
1477
- inferSymbolType(symbol) {
1478
- if (symbol.startsWith("#")) return "component";
1479
- if (symbol.startsWith("^")) return "gate";
1480
- if (symbol.startsWith("!")) return "signal";
1481
- if (symbol.startsWith("$")) return "flow";
1482
- if (symbol.startsWith("~")) return "aspect";
1483
- return "raw";
1484
- }
1485
- insertLog(input) {
1486
- this.initializeSync();
1487
- const id = input.id || uuidv4();
1488
- const timestamp = input.timestamp || (/* @__PURE__ */ new Date()).toISOString();
1489
- const symbolType = input.symbolType || this.inferSymbolType(input.symbol);
1490
- this.db.run(
1491
- `INSERT INTO logs (
1492
- id, timestamp, level, symbol, symbol_type, message, data_json,
1493
- service, session_id, correlation_id, duration_ms, environment
1494
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1495
- [
1496
- id,
1497
- timestamp,
1498
- input.level,
1499
- input.symbol,
1500
- symbolType,
1501
- input.message,
1502
- input.data ? JSON.stringify(input.data) : null,
1503
- input.service,
1504
- input.sessionId || null,
1505
- input.correlationId || null,
1506
- input.durationMs ?? null,
1507
- input.environment || null
1508
- ]
1509
- );
1510
- this.save();
1511
- return id;
1512
- }
1513
- insertLogBatch(entries) {
1514
- this.initializeSync();
1515
- let accepted = 0;
1516
- const errors = [];
1517
- for (const input of entries) {
1518
- try {
1519
- const id = input.id || uuidv4();
1520
- const timestamp = input.timestamp || (/* @__PURE__ */ new Date()).toISOString();
1521
- const symbolType = input.symbolType || this.inferSymbolType(input.symbol);
1522
- this.db.run(
1523
- `INSERT INTO logs (
1524
- id, timestamp, level, symbol, symbol_type, message, data_json,
1525
- service, session_id, correlation_id, duration_ms, environment
1526
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1527
- [
1528
- id,
1529
- timestamp,
1530
- input.level,
1531
- input.symbol,
1532
- symbolType,
1533
- input.message,
1534
- input.data ? JSON.stringify(input.data) : null,
1535
- input.service,
1536
- input.sessionId || null,
1537
- input.correlationId || null,
1538
- input.durationMs ?? null,
1539
- input.environment || null
1540
- ]
1541
- );
1542
- accepted++;
1543
- } catch (err) {
1544
- errors.push(err instanceof Error ? err.message : String(err));
1545
- }
1546
- }
1547
- this.save();
1548
- return { accepted, errors };
1549
- }
1550
- queryLogs(options = {}) {
1551
- this.initializeSync();
1552
- const { limit = 100, offset = 0 } = options;
1553
- const conditions = [];
1554
- const params = [];
1555
- if (options.level) {
1556
- conditions.push("level = ?");
1557
- params.push(options.level);
1558
- }
1559
- if (options.symbol) {
1560
- conditions.push("symbol LIKE ?");
1561
- params.push(`%${options.symbol}%`);
1562
- }
1563
- if (options.service) {
1564
- conditions.push("service = ?");
1565
- params.push(options.service);
1566
- }
1567
- if (options.sessionId) {
1568
- conditions.push("session_id = ?");
1569
- params.push(options.sessionId);
1570
- }
1571
- if (options.correlationId) {
1572
- conditions.push("correlation_id = ?");
1573
- params.push(options.correlationId);
1574
- }
1575
- if (options.search) {
1576
- conditions.push("message LIKE ?");
1577
- params.push(`%${options.search}%`);
1578
- }
1579
- if (options.since) {
1580
- conditions.push("timestamp >= ?");
1581
- params.push(options.since);
1582
- }
1583
- if (options.until) {
1584
- conditions.push("timestamp <= ?");
1585
- params.push(options.until);
1586
- }
1587
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1588
- const result = this.db.exec(
1589
- `SELECT * FROM logs ${whereClause} ORDER BY timestamp DESC LIMIT ? OFFSET ?`,
1590
- [...params, limit, offset]
1591
- );
1592
- if (result.length === 0) return [];
1593
- return result[0].values.map(
1594
- (row) => this.rowToLogEntry(result[0].columns, row)
1595
- );
1596
- }
1597
- getLogCount(options = {}) {
1598
- this.initializeSync();
1599
- const conditions = [];
1600
- const params = [];
1601
- if (options.level) {
1602
- conditions.push("level = ?");
1603
- params.push(options.level);
1604
- }
1605
- if (options.symbol) {
1606
- conditions.push("symbol LIKE ?");
1607
- params.push(`%${options.symbol}%`);
1608
- }
1609
- if (options.service) {
1610
- conditions.push("service = ?");
1611
- params.push(options.service);
1612
- }
1613
- if (options.since) {
1614
- conditions.push("timestamp >= ?");
1615
- params.push(options.since);
1616
- }
1617
- if (options.until) {
1618
- conditions.push("timestamp <= ?");
1619
- params.push(options.until);
1620
- }
1621
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1622
- const result = this.db.exec(
1623
- `SELECT COUNT(*) as count FROM logs ${whereClause}`,
1624
- params
1625
- );
1626
- if (result.length === 0 || result[0].values.length === 0) return 0;
1627
- return result[0].values[0][0];
1628
- }
1629
- pruneLogs(maxCount) {
1630
- this.initializeSync();
1631
- if (maxCount <= 0) return 0;
1632
- const currentCount = this.getLogCount();
1633
- if (currentCount <= maxCount) return 0;
1634
- const deleteCount = currentCount - maxCount;
1635
- this.db.run(
1636
- `DELETE FROM logs WHERE id IN (
1637
- SELECT id FROM logs ORDER BY timestamp ASC LIMIT ?
1638
- )`,
1639
- [deleteCount]
1640
- );
1641
- this.save();
1642
- return deleteCount;
1643
- }
1644
- rowToLogEntry(columns, row) {
1645
- const obj = {};
1646
- columns.forEach((col, i) => {
1647
- obj[col] = row[i];
1648
- });
1649
- return {
1650
- id: obj.id,
1651
- timestamp: obj.timestamp,
1652
- level: obj.level,
1653
- symbol: obj.symbol,
1654
- symbolType: obj.symbol_type || "raw",
1655
- message: obj.message,
1656
- data: obj.data_json ? JSON.parse(obj.data_json) : void 0,
1657
- service: obj.service,
1658
- sessionId: obj.session_id || void 0,
1659
- correlationId: obj.correlation_id || void 0,
1660
- durationMs: obj.duration_ms || void 0,
1661
- environment: obj.environment || void 0
1662
- };
1663
- }
1664
- // ─── Service Registry ──────────────────────────────────────────
1665
- registerService(reg) {
1666
- this.initializeSync();
1667
- const now = (/* @__PURE__ */ new Date()).toISOString();
1668
- this.db.run(
1669
- `INSERT INTO services (name, version, pid, started_at, last_seen_at, environment, metadata_json)
1670
- VALUES (?, ?, ?, ?, ?, ?, ?)
1671
- ON CONFLICT(name) DO UPDATE SET
1672
- version = excluded.version,
1673
- pid = excluded.pid,
1674
- last_seen_at = excluded.last_seen_at,
1675
- environment = excluded.environment,
1676
- metadata_json = excluded.metadata_json`,
1677
- [
1678
- reg.name,
1679
- reg.version || null,
1680
- reg.pid ?? null,
1681
- now,
1682
- now,
1683
- reg.environment || null,
1684
- reg.metadata ? JSON.stringify(reg.metadata) : null
1685
- ]
1686
- );
1687
- this.save();
1688
- }
1689
- updateServiceLastSeen(name) {
1690
- this.initializeSync();
1691
- const now = (/* @__PURE__ */ new Date()).toISOString();
1692
- this.db.run(
1693
- "UPDATE services SET last_seen_at = ? WHERE name = ?",
1694
- [now, name]
1695
- );
1696
- this.save();
1697
- }
1698
- getServices() {
1699
- this.initializeSync();
1700
- const result = this.db.exec(
1701
- "SELECT * FROM services ORDER BY last_seen_at DESC"
1702
- );
1703
- if (result.length === 0) return [];
1704
- return result[0].values.map((row) => {
1705
- const obj = {};
1706
- result[0].columns.forEach((col, i) => {
1707
- obj[col] = row[i];
1708
- });
1709
- return {
1710
- name: obj.name,
1711
- version: obj.version || void 0,
1712
- pid: obj.pid || void 0,
1713
- startedAt: obj.started_at,
1714
- lastSeenAt: obj.last_seen_at,
1715
- environment: obj.environment || void 0,
1716
- metadata: obj.metadata_json ? JSON.parse(obj.metadata_json) : void 0
1717
- };
1718
- });
1719
- }
1720
- // ─── App State ──────────────────────────────────────────────────
1721
- upsertAppState(state) {
1722
- this.initializeSync();
1723
- this.db.run(
1724
- `INSERT INTO app_state (service, session_id, timestamp, state_json, active_flows_json, active_gates_json)
1725
- VALUES (?, ?, ?, ?, ?, ?)
1726
- ON CONFLICT(service, session_id) DO UPDATE SET
1727
- timestamp = excluded.timestamp,
1728
- state_json = excluded.state_json,
1729
- active_flows_json = excluded.active_flows_json,
1730
- active_gates_json = excluded.active_gates_json`,
1731
- [
1732
- state.service,
1733
- state.sessionId,
1734
- state.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
1735
- JSON.stringify(state.state),
1736
- state.activeFlows ? JSON.stringify(state.activeFlows) : null,
1737
- state.activeGates ? JSON.stringify(state.activeGates) : null
1738
- ]
1739
- );
1740
- this.save();
1741
- }
1742
- getAppState(service, sessionId) {
1743
- this.initializeSync();
1744
- let query = "SELECT * FROM app_state WHERE service = ?";
1745
- const params = [service];
1746
- if (sessionId) {
1747
- query += " AND session_id = ?";
1748
- params.push(sessionId);
1749
- }
1750
- query += " ORDER BY timestamp DESC";
1751
- const result = this.db.exec(query, params);
1752
- if (result.length === 0) return [];
1753
- return result[0].values.map((row) => this.rowToAppState(result[0].columns, row));
1754
- }
1755
- getAllAppStates() {
1756
- this.initializeSync();
1757
- const result = this.db.exec(
1758
- "SELECT * FROM app_state ORDER BY timestamp DESC"
1759
- );
1760
- if (result.length === 0) return [];
1761
- return result[0].values.map((row) => this.rowToAppState(result[0].columns, row));
1762
- }
1763
- rowToAppState(columns, row) {
1764
- const obj = {};
1765
- columns.forEach((col, i) => {
1766
- obj[col] = row[i];
1767
- });
1768
- return {
1769
- service: obj.service,
1770
- sessionId: obj.session_id,
1771
- timestamp: obj.timestamp,
1772
- state: JSON.parse(obj.state_json),
1773
- activeFlows: obj.active_flows_json ? JSON.parse(obj.active_flows_json) : void 0,
1774
- activeGates: obj.active_gates_json ? JSON.parse(obj.active_gates_json) : void 0
1775
- };
1776
- }
1777
- // ─── Metrics ───────────────────────────────────────────────────
1778
- insertMetric(input) {
1779
- this.initializeSync();
1780
- const id = uuidv4();
1781
- const timestamp = input.timestamp || (/* @__PURE__ */ new Date()).toISOString();
1782
- this.db.run(
1783
- `INSERT INTO metrics (
1784
- id, timestamp, name, type, value, tags_json, service, environment
1785
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
1786
- [
1787
- id,
1788
- timestamp,
1789
- input.name,
1790
- input.type,
1791
- input.value,
1792
- JSON.stringify(input.tags || {}),
1793
- input.service,
1794
- input.environment || null
1795
- ]
1796
- );
1797
- this.save();
1798
- return id;
1799
- }
1800
- insertMetricBatch(entries) {
1801
- this.initializeSync();
1802
- let accepted = 0;
1803
- const errors = [];
1804
- for (const input of entries) {
1805
- try {
1806
- const id = uuidv4();
1807
- const timestamp = input.timestamp || (/* @__PURE__ */ new Date()).toISOString();
1808
- this.db.run(
1809
- `INSERT INTO metrics (
1810
- id, timestamp, name, type, value, tags_json, service, environment
1811
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
1812
- [
1813
- id,
1814
- timestamp,
1815
- input.name,
1816
- input.type,
1817
- input.value,
1818
- JSON.stringify(input.tags || {}),
1819
- input.service,
1820
- input.environment || null
1821
- ]
1822
- );
1823
- accepted++;
1824
- } catch (err) {
1825
- errors.push(err instanceof Error ? err.message : String(err));
1826
- }
1827
- }
1828
- this.save();
1829
- return { accepted, errors };
1830
- }
1831
- queryMetrics(options = {}) {
1832
- this.initializeSync();
1833
- const { limit = 100, offset = 0 } = options;
1834
- const conditions = [];
1835
- const params = [];
1836
- if (options.name) {
1837
- conditions.push("name = ?");
1838
- params.push(options.name);
1839
- }
1840
- if (options.type) {
1841
- conditions.push("type = ?");
1842
- params.push(options.type);
1843
- }
1844
- if (options.service) {
1845
- conditions.push("service = ?");
1846
- params.push(options.service);
1847
- }
1848
- if (options.tag) {
1849
- const eqIdx = options.tag.indexOf("=");
1850
- if (eqIdx > 0) {
1851
- const tagKey = options.tag.substring(0, eqIdx);
1852
- const tagValue = options.tag.substring(eqIdx + 1);
1853
- conditions.push("tags_json LIKE ?");
1854
- params.push(`%"${tagKey}":"${tagValue}"%`);
1855
- }
1856
- }
1857
- if (options.since) {
1858
- conditions.push("timestamp >= ?");
1859
- params.push(options.since);
1860
- }
1861
- if (options.until) {
1862
- conditions.push("timestamp <= ?");
1863
- params.push(options.until);
1864
- }
1865
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1866
- const result = this.db.exec(
1867
- `SELECT * FROM metrics ${whereClause} ORDER BY timestamp DESC LIMIT ? OFFSET ?`,
1868
- [...params, limit, offset]
1869
- );
1870
- if (result.length === 0) return [];
1871
- return result[0].values.map(
1872
- (row) => this.rowToMetricEntry(result[0].columns, row)
1873
- );
1874
- }
1875
- getMetricCount(options = {}) {
1876
- this.initializeSync();
1877
- const conditions = [];
1878
- const params = [];
1879
- if (options.name) {
1880
- conditions.push("name = ?");
1881
- params.push(options.name);
1882
- }
1883
- if (options.type) {
1884
- conditions.push("type = ?");
1885
- params.push(options.type);
1886
- }
1887
- if (options.service) {
1888
- conditions.push("service = ?");
1889
- params.push(options.service);
1890
- }
1891
- if (options.tag) {
1892
- const eqIdx = options.tag.indexOf("=");
1893
- if (eqIdx > 0) {
1894
- const tagKey = options.tag.substring(0, eqIdx);
1895
- const tagValue = options.tag.substring(eqIdx + 1);
1896
- conditions.push("tags_json LIKE ?");
1897
- params.push(`%"${tagKey}":"${tagValue}"%`);
1898
- }
1899
- }
1900
- if (options.since) {
1901
- conditions.push("timestamp >= ?");
1902
- params.push(options.since);
1903
- }
1904
- if (options.until) {
1905
- conditions.push("timestamp <= ?");
1906
- params.push(options.until);
1907
- }
1908
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1909
- const result = this.db.exec(
1910
- `SELECT COUNT(*) as count FROM metrics ${whereClause}`,
1911
- params
1912
- );
1913
- if (result.length === 0 || result[0].values.length === 0) return 0;
1914
- return result[0].values[0][0];
1915
- }
1916
- aggregateMetric(name, options) {
1917
- this.initializeSync();
1918
- const conditions = ["name = ?"];
1919
- const params = [name];
1920
- if (options?.service) {
1921
- conditions.push("service = ?");
1922
- params.push(options.service);
1923
- }
1924
- if (options?.since) {
1925
- conditions.push("timestamp >= ?");
1926
- params.push(options.since);
1927
- }
1928
- if (options?.until) {
1929
- conditions.push("timestamp <= ?");
1930
- params.push(options.until);
1931
- }
1932
- const whereClause = `WHERE ${conditions.join(" AND ")}`;
1933
- const result = this.db.exec(
1934
- `SELECT COUNT(*) as count, SUM(value) as sum, MIN(value) as min, MAX(value) as max, AVG(value) as avg
1935
- FROM metrics ${whereClause}`,
1936
- params
1937
- );
1938
- if (result.length === 0 || result[0].values.length === 0) {
1939
- return { name, count: 0, sum: 0, min: 0, max: 0, avg: 0 };
1940
- }
1941
- const row = result[0].values[0];
1942
- return {
1943
- name,
1944
- count: row[0] || 0,
1945
- sum: row[1] || 0,
1946
- min: row[2] || 0,
1947
- max: row[3] || 0,
1948
- avg: row[4] || 0
1949
- };
1950
- }
1951
- pruneMetrics(maxCount) {
1952
- this.initializeSync();
1953
- if (maxCount <= 0) return 0;
1954
- const currentCount = this.getMetricCount();
1955
- if (currentCount <= maxCount) return 0;
1956
- const deleteCount = currentCount - maxCount;
1957
- this.db.run(
1958
- `DELETE FROM metrics WHERE id IN (
1959
- SELECT id FROM metrics ORDER BY timestamp ASC LIMIT ?
1960
- )`,
1961
- [deleteCount]
1962
- );
1963
- this.save();
1964
- return deleteCount;
1965
- }
1966
- rowToMetricEntry(columns, row) {
1967
- const obj = {};
1968
- columns.forEach((col, i) => {
1969
- obj[col] = row[i];
1970
- });
1971
- return {
1972
- id: obj.id,
1973
- timestamp: obj.timestamp,
1974
- name: obj.name,
1975
- type: obj.type,
1976
- value: obj.value,
1977
- tags: obj.tags_json ? JSON.parse(obj.tags_json) : {},
1978
- service: obj.service,
1979
- environment: obj.environment || void 0
1980
- };
1981
- }
1982
- // ─── Traces ───────────────────────────────────────────────────
1983
- insertSpan(input) {
1984
- this.initializeSync();
1985
- const spanId = input.spanId || uuidv4();
1986
- const startTime = input.startTime || (/* @__PURE__ */ new Date()).toISOString();
1987
- this.db.run(
1988
- `INSERT INTO traces (
1989
- trace_id, span_id, parent_span_id, service, symbol, operation,
1990
- start_time, end_time, duration_ms, status, tags_json, log_ids_json
1991
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1992
- [
1993
- input.traceId,
1994
- spanId,
1995
- input.parentSpanId || null,
1996
- input.service,
1997
- input.symbol,
1998
- input.operation,
1999
- startTime,
2000
- input.endTime || null,
2001
- input.durationMs ?? null,
2002
- input.status || "ok",
2003
- JSON.stringify(input.tags || {}),
2004
- JSON.stringify(input.logIds || [])
2005
- ]
2006
- );
2007
- this.save();
2008
- return spanId;
2009
- }
2010
- getTrace(traceId) {
2011
- this.initializeSync();
2012
- const result = this.db.exec(
2013
- "SELECT * FROM traces WHERE trace_id = ? ORDER BY start_time ASC",
2014
- [traceId]
2015
- );
2016
- if (result.length === 0 || result[0].values.length === 0) return null;
2017
- const spans = result[0].values.map(
2018
- (row) => this.rowToTraceSpan(result[0].columns, row)
2019
- );
2020
- const services = [...new Set(spans.map((s) => s.service))];
2021
- const startTimes = spans.map((s) => s.startTime);
2022
- const endTimes = spans.filter((s) => s.endTime).map((s) => s.endTime);
2023
- const startTime = startTimes.sort()[0];
2024
- const endTime = endTimes.length > 0 ? endTimes.sort().reverse()[0] : startTime;
2025
- const startMs = new Date(startTime).getTime();
2026
- const endMs = new Date(endTime).getTime();
2027
- const totalDurationMs = endMs - startMs;
2028
- return {
2029
- traceId,
2030
- spans,
2031
- services,
2032
- totalDurationMs: totalDurationMs > 0 ? totalDurationMs : 0,
2033
- startTime,
2034
- endTime
2035
- };
2036
- }
2037
- queryTraces(options = {}) {
2038
- this.initializeSync();
2039
- const conditions = [];
2040
- const params = [];
2041
- if (options.service) {
2042
- conditions.push("service = ?");
2043
- params.push(options.service);
2044
- }
2045
- if (options.symbol) {
2046
- conditions.push("symbol = ?");
2047
- params.push(options.symbol);
2048
- }
2049
- if (options.since) {
2050
- conditions.push("start_time >= ?");
2051
- params.push(options.since);
2052
- }
2053
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2054
- const traceLimit = Math.min(options.limit || 20, 20);
2055
- const result = this.db.exec(
2056
- `SELECT DISTINCT trace_id FROM traces ${whereClause} ORDER BY start_time DESC LIMIT ?`,
2057
- [...params, traceLimit]
2058
- );
2059
- if (result.length === 0) return [];
2060
- const traces = [];
2061
- for (const row of result[0].values) {
2062
- const traceId = row[0];
2063
- const trace = this.getTrace(traceId);
2064
- if (trace) {
2065
- traces.push(trace);
2066
- }
2067
- }
2068
- return traces;
2069
- }
2070
- rowToTraceSpan(columns, row) {
2071
- const obj = {};
2072
- columns.forEach((col, i) => {
2073
- obj[col] = row[i];
2074
- });
2075
- return {
2076
- traceId: obj.trace_id,
2077
- spanId: obj.span_id,
2078
- parentSpanId: obj.parent_span_id || void 0,
2079
- service: obj.service,
2080
- symbol: obj.symbol,
2081
- operation: obj.operation,
2082
- startTime: obj.start_time,
2083
- endTime: obj.end_time || void 0,
2084
- durationMs: obj.duration_ms || void 0,
2085
- status: obj.status || "ok",
2086
- tags: obj.tags_json ? JSON.parse(obj.tags_json) : {},
2087
- logs: obj.log_ids_json ? JSON.parse(obj.log_ids_json) : []
2088
- };
2089
- }
2090
- // ─── Schema Registry ─────────────────────────────────────────────
2091
- registerSchema(schema) {
2092
- this.initializeSync();
2093
- const now = (/* @__PURE__ */ new Date()).toISOString();
2094
- this.db.run(
2095
- `INSERT INTO schemas (
2096
- id, version, name, description, scope_json, event_types_json,
2097
- causality_json, visualization_json, tags_json, registered_at, updated_at
2098
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2099
- ON CONFLICT(id) DO UPDATE SET
2100
- version = excluded.version,
2101
- name = excluded.name,
2102
- description = excluded.description,
2103
- scope_json = excluded.scope_json,
2104
- event_types_json = excluded.event_types_json,
2105
- causality_json = excluded.causality_json,
2106
- visualization_json = excluded.visualization_json,
2107
- tags_json = excluded.tags_json,
2108
- updated_at = excluded.updated_at`,
2109
- [
2110
- schema.id,
2111
- schema.version,
2112
- schema.name,
2113
- schema.description || null,
2114
- JSON.stringify(schema.scope),
2115
- JSON.stringify(schema.eventTypes),
2116
- schema.causality ? JSON.stringify(schema.causality) : null,
2117
- schema.visualization ? JSON.stringify(schema.visualization) : null,
2118
- JSON.stringify(schema.tags || []),
2119
- now,
2120
- now
2121
- ]
2122
- );
2123
- this.save();
2124
- return {
2125
- id: schema.id,
2126
- version: schema.version,
2127
- name: schema.name,
2128
- description: schema.description,
2129
- scope: schema.scope,
2130
- eventTypes: schema.eventTypes,
2131
- causality: schema.causality,
2132
- visualization: schema.visualization,
2133
- tags: schema.tags || [],
2134
- registeredAt: now,
2135
- updatedAt: now
2136
- };
2137
- }
2138
- getSchema(id) {
2139
- this.initializeSync();
2140
- const result = this.db.exec("SELECT * FROM schemas WHERE id = ?", [id]);
2141
- if (result.length === 0 || result[0].values.length === 0) return null;
2142
- return this.rowToSchema(result[0].columns, result[0].values[0]);
2143
- }
2144
- listSchemas() {
2145
- this.initializeSync();
2146
- const result = this.db.exec("SELECT * FROM schemas ORDER BY name ASC");
2147
- if (result.length === 0) return [];
2148
- return result[0].values.map(
2149
- (row) => this.rowToSchema(result[0].columns, row)
2150
- );
2151
- }
2152
- rowToSchema(columns, row) {
2153
- const obj = {};
2154
- columns.forEach((col, i) => {
2155
- obj[col] = row[i];
2156
- });
2157
- return {
2158
- id: obj.id,
2159
- version: obj.version,
2160
- name: obj.name,
2161
- description: obj.description || void 0,
2162
- scope: JSON.parse(obj.scope_json),
2163
- eventTypes: JSON.parse(obj.event_types_json),
2164
- causality: obj.causality_json ? JSON.parse(obj.causality_json) : void 0,
2165
- visualization: obj.visualization_json ? JSON.parse(obj.visualization_json) : void 0,
2166
- tags: JSON.parse(obj.tags_json || "[]"),
2167
- registeredAt: obj.registered_at,
2168
- updatedAt: obj.updated_at
2169
- };
2170
- }
2171
- // ─── Generic Events ────────────────────────────────────────────
2172
- insertEventBatch(schemaId, service, inputs) {
2173
- this.initializeSync();
2174
- const schema = this.getSchema(schemaId);
2175
- const typeMap = /* @__PURE__ */ new Map();
2176
- if (schema) {
2177
- for (const et of schema.eventTypes) {
2178
- typeMap.set(et.type, {
2179
- category: et.category,
2180
- severity: et.severity || "info"
2181
- });
2182
- }
2183
- }
2184
- let accepted = 0;
2185
- const errors = [];
2186
- for (const input of inputs) {
2187
- try {
2188
- const id = input.id || uuidv4();
2189
- const timestamp = input.timestamp || (/* @__PURE__ */ new Date()).toISOString();
2190
- const resolved = typeMap.get(input.type);
2191
- const category = resolved?.category || "unknown";
2192
- const severity = input.severity || resolved?.severity || "info";
2193
- const scopeValue = input.scopeValue != null ? String(input.scopeValue) : null;
2194
- const scopeOrdinal = typeof input.scopeValue === "number" ? input.scopeValue : null;
2195
- this.db.run(
2196
- `INSERT INTO events (
2197
- id, schema_id, event_type, category, timestamp, scope_value,
2198
- scope_ordinal, session_id, service, data_json, severity,
2199
- parent_event_id, depth
2200
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
2201
- [
2202
- id,
2203
- schemaId,
2204
- input.type,
2205
- category,
2206
- timestamp,
2207
- scopeValue,
2208
- scopeOrdinal,
2209
- input.sessionId || null,
2210
- service,
2211
- input.data ? JSON.stringify(input.data) : null,
2212
- severity,
2213
- input.parentEventId || null,
2214
- input.depth ?? 0
2215
- ]
2216
- );
2217
- accepted++;
2218
- } catch (err) {
2219
- errors.push(err instanceof Error ? err.message : String(err));
2220
- }
2221
- }
2222
- this.save();
2223
- return { accepted, errors };
2224
- }
2225
- queryEvents(options = {}) {
2226
- this.initializeSync();
2227
- const { limit = 100, offset = 0 } = options;
2228
- const conditions = [];
2229
- const params = [];
2230
- if (options.schemaId) {
2231
- conditions.push("schema_id = ?");
2232
- params.push(options.schemaId);
2233
- }
2234
- if (options.eventType) {
2235
- conditions.push("event_type = ?");
2236
- params.push(options.eventType);
2237
- }
2238
- if (options.category) {
2239
- conditions.push("category = ?");
2240
- params.push(options.category);
2241
- }
2242
- if (options.service) {
2243
- conditions.push("service = ?");
2244
- params.push(options.service);
2245
- }
2246
- if (options.sessionId) {
2247
- conditions.push("session_id = ?");
2248
- params.push(options.sessionId);
2249
- }
2250
- if (options.scopeValue) {
2251
- conditions.push("scope_value = ?");
2252
- params.push(options.scopeValue);
2253
- }
2254
- if (options.scopeFrom) {
2255
- conditions.push("scope_value >= ?");
2256
- params.push(options.scopeFrom);
2257
- }
2258
- if (options.scopeTo) {
2259
- conditions.push("scope_value <= ?");
2260
- params.push(options.scopeTo);
2261
- }
2262
- if (options.severity) {
2263
- conditions.push("severity = ?");
2264
- params.push(options.severity);
2265
- }
2266
- if (options.since) {
2267
- conditions.push("timestamp >= ?");
2268
- params.push(options.since);
2269
- }
2270
- if (options.until) {
2271
- conditions.push("timestamp <= ?");
2272
- params.push(options.until);
2273
- }
2274
- if (options.search) {
2275
- conditions.push("data_json LIKE ?");
2276
- params.push(`%${options.search}%`);
2277
- }
2278
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2279
- const result = this.db.exec(
2280
- `SELECT * FROM events ${whereClause} ORDER BY timestamp DESC LIMIT ? OFFSET ?`,
2281
- [...params, limit, offset]
2282
- );
2283
- if (result.length === 0) return [];
2284
- return result[0].values.map(
2285
- (row) => this.rowToGenericEvent(result[0].columns, row)
2286
- );
2287
- }
2288
- queryEventsByScope(schemaId, scopeValue) {
2289
- this.initializeSync();
2290
- const result = this.db.exec(
2291
- `SELECT * FROM events
2292
- WHERE schema_id = ? AND scope_value = ?
2293
- ORDER BY timestamp ASC`,
2294
- [schemaId, scopeValue]
2295
- );
2296
- if (result.length === 0) return [];
2297
- return result[0].values.map(
2298
- (row) => this.rowToGenericEvent(result[0].columns, row)
2299
- );
2300
- }
2301
- getEventScopes(schemaId, options = {}) {
2302
- this.initializeSync();
2303
- const { limit = 100, offset = 0 } = options;
2304
- const conditions = ["schema_id = ?"];
2305
- const params = [schemaId];
2306
- if (options.sessionId) {
2307
- conditions.push("session_id = ?");
2308
- params.push(options.sessionId);
2309
- }
2310
- const whereClause = `WHERE ${conditions.join(" AND ")}`;
2311
- const result = this.db.exec(
2312
- `SELECT
2313
- scope_value,
2314
- MIN(scope_ordinal) as scope_ordinal,
2315
- COUNT(*) as event_count,
2316
- MIN(timestamp) as first_timestamp,
2317
- MAX(timestamp) as last_timestamp
2318
- FROM events
2319
- ${whereClause}
2320
- AND scope_value IS NOT NULL
2321
- GROUP BY scope_value
2322
- ORDER BY MIN(COALESCE(scope_ordinal, 0)) DESC, MIN(timestamp) DESC
2323
- LIMIT ? OFFSET ?`,
2324
- [...params, limit, offset]
2325
- );
2326
- if (result.length === 0) return [];
2327
- const scopes = [];
2328
- for (const row of result[0].values) {
2329
- const scopeValue = row[0];
2330
- const scopeOrdinal = row[1] != null ? row[1] : void 0;
2331
- const eventCount = row[2];
2332
- const firstTimestamp = row[3];
2333
- const lastTimestamp = row[4];
2334
- const catResult = this.db.exec(
2335
- `SELECT category, COUNT(*) as count FROM events
2336
- WHERE schema_id = ? AND scope_value = ?
2337
- GROUP BY category`,
2338
- [schemaId, scopeValue]
2339
- );
2340
- const categories = {};
2341
- if (catResult.length > 0) {
2342
- for (const catRow of catResult[0].values) {
2343
- categories[catRow[0]] = catRow[1];
2344
- }
2345
- }
2346
- scopes.push({
2347
- scopeValue,
2348
- scopeOrdinal,
2349
- eventCount,
2350
- categories,
2351
- firstTimestamp,
2352
- lastTimestamp
2353
- });
2354
- }
2355
- return scopes;
2356
- }
2357
- getEventCount(options = {}) {
2358
- this.initializeSync();
2359
- const conditions = [];
2360
- const params = [];
2361
- if (options.schemaId) {
2362
- conditions.push("schema_id = ?");
2363
- params.push(options.schemaId);
2364
- }
2365
- if (options.eventType) {
2366
- conditions.push("event_type = ?");
2367
- params.push(options.eventType);
2368
- }
2369
- if (options.service) {
2370
- conditions.push("service = ?");
2371
- params.push(options.service);
2372
- }
2373
- if (options.since) {
2374
- conditions.push("timestamp >= ?");
2375
- params.push(options.since);
2376
- }
2377
- if (options.until) {
2378
- conditions.push("timestamp <= ?");
2379
- params.push(options.until);
2380
- }
2381
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2382
- const result = this.db.exec(
2383
- `SELECT COUNT(*) as count FROM events ${whereClause}`,
2384
- params
2385
- );
2386
- if (result.length === 0 || result[0].values.length === 0) return 0;
2387
- return result[0].values[0][0];
2388
- }
2389
- pruneEvents(maxCount) {
2390
- this.initializeSync();
2391
- if (maxCount <= 0) return 0;
2392
- const currentCount = this.getEventCount();
2393
- if (currentCount <= maxCount) return 0;
2394
- const deleteCount = currentCount - maxCount;
2395
- this.db.run(
2396
- `DELETE FROM events WHERE id IN (
2397
- SELECT id FROM events ORDER BY timestamp ASC LIMIT ?
2398
- )`,
2399
- [deleteCount]
2400
- );
2401
- this.save();
2402
- return deleteCount;
2403
- }
2404
- rowToGenericEvent(columns, row) {
2405
- const obj = {};
2406
- columns.forEach((col, i) => {
2407
- obj[col] = row[i];
2408
- });
2409
- return {
2410
- id: obj.id,
2411
- schemaId: obj.schema_id,
2412
- eventType: obj.event_type,
2413
- category: obj.category,
2414
- timestamp: obj.timestamp,
2415
- scopeValue: obj.scope_value || void 0,
2416
- scopeOrdinal: obj.scope_ordinal != null ? obj.scope_ordinal : void 0,
2417
- sessionId: obj.session_id || void 0,
2418
- service: obj.service,
2419
- data: obj.data_json ? JSON.parse(obj.data_json) : void 0,
2420
- severity: obj.severity || "info",
2421
- parentEventId: obj.parent_event_id || void 0,
2422
- depth: obj.depth || 0
2423
- };
2424
- }
2425
- close() {
2426
- if (this.db) {
2427
- this.save();
2428
- this.db.close();
2429
- this.db = null;
2430
- }
2431
- }
2432
- };
2433
- var DEFAULT_AUTH_CONFIG = {
2434
- enabled: false,
2435
- tokens: []
2436
- };
2437
- var DEFAULT_RATE_LIMIT_CONFIG = {
2438
- enabled: false,
2439
- global: {
2440
- maxRequestsPerMinute: 600,
2441
- maxEntriesPerBatch: 500,
2442
- samplingRate: 1
2443
- },
2444
- perService: {}
2445
- };
2446
- var DEFAULT_SERVER_CONFIG = {
2447
- port: 3838,
2448
- maxLogs: 1e4,
2449
- maxBatchSize: 500,
2450
- wsMaxSubscribers: 256,
2451
- pruneIntervalInserts: 100,
2452
- logRetentionDays: 0,
2453
- auth: DEFAULT_AUTH_CONFIG,
2454
- rateLimit: DEFAULT_RATE_LIMIT_CONFIG
2455
- };
2456
- var CONFIG_FILES = [".sentinel.yaml", ".sentinel.yml"];
2457
- function loadConfig(projectDir) {
2458
- for (const filename of CONFIG_FILES) {
2459
- const filePath = path2.join(projectDir, filename);
2460
- if (fs2.existsSync(filePath)) {
2461
- const content = fs2.readFileSync(filePath, "utf-8");
2462
- return parseSimpleYaml(content);
2463
- }
2464
- }
2465
- return null;
2466
- }
2467
- function writeConfig(projectDir, config) {
2468
- const filePath = path2.join(projectDir, ".sentinel.yaml");
2469
- const content = serializeSimpleYaml(config);
2470
- fs2.writeFileSync(filePath, content, "utf-8");
2471
- }
2472
- function parseSimpleYaml(content) {
2473
- const config = { version: "1.0", project: "" };
2474
- const lines = content.split("\n");
2475
- let currentSection = null;
2476
- let currentSubSection = null;
2477
- for (const line of lines) {
2478
- const trimmed = line.trimEnd();
2479
- if (!trimmed || trimmed.startsWith("#")) continue;
2480
- const topMatch = trimmed.match(/^(\w+):\s*(.+)$/);
2481
- if (topMatch) {
2482
- const [, key, value] = topMatch;
2483
- if (key === "version") config.version = value.replace(/['"]/g, "");
2484
- else if (key === "project") config.project = value.replace(/['"]/g, "");
2485
- else if (key === "environment") config.environment = value.replace(/['"]/g, "");
2486
- currentSection = null;
2487
- currentSubSection = null;
2488
- continue;
2489
- }
2490
- const sectionMatch = trimmed.match(/^(\w+):$/);
2491
- if (sectionMatch) {
2492
- currentSection = sectionMatch[1];
2493
- currentSubSection = null;
2494
- if (currentSection === "symbols" && !config.symbols) {
2495
- config.symbols = {};
2496
- }
2497
- if (currentSection === "routes" && !config.routes) {
2498
- config.routes = {};
2499
- }
2500
- if (currentSection === "scrub" && !config.scrub) {
2501
- config.scrub = {};
2502
- }
2503
- if (currentSection === "server" && !config.server) {
2504
- config.server = {};
2505
- }
2506
- continue;
2507
- }
2508
- const subMatch = trimmed.match(/^\s{2}(\w+):$/);
2509
- if (subMatch && currentSection) {
2510
- currentSubSection = subMatch[1];
2511
- if (currentSection === "symbols" && config.symbols) {
2512
- config.symbols[currentSubSection] = [];
2513
- }
2514
- if (currentSection === "scrub" && config.scrub) {
2515
- config.scrub[currentSubSection] = [];
2516
- }
2517
- continue;
2518
- }
2519
- const listMatch = trimmed.match(/^\s+-\s+(.+)$/);
2520
- if (listMatch && currentSection && currentSubSection) {
2521
- const value = listMatch[1].replace(/['"]/g, "");
2522
- if (currentSection === "symbols" && config.symbols) {
2523
- const arr = config.symbols[currentSubSection];
2524
- if (Array.isArray(arr)) arr.push(value);
2525
- }
2526
- if (currentSection === "scrub" && config.scrub) {
2527
- const arr = config.scrub[currentSubSection];
2528
- if (Array.isArray(arr)) arr.push(value);
2529
- }
2530
- continue;
2531
- }
2532
- const routeMatch = trimmed.match(/^\s+(['"]?\/[^'"]+['"]?):\s+['"]?([^'"]+)['"]?$/);
2533
- if (routeMatch && currentSection === "routes" && config.routes) {
2534
- const route = routeMatch[1].replace(/['"]/g, "");
2535
- config.routes[route] = routeMatch[2];
2536
- continue;
2537
- }
2538
- const serverKvMatch = trimmed.match(/^\s+(\w+):\s+(\d+)$/);
2539
- if (serverKvMatch && currentSection === "server" && config.server) {
2540
- const key = serverKvMatch[1];
2541
- const value = parseInt(serverKvMatch[2], 10);
2542
- if (key in { port: 1, maxLogs: 1, maxBatchSize: 1, wsMaxSubscribers: 1, pruneIntervalInserts: 1, logRetentionDays: 1 }) {
2543
- config.server[key] = value;
2544
- }
2545
- continue;
2546
- }
2547
- }
2548
- return config;
2549
- }
2550
- function serializeSimpleYaml(config) {
2551
- const lines = [];
2552
- lines.push(`# Sentinel Configuration`);
2553
- lines.push(`# Auto-generated \u2014 edit freely`);
2554
- lines.push("");
2555
- lines.push(`version: "${config.version}"`);
2556
- lines.push(`project: "${config.project}"`);
2557
- if (config.environment) {
2558
- lines.push(`environment: "${config.environment}"`);
2559
- }
2560
- if (config.symbols) {
2561
- lines.push("");
2562
- lines.push("symbols:");
2563
- for (const [key, values] of Object.entries(config.symbols)) {
2564
- if (values && values.length > 0) {
2565
- lines.push(` ${key}:`);
2566
- for (const v of values) {
2567
- lines.push(` - ${v}`);
2568
- }
2569
- }
2570
- }
2571
- }
2572
- if (config.routes && Object.keys(config.routes).length > 0) {
2573
- lines.push("");
2574
- lines.push("routes:");
2575
- for (const [route, symbol] of Object.entries(config.routes)) {
2576
- lines.push(` "${route}": ${symbol}`);
2577
- }
2578
- }
2579
- if (config.scrub) {
2580
- lines.push("");
2581
- lines.push("scrub:");
2582
- if (config.scrub.headers?.length) {
2583
- lines.push(" headers:");
2584
- for (const h of config.scrub.headers) {
2585
- lines.push(` - ${h}`);
2586
- }
2587
- }
2588
- if (config.scrub.fields?.length) {
2589
- lines.push(" fields:");
2590
- for (const f of config.scrub.fields) {
2591
- lines.push(` - ${f}`);
2592
- }
2593
- }
2594
- }
2595
- if (config.server && Object.keys(config.server).length > 0) {
2596
- lines.push("");
2597
- lines.push("server:");
2598
- for (const [key, value] of Object.entries(config.server)) {
2599
- if (value !== void 0) {
2600
- lines.push(` ${key}: ${value}`);
2601
- }
2602
- }
2603
- }
2604
- lines.push("");
2605
- return lines.join("\n");
2606
- }
2607
- function loadServerConfig(projectDir) {
2608
- const config = { ...DEFAULT_SERVER_CONFIG };
2609
- const yamlConfig = projectDir ? loadConfig(projectDir) : null;
2610
- const globalDir = path2.join(process.env.HOME || "~", ".paradigm");
2611
- const globalConfig = loadConfig(globalDir);
2612
- for (const src of [globalConfig, yamlConfig]) {
2613
- if (src?.server) {
2614
- if (src.server.port !== void 0) config.port = src.server.port;
2615
- if (src.server.maxLogs !== void 0) config.maxLogs = src.server.maxLogs;
2616
- if (src.server.maxBatchSize !== void 0) config.maxBatchSize = src.server.maxBatchSize;
2617
- if (src.server.wsMaxSubscribers !== void 0) config.wsMaxSubscribers = src.server.wsMaxSubscribers;
2618
- if (src.server.pruneIntervalInserts !== void 0) config.pruneIntervalInserts = src.server.pruneIntervalInserts;
2619
- if (src.server.logRetentionDays !== void 0) config.logRetentionDays = src.server.logRetentionDays;
2620
- }
2621
- }
2622
- if (process.env.SENTINEL_PORT) config.port = parseInt(process.env.SENTINEL_PORT, 10);
2623
- if (process.env.SENTINEL_MAX_LOGS) config.maxLogs = parseInt(process.env.SENTINEL_MAX_LOGS, 10);
2624
- return config;
2625
- }
2626
- var PARADIGM_SCHEMA = {
2627
- id: "paradigm-logger",
2628
- version: "1.0.0",
2629
- name: "Paradigm Logger",
2630
- description: "Structured logs from @a-company/paradigm-logger with symbolic context",
2631
- scope: {
2632
- field: "correlationId",
2633
- type: "string",
2634
- label: "Correlation",
2635
- ordering: "independent",
2636
- sessionField: "sessionId"
2637
- },
2638
- eventTypes: [
2639
- {
2640
- type: "log:debug",
2641
- category: "logs",
2642
- label: "Debug Log",
2643
- severity: "debug",
2644
- frequency: "high",
2645
- fields: [
2646
- { name: "symbol", type: "string", indexed: true, display: true },
2647
- { name: "symbolType", type: "string", indexed: true, display: true },
2648
- { name: "message", type: "string", display: true },
2649
- { name: "service", type: "string", indexed: true, display: true },
2650
- { name: "durationMs", type: "number", display: true }
2651
- ]
2652
- },
2653
- {
2654
- type: "log:info",
2655
- category: "logs",
2656
- label: "Info Log",
2657
- severity: "info",
2658
- frequency: "high",
2659
- fields: [
2660
- { name: "symbol", type: "string", indexed: true, display: true },
2661
- { name: "symbolType", type: "string", indexed: true, display: true },
2662
- { name: "message", type: "string", display: true },
2663
- { name: "service", type: "string", indexed: true, display: true },
2664
- { name: "durationMs", type: "number", display: true }
2665
- ]
2666
- },
2667
- {
2668
- type: "log:warn",
2669
- category: "logs",
2670
- label: "Warning Log",
2671
- severity: "warn",
2672
- frequency: "medium",
2673
- fields: [
2674
- { name: "symbol", type: "string", indexed: true, display: true },
2675
- { name: "symbolType", type: "string", indexed: true, display: true },
2676
- { name: "message", type: "string", display: true },
2677
- { name: "service", type: "string", indexed: true, display: true }
2678
- ]
2679
- },
2680
- {
2681
- type: "log:error",
2682
- category: "logs",
2683
- label: "Error Log",
2684
- severity: "error",
2685
- frequency: "low",
2686
- fields: [
2687
- { name: "symbol", type: "string", indexed: true, display: true },
2688
- { name: "symbolType", type: "string", indexed: true, display: true },
2689
- { name: "message", type: "string", display: true },
2690
- { name: "service", type: "string", indexed: true, display: true }
2691
- ]
2692
- },
2693
- {
2694
- type: "metric:counter",
2695
- category: "metrics",
2696
- label: "Counter Metric",
2697
- severity: "info",
2698
- frequency: "high",
2699
- fields: [
2700
- { name: "name", type: "string", indexed: true, display: true },
2701
- { name: "value", type: "number", display: true },
2702
- { name: "tags", type: "object" }
2703
- ]
2704
- },
2705
- {
2706
- type: "metric:gauge",
2707
- category: "metrics",
2708
- label: "Gauge Metric",
2709
- severity: "info",
2710
- frequency: "medium",
2711
- fields: [
2712
- { name: "name", type: "string", indexed: true, display: true },
2713
- { name: "value", type: "number", display: true },
2714
- { name: "tags", type: "object" }
2715
- ]
2716
- },
2717
- {
2718
- type: "metric:histogram",
2719
- category: "metrics",
2720
- label: "Histogram Metric",
2721
- severity: "info",
2722
- frequency: "medium",
2723
- fields: [
2724
- { name: "name", type: "string", indexed: true, display: true },
2725
- { name: "value", type: "number", display: true },
2726
- { name: "tags", type: "object" }
2727
- ]
2728
- },
2729
- {
2730
- type: "trace:span",
2731
- category: "traces",
2732
- label: "Trace Span",
2733
- severity: "info",
2734
- frequency: "medium",
2735
- fields: [
2736
- { name: "traceId", type: "string", indexed: true, display: true },
2737
- { name: "spanId", type: "string", indexed: true },
2738
- { name: "operation", type: "string", display: true },
2739
- { name: "durationMs", type: "number", display: true },
2740
- { name: "status", type: "string", display: true }
2741
- ]
2742
- },
2743
- {
2744
- type: "incident:recorded",
2745
- category: "incidents",
2746
- label: "Incident Recorded",
2747
- severity: "error",
2748
- frequency: "low",
2749
- fields: [
2750
- { name: "incidentId", type: "string", indexed: true, display: true },
2751
- { name: "errorMessage", type: "string", display: true },
2752
- { name: "symbols", type: "object" },
2753
- { name: "environment", type: "string", display: true }
2754
- ]
2755
- }
2756
- ],
2757
- visualization: {
2758
- defaultView: "table",
2759
- categoryColors: {
2760
- logs: "#3b82f6",
2761
- metrics: "#22c55e",
2762
- traces: "#a855f7",
2763
- incidents: "#ef4444"
2764
- },
2765
- summaryFields: ["symbol", "message", "service"],
2766
- defaultExcluded: ["log:debug"]
2767
- },
2768
- tags: ["builtin", "paradigm"]
2769
- };
2770
- var SYMPHONY_SCHEMA = {
2771
- id: "paradigm-symphony",
2772
- version: "1.0.0",
2773
- name: "Symphony Conversations",
2774
- description: "Agent-to-agent messaging events from The Score protocol",
2775
- scope: {
2776
- field: "threadId",
2777
- type: "string",
2778
- label: "Thread",
2779
- ordering: "independent",
2780
- sessionField: "sessionId"
2781
- },
2782
- eventTypes: [
2783
- // ── Dialogue (5) ──────────────────────────────────────
2784
- {
2785
- type: "note:question",
2786
- category: "dialogue",
2787
- label: "Question",
2788
- severity: "info",
2789
- frequency: "high",
2790
- fields: [
2791
- { name: "sender", type: "string", indexed: true, display: true },
2792
- { name: "senderRole", type: "string", indexed: true, display: true },
2793
- { name: "text", type: "string", display: true },
2794
- { name: "symbols", type: "object" },
2795
- { name: "parentId", type: "string", indexed: true }
2796
- ]
2797
- },
2798
- {
2799
- type: "note:context",
2800
- category: "dialogue",
2801
- label: "Context",
2802
- severity: "info",
2803
- frequency: "high",
2804
- fields: [
2805
- { name: "sender", type: "string", indexed: true, display: true },
2806
- { name: "senderRole", type: "string", indexed: true, display: true },
2807
- { name: "text", type: "string", display: true },
2808
- { name: "symbols", type: "object" },
2809
- { name: "parentId", type: "string", indexed: true }
2810
- ]
2811
- },
2812
- {
2813
- type: "note:clarification",
2814
- category: "dialogue",
2815
- label: "Clarification",
2816
- severity: "info",
2817
- frequency: "medium",
2818
- fields: [
2819
- { name: "sender", type: "string", indexed: true, display: true },
2820
- { name: "senderRole", type: "string", indexed: true, display: true },
2821
- { name: "text", type: "string", display: true },
2822
- { name: "symbols", type: "object" },
2823
- { name: "parentId", type: "string", indexed: true }
2824
- ]
2825
- },
2826
- {
2827
- type: "note:verification",
2828
- category: "dialogue",
2829
- label: "Verification",
2830
- severity: "info",
2831
- frequency: "medium",
2832
- fields: [
2833
- { name: "sender", type: "string", indexed: true, display: true },
2834
- { name: "senderRole", type: "string", indexed: true, display: true },
2835
- { name: "text", type: "string", display: true },
2836
- { name: "symbols", type: "object" },
2837
- { name: "parentId", type: "string", indexed: true }
2838
- ]
2839
- },
2840
- {
2841
- type: "note:reference",
2842
- category: "dialogue",
2843
- label: "Reference",
2844
- severity: "info",
2845
- frequency: "medium",
2846
- fields: [
2847
- { name: "sender", type: "string", indexed: true, display: true },
2848
- { name: "senderRole", type: "string", indexed: true, display: true },
2849
- { name: "text", type: "string", display: true },
2850
- { name: "symbols", type: "object" },
2851
- { name: "parentId", type: "string", indexed: true }
2852
- ]
2853
- },
2854
- // ── Action (2) ────────────────────────────────────────
2855
- {
2856
- type: "note:proposal",
2857
- category: "action",
2858
- label: "Proposal",
2859
- severity: "info",
2860
- frequency: "medium",
2861
- fields: [
2862
- { name: "sender", type: "string", indexed: true, display: true },
2863
- { name: "senderRole", type: "string", indexed: true, display: true },
2864
- { name: "text", type: "string", display: true },
2865
- { name: "diff", type: "string" },
2866
- { name: "symbols", type: "object" },
2867
- { name: "parentId", type: "string", indexed: true }
2868
- ]
2869
- },
2870
- {
2871
- type: "note:action",
2872
- category: "action",
2873
- label: "Action",
2874
- severity: "info",
2875
- frequency: "medium",
2876
- fields: [
2877
- { name: "sender", type: "string", indexed: true, display: true },
2878
- { name: "senderRole", type: "string", indexed: true, display: true },
2879
- { name: "text", type: "string", display: true },
2880
- { name: "diff", type: "string" },
2881
- { name: "symbols", type: "object" },
2882
- { name: "parentId", type: "string", indexed: true }
2883
- ]
2884
- },
2885
- // ── Outcome (3) ───────────────────────────────────────
2886
- {
2887
- type: "note:decision",
2888
- category: "outcome",
2889
- label: "Decision",
2890
- severity: "warn",
2891
- frequency: "low",
2892
- fields: [
2893
- { name: "sender", type: "string", indexed: true, display: true },
2894
- { name: "senderRole", type: "string", indexed: true, display: true },
2895
- { name: "text", type: "string", display: true },
2896
- { name: "decision", type: "string", display: true },
2897
- { name: "symbols", type: "object" },
2898
- { name: "parentId", type: "string", indexed: true }
2899
- ]
2900
- },
2901
- {
2902
- type: "note:approval",
2903
- category: "outcome",
2904
- label: "Approval",
2905
- severity: "info",
2906
- frequency: "low",
2907
- fields: [
2908
- { name: "sender", type: "string", indexed: true, display: true },
2909
- { name: "senderRole", type: "string", indexed: true, display: true },
2910
- { name: "text", type: "string", display: true },
2911
- { name: "parentId", type: "string", indexed: true }
2912
- ]
2913
- },
2914
- {
2915
- type: "note:rejection",
2916
- category: "outcome",
2917
- label: "Rejection",
2918
- severity: "warn",
2919
- frequency: "low",
2920
- fields: [
2921
- { name: "sender", type: "string", indexed: true, display: true },
2922
- { name: "senderRole", type: "string", indexed: true, display: true },
2923
- { name: "text", type: "string", display: true },
2924
- { name: "parentId", type: "string", indexed: true }
2925
- ]
2926
- },
2927
- // ── System (1) ────────────────────────────────────────
2928
- {
2929
- type: "note:alert",
2930
- category: "system",
2931
- label: "Alert",
2932
- severity: "error",
2933
- frequency: "low",
2934
- fields: [
2935
- { name: "sender", type: "string", indexed: true, display: true },
2936
- { name: "senderRole", type: "string", indexed: true, display: true },
2937
- { name: "text", type: "string", display: true },
2938
- { name: "symbols", type: "object" },
2939
- { name: "parentId", type: "string", indexed: true }
2940
- ]
2941
- },
2942
- // ── Lifecycle (4) ─────────────────────────────────────
2943
- {
2944
- type: "note:handoff",
2945
- category: "lifecycle",
2946
- label: "Handoff",
2947
- severity: "info",
2948
- frequency: "low",
2949
- fields: [
2950
- { name: "sender", type: "string", indexed: true, display: true },
2951
- { name: "senderRole", type: "string", indexed: true, display: true },
2952
- { name: "text", type: "string", display: true },
2953
- { name: "parentId", type: "string", indexed: true }
2954
- ]
2955
- },
2956
- {
2957
- type: "thread:created",
2958
- category: "lifecycle",
2959
- label: "Thread Created",
2960
- severity: "info",
2961
- frequency: "low",
2962
- fields: [
2963
- { name: "topic", type: "string", display: true },
2964
- { name: "initiator", type: "string", indexed: true, display: true }
2965
- ]
2966
- },
2967
- {
2968
- type: "thread:resolved",
2969
- category: "lifecycle",
2970
- label: "Thread Resolved",
2971
- severity: "info",
2972
- frequency: "low",
2973
- fields: [
2974
- { name: "topic", type: "string", display: true },
2975
- { name: "decision", type: "string", display: true }
2976
- ]
2977
- },
2978
- {
2979
- type: "participant:joined",
2980
- category: "lifecycle",
2981
- label: "Participant Joined",
2982
- severity: "info",
2983
- frequency: "low",
2984
- fields: [
2985
- { name: "participantId", type: "string", indexed: true, display: true },
2986
- { name: "participantName", type: "string", display: true },
2987
- { name: "participantRole", type: "string", display: true }
2988
- ]
2989
- },
2990
- {
2991
- type: "participant:left",
2992
- category: "lifecycle",
2993
- label: "Participant Left",
2994
- severity: "info",
2995
- frequency: "low",
2996
- fields: [
2997
- { name: "participantId", type: "string", indexed: true, display: true },
2998
- { name: "participantName", type: "string", display: true }
2999
- ]
3000
- },
3001
- // ── Transfer (4) ──────────────────────────────────────
3002
- {
3003
- type: "file:requested",
3004
- category: "transfer",
3005
- label: "File Requested",
3006
- severity: "info",
3007
- frequency: "low",
3008
- fields: [
3009
- { name: "requestId", type: "string", indexed: true, display: true },
3010
- { name: "filePath", type: "string", display: true },
3011
- { name: "requester", type: "string", indexed: true, display: true },
3012
- { name: "reason", type: "string", display: true },
3013
- { name: "urgency", type: "string", display: true }
3014
- ]
3015
- },
3016
- {
3017
- type: "file:approved",
3018
- category: "transfer",
3019
- label: "File Approved",
3020
- severity: "info",
3021
- frequency: "low",
3022
- fields: [
3023
- { name: "requestId", type: "string", indexed: true, display: true },
3024
- { name: "filePath", type: "string", display: true },
3025
- { name: "size", type: "number", display: true },
3026
- { name: "hash", type: "string" }
3027
- ]
3028
- },
3029
- {
3030
- type: "file:denied",
3031
- category: "transfer",
3032
- label: "File Denied",
3033
- severity: "warn",
3034
- frequency: "low",
3035
- fields: [
3036
- { name: "requestId", type: "string", indexed: true, display: true },
3037
- { name: "filePath", type: "string", display: true },
3038
- { name: "reason", type: "string", display: true }
3039
- ]
3040
- },
3041
- {
3042
- type: "file:delivered",
3043
- category: "transfer",
3044
- label: "File Delivered",
3045
- severity: "info",
3046
- frequency: "low",
3047
- fields: [
3048
- { name: "requestId", type: "string", indexed: true, display: true },
3049
- { name: "filePath", type: "string", display: true },
3050
- { name: "size", type: "number", display: true },
3051
- { name: "hash", type: "string" }
3052
- ]
3053
- }
3054
- ],
3055
- visualization: {
3056
- defaultView: "tree",
3057
- categoryColors: {
3058
- dialogue: "#7dd3fc",
3059
- action: "#86efac",
3060
- outcome: "#fbbf24",
3061
- system: "#f87171",
3062
- lifecycle: "#a78bfa",
3063
- transfer: "#34d399"
3064
- },
3065
- summaryFields: ["sender", "text", "senderRole"],
3066
- defaultExcluded: []
3067
- },
3068
- tags: ["builtin", "symphony"]
3069
- };
3070
-
3071
- export {
3072
- SentinelStorage,
3073
- DEFAULT_AUTH_CONFIG,
3074
- DEFAULT_RATE_LIMIT_CONFIG,
3075
- DEFAULT_SERVER_CONFIG,
3076
- loadConfig,
3077
- writeConfig,
3078
- loadServerConfig,
3079
- PARADIGM_SCHEMA,
3080
- SYMPHONY_SCHEMA
3081
- };