@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,1647 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- PARADIGM_SCHEMA,
4
- SYMPHONY_SCHEMA,
5
- SentinelStorage,
6
- loadServerConfig
7
- } from "./chunk-FKJUBQU3.js";
8
- import "./chunk-PDX44BCA.js";
9
-
10
- // ../sentinel/dist/server/index.js
11
- import express from "express";
12
- import * as http from "http";
13
- import * as path3 from "path";
14
- import * as fs2 from "fs";
15
- import { fileURLToPath } from "url";
16
- import chalk3 from "chalk";
17
- import { WebSocketServer, WebSocket } from "ws";
18
- import { Router } from "express";
19
- import chalk2 from "chalk";
20
- import * as fs from "fs";
21
- import * as path from "path";
22
- import chalk from "chalk";
23
- import { Router as Router2 } from "express";
24
- import { Router as Router3 } from "express";
25
- import simpleGit from "simple-git";
26
- import * as path2 from "path";
27
- import { Router as Router4 } from "express";
28
- import { Router as Router5 } from "express";
29
- import { Router as Router6 } from "express";
30
- import { v4 as uuidv4 } from "uuid";
31
- import { Router as Router7 } from "express";
32
- import { Router as Router8 } from "express";
33
- import { Router as Router9 } from "express";
34
- import { Router as Router10 } from "express";
35
- import { Router as Router11 } from "express";
36
- var LOG_LEVEL = process.env.SENTINEL_LOG_LEVEL || process.env.LOG_LEVEL || "info";
37
- var LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
38
- function shouldLog(level) {
39
- return LOG_LEVELS[level] >= LOG_LEVELS[LOG_LEVEL];
40
- }
41
- function formatData(data) {
42
- if (!data) return "";
43
- const entries = Object.entries(data).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
44
- return chalk.gray(` ${entries}`);
45
- }
46
- var log = {
47
- component(name) {
48
- const symbol = chalk.magenta(`#${name}`);
49
- return {
50
- debug: (msg, data) => {
51
- if (shouldLog("debug")) console.log(`${chalk.gray("\u25CB")} ${symbol} ${msg}${formatData(data)}`);
52
- },
53
- info: (msg, data) => {
54
- if (shouldLog("info")) console.log(`${chalk.blue("\u2139")} ${symbol} ${msg}${formatData(data)}`);
55
- },
56
- warn: (msg, data) => {
57
- if (shouldLog("warn")) console.log(`${chalk.yellow("\u26A0")} ${symbol} ${msg}${formatData(data)}`);
58
- },
59
- error: (msg, data) => {
60
- if (shouldLog("error")) console.error(`${chalk.red("\u2716")} ${symbol} ${msg}${formatData(data)}`);
61
- }
62
- };
63
- },
64
- flow(name) {
65
- const symbol = chalk.yellow(`$${name}`);
66
- return {
67
- debug: (msg, data) => {
68
- if (shouldLog("debug")) console.log(`${chalk.gray("\u25CB")} ${symbol} ${msg}${formatData(data)}`);
69
- },
70
- info: (msg, data) => {
71
- if (shouldLog("info")) console.log(`${chalk.blue("\u2139")} ${symbol} ${msg}${formatData(data)}`);
72
- },
73
- warn: (msg, data) => {
74
- if (shouldLog("warn")) console.log(`${chalk.yellow("\u26A0")} ${symbol} ${msg}${formatData(data)}`);
75
- },
76
- error: (msg, data) => {
77
- if (shouldLog("error")) console.error(`${chalk.red("\u2716")} ${symbol} ${msg}${formatData(data)}`);
78
- }
79
- };
80
- }
81
- };
82
- var SYMBOL_BLOCKLIST = /* @__PURE__ */ new Set([
83
- "$lib",
84
- "$env",
85
- "$app",
86
- "$service-worker",
87
- "$virtual",
88
- "$schema",
89
- "$ref",
90
- "$id",
91
- "$type"
92
- ]);
93
- async function loadParadigmConfig(projectDir) {
94
- const configPath = path.join(projectDir, ".paradigm", "config.yaml");
95
- if (!fs.existsSync(configPath)) {
96
- const packagePath = path.join(projectDir, "package.json");
97
- if (fs.existsSync(packagePath)) {
98
- try {
99
- const pkg = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
100
- return { name: pkg.name };
101
- } catch {
102
- }
103
- }
104
- return {};
105
- }
106
- try {
107
- const content = fs.readFileSync(configPath, "utf-8");
108
- const config = {};
109
- const nameMatch = content.match(/^name:\s*(.+)$/m);
110
- if (nameMatch) config.name = nameMatch[1].trim().replace(/^["']|["']$/g, "");
111
- const disciplineMatch = content.match(/^discipline:\s*(.+)$/m);
112
- if (disciplineMatch) config.discipline = disciplineMatch[1].trim();
113
- const versionMatch = content.match(/^version:\s*(.+)$/m);
114
- if (versionMatch) config.version = versionMatch[1].trim();
115
- return config;
116
- } catch (error) {
117
- log.component("config-loader").error("Failed to load Paradigm config", { error: String(error) });
118
- return {};
119
- }
120
- }
121
- async function loadWithPremiseCore(projectDir) {
122
- try {
123
- const { aggregateFromDirectory } = await import("./dist-5QE2BB2B-5S3T6Y3T.js");
124
- log.flow("load-symbols").info("Using premise-core aggregator", { path: projectDir });
125
- const result = await aggregateFromDirectory(projectDir);
126
- const counts = {};
127
- for (const sym of result.symbols) {
128
- counts[sym.type] = (counts[sym.type] || 0) + 1;
129
- }
130
- log.flow("load-symbols").info("Aggregation complete", {
131
- total: result.symbols.length,
132
- ...counts,
133
- purposeFiles: result.purposeFiles.length,
134
- portalFiles: result.portalFiles.length
135
- });
136
- if (result.errors.length > 0) {
137
- for (const err of result.errors) {
138
- log.component("aggregator").warn("Aggregation error", {
139
- source: err.source,
140
- file: err.filePath,
141
- message: err.message
142
- });
143
- }
144
- }
145
- for (const file of result.purposeFiles) {
146
- log.component("purpose-loader").info("Loaded .purpose file", { file: path.relative(projectDir, file) });
147
- }
148
- for (const file of result.portalFiles) {
149
- log.component("gate-loader").info("Loaded portal.yaml", { file: path.relative(projectDir, file) });
150
- }
151
- return result.symbols;
152
- } catch (error) {
153
- log.component("premise-core").warn("premise-core not available, using fallback scanner", {
154
- error: error instanceof Error ? error.message : String(error)
155
- });
156
- return null;
157
- }
158
- }
159
- async function loadSymbolIndex(projectDir) {
160
- log.flow("load-symbols").info("Loading symbols", { projectDir });
161
- const indexPath = path.join(projectDir, ".paradigm", "index.json");
162
- if (fs.existsSync(indexPath)) {
163
- try {
164
- log.component("index-loader").info("Found cached index", { path: indexPath });
165
- const content = fs.readFileSync(indexPath, "utf-8");
166
- const index = JSON.parse(content);
167
- const entries = Array.isArray(index.entries) ? index.entries : Array.isArray(index) ? index : null;
168
- if (entries) {
169
- log.flow("load-symbols").info("Loaded from cached index", { count: entries.length });
170
- return entries;
171
- }
172
- } catch (error) {
173
- log.component("index-loader").error("Failed to load cached index", { error: String(error) });
174
- }
175
- }
176
- const premiseResult = await loadWithPremiseCore(projectDir);
177
- if (premiseResult) {
178
- return premiseResult;
179
- }
180
- log.flow("load-symbols").info("Using fallback scanner");
181
- return scanPurposeFiles(projectDir);
182
- }
183
- async function scanPurposeFiles(projectDir) {
184
- const symbols = [];
185
- const seenIds = /* @__PURE__ */ new Set();
186
- const scanDirs = ["src", "lib", "packages", "apps", "."];
187
- for (const dir of scanDirs) {
188
- const fullPath = path.join(projectDir, dir);
189
- if (fs.existsSync(fullPath)) {
190
- await scanDirectory(fullPath, symbols, seenIds, projectDir);
191
- }
192
- }
193
- const portalPath = path.join(projectDir, "portal.yaml");
194
- if (fs.existsSync(portalPath)) {
195
- log.component("gate-loader").debug("Found portal.yaml", { path: "portal.yaml" });
196
- try {
197
- const content = fs.readFileSync(portalPath, "utf-8");
198
- const gatesSection = content.match(/^gates:\s*\n((?: .+\n)*)/m);
199
- if (gatesSection) {
200
- const gateMatches = gatesSection[1].matchAll(/^ ([a-z][a-z0-9-]*):/gm);
201
- for (const match of gateMatches) {
202
- const gateName = match[1];
203
- const id = `gate-${gateName}`;
204
- if (!seenIds.has(id)) {
205
- seenIds.add(id);
206
- symbols.push({
207
- id,
208
- symbol: `^${gateName}`,
209
- type: "gate",
210
- source: "portal",
211
- filePath: "portal.yaml",
212
- data: {},
213
- references: [],
214
- referencedBy: []
215
- });
216
- log.component("gate-loader").debug("Extracted gate", { symbol: `^${gateName}` });
217
- }
218
- }
219
- }
220
- } catch (error) {
221
- log.component("gate-loader").error("Failed to parse portal.yaml", { error: String(error) });
222
- }
223
- }
224
- log.flow("load-symbols").info("Fallback scan complete", { count: symbols.length });
225
- return symbols;
226
- }
227
- async function scanDirectory(dir, symbols, seenIds, projectDir) {
228
- const skipDirs = ["node_modules", ".git", "dist", "build", ".paradigm", "coverage", ".next", ".svelte-kit"];
229
- let entries;
230
- try {
231
- entries = fs.readdirSync(dir, { withFileTypes: true });
232
- } catch {
233
- return;
234
- }
235
- for (const entry of entries) {
236
- const fullPath = path.join(dir, entry.name);
237
- if (entry.isDirectory()) {
238
- if (!skipDirs.includes(entry.name)) {
239
- await scanDirectory(fullPath, symbols, seenIds, projectDir);
240
- }
241
- } else if (entry.name === ".purpose") {
242
- const relativePath = path.relative(projectDir, fullPath);
243
- log.component("purpose-loader").debug("Scanning .purpose file", { path: relativePath });
244
- try {
245
- const content = fs.readFileSync(fullPath, "utf-8");
246
- const parsed = parsePurposeFile(content, fullPath, projectDir);
247
- for (const symbol of parsed) {
248
- if (!seenIds.has(symbol.id)) {
249
- seenIds.add(symbol.id);
250
- symbols.push(symbol);
251
- log.component("purpose-loader").debug("Extracted symbol", {
252
- symbol: symbol.symbol,
253
- type: symbol.type,
254
- file: relativePath
255
- });
256
- }
257
- }
258
- } catch (error) {
259
- log.component("purpose-loader").error("Failed to parse .purpose file", {
260
- path: relativePath,
261
- error: String(error)
262
- });
263
- }
264
- }
265
- }
266
- }
267
- function parsePurposeFile(content, filePath, projectDir) {
268
- const symbols = [];
269
- const relativePath = path.relative(projectDir, filePath);
270
- const componentMatches = content.matchAll(/(?:^|\s)#([a-z][a-z0-9-]*)/gm);
271
- for (const match of componentMatches) {
272
- const name = match[1];
273
- symbols.push({
274
- id: `component-${name}`,
275
- symbol: `#${name}`,
276
- type: "component",
277
- source: "purpose",
278
- filePath: relativePath,
279
- data: {},
280
- description: extractDescription(content, `#${name}`),
281
- references: extractReferences(content),
282
- referencedBy: [],
283
- tags: extractTags(content)
284
- });
285
- }
286
- const flowMatches = content.matchAll(/\$([a-z][a-z0-9-]*)/gm);
287
- for (const match of flowMatches) {
288
- const name = match[1];
289
- const symbol = `$${name}`;
290
- if (SYMBOL_BLOCKLIST.has(symbol)) {
291
- log.component("purpose-loader").debug("Skipping blocklisted symbol", { symbol });
292
- continue;
293
- }
294
- if (!symbols.find((s) => s.symbol === symbol)) {
295
- symbols.push({
296
- id: `flow-${name}`,
297
- symbol,
298
- type: "flow",
299
- source: "purpose",
300
- filePath: relativePath,
301
- data: {},
302
- references: [],
303
- referencedBy: []
304
- });
305
- }
306
- }
307
- const signalMatches = content.matchAll(/!([a-z][a-z0-9-]*)/gm);
308
- for (const match of signalMatches) {
309
- const name = match[1];
310
- if (!symbols.find((s) => s.symbol === `!${name}`)) {
311
- symbols.push({
312
- id: `signal-${name}`,
313
- symbol: `!${name}`,
314
- type: "signal",
315
- source: "purpose",
316
- filePath: relativePath,
317
- data: {},
318
- references: [],
319
- referencedBy: []
320
- });
321
- }
322
- }
323
- const gateMatches = content.matchAll(/\^([a-z][a-z0-9-]*)/gm);
324
- for (const match of gateMatches) {
325
- const name = match[1];
326
- if (!symbols.find((s) => s.symbol === `^${name}`)) {
327
- symbols.push({
328
- id: `gate-${name}`,
329
- symbol: `^${name}`,
330
- type: "gate",
331
- source: "purpose",
332
- filePath: relativePath,
333
- data: {},
334
- references: [],
335
- referencedBy: []
336
- });
337
- }
338
- }
339
- const aspectMatches = content.matchAll(/~([a-z][a-z0-9-]*)/gm);
340
- for (const match of aspectMatches) {
341
- const name = match[1];
342
- if (!symbols.find((s) => s.symbol === `~${name}`)) {
343
- symbols.push({
344
- id: `aspect-${name}`,
345
- symbol: `~${name}`,
346
- type: "aspect",
347
- source: "purpose",
348
- filePath: relativePath,
349
- data: {},
350
- references: [],
351
- referencedBy: []
352
- });
353
- }
354
- }
355
- return symbols;
356
- }
357
- function extractDescription(content, symbol) {
358
- const regex = new RegExp(`${symbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*[-:]?\\s*(.+)`, "m");
359
- const match = content.match(regex);
360
- if (match && match[1]) {
361
- return match[1].trim();
362
- }
363
- return void 0;
364
- }
365
- function extractReferences(content) {
366
- const refs = /* @__PURE__ */ new Set();
367
- const refMatches = content.matchAll(/[@#$!^~]([a-z][a-z0-9-]*)/g);
368
- for (const match of refMatches) {
369
- const symbol = match[0];
370
- if (!SYMBOL_BLOCKLIST.has(symbol)) {
371
- refs.add(symbol);
372
- }
373
- }
374
- return Array.from(refs);
375
- }
376
- function extractTags(content) {
377
- const tagMatch = content.match(/tags:\s*\[([^\]]+)\]/);
378
- if (tagMatch) {
379
- return tagMatch[1].split(",").map((t) => t.trim().replace(/^["']|["']$/g, ""));
380
- }
381
- return [];
382
- }
383
- async function getSymbolCount(projectDir) {
384
- const symbols = await loadSymbolIndex(projectDir);
385
- return symbols.length;
386
- }
387
- async function updateSymbol(projectDir, symbolId, updates) {
388
- const symbols = await loadSymbolIndex(projectDir);
389
- const symbol = symbols.find((s) => s.id === symbolId);
390
- if (!symbol) {
391
- return { success: false, error: "Symbol not found" };
392
- }
393
- const filePath = path.join(projectDir, symbol.filePath);
394
- if (!fs.existsSync(filePath)) {
395
- return { success: false, error: "Source file not found" };
396
- }
397
- try {
398
- let content = fs.readFileSync(filePath, "utf-8");
399
- let modified = false;
400
- if (updates.description !== void 0) {
401
- const symbolPattern = symbol.symbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
402
- const descRegex = new RegExp(`(${symbolPattern})\\s*[-:]?\\s*(.*)`, "m");
403
- const match = content.match(descRegex);
404
- if (match) {
405
- const newLine = updates.description ? `${symbol.symbol}: ${updates.description}` : symbol.symbol;
406
- content = content.replace(descRegex, newLine);
407
- modified = true;
408
- }
409
- }
410
- if (updates.tags !== void 0) {
411
- const tagsStr = updates.tags.length > 0 ? `tags: [${updates.tags.map((t) => `"${t}"`).join(", ")}]` : "";
412
- const tagsRegex = /^tags:\s*\[[^\]]*\]\s*$/m;
413
- if (tagsRegex.test(content)) {
414
- if (tagsStr) {
415
- content = content.replace(tagsRegex, tagsStr);
416
- } else {
417
- content = content.replace(tagsRegex, "");
418
- }
419
- modified = true;
420
- } else if (tagsStr) {
421
- const symbolPattern = symbol.symbol.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
422
- const symbolLineRegex = new RegExp(`(${symbolPattern}[^\\n]*\\n)`, "m");
423
- const symbolMatch = content.match(symbolLineRegex);
424
- if (symbolMatch) {
425
- content = content.replace(symbolLineRegex, `$1${tagsStr}
426
- `);
427
- modified = true;
428
- }
429
- }
430
- }
431
- if (modified) {
432
- content = content.replace(/\n{3,}/g, "\n\n");
433
- fs.writeFileSync(filePath, content, "utf-8");
434
- log.component("symbol-updater").info("Updated symbol", { symbol: symbol.symbol, file: symbol.filePath });
435
- const indexPath = path.join(projectDir, ".paradigm", "index.json");
436
- if (fs.existsSync(indexPath)) {
437
- try {
438
- const indexContent = fs.readFileSync(indexPath, "utf-8");
439
- const index = JSON.parse(indexContent);
440
- const entries = Array.isArray(index.entries) ? index.entries : index;
441
- const entryIndex = entries.findIndex((e) => e.id === symbolId);
442
- if (entryIndex >= 0) {
443
- if (updates.description !== void 0) {
444
- entries[entryIndex].description = updates.description;
445
- }
446
- if (updates.tags !== void 0) {
447
- entries[entryIndex].tags = updates.tags;
448
- }
449
- if (Array.isArray(index.entries)) {
450
- index.entries = entries;
451
- fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), "utf-8");
452
- } else {
453
- fs.writeFileSync(indexPath, JSON.stringify(entries, null, 2), "utf-8");
454
- }
455
- }
456
- } catch {
457
- }
458
- }
459
- return { success: true };
460
- }
461
- return { success: true };
462
- } catch (error) {
463
- log.component("symbol-updater").error("Failed to update symbol", { error: String(error) });
464
- return { success: false, error: "Failed to write file" };
465
- }
466
- }
467
- var LOG_LEVEL2 = process.env.SENTINEL_LOG_LEVEL || process.env.LOG_LEVEL || "info";
468
- var shouldLog2 = (level) => {
469
- const levels = { debug: 0, info: 1, warn: 2, error: 3 };
470
- return levels[level] >= levels[LOG_LEVEL2];
471
- };
472
- var log2 = {
473
- gate(name) {
474
- const symbol = chalk2.cyan(`^${name}`);
475
- return {
476
- info: (msg, data) => {
477
- if (shouldLog2("info")) {
478
- const dataStr = data ? chalk2.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
479
- console.log(`${chalk2.blue("\u2139")} ${symbol} ${msg}${dataStr}`);
480
- }
481
- },
482
- error: (msg, data) => {
483
- if (shouldLog2("error")) {
484
- const dataStr = data ? chalk2.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
485
- console.error(`${chalk2.red("\u2716")} ${symbol} ${msg}${dataStr}`);
486
- }
487
- }
488
- };
489
- }
490
- };
491
- function createSymbolsRouter(projectDir) {
492
- const router = Router();
493
- router.get("/", async (_req, res) => {
494
- try {
495
- const symbols = await loadSymbolIndex(projectDir);
496
- log2.gate("api-symbols").info("Symbols loaded", { count: symbols.length });
497
- res.json({ symbols });
498
- } catch (error) {
499
- log2.gate("api-symbols").error("Failed to load symbols", { error: String(error) });
500
- res.status(500).json({ error: "Failed to load symbols" });
501
- }
502
- });
503
- router.put("/:id", async (req, res) => {
504
- try {
505
- const { id } = req.params;
506
- const updates = req.body;
507
- log2.gate("api-symbols").info("Update requested", { id, updates: JSON.stringify(updates) });
508
- if (updates.tags && !Array.isArray(updates.tags)) {
509
- res.status(400).json({ error: "Tags must be an array" });
510
- return;
511
- }
512
- const result = await updateSymbol(projectDir, id, updates);
513
- if (result.success) {
514
- const symbols = await loadSymbolIndex(projectDir);
515
- const updatedSymbol = symbols.find((s) => s.id === id);
516
- log2.gate("api-symbols").info("Symbol updated", { id });
517
- res.json({ success: true, symbol: updatedSymbol });
518
- } else {
519
- log2.gate("api-symbols").error("Update failed", { id, error: result.error });
520
- res.status(400).json({ success: false, error: result.error });
521
- }
522
- } catch (error) {
523
- log2.gate("api-symbols").error("Failed to update symbol", { error: String(error) });
524
- res.status(500).json({ error: "Failed to update symbol" });
525
- }
526
- });
527
- return router;
528
- }
529
- function createInfoRouter(projectDir) {
530
- const router = Router2();
531
- router.get("/", async (_req, res) => {
532
- try {
533
- const config = await loadParadigmConfig(projectDir);
534
- const symbolCount = await getSymbolCount(projectDir);
535
- res.json({
536
- projectName: config.name || null,
537
- discipline: config.discipline || null,
538
- symbolCount,
539
- projectDir
540
- });
541
- } catch (error) {
542
- console.error("Failed to load project info:", error);
543
- res.status(500).json({ error: "Failed to load project info" });
544
- }
545
- });
546
- return router;
547
- }
548
- function extractSymbolsFromFiles(files) {
549
- const symbols = /* @__PURE__ */ new Set();
550
- for (const file of files) {
551
- if (file.endsWith(".purpose")) {
552
- const dir = path2.dirname(file);
553
- const name = path2.basename(dir);
554
- if (dir.includes("features/") || dir.includes("routes/") || dir.includes("api/")) {
555
- symbols.add(`@${name}`);
556
- } else if (dir.includes("components/") || dir.includes("lib/") || dir.includes("utils/")) {
557
- symbols.add(`#${name}`);
558
- } else if (dir.includes("middleware/") || dir.includes("auth/") || dir.includes("guards/")) {
559
- symbols.add(`^${name}`);
560
- } else if (dir.includes("flows/") || dir.includes("workflows/")) {
561
- symbols.add(`$${name}`);
562
- }
563
- }
564
- if (file.includes("portal.yaml")) {
565
- symbols.add("^portal");
566
- }
567
- const featureMatch = file.match(/features\/([^/]+)/);
568
- if (featureMatch) {
569
- symbols.add(`@${featureMatch[1]}`);
570
- }
571
- const componentMatch = file.match(/components\/([^/]+)/);
572
- if (componentMatch) {
573
- symbols.add(`#${componentMatch[1]}`);
574
- }
575
- }
576
- return Array.from(symbols);
577
- }
578
- async function loadGitHistory(projectDir, options = {}) {
579
- const git = simpleGit(projectDir);
580
- const isRepo = await git.checkIsRepo();
581
- if (!isRepo) {
582
- return [];
583
- }
584
- try {
585
- const logOptions = {
586
- maxCount: options.limit || 100
587
- };
588
- if (options.since) {
589
- logOptions["--since"] = options.since;
590
- }
591
- const log4 = await git.log(logOptions);
592
- const commits = [];
593
- for (const commit of log4.all) {
594
- let filesChanged = [];
595
- let symbolsModified = [];
596
- try {
597
- const diff = await git.diffSummary([`${commit.hash}^`, commit.hash]);
598
- filesChanged = diff.files.map((f) => f.file);
599
- symbolsModified = extractSymbolsFromFiles(filesChanged);
600
- } catch {
601
- }
602
- commits.push({
603
- hash: commit.hash,
604
- shortHash: commit.hash.slice(0, 7),
605
- date: commit.date,
606
- author: commit.author_name,
607
- message: commit.message.split("\n")[0],
608
- // First line only
609
- symbolsModified,
610
- filesChanged
611
- });
612
- }
613
- return commits;
614
- } catch (error) {
615
- console.error("Failed to load git history:", error);
616
- return [];
617
- }
618
- }
619
- async function getSymbolsAtCommit(projectDir, commitHash) {
620
- const git = simpleGit(projectDir);
621
- try {
622
- const result = await git.raw(["ls-tree", "-r", "--name-only", commitHash]);
623
- const files = result.split("\n").filter(Boolean);
624
- const purposeFiles = files.filter((f) => f.endsWith(".purpose"));
625
- return extractSymbolsFromFiles(purposeFiles);
626
- } catch (error) {
627
- console.error("Failed to get symbols at commit:", error);
628
- return [];
629
- }
630
- }
631
- function createCommitsRouter(projectDir) {
632
- const router = Router3();
633
- router.get("/", async (req, res) => {
634
- try {
635
- const limit = parseInt(req.query.limit) || 100;
636
- const since = req.query.since;
637
- const commits = await loadGitHistory(projectDir, { limit, since });
638
- res.json({ commits });
639
- } catch (error) {
640
- console.error("Failed to load commits:", error);
641
- res.status(500).json({ error: "Failed to load commits" });
642
- }
643
- });
644
- return router;
645
- }
646
- function createIncidentsRouter(_projectDir) {
647
- const router = Router4();
648
- const storage = new SentinelStorage();
649
- router.get("/", async (req, res) => {
650
- try {
651
- const limit = parseInt(req.query.limit) || 50;
652
- const status = req.query.status;
653
- const environment = req.query.environment;
654
- const symbol = req.query.symbol;
655
- const options = { limit };
656
- if (status && ["open", "investigating", "resolved", "wont-fix"].includes(status)) {
657
- options.status = status;
658
- }
659
- if (environment) options.environment = environment;
660
- if (symbol) options.symbol = symbol;
661
- const incidents = storage.getRecentIncidents(options);
662
- const summaries = incidents.map((incident) => ({
663
- id: incident.id,
664
- timestamp: incident.timestamp,
665
- status: incident.status,
666
- error: {
667
- message: incident.error.message,
668
- type: incident.error.type
669
- },
670
- symbols: incident.symbols,
671
- environment: incident.environment,
672
- patternMatches: []
673
- // Would need PatternMatcher to populate
674
- }));
675
- res.json({ incidents: summaries });
676
- } catch (error) {
677
- console.error("Failed to load incidents:", error);
678
- res.status(500).json({ error: "Failed to load incidents" });
679
- }
680
- });
681
- router.get("/:id", async (req, res) => {
682
- try {
683
- const incident = storage.getIncident(req.params.id);
684
- if (!incident) {
685
- res.status(404).json({ error: "Incident not found" });
686
- return;
687
- }
688
- res.json({ incident });
689
- } catch (error) {
690
- console.error("Failed to load incident:", error);
691
- res.status(500).json({ error: "Failed to load incident" });
692
- }
693
- });
694
- router.post("/:id/resolve", async (req, res) => {
695
- try {
696
- const incident = storage.getIncident(req.params.id);
697
- if (!incident) {
698
- res.status(404).json({ error: "Incident not found" });
699
- return;
700
- }
701
- storage.resolveIncident(req.params.id, {
702
- notes: req.body.notes,
703
- patternId: req.body.patternId
704
- });
705
- res.json({ success: true });
706
- } catch (error) {
707
- console.error("Failed to resolve incident:", error);
708
- res.status(500).json({ error: "Failed to resolve incident" });
709
- }
710
- });
711
- return router;
712
- }
713
- function createPatternsRouter(_projectDir) {
714
- const router = Router5();
715
- const storage = new SentinelStorage();
716
- router.get("/", async (req, res) => {
717
- try {
718
- const source = req.query.source;
719
- const symbol = req.query.symbol;
720
- const minConfidence = parseInt(req.query.minConfidence) || void 0;
721
- const options = {};
722
- if (source && ["manual", "suggested", "imported", "community"].includes(source)) {
723
- options.source = source;
724
- }
725
- if (symbol) options.symbol = symbol;
726
- if (minConfidence) options.minConfidence = minConfidence;
727
- const patterns = storage.getAllPatterns(options);
728
- const summaries = patterns.map((pattern) => ({
729
- id: pattern.id,
730
- name: pattern.name,
731
- description: pattern.description,
732
- confidence: {
733
- score: pattern.confidence.score,
734
- timesMatched: pattern.confidence.timesMatched,
735
- timesResolved: pattern.confidence.timesResolved
736
- },
737
- tags: pattern.tags
738
- }));
739
- res.json({ patterns: summaries });
740
- } catch (error) {
741
- console.error("Failed to load patterns:", error);
742
- res.status(500).json({ error: "Failed to load patterns" });
743
- }
744
- });
745
- router.get("/:id", async (req, res) => {
746
- try {
747
- const pattern = storage.getPattern(req.params.id);
748
- if (!pattern) {
749
- res.status(404).json({ error: "Pattern not found" });
750
- return;
751
- }
752
- res.json({ pattern });
753
- } catch (error) {
754
- console.error("Failed to load pattern:", error);
755
- res.status(500).json({ error: "Failed to load pattern" });
756
- }
757
- });
758
- return router;
759
- }
760
- function inferSymbolType(symbol) {
761
- if (symbol.startsWith("#")) return "component";
762
- if (symbol.startsWith("^")) return "gate";
763
- if (symbol.startsWith("!")) return "signal";
764
- if (symbol.startsWith("$")) return "flow";
765
- if (symbol.startsWith("~")) return "aspect";
766
- return "raw";
767
- }
768
- function validateSymbol(symbol, index) {
769
- const entry = index.find((e) => e.symbol === symbol);
770
- if (entry) return { known: true };
771
- const symbolName = symbol.replace(/^[#^!$~]/, "");
772
- let bestMatch;
773
- let bestScore = 0;
774
- for (const e of index) {
775
- const eName = e.symbol.replace(/^[#^!$~]/, "");
776
- let shared = 0;
777
- for (let i = 0; i < Math.min(symbolName.length, eName.length); i++) {
778
- if (symbolName[i] === eName[i]) shared++;
779
- else break;
780
- }
781
- const score = shared / Math.max(symbolName.length, eName.length);
782
- if (score > bestScore && score > 0.5) {
783
- bestScore = score;
784
- bestMatch = e.symbol;
785
- }
786
- }
787
- return { known: false, suggestion: bestMatch };
788
- }
789
- function autoPromoteToIncident(entry, storage) {
790
- try {
791
- const symbolType = inferSymbolType(entry.symbol);
792
- const symbols = {};
793
- if (symbolType === "component") symbols.component = entry.symbol;
794
- else if (symbolType === "gate") symbols.gate = entry.symbol;
795
- else if (symbolType === "signal") symbols.signal = entry.symbol;
796
- else if (symbolType === "flow") symbols.flow = entry.symbol;
797
- else symbols.component = entry.symbol;
798
- storage.recordIncident({
799
- error: {
800
- message: entry.message,
801
- type: "LogError"
802
- },
803
- symbols,
804
- environment: entry.environment || "unknown",
805
- service: entry.service
806
- });
807
- } catch {
808
- }
809
- }
810
- var insertsSincePrune = 0;
811
- function createLogsRouter(options) {
812
- const router = Router6();
813
- const { storage, serverConfig, onLogReceived, symbolIndex } = options;
814
- router.post("/", async (req, res) => {
815
- try {
816
- const body = req.body;
817
- let entries;
818
- if (Array.isArray(body.entries)) {
819
- entries = body.entries;
820
- } else if (body.level && body.symbol && body.message && body.service) {
821
- entries = [body];
822
- } else {
823
- res.status(400).json({ error: "Expected {entries: [...]} or a single log entry with level, symbol, message, service" });
824
- return;
825
- }
826
- if (entries.length > serverConfig.maxBatchSize) {
827
- res.status(413).json({
828
- error: `Batch too large: ${entries.length} entries, max ${serverConfig.maxBatchSize}`
829
- });
830
- return;
831
- }
832
- for (let i = 0; i < entries.length; i++) {
833
- const e = entries[i];
834
- if (!e.level || !e.symbol || !e.message || !e.service) {
835
- res.status(400).json({
836
- error: `Entry ${i}: missing required fields (level, symbol, message, service)`
837
- });
838
- return;
839
- }
840
- if (!["debug", "info", "warn", "error"].includes(e.level)) {
841
- res.status(400).json({
842
- error: `Entry ${i}: invalid level "${e.level}", must be debug|info|warn|error`
843
- });
844
- return;
845
- }
846
- }
847
- const result = storage.insertLogBatch(entries);
848
- for (const input of entries) {
849
- const entry = {
850
- id: input.id || uuidv4(),
851
- timestamp: input.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
852
- level: input.level,
853
- symbol: input.symbol,
854
- symbolType: input.symbolType || inferSymbolType(input.symbol),
855
- message: input.message,
856
- data: input.data,
857
- service: input.service,
858
- sessionId: input.sessionId,
859
- correlationId: input.correlationId,
860
- durationMs: input.durationMs,
861
- environment: input.environment
862
- };
863
- let validation;
864
- if (symbolIndex) {
865
- validation = validateSymbol(entry.symbol, symbolIndex);
866
- }
867
- if (entry.level === "error") {
868
- autoPromoteToIncident(entry, storage);
869
- }
870
- if (onLogReceived) {
871
- onLogReceived(entry, validation);
872
- }
873
- }
874
- insertsSincePrune += result.accepted;
875
- if (serverConfig.maxLogs > 0 && insertsSincePrune >= serverConfig.pruneIntervalInserts) {
876
- insertsSincePrune = 0;
877
- storage.pruneLogs(serverConfig.maxLogs);
878
- }
879
- res.json({ accepted: result.accepted, errors: result.errors.length > 0 ? result.errors : void 0 });
880
- } catch (error) {
881
- res.status(500).json({ error: "Failed to insert logs" });
882
- }
883
- });
884
- router.get("/", async (req, res) => {
885
- try {
886
- const options2 = {
887
- level: req.query.level,
888
- symbol: req.query.symbol,
889
- service: req.query.service,
890
- sessionId: req.query.sessionId,
891
- correlationId: req.query.correlationId,
892
- search: req.query.search,
893
- since: req.query.since,
894
- until: req.query.until,
895
- limit: req.query.limit ? parseInt(req.query.limit) : 100,
896
- offset: req.query.offset ? parseInt(req.query.offset) : 0
897
- };
898
- const logs = storage.queryLogs(options2);
899
- const total = storage.getLogCount(options2);
900
- res.json({ count: logs.length, total, logs });
901
- } catch (error) {
902
- res.status(500).json({ error: "Failed to query logs" });
903
- }
904
- });
905
- return router;
906
- }
907
- function createServicesRouter(options) {
908
- const router = Router7();
909
- const { storage } = options;
910
- router.post("/", async (req, res) => {
911
- try {
912
- const { name, version, pid, environment, metadata } = req.body;
913
- if (!name) {
914
- res.status(400).json({ error: "Missing required field: name" });
915
- return;
916
- }
917
- storage.registerService({ name, version, pid, environment, metadata });
918
- res.json({ success: true, service: name });
919
- } catch (error) {
920
- res.status(500).json({ error: "Failed to register service" });
921
- }
922
- });
923
- router.get("/", async (_req, res) => {
924
- try {
925
- const services = storage.getServices();
926
- res.json({ count: services.length, services });
927
- } catch (error) {
928
- res.status(500).json({ error: "Failed to list services" });
929
- }
930
- });
931
- return router;
932
- }
933
- function createStateRouter(options) {
934
- const router = Router7();
935
- const { storage } = options;
936
- router.post("/", async (req, res) => {
937
- try {
938
- const { service, sessionId, state, activeFlows, activeGates } = req.body;
939
- if (!service || !sessionId || !state) {
940
- res.status(400).json({ error: "Missing required fields: service, sessionId, state" });
941
- return;
942
- }
943
- storage.upsertAppState({
944
- service,
945
- sessionId,
946
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
947
- state,
948
- activeFlows,
949
- activeGates
950
- });
951
- storage.updateServiceLastSeen(service);
952
- res.json({ success: true });
953
- } catch (error) {
954
- res.status(500).json({ error: "Failed to update state" });
955
- }
956
- });
957
- router.get("/", async (_req, res) => {
958
- try {
959
- const states = storage.getAllAppStates();
960
- res.json({ count: states.length, states });
961
- } catch (error) {
962
- res.status(500).json({ error: "Failed to get states" });
963
- }
964
- });
965
- router.get("/:service", async (req, res) => {
966
- try {
967
- const states = storage.getAppState(req.params.service);
968
- res.json({ count: states.length, states });
969
- } catch (error) {
970
- res.status(500).json({ error: "Failed to get service state" });
971
- }
972
- });
973
- return router;
974
- }
975
- var VALID_METRIC_TYPES = ["counter", "gauge", "histogram"];
976
- function createMetricsRouter(options) {
977
- const router = Router8();
978
- const { storage, serverConfig } = options;
979
- router.post("/", (req, res) => {
980
- try {
981
- const body = req.body;
982
- let entries;
983
- if (Array.isArray(body.entries)) {
984
- entries = body.entries;
985
- } else if (body.name && body.type && body.value !== void 0 && body.service) {
986
- entries = [body];
987
- } else {
988
- res.status(400).json({
989
- error: "Expected {entries: [...]} or a single metric with name, type, value, service"
990
- });
991
- return;
992
- }
993
- if (entries.length > serverConfig.maxBatchSize) {
994
- res.status(413).json({
995
- error: `Batch too large: ${entries.length} entries, max ${serverConfig.maxBatchSize}`
996
- });
997
- return;
998
- }
999
- for (let i = 0; i < entries.length; i++) {
1000
- const e = entries[i];
1001
- if (!e.name || !e.type || e.value === void 0 || !e.service) {
1002
- res.status(400).json({
1003
- error: `Entry ${i}: missing required fields (name, type, value, service)`
1004
- });
1005
- return;
1006
- }
1007
- if (!VALID_METRIC_TYPES.includes(e.type)) {
1008
- res.status(400).json({
1009
- error: `Entry ${i}: invalid type "${e.type}", must be counter|gauge|histogram`
1010
- });
1011
- return;
1012
- }
1013
- }
1014
- const result = storage.insertMetricBatch(entries);
1015
- res.json({
1016
- accepted: result.accepted,
1017
- errors: result.errors.length > 0 ? result.errors : void 0
1018
- });
1019
- } catch {
1020
- res.status(500).json({ error: "Failed to insert metrics" });
1021
- }
1022
- });
1023
- router.get("/", (req, res) => {
1024
- try {
1025
- const options2 = {
1026
- name: req.query.name,
1027
- type: req.query.type,
1028
- service: req.query.service,
1029
- tag: req.query.tag,
1030
- since: req.query.since,
1031
- until: req.query.until,
1032
- limit: req.query.limit ? parseInt(req.query.limit) : 100,
1033
- offset: req.query.offset ? parseInt(req.query.offset) : 0
1034
- };
1035
- const metrics = storage.queryMetrics(options2);
1036
- const total = storage.getMetricCount(options2);
1037
- res.json({ count: metrics.length, total, metrics });
1038
- } catch {
1039
- res.status(500).json({ error: "Failed to query metrics" });
1040
- }
1041
- });
1042
- router.get("/aggregate/:name", (req, res) => {
1043
- try {
1044
- const aggregation = storage.aggregateMetric(req.params.name, {
1045
- service: req.query.service,
1046
- since: req.query.since,
1047
- until: req.query.until
1048
- });
1049
- res.json(aggregation);
1050
- } catch {
1051
- res.status(500).json({ error: "Failed to aggregate metric" });
1052
- }
1053
- });
1054
- return router;
1055
- }
1056
- function createTracesRouter(options) {
1057
- const router = Router9();
1058
- const { storage } = options;
1059
- router.post("/", (req, res) => {
1060
- try {
1061
- const body = req.body;
1062
- if (!body.traceId || !body.service || !body.symbol || !body.operation) {
1063
- res.status(400).json({
1064
- error: "Missing required fields: traceId, service, symbol, operation"
1065
- });
1066
- return;
1067
- }
1068
- const spanId = storage.insertSpan(body);
1069
- res.json({ spanId, traceId: body.traceId });
1070
- } catch {
1071
- res.status(500).json({ error: "Failed to insert trace span" });
1072
- }
1073
- });
1074
- router.get("/", (req, res) => {
1075
- try {
1076
- const traces = storage.queryTraces({
1077
- service: req.query.service,
1078
- symbol: req.query.symbol,
1079
- since: req.query.since,
1080
- limit: req.query.limit ? parseInt(req.query.limit) : 20
1081
- });
1082
- res.json({ count: traces.length, traces });
1083
- } catch {
1084
- res.status(500).json({ error: "Failed to query traces" });
1085
- }
1086
- });
1087
- router.get("/:traceId", (req, res) => {
1088
- try {
1089
- const trace = storage.getTrace(req.params.traceId);
1090
- if (!trace) {
1091
- res.status(404).json({ error: "Trace not found" });
1092
- return;
1093
- }
1094
- res.json(trace);
1095
- } catch {
1096
- res.status(500).json({ error: "Failed to get trace" });
1097
- }
1098
- });
1099
- return router;
1100
- }
1101
- function createSchemasRouter(options) {
1102
- const router = Router10();
1103
- const { storage } = options;
1104
- router.post("/", (req, res) => {
1105
- try {
1106
- const body = req.body;
1107
- if (!body.id || !body.version || !body.name || !body.scope || !body.eventTypes) {
1108
- res.status(400).json({
1109
- error: "Missing required fields: id, version, name, scope, eventTypes"
1110
- });
1111
- return;
1112
- }
1113
- if (!body.scope.field || !body.scope.type || !body.scope.label || !body.scope.ordering) {
1114
- res.status(400).json({
1115
- error: "Invalid scope: requires field, type, label, ordering"
1116
- });
1117
- return;
1118
- }
1119
- if (!Array.isArray(body.eventTypes) || body.eventTypes.length === 0) {
1120
- res.status(400).json({
1121
- error: "eventTypes must be a non-empty array"
1122
- });
1123
- return;
1124
- }
1125
- for (let i = 0; i < body.eventTypes.length; i++) {
1126
- const et = body.eventTypes[i];
1127
- if (!et.type || !et.category) {
1128
- res.status(400).json({
1129
- error: `eventTypes[${i}]: missing required fields (type, category)`
1130
- });
1131
- return;
1132
- }
1133
- }
1134
- const schema = storage.registerSchema(body);
1135
- res.status(201).json(schema);
1136
- } catch (error) {
1137
- res.status(500).json({ error: "Failed to register schema" });
1138
- }
1139
- });
1140
- router.get("/", (_req, res) => {
1141
- try {
1142
- const schemas = storage.listSchemas();
1143
- res.json({ count: schemas.length, schemas });
1144
- } catch (error) {
1145
- res.status(500).json({ error: "Failed to list schemas" });
1146
- }
1147
- });
1148
- router.get("/:id", (req, res) => {
1149
- try {
1150
- const schema = storage.getSchema(req.params.id);
1151
- if (!schema) {
1152
- res.status(404).json({ error: "Schema not found" });
1153
- return;
1154
- }
1155
- res.json(schema);
1156
- } catch (error) {
1157
- res.status(500).json({ error: "Failed to get schema" });
1158
- }
1159
- });
1160
- return router;
1161
- }
1162
- function createEventsRouter(options) {
1163
- const router = Router11();
1164
- const { storage, serverConfig, onEventReceived } = options;
1165
- let insertsSincePrune2 = 0;
1166
- router.post("/", (req, res) => {
1167
- try {
1168
- const body = req.body;
1169
- if (!body.schemaId || !body.service || !Array.isArray(body.events)) {
1170
- res.status(400).json({
1171
- error: "Expected { schemaId, service, events: [...] }"
1172
- });
1173
- return;
1174
- }
1175
- const { schemaId, service, events } = body;
1176
- const schema = storage.getSchema(schemaId);
1177
- if (!schema) {
1178
- res.status(404).json({
1179
- error: `Schema "${schemaId}" not found. Register it first via POST /api/schemas.`
1180
- });
1181
- return;
1182
- }
1183
- if (events.length > serverConfig.maxBatchSize) {
1184
- res.status(413).json({
1185
- error: `Batch too large: ${events.length} events, max ${serverConfig.maxBatchSize}`
1186
- });
1187
- return;
1188
- }
1189
- for (let i = 0; i < events.length; i++) {
1190
- const e = events[i];
1191
- if (!e.type) {
1192
- res.status(400).json({
1193
- error: `events[${i}]: missing required field "type"`
1194
- });
1195
- return;
1196
- }
1197
- }
1198
- const result = storage.insertEventBatch(schemaId, service, events);
1199
- if (onEventReceived) {
1200
- const typeMap = /* @__PURE__ */ new Map();
1201
- for (const et of schema.eventTypes) {
1202
- typeMap.set(et.type, et.category);
1203
- }
1204
- for (const input of events) {
1205
- const evt = {
1206
- id: input.id || "",
1207
- schemaId,
1208
- eventType: input.type,
1209
- category: typeMap.get(input.type) || "unknown",
1210
- timestamp: input.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
1211
- scopeValue: input.scopeValue != null ? String(input.scopeValue) : void 0,
1212
- sessionId: input.sessionId,
1213
- service,
1214
- data: input.data,
1215
- severity: input.severity || "info",
1216
- parentEventId: input.parentEventId,
1217
- depth: input.depth
1218
- };
1219
- onEventReceived(evt);
1220
- }
1221
- }
1222
- insertsSincePrune2 += result.accepted;
1223
- if (serverConfig.maxLogs > 0 && insertsSincePrune2 >= serverConfig.pruneIntervalInserts) {
1224
- insertsSincePrune2 = 0;
1225
- storage.pruneEvents(serverConfig.maxLogs);
1226
- }
1227
- res.json({
1228
- accepted: result.accepted,
1229
- errors: result.errors.length > 0 ? result.errors : void 0
1230
- });
1231
- } catch (error) {
1232
- res.status(500).json({ error: "Failed to ingest events" });
1233
- }
1234
- });
1235
- router.get("/", (req, res) => {
1236
- try {
1237
- const query = {
1238
- schemaId: req.query.schemaId,
1239
- eventType: req.query.eventType,
1240
- category: req.query.category,
1241
- service: req.query.service,
1242
- sessionId: req.query.sessionId,
1243
- scopeValue: req.query.scopeValue,
1244
- scopeFrom: req.query.scopeFrom,
1245
- scopeTo: req.query.scopeTo,
1246
- severity: req.query.severity,
1247
- since: req.query.since,
1248
- until: req.query.until,
1249
- search: req.query.search,
1250
- limit: req.query.limit ? parseInt(req.query.limit) : 100,
1251
- offset: req.query.offset ? parseInt(req.query.offset) : 0
1252
- };
1253
- const events = storage.queryEvents(query);
1254
- const total = storage.getEventCount(query);
1255
- res.json({ count: events.length, total, events });
1256
- } catch (error) {
1257
- res.status(500).json({ error: "Failed to query events" });
1258
- }
1259
- });
1260
- router.get("/scopes", (req, res) => {
1261
- try {
1262
- const schemaId = req.query.schemaId;
1263
- if (!schemaId) {
1264
- res.status(400).json({ error: "schemaId query parameter is required" });
1265
- return;
1266
- }
1267
- const scopes = storage.getEventScopes(schemaId, {
1268
- limit: req.query.limit ? parseInt(req.query.limit) : 100,
1269
- offset: req.query.offset ? parseInt(req.query.offset) : 0,
1270
- sessionId: req.query.sessionId
1271
- });
1272
- res.json({ count: scopes.length, scopes });
1273
- } catch (error) {
1274
- res.status(500).json({ error: "Failed to query scopes" });
1275
- }
1276
- });
1277
- router.get("/scope/:value", (req, res) => {
1278
- try {
1279
- const schemaId = req.query.schemaId;
1280
- if (!schemaId) {
1281
- res.status(400).json({ error: "schemaId query parameter is required" });
1282
- return;
1283
- }
1284
- const events = storage.queryEventsByScope(schemaId, req.params.value);
1285
- res.json({ count: events.length, events });
1286
- } catch (error) {
1287
- res.status(500).json({ error: "Failed to query scope events" });
1288
- }
1289
- });
1290
- return router;
1291
- }
1292
- function createAuthMiddleware(config) {
1293
- return function authMiddleware(requiredPermission) {
1294
- return (req, res, next) => {
1295
- if (!config.enabled) {
1296
- next();
1297
- return;
1298
- }
1299
- const authHeader = req.headers.authorization;
1300
- if (!authHeader) {
1301
- res.status(401).json({ error: "Authentication required. Provide Authorization: Bearer <token>" });
1302
- return;
1303
- }
1304
- const match = authHeader.match(/^Bearer\s+(.+)$/i);
1305
- if (!match) {
1306
- res.status(401).json({ error: "Invalid authorization format. Use: Bearer <token>" });
1307
- return;
1308
- }
1309
- const tokenValue = match[1];
1310
- const tokenEntry = config.tokens.find((t) => t.token === tokenValue);
1311
- if (!tokenEntry) {
1312
- res.status(401).json({ error: "Invalid token" });
1313
- return;
1314
- }
1315
- if (tokenEntry.expiresAt && new Date(tokenEntry.expiresAt) < /* @__PURE__ */ new Date()) {
1316
- res.status(401).json({ error: "Token expired" });
1317
- return;
1318
- }
1319
- const permissionLevel = { read: 1, write: 2, admin: 3 };
1320
- const hasPermission = tokenEntry.permissions.some(
1321
- (p) => permissionLevel[p] >= permissionLevel[requiredPermission]
1322
- );
1323
- if (!hasPermission) {
1324
- res.status(403).json({ error: `Insufficient permissions. Required: ${requiredPermission}` });
1325
- return;
1326
- }
1327
- req.authToken = tokenEntry;
1328
- next();
1329
- };
1330
- };
1331
- }
1332
- var serviceWindows = /* @__PURE__ */ new Map();
1333
- var globalWindow = { count: 0, windowStart: Date.now() };
1334
- var WINDOW_MS = 6e4;
1335
- function getOrResetWindow(entry) {
1336
- const now = Date.now();
1337
- if (now - entry.windowStart > WINDOW_MS) {
1338
- entry.count = 0;
1339
- entry.windowStart = now;
1340
- }
1341
- return entry;
1342
- }
1343
- function createRateLimiter(config) {
1344
- return (req, res, next) => {
1345
- if (!config.enabled) {
1346
- next();
1347
- return;
1348
- }
1349
- const service = req.body?.service || req.body?.entries?.[0]?.service || req.query.service || "_unknown";
1350
- const rule = config.perService[service] || config.global;
1351
- if (rule.samplingRate < 1 && Math.random() > rule.samplingRate) {
1352
- res.status(200).json({ accepted: 0, sampled: true, message: "Request dropped by sampling" });
1353
- return;
1354
- }
1355
- const gw = getOrResetWindow(globalWindow);
1356
- if (gw.count >= config.global.maxRequestsPerMinute) {
1357
- res.status(429).json({
1358
- error: "Global rate limit exceeded",
1359
- retryAfterMs: WINDOW_MS - (Date.now() - gw.windowStart)
1360
- });
1361
- return;
1362
- }
1363
- if (!serviceWindows.has(service)) {
1364
- serviceWindows.set(service, { count: 0, windowStart: Date.now() });
1365
- }
1366
- const sw = getOrResetWindow(serviceWindows.get(service));
1367
- if (sw.count >= rule.maxRequestsPerMinute) {
1368
- res.status(429).json({
1369
- error: `Rate limit exceeded for service: ${service}`,
1370
- retryAfterMs: WINDOW_MS - (Date.now() - sw.windowStart)
1371
- });
1372
- return;
1373
- }
1374
- const batchSize = req.body?.entries?.length || 1;
1375
- if (batchSize > rule.maxEntriesPerBatch) {
1376
- res.status(413).json({
1377
- error: `Batch too large: ${batchSize} entries, max ${rule.maxEntriesPerBatch} for service ${service}`
1378
- });
1379
- return;
1380
- }
1381
- gw.count++;
1382
- sw.count++;
1383
- next();
1384
- };
1385
- }
1386
- var __filename = fileURLToPath(import.meta.url);
1387
- var __dirname = path3.dirname(__filename);
1388
- var log3 = {
1389
- component(name) {
1390
- const symbol = chalk3.magenta(`#${name}`);
1391
- return {
1392
- info: (msg, data) => {
1393
- const dataStr = data ? chalk3.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
1394
- console.log(`${chalk3.blue("\u2139")} ${symbol} ${msg}${dataStr}`);
1395
- },
1396
- success: (msg, data) => {
1397
- const dataStr = data ? chalk3.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
1398
- console.log(`${chalk3.green("\u2714")} ${symbol} ${msg}${dataStr}`);
1399
- },
1400
- warn: (msg, data) => {
1401
- const dataStr = data ? chalk3.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
1402
- console.log(`${chalk3.yellow("\u26A0")} ${symbol} ${msg}${dataStr}`);
1403
- },
1404
- error: (msg, data) => {
1405
- const dataStr = data ? chalk3.gray(` ${Object.entries(data).map(([k, v]) => `${k}=${v}`).join(" ")}`) : "";
1406
- console.error(`${chalk3.red("\u2716")} ${symbol} ${msg}${dataStr}`);
1407
- }
1408
- };
1409
- }
1410
- };
1411
- function createApp(options) {
1412
- const app = express();
1413
- app.use(express.json({ limit: "5mb" }));
1414
- app.use((_req, res, next) => {
1415
- const corsOrigin = options.serverConfig?.cors?.origin;
1416
- const origin = Array.isArray(corsOrigin) ? corsOrigin.join(", ") : corsOrigin ?? "*";
1417
- res.header("Access-Control-Allow-Origin", origin);
1418
- res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
1419
- res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
1420
- if (options.serverConfig?.cors?.credentials) {
1421
- res.header("Access-Control-Allow-Credentials", "true");
1422
- }
1423
- if (_req.method === "OPTIONS") {
1424
- res.sendStatus(204);
1425
- return;
1426
- }
1427
- next();
1428
- });
1429
- app.use("/api/symbols", createSymbolsRouter(options.projectDir));
1430
- app.use("/api/info", createInfoRouter(options.projectDir));
1431
- app.use("/api/commits", createCommitsRouter(options.projectDir));
1432
- app.use("/api/incidents", createIncidentsRouter(options.projectDir));
1433
- app.use("/api/patterns", createPatternsRouter(options.projectDir));
1434
- if (options.storage && options.serverConfig) {
1435
- const config = options.serverConfig;
1436
- const auth = createAuthMiddleware(config.auth);
1437
- const rateLimiter = createRateLimiter(config.rateLimit);
1438
- app.use("/api/logs", rateLimiter, auth("write"), createLogsRouter({
1439
- storage: options.storage,
1440
- serverConfig: config,
1441
- onLogReceived: options.onLogReceived,
1442
- symbolIndex: options.symbolIndex
1443
- }));
1444
- app.use("/api/services", rateLimiter, auth("write"), createServicesRouter({ storage: options.storage }));
1445
- app.use("/api/state", rateLimiter, auth("write"), createStateRouter({ storage: options.storage }));
1446
- app.use("/api/metrics", rateLimiter, auth("write"), createMetricsRouter({
1447
- storage: options.storage,
1448
- serverConfig: config
1449
- }));
1450
- app.use("/api/traces", rateLimiter, auth("write"), createTracesRouter({
1451
- storage: options.storage
1452
- }));
1453
- app.use("/api/schemas", rateLimiter, auth("write"), createSchemasRouter({
1454
- storage: options.storage
1455
- }));
1456
- app.use("/api/events", rateLimiter, auth("write"), createEventsRouter({
1457
- storage: options.storage,
1458
- serverConfig: config,
1459
- onEventReceived: options.onEventReceived
1460
- }));
1461
- }
1462
- app.get("/api/health", (_req, res) => {
1463
- res.json({ status: "ok", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
1464
- });
1465
- const uiCandidates = [
1466
- path3.join(__dirname, "sentinel-ui"),
1467
- // bundled: paradigm/dist/sentinel-ui/ (copied during build)
1468
- path3.join(__dirname, "..", "..", "ui", "dist"),
1469
- // standalone: sentinel/dist/server/ → sentinel/ui/dist
1470
- path3.join(__dirname, "..", "ui", "dist")
1471
- // standalone flat: sentinel/dist/ → sentinel/ui/dist
1472
- ];
1473
- const uiDistPath = uiCandidates.find((p) => fs2.existsSync(p));
1474
- if (uiDistPath) {
1475
- app.use(express.static(uiDistPath));
1476
- app.get("{*path}", (req, res) => {
1477
- if (!req.path.startsWith("/api")) {
1478
- res.sendFile(path3.join(uiDistPath, "index.html"));
1479
- }
1480
- });
1481
- }
1482
- return app;
1483
- }
1484
- async function startServer(options) {
1485
- const serverConfig = loadServerConfig(options.projectDir);
1486
- if (options.logPruneLimit !== void 0) {
1487
- serverConfig.maxLogs = options.logPruneLimit;
1488
- }
1489
- const storage = new SentinelStorage(options.dbPath);
1490
- await storage.ensureReady();
1491
- storage.registerSchema(PARADIGM_SCHEMA);
1492
- storage.registerSchema(SYMPHONY_SCHEMA);
1493
- log3.component("sentinel-server").info("Registered builtin schemas", { schemas: "paradigm-logger, paradigm-symphony" });
1494
- let symbolIndex = [];
1495
- try {
1496
- symbolIndex = await loadSymbolIndex(options.projectDir);
1497
- } catch {
1498
- log3.component("sentinel-server").warn("Could not load symbol index for validation");
1499
- }
1500
- const wsClients = /* @__PURE__ */ new Set();
1501
- function broadcast(message) {
1502
- const data = JSON.stringify(message);
1503
- for (const client of wsClients) {
1504
- if (client.readyState === WebSocket.OPEN) {
1505
- client.send(data);
1506
- }
1507
- }
1508
- }
1509
- function onLogReceived(entry, validation) {
1510
- const message = { type: "log", entry };
1511
- if (validation && !validation.known) {
1512
- message.validation = validation;
1513
- }
1514
- broadcast(message);
1515
- if (entry.symbolType === "signal" || entry.symbolType === "gate" || entry.symbolType === "flow") {
1516
- broadcast({
1517
- type: "flow_event",
1518
- flowId: entry.symbolType === "flow" ? entry.symbol : void 0,
1519
- nodeSymbol: entry.symbol,
1520
- event: entry.symbolType,
1521
- timestamp: entry.timestamp,
1522
- service: entry.service
1523
- });
1524
- }
1525
- }
1526
- function onEventReceived(event) {
1527
- broadcast({ type: "event", event });
1528
- }
1529
- const app = createApp({
1530
- ...options,
1531
- storage,
1532
- serverConfig,
1533
- symbolIndex,
1534
- onLogReceived,
1535
- onEventReceived
1536
- });
1537
- log3.component("sentinel-server").info("Starting server", { port: options.port });
1538
- log3.component("sentinel-server").info("Project directory", { path: options.projectDir });
1539
- return new Promise((resolve, reject) => {
1540
- const httpServer = http.createServer(app);
1541
- const wss = new WebSocketServer({ server: httpServer });
1542
- wss.on("connection", (ws) => {
1543
- if (wsClients.size >= serverConfig.wsMaxSubscribers) {
1544
- ws.close(1013, "Max subscribers reached");
1545
- return;
1546
- }
1547
- wsClients.add(ws);
1548
- log3.component("sentinel-ws").info("Client connected", { total: wsClients.size });
1549
- ws.on("message", (raw) => {
1550
- try {
1551
- const msg = JSON.parse(raw.toString());
1552
- if (msg.method === "ping") {
1553
- ws.send(JSON.stringify({
1554
- jsonrpc: "2.0",
1555
- result: { pong: true, timestamp: (/* @__PURE__ */ new Date()).toISOString() },
1556
- id: msg.id
1557
- }));
1558
- } else if (msg.method === "subscribe") {
1559
- ws.send(JSON.stringify({
1560
- jsonrpc: "2.0",
1561
- result: { subscribed: true },
1562
- id: msg.id
1563
- }));
1564
- } else if (msg.method === "query_logs") {
1565
- const logs = storage.queryLogs(msg.params || {});
1566
- ws.send(JSON.stringify({
1567
- jsonrpc: "2.0",
1568
- result: { logs },
1569
- id: msg.id
1570
- }));
1571
- } else if (msg.method === "query_events") {
1572
- const events = storage.queryEvents(msg.params || {});
1573
- ws.send(JSON.stringify({
1574
- jsonrpc: "2.0",
1575
- result: { events },
1576
- id: msg.id
1577
- }));
1578
- } else if (msg.method === "query_scopes") {
1579
- const { schemaId, ...rest } = msg.params || {};
1580
- const scopes = schemaId ? storage.getEventScopes(schemaId, rest) : [];
1581
- ws.send(JSON.stringify({
1582
- jsonrpc: "2.0",
1583
- result: { scopes },
1584
- id: msg.id
1585
- }));
1586
- }
1587
- } catch {
1588
- }
1589
- });
1590
- ws.on("close", () => {
1591
- wsClients.delete(ws);
1592
- log3.component("sentinel-ws").info("Client disconnected", { total: wsClients.size });
1593
- });
1594
- ws.on("error", () => {
1595
- wsClients.delete(ws);
1596
- });
1597
- });
1598
- httpServer.listen(options.port, () => {
1599
- log3.component("sentinel-server").success("Server running", { url: `http://localhost:${options.port}` });
1600
- log3.component("sentinel-ws").success("WebSocket ready", { url: `ws://localhost:${options.port}` });
1601
- if (options.open) {
1602
- import("open").then((openModule) => {
1603
- openModule.default(`http://localhost:${options.port}`);
1604
- log3.component("sentinel-server").info("Opened browser");
1605
- }).catch(() => {
1606
- log3.component("sentinel-server").warn("Could not open browser automatically");
1607
- });
1608
- }
1609
- resolve();
1610
- });
1611
- httpServer.on("error", (err) => {
1612
- if (err.code === "EADDRINUSE") {
1613
- log3.component("sentinel-server").error("Port already in use", { port: options.port });
1614
- } else {
1615
- log3.component("sentinel-server").error("Server error", { error: err.message });
1616
- }
1617
- reject(err);
1618
- });
1619
- });
1620
- }
1621
- export {
1622
- PARADIGM_SCHEMA,
1623
- SYMPHONY_SCHEMA,
1624
- SentinelStorage,
1625
- createApp,
1626
- createAuthMiddleware,
1627
- createCommitsRouter,
1628
- createEventsRouter,
1629
- createIncidentsRouter,
1630
- createInfoRouter,
1631
- createLogsRouter,
1632
- createMetricsRouter,
1633
- createPatternsRouter,
1634
- createRateLimiter,
1635
- createSchemasRouter,
1636
- createServicesRouter,
1637
- createStateRouter,
1638
- createSymbolsRouter,
1639
- createTracesRouter,
1640
- getSymbolCount,
1641
- getSymbolsAtCommit,
1642
- loadGitHistory,
1643
- loadParadigmConfig,
1644
- loadServerConfig,
1645
- loadSymbolIndex,
1646
- startServer
1647
- };