@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,116 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toProxyRequest = toProxyRequest;
4
+ exports.toProxyResponseFromIntercept = toProxyResponseFromIntercept;
5
+ exports.toProxyResponseFromComplete = toProxyResponseFromComplete;
6
+ exports.adaptPlugin = adaptPlugin;
7
+ const logger_js_1 = require("../utils/logger.js");
8
+ const log = (0, logger_js_1.createLogger)('plugin-adapter');
9
+ /** Convert internal RequestContext to public ProxyRequest (strip internal flags) */
10
+ function toProxyRequest(ctx) {
11
+ return {
12
+ id: ctx.id,
13
+ provider: ctx.provider,
14
+ model: ctx.model,
15
+ method: ctx.method,
16
+ path: ctx.path,
17
+ headers: Object.freeze({ ...ctx.headers }),
18
+ body: ctx.body,
19
+ parsedBody: Object.freeze({ ...ctx.parsedBody }),
20
+ isStreaming: ctx.isStreaming,
21
+ sessionId: ctx.sessionId,
22
+ };
23
+ }
24
+ /** Convert internal ResponseInterceptContext to public ProxyResponse (no usage/latency available) */
25
+ function toProxyResponseFromIntercept(ctx) {
26
+ return {
27
+ request: toProxyRequest(ctx.request),
28
+ statusCode: ctx.statusCode,
29
+ headers: Object.freeze({}),
30
+ body: ctx.body,
31
+ parsedBody: ctx.parsedBody ? Object.freeze({ ...ctx.parsedBody }) : null,
32
+ isStreaming: ctx.isStreaming,
33
+ };
34
+ }
35
+ /** Convert internal ResponseCompleteContext to public ProxyResponse (with usage/latency) */
36
+ function toProxyResponseFromComplete(ctx) {
37
+ return {
38
+ request: toProxyRequest(ctx.request),
39
+ statusCode: ctx.statusCode,
40
+ headers: Object.freeze({}),
41
+ body: ctx.body,
42
+ parsedBody: ctx.parsedBody ? Object.freeze({ ...ctx.parsedBody }) : null,
43
+ isStreaming: ctx.isStreaming,
44
+ usage: ctx.usage ? { inputTokens: ctx.usage.inputTokens, outputTokens: ctx.usage.outputTokens } : undefined,
45
+ latencyMs: ctx.latencyMs,
46
+ };
47
+ }
48
+ /** Persist PluginResult.events to DB */
49
+ function persistEvents(pluginName, requestId, result, repo) {
50
+ if (!result?.events?.length)
51
+ return;
52
+ for (const event of result.events) {
53
+ try {
54
+ repo.insertEvent(pluginName, requestId, event);
55
+ }
56
+ catch (err) {
57
+ log.warn('Failed to persist plugin event', { plugin: pluginName, error: err.message });
58
+ }
59
+ }
60
+ }
61
+ /** Convert public PluginResult to internal PluginRequestResult */
62
+ function toPluginRequestResult(result) {
63
+ if (!result)
64
+ return {};
65
+ if (result.action === 'block') {
66
+ return { blocked: { reason: `Blocked by plugin` } };
67
+ }
68
+ return {};
69
+ }
70
+ /** Convert public PluginResult to internal PluginResponseResult */
71
+ function toPluginResponseResult(result) {
72
+ if (!result)
73
+ return {};
74
+ if (result.action === 'block') {
75
+ return { blocked: { reason: `Blocked by plugin` } };
76
+ }
77
+ return {};
78
+ }
79
+ /** Adapt an external BastionPlugin to the internal Plugin interface */
80
+ function adaptPlugin(external, priority, repo, packageName) {
81
+ const plugin = {
82
+ name: external.name,
83
+ priority,
84
+ version: external.version,
85
+ apiVersion: external.apiVersion,
86
+ source: 'external',
87
+ packageName,
88
+ };
89
+ if (external.onRequest) {
90
+ const originalOnRequest = external.onRequest.bind(external);
91
+ plugin.onRequest = async (ctx) => {
92
+ const proxyReq = toProxyRequest(ctx);
93
+ const result = await originalOnRequest(proxyReq);
94
+ persistEvents(external.name, ctx.id, result, repo);
95
+ return toPluginRequestResult(result);
96
+ };
97
+ }
98
+ if (external.onResponse) {
99
+ const originalOnResponse = external.onResponse.bind(external);
100
+ plugin.onResponse = async (ctx) => {
101
+ const proxyRes = toProxyResponseFromIntercept(ctx);
102
+ const result = await originalOnResponse(proxyRes);
103
+ persistEvents(external.name, ctx.request.id, result, repo);
104
+ return toPluginResponseResult(result);
105
+ };
106
+ }
107
+ if (external.onResponseComplete) {
108
+ const originalOnResponseComplete = external.onResponseComplete.bind(external);
109
+ plugin.onResponseComplete = async (ctx) => {
110
+ const proxyRes = toProxyResponseFromComplete(ctx);
111
+ await originalOnResponseComplete(proxyRes);
112
+ };
113
+ }
114
+ return plugin;
115
+ }
116
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/plugins/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { Plugin } from '../types.js';
2
+ import type Database from 'better-sqlite3';
3
+ export interface AuditLoggerConfig {
4
+ rawData: boolean;
5
+ rawMaxBytes: number;
6
+ summaryMaxBytes: number;
7
+ }
8
+ export declare function createAuditLoggerPlugin(db: Database.Database, config: AuditLoggerConfig): Plugin;
9
+ //# sourceMappingURL=audit-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.d.ts","sourceRoot":"","sources":["../../../src/plugins/builtin/audit-logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAgE,MAAM,aAAa,CAAC;AAIxG,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAI3C,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAiDhG"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createAuditLoggerPlugin = createAuditLoggerPlugin;
4
+ const audit_log_js_1 = require("../../storage/repositories/audit-log.js");
5
+ const classify_js_1 = require("../../proxy/providers/classify.js");
6
+ const logger_js_1 = require("../../utils/logger.js");
7
+ const log = (0, logger_js_1.createLogger)('audit-plugin');
8
+ function createAuditLoggerPlugin(db, config) {
9
+ const auditRepo = new audit_log_js_1.AuditLogRepository(db);
10
+ // Store request bodies temporarily until response is complete
11
+ const pendingRequests = new Map();
12
+ return {
13
+ name: 'audit-logger',
14
+ priority: 25,
15
+ version: '1.0.0',
16
+ apiVersion: 2,
17
+ async onRequest(context) {
18
+ // Capture request body for later storage
19
+ pendingRequests.set(context.id, context.body);
20
+ },
21
+ async onResponseComplete(context) {
22
+ const requestBody = pendingRequests.get(context.request.id) ?? '';
23
+ pendingRequests.delete(context.request.id);
24
+ // Skip high-frequency polling requests — unless DLP flagged sensitive data
25
+ if ((0, classify_js_1.isPollingRequest)(context.request.provider, context.request.path) && !context.request.dlpHit)
26
+ return;
27
+ try {
28
+ // Avoid duplicates — DLP auto-audit may have already stored this request
29
+ if (auditRepo.hasEntry(context.request.id))
30
+ return;
31
+ // Read flags set by upstream plugins during onRequest/onResponse/onResponseComplete
32
+ const dlpHit = Boolean(context.request.dlpHit);
33
+ const toolGuardHit = Boolean(context.request.toolGuardHit);
34
+ auditRepo.insert({
35
+ id: crypto.randomUUID(),
36
+ request_id: context.request.id,
37
+ requestBody,
38
+ responseBody: context.body,
39
+ dlpHit,
40
+ toolGuardHit,
41
+ rawData: config.rawData,
42
+ rawMaxBytes: config.rawMaxBytes,
43
+ summaryMaxBytes: config.summaryMaxBytes,
44
+ });
45
+ log.debug('Audit entry stored', { requestId: context.request.id });
46
+ }
47
+ catch (err) {
48
+ log.warn('Failed to store audit entry', { error: err.message });
49
+ }
50
+ },
51
+ };
52
+ }
53
+ //# sourceMappingURL=audit-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-logger.js","sourceRoot":"","sources":["../../../src/plugins/builtin/audit-logger.ts"],"names":[],"mappings":";;AAcA,0DAiDC;AA9DD,0EAA6E;AAC7E,mEAAqE;AACrE,qDAAqD;AAGrD,MAAM,GAAG,GAAG,IAAA,wBAAY,EAAC,cAAc,CAAC,CAAC;AAQzC,SAAgB,uBAAuB,CAAC,EAAqB,EAAE,MAAyB;IACtF,MAAM,SAAS,GAAG,IAAI,iCAAkB,CAAC,EAAE,CAAC,CAAC;IAE7C,8DAA8D;IAC9D,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAC;IAElD,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,QAAQ,EAAE,EAAE;QACZ,OAAO,EAAE,OAAO;QAChB,UAAU,EAAE,CAAC;QAEb,KAAK,CAAC,SAAS,CAAC,OAAuB;YACrC,yCAAyC;YACzC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC;QAED,KAAK,CAAC,kBAAkB,CAAC,OAAgC;YACvD,MAAM,WAAW,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAClE,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE3C,2EAA2E;YAC3E,IAAI,IAAA,8BAAgB,EAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM;gBAAE,OAAO;YAExG,IAAI,CAAC;gBACH,yEAAyE;gBACzE,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAAE,OAAO;gBAEnD,oFAAoF;gBACpF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;gBAE3D,SAAS,CAAC,MAAM,CAAC;oBACf,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;oBACvB,UAAU,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE;oBAC9B,WAAW;oBACX,YAAY,EAAE,OAAO,CAAC,IAAI;oBAC1B,MAAM;oBACN,YAAY;oBACZ,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,WAAW,EAAE,MAAM,CAAC,WAAW;oBAC/B,eAAe,EAAE,MAAM,CAAC,eAAe;iBACxC,CAAC,CAAC;gBACH,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;YACrE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,GAAG,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Plugin } from '../types.js';
2
+ import type { DlpAction } from '../../dlp/actions.js';
3
+ import { type AiValidatorConfig } from '../../dlp/ai-validator.js';
4
+ import type Database from 'better-sqlite3';
5
+ export interface DlpScannerConfig {
6
+ action: DlpAction;
7
+ patterns: string[];
8
+ remotePatterns?: {
9
+ url: string;
10
+ branch: string;
11
+ syncOnStart: boolean;
12
+ syncIntervalMinutes: number;
13
+ };
14
+ aiValidation?: AiValidatorConfig;
15
+ /** Live getter for action — when provided, overrides static `action` field */
16
+ getAction?: () => DlpAction;
17
+ }
18
+ export declare function createDlpScannerPlugin(db: Database.Database, config: DlpScannerConfig): Plugin;
19
+ //# sourceMappingURL=dlp-scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlp-scanner.d.ts","sourceRoot":"","sources":["../../../src/plugins/builtin/dlp-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAItD,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAShF,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAM3C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,OAAO,CAAC;QACrB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,SAAS,CAAC;CAC7B;AAiBD,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA+Q9F"}
@@ -0,0 +1,284 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDlpScannerPlugin = createDlpScannerPlugin;
4
+ const engine_js_1 = require("../../dlp/engine.js");
5
+ const dlp_events_js_1 = require("../../storage/repositories/dlp-events.js");
6
+ const dlp_patterns_js_1 = require("../../storage/repositories/dlp-patterns.js");
7
+ const audit_log_js_1 = require("../../storage/repositories/audit-log.js");
8
+ const ai_validator_js_1 = require("../../dlp/ai-validator.js");
9
+ const high_confidence_js_1 = require("../../dlp/patterns/high-confidence.js");
10
+ const validated_js_1 = require("../../dlp/patterns/validated.js");
11
+ const context_aware_js_1 = require("../../dlp/patterns/context-aware.js");
12
+ const prompt_injection_js_1 = require("../../dlp/patterns/prompt-injection.js");
13
+ const remote_sync_js_1 = require("../../dlp/remote-sync.js");
14
+ const message_cache_js_1 = require("../../dlp/message-cache.js");
15
+ const classify_js_1 = require("../../proxy/providers/classify.js");
16
+ const logger_js_1 = require("../../utils/logger.js");
17
+ const log = (0, logger_js_1.createLogger)('dlp-plugin');
18
+ const SNIPPET_CONTEXT = 25; // chars of context on each side of match
19
+ /**
20
+ * Extract a context snippet around the first match in the text.
21
+ * Returns up to 50 chars of context centered on the match.
22
+ */
23
+ function extractSnippet(text, match) {
24
+ const idx = text.indexOf(match);
25
+ if (idx === -1)
26
+ return match.slice(0, 50);
27
+ const start = Math.max(0, idx - SNIPPET_CONTEXT);
28
+ const end = Math.min(text.length, idx + match.length + SNIPPET_CONTEXT);
29
+ let snippet = text.slice(start, end);
30
+ if (start > 0)
31
+ snippet = '...' + snippet;
32
+ if (end < text.length)
33
+ snippet = snippet + '...';
34
+ return snippet;
35
+ }
36
+ function createDlpScannerPlugin(db, config) {
37
+ const dlpRepo = new dlp_events_js_1.DlpEventsRepository(db);
38
+ const patternsRepo = new dlp_patterns_js_1.DlpPatternsRepository(db);
39
+ const auditRepo = new audit_log_js_1.AuditLogRepository(db);
40
+ const getAction = () => config.getAction ? config.getAction() : config.action;
41
+ // AI validation — optional, default off
42
+ const aiValidator = config.aiValidation
43
+ ? new ai_validator_js_1.AiValidator(config.aiValidation)
44
+ : null;
45
+ // Message-level DLP cache — avoids re-scanning repeated conversation history
46
+ const messageCache = new message_cache_js_1.DlpMessageCache();
47
+ // Seed built-in patterns from the 3 pattern files
48
+ const allBuiltins = [
49
+ ...high_confidence_js_1.highConfidencePatterns,
50
+ ...validated_js_1.validatedPatterns,
51
+ ...context_aware_js_1.contextAwarePatterns,
52
+ ...prompt_injection_js_1.promptInjectionPatterns,
53
+ ];
54
+ patternsRepo.seedBuiltins(allBuiltins, config.patterns);
55
+ // Sync remote patterns from signature repo (if configured)
56
+ if (config.remotePatterns?.url) {
57
+ if (config.remotePatterns.syncOnStart !== false) {
58
+ try {
59
+ (0, remote_sync_js_1.syncRemotePatterns)(config.remotePatterns, patternsRepo, config.patterns);
60
+ }
61
+ catch (err) {
62
+ log.warn('Remote pattern sync failed on startup', { error: err.message });
63
+ }
64
+ }
65
+ if (config.remotePatterns.syncIntervalMinutes > 0) {
66
+ (0, remote_sync_js_1.startPeriodicSync)(config.remotePatterns, patternsRepo, config.patterns);
67
+ }
68
+ }
69
+ return {
70
+ name: 'dlp-scanner',
71
+ priority: 20,
72
+ version: '1.0.0',
73
+ apiVersion: 2,
74
+ // ── Request-side: scan outgoing requests to LLM ──
75
+ async onRequest(context) {
76
+ // GET/HEAD have no meaningful request body to scan
77
+ if (context.method === 'GET' || context.method === 'HEAD')
78
+ return;
79
+ const patterns = patternsRepo.getEnabled();
80
+ const result = messageCache.scanWithCache(context.body, context.parsedBody, patterns, getAction());
81
+ if (result.findings.length === 0)
82
+ return;
83
+ // AI validation: only validate NEW findings (cached ones were already validated)
84
+ if (aiValidator?.ready && result.newFindings.length > 0) {
85
+ result.newFindings = await aiValidator.validate(result.newFindings, context.body);
86
+ // Rebuild combined findings
87
+ result.findings = [...result.newFindings, ...result.cachedFindings];
88
+ if (result.findings.length === 0)
89
+ return;
90
+ }
91
+ // Record DLP events — only for NEW findings to avoid duplicate records
92
+ for (const finding of result.newFindings) {
93
+ const firstMatch = finding.matches[0] ?? '';
94
+ const originalSnippet = extractSnippet(context.body, firstMatch);
95
+ let redactedSnippet = null;
96
+ if (result.action === 'redact' && result.redactedBody) {
97
+ const redactedTag = `[${finding.patternName.toUpperCase()}_REDACTED]`;
98
+ redactedSnippet = extractSnippet(result.redactedBody, redactedTag);
99
+ }
100
+ dlpRepo.insert({
101
+ id: crypto.randomUUID(),
102
+ request_id: context.id,
103
+ pattern_name: finding.patternName,
104
+ pattern_category: finding.patternCategory,
105
+ action: result.action,
106
+ match_count: finding.matchCount,
107
+ original_snippet: originalSnippet,
108
+ redacted_snippet: redactedSnippet,
109
+ });
110
+ }
111
+ log.info('DLP findings', {
112
+ requestId: context.id,
113
+ action: result.action,
114
+ newFindings: result.newFindings.map((f) => f.patternName),
115
+ cachedFindings: result.cachedFindings.map((f) => f.patternName),
116
+ totalFindings: result.findings.length,
117
+ });
118
+ // Set DLP flags on context for downstream plugins (audit-logger, metrics-collector)
119
+ // Only count new findings for dlpHit to avoid noise in audit logs
120
+ context.dlpHit = result.newFindings.length > 0;
121
+ context.dlpAction = result.action;
122
+ context.dlpFindings = result.newFindings.length;
123
+ // Auto-audit on DLP hit — only for new findings
124
+ if (result.action === 'block') {
125
+ const allPatterns = result.findings.map((f) => f.patternName).join(', ');
126
+ const blockReason = `Request blocked: sensitive data detected (${allPatterns})`;
127
+ if (result.newFindings.length > 0) {
128
+ try {
129
+ auditRepo.insert({
130
+ id: crypto.randomUUID(),
131
+ request_id: context.id,
132
+ requestBody: context.body,
133
+ responseBody: JSON.stringify({ error: blockReason }),
134
+ dlpHit: true,
135
+ });
136
+ }
137
+ catch (err) {
138
+ log.warn('Failed to write DLP auto-audit for blocked request', { error: err.message });
139
+ }
140
+ }
141
+ else {
142
+ log.info('DLP block from cached findings only (no new audit entry)', {
143
+ requestId: context.id,
144
+ cachedFindings: result.cachedFindings.map((f) => f.patternName),
145
+ });
146
+ }
147
+ return { blocked: { reason: blockReason } };
148
+ }
149
+ if (result.action === 'redact' && result.redactedBody) {
150
+ if (result.newFindings.length === 0) {
151
+ log.info('DLP redaction from cached findings only (no new DLP events)', {
152
+ requestId: context.id,
153
+ cachedFindings: result.cachedFindings.map((f) => f.patternName),
154
+ });
155
+ }
156
+ return { modifiedBody: result.redactedBody };
157
+ }
158
+ },
159
+ // ── Response-side: scan LLM response BEFORE sending to client (non-streaming only) ──
160
+ async onResponse(context) {
161
+ if (context.isStreaming)
162
+ return; // streaming handled in onResponseComplete (post-send)
163
+ const patterns = patternsRepo.getEnabled();
164
+ const result = (0, engine_js_1.scanText)(context.body, patterns, getAction());
165
+ if (result.findings.length === 0)
166
+ return;
167
+ // AI validation on response findings
168
+ if (aiValidator?.ready) {
169
+ result.findings = await aiValidator.validate(result.findings, context.body);
170
+ if (result.findings.length === 0)
171
+ return;
172
+ }
173
+ // Record response-side DLP events
174
+ for (const finding of result.findings) {
175
+ const firstMatch = finding.matches[0] ?? '';
176
+ const originalSnippet = extractSnippet(context.body, firstMatch);
177
+ let redactedSnippet = null;
178
+ if (result.action === 'redact' && result.redactedBody) {
179
+ const redactedTag = `[${finding.patternName.toUpperCase()}_REDACTED]`;
180
+ redactedSnippet = extractSnippet(result.redactedBody, redactedTag);
181
+ }
182
+ dlpRepo.insert({
183
+ id: crypto.randomUUID(),
184
+ request_id: context.request.id,
185
+ pattern_name: finding.patternName,
186
+ pattern_category: finding.patternCategory,
187
+ action: result.action,
188
+ match_count: finding.matchCount,
189
+ original_snippet: originalSnippet,
190
+ redacted_snippet: redactedSnippet,
191
+ direction: 'response',
192
+ });
193
+ }
194
+ log.info('DLP response findings', {
195
+ requestId: context.request.id,
196
+ direction: 'response',
197
+ action: result.action,
198
+ findings: result.findings.map((f) => f.patternName),
199
+ });
200
+ // Set DLP flags on context for downstream plugins (audit-logger reads these)
201
+ context.request.dlpHit = true;
202
+ context.request.dlpAction = result.action;
203
+ context.request.dlpFindings = (context.request.dlpFindings ?? 0) + result.findings.length;
204
+ // Apply action: block or redact the response
205
+ if (result.action === 'block') {
206
+ // Polling responses: return empty result instead of 403 to keep client connected
207
+ if ((0, classify_js_1.isPollingRequest)(context.request.provider, context.request.path)) {
208
+ log.warn('DLP blocked polling response, returning empty result', {
209
+ requestId: context.request.id,
210
+ findings: result.findings.map((f) => f.patternName),
211
+ });
212
+ return { modifiedBody: JSON.stringify({ ok: true, result: [] }) };
213
+ }
214
+ return {
215
+ blocked: {
216
+ reason: `Response blocked: sensitive data detected (${result.findings.map((f) => f.patternName).join(', ')})`,
217
+ },
218
+ };
219
+ }
220
+ if (result.action === 'redact' && result.redactedBody) {
221
+ return { modifiedBody: result.redactedBody };
222
+ }
223
+ // 'warn' and 'pass' — let through without modification
224
+ },
225
+ // ── Post-send: streaming response detection (can't block, but record + audit) ──
226
+ async onResponseComplete(context) {
227
+ if (!context.isStreaming)
228
+ return;
229
+ // Skip DLP scanning for very large streaming bodies (data already sent, can only warn)
230
+ if (context.body.length > 1024 * 1024) {
231
+ log.debug('Skipping DLP scan for large streaming response', {
232
+ requestId: context.request.id,
233
+ bodyLength: context.body.length,
234
+ });
235
+ return;
236
+ }
237
+ const patterns = patternsRepo.getEnabled();
238
+ const responseResult = (0, engine_js_1.scanText)(context.body, patterns, 'warn');
239
+ if (responseResult.findings.length === 0)
240
+ return;
241
+ if (aiValidator?.ready) {
242
+ responseResult.findings = await aiValidator.validate(responseResult.findings, context.body);
243
+ if (responseResult.findings.length === 0)
244
+ return;
245
+ }
246
+ for (const finding of responseResult.findings) {
247
+ const firstMatch = finding.matches[0] ?? '';
248
+ dlpRepo.insert({
249
+ id: crypto.randomUUID(),
250
+ request_id: context.request.id,
251
+ pattern_name: finding.patternName,
252
+ pattern_category: finding.patternCategory,
253
+ action: 'warn',
254
+ match_count: finding.matchCount,
255
+ original_snippet: extractSnippet(context.body, firstMatch),
256
+ redacted_snippet: null,
257
+ direction: 'response',
258
+ });
259
+ }
260
+ log.info('DLP streaming response findings (post-send)', {
261
+ requestId: context.request.id,
262
+ findings: responseResult.findings.map((f) => f.patternName),
263
+ });
264
+ try {
265
+ if (!auditRepo.hasEntry(context.request.id)) {
266
+ auditRepo.insert({
267
+ id: crypto.randomUUID(),
268
+ request_id: context.request.id,
269
+ requestBody: context.request.body,
270
+ responseBody: context.body,
271
+ dlpHit: true,
272
+ });
273
+ }
274
+ else {
275
+ auditRepo.markDlpHit(context.request.id);
276
+ }
277
+ }
278
+ catch (err) {
279
+ log.warn('Failed to write DLP streaming response auto-audit', { error: err.message });
280
+ }
281
+ },
282
+ };
283
+ }
284
+ //# sourceMappingURL=dlp-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dlp-scanner.js","sourceRoot":"","sources":["../../../src/plugins/builtin/dlp-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Plugin } from '../types.js';
2
+ import type Database from 'better-sqlite3';
3
+ export declare function createMetricsCollectorPlugin(db: Database.Database): Plugin;
4
+ //# sourceMappingURL=metrics-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metrics-collector.d.ts","sourceRoot":"","sources":["../../../src/plugins/builtin/metrics-collector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAA2B,MAAM,aAAa,CAAC;AAMnE,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAyC3C,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAgE1E"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createMetricsCollectorPlugin = createMetricsCollectorPlugin;
4
+ const collector_js_1 = require("../../metrics/collector.js");
5
+ const requests_js_1 = require("../../storage/repositories/requests.js");
6
+ const sessions_js_1 = require("../../storage/repositories/sessions.js");
7
+ const classify_js_1 = require("../../proxy/providers/classify.js");
8
+ const logger_js_1 = require("../../utils/logger.js");
9
+ const node_path_1 = require("node:path");
10
+ const log = (0, logger_js_1.createLogger)('metrics-plugin');
11
+ /**
12
+ * Extract project path from the request body's system prompt.
13
+ * Claude Code includes "Primary working directory: /path/to/project" in system prompts.
14
+ */
15
+ function extractProjectPath(parsedBody) {
16
+ let systemText = '';
17
+ if (typeof parsedBody.system === 'string') {
18
+ systemText = parsedBody.system;
19
+ }
20
+ else if (Array.isArray(parsedBody.system)) {
21
+ for (const block of parsedBody.system) {
22
+ if (typeof block === 'string')
23
+ systemText += block;
24
+ else if (block?.type === 'text' && typeof block.text === 'string')
25
+ systemText += block.text;
26
+ }
27
+ }
28
+ // Also check first user message for system-reminder style content
29
+ if (!systemText && Array.isArray(parsedBody.messages)) {
30
+ const first = parsedBody.messages[0];
31
+ if (first?.role === 'user') {
32
+ const content = first.content;
33
+ if (typeof content === 'string')
34
+ systemText = content;
35
+ else if (Array.isArray(content)) {
36
+ for (const block of content) {
37
+ if (typeof block === 'string')
38
+ systemText += block;
39
+ else if (block?.type === 'text' && typeof block.text === 'string')
40
+ systemText += block.text;
41
+ }
42
+ }
43
+ }
44
+ }
45
+ const match = systemText.match(/Primary working directory:\s*([^\n]+)/);
46
+ if (match)
47
+ return match[1].trim();
48
+ return null;
49
+ }
50
+ function createMetricsCollectorPlugin(db) {
51
+ const requestsRepo = new requests_js_1.RequestsRepository(db);
52
+ const sessionsRepo = new sessions_js_1.SessionsRepository(db);
53
+ return {
54
+ name: 'metrics-collector',
55
+ priority: 10,
56
+ version: '1.0.0',
57
+ apiVersion: 2,
58
+ async onResponseComplete(context) {
59
+ // Skip high-frequency polling requests (e.g., Telegram getUpdates)
60
+ if ((0, classify_js_1.isPollingRequest)(context.request.provider, context.request.path))
61
+ return;
62
+ const metrics = (0, collector_js_1.extractMetrics)(context);
63
+ const sessionId = context.request.sessionId ?? null;
64
+ requestsRepo.insert({
65
+ id: context.request.id,
66
+ provider: context.request.provider,
67
+ model: context.request.model,
68
+ method: context.request.method,
69
+ path: context.request.path,
70
+ status_code: context.statusCode,
71
+ input_tokens: metrics.inputTokens,
72
+ output_tokens: metrics.outputTokens,
73
+ cache_creation_tokens: metrics.cacheCreationTokens,
74
+ cache_read_tokens: metrics.cacheReadTokens,
75
+ cost_usd: metrics.costUsd,
76
+ latency_ms: metrics.latencyMs,
77
+ cached: 0,
78
+ dlp_action: context.request.dlpAction ?? null,
79
+ dlp_findings: context.request.dlpFindings ?? 0,
80
+ session_id: sessionId,
81
+ api_key_hash: context.request.apiKeyHash ?? null,
82
+ });
83
+ // Persist session metadata with client info
84
+ if (sessionId) {
85
+ try {
86
+ const projectPath = extractProjectPath(context.request.parsedBody);
87
+ let label = projectPath ? (0, node_path_1.basename)(projectPath) : null;
88
+ // Fallback label: use provider:model so sessions are identifiable
89
+ if (!label) {
90
+ const provider = context.request.provider;
91
+ const model = context.request.model;
92
+ label = model && model !== provider ? `${provider}:${model}` : provider;
93
+ }
94
+ const source = context.request.sessionSource ?? 'auto';
95
+ sessionsRepo.upsert(sessionId, { label: label ?? undefined, source, projectPath: projectPath ?? undefined });
96
+ }
97
+ catch (err) {
98
+ log.debug('Failed to upsert session', { error: err.message });
99
+ }
100
+ }
101
+ log.debug('Recorded request metrics', {
102
+ id: context.request.id,
103
+ model: context.request.model,
104
+ cost: metrics.costUsd.toFixed(6),
105
+ latency: metrics.latencyMs,
106
+ sessionId,
107
+ });
108
+ },
109
+ };
110
+ }
111
+ //# sourceMappingURL=metrics-collector.js.map