@terminals-tech/agent-zero 1.0.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 (263) hide show
  1. package/README.md +209 -0
  2. package/bin/agent-zero.js +332 -0
  3. package/dist/agency/commandRouter.d.ts +48 -0
  4. package/dist/agency/commandRouter.d.ts.map +1 -0
  5. package/dist/agency/commandRouter.js +343 -0
  6. package/dist/agency/commandRouter.js.map +1 -0
  7. package/dist/agency/runtime.d.ts +66 -0
  8. package/dist/agency/runtime.d.ts.map +1 -0
  9. package/dist/agency/runtime.js +247 -0
  10. package/dist/agency/runtime.js.map +1 -0
  11. package/dist/agency/summaryGenerator.d.ts +39 -0
  12. package/dist/agency/summaryGenerator.d.ts.map +1 -0
  13. package/dist/agency/summaryGenerator.js +110 -0
  14. package/dist/agency/summaryGenerator.js.map +1 -0
  15. package/dist/agency/summaryScheduler.d.ts +33 -0
  16. package/dist/agency/summaryScheduler.d.ts.map +1 -0
  17. package/dist/agency/summaryScheduler.js +68 -0
  18. package/dist/agency/summaryScheduler.js.map +1 -0
  19. package/dist/browser/agent-runtime/RuntimePanel.d.ts +20 -0
  20. package/dist/browser/agent-runtime/RuntimePanel.d.ts.map +1 -0
  21. package/dist/browser/agent-runtime/RuntimePanel.js +203 -0
  22. package/dist/browser/agent-runtime/RuntimePanel.js.map +1 -0
  23. package/dist/browser/agent-runtime/config.d.ts +28 -0
  24. package/dist/browser/agent-runtime/config.d.ts.map +1 -0
  25. package/dist/browser/agent-runtime/config.js +50 -0
  26. package/dist/browser/agent-runtime/config.js.map +1 -0
  27. package/dist/browser/agent-runtime/launcher.d.ts +71 -0
  28. package/dist/browser/agent-runtime/launcher.d.ts.map +1 -0
  29. package/dist/browser/agent-runtime/launcher.js +167 -0
  30. package/dist/browser/agent-runtime/launcher.js.map +1 -0
  31. package/dist/browser/rail-auth-bridge.d.ts +85 -0
  32. package/dist/browser/rail-auth-bridge.d.ts.map +1 -0
  33. package/dist/browser/rail-auth-bridge.js +209 -0
  34. package/dist/browser/rail-auth-bridge.js.map +1 -0
  35. package/dist/channels/index.d.ts +13 -0
  36. package/dist/channels/index.d.ts.map +1 -0
  37. package/dist/channels/index.js +12 -0
  38. package/dist/channels/index.js.map +1 -0
  39. package/dist/channels/moltbook.d.ts +114 -0
  40. package/dist/channels/moltbook.d.ts.map +1 -0
  41. package/dist/channels/moltbook.js +348 -0
  42. package/dist/channels/moltbook.js.map +1 -0
  43. package/dist/channels/sms.d.ts +33 -0
  44. package/dist/channels/sms.d.ts.map +1 -0
  45. package/dist/channels/sms.js +160 -0
  46. package/dist/channels/sms.js.map +1 -0
  47. package/dist/channels/telegram.d.ts +47 -0
  48. package/dist/channels/telegram.d.ts.map +1 -0
  49. package/dist/channels/telegram.js +276 -0
  50. package/dist/channels/telegram.js.map +1 -0
  51. package/dist/channels/twitter.d.ts +93 -0
  52. package/dist/channels/twitter.d.ts.map +1 -0
  53. package/dist/channels/twitter.js +411 -0
  54. package/dist/channels/twitter.js.map +1 -0
  55. package/dist/channels/whatsapp.d.ts +77 -0
  56. package/dist/channels/whatsapp.d.ts.map +1 -0
  57. package/dist/channels/whatsapp.js +514 -0
  58. package/dist/channels/whatsapp.js.map +1 -0
  59. package/dist/checkout/index.d.ts +92 -0
  60. package/dist/checkout/index.d.ts.map +1 -0
  61. package/dist/checkout/index.js +125 -0
  62. package/dist/checkout/index.js.map +1 -0
  63. package/dist/cli/moltbook.d.ts +11 -0
  64. package/dist/cli/moltbook.d.ts.map +1 -0
  65. package/dist/cli/moltbook.js +259 -0
  66. package/dist/cli/moltbook.js.map +1 -0
  67. package/dist/cli/setup.d.ts +10 -0
  68. package/dist/cli/setup.d.ts.map +1 -0
  69. package/dist/cli/setup.js +232 -0
  70. package/dist/cli/setup.js.map +1 -0
  71. package/dist/coherence/absorption.d.ts +141 -0
  72. package/dist/coherence/absorption.d.ts.map +1 -0
  73. package/dist/coherence/absorption.js +343 -0
  74. package/dist/coherence/absorption.js.map +1 -0
  75. package/dist/coherence/crossPlatform.d.ts +55 -0
  76. package/dist/coherence/crossPlatform.d.ts.map +1 -0
  77. package/dist/coherence/crossPlatform.js +219 -0
  78. package/dist/coherence/crossPlatform.js.map +1 -0
  79. package/dist/coherence/identityResolver.d.ts +27 -0
  80. package/dist/coherence/identityResolver.d.ts.map +1 -0
  81. package/dist/coherence/identityResolver.js +102 -0
  82. package/dist/coherence/identityResolver.js.map +1 -0
  83. package/dist/identity/burner.d.ts +100 -0
  84. package/dist/identity/burner.d.ts.map +1 -0
  85. package/dist/identity/burner.js +256 -0
  86. package/dist/identity/burner.js.map +1 -0
  87. package/dist/identity/burnerScheduler.d.ts +18 -0
  88. package/dist/identity/burnerScheduler.d.ts.map +1 -0
  89. package/dist/identity/burnerScheduler.js +82 -0
  90. package/dist/identity/burnerScheduler.js.map +1 -0
  91. package/dist/identity/moltbookBurnerAdapter.d.ts +14 -0
  92. package/dist/identity/moltbookBurnerAdapter.d.ts.map +1 -0
  93. package/dist/identity/moltbookBurnerAdapter.js +82 -0
  94. package/dist/identity/moltbookBurnerAdapter.js.map +1 -0
  95. package/dist/identity/operationalVault.d.ts +108 -0
  96. package/dist/identity/operationalVault.d.ts.map +1 -0
  97. package/dist/identity/operationalVault.js +259 -0
  98. package/dist/identity/operationalVault.js.map +1 -0
  99. package/dist/index.d.ts +43 -0
  100. package/dist/index.d.ts.map +1 -0
  101. package/dist/index.js +57 -0
  102. package/dist/index.js.map +1 -0
  103. package/dist/moltbook/apiErrorHandler.d.ts +48 -0
  104. package/dist/moltbook/apiErrorHandler.d.ts.map +1 -0
  105. package/dist/moltbook/apiErrorHandler.js +125 -0
  106. package/dist/moltbook/apiErrorHandler.js.map +1 -0
  107. package/dist/moltbook/approvalGate.d.ts +81 -0
  108. package/dist/moltbook/approvalGate.d.ts.map +1 -0
  109. package/dist/moltbook/approvalGate.js +211 -0
  110. package/dist/moltbook/approvalGate.js.map +1 -0
  111. package/dist/moltbook/attentionField.d.ts +55 -0
  112. package/dist/moltbook/attentionField.d.ts.map +1 -0
  113. package/dist/moltbook/attentionField.js +163 -0
  114. package/dist/moltbook/attentionField.js.map +1 -0
  115. package/dist/moltbook/contentEnhancer.d.ts +28 -0
  116. package/dist/moltbook/contentEnhancer.d.ts.map +1 -0
  117. package/dist/moltbook/contentEnhancer.js +129 -0
  118. package/dist/moltbook/contentEnhancer.js.map +1 -0
  119. package/dist/moltbook/daemon.d.ts +111 -0
  120. package/dist/moltbook/daemon.d.ts.map +1 -0
  121. package/dist/moltbook/daemon.js +497 -0
  122. package/dist/moltbook/daemon.js.map +1 -0
  123. package/dist/moltbook/observer.d.ts +44 -0
  124. package/dist/moltbook/observer.d.ts.map +1 -0
  125. package/dist/moltbook/observer.js +71 -0
  126. package/dist/moltbook/observer.js.map +1 -0
  127. package/dist/moltbook/responseComposer.d.ts +54 -0
  128. package/dist/moltbook/responseComposer.d.ts.map +1 -0
  129. package/dist/moltbook/responseComposer.js +233 -0
  130. package/dist/moltbook/responseComposer.js.map +1 -0
  131. package/dist/openclaw/gateway.d.ts +45 -0
  132. package/dist/openclaw/gateway.d.ts.map +1 -0
  133. package/dist/openclaw/gateway.js +139 -0
  134. package/dist/openclaw/gateway.js.map +1 -0
  135. package/dist/openclaw/skill.d.ts +185 -0
  136. package/dist/openclaw/skill.d.ts.map +1 -0
  137. package/dist/openclaw/skill.js +297 -0
  138. package/dist/openclaw/skill.js.map +1 -0
  139. package/dist/primitives/index.d.ts +23 -0
  140. package/dist/primitives/index.d.ts.map +1 -0
  141. package/dist/primitives/index.js +27 -0
  142. package/dist/primitives/index.js.map +1 -0
  143. package/dist/primitives/types.d.ts +673 -0
  144. package/dist/primitives/types.d.ts.map +1 -0
  145. package/dist/primitives/types.js +205 -0
  146. package/dist/primitives/types.js.map +1 -0
  147. package/dist/rail/absorptionBridge.d.ts +47 -0
  148. package/dist/rail/absorptionBridge.d.ts.map +1 -0
  149. package/dist/rail/absorptionBridge.js +78 -0
  150. package/dist/rail/absorptionBridge.js.map +1 -0
  151. package/dist/rail/authProtocol.d.ts +32 -0
  152. package/dist/rail/authProtocol.d.ts.map +1 -0
  153. package/dist/rail/authProtocol.js +83 -0
  154. package/dist/rail/authProtocol.js.map +1 -0
  155. package/dist/rail/clientRateLimiter.d.ts +17 -0
  156. package/dist/rail/clientRateLimiter.d.ts.map +1 -0
  157. package/dist/rail/clientRateLimiter.js +64 -0
  158. package/dist/rail/clientRateLimiter.js.map +1 -0
  159. package/dist/rail/index.d.ts +8 -0
  160. package/dist/rail/index.d.ts.map +1 -0
  161. package/dist/rail/index.js +38 -0
  162. package/dist/rail/index.js.map +1 -0
  163. package/dist/rail/jwtVerifier.d.ts +11 -0
  164. package/dist/rail/jwtVerifier.d.ts.map +1 -0
  165. package/dist/rail/jwtVerifier.js +55 -0
  166. package/dist/rail/jwtVerifier.js.map +1 -0
  167. package/dist/rail/logger.d.ts +13 -0
  168. package/dist/rail/logger.d.ts.map +1 -0
  169. package/dist/rail/logger.js +29 -0
  170. package/dist/rail/logger.js.map +1 -0
  171. package/dist/rail/metadataBroadcaster.d.ts +53 -0
  172. package/dist/rail/metadataBroadcaster.d.ts.map +1 -0
  173. package/dist/rail/metadataBroadcaster.js +126 -0
  174. package/dist/rail/metadataBroadcaster.js.map +1 -0
  175. package/dist/rail/persistence.d.ts +57 -0
  176. package/dist/rail/persistence.d.ts.map +1 -0
  177. package/dist/rail/persistence.js +103 -0
  178. package/dist/rail/persistence.js.map +1 -0
  179. package/dist/rail/securityMonitor.d.ts +23 -0
  180. package/dist/rail/securityMonitor.d.ts.map +1 -0
  181. package/dist/rail/securityMonitor.js +52 -0
  182. package/dist/rail/securityMonitor.js.map +1 -0
  183. package/dist/rail/server.d.ts +186 -0
  184. package/dist/rail/server.d.ts.map +1 -0
  185. package/dist/rail/server.js +568 -0
  186. package/dist/rail/server.js.map +1 -0
  187. package/dist/rail/userSessionManager.d.ts +29 -0
  188. package/dist/rail/userSessionManager.d.ts.map +1 -0
  189. package/dist/rail/userSessionManager.js +87 -0
  190. package/dist/rail/userSessionManager.js.map +1 -0
  191. package/dist/rail/wsServer.d.ts +39 -0
  192. package/dist/rail/wsServer.d.ts.map +1 -0
  193. package/dist/rail/wsServer.js +544 -0
  194. package/dist/rail/wsServer.js.map +1 -0
  195. package/dist/resonance/globalKuramoto.d.ts +67 -0
  196. package/dist/resonance/globalKuramoto.d.ts.map +1 -0
  197. package/dist/resonance/globalKuramoto.js +161 -0
  198. package/dist/resonance/globalKuramoto.js.map +1 -0
  199. package/dist/resonance/index.d.ts +12 -0
  200. package/dist/resonance/index.d.ts.map +1 -0
  201. package/dist/resonance/index.js +9 -0
  202. package/dist/resonance/index.js.map +1 -0
  203. package/dist/resonance/kuramoto.d.ts +118 -0
  204. package/dist/resonance/kuramoto.d.ts.map +1 -0
  205. package/dist/resonance/kuramoto.js +212 -0
  206. package/dist/resonance/kuramoto.js.map +1 -0
  207. package/dist/routing/distributedRouter.d.ts +84 -0
  208. package/dist/routing/distributedRouter.d.ts.map +1 -0
  209. package/dist/routing/distributedRouter.js +209 -0
  210. package/dist/routing/distributedRouter.js.map +1 -0
  211. package/dist/routing/index.d.ts +8 -0
  212. package/dist/routing/index.d.ts.map +1 -0
  213. package/dist/routing/index.js +7 -0
  214. package/dist/routing/index.js.map +1 -0
  215. package/dist/routing/thermodynamic.d.ts +91 -0
  216. package/dist/routing/thermodynamic.d.ts.map +1 -0
  217. package/dist/routing/thermodynamic.js +184 -0
  218. package/dist/routing/thermodynamic.js.map +1 -0
  219. package/dist/runtime/agent-zero.d.ts +138 -0
  220. package/dist/runtime/agent-zero.d.ts.map +1 -0
  221. package/dist/runtime/agent-zero.js +435 -0
  222. package/dist/runtime/agent-zero.js.map +1 -0
  223. package/dist/runtime/index.d.ts +13 -0
  224. package/dist/runtime/index.d.ts.map +1 -0
  225. package/dist/runtime/index.js +15 -0
  226. package/dist/runtime/index.js.map +1 -0
  227. package/dist/security/capabilities.d.ts +178 -0
  228. package/dist/security/capabilities.d.ts.map +1 -0
  229. package/dist/security/capabilities.js +270 -0
  230. package/dist/security/capabilities.js.map +1 -0
  231. package/dist/security/channelFirewallMiddleware.d.ts +22 -0
  232. package/dist/security/channelFirewallMiddleware.d.ts.map +1 -0
  233. package/dist/security/channelFirewallMiddleware.js +52 -0
  234. package/dist/security/channelFirewallMiddleware.js.map +1 -0
  235. package/dist/security/index.d.ts +11 -0
  236. package/dist/security/index.d.ts.map +1 -0
  237. package/dist/security/index.js +11 -0
  238. package/dist/security/index.js.map +1 -0
  239. package/dist/security/injectionFirewall.d.ts +47 -0
  240. package/dist/security/injectionFirewall.d.ts.map +1 -0
  241. package/dist/security/injectionFirewall.js +262 -0
  242. package/dist/security/injectionFirewall.js.map +1 -0
  243. package/dist/security/outputSanitizer.d.ts +28 -0
  244. package/dist/security/outputSanitizer.d.ts.map +1 -0
  245. package/dist/security/outputSanitizer.js +66 -0
  246. package/dist/security/outputSanitizer.js.map +1 -0
  247. package/dist/security/sandbox.d.ts +192 -0
  248. package/dist/security/sandbox.d.ts.map +1 -0
  249. package/dist/security/sandbox.js +359 -0
  250. package/dist/security/sandbox.js.map +1 -0
  251. package/dist/security/skillVerify.d.ts +128 -0
  252. package/dist/security/skillVerify.d.ts.map +1 -0
  253. package/dist/security/skillVerify.js +220 -0
  254. package/dist/security/skillVerify.js.map +1 -0
  255. package/dist/security/vault.d.ts +60 -0
  256. package/dist/security/vault.d.ts.map +1 -0
  257. package/dist/security/vault.js +522 -0
  258. package/dist/security/vault.js.map +1 -0
  259. package/dist/utils/persistentRateLimiter.d.ts +69 -0
  260. package/dist/utils/persistentRateLimiter.d.ts.map +1 -0
  261. package/dist/utils/persistentRateLimiter.js +128 -0
  262. package/dist/utils/persistentRateLimiter.js.map +1 -0
  263. package/package.json +95 -0
@@ -0,0 +1,55 @@
1
+ /**
2
+ * JWT Verifier for Supabase tokens.
3
+ * Uses HMAC-SHA256 with shared JWT secret (from Supabase project settings).
4
+ */
5
+ import { createHmac } from 'crypto';
6
+ function base64UrlDecode(str) {
7
+ const padded = str.replace(/-/g, '+').replace(/_/g, '/');
8
+ return Buffer.from(padded, 'base64').toString('utf-8');
9
+ }
10
+ function base64UrlEncode(buf) {
11
+ return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
12
+ }
13
+ export function verifyUserToken(jwt) {
14
+ const secret = process.env['SUPABASE_JWT_SECRET'];
15
+ if (!secret)
16
+ return null;
17
+ const parts = jwt.split('.');
18
+ if (parts.length !== 3)
19
+ return null;
20
+ try {
21
+ // Verify signature
22
+ const signatureInput = `${parts[0]}.${parts[1]}`;
23
+ const expectedSig = base64UrlEncode(createHmac('sha256', secret).update(signatureInput).digest());
24
+ // Timing-safe comparison
25
+ if (expectedSig.length !== parts[2].length)
26
+ return null;
27
+ const a = Buffer.from(expectedSig);
28
+ const b = Buffer.from(parts[2]);
29
+ if (a.length !== b.length)
30
+ return null;
31
+ let diff = 0;
32
+ for (let i = 0; i < a.length; i++) {
33
+ diff |= (a[i] ?? 0) ^ (b[i] ?? 0);
34
+ }
35
+ if (diff !== 0)
36
+ return null;
37
+ // Decode payload
38
+ const payload = JSON.parse(base64UrlDecode(parts[1]));
39
+ // Check expiration
40
+ if (payload.exp && payload.exp < Math.floor(Date.now() / 1000))
41
+ return null;
42
+ // Check required fields
43
+ if (!payload.sub)
44
+ return null;
45
+ return {
46
+ userId: payload.sub,
47
+ email: payload.email ?? '',
48
+ metadata: payload.user_metadata,
49
+ };
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ //# sourceMappingURL=jwtVerifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwtVerifier.js","sourceRoot":"","sources":["../../src/rail/jwtVerifier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAQpC,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,IAAI,CAAC;QACH,mBAAmB;QACnB,MAAM,cAAc,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,WAAW,GAAG,eAAe,CACjC,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAC7D,CAAC;QAEF,yBAAyB;QACzB,IAAI,WAAW,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACxD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACvC,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,IAAI,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE5B,iBAAiB;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAOnD,CAAC;QAEF,mBAAmB;QACnB,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QAE5E,wBAAwB;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAE9B,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,GAAG;YACnB,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;YAC1B,QAAQ,EAAE,OAAO,CAAC,aAAa;SAChC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Structured JSON logger for rail server.
3
+ * Fly.io captures stdout automatically.
4
+ */
5
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
6
+ export declare function log(level: LogLevel, component: string, message: string, data?: Record<string, unknown>): void;
7
+ export declare const railLog: {
8
+ debug: (component: string, msg: string, data?: Record<string, unknown>) => void;
9
+ info: (component: string, msg: string, data?: Record<string, unknown>) => void;
10
+ warn: (component: string, msg: string, data?: Record<string, unknown>) => void;
11
+ error: (component: string, msg: string, data?: Record<string, unknown>) => void;
12
+ };
13
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/rail/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAM3D,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAY7G;AAED,eAAO,MAAM,OAAO;uBACC,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;sBACpD,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;sBACnD,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;uBAClD,MAAM,OAAO,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CACvE,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Structured JSON logger for rail server.
3
+ * Fly.io captures stdout automatically.
4
+ */
5
+ const LEVEL_PRIORITY = { debug: 0, info: 1, warn: 2, error: 3 };
6
+ const minLevel = process.env['LOG_LEVEL'] || 'info';
7
+ export function log(level, component, message, data) {
8
+ if (LEVEL_PRIORITY[level] < LEVEL_PRIORITY[minLevel])
9
+ return;
10
+ const entry = {
11
+ ts: new Date().toISOString(),
12
+ level,
13
+ component,
14
+ msg: message,
15
+ ...data,
16
+ };
17
+ const line = JSON.stringify(entry);
18
+ if (level === 'error')
19
+ process.stderr.write(line + '\n');
20
+ else
21
+ process.stdout.write(line + '\n');
22
+ }
23
+ export const railLog = {
24
+ debug: (component, msg, data) => log('debug', component, msg, data),
25
+ info: (component, msg, data) => log('info', component, msg, data),
26
+ warn: (component, msg, data) => log('warn', component, msg, data),
27
+ error: (component, msg, data) => log('error', component, msg, data),
28
+ };
29
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/rail/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,cAAc,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAE1F,MAAM,QAAQ,GAAc,OAAO,CAAC,GAAG,CAAC,WAAW,CAAc,IAAI,MAAM,CAAC;AAE5E,MAAM,UAAU,GAAG,CAAC,KAAe,EAAE,SAAiB,EAAE,OAAe,EAAE,IAA8B;IACrG,IAAI,cAAc,CAAC,KAAK,CAAC,GAAG,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC7D,MAAM,KAAK,GAAG;QACZ,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,KAAK;QACL,SAAS;QACT,GAAG,EAAE,OAAO;QACZ,GAAG,IAAI;KACR,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,OAAO;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;;QACpD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,KAAK,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC;IAC7G,IAAI,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC;IAC3G,IAAI,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC;IAC3G,KAAK,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,IAA8B,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC;CAC9G,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Metadata Broadcaster
3
+ *
4
+ * Aggregates rail subsystem state every 2s and broadcasts to observers.
5
+ * Supports delta encoding — only changed fields are sent.
6
+ * Full snapshot every 10th cycle.
7
+ */
8
+ import type { ResonanceRailServer } from './server.js';
9
+ export interface RailMetadata {
10
+ type: 'metadata';
11
+ full: boolean;
12
+ energyLandscape?: Record<string, {
13
+ energy: number;
14
+ probability: number;
15
+ }>;
16
+ routerTemperature?: number;
17
+ trustScores?: Record<string, {
18
+ stage: string;
19
+ couplingStrength: number;
20
+ }>;
21
+ securityStats?: Record<string, number>;
22
+ coherenceField?: {
23
+ oscillators: Array<{
24
+ id: string;
25
+ phase: number;
26
+ }>;
27
+ globalR: number;
28
+ meanPhase: number;
29
+ };
30
+ platformStats?: Record<string, number>;
31
+ absorptionStats?: Record<string, number>;
32
+ externalAgentCount?: number;
33
+ timestamp: number;
34
+ }
35
+ export interface MetadataBroadcasterConfig {
36
+ intervalMs: number;
37
+ fullSnapshotEvery: number;
38
+ }
39
+ export declare class MetadataBroadcaster {
40
+ private config;
41
+ private rail;
42
+ private broadcastFn;
43
+ private timer?;
44
+ private cycleCount;
45
+ private previousSnapshot;
46
+ constructor(rail: ResonanceRailServer, broadcastFn: (msg: unknown) => void, config?: Partial<MetadataBroadcasterConfig>);
47
+ start(): void;
48
+ stop(): void;
49
+ private broadcast;
50
+ private collectSnapshot;
51
+ }
52
+ export declare function createMetadataBroadcaster(rail: ResonanceRailServer, broadcastFn: (msg: unknown) => void, config?: Partial<MetadataBroadcasterConfig>): MetadataBroadcaster;
53
+ //# sourceMappingURL=metadataBroadcaster.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataBroadcaster.d.ts","sourceRoot":"","sources":["../../src/rail/metadataBroadcaster.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAc,MAAM,aAAa,CAAC;AAMnE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1E,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,cAAc,CAAC,EAAE;QACf,WAAW,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAClD,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAOD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,IAAI,CAAsB;IAClC,OAAO,CAAC,WAAW,CAAyB;IAC5C,OAAO,CAAC,KAAK,CAAC,CAAiC;IAC/C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAkE;gBAGxF,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,EACnC,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC;IAO7C,KAAK,IAAI,IAAI;IAIb,IAAI,IAAI,IAAI;IAOZ,OAAO,CAAC,SAAS;IA4BjB,OAAO,CAAC,eAAe;CAuExB;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,EACnC,MAAM,CAAC,EAAE,OAAO,CAAC,yBAAyB,CAAC,GAC1C,mBAAmB,CAErB"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Metadata Broadcaster
3
+ *
4
+ * Aggregates rail subsystem state every 2s and broadcasts to observers.
5
+ * Supports delta encoding — only changed fields are sent.
6
+ * Full snapshot every 10th cycle.
7
+ */
8
+ const DEFAULT_CONFIG = {
9
+ intervalMs: 2000,
10
+ fullSnapshotEvery: 10,
11
+ };
12
+ export class MetadataBroadcaster {
13
+ config;
14
+ rail;
15
+ broadcastFn;
16
+ timer;
17
+ cycleCount = 0;
18
+ previousSnapshot = null;
19
+ constructor(rail, broadcastFn, config) {
20
+ this.rail = rail;
21
+ this.broadcastFn = broadcastFn;
22
+ this.config = { ...DEFAULT_CONFIG, ...config };
23
+ }
24
+ start() {
25
+ this.timer = setInterval(() => this.broadcast(), this.config.intervalMs);
26
+ }
27
+ stop() {
28
+ if (this.timer) {
29
+ clearInterval(this.timer);
30
+ this.timer = undefined;
31
+ }
32
+ }
33
+ broadcast() {
34
+ this.cycleCount++;
35
+ const isFull = this.cycleCount % this.config.fullSnapshotEvery === 0;
36
+ const snapshot = this.collectSnapshot();
37
+ const msg = {
38
+ type: 'metadata',
39
+ full: isFull,
40
+ timestamp: Date.now(),
41
+ };
42
+ if (isFull || !this.previousSnapshot) {
43
+ Object.assign(msg, snapshot);
44
+ }
45
+ else {
46
+ // Delta: only include changed fields
47
+ for (const key of Object.keys(snapshot)) {
48
+ const current = JSON.stringify(snapshot[key]);
49
+ const previous = JSON.stringify(this.previousSnapshot[key]);
50
+ if (current !== previous) {
51
+ msg[key] = snapshot[key];
52
+ }
53
+ }
54
+ }
55
+ this.previousSnapshot = snapshot;
56
+ this.broadcastFn(msg);
57
+ }
58
+ collectSnapshot() {
59
+ const clients = this.rail.getClients();
60
+ const stats = this.rail.getStats();
61
+ const coherenceStats = this.rail.getCoherenceStats();
62
+ const securityStats = this.rail.getSecurityStats(60_000);
63
+ // Energy landscape — simplified (no active message to route against)
64
+ const energyLandscape = {};
65
+ if (clients.length > 0) {
66
+ const uniform = 1 / clients.length;
67
+ for (const c of clients) {
68
+ energyLandscape[c.agentId] = {
69
+ energy: 1 - c.coherenceContribution,
70
+ probability: uniform,
71
+ };
72
+ }
73
+ }
74
+ // Trust scores from absorption bridge
75
+ const trustScores = {};
76
+ const bridge = this.rail.getAbsorptionBridge();
77
+ if (bridge) {
78
+ for (const c of clients) {
79
+ const cap = bridge.getCapabilityToken(c.agentId);
80
+ trustScores[c.agentId] = {
81
+ stage: cap ? 'connected' : 'observed',
82
+ couplingStrength: c.coherenceContribution,
83
+ };
84
+ }
85
+ }
86
+ // Coherence field from Kuramoto
87
+ const oscillators = clients.map(c => ({
88
+ id: c.agentId,
89
+ phase: c.phase,
90
+ }));
91
+ // Platform stats
92
+ const platformStats = {};
93
+ for (const c of clients) {
94
+ platformStats[c.platform] = (platformStats[c.platform] ?? 0) + 1;
95
+ }
96
+ // Absorption stats
97
+ const absorptionStats = {};
98
+ const bridgeInstance = this.rail.getAbsorptionBridge();
99
+ if (bridgeInstance) {
100
+ // Count agents by absorption stage from trust scores
101
+ for (const score of Object.values(trustScores)) {
102
+ absorptionStats[score.stage] = (absorptionStats[score.stage] ?? 0) + 1;
103
+ }
104
+ }
105
+ // External agent count (not browser-runtime users)
106
+ const externalAgentCount = clients.filter(c => c.platform !== 'browser-runtime' && c.platform !== 'observer').length;
107
+ return {
108
+ energyLandscape,
109
+ routerTemperature: 0.8,
110
+ trustScores,
111
+ securityStats: securityStats,
112
+ coherenceField: {
113
+ oscillators,
114
+ globalR: stats.globalCoherence,
115
+ meanPhase: coherenceStats?.current ?? 0,
116
+ },
117
+ platformStats,
118
+ absorptionStats,
119
+ externalAgentCount,
120
+ };
121
+ }
122
+ }
123
+ export function createMetadataBroadcaster(rail, broadcastFn, config) {
124
+ return new MetadataBroadcaster(rail, broadcastFn, config);
125
+ }
126
+ //# sourceMappingURL=metadataBroadcaster.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadataBroadcaster.js","sourceRoot":"","sources":["../../src/rail/metadataBroadcaster.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Rail Persistence Layer
3
+ *
4
+ * PGlite-backed persistence for rail sessions, events, and coherence logs.
5
+ * Stores to RAIL_DATA_DIR (default ./data) for Fly.io volume mount.
6
+ */
7
+ import type { RailClient } from './server.js';
8
+ export interface RailPersistence {
9
+ init(): Promise<void>;
10
+ recordSession(client: RailClient, action: 'join' | 'leave'): Promise<void>;
11
+ recordEvent(type: string, clientId: string, details?: unknown): Promise<void>;
12
+ logCoherence(coherence: number, agentCount: number, meanPhase: number): Promise<void>;
13
+ getHistory(limit?: number): Promise<Array<{
14
+ timestamp: string;
15
+ type: string;
16
+ client_id: string;
17
+ details: string;
18
+ }>>;
19
+ getClientHistory(agentId: string, limit?: number): Promise<Array<{
20
+ timestamp: string;
21
+ action: string;
22
+ }>>;
23
+ saveEnrollment(agentId: string, secretHash: string): Promise<void>;
24
+ loadEnrollments(): Promise<Array<{
25
+ agent_id: string;
26
+ secret_hash: string;
27
+ }>>;
28
+ close(): Promise<void>;
29
+ }
30
+ export declare class PGliteRailPersistence implements RailPersistence {
31
+ private db;
32
+ private coherenceLogInterval?;
33
+ constructor(dataDir: string);
34
+ init(): Promise<void>;
35
+ recordSession(client: RailClient, action: 'join' | 'leave'): Promise<void>;
36
+ recordEvent(type: string, clientId: string, details?: unknown): Promise<void>;
37
+ logCoherence(coherence: number, agentCount: number, meanPhase: number): Promise<void>;
38
+ getHistory(limit?: number): Promise<Array<{
39
+ timestamp: string;
40
+ type: string;
41
+ client_id: string;
42
+ details: string;
43
+ }>>;
44
+ getClientHistory(agentId: string, limit?: number): Promise<Array<{
45
+ timestamp: string;
46
+ action: string;
47
+ }>>;
48
+ saveEnrollment(agentId: string, secretHash: string): Promise<void>;
49
+ loadEnrollments(): Promise<Array<{
50
+ agent_id: string;
51
+ secret_hash: string;
52
+ }>>;
53
+ startCoherenceLogging(getCoherence: () => number, getAgentCount: () => number, getMeanPhase: () => number): void;
54
+ close(): Promise<void>;
55
+ }
56
+ export declare function createRailPersistence(dataDir: string): PGliteRailPersistence;
57
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../src/rail/persistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Rail Persistence Layer
3
+ *
4
+ * PGlite-backed persistence for rail sessions, events, and coherence logs.
5
+ * Stores to RAIL_DATA_DIR (default ./data) for Fly.io volume mount.
6
+ */
7
+ import { PGlite } from '@electric-sql/pglite';
8
+ export class PGliteRailPersistence {
9
+ db;
10
+ coherenceLogInterval;
11
+ constructor(dataDir) {
12
+ this.db = new PGlite(dataDir);
13
+ }
14
+ async init() {
15
+ await this.db.exec(`
16
+ CREATE TABLE IF NOT EXISTS rail_clients (
17
+ id SERIAL PRIMARY KEY,
18
+ agent_id TEXT NOT NULL,
19
+ agent_name TEXT NOT NULL,
20
+ platform TEXT NOT NULL,
21
+ action TEXT NOT NULL,
22
+ timestamp TIMESTAMPTZ DEFAULT NOW()
23
+ );
24
+
25
+ CREATE TABLE IF NOT EXISTS rail_events (
26
+ id SERIAL PRIMARY KEY,
27
+ type TEXT NOT NULL,
28
+ client_id TEXT NOT NULL,
29
+ details JSONB,
30
+ timestamp TIMESTAMPTZ DEFAULT NOW()
31
+ );
32
+
33
+ CREATE TABLE IF NOT EXISTS rail_coherence_log (
34
+ id SERIAL PRIMARY KEY,
35
+ coherence REAL NOT NULL,
36
+ agent_count INTEGER NOT NULL,
37
+ mean_phase REAL NOT NULL,
38
+ timestamp TIMESTAMPTZ DEFAULT NOW()
39
+ );
40
+
41
+ CREATE INDEX IF NOT EXISTS idx_rail_clients_agent ON rail_clients(agent_id);
42
+ CREATE INDEX IF NOT EXISTS idx_rail_events_type ON rail_events(type);
43
+ CREATE INDEX IF NOT EXISTS idx_rail_coherence_ts ON rail_coherence_log(timestamp);
44
+
45
+ CREATE TABLE IF NOT EXISTS rail_user_sessions (
46
+ id SERIAL PRIMARY KEY,
47
+ user_id TEXT NOT NULL,
48
+ agent_id TEXT NOT NULL,
49
+ email TEXT,
50
+ connected_at TIMESTAMPTZ DEFAULT NOW(),
51
+ last_active TIMESTAMPTZ DEFAULT NOW()
52
+ );
53
+
54
+ CREATE INDEX IF NOT EXISTS idx_rail_user_sessions_user ON rail_user_sessions(user_id);
55
+
56
+ CREATE TABLE IF NOT EXISTS rail_enrollments (
57
+ agent_id TEXT PRIMARY KEY,
58
+ secret_hash TEXT NOT NULL,
59
+ enrolled_at TIMESTAMPTZ DEFAULT NOW()
60
+ );
61
+ `);
62
+ }
63
+ async recordSession(client, action) {
64
+ await this.db.query('INSERT INTO rail_clients (agent_id, agent_name, platform, action) VALUES ($1, $2, $3, $4)', [client.agentId, client.agentName, client.platform, action]);
65
+ }
66
+ async recordEvent(type, clientId, details) {
67
+ await this.db.query('INSERT INTO rail_events (type, client_id, details) VALUES ($1, $2, $3)', [type, clientId, details ? JSON.stringify(details) : null]);
68
+ }
69
+ async logCoherence(coherence, agentCount, meanPhase) {
70
+ await this.db.query('INSERT INTO rail_coherence_log (coherence, agent_count, mean_phase) VALUES ($1, $2, $3)', [coherence, agentCount, meanPhase]);
71
+ }
72
+ async getHistory(limit = 100) {
73
+ const result = await this.db.query('SELECT timestamp, type, client_id, details FROM rail_events ORDER BY timestamp DESC LIMIT $1', [limit]);
74
+ return result.rows;
75
+ }
76
+ async getClientHistory(agentId, limit = 50) {
77
+ const result = await this.db.query('SELECT timestamp, action FROM rail_clients WHERE agent_id = $1 ORDER BY timestamp DESC LIMIT $2', [agentId, limit]);
78
+ return result.rows;
79
+ }
80
+ async saveEnrollment(agentId, secretHash) {
81
+ await this.db.query(`INSERT INTO rail_enrollments (agent_id, secret_hash) VALUES ($1, $2)
82
+ ON CONFLICT (agent_id) DO UPDATE SET secret_hash = $2`, [agentId, secretHash]);
83
+ }
84
+ async loadEnrollments() {
85
+ const result = await this.db.query('SELECT agent_id, secret_hash FROM rail_enrollments');
86
+ return result.rows;
87
+ }
88
+ startCoherenceLogging(getCoherence, getAgentCount, getMeanPhase) {
89
+ this.coherenceLogInterval = setInterval(() => {
90
+ this.logCoherence(getCoherence(), getAgentCount(), getMeanPhase()).catch(() => { });
91
+ }, 60_000);
92
+ }
93
+ async close() {
94
+ if (this.coherenceLogInterval) {
95
+ clearInterval(this.coherenceLogInterval);
96
+ }
97
+ await this.db.close();
98
+ }
99
+ }
100
+ export function createRailPersistence(dataDir) {
101
+ return new PGliteRailPersistence(dataDir);
102
+ }
103
+ //# sourceMappingURL=persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.js","sourceRoot":"","sources":["../../src/rail/persistence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Security Monitor
3
+ *
4
+ * Aggregates security events with threshold alerting for the rail server.
5
+ */
6
+ import { EventEmitter } from 'eventemitter3';
7
+ interface SecurityEvent {
8
+ type: 'blocked_message' | 'failed_auth' | 'rate_violation' | 'injection_attempt' | 'stale_disconnect';
9
+ clientId: string;
10
+ timestamp: number;
11
+ details?: Record<string, unknown>;
12
+ }
13
+ export declare class SecurityMonitor extends EventEmitter {
14
+ private events;
15
+ private thresholds;
16
+ private maxEvents;
17
+ record(event: Omit<SecurityEvent, 'timestamp'>): void;
18
+ private checkThresholds;
19
+ getStats(windowMs?: number): Record<string, number>;
20
+ getEventsForClient(clientId: string, limit?: number): SecurityEvent[];
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=securityMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityMonitor.d.ts","sourceRoot":"","sources":["../../src/rail/securityMonitor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,UAAU,aAAa;IACrB,IAAI,EAAE,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;IACtG,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAQD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAIhB;IACF,OAAO,CAAC,SAAS,CAAS;IAE1B,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GAAG,IAAI;IASrD,OAAO,CAAC,eAAe;IAkBvB,QAAQ,CAAC,QAAQ,SAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAUpD,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,aAAa,EAAE;CAGlE"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Security Monitor
3
+ *
4
+ * Aggregates security events with threshold alerting for the rail server.
5
+ */
6
+ import { EventEmitter } from 'eventemitter3';
7
+ export class SecurityMonitor extends EventEmitter {
8
+ events = [];
9
+ thresholds = [
10
+ { eventType: 'failed_auth', count: 10, windowMs: 60000 },
11
+ { eventType: 'rate_violation', count: 20, windowMs: 60000 },
12
+ { eventType: 'injection_attempt', count: 5, windowMs: 60000 },
13
+ ];
14
+ maxEvents = 10000;
15
+ record(event) {
16
+ const full = { ...event, timestamp: Date.now() };
17
+ this.events.push(full);
18
+ if (this.events.length > this.maxEvents) {
19
+ this.events = this.events.slice(-this.maxEvents / 2);
20
+ }
21
+ this.checkThresholds(full.type);
22
+ }
23
+ checkThresholds(eventType) {
24
+ const now = Date.now();
25
+ for (const threshold of this.thresholds) {
26
+ if (threshold.eventType !== eventType)
27
+ continue;
28
+ const recent = this.events.filter(e => e.type === eventType && now - e.timestamp < threshold.windowMs);
29
+ if (recent.length >= threshold.count) {
30
+ this.emit('alert', {
31
+ type: eventType,
32
+ count: recent.length,
33
+ windowMs: threshold.windowMs,
34
+ timestamp: now,
35
+ });
36
+ }
37
+ }
38
+ }
39
+ getStats(windowMs = 3600000) {
40
+ const now = Date.now();
41
+ const recent = this.events.filter(e => now - e.timestamp < windowMs);
42
+ const stats = {};
43
+ for (const e of recent) {
44
+ stats[e.type] = (stats[e.type] || 0) + 1;
45
+ }
46
+ return stats;
47
+ }
48
+ getEventsForClient(clientId, limit = 50) {
49
+ return this.events.filter(e => e.clientId === clientId).slice(-limit);
50
+ }
51
+ }
52
+ //# sourceMappingURL=securityMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"securityMonitor.js","sourceRoot":"","sources":["../../src/rail/securityMonitor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAe7C,MAAM,OAAO,eAAgB,SAAQ,YAAY;IACvC,MAAM,GAAoB,EAAE,CAAC;IAC7B,UAAU,GAAqB;QACrC,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;QACxD,EAAE,SAAS,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC3D,EAAE,SAAS,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;KAC9D,CAAC;IACM,SAAS,GAAG,KAAK,CAAC;IAE1B,MAAM,CAAC,KAAuC;QAC5C,MAAM,IAAI,GAAkB,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAChE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAEO,eAAe,CAAC,SAAiB;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,SAAS,CAAC,SAAS,KAAK,SAAS;gBAAE,SAAS;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAC/B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC,QAAQ,CACpE,CAAC;YACF,IAAI,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;gBACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;oBACjB,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,MAAM,CAAC,MAAM;oBACpB,QAAQ,EAAE,SAAS,CAAC,QAAQ;oBAC5B,SAAS,EAAE,GAAG;iBACf,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,QAAQ,GAAG,OAAO;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC;QACrE,MAAM,KAAK,GAA2B,EAAE,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,kBAAkB,CAAC,QAAgB,EAAE,KAAK,GAAG,EAAE;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC;CACF"}