atabey 0.0.13 → 0.0.15

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 (282) hide show
  1. package/ATABEY.md +1 -1
  2. package/PRIVACY.md +8 -14
  3. package/README.md +405 -56
  4. package/bin/cli.js +72 -5
  5. package/dist/framework-mcp/src/index.js +988 -63
  6. package/dist/framework-mcp/src/index.js.map +1 -1
  7. package/dist/framework-mcp/src/tools/compliance/mask_pii.d.ts +17 -0
  8. package/dist/framework-mcp/src/tools/compliance/mask_pii.js +56 -0
  9. package/dist/framework-mcp/src/tools/compliance/mask_pii.js.map +1 -0
  10. package/dist/framework-mcp/src/tools/definitions.js +10 -9
  11. package/dist/framework-mcp/src/tools/definitions.js.map +1 -1
  12. package/dist/framework-mcp/src/tools/framework/run_tests.js +25 -0
  13. package/dist/framework-mcp/src/tools/framework/run_tests.js.map +1 -1
  14. package/dist/framework-mcp/src/tools/index.js +7 -8
  15. package/dist/framework-mcp/src/tools/index.js.map +1 -1
  16. package/dist/framework-mcp/src/tools/messaging/approve_operation.d.ts +22 -0
  17. package/dist/framework-mcp/src/tools/messaging/approve_operation.js +81 -0
  18. package/dist/framework-mcp/src/tools/messaging/approve_operation.js.map +1 -0
  19. package/dist/framework-mcp/src/tools/messaging/ask_human.d.ts +15 -0
  20. package/dist/framework-mcp/src/tools/messaging/ask_human.js +89 -20
  21. package/dist/framework-mcp/src/tools/messaging/ask_human.js.map +1 -1
  22. package/dist/framework-mcp/src/tools/observability/check_ports.d.ts +1 -0
  23. package/dist/framework-mcp/src/tools/observability/check_ports.js +24 -8
  24. package/dist/framework-mcp/src/tools/observability/check_ports.js.map +1 -1
  25. package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +13 -64
  26. package/dist/framework-mcp/src/tools/quality/analyze_code_quality.js.map +1 -1
  27. package/dist/framework-mcp/src/tools/schemas.d.ts +48 -53
  28. package/dist/framework-mcp/src/tools/schemas.js +18 -22
  29. package/dist/framework-mcp/src/tools/schemas.js.map +1 -1
  30. package/dist/framework-mcp/src/tools/shell/run_command.js +146 -90
  31. package/dist/framework-mcp/src/tools/shell/run_command.js.map +1 -1
  32. package/dist/framework-mcp/src/tools/types.d.ts +11 -105
  33. package/dist/framework-mcp/src/tools/types.js +1 -0
  34. package/dist/framework-mcp/src/tools/types.js.map +1 -1
  35. package/dist/framework-mcp/src/utils/auth.d.ts +36 -0
  36. package/dist/framework-mcp/src/utils/auth.js +79 -0
  37. package/dist/framework-mcp/src/utils/auth.js.map +1 -0
  38. package/dist/framework-mcp/src/utils/auto-rollback.d.ts +71 -0
  39. package/dist/framework-mcp/src/utils/auto-rollback.js +266 -0
  40. package/dist/framework-mcp/src/utils/auto-rollback.js.map +1 -0
  41. package/dist/framework-mcp/src/utils/compliance.js +12 -4
  42. package/dist/framework-mcp/src/utils/compliance.js.map +1 -1
  43. package/dist/framework-mcp/src/utils/context-optimizer.d.ts +69 -0
  44. package/dist/framework-mcp/src/utils/context-optimizer.js +157 -0
  45. package/dist/framework-mcp/src/utils/context-optimizer.js.map +1 -0
  46. package/dist/framework-mcp/src/utils/discipline.d.ts +68 -0
  47. package/dist/framework-mcp/src/utils/discipline.js +218 -0
  48. package/dist/framework-mcp/src/utils/discipline.js.map +1 -0
  49. package/dist/framework-mcp/src/utils/finops.d.ts +143 -0
  50. package/dist/framework-mcp/src/utils/finops.js +326 -0
  51. package/dist/framework-mcp/src/utils/finops.js.map +1 -0
  52. package/dist/framework-mcp/src/utils/human-in-loop.d.ts +95 -0
  53. package/dist/framework-mcp/src/utils/human-in-loop.js +216 -0
  54. package/dist/framework-mcp/src/utils/human-in-loop.js.map +1 -0
  55. package/dist/framework-mcp/src/utils/license-scanner.d.ts +71 -0
  56. package/dist/framework-mcp/src/utils/license-scanner.js +284 -0
  57. package/dist/framework-mcp/src/utils/license-scanner.js.map +1 -0
  58. package/dist/framework-mcp/src/utils/loop-detector.d.ts +105 -0
  59. package/dist/framework-mcp/src/utils/loop-detector.js +362 -0
  60. package/dist/framework-mcp/src/utils/loop-detector.js.map +1 -0
  61. package/dist/framework-mcp/src/utils/quality.d.ts +19 -0
  62. package/dist/framework-mcp/src/utils/quality.js +125 -0
  63. package/dist/framework-mcp/src/utils/quality.js.map +1 -0
  64. package/dist/framework-mcp/src/utils/rules-engine.d.ts +78 -0
  65. package/dist/framework-mcp/src/utils/rules-engine.js +232 -0
  66. package/dist/framework-mcp/src/utils/rules-engine.js.map +1 -0
  67. package/dist/framework-mcp/src/utils/silent-router.d.ts +49 -0
  68. package/dist/framework-mcp/src/utils/silent-router.js +155 -0
  69. package/dist/framework-mcp/src/utils/silent-router.js.map +1 -0
  70. package/dist/framework-mcp/src/utils/storage.d.ts +1 -0
  71. package/dist/framework-mcp/src/utils/storage.js +2 -2
  72. package/dist/framework-mcp/src/utils/storage.js.map +1 -1
  73. package/dist/framework-mcp/src/utils/telemetry-streamer.d.ts +133 -0
  74. package/dist/framework-mcp/src/utils/telemetry-streamer.js +397 -0
  75. package/dist/framework-mcp/src/utils/telemetry-streamer.js.map +1 -0
  76. package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js +2 -2
  77. package/dist/framework-mcp/tests/tools/file_system/file_system_tools.test.js.map +1 -1
  78. package/dist/framework-mcp/tests/tools/framework/run_tests.test.d.ts +1 -0
  79. package/dist/framework-mcp/tests/tools/framework/run_tests.test.js +49 -0
  80. package/dist/framework-mcp/tests/tools/framework/run_tests.test.js.map +1 -0
  81. package/dist/framework-mcp/tests/tools/messaging/send_message.test.js +14 -5
  82. package/dist/framework-mcp/tests/tools/messaging/send_message.test.js.map +1 -1
  83. package/dist/framework-mcp/tests/tools/observability/check_ports.test.d.ts +1 -0
  84. package/dist/framework-mcp/tests/tools/observability/check_ports.test.js +44 -0
  85. package/dist/framework-mcp/tests/tools/observability/check_ports.test.js.map +1 -0
  86. package/dist/framework-mcp/tests/tools/shell/run_command.test.js +44 -14
  87. package/dist/framework-mcp/tests/tools/shell/run_command.test.js.map +1 -1
  88. package/dist/framework-mcp/tests/utils/auto-rollback.test.d.ts +7 -0
  89. package/dist/framework-mcp/tests/utils/auto-rollback.test.js +178 -0
  90. package/dist/framework-mcp/tests/utils/auto-rollback.test.js.map +1 -0
  91. package/dist/framework-mcp/tests/utils/context-optimizer.test.d.ts +1 -0
  92. package/dist/framework-mcp/tests/utils/context-optimizer.test.js +62 -0
  93. package/dist/framework-mcp/tests/utils/context-optimizer.test.js.map +1 -0
  94. package/dist/framework-mcp/tests/utils/finops.test.d.ts +7 -0
  95. package/dist/framework-mcp/tests/utils/finops.test.js +157 -0
  96. package/dist/framework-mcp/tests/utils/finops.test.js.map +1 -0
  97. package/dist/framework-mcp/tests/utils/human-in-loop.test.d.ts +1 -0
  98. package/dist/framework-mcp/tests/utils/human-in-loop.test.js +59 -0
  99. package/dist/framework-mcp/tests/utils/human-in-loop.test.js.map +1 -0
  100. package/dist/framework-mcp/tests/utils/license-scanner.test.d.ts +7 -0
  101. package/dist/framework-mcp/tests/utils/license-scanner.test.js +131 -0
  102. package/dist/framework-mcp/tests/utils/license-scanner.test.js.map +1 -0
  103. package/dist/framework-mcp/tests/utils/loop-detector.test.d.ts +7 -0
  104. package/dist/framework-mcp/tests/utils/loop-detector.test.js +204 -0
  105. package/dist/framework-mcp/tests/utils/loop-detector.test.js.map +1 -0
  106. package/dist/framework-mcp/tests/utils/rules-engine.test.d.ts +1 -0
  107. package/dist/framework-mcp/tests/utils/rules-engine.test.js +106 -0
  108. package/dist/framework-mcp/tests/utils/rules-engine.test.js.map +1 -0
  109. package/dist/framework-mcp/tests/utils/telemetry-streamer.test.d.ts +7 -0
  110. package/dist/framework-mcp/tests/utils/telemetry-streamer.test.js +201 -0
  111. package/dist/framework-mcp/tests/utils/telemetry-streamer.test.js.map +1 -0
  112. package/dist/src/cli/commands/check.js +16 -1
  113. package/dist/src/cli/commands/check.js.map +1 -1
  114. package/dist/src/cli/commands/dashboard.js +188 -164
  115. package/dist/src/cli/commands/dashboard.js.map +1 -1
  116. package/dist/src/cli/commands/gateway.js +2 -2
  117. package/dist/src/cli/commands/gateway.js.map +1 -1
  118. package/dist/src/cli/commands/init/scaffold-core.d.ts +2 -0
  119. package/dist/src/cli/commands/init/scaffold-core.js +16 -1
  120. package/dist/src/cli/commands/init/scaffold-core.js.map +1 -1
  121. package/dist/src/cli/commands/init/scaffold-ops.js +2 -2
  122. package/dist/src/cli/commands/init/scaffold-ops.js.map +1 -1
  123. package/dist/src/cli/commands/init/scaffold-standards.js +13 -1
  124. package/dist/src/cli/commands/init/scaffold-standards.js.map +1 -1
  125. package/dist/src/cli/commands/init.d.ts +4 -0
  126. package/dist/src/cli/commands/init.js +94 -31
  127. package/dist/src/cli/commands/init.js.map +1 -1
  128. package/dist/src/cli/commands/mcp.js +3 -1
  129. package/dist/src/cli/commands/mcp.js.map +1 -1
  130. package/dist/src/cli/commands/quickstart.d.ts +1 -1
  131. package/dist/src/cli/commands/quickstart.js +12 -24
  132. package/dist/src/cli/commands/quickstart.js.map +1 -1
  133. package/dist/src/cli/commands/script.js +8 -1
  134. package/dist/src/cli/commands/script.js.map +1 -1
  135. package/dist/src/cli/index.js +24 -23
  136. package/dist/src/cli/index.js.map +1 -1
  137. package/dist/src/cli/shims.js +7 -7
  138. package/dist/src/cli/utils/pkg.js +2 -3
  139. package/dist/src/cli/utils/pkg.js.map +1 -1
  140. package/dist/src/cli/utils/quality.d.ts +10 -0
  141. package/dist/src/cli/utils/quality.js +10 -0
  142. package/dist/src/cli/utils/quality.js.map +1 -0
  143. package/dist/src/modules/agents/definitions.js +45 -40
  144. package/dist/src/modules/agents/definitions.js.map +1 -1
  145. package/dist/src/modules/agents/registry/manager.js +6 -1
  146. package/dist/src/modules/agents/registry/manager.js.map +1 -1
  147. package/dist/src/modules/engines/agent-executor.d.ts +6 -10
  148. package/dist/src/modules/engines/agent-executor.js +63 -21
  149. package/dist/src/modules/engines/agent-executor.js.map +1 -1
  150. package/dist/src/modules/engines/agent-loop.d.ts +34 -0
  151. package/dist/src/modules/engines/agent-loop.js +102 -0
  152. package/dist/src/modules/engines/agent-loop.js.map +1 -0
  153. package/dist/src/modules/engines/evaluation-engine.d.ts +12 -2
  154. package/dist/src/modules/engines/evaluation-engine.js +78 -11
  155. package/dist/src/modules/engines/evaluation-engine.js.map +1 -1
  156. package/dist/src/modules/engines/quality-gate.d.ts +13 -5
  157. package/dist/src/modules/engines/quality-gate.js +39 -31
  158. package/dist/src/modules/engines/quality-gate.js.map +1 -1
  159. package/dist/src/modules/engines/routing-engine.d.ts +5 -3
  160. package/dist/src/modules/engines/routing-engine.js +16 -9
  161. package/dist/src/modules/engines/routing-engine.js.map +1 -1
  162. package/dist/src/modules/gateway/cost-tracker.d.ts +5 -0
  163. package/dist/src/modules/gateway/cost-tracker.js +71 -0
  164. package/dist/src/modules/gateway/cost-tracker.js.map +1 -1
  165. package/dist/src/modules/gateway/gateway.d.ts +4 -0
  166. package/dist/src/modules/gateway/gateway.js +8 -0
  167. package/dist/src/modules/gateway/gateway.js.map +1 -1
  168. package/dist/src/shared/audit.js +3 -2
  169. package/dist/src/shared/audit.js.map +1 -1
  170. package/dist/src/shared/pii.d.ts +41 -9
  171. package/dist/src/shared/pii.js +122 -31
  172. package/dist/src/shared/pii.js.map +1 -1
  173. package/dist/src/shared/storage.d.ts +62 -0
  174. package/dist/src/shared/storage.js +47 -7
  175. package/dist/src/shared/storage.js.map +1 -1
  176. package/dist/tests/embedding.test.d.ts +1 -0
  177. package/dist/tests/embedding.test.js +82 -0
  178. package/dist/tests/embedding.test.js.map +1 -0
  179. package/dist/tests/engines/evaluation-engine.test.d.ts +1 -0
  180. package/dist/tests/engines/evaluation-engine.test.js +71 -0
  181. package/dist/tests/engines/evaluation-engine.test.js.map +1 -0
  182. package/dist/tests/engines/planning-engine.test.d.ts +1 -0
  183. package/dist/tests/engines/planning-engine.test.js +100 -0
  184. package/dist/tests/engines/planning-engine.test.js.map +1 -0
  185. package/dist/tests/engines/quality-gate.test.d.ts +1 -0
  186. package/dist/tests/engines/quality-gate.test.js +59 -0
  187. package/dist/tests/engines/quality-gate.test.js.map +1 -0
  188. package/dist/tests/engines/risk-engine.test.d.ts +1 -0
  189. package/dist/tests/engines/risk-engine.test.js +80 -0
  190. package/dist/tests/engines/risk-engine.test.js.map +1 -0
  191. package/dist/tests/engines/routing-engine.test.d.ts +1 -0
  192. package/dist/tests/engines/routing-engine.test.js +78 -0
  193. package/dist/tests/engines/routing-engine.test.js.map +1 -0
  194. package/dist/tests/integration/hermes_locking.test.js +1 -0
  195. package/dist/tests/integration/hermes_locking.test.js.map +1 -1
  196. package/dist/tests/modules/engines/agent-executor.test.js +1 -1
  197. package/dist/tests/modules/engines/agent-executor.test.js.map +1 -1
  198. package/dist/tests/modules/gateway/cost-tracker.test.js +20 -1
  199. package/dist/tests/modules/gateway/cost-tracker.test.js.map +1 -1
  200. package/dist/tests/shared/lock.test.d.ts +1 -0
  201. package/dist/tests/shared/lock.test.js +95 -0
  202. package/dist/tests/shared/lock.test.js.map +1 -0
  203. package/dist/tests/shared/pii.test.d.ts +1 -0
  204. package/dist/tests/shared/pii.test.js +183 -0
  205. package/dist/tests/shared/pii.test.js.map +1 -0
  206. package/framework-mcp/README.md +307 -35
  207. package/framework-mcp/dist/dashboard/assets/index-B_rK57vi.js +1221 -0
  208. package/framework-mcp/dist/dashboard/index.html +1 -1
  209. package/framework-mcp/dist/framework-mcp/src/index.js +988 -63
  210. package/framework-mcp/dist/framework-mcp/src/tools/compliance/mask_pii.js +55 -0
  211. package/framework-mcp/dist/framework-mcp/src/tools/definitions.js +10 -9
  212. package/framework-mcp/dist/framework-mcp/src/tools/framework/run_tests.js +25 -0
  213. package/framework-mcp/dist/framework-mcp/src/tools/index.js +7 -8
  214. package/framework-mcp/dist/framework-mcp/src/tools/messaging/approve_operation.js +80 -0
  215. package/framework-mcp/dist/framework-mcp/src/tools/messaging/ask_human.js +89 -20
  216. package/framework-mcp/dist/framework-mcp/src/tools/observability/check_ports.js +24 -8
  217. package/framework-mcp/dist/framework-mcp/src/tools/quality/analyze_code_quality.js +13 -64
  218. package/framework-mcp/dist/framework-mcp/src/tools/schemas.js +18 -22
  219. package/framework-mcp/dist/framework-mcp/src/tools/shell/run_command.js +146 -90
  220. package/framework-mcp/dist/framework-mcp/src/tools/types.js +1 -0
  221. package/framework-mcp/dist/framework-mcp/src/utils/auth.js +78 -0
  222. package/framework-mcp/dist/framework-mcp/src/utils/auto-rollback.js +265 -0
  223. package/framework-mcp/dist/framework-mcp/src/utils/compliance.js +12 -4
  224. package/framework-mcp/dist/framework-mcp/src/utils/context-optimizer.js +156 -0
  225. package/framework-mcp/dist/framework-mcp/src/utils/discipline.js +217 -0
  226. package/framework-mcp/dist/framework-mcp/src/utils/finops.js +325 -0
  227. package/framework-mcp/dist/framework-mcp/src/utils/human-in-loop.js +215 -0
  228. package/framework-mcp/dist/framework-mcp/src/utils/license-scanner.js +283 -0
  229. package/framework-mcp/dist/framework-mcp/src/utils/loop-detector.js +361 -0
  230. package/framework-mcp/dist/framework-mcp/src/utils/quality.js +124 -0
  231. package/framework-mcp/dist/framework-mcp/src/utils/rules-engine.js +231 -0
  232. package/framework-mcp/dist/framework-mcp/src/utils/silent-router.js +154 -0
  233. package/framework-mcp/dist/framework-mcp/src/utils/storage.js +2 -2
  234. package/framework-mcp/dist/framework-mcp/src/utils/telemetry-streamer.js +396 -0
  235. package/framework-mcp/dist/src/cli/platforms/core.js +72 -0
  236. package/framework-mcp/dist/src/cli/platforms/index.js +5 -0
  237. package/framework-mcp/dist/src/cli/platforms/paths.js +101 -0
  238. package/framework-mcp/dist/src/cli/platforms/scaffold.js +72 -0
  239. package/framework-mcp/dist/src/cli/platforms/utils.js +75 -0
  240. package/framework-mcp/dist/src/cli/utils/claude.js +57 -0
  241. package/framework-mcp/dist/src/cli/utils/compliance.js +12 -0
  242. package/framework-mcp/dist/src/cli/utils/fs.js +138 -0
  243. package/framework-mcp/dist/src/cli/utils/pkg.js +282 -0
  244. package/framework-mcp/dist/src/cli/utils/quality.js +9 -0
  245. package/framework-mcp/dist/src/modules/agents/definitions.js +563 -0
  246. package/framework-mcp/dist/src/modules/agents/registry/analyst.js +39 -0
  247. package/framework-mcp/dist/src/modules/agents/registry/architect.js +42 -0
  248. package/framework-mcp/dist/src/modules/agents/registry/backend.js +50 -0
  249. package/framework-mcp/dist/src/modules/agents/registry/database.js +45 -0
  250. package/framework-mcp/dist/src/modules/agents/registry/devops.js +45 -0
  251. package/framework-mcp/dist/src/modules/agents/registry/explorer.js +37 -0
  252. package/framework-mcp/dist/src/modules/agents/registry/frontend.js +52 -0
  253. package/framework-mcp/dist/src/modules/agents/registry/git.js +36 -0
  254. package/framework-mcp/dist/src/modules/agents/registry/manager.js +64 -0
  255. package/framework-mcp/dist/src/modules/agents/registry/mobile.js +41 -0
  256. package/framework-mcp/dist/src/modules/agents/registry/native.js +41 -0
  257. package/framework-mcp/dist/src/modules/agents/registry/quality.js +43 -0
  258. package/framework-mcp/dist/src/modules/agents/registry/security.js +42 -0
  259. package/framework-mcp/dist/src/modules/agents/types.js +1 -0
  260. package/framework-mcp/dist/src/modules/engines/evaluation-engine.js +169 -0
  261. package/framework-mcp/dist/src/modules/engines/quality-gate.js +92 -0
  262. package/framework-mcp/dist/src/modules/engines/risk-engine.js +105 -0
  263. package/framework-mcp/dist/src/modules/engines/routing-engine.js +408 -0
  264. package/framework-mcp/dist/src/modules/engines/types.js +1 -0
  265. package/framework-mcp/dist/src/modules/providers/definitions.js +140 -0
  266. package/framework-mcp/dist/src/modules/providers/registry.js +18 -0
  267. package/framework-mcp/dist/src/modules/providers/shared.js +104 -0
  268. package/framework-mcp/dist/src/modules/providers/types.js +1 -0
  269. package/framework-mcp/dist/src/modules/skills/adapter-skills.js +449 -0
  270. package/framework-mcp/dist/src/modules/skills/definitions.js +70 -0
  271. package/framework-mcp/dist/src/shared/audit.js +220 -0
  272. package/framework-mcp/dist/src/shared/errors.js +68 -0
  273. package/framework-mcp/dist/src/shared/lock.js +159 -0
  274. package/framework-mcp/dist/src/shared/pii.js +122 -31
  275. package/framework-mcp/dist/src/shared/retention.js +170 -0
  276. package/framework-mcp/dist/src/shared/storage.js +47 -7
  277. package/framework-mcp/dist/src/shared/string.js +29 -0
  278. package/framework-mcp/package.json +8 -2
  279. package/mcp.json +12 -6
  280. package/package.json +11 -5
  281. package/templates/full/ATABEY_FULL.md +1 -1
  282. package/framework-mcp/dist/dashboard/assets/index-BAPGLiWE.js +0 -267
@@ -0,0 +1,157 @@
1
+ /**
2
+ * ─── CONTEXT OPTIMIZER ─────────────────────────────────────────────
3
+ *
4
+ * Prevents context poisoning and runaway token consumption by AI CLIs.
5
+ * Acts as a Circuit Breaker at the MCP middleware layer.
6
+ *
7
+ * Features:
8
+ * - Token Budget Enforcer: Max tokens per tool call response
9
+ * - File Read Limiter: Auto-truncate large file reads
10
+ * - Token-Based Rate Limiter: Max token spend per window
11
+ * - Response Size Governor: Truncates oversized responses
12
+ *
13
+ * [KVKK/GDPR] Also prevents PII leakage via oversized responses.
14
+ */
15
+ // ─── Configuration ────────────────────────────────────────────────
16
+ const CONFIG = {
17
+ /** Max tokens allowed in a single tool response */
18
+ MAX_TOKENS_PER_CALL: parseInt(process.env.MCP_MAX_TOKENS_PER_CALL || "4000", 10),
19
+ /** Max tokens per minute across all calls for an agent */
20
+ MAX_TOKENS_PER_MINUTE: parseInt(process.env.MCP_MAX_TOKENS_PER_MINUTE || "20000", 10),
21
+ /** Max tokens per hour across all calls for an agent */
22
+ MAX_TOKENS_PER_HOUR: parseInt(process.env.MCP_MAX_TOKENS_PER_HOUR || "100000", 10),
23
+ /** Max file size in bytes before auto-truncation (100KB) */
24
+ MAX_FILE_READ_SIZE: parseInt(process.env.MCP_MAX_FILE_READ_SIZE || "102400", 10),
25
+ /** Max lines to return for truncated files */
26
+ MAX_FILE_LINES: parseInt(process.env.MCP_MAX_FILE_LINES || "200", 10),
27
+ /** Token estimation ratio (chars per token) */
28
+ CHARS_PER_TOKEN: 4,
29
+ };
30
+ const agentBudgets = new Map();
31
+ function getOrCreateBudget(agent) {
32
+ if (!agentBudgets.has(agent)) {
33
+ agentBudgets.set(agent, {
34
+ records: [],
35
+ totalTokens: 0,
36
+ lastWarning: 0,
37
+ blockedUntil: null,
38
+ });
39
+ }
40
+ return agentBudgets.get(agent);
41
+ }
42
+ function pruneOldRecords(agent) {
43
+ const oneHourAgo = Date.now() - 3600000;
44
+ agent.records = agent.records.filter(r => r.timestamp > oneHourAgo);
45
+ }
46
+ function sumTokensInWindow(agent, windowMs) {
47
+ const cutoff = Date.now() - windowMs;
48
+ return agent.records
49
+ .filter(r => r.timestamp > cutoff)
50
+ .reduce((sum, r) => sum + r.tokens, 0);
51
+ }
52
+ /**
53
+ * Estimate token count from text.
54
+ * Uses 4 chars per token as a conservative estimate.
55
+ */
56
+ export function estimateTokens(text) {
57
+ if (!text)
58
+ return 0;
59
+ return Math.ceil(text.length / CONFIG.CHARS_PER_TOKEN);
60
+ }
61
+ /**
62
+ * Check if a tool response is within token budget.
63
+ * Returns null if allowed, or an error message if blocked.
64
+ */
65
+ export function checkTokenBudget(agent, toolName, responseText) {
66
+ const budget = getOrCreateBudget(agent);
67
+ // Check if agent is currently blocked
68
+ if (budget.blockedUntil && Date.now() < budget.blockedUntil) {
69
+ const remaining = Math.ceil((budget.blockedUntil - Date.now()) / 1000);
70
+ return `[TOKEN BUDGET] Agent ${agent} is blocked for ${remaining}s. Token limit exceeded.`;
71
+ }
72
+ const estimatedTokens = estimateTokens(responseText);
73
+ // 1. Check per-call limit
74
+ if (estimatedTokens > CONFIG.MAX_TOKENS_PER_CALL) {
75
+ return `[TOKEN BUDGET] Response too large: ~${estimatedTokens} tokens (max: ${CONFIG.MAX_TOKENS_PER_CALL}). Truncate your request.`;
76
+ }
77
+ // Record the token usage
78
+ budget.records.push({
79
+ tokens: estimatedTokens,
80
+ timestamp: Date.now(),
81
+ toolName,
82
+ });
83
+ budget.totalTokens += estimatedTokens;
84
+ // Prune old records
85
+ pruneOldRecords(budget);
86
+ // 2. Check per-minute limit
87
+ const minuteTokens = sumTokensInWindow(budget, 60000);
88
+ if (minuteTokens > CONFIG.MAX_TOKENS_PER_MINUTE) {
89
+ budget.blockedUntil = Date.now() + 30000; // 30s cooldown
90
+ return `[TOKEN BUDGET] Agent ${agent} exceeded ${CONFIG.MAX_TOKENS_PER_MINUTE} tokens/min. Cooldown 30s.`;
91
+ }
92
+ // 3. Check per-hour limit
93
+ const hourTokens = sumTokensInWindow(budget, 3600000);
94
+ if (hourTokens > CONFIG.MAX_TOKENS_PER_HOUR) {
95
+ budget.blockedUntil = Date.now() + 120000; // 2min cooldown
96
+ return `[TOKEN BUDGET] Agent ${agent} exceeded ${CONFIG.MAX_TOKENS_PER_HOUR} tokens/hour. Cooldown 2min.`;
97
+ }
98
+ // 4. Warning at 80% of per-minute limit
99
+ if (minuteTokens > CONFIG.MAX_TOKENS_PER_MINUTE * 0.8) {
100
+ const now = Date.now();
101
+ if (now - budget.lastWarning > 10000) { // Throttle warnings to once per 10s
102
+ budget.lastWarning = now;
103
+ process.stderr.write(`[TOKEN BUDGET WARNING] Agent ${agent} at ${Math.round(minuteTokens / CONFIG.MAX_TOKENS_PER_MINUTE * 100)}% of minute token budget.\n`);
104
+ }
105
+ }
106
+ return null;
107
+ }
108
+ /**
109
+ * Truncate file content to fit within token budget.
110
+ * Returns truncated content with a header note.
111
+ */
112
+ export function truncateFileContent(content, filePath, maxTokens = CONFIG.MAX_TOKENS_PER_CALL) {
113
+ const estimatedTokens = estimateTokens(content);
114
+ if (estimatedTokens <= maxTokens)
115
+ return content;
116
+ const lines = content.split("\n");
117
+ const maxLines = Math.min(CONFIG.MAX_FILE_LINES, Math.floor(maxTokens * CONFIG.CHARS_PER_TOKEN / 80));
118
+ const truncated = lines.slice(0, maxLines).join("\n");
119
+ const remaining = lines.length - maxLines;
120
+ return `[TRUNCATED] File "${filePath}" is too large (~${estimatedTokens} tokens). Showing first ${maxLines}/${lines.length} lines.\n\n${truncated}\n\n[... ${remaining} more lines truncated. Use grep_search for targeted queries.]`;
121
+ }
122
+ /**
123
+ * Get token budget stats for an agent.
124
+ */
125
+ export function getTokenBudgetStats(agent) {
126
+ const budget = agentBudgets.get(agent);
127
+ if (!budget) {
128
+ return { totalTokens: 0, recentMinute: 0, recentHour: 0, blocked: false, blockedRemaining: 0, callCount: 0 };
129
+ }
130
+ pruneOldRecords(budget);
131
+ return {
132
+ totalTokens: budget.totalTokens,
133
+ recentMinute: sumTokensInWindow(budget, 60000),
134
+ recentHour: sumTokensInWindow(budget, 3600000),
135
+ blocked: budget.blockedUntil !== null && Date.now() < budget.blockedUntil,
136
+ blockedRemaining: budget.blockedUntil ? Math.max(0, budget.blockedUntil - Date.now()) : 0,
137
+ callCount: budget.records.length,
138
+ };
139
+ }
140
+ /**
141
+ * Get all agents' token budget stats.
142
+ */
143
+ export function getAllTokenBudgetStats() {
144
+ const stats = {};
145
+ for (const [agent] of agentBudgets) {
146
+ stats[agent] = getTokenBudgetStats(agent);
147
+ }
148
+ return stats;
149
+ }
150
+ /**
151
+ * Reset all token budgets.
152
+ */
153
+ export function resetTokenBudgets() {
154
+ agentBudgets.clear();
155
+ }
156
+ export { CONFIG as TokenBudgetConfig };
157
+ //# sourceMappingURL=context-optimizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-optimizer.js","sourceRoot":"","sources":["../../../../framework-mcp/src/utils/context-optimizer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * ─── AI DISCIPLINE ENGINE ─────────────────────────────────────────
3
+ *
4
+ * Enforces strict rules on AI behavior at the MCP middleware layer.
5
+ * Unlike agent instructions (which AI can ignore), these are enforced
6
+ * at the tool level - AI cannot bypass them.
7
+ *
8
+ * Features:
9
+ * - Tool call rate limiting (prevents abuse)
10
+ * - File size limits (prevents reading/writing huge files)
11
+ * - Call frequency tracking (detects loops)
12
+ * - Tool blacklist per agent
13
+ * - Agent-based tool whitelist
14
+ * - Response content validation
15
+ * - Max concurrent operations
16
+ */
17
+ declare const CONFIG: {
18
+ MAX_CALLS_PER_MINUTE: number;
19
+ MAX_TOTAL_CALLS: number;
20
+ MAX_FILE_SIZE: number;
21
+ MAX_ARGS_SIZE: number;
22
+ COOLDOWN_MS: number;
23
+ MAX_RESPONSE_SIZE: number;
24
+ MAX_CONSECUTIVE_SAME_TOOL: number;
25
+ RESTRICTED_TOOLS: string[];
26
+ AGENT_TOOL_WHITELIST: Map<string, Set<string>>;
27
+ };
28
+ /**
29
+ * Enforce discipline on a tool call before execution.
30
+ * Returns error message if blocked, null if allowed.
31
+ */
32
+ export declare function enforceDiscipline(agent: string, toolName: string, args: Record<string, unknown>): Promise<string | null>;
33
+ /**
34
+ * Validate tool response content before returning to AI.
35
+ * Returns error message if blocked, null if allowed.
36
+ */
37
+ export declare function validateResponse(toolName: string, result: {
38
+ content: Array<{
39
+ type: string;
40
+ text: string;
41
+ }>;
42
+ }): string | null;
43
+ /**
44
+ * Get discipline stats for an agent.
45
+ */
46
+ export declare function getDisciplineStats(agent: string): {
47
+ totalCalls: number;
48
+ recentCalls: number;
49
+ inCooldown: boolean;
50
+ cooldownRemaining: number;
51
+ violations: number;
52
+ lastViolation: string | null;
53
+ };
54
+ /**
55
+ * Get all agents' discipline stats.
56
+ */
57
+ export declare function getAllDisciplineStats(): Record<string, {
58
+ totalCalls: number;
59
+ recentCalls: number;
60
+ inCooldown: boolean;
61
+ violations: number;
62
+ lastViolation: string | null;
63
+ }>;
64
+ /**
65
+ * Reset discipline for all agents.
66
+ */
67
+ export declare function resetDiscipline(): void;
68
+ export { CONFIG as DisciplineConfig };
@@ -0,0 +1,218 @@
1
+ /**
2
+ * ─── AI DISCIPLINE ENGINE ─────────────────────────────────────────
3
+ *
4
+ * Enforces strict rules on AI behavior at the MCP middleware layer.
5
+ * Unlike agent instructions (which AI can ignore), these are enforced
6
+ * at the tool level - AI cannot bypass them.
7
+ *
8
+ * Features:
9
+ * - Tool call rate limiting (prevents abuse)
10
+ * - File size limits (prevents reading/writing huge files)
11
+ * - Call frequency tracking (detects loops)
12
+ * - Tool blacklist per agent
13
+ * - Agent-based tool whitelist
14
+ * - Response content validation
15
+ * - Max concurrent operations
16
+ */
17
+ import fs from "fs";
18
+ import path from "path";
19
+ // Per-agent discipline tracking
20
+ const agentDiscipline = new Map();
21
+ // ─── Configuration (from env or defaults) ─────────────────────────
22
+ const CONFIG = {
23
+ MAX_CALLS_PER_MINUTE: parseInt(process.env.MCP_MAX_CALLS_PER_MINUTE || "60", 10),
24
+ MAX_TOTAL_CALLS: parseInt(process.env.MCP_MAX_TOTAL_CALLS || "500", 10),
25
+ MAX_FILE_SIZE: parseInt(process.env.MCP_MAX_FILE_SIZE || "1048576", 10),
26
+ MAX_ARGS_SIZE: parseInt(process.env.MCP_MAX_ARGS_SIZE || "102400", 10),
27
+ COOLDOWN_MS: parseInt(process.env.MCP_COOLDOWN_MS || "30000", 10),
28
+ MAX_RESPONSE_SIZE: parseInt(process.env.MCP_MAX_RESPONSE_SIZE || "512000", 10), // 500KB max response
29
+ MAX_CONSECUTIVE_SAME_TOOL: parseInt(process.env.MCP_MAX_CONSECUTIVE_SAME_TOOL || "10", 10),
30
+ RESTRICTED_TOOLS: (process.env.MCP_RESTRICTED_TOOLS || "")
31
+ .split(",").map(t => t.trim()).filter(Boolean),
32
+ // Agent-based tool whitelist (format: agent1:tool1,tool2;agent2:tool3,tool4)
33
+ AGENT_TOOL_WHITELIST: parseAgentWhitelist(process.env.MCP_AGENT_TOOL_WHITELIST || ""),
34
+ };
35
+ function parseAgentWhitelist(input) {
36
+ const map = new Map();
37
+ if (!input)
38
+ return map;
39
+ input.split(";").forEach(pair => {
40
+ const [agent, tools] = pair.split(":");
41
+ if (agent && tools) {
42
+ map.set(agent.trim(), new Set(tools.split(",").map(t => t.trim())));
43
+ }
44
+ });
45
+ return map;
46
+ }
47
+ const cooldowns = new Map();
48
+ function getOrCreateAgent(agent) {
49
+ if (!agentDiscipline.has(agent)) {
50
+ const whitelist = CONFIG.AGENT_TOOL_WHITELIST.get(agent) || null;
51
+ agentDiscipline.set(agent, {
52
+ totalCalls: 0,
53
+ calls: [],
54
+ lastReset: Date.now(),
55
+ blacklistedTools: new Set(),
56
+ whitelistedTools: whitelist,
57
+ violations: 0,
58
+ lastViolation: null,
59
+ });
60
+ }
61
+ return agentDiscipline.get(agent);
62
+ }
63
+ function pruneOldCalls(agent, windowMs = 60000) {
64
+ const cutoff = Date.now() - windowMs;
65
+ agent.calls = agent.calls.filter(c => c.timestamp > cutoff);
66
+ }
67
+ function isInCooldown(agent) {
68
+ const until = cooldowns.get(agent);
69
+ if (!until)
70
+ return false;
71
+ if (Date.now() > until) {
72
+ cooldowns.delete(agent);
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+ function recordViolation(agent, reason) {
78
+ const discipline = agentDiscipline.get(agent);
79
+ if (discipline) {
80
+ discipline.violations++;
81
+ discipline.lastViolation = reason;
82
+ }
83
+ }
84
+ /**
85
+ * Enforce discipline on a tool call before execution.
86
+ * Returns error message if blocked, null if allowed.
87
+ */
88
+ export async function enforceDiscipline(agent, toolName, args) {
89
+ const discipline = getOrCreateAgent(agent);
90
+ // 1. Check cooldown
91
+ if (isInCooldown(agent)) {
92
+ const until = cooldowns.get(agent);
93
+ const remaining = Math.ceil((until - Date.now()) / 1000);
94
+ return `[DISCIPLINE] Agent ${agent} is in cooldown for ${remaining}s. Too many requests.`;
95
+ }
96
+ // 2. Check restricted tools (global blacklist)
97
+ if (CONFIG.RESTRICTED_TOOLS.includes(toolName)) {
98
+ recordViolation(agent, `Attempted to use restricted tool: ${toolName}`);
99
+ return `[DISCIPLINE] Tool "${toolName}" is restricted. Agent ${agent} cannot use it.`;
100
+ }
101
+ // 3. Check agent-specific whitelist
102
+ if (discipline.whitelistedTools && !discipline.whitelistedTools.has(toolName)) {
103
+ recordViolation(agent, `Attempted to use non-whitelisted tool: ${toolName}`);
104
+ const allowed = Array.from(discipline.whitelistedTools).join(", ");
105
+ return `[DISCIPLINE] Agent ${agent} is not allowed to use "${toolName}". Allowed tools: ${allowed}`;
106
+ }
107
+ // 4. Check total call limit
108
+ if (discipline.totalCalls >= CONFIG.MAX_TOTAL_CALLS) {
109
+ cooldowns.set(agent, Date.now() + CONFIG.COOLDOWN_MS);
110
+ recordViolation(agent, `Exceeded max total calls (${CONFIG.MAX_TOTAL_CALLS})`);
111
+ return `[DISCIPLINE] Agent ${agent} exceeded max total calls (${CONFIG.MAX_TOTAL_CALLS}). Cooldown ${CONFIG.COOLDOWN_MS / 1000}s.`;
112
+ }
113
+ // 5. Check rate limit (calls per minute)
114
+ pruneOldCalls(discipline);
115
+ if (discipline.calls.length >= CONFIG.MAX_CALLS_PER_MINUTE) {
116
+ cooldowns.set(agent, Date.now() + CONFIG.COOLDOWN_MS);
117
+ recordViolation(agent, `Rate limit exceeded (${CONFIG.MAX_CALLS_PER_MINUTE}/min)`);
118
+ return `[DISCIPLINE] Agent ${agent} exceeded rate limit (${CONFIG.MAX_CALLS_PER_MINUTE}/min). Cooldown ${CONFIG.COOLDOWN_MS / 1000}s.`;
119
+ }
120
+ // 6. Check consecutive same tool (prevents loops)
121
+ if (discipline.calls.length >= CONFIG.MAX_CONSECUTIVE_SAME_TOOL) {
122
+ const lastCalls = discipline.calls.slice(-CONFIG.MAX_CONSECUTIVE_SAME_TOOL);
123
+ const allSame = lastCalls.every(c => c.tool === toolName);
124
+ if (allSame) {
125
+ cooldowns.set(agent, Date.now() + CONFIG.COOLDOWN_MS);
126
+ recordViolation(agent, `Consecutive same tool limit: ${toolName} x${CONFIG.MAX_CONSECUTIVE_SAME_TOOL}`);
127
+ return `[DISCIPLINE] Agent ${agent} called "${toolName}" ${CONFIG.MAX_CONSECUTIVE_SAME_TOOL} times in a row. Possible loop. Cooldown.`;
128
+ }
129
+ }
130
+ // 7. Check args size
131
+ const argsStr = JSON.stringify(args);
132
+ if (argsStr.length > CONFIG.MAX_ARGS_SIZE) {
133
+ recordViolation(agent, `Args too large: ${argsStr.length} bytes`);
134
+ return `[DISCIPLINE] Tool call args too large (${argsStr.length} bytes, max: ${CONFIG.MAX_ARGS_SIZE}).`;
135
+ }
136
+ // 8. Check file size for read/write operations
137
+ if ((toolName === "read_file" || toolName === "write_file") && args.path) {
138
+ try {
139
+ const projectRoot = process.env.ATABEY_PROJECT_ROOT || process.cwd();
140
+ const filePath = path.resolve(projectRoot, args.path);
141
+ if (fs.existsSync(filePath)) {
142
+ const stat = fs.statSync(filePath);
143
+ if (stat.size > CONFIG.MAX_FILE_SIZE) {
144
+ return `[DISCIPLINE] File too large (${(stat.size / 1024 / 1024).toFixed(1)}MB, max: ${(CONFIG.MAX_FILE_SIZE / 1024 / 1024).toFixed(1)}MB). Use grep_search instead.`;
145
+ }
146
+ }
147
+ }
148
+ catch { /* ignore */ }
149
+ }
150
+ // Record the call
151
+ discipline.totalCalls++;
152
+ discipline.calls.push({
153
+ tool: toolName,
154
+ timestamp: Date.now(),
155
+ argsSize: argsStr.length,
156
+ });
157
+ return null;
158
+ }
159
+ /**
160
+ * Validate tool response content before returning to AI.
161
+ * Returns error message if blocked, null if allowed.
162
+ */
163
+ export function validateResponse(toolName, result) {
164
+ if (!result || !result.content)
165
+ return null;
166
+ for (const block of result.content) {
167
+ if (block.type !== "text" || !block.text)
168
+ continue;
169
+ // Check response size
170
+ if (block.text.length > CONFIG.MAX_RESPONSE_SIZE) {
171
+ return `[DISCIPLINE] Response too large (${(block.text.length / 1024).toFixed(1)}KB, max: ${(CONFIG.MAX_RESPONSE_SIZE / 1024).toFixed(1)}KB).`;
172
+ }
173
+ // Block binary/gibberish content in text responses
174
+ const nonPrintable = (block.text.match(/[^\x20-\x7E\n\r\t]/g) || []).length;
175
+ if (nonPrintable > block.text.length * 0.3) {
176
+ return `[DISCIPLINE] Response contains too much binary data (${nonPrintable} non-printable chars). Blocked.`;
177
+ }
178
+ }
179
+ return null;
180
+ }
181
+ /**
182
+ * Get discipline stats for an agent.
183
+ */
184
+ export function getDisciplineStats(agent) {
185
+ const discipline = agentDiscipline.get(agent);
186
+ if (!discipline) {
187
+ return { totalCalls: 0, recentCalls: 0, inCooldown: false, cooldownRemaining: 0, violations: 0, lastViolation: null };
188
+ }
189
+ pruneOldCalls(discipline);
190
+ const cooldownUntil = cooldowns.get(agent);
191
+ return {
192
+ totalCalls: discipline.totalCalls,
193
+ recentCalls: discipline.calls.length,
194
+ inCooldown: isInCooldown(agent),
195
+ cooldownRemaining: cooldownUntil ? Math.max(0, cooldownUntil - Date.now()) : 0,
196
+ violations: discipline.violations,
197
+ lastViolation: discipline.lastViolation,
198
+ };
199
+ }
200
+ /**
201
+ * Get all agents' discipline stats.
202
+ */
203
+ export function getAllDisciplineStats() {
204
+ const stats = {};
205
+ for (const [agent] of agentDiscipline) {
206
+ stats[agent] = getDisciplineStats(agent);
207
+ }
208
+ return stats;
209
+ }
210
+ /**
211
+ * Reset discipline for all agents.
212
+ */
213
+ export function resetDiscipline() {
214
+ agentDiscipline.clear();
215
+ cooldowns.clear();
216
+ }
217
+ export { CONFIG as DisciplineConfig };
218
+ //# sourceMappingURL=discipline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discipline.js","sourceRoot":"","sources":["../../../../framework-mcp/src/utils/discipline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * ─── FINOPS / BUDGET ENFORCEMENT ──────────────────────────────────
3
+ *
4
+ * Enterprise budget management for AI token consumption.
5
+ * Enforces strict cost limits per team, agent, or project.
6
+ *
7
+ * Features:
8
+ * - Team-based budget allocation (monthly/quarterly)
9
+ * - Per-agent spending limits
10
+ * - Automatic shutdown when budget exceeded
11
+ * - Central server sync for budget policies
12
+ * - Real-time cost tracking
13
+ * - Budget alerts at configurable thresholds (50%, 80%, 90%, 100%)
14
+ *
15
+ * Architecture:
16
+ * [Local MCP] → Budget Check → [Enterprise Server] → Shutdown Signal
17
+ *
18
+ * Environment Variables:
19
+ * ATABEY_BUDGET_TEAM - Team name for budget grouping
20
+ * ATABEY_BUDGET_MONTHLY - Monthly budget in USD (local override)
21
+ * ATABEY_BUDGET_AGENT_MAX - Max spend per agent in USD
22
+ * ATABEY_BUDGET_SYNC_URL - Enterprise server URL for budget sync
23
+ */
24
+ declare const CONFIG: {
25
+ /** Team name for budget grouping */
26
+ TEAM: string;
27
+ /** Monthly budget in USD (0 = unlimited) */
28
+ MONTHLY_BUDGET: number;
29
+ /** Max spend per agent in USD (0 = unlimited) */
30
+ AGENT_MAX_BUDGET: number;
31
+ /** Enterprise server URL for budget policy sync */
32
+ SYNC_URL: string;
33
+ /** Sync token */
34
+ SYNC_TOKEN: string;
35
+ /** Budget alert thresholds (percentages) */
36
+ ALERT_THRESHOLDS: number[];
37
+ /** Cost per 1K tokens (USD) – default: $0.003 for Claude */
38
+ COST_PER_1K_TOKENS: number;
39
+ /** Sync interval in ms */
40
+ SYNC_INTERVAL_MS: number;
41
+ /** Enable/disable budget enforcement */
42
+ ENABLED: boolean;
43
+ };
44
+ export interface BudgetState {
45
+ team: string;
46
+ /** Total spend this month in USD */
47
+ monthlySpend: number;
48
+ /** Per-agent spend this month */
49
+ agentSpend: Record<string, number>;
50
+ /** Budget period start (ISO date) */
51
+ periodStart: string;
52
+ /** Budget period end (ISO date) */
53
+ periodEnd: string;
54
+ /** Whether this team/agent is blocked */
55
+ blocked: boolean;
56
+ /** Block reason if blocked */
57
+ blockReason: string | null;
58
+ /** Last alert thresholds triggered */
59
+ triggeredAlerts: number[];
60
+ /** Last sync timestamp */
61
+ lastSync: string | null;
62
+ }
63
+ interface BudgetPolicy {
64
+ team: string;
65
+ monthlyBudget: number;
66
+ agentMaxBudget: number;
67
+ blocked: boolean;
68
+ blockReason: string | null;
69
+ updatedAt: string;
70
+ }
71
+ export declare class BudgetManager {
72
+ private static instance;
73
+ private state;
74
+ private syncTimer;
75
+ private localMetricsPath;
76
+ private constructor();
77
+ static getInstance(): BudgetManager;
78
+ /**
79
+ * Start the budget manager.
80
+ * Begins periodic sync with enterprise server.
81
+ */
82
+ start(): void;
83
+ /**
84
+ * Stop the budget manager.
85
+ */
86
+ stop(): void;
87
+ /**
88
+ * Record token usage and check budget.
89
+ * Returns error message if budget exceeded, null if allowed.
90
+ */
91
+ recordUsage(agent: string, tokens: number): string | null;
92
+ /**
93
+ * Check if an agent is within budget without recording usage.
94
+ */
95
+ checkBudget(agent: string): {
96
+ allowed: boolean;
97
+ monthlySpend: number;
98
+ monthlyBudget: number;
99
+ agentSpend: number;
100
+ agentMaxBudget: number;
101
+ usagePercent: number;
102
+ blocked: boolean;
103
+ blockReason: string | null;
104
+ };
105
+ /**
106
+ * Get full budget state.
107
+ */
108
+ getState(): BudgetState;
109
+ /**
110
+ * Reset budget for new period.
111
+ */
112
+ resetPeriod(): void;
113
+ /**
114
+ * Apply a budget policy from the enterprise server.
115
+ */
116
+ applyPolicy(policy: BudgetPolicy): void;
117
+ /**
118
+ * Sync budget state with enterprise server.
119
+ */
120
+ private syncWithServer;
121
+ /**
122
+ * Recalculate spend from local metrics file.
123
+ */
124
+ private recalculateFromLocalMetrics;
125
+ /**
126
+ * Trigger a budget alert.
127
+ */
128
+ private triggerAlert;
129
+ /**
130
+ * Save budget state to disk.
131
+ */
132
+ private saveState;
133
+ /**
134
+ * Reset the singleton instance (for testing).
135
+ */
136
+ static resetInstance(): void;
137
+ /**
138
+ * Load budget state from disk.
139
+ */
140
+ private loadState;
141
+ }
142
+ export declare const budgetManager: BudgetManager;
143
+ export { CONFIG as FinOpsConfig };