@aion0/bastion 0.1.7

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 (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +183 -0
  3. package/README.zh.md +468 -0
  4. package/config/default.yaml +73 -0
  5. package/dist/cli/commands/config.d.ts +3 -0
  6. package/dist/cli/commands/config.d.ts.map +1 -0
  7. package/dist/cli/commands/config.js +31 -0
  8. package/dist/cli/commands/config.js.map +1 -0
  9. package/dist/cli/commands/env.d.ts +3 -0
  10. package/dist/cli/commands/env.d.ts.map +1 -0
  11. package/dist/cli/commands/env.js +83 -0
  12. package/dist/cli/commands/env.js.map +1 -0
  13. package/dist/cli/commands/health.d.ts +3 -0
  14. package/dist/cli/commands/health.d.ts.map +1 -0
  15. package/dist/cli/commands/health.js +45 -0
  16. package/dist/cli/commands/health.js.map +1 -0
  17. package/dist/cli/commands/openclaw.d.ts +3 -0
  18. package/dist/cli/commands/openclaw.d.ts.map +1 -0
  19. package/dist/cli/commands/openclaw.js +1062 -0
  20. package/dist/cli/commands/openclaw.js.map +1 -0
  21. package/dist/cli/commands/proxy.d.ts +8 -0
  22. package/dist/cli/commands/proxy.d.ts.map +1 -0
  23. package/dist/cli/commands/proxy.js +433 -0
  24. package/dist/cli/commands/proxy.js.map +1 -0
  25. package/dist/cli/commands/start.d.ts +3 -0
  26. package/dist/cli/commands/start.d.ts.map +1 -0
  27. package/dist/cli/commands/start.js +62 -0
  28. package/dist/cli/commands/start.js.map +1 -0
  29. package/dist/cli/commands/stats.d.ts +3 -0
  30. package/dist/cli/commands/stats.d.ts.map +1 -0
  31. package/dist/cli/commands/stats.js +32 -0
  32. package/dist/cli/commands/stats.js.map +1 -0
  33. package/dist/cli/commands/stop.d.ts +3 -0
  34. package/dist/cli/commands/stop.d.ts.map +1 -0
  35. package/dist/cli/commands/stop.js +28 -0
  36. package/dist/cli/commands/stop.js.map +1 -0
  37. package/dist/cli/commands/token.d.ts +3 -0
  38. package/dist/cli/commands/token.d.ts.map +1 -0
  39. package/dist/cli/commands/token.js +32 -0
  40. package/dist/cli/commands/token.js.map +1 -0
  41. package/dist/cli/commands/trust-ca.d.ts +3 -0
  42. package/dist/cli/commands/trust-ca.d.ts.map +1 -0
  43. package/dist/cli/commands/trust-ca.js +44 -0
  44. package/dist/cli/commands/trust-ca.js.map +1 -0
  45. package/dist/cli/commands/wrap.d.ts +3 -0
  46. package/dist/cli/commands/wrap.d.ts.map +1 -0
  47. package/dist/cli/commands/wrap.js +70 -0
  48. package/dist/cli/commands/wrap.js.map +1 -0
  49. package/dist/cli/daemon.d.ts +11 -0
  50. package/dist/cli/daemon.d.ts.map +1 -0
  51. package/dist/cli/daemon.js +82 -0
  52. package/dist/cli/daemon.js.map +1 -0
  53. package/dist/cli/index.d.ts +3 -0
  54. package/dist/cli/index.d.ts.map +1 -0
  55. package/dist/cli/index.js +35 -0
  56. package/dist/cli/index.js.map +1 -0
  57. package/dist/config/index.d.ts +3 -0
  58. package/dist/config/index.d.ts.map +1 -0
  59. package/dist/config/index.js +60 -0
  60. package/dist/config/index.js.map +1 -0
  61. package/dist/config/manager.d.ts +12 -0
  62. package/dist/config/manager.d.ts.map +1 -0
  63. package/dist/config/manager.js +73 -0
  64. package/dist/config/manager.js.map +1 -0
  65. package/dist/config/paths.d.ts +10 -0
  66. package/dist/config/paths.d.ts.map +1 -0
  67. package/dist/config/paths.js +16 -0
  68. package/dist/config/paths.js.map +1 -0
  69. package/dist/config/schema.d.ts +85 -0
  70. package/dist/config/schema.d.ts.map +1 -0
  71. package/dist/config/schema.js +3 -0
  72. package/dist/config/schema.js.map +1 -0
  73. package/dist/dashboard/api-routes.d.ts +6 -0
  74. package/dist/dashboard/api-routes.d.ts.map +1 -0
  75. package/dist/dashboard/api-routes.js +671 -0
  76. package/dist/dashboard/api-routes.js.map +1 -0
  77. package/dist/dashboard/api.d.ts +4 -0
  78. package/dist/dashboard/api.d.ts.map +1 -0
  79. package/dist/dashboard/api.js +25 -0
  80. package/dist/dashboard/api.js.map +1 -0
  81. package/dist/dashboard/page.d.ts +3 -0
  82. package/dist/dashboard/page.d.ts.map +1 -0
  83. package/dist/dashboard/page.js +1622 -0
  84. package/dist/dashboard/page.js.map +1 -0
  85. package/dist/dlp/actions.d.ts +13 -0
  86. package/dist/dlp/actions.d.ts.map +1 -0
  87. package/dist/dlp/actions.js +3 -0
  88. package/dist/dlp/actions.js.map +1 -0
  89. package/dist/dlp/ai-validator.d.ts +28 -0
  90. package/dist/dlp/ai-validator.d.ts.map +1 -0
  91. package/dist/dlp/ai-validator.js +214 -0
  92. package/dist/dlp/ai-validator.js.map +1 -0
  93. package/dist/dlp/engine.d.ts +34 -0
  94. package/dist/dlp/engine.d.ts.map +1 -0
  95. package/dist/dlp/engine.js +342 -0
  96. package/dist/dlp/engine.js.map +1 -0
  97. package/dist/dlp/entropy.d.ts +22 -0
  98. package/dist/dlp/entropy.d.ts.map +1 -0
  99. package/dist/dlp/entropy.js +43 -0
  100. package/dist/dlp/entropy.js.map +1 -0
  101. package/dist/dlp/message-cache.d.ts +45 -0
  102. package/dist/dlp/message-cache.d.ts.map +1 -0
  103. package/dist/dlp/message-cache.js +251 -0
  104. package/dist/dlp/message-cache.js.map +1 -0
  105. package/dist/dlp/patterns/context-aware.d.ts +4 -0
  106. package/dist/dlp/patterns/context-aware.d.ts.map +1 -0
  107. package/dist/dlp/patterns/context-aware.js +45 -0
  108. package/dist/dlp/patterns/context-aware.js.map +1 -0
  109. package/dist/dlp/patterns/high-confidence.d.ts +4 -0
  110. package/dist/dlp/patterns/high-confidence.d.ts.map +1 -0
  111. package/dist/dlp/patterns/high-confidence.js +140 -0
  112. package/dist/dlp/patterns/high-confidence.js.map +1 -0
  113. package/dist/dlp/patterns/prompt-injection.d.ts +4 -0
  114. package/dist/dlp/patterns/prompt-injection.d.ts.map +1 -0
  115. package/dist/dlp/patterns/prompt-injection.js +244 -0
  116. package/dist/dlp/patterns/prompt-injection.js.map +1 -0
  117. package/dist/dlp/patterns/validated.d.ts +4 -0
  118. package/dist/dlp/patterns/validated.d.ts.map +1 -0
  119. package/dist/dlp/patterns/validated.js +21 -0
  120. package/dist/dlp/patterns/validated.js.map +1 -0
  121. package/dist/dlp/remote-sync.d.ts +47 -0
  122. package/dist/dlp/remote-sync.d.ts.map +1 -0
  123. package/dist/dlp/remote-sync.js +252 -0
  124. package/dist/dlp/remote-sync.js.map +1 -0
  125. package/dist/dlp/semantics.d.ts +27 -0
  126. package/dist/dlp/semantics.d.ts.map +1 -0
  127. package/dist/dlp/semantics.js +93 -0
  128. package/dist/dlp/semantics.js.map +1 -0
  129. package/dist/dlp/structure.d.ts +25 -0
  130. package/dist/dlp/structure.d.ts.map +1 -0
  131. package/dist/dlp/structure.js +86 -0
  132. package/dist/dlp/structure.js.map +1 -0
  133. package/dist/dlp/validators.d.ts +6 -0
  134. package/dist/dlp/validators.d.ts.map +1 -0
  135. package/dist/dlp/validators.js +46 -0
  136. package/dist/dlp/validators.js.map +1 -0
  137. package/dist/index.d.ts +2 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +200 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/license/verify.d.ts +18 -0
  142. package/dist/license/verify.d.ts.map +1 -0
  143. package/dist/license/verify.js +71 -0
  144. package/dist/license/verify.js.map +1 -0
  145. package/dist/metrics/collector.d.ts +11 -0
  146. package/dist/metrics/collector.d.ts.map +1 -0
  147. package/dist/metrics/collector.js +17 -0
  148. package/dist/metrics/collector.js.map +1 -0
  149. package/dist/metrics/dashboard.d.ts +6 -0
  150. package/dist/metrics/dashboard.d.ts.map +1 -0
  151. package/dist/metrics/dashboard.js +66 -0
  152. package/dist/metrics/dashboard.js.map +1 -0
  153. package/dist/metrics/pricing.d.ts +10 -0
  154. package/dist/metrics/pricing.d.ts.map +1 -0
  155. package/dist/metrics/pricing.js +62 -0
  156. package/dist/metrics/pricing.js.map +1 -0
  157. package/dist/optimizer/cache.d.ts +14 -0
  158. package/dist/optimizer/cache.d.ts.map +1 -0
  159. package/dist/optimizer/cache.js +58 -0
  160. package/dist/optimizer/cache.js.map +1 -0
  161. package/dist/optimizer/estimator.d.ts +6 -0
  162. package/dist/optimizer/estimator.d.ts.map +1 -0
  163. package/dist/optimizer/estimator.js +12 -0
  164. package/dist/optimizer/estimator.js.map +1 -0
  165. package/dist/optimizer/reorder.d.ts +9 -0
  166. package/dist/optimizer/reorder.d.ts.map +1 -0
  167. package/dist/optimizer/reorder.js +27 -0
  168. package/dist/optimizer/reorder.js.map +1 -0
  169. package/dist/optimizer/trimmer.d.ts +9 -0
  170. package/dist/optimizer/trimmer.d.ts.map +1 -0
  171. package/dist/optimizer/trimmer.js +47 -0
  172. package/dist/optimizer/trimmer.js.map +1 -0
  173. package/dist/plugin-api/index.d.ts +3 -0
  174. package/dist/plugin-api/index.d.ts.map +1 -0
  175. package/dist/plugin-api/index.js +6 -0
  176. package/dist/plugin-api/index.js.map +1 -0
  177. package/dist/plugin-api/types.d.ts +77 -0
  178. package/dist/plugin-api/types.d.ts.map +1 -0
  179. package/dist/plugin-api/types.js +6 -0
  180. package/dist/plugin-api/types.js.map +1 -0
  181. package/dist/plugins/adapter.d.ts +12 -0
  182. package/dist/plugins/adapter.d.ts.map +1 -0
  183. package/dist/plugins/adapter.js +116 -0
  184. package/dist/plugins/adapter.js.map +1 -0
  185. package/dist/plugins/builtin/audit-logger.d.ts +9 -0
  186. package/dist/plugins/builtin/audit-logger.d.ts.map +1 -0
  187. package/dist/plugins/builtin/audit-logger.js +53 -0
  188. package/dist/plugins/builtin/audit-logger.js.map +1 -0
  189. package/dist/plugins/builtin/dlp-scanner.d.ts +19 -0
  190. package/dist/plugins/builtin/dlp-scanner.d.ts.map +1 -0
  191. package/dist/plugins/builtin/dlp-scanner.js +284 -0
  192. package/dist/plugins/builtin/dlp-scanner.js.map +1 -0
  193. package/dist/plugins/builtin/metrics-collector.d.ts +4 -0
  194. package/dist/plugins/builtin/metrics-collector.d.ts.map +1 -0
  195. package/dist/plugins/builtin/metrics-collector.js +111 -0
  196. package/dist/plugins/builtin/metrics-collector.js.map +1 -0
  197. package/dist/plugins/builtin/token-optimizer.d.ts +10 -0
  198. package/dist/plugins/builtin/token-optimizer.d.ts.map +1 -0
  199. package/dist/plugins/builtin/token-optimizer.js +120 -0
  200. package/dist/plugins/builtin/token-optimizer.js.map +1 -0
  201. package/dist/plugins/builtin/tool-guard.d.ts +20 -0
  202. package/dist/plugins/builtin/tool-guard.d.ts.map +1 -0
  203. package/dist/plugins/builtin/tool-guard.js +259 -0
  204. package/dist/plugins/builtin/tool-guard.js.map +1 -0
  205. package/dist/plugins/context.d.ts +8 -0
  206. package/dist/plugins/context.d.ts.map +1 -0
  207. package/dist/plugins/context.js +33 -0
  208. package/dist/plugins/context.js.map +1 -0
  209. package/dist/plugins/event-bus.d.ts +9 -0
  210. package/dist/plugins/event-bus.d.ts.map +1 -0
  211. package/dist/plugins/event-bus.js +25 -0
  212. package/dist/plugins/event-bus.js.map +1 -0
  213. package/dist/plugins/index.d.ts +18 -0
  214. package/dist/plugins/index.d.ts.map +1 -0
  215. package/dist/plugins/index.js +148 -0
  216. package/dist/plugins/index.js.map +1 -0
  217. package/dist/plugins/loader.d.ts +14 -0
  218. package/dist/plugins/loader.d.ts.map +1 -0
  219. package/dist/plugins/loader.js +98 -0
  220. package/dist/plugins/loader.js.map +1 -0
  221. package/dist/plugins/types.d.ts +91 -0
  222. package/dist/plugins/types.d.ts.map +1 -0
  223. package/dist/plugins/types.js +3 -0
  224. package/dist/plugins/types.js.map +1 -0
  225. package/dist/proxy/certs.d.ts +10 -0
  226. package/dist/proxy/certs.d.ts.map +1 -0
  227. package/dist/proxy/certs.js +110 -0
  228. package/dist/proxy/certs.js.map +1 -0
  229. package/dist/proxy/connect.d.ts +11 -0
  230. package/dist/proxy/connect.d.ts.map +1 -0
  231. package/dist/proxy/connect.js +298 -0
  232. package/dist/proxy/connect.js.map +1 -0
  233. package/dist/proxy/forwarder.d.ts +14 -0
  234. package/dist/proxy/forwarder.d.ts.map +1 -0
  235. package/dist/proxy/forwarder.js +342 -0
  236. package/dist/proxy/forwarder.js.map +1 -0
  237. package/dist/proxy/passthrough.d.ts +4 -0
  238. package/dist/proxy/passthrough.d.ts.map +1 -0
  239. package/dist/proxy/passthrough.js +68 -0
  240. package/dist/proxy/passthrough.js.map +1 -0
  241. package/dist/proxy/providers/anthropic.d.ts +4 -0
  242. package/dist/proxy/providers/anthropic.d.ts.map +1 -0
  243. package/dist/proxy/providers/anthropic.js +46 -0
  244. package/dist/proxy/providers/anthropic.js.map +1 -0
  245. package/dist/proxy/providers/classify.d.ts +14 -0
  246. package/dist/proxy/providers/classify.d.ts.map +1 -0
  247. package/dist/proxy/providers/classify.js +37 -0
  248. package/dist/proxy/providers/classify.js.map +1 -0
  249. package/dist/proxy/providers/claude-web.d.ts +8 -0
  250. package/dist/proxy/providers/claude-web.d.ts.map +1 -0
  251. package/dist/proxy/providers/claude-web.js +50 -0
  252. package/dist/proxy/providers/claude-web.js.map +1 -0
  253. package/dist/proxy/providers/gemini.d.ts +4 -0
  254. package/dist/proxy/providers/gemini.d.ts.map +1 -0
  255. package/dist/proxy/providers/gemini.js +38 -0
  256. package/dist/proxy/providers/gemini.js.map +1 -0
  257. package/dist/proxy/providers/index.d.ts +27 -0
  258. package/dist/proxy/providers/index.d.ts.map +1 -0
  259. package/dist/proxy/providers/index.js +32 -0
  260. package/dist/proxy/providers/index.js.map +1 -0
  261. package/dist/proxy/providers/messaging.d.ts +2 -0
  262. package/dist/proxy/providers/messaging.d.ts.map +1 -0
  263. package/dist/proxy/providers/messaging.js +53 -0
  264. package/dist/proxy/providers/messaging.js.map +1 -0
  265. package/dist/proxy/providers/openai.d.ts +4 -0
  266. package/dist/proxy/providers/openai.d.ts.map +1 -0
  267. package/dist/proxy/providers/openai.js +38 -0
  268. package/dist/proxy/providers/openai.js.map +1 -0
  269. package/dist/proxy/providers/telegram.d.ts +8 -0
  270. package/dist/proxy/providers/telegram.d.ts.map +1 -0
  271. package/dist/proxy/providers/telegram.js +35 -0
  272. package/dist/proxy/providers/telegram.js.map +1 -0
  273. package/dist/proxy/router.d.ts +12 -0
  274. package/dist/proxy/router.d.ts.map +1 -0
  275. package/dist/proxy/router.js +26 -0
  276. package/dist/proxy/router.js.map +1 -0
  277. package/dist/proxy/safety.d.ts +13 -0
  278. package/dist/proxy/safety.d.ts.map +1 -0
  279. package/dist/proxy/safety.js +58 -0
  280. package/dist/proxy/safety.js.map +1 -0
  281. package/dist/proxy/server.d.ts +8 -0
  282. package/dist/proxy/server.d.ts.map +1 -0
  283. package/dist/proxy/server.js +126 -0
  284. package/dist/proxy/server.js.map +1 -0
  285. package/dist/proxy/streaming.d.ts +21 -0
  286. package/dist/proxy/streaming.d.ts.map +1 -0
  287. package/dist/proxy/streaming.js +70 -0
  288. package/dist/proxy/streaming.js.map +1 -0
  289. package/dist/storage/database.d.ts +6 -0
  290. package/dist/storage/database.d.ts.map +1 -0
  291. package/dist/storage/database.js +44 -0
  292. package/dist/storage/database.js.map +1 -0
  293. package/dist/storage/encryption.d.ts +11 -0
  294. package/dist/storage/encryption.d.ts.map +1 -0
  295. package/dist/storage/encryption.js +47 -0
  296. package/dist/storage/encryption.js.map +1 -0
  297. package/dist/storage/migrations.d.ts +3 -0
  298. package/dist/storage/migrations.d.ts.map +1 -0
  299. package/dist/storage/migrations.js +265 -0
  300. package/dist/storage/migrations.js.map +1 -0
  301. package/dist/storage/repositories/audit-log.d.ts +115 -0
  302. package/dist/storage/repositories/audit-log.d.ts.map +1 -0
  303. package/dist/storage/repositories/audit-log.js +586 -0
  304. package/dist/storage/repositories/audit-log.js.map +1 -0
  305. package/dist/storage/repositories/cache.d.ts +26 -0
  306. package/dist/storage/repositories/cache.d.ts.map +1 -0
  307. package/dist/storage/repositories/cache.js +44 -0
  308. package/dist/storage/repositories/cache.js.map +1 -0
  309. package/dist/storage/repositories/dlp-config-history.d.ts +17 -0
  310. package/dist/storage/repositories/dlp-config-history.d.ts.map +1 -0
  311. package/dist/storage/repositories/dlp-config-history.js +30 -0
  312. package/dist/storage/repositories/dlp-config-history.js.map +1 -0
  313. package/dist/storage/repositories/dlp-events.d.ts +35 -0
  314. package/dist/storage/repositories/dlp-events.d.ts.map +1 -0
  315. package/dist/storage/repositories/dlp-events.js +57 -0
  316. package/dist/storage/repositories/dlp-events.js.map +1 -0
  317. package/dist/storage/repositories/dlp-patterns.d.ts +70 -0
  318. package/dist/storage/repositories/dlp-patterns.d.ts.map +1 -0
  319. package/dist/storage/repositories/dlp-patterns.js +187 -0
  320. package/dist/storage/repositories/dlp-patterns.js.map +1 -0
  321. package/dist/storage/repositories/optimizer-events.d.ts +28 -0
  322. package/dist/storage/repositories/optimizer-events.d.ts.map +1 -0
  323. package/dist/storage/repositories/optimizer-events.js +49 -0
  324. package/dist/storage/repositories/optimizer-events.js.map +1 -0
  325. package/dist/storage/repositories/plugin-events.d.ts +34 -0
  326. package/dist/storage/repositories/plugin-events.d.ts.map +1 -0
  327. package/dist/storage/repositories/plugin-events.js +64 -0
  328. package/dist/storage/repositories/plugin-events.js.map +1 -0
  329. package/dist/storage/repositories/requests.d.ts +68 -0
  330. package/dist/storage/repositories/requests.d.ts.map +1 -0
  331. package/dist/storage/repositories/requests.js +113 -0
  332. package/dist/storage/repositories/requests.js.map +1 -0
  333. package/dist/storage/repositories/sessions.d.ts +23 -0
  334. package/dist/storage/repositories/sessions.d.ts.map +1 -0
  335. package/dist/storage/repositories/sessions.js +42 -0
  336. package/dist/storage/repositories/sessions.js.map +1 -0
  337. package/dist/storage/repositories/tool-calls.d.ts +49 -0
  338. package/dist/storage/repositories/tool-calls.d.ts.map +1 -0
  339. package/dist/storage/repositories/tool-calls.js +61 -0
  340. package/dist/storage/repositories/tool-calls.js.map +1 -0
  341. package/dist/storage/repositories/tool-guard-rules.d.ts +50 -0
  342. package/dist/storage/repositories/tool-guard-rules.d.ts.map +1 -0
  343. package/dist/storage/repositories/tool-guard-rules.js +120 -0
  344. package/dist/storage/repositories/tool-guard-rules.js.map +1 -0
  345. package/dist/tool-guard/alert.d.ts +30 -0
  346. package/dist/tool-guard/alert.d.ts.map +1 -0
  347. package/dist/tool-guard/alert.js +113 -0
  348. package/dist/tool-guard/alert.js.map +1 -0
  349. package/dist/tool-guard/extractor.d.ts +10 -0
  350. package/dist/tool-guard/extractor.d.ts.map +1 -0
  351. package/dist/tool-guard/extractor.js +309 -0
  352. package/dist/tool-guard/extractor.js.map +1 -0
  353. package/dist/tool-guard/rules.d.ts +18 -0
  354. package/dist/tool-guard/rules.d.ts.map +1 -0
  355. package/dist/tool-guard/rules.js +255 -0
  356. package/dist/tool-guard/rules.js.map +1 -0
  357. package/dist/tool-guard/streaming-guard.d.ts +57 -0
  358. package/dist/tool-guard/streaming-guard.d.ts.map +1 -0
  359. package/dist/tool-guard/streaming-guard.js +389 -0
  360. package/dist/tool-guard/streaming-guard.js.map +1 -0
  361. package/dist/utils/hash.d.ts +2 -0
  362. package/dist/utils/hash.d.ts.map +1 -0
  363. package/dist/utils/hash.js +8 -0
  364. package/dist/utils/hash.js.map +1 -0
  365. package/dist/utils/logger.d.ts +11 -0
  366. package/dist/utils/logger.d.ts.map +1 -0
  367. package/dist/utils/logger.js +54 -0
  368. package/dist/utils/logger.js.map +1 -0
  369. package/dist/utils/timeout.d.ts +5 -0
  370. package/dist/utils/timeout.d.ts.map +1 -0
  371. package/dist/utils/timeout.js +26 -0
  372. package/dist/utils/timeout.js.map +1 -0
  373. package/dist/version.d.ts +5 -0
  374. package/dist/version.d.ts.map +1 -0
  375. package/dist/version.js +23 -0
  376. package/dist/version.js.map +1 -0
  377. package/package.json +67 -0
@@ -0,0 +1,671 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createApiRouter = createApiRouter;
4
+ const requests_js_1 = require("../storage/repositories/requests.js");
5
+ const dlp_events_js_1 = require("../storage/repositories/dlp-events.js");
6
+ const optimizer_events_js_1 = require("../storage/repositories/optimizer-events.js");
7
+ const audit_log_js_1 = require("../storage/repositories/audit-log.js");
8
+ const cache_js_1 = require("../storage/repositories/cache.js");
9
+ const sessions_js_1 = require("../storage/repositories/sessions.js");
10
+ const dlp_patterns_js_1 = require("../storage/repositories/dlp-patterns.js");
11
+ const dlp_config_history_js_1 = require("../storage/repositories/dlp-config-history.js");
12
+ const tool_calls_js_1 = require("../storage/repositories/tool-calls.js");
13
+ const tool_guard_rules_js_1 = require("../storage/repositories/tool-guard-rules.js");
14
+ const alert_js_1 = require("../tool-guard/alert.js");
15
+ const engine_js_1 = require("../dlp/engine.js");
16
+ const semantics_js_1 = require("../dlp/semantics.js");
17
+ const remote_sync_js_1 = require("../dlp/remote-sync.js");
18
+ const version_js_1 = require("../version.js");
19
+ const verify_js_1 = require("../license/verify.js");
20
+ const logger_js_1 = require("../utils/logger.js");
21
+ const log = (0, logger_js_1.createLogger)('api-routes');
22
+ function parseUrl(req) {
23
+ return new URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
24
+ }
25
+ function sendJson(res, data, status = 200) {
26
+ res.writeHead(status, { 'content-type': 'application/json' });
27
+ res.end(JSON.stringify(data));
28
+ }
29
+ function bufferBody(req) {
30
+ return new Promise((resolve, reject) => {
31
+ const chunks = [];
32
+ req.on('data', (chunk) => chunks.push(chunk));
33
+ req.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
34
+ req.on('error', reject);
35
+ });
36
+ }
37
+ function createApiRouter(db, configManager, pluginManager, getPluginState) {
38
+ const requestsRepo = new requests_js_1.RequestsRepository(db);
39
+ const dlpRepo = new dlp_events_js_1.DlpEventsRepository(db);
40
+ const optimizerRepo = new optimizer_events_js_1.OptimizerEventsRepository(db);
41
+ const auditRepo = new audit_log_js_1.AuditLogRepository(db);
42
+ const cacheRepo = new cache_js_1.CacheRepository(db);
43
+ const sessionsRepo = new sessions_js_1.SessionsRepository(db);
44
+ const dlpPatternsRepo = new dlp_patterns_js_1.DlpPatternsRepository(db);
45
+ const dlpConfigHistory = new dlp_config_history_js_1.DlpConfigHistoryRepository(db);
46
+ const toolCallsRepo = new tool_calls_js_1.ToolCallsRepository(db);
47
+ const toolGuardRulesRepo = new tool_guard_rules_js_1.ToolGuardRulesRepository(db);
48
+ let devUnlocked = false;
49
+ return (req, res) => {
50
+ const url = parseUrl(req);
51
+ const path = url.pathname;
52
+ // GET /api/dev — dev mode check (only true when started with --dev)
53
+ if (req.method === 'GET' && path === '/api/dev') {
54
+ sendJson(res, { dev: process.env.BASTION_DEV === '1' });
55
+ return true;
56
+ }
57
+ // POST /api/dev/activate — activate dev unlock with token
58
+ if (req.method === 'POST' && path === '/api/dev/activate') {
59
+ const expected = process.env.BASTION_DEV_TOKEN;
60
+ if (!expected) {
61
+ sendJson(res, { error: 'Dev mode not enabled' }, 403);
62
+ return true;
63
+ }
64
+ bufferBody(req).then((body) => {
65
+ try {
66
+ const data = JSON.parse(body);
67
+ if (data.token === expected) {
68
+ devUnlocked = true;
69
+ sendJson(res, { ok: true });
70
+ }
71
+ else {
72
+ sendJson(res, { error: 'Invalid token' }, 403);
73
+ }
74
+ }
75
+ catch {
76
+ sendJson(res, { error: 'Invalid request' }, 400);
77
+ }
78
+ }).catch(() => sendJson(res, { error: 'Internal error' }, 500));
79
+ return true;
80
+ }
81
+ // GET /api/stats — Enhanced with filters
82
+ if (req.method === 'GET' && path === '/api/stats') {
83
+ const sessionId = url.searchParams.get('session_id') ?? undefined;
84
+ const apiKeyHash = url.searchParams.get('api_key_hash') ?? undefined;
85
+ const hours = url.searchParams.get('hours');
86
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
87
+ const stats = requestsRepo.getStats({ sinceHours, sessionId, apiKeyHash });
88
+ const recent = requestsRepo.getRecent(20, sinceHours);
89
+ const cacheStats = cacheRepo.getStats();
90
+ const dlpStats = dlpRepo.getStats();
91
+ sendJson(res, {
92
+ stats,
93
+ recent,
94
+ cache: cacheStats,
95
+ dlp: dlpStats,
96
+ version: (0, version_js_1.getVersion)(),
97
+ uptime: process.uptime(),
98
+ memory: process.memoryUsage().rss,
99
+ });
100
+ return true;
101
+ }
102
+ // GET /api/sessions
103
+ if (req.method === 'GET' && path === '/api/sessions') {
104
+ sendJson(res, requestsRepo.getSessions());
105
+ return true;
106
+ }
107
+ // GET /api/dlp/recent
108
+ if (req.method === 'GET' && path === '/api/dlp/recent') {
109
+ const limit = parseInt(url.searchParams.get('limit') ?? '50', 10);
110
+ const hours = url.searchParams.get('hours');
111
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
112
+ sendJson(res, dlpRepo.getRecent(limit, sinceHours));
113
+ return true;
114
+ }
115
+ // POST /api/dlp/scan — standalone DLP scan for testing and external integration
116
+ if (req.method === 'POST' && path === '/api/dlp/scan') {
117
+ bufferBody(req).then((body) => {
118
+ try {
119
+ const data = JSON.parse(body);
120
+ const text = data.text;
121
+ if (typeof text !== 'string' || text.length === 0) {
122
+ sendJson(res, { error: 'text field is required' }, 400);
123
+ return;
124
+ }
125
+ const action = (data.action ?? configManager.get().plugins.dlp.action ?? 'warn');
126
+ const patterns = dlpPatternsRepo.getEnabled();
127
+ const enableTrace = Boolean(data.trace);
128
+ const trace = enableTrace ? { entries: [], totalDurationMs: 0 } : undefined;
129
+ const result = (0, engine_js_1.scanText)(text, patterns, action, trace);
130
+ sendJson(res, {
131
+ action: result.action,
132
+ findings: result.findings.map((f) => ({
133
+ patternName: f.patternName,
134
+ patternCategory: f.patternCategory,
135
+ matchCount: f.matchCount,
136
+ matches: f.matches,
137
+ })),
138
+ redactedText: result.redactedBody ?? null,
139
+ trace: trace ?? null,
140
+ });
141
+ }
142
+ catch (err) {
143
+ sendJson(res, { error: err.message }, 400);
144
+ }
145
+ }).catch((err) => {
146
+ sendJson(res, { error: err.message }, 500);
147
+ });
148
+ return true;
149
+ }
150
+ // GET /api/optimizer/stats
151
+ if (req.method === 'GET' && path === '/api/optimizer/stats') {
152
+ sendJson(res, optimizerRepo.getStats());
153
+ return true;
154
+ }
155
+ // GET /api/optimizer/recent
156
+ if (req.method === 'GET' && path === '/api/optimizer/recent') {
157
+ const limit = parseInt(url.searchParams.get('limit') ?? '50', 10);
158
+ const hours = url.searchParams.get('hours');
159
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
160
+ sendJson(res, optimizerRepo.getRecent(limit, sinceHours));
161
+ return true;
162
+ }
163
+ // GET /api/audit/recent
164
+ if (req.method === 'GET' && path === '/api/audit/recent') {
165
+ const limit = parseInt(url.searchParams.get('limit') ?? '50', 10);
166
+ const hours = url.searchParams.get('hours');
167
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
168
+ sendJson(res, auditRepo.getRecent(limit, sinceHours));
169
+ return true;
170
+ }
171
+ // GET /api/audit/sessions — list sessions with audit data
172
+ if (req.method === 'GET' && path === '/api/audit/sessions') {
173
+ const hours = url.searchParams.get('hours');
174
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
175
+ sendJson(res, auditRepo.getAuditSessions(30, sinceHours));
176
+ return true;
177
+ }
178
+ // GET /api/audit/session/:sessionId — full parsed timeline for a session
179
+ if (req.method === 'GET' && path.startsWith('/api/audit/session/')) {
180
+ const sessionId = path.slice('/api/audit/session/'.length);
181
+ if (!sessionId) {
182
+ sendJson(res, { error: 'Missing session ID' }, 400);
183
+ return true;
184
+ }
185
+ const timeline = auditRepo.getParsedSession(sessionId);
186
+ if (timeline.length === 0) {
187
+ sendJson(res, { error: 'No audit entries for this session' }, 404);
188
+ return true;
189
+ }
190
+ const session = sessionsRepo.get(sessionId) ?? null;
191
+ sendJson(res, { session, timeline });
192
+ return true;
193
+ }
194
+ // GET /api/audit/:requestId — single request parsed
195
+ if (req.method === 'GET' && path.startsWith('/api/audit/') && !path.includes('/session')) {
196
+ const requestId = path.slice('/api/audit/'.length);
197
+ if (!requestId) {
198
+ sendJson(res, { error: 'Missing request ID' }, 400);
199
+ return true;
200
+ }
201
+ const parsed = auditRepo.getParsedByRequestId(requestId);
202
+ if (!parsed) {
203
+ // Fallback: raw data may be off — return summary-only
204
+ const meta = auditRepo.getMetaByRequestId(requestId);
205
+ if (!meta) {
206
+ sendJson(res, { error: 'Audit entry not found' }, 404);
207
+ return true;
208
+ }
209
+ sendJson(res, { summaryOnly: true, summary: meta.summary, meta });
210
+ return true;
211
+ }
212
+ // DLP highlight: re-scan raw text with matched patterns to get exact match strings
213
+ if (url.searchParams.get('dlp') === 'true') {
214
+ const dlpFindings = dlpRepo.getByRequestId(requestId);
215
+ if (dlpFindings.length > 0) {
216
+ const patternNames = [...new Set(dlpFindings.map(f => f.pattern_name))];
217
+ const relevantPatterns = dlpPatternsRepo.getByNames(patternNames);
218
+ if (relevantPatterns.length > 0) {
219
+ const allMatches = [];
220
+ try {
221
+ const reqResult = (0, engine_js_1.scanText)(parsed.raw.request, relevantPatterns, 'warn');
222
+ reqResult.findings.forEach(f => allMatches.push(...f.matches));
223
+ const resResult = (0, engine_js_1.scanText)(parsed.raw.response, relevantPatterns, 'warn');
224
+ resResult.findings.forEach(f => allMatches.push(...f.matches));
225
+ }
226
+ catch { /* ignore scan errors */ }
227
+ parsed.dlpHighlights = [...new Set(allMatches)];
228
+ }
229
+ }
230
+ }
231
+ // Tool Guard: attach tool_calls for this request
232
+ if (url.searchParams.get('tg') === 'true') {
233
+ const toolCalls = toolCallsRepo.getByRequestId(requestId);
234
+ if (toolCalls.length > 0) {
235
+ parsed.toolGuardFindings = toolCalls;
236
+ }
237
+ }
238
+ sendJson(res, parsed);
239
+ return true;
240
+ }
241
+ // GET /api/config
242
+ if (req.method === 'GET' && path === '/api/config') {
243
+ const config = configManager.get();
244
+ const pluginStatus = {};
245
+ const pluginInfo = [];
246
+ for (const p of pluginManager.getPlugins()) {
247
+ const enabled = !pluginManager.isDisabled(p.name);
248
+ pluginStatus[p.name] = enabled;
249
+ pluginInfo.push({ name: p.name, enabled, source: p.source ?? 'builtin', version: p.version, packageName: p.packageName, priority: p.priority });
250
+ }
251
+ sendJson(res, { config, pluginStatus, pluginInfo });
252
+ return true;
253
+ }
254
+ // PUT /api/config
255
+ if (req.method === 'PUT' && path === '/api/config') {
256
+ bufferBody(req).then((body) => {
257
+ try {
258
+ const update = JSON.parse(body);
259
+ // Handle plugin enable/disable
260
+ if (update.pluginStatus) {
261
+ for (const [name, enabled] of Object.entries(update.pluginStatus)) {
262
+ if (enabled) {
263
+ pluginManager.enable(name);
264
+ }
265
+ else {
266
+ pluginManager.disable(name);
267
+ }
268
+ }
269
+ delete update.pluginStatus;
270
+ }
271
+ // Apply remaining config changes
272
+ if (Object.keys(update).length > 0) {
273
+ configManager.update(update);
274
+ }
275
+ const config = configManager.get();
276
+ const pluginStatus = {};
277
+ const pluginInfo = [];
278
+ for (const p of pluginManager.getPlugins()) {
279
+ const enabled = !pluginManager.isDisabled(p.name);
280
+ pluginStatus[p.name] = enabled;
281
+ pluginInfo.push({ name: p.name, enabled, source: p.source ?? 'builtin', version: p.version, packageName: p.packageName, priority: p.priority });
282
+ }
283
+ sendJson(res, { config, pluginStatus, pluginInfo });
284
+ }
285
+ catch (err) {
286
+ sendJson(res, { error: err.message }, 400);
287
+ }
288
+ }).catch((err) => {
289
+ sendJson(res, { error: err.message }, 500);
290
+ });
291
+ return true;
292
+ }
293
+ // POST /api/dlp/config/apply — batch-apply DLP config and record history
294
+ if (req.method === 'POST' && path === '/api/dlp/config/apply') {
295
+ bufferBody(req).then((body) => {
296
+ try {
297
+ const dlpUpdate = JSON.parse(body);
298
+ // Handle plugin enable/disable
299
+ if (dlpUpdate.enabled !== undefined) {
300
+ if (dlpUpdate.enabled)
301
+ pluginManager.enable('dlp-scanner');
302
+ else
303
+ pluginManager.disable('dlp-scanner');
304
+ delete dlpUpdate.enabled;
305
+ }
306
+ // Apply config changes
307
+ if (Object.keys(dlpUpdate).length > 0) {
308
+ configManager.update({ plugins: { dlp: dlpUpdate } });
309
+ }
310
+ // Record snapshot to history
311
+ const snap = configManager.get().plugins.dlp;
312
+ const dlpEnabled = !pluginManager.isDisabled('dlp-scanner');
313
+ dlpConfigHistory.insert({ ...snap, enabled: dlpEnabled });
314
+ sendJson(res, { ok: true, config: snap, enabled: dlpEnabled });
315
+ }
316
+ catch (err) {
317
+ sendJson(res, { error: err.message }, 400);
318
+ }
319
+ }).catch((err) => sendJson(res, { error: err.message }, 500));
320
+ return true;
321
+ }
322
+ // GET /api/dlp/config/history — last 10 config changes
323
+ if (req.method === 'GET' && path === '/api/dlp/config/history') {
324
+ sendJson(res, dlpConfigHistory.getRecent());
325
+ return true;
326
+ }
327
+ // POST /api/dlp/config/restore/:id — restore a config snapshot
328
+ if (req.method === 'POST' && path.startsWith('/api/dlp/config/restore/')) {
329
+ const id = parseInt(path.slice('/api/dlp/config/restore/'.length), 10);
330
+ if (isNaN(id)) {
331
+ sendJson(res, { error: 'Invalid history ID' }, 400);
332
+ return true;
333
+ }
334
+ const entry = dlpConfigHistory.getById(id);
335
+ if (!entry) {
336
+ sendJson(res, { error: 'History entry not found' }, 404);
337
+ return true;
338
+ }
339
+ try {
340
+ const snapshot = JSON.parse(entry.config_json);
341
+ // Restore plugin enabled state
342
+ if (snapshot.enabled !== undefined) {
343
+ if (snapshot.enabled)
344
+ pluginManager.enable('dlp-scanner');
345
+ else
346
+ pluginManager.disable('dlp-scanner');
347
+ }
348
+ // Restore config (exclude non-config fields)
349
+ const { enabled: _, ...configPart } = snapshot;
350
+ if (Object.keys(configPart).length > 0) {
351
+ configManager.update({ plugins: { dlp: configPart } });
352
+ }
353
+ // Record this restore as a new history entry
354
+ const snap = configManager.get().plugins.dlp;
355
+ const dlpEnabled = !pluginManager.isDisabled('dlp-scanner');
356
+ dlpConfigHistory.insert({ ...snap, enabled: dlpEnabled });
357
+ sendJson(res, { ok: true, config: snap, enabled: dlpEnabled });
358
+ }
359
+ catch (err) {
360
+ sendJson(res, { error: err.message }, 400);
361
+ }
362
+ return true;
363
+ }
364
+ // GET /api/dlp/semantics/builtins — read-only built-in defaults
365
+ if (req.method === 'GET' && path === '/api/dlp/semantics/builtins') {
366
+ sendJson(res, {
367
+ sensitivePatterns: (0, semantics_js_1.getBuiltinSensitivePatterns)(),
368
+ nonSensitiveNames: (0, semantics_js_1.getBuiltinNonSensitiveNames)(),
369
+ });
370
+ return true;
371
+ }
372
+ // GET /api/dlp/signature — signature version and update status
373
+ if (req.method === 'GET' && path === '/api/dlp/signature') {
374
+ const remoteConfig = configManager.get().plugins.dlp.remotePatterns;
375
+ const check = url.searchParams.get('check') === 'true';
376
+ if (check && remoteConfig?.url) {
377
+ sendJson(res, (0, remote_sync_js_1.checkForUpdates)(remoteConfig));
378
+ }
379
+ else {
380
+ const local = (0, remote_sync_js_1.getLocalSignatureMeta)();
381
+ sendJson(res, { local, remote: null, updateAvailable: false });
382
+ }
383
+ return true;
384
+ }
385
+ // POST /api/dlp/signature/sync — trigger manual sync
386
+ if (req.method === 'POST' && path === '/api/dlp/signature/sync') {
387
+ const remoteConfig = configManager.get().plugins.dlp.remotePatterns;
388
+ if (!remoteConfig?.url) {
389
+ sendJson(res, { error: 'Remote patterns not configured' }, 400);
390
+ return true;
391
+ }
392
+ const enabledCategories = configManager.get().plugins.dlp.patterns;
393
+ const count = (0, remote_sync_js_1.syncRemotePatterns)(remoteConfig, dlpPatternsRepo, enabledCategories);
394
+ if (count < 0) {
395
+ sendJson(res, { error: 'Sync failed' }, 500);
396
+ return true;
397
+ }
398
+ const local = (0, remote_sync_js_1.getLocalSignatureMeta)();
399
+ sendJson(res, { ok: true, synced: count, signature: local });
400
+ return true;
401
+ }
402
+ // GET /api/dlp/patterns — all patterns for UI listing
403
+ if (req.method === 'GET' && path === '/api/dlp/patterns') {
404
+ sendJson(res, dlpPatternsRepo.getAll());
405
+ return true;
406
+ }
407
+ // POST /api/dlp/patterns — add custom pattern
408
+ if (req.method === 'POST' && path === '/api/dlp/patterns') {
409
+ bufferBody(req).then((body) => {
410
+ try {
411
+ const data = JSON.parse(body);
412
+ if (!data.name || !data.regex_source) {
413
+ sendJson(res, { error: 'name and regex_source are required' }, 400);
414
+ return;
415
+ }
416
+ // Validate regex
417
+ try {
418
+ new RegExp(data.regex_source, data.regex_flags ?? 'g');
419
+ }
420
+ catch {
421
+ sendJson(res, { error: 'Invalid regex' }, 400);
422
+ return;
423
+ }
424
+ const id = `custom-${crypto.randomUUID()}`;
425
+ dlpPatternsRepo.upsert({
426
+ id,
427
+ name: data.name,
428
+ category: data.category ?? 'custom',
429
+ regex_source: data.regex_source,
430
+ regex_flags: data.regex_flags ?? 'g',
431
+ description: data.description ?? null,
432
+ validator: data.validator ?? null,
433
+ require_context: data.require_context ?? null,
434
+ enabled: data.enabled !== false,
435
+ });
436
+ sendJson(res, { id }, 201);
437
+ }
438
+ catch (err) {
439
+ sendJson(res, { error: err.message }, 400);
440
+ }
441
+ }).catch((err) => {
442
+ sendJson(res, { error: err.message }, 500);
443
+ });
444
+ return true;
445
+ }
446
+ // PUT /api/dlp/patterns/:id — update pattern (toggle enabled, edit fields)
447
+ if (req.method === 'PUT' && path.startsWith('/api/dlp/patterns/')) {
448
+ const id = decodeURIComponent(path.slice('/api/dlp/patterns/'.length));
449
+ if (!id) {
450
+ sendJson(res, { error: 'Missing pattern ID' }, 400);
451
+ return true;
452
+ }
453
+ bufferBody(req).then((body) => {
454
+ try {
455
+ const data = JSON.parse(body);
456
+ // If just toggling enabled
457
+ if (data.enabled !== undefined && Object.keys(data).length === 1) {
458
+ dlpPatternsRepo.toggle(id, Boolean(data.enabled));
459
+ sendJson(res, { ok: true });
460
+ return;
461
+ }
462
+ // Validate regex if provided
463
+ if (data.regex_source) {
464
+ try {
465
+ new RegExp(data.regex_source, data.regex_flags ?? 'g');
466
+ }
467
+ catch {
468
+ sendJson(res, { error: 'Invalid regex' }, 400);
469
+ return;
470
+ }
471
+ }
472
+ // Full upsert for custom patterns
473
+ if (data.name && data.regex_source) {
474
+ dlpPatternsRepo.upsert({ id, ...data });
475
+ }
476
+ else if (data.enabled !== undefined) {
477
+ dlpPatternsRepo.toggle(id, Boolean(data.enabled));
478
+ }
479
+ sendJson(res, { ok: true });
480
+ }
481
+ catch (err) {
482
+ sendJson(res, { error: err.message }, 400);
483
+ }
484
+ }).catch((err) => {
485
+ sendJson(res, { error: err.message }, 500);
486
+ });
487
+ return true;
488
+ }
489
+ // DELETE /api/dlp/patterns/:id — delete custom pattern only
490
+ if (req.method === 'DELETE' && path.startsWith('/api/dlp/patterns/')) {
491
+ const id = decodeURIComponent(path.slice('/api/dlp/patterns/'.length));
492
+ if (!id) {
493
+ sendJson(res, { error: 'Missing pattern ID' }, 400);
494
+ return true;
495
+ }
496
+ try {
497
+ dlpPatternsRepo.remove(id);
498
+ sendJson(res, { ok: true });
499
+ }
500
+ catch (err) {
501
+ sendJson(res, { error: err.message }, 400);
502
+ }
503
+ return true;
504
+ }
505
+ // GET /api/tool-guard/alerts — recent alerts with unack count
506
+ if (req.method === 'GET' && path === '/api/tool-guard/alerts') {
507
+ sendJson(res, {
508
+ alerts: (0, alert_js_1.getRecentAlerts)(),
509
+ unacknowledged: (0, alert_js_1.getUnacknowledgedCount)(),
510
+ });
511
+ return true;
512
+ }
513
+ // POST /api/tool-guard/alerts/ack — acknowledge all alerts
514
+ if (req.method === 'POST' && path === '/api/tool-guard/alerts/ack') {
515
+ (0, alert_js_1.acknowledgeAlerts)();
516
+ sendJson(res, { ok: true });
517
+ return true;
518
+ }
519
+ // GET /api/tool-guard/recent — recent tool calls
520
+ if (req.method === 'GET' && path === '/api/tool-guard/recent') {
521
+ const limit = parseInt(url.searchParams.get('limit') ?? '50', 10);
522
+ const hours = url.searchParams.get('hours');
523
+ const sinceHours = hours ? parseInt(hours, 10) : undefined;
524
+ sendJson(res, toolCallsRepo.getRecent(limit, sinceHours));
525
+ return true;
526
+ }
527
+ // GET /api/tool-guard/stats — counts by severity, category, top tool names
528
+ if (req.method === 'GET' && path === '/api/tool-guard/stats') {
529
+ sendJson(res, toolCallsRepo.getStats());
530
+ return true;
531
+ }
532
+ // GET /api/tool-guard/session/:id — tool calls for a specific session
533
+ if (req.method === 'GET' && path.startsWith('/api/tool-guard/session/')) {
534
+ const sessionId = path.slice('/api/tool-guard/session/'.length);
535
+ if (!sessionId) {
536
+ sendJson(res, { error: 'Missing session ID' }, 400);
537
+ return true;
538
+ }
539
+ sendJson(res, toolCallsRepo.getBySession(sessionId));
540
+ return true;
541
+ }
542
+ // GET /api/tool-guard/rules — list all rules
543
+ if (req.method === 'GET' && path === '/api/tool-guard/rules') {
544
+ sendJson(res, toolGuardRulesRepo.getAll());
545
+ return true;
546
+ }
547
+ // POST /api/tool-guard/rules — add custom rule
548
+ if (req.method === 'POST' && path === '/api/tool-guard/rules') {
549
+ bufferBody(req).then(raw => {
550
+ try {
551
+ const body = JSON.parse(raw);
552
+ if (!body.name || !body.input_pattern) {
553
+ sendJson(res, { error: 'name and input_pattern are required' }, 400);
554
+ return;
555
+ }
556
+ // Validate regex
557
+ try {
558
+ new RegExp(body.input_pattern, body.input_flags ?? 'i');
559
+ }
560
+ catch {
561
+ sendJson(res, { error: 'Invalid input_pattern regex' }, 400);
562
+ return;
563
+ }
564
+ if (body.tool_name_pattern) {
565
+ try {
566
+ new RegExp(body.tool_name_pattern, body.tool_name_flags ?? '');
567
+ }
568
+ catch {
569
+ sendJson(res, { error: 'Invalid tool_name_pattern regex' }, 400);
570
+ return;
571
+ }
572
+ }
573
+ const id = body.id ?? `custom-${Date.now()}`;
574
+ toolGuardRulesRepo.upsert({ ...body, id });
575
+ sendJson(res, { ok: true, id });
576
+ }
577
+ catch {
578
+ sendJson(res, { error: 'Invalid JSON' }, 400);
579
+ }
580
+ });
581
+ return true;
582
+ }
583
+ // PUT /api/tool-guard/rules/:id — update or toggle rule
584
+ if (req.method === 'PUT' && path.startsWith('/api/tool-guard/rules/')) {
585
+ const id = decodeURIComponent(path.slice('/api/tool-guard/rules/'.length));
586
+ if (!id) {
587
+ sendJson(res, { error: 'Missing rule ID' }, 400);
588
+ return true;
589
+ }
590
+ bufferBody(req).then(raw => {
591
+ try {
592
+ const body = JSON.parse(raw);
593
+ // Toggle shortcut: { enabled: true/false }
594
+ if ('enabled' in body && Object.keys(body).length === 1) {
595
+ toolGuardRulesRepo.toggle(id, body.enabled);
596
+ sendJson(res, { ok: true });
597
+ return;
598
+ }
599
+ // Full update (custom rules only)
600
+ if (body.input_pattern) {
601
+ try {
602
+ new RegExp(body.input_pattern, body.input_flags ?? 'i');
603
+ }
604
+ catch {
605
+ sendJson(res, { error: 'Invalid input_pattern regex' }, 400);
606
+ return;
607
+ }
608
+ }
609
+ if (body.tool_name_pattern) {
610
+ try {
611
+ new RegExp(body.tool_name_pattern, body.tool_name_flags ?? '');
612
+ }
613
+ catch {
614
+ sendJson(res, { error: 'Invalid tool_name_pattern regex' }, 400);
615
+ return;
616
+ }
617
+ }
618
+ toolGuardRulesRepo.upsert({ ...body, id });
619
+ sendJson(res, { ok: true });
620
+ }
621
+ catch {
622
+ sendJson(res, { error: 'Invalid JSON' }, 400);
623
+ }
624
+ });
625
+ return true;
626
+ }
627
+ // DELETE /api/tool-guard/rules/:id — delete custom rule
628
+ if (req.method === 'DELETE' && path.startsWith('/api/tool-guard/rules/')) {
629
+ const id = decodeURIComponent(path.slice('/api/tool-guard/rules/'.length));
630
+ if (!id) {
631
+ sendJson(res, { error: 'Missing rule ID' }, 400);
632
+ return true;
633
+ }
634
+ try {
635
+ toolGuardRulesRepo.remove(id);
636
+ sendJson(res, { ok: true });
637
+ }
638
+ catch (err) {
639
+ sendJson(res, { error: err.message }, 400);
640
+ }
641
+ return true;
642
+ }
643
+ // GET /api/license — Pro license status
644
+ if (req.method === 'GET' && path === '/api/license') {
645
+ // Dev token unlock — all features available for debugging
646
+ if (devUnlocked) {
647
+ sendJson(res, { pro: true, plan: 'dev', expiresAt: '', features: ['ai-injection', 'budget', 'ratelimit'] });
648
+ return true;
649
+ }
650
+ const proPlugin = pluginManager.getPlugins().find(p => p.source === 'external' && p.packageName?.match(/bastion-pro|@bastion\/pro/));
651
+ if (!proPlugin || pluginManager.isDisabled(proPlugin.name)) {
652
+ sendJson(res, { pro: false });
653
+ return true;
654
+ }
655
+ // The Pro plugin stores a signed token — we verify the signature
656
+ // so a forged plugin cannot simply claim valid: true.
657
+ const licenseState = getPluginState ? getPluginState(proPlugin.name, 'license') : undefined;
658
+ const token = licenseState?.token;
659
+ const result = (0, verify_js_1.verifyLicenseToken)(token);
660
+ if (result.valid && result.payload) {
661
+ sendJson(res, { pro: true, plan: result.payload.plan, expiresAt: result.payload.expiresAt, features: result.payload.features });
662
+ }
663
+ else {
664
+ sendJson(res, { pro: false, installed: true, reason: result.reason });
665
+ }
666
+ return true;
667
+ }
668
+ return false;
669
+ };
670
+ }
671
+ //# sourceMappingURL=api-routes.js.map