@a-company/paradigm 5.11.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 (408) 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 -20529
  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/plsat/.purpose +3 -2
  195. package/dist/university-ui/assets/{index-BjewBB6s.js → index-CGFJczb1.js} +2 -2
  196. package/dist/university-ui/assets/{index-BjewBB6s.js.map → index-CGFJczb1.js.map} +1 -1
  197. package/dist/university-ui/index.html +1 -1
  198. package/dist/upgrade-B4IOLZYK.js +53 -0
  199. package/dist/validate-C6SMKGYD.js +9 -0
  200. package/dist/validate-LSCDOLBO.js +13 -0
  201. package/dist/validate-VZXTJHGO.js +6 -0
  202. package/dist/watch-LRM5XD46.js +8 -0
  203. package/dist/watch-PZCCUP6K.js +9 -0
  204. package/dist/wisdom-XZ3QKPNP.js +7 -0
  205. package/dist/work-log-loader-DL5GZ2BQ.js +2 -0
  206. package/dist/workspace-2ODL5WLY.js +2 -0
  207. package/package.json +1 -1
  208. package/platform-ui/dist/assets/AmbientSection-DqQ2mfCO.js +1 -0
  209. package/platform-ui/dist/assets/{CanvasSection-DwPTRdIN.js → CanvasSection-DLW0s-Bu.js} +1 -1
  210. package/platform-ui/dist/assets/{DocsSection-BJc_ws4I.js → DocsSection-BQ9Hi51g.js} +1 -1
  211. package/platform-ui/dist/assets/{GitSection-DhqBo1xc.js → GitSection-QQeUX6o3.js} +1 -1
  212. package/platform-ui/dist/assets/{GraphSection-D9fhVnZ0.js → GraphSection-0c9C-w7K.js} +2 -2
  213. package/platform-ui/dist/assets/{GraphSection-BlgXTl53.css → GraphSection-Bbs2a8sC.css} +1 -1
  214. package/platform-ui/dist/assets/LoreSection--t56kCj2.js +1 -0
  215. package/platform-ui/dist/assets/LoreSection-qnmm3o4y.css +1 -0
  216. package/platform-ui/dist/assets/SentinelSection-C4OoME9U.js +1 -0
  217. package/platform-ui/dist/assets/{SymphonySection-BRoBaUSS.js → SymphonySection-B-rvsLxq.js} +1 -1
  218. package/platform-ui/dist/assets/TeamSection-CBFmNEEo.js +1 -0
  219. package/platform-ui/dist/assets/index-Bxp0TVaf.css +1 -0
  220. package/platform-ui/dist/assets/index-DPpOdAtC.js +57 -0
  221. package/platform-ui/dist/index.html +2 -2
  222. package/dist/accept-orchestration-UQLM7PTQ.js +0 -189
  223. package/dist/add-FZRKEGH4.js +0 -81
  224. package/dist/agent-WERIO2XV.js +0 -523
  225. package/dist/agent-loader-TFIANSF4.js +0 -44
  226. package/dist/agent-state-S5DAWPTF.js +0 -24
  227. package/dist/agents-suggest-DNSYJ6IA.js +0 -83
  228. package/dist/aggregate-H57K7PNV.js +0 -88
  229. package/dist/assess-4WVXZLZQ.js +0 -68
  230. package/dist/auto-QFS5NHQU.js +0 -504
  231. package/dist/beacon-KXZXYQHX.js +0 -251
  232. package/dist/calibration-V46G7JTY.js +0 -135
  233. package/dist/check-OWAIWV23.js +0 -175
  234. package/dist/chunk-2IO7JAG2.js +0 -148
  235. package/dist/chunk-2T6BTYBN.js +0 -712
  236. package/dist/chunk-36TKPM5Z.js +0 -400
  237. package/dist/chunk-45MUDW6E.js +0 -804
  238. package/dist/chunk-4BLYIB7J.js +0 -5701
  239. package/dist/chunk-4L3UTYQX.js +0 -677
  240. package/dist/chunk-4NCFWYGG.js +0 -110
  241. package/dist/chunk-54LTTQBH.js +0 -138
  242. package/dist/chunk-5EWAQHFY.js +0 -269
  243. package/dist/chunk-5JGJACDU.js +0 -37
  244. package/dist/chunk-5OUOLN6M.js +0 -659
  245. package/dist/chunk-5VKJBNJL.js +0 -444
  246. package/dist/chunk-6N3JTACN.js +0 -2260
  247. package/dist/chunk-6QC3YGB6.js +0 -114
  248. package/dist/chunk-7N7GSU6K.js +0 -34
  249. package/dist/chunk-ABVQGRF7.js +0 -268
  250. package/dist/chunk-CL7JSK52.js +0 -129
  251. package/dist/chunk-CSD7IHSN.js +0 -152
  252. package/dist/chunk-EDOAWN7J.js +0 -717
  253. package/dist/chunk-EKGMAM62.js +0 -525
  254. package/dist/chunk-EZ3GOCYC.js +0 -132
  255. package/dist/chunk-F3BCHPYT.js +0 -143
  256. package/dist/chunk-FKJUBQU3.js +0 -3081
  257. package/dist/chunk-GT5QGC2H.js +0 -253
  258. package/dist/chunk-GZDFVP2N.js +0 -540
  259. package/dist/chunk-IRKUEJVW.js +0 -405
  260. package/dist/chunk-J2JEQRT3.js +0 -164
  261. package/dist/chunk-JASGXLK3.js +0 -679
  262. package/dist/chunk-KVDYJLTC.js +0 -121
  263. package/dist/chunk-L27I3CPZ.js +0 -357
  264. package/dist/chunk-LHLIAYQ3.js +0 -185
  265. package/dist/chunk-MCMOGQMU.js +0 -145
  266. package/dist/chunk-NQKQG45G.js +0 -688
  267. package/dist/chunk-PBHIFAL4.js +0 -259
  268. package/dist/chunk-PDX44BCA.js +0 -11
  269. package/dist/chunk-PMXRGPRQ.js +0 -305
  270. package/dist/chunk-RAB5IKPR.js +0 -487
  271. package/dist/chunk-RJE5G7WO.js +0 -590
  272. package/dist/chunk-RTHA3XRE.js +0 -880
  273. package/dist/chunk-S2HO5MLR.js +0 -621
  274. package/dist/chunk-S3ORKP3V.js +0 -716
  275. package/dist/chunk-TAIJOFOE.js +0 -124
  276. package/dist/chunk-TXESEO7Y.js +0 -245
  277. package/dist/chunk-UPLDI7CN.js +0 -1334
  278. package/dist/chunk-VL67H5IC.js +0 -506
  279. package/dist/chunk-VPPK3SY4.js +0 -1136
  280. package/dist/chunk-YMDLDELF.js +0 -314
  281. package/dist/chunk-YO6DVTL7.js +0 -99
  282. package/dist/chunk-YRZ5RPEB.js +0 -1561
  283. package/dist/chunk-ZDHLG5VP.js +0 -5676
  284. package/dist/chunk-ZGUAAVMA.js +0 -756
  285. package/dist/chunk-ZSYVKSY6.js +0 -2602
  286. package/dist/claude-FRRWJSTJ.js +0 -362
  287. package/dist/claude-cli-XJLK2X4L.js +0 -276
  288. package/dist/claude-code-HTBA4XRB.js +0 -126
  289. package/dist/claude-code-teams-T4SP24MD.js +0 -199
  290. package/dist/commands-5N4ILTPH.js +0 -5859
  291. package/dist/conductor-CQVGTEQN.js +0 -161
  292. package/dist/config-schema-EA4XALGG.js +0 -154
  293. package/dist/constellation-A26CCGQS.js +0 -225
  294. package/dist/context-audit-RLO3ETRP.js +0 -682
  295. package/dist/cost-BGM32XJU.js +0 -93
  296. package/dist/cost-VI46A4XL.js +0 -174
  297. package/dist/cursor-cli-JVEZGHWQ.js +0 -269
  298. package/dist/cursorrules-HLIKJJZT.js +0 -84
  299. package/dist/decision-loader-WWCLIQPJ.js +0 -20
  300. package/dist/delete-KBRPQLPC.js +0 -56
  301. package/dist/diff-D4X53HAC.js +0 -126
  302. package/dist/discipline-FA4OZXIS.js +0 -24
  303. package/dist/dist-34NA5RS5.js +0 -74
  304. package/dist/dist-5QE2BB2B-5S3T6Y3T.js +0 -6919
  305. package/dist/dist-77JDTVAY.js +0 -62
  306. package/dist/dist-OGTSAZ55.js +0 -1358
  307. package/dist/dist-QK4SQAK7.js +0 -64
  308. package/dist/dist-TA6LSC2Q.js +0 -20
  309. package/dist/docs-PBZB7LYP.js +0 -89
  310. package/dist/docs-QIYKO3BR.js +0 -155
  311. package/dist/doctor-ULBOHEIC.js +0 -11
  312. package/dist/drift-R5NRKFHI.js +0 -251
  313. package/dist/echo-O2LY7CC2.js +0 -248
  314. package/dist/edit-R2HNLMOG.js +0 -63
  315. package/dist/event-25OJKDCE.js +0 -31
  316. package/dist/export-IWVL7XLF.js +0 -38
  317. package/dist/flow-CRRVV3O3.js +0 -185
  318. package/dist/global-3NG5JXUB.js +0 -136
  319. package/dist/graduate-USAWGBJM.js +0 -160
  320. package/dist/graph-VHUMAAS6.js +0 -12
  321. package/dist/graph-server-YL22VBBN.js +0 -116
  322. package/dist/habits-OL5NGPXO.js +0 -1405
  323. package/dist/history-WOWC573W.js +0 -277
  324. package/dist/hooks-HFWSCGPV.js +0 -12
  325. package/dist/integrity-IHO4FZTS.js +0 -194
  326. package/dist/integrity-checker-PSKJA5SB.js +0 -12
  327. package/dist/journal-loader-5EYSBFFY.js +0 -18
  328. package/dist/lint-K6CJGGPH.js +0 -456
  329. package/dist/list-4YK7QKFF.js +0 -57
  330. package/dist/list-ENR7Q4CR.js +0 -56
  331. package/dist/lore-loader-7NO6N6FT.js +0 -26
  332. package/dist/lore-server-UNJY5KC3.js +0 -118
  333. package/dist/manual-G6FISID5.js +0 -204
  334. package/dist/migrate-LS45DNEV.js +0 -889
  335. package/dist/migrate-assessments-RGH4O6IX.js +0 -97
  336. package/dist/model-discovery-D2H3VBGC.js +0 -8
  337. package/dist/nomination-engine-RV5CNO5B.js +0 -42
  338. package/dist/notebook-YWIYGEHV.js +0 -155
  339. package/dist/orchestrate-JLILBBJE.js +0 -324
  340. package/dist/peers-DEOUIZM6.js +0 -82
  341. package/dist/persona-UHAHIVST.js +0 -390
  342. package/dist/pipeline-L4HCSBGN.js +0 -263
  343. package/dist/platform-server-H5YO3DQD.js +0 -1475
  344. package/dist/plugin-update-checker-KRRSGXMV.js +0 -12
  345. package/dist/portal-check-NPYGII2D.js +0 -42
  346. package/dist/portal-compliance-J7DGAPFX.js +0 -18
  347. package/dist/probe-MHL5HQZ2.js +0 -167
  348. package/dist/promote-F6ZYZZAL.js +0 -182
  349. package/dist/providers-GK7PB2OL.js +0 -104
  350. package/dist/quiz-M66SC7F7.js +0 -99
  351. package/dist/record-RA4WR2BO.js +0 -49
  352. package/dist/reindex-5LTD53ZC.js +0 -16
  353. package/dist/remember-HBWJ655S.js +0 -77
  354. package/dist/retag-3OLCVDEQ.js +0 -62
  355. package/dist/review-27ATYTD2.js +0 -33
  356. package/dist/review-57QMURZV.js +0 -334
  357. package/dist/ripple-JPBXP5I3.js +0 -215
  358. package/dist/sentinel-4XIG4STA.js +0 -63
  359. package/dist/sentinel-bridge-MDUXTQRL.js +0 -109
  360. package/dist/serve-CAH3PHE7.js +0 -33
  361. package/dist/serve-INL7SNBK.js +0 -36
  362. package/dist/serve-KBSE36PL.js +0 -49
  363. package/dist/server-54SKYFFY.js +0 -1647
  364. package/dist/server-XUOIO7E6.js +0 -338
  365. package/dist/session-tracker-C4BMD5WG.js +0 -13
  366. package/dist/session-work-log-MZ47OAPB.js +0 -20
  367. package/dist/setup-EDS27WUR.js +0 -25
  368. package/dist/setup-KO5AFC4K.js +0 -296
  369. package/dist/shift-D2JOHHBF.js +0 -668
  370. package/dist/show-5PV5KFJE.js +0 -176
  371. package/dist/show-NQKYX6WQ.js +0 -82
  372. package/dist/snapshot-BK4RBPCG.js +0 -62
  373. package/dist/spawn-RCHNXDHE.js +0 -196
  374. package/dist/status-WGIAQODY.js +0 -71
  375. package/dist/summary-NIRABMF5.js +0 -140
  376. package/dist/sweep-QMHNSIY5.js +0 -934
  377. package/dist/switch-6EJPZDIA.js +0 -232
  378. package/dist/symphony-4OCY36AI.js +0 -791
  379. package/dist/symphony-B75X2MME.js +0 -326
  380. package/dist/symphony-loader-UZGON56V.js +0 -90
  381. package/dist/symphony-peers-2ZQYLRNI.js +0 -34
  382. package/dist/symphony-peers-OL7F6M5S.js +0 -121
  383. package/dist/symphony-relay-UJYUXN65.js +0 -710
  384. package/dist/sync-VEHUH4OA.js +0 -11
  385. package/dist/sync-llms-YHCFIE6X.js +0 -166
  386. package/dist/task-loader-LDYWQSLM.js +0 -20
  387. package/dist/team-O5MIIFMA.js +0 -34
  388. package/dist/test-566CP5KC.js +0 -1017
  389. package/dist/thread-N754I4D5.js +0 -274
  390. package/dist/timeline-M3CICQFE.js +0 -112
  391. package/dist/triage-HHYGT3HY.js +0 -671
  392. package/dist/tutorial-KD22SUNO.js +0 -666
  393. package/dist/upgrade-H5PF32BW.js +0 -551
  394. package/dist/validate-CNKEKO6A.js +0 -134
  395. package/dist/validate-MB5ULIHS.js +0 -39
  396. package/dist/validate-QH3LADM6.js +0 -64
  397. package/dist/watch-2TKP5PVL.js +0 -199
  398. package/dist/watch-ZF4ML6CD.js +0 -111
  399. package/dist/wisdom-AATMGNFA.js +0 -319
  400. package/dist/work-log-loader-5L45XNYZ.js +0 -14
  401. package/dist/workspace-6E6OSRNU.js +0 -21
  402. package/platform-ui/dist/assets/AmbientSection-WtHfNedO.js +0 -1
  403. package/platform-ui/dist/assets/LoreSection-C3EixkjW.css +0 -1
  404. package/platform-ui/dist/assets/LoreSection-CwDDHrz9.js +0 -1
  405. package/platform-ui/dist/assets/SentinelSection-Cl7e5oZ6.js +0 -1
  406. package/platform-ui/dist/assets/TeamSection-CqSIMrKz.js +0 -1
  407. package/platform-ui/dist/assets/index-CfpZFjea.css +0 -1
  408. 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
- };