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,55 @@
1
+ import { classifyData, containsPII, maskObject, maskText } from "../../../../src/shared/pii.js";
2
+ export function handleMaskPII(root, args) {
3
+ const mode = args.mode || "auto";
4
+ const strictMode = args.strictMode ?? false;
5
+ // Mode: text
6
+ if (mode === "text" || (mode === "auto" && args.text && !args.data)) {
7
+ if (!args.text) {
8
+ return {
9
+ isError: true,
10
+ content: [{ type: "text", text: "[ERROR] 'text' parameter is required when mode is 'text'." }],
11
+ };
12
+ }
13
+ const masked = maskText(args.text);
14
+ const hasPII = containsPII(args.text);
15
+ const classification = classifyData(args.text);
16
+ return {
17
+ content: [{
18
+ type: "text",
19
+ text: JSON.stringify({
20
+ originalLength: args.text.length,
21
+ maskedLength: masked.length,
22
+ hasPII,
23
+ classification,
24
+ masked,
25
+ }, null, 2),
26
+ }],
27
+ };
28
+ }
29
+ // Mode: object
30
+ if (mode === "object" || (mode === "auto" && args.data)) {
31
+ if (!args.data) {
32
+ return {
33
+ isError: true,
34
+ content: [{ type: "text", text: "[ERROR] 'data' parameter is required when mode is 'object'." }],
35
+ };
36
+ }
37
+ const masked = maskObject(args.data, 0, strictMode);
38
+ const hasPII = containsPII(JSON.stringify(args.data));
39
+ const classification = classifyData(JSON.stringify(args.data));
40
+ return {
41
+ content: [{
42
+ type: "text",
43
+ text: JSON.stringify({
44
+ hasPII,
45
+ classification,
46
+ masked,
47
+ }, null, 2),
48
+ }],
49
+ };
50
+ }
51
+ return {
52
+ isError: true,
53
+ content: [{ type: "text", text: "[ERROR] Provide either 'text' (string) or 'data' (object) parameter." }],
54
+ };
55
+ }
@@ -172,6 +172,12 @@ export const TOOLS = [
172
172
  description: "Pause execution and ask the human developer a clarifying question via the terminal.",
173
173
  inputSchema: zodToMcpSchema(schemas.AskHumanSchema),
174
174
  },
175
+ // ─── PII / Compliance ─────────────────────────────────────────
176
+ {
177
+ name: "mask_pii",
178
+ description: "Mask Personally Identifiable Information (PII) in text or structured data. Compliant with KVKK (Law No. 6698) and GDPR. Detects and masks emails, phone numbers, TC IDs, API keys, tokens, IPs, credit cards, IBANs, and more.",
179
+ inputSchema: zodToMcpSchema(schemas.MaskPIISchema),
180
+ },
175
181
  // ─── Code Quality ─────────────────────────────────────────────
176
182
  {
177
183
  name: "analyze_code_quality",
@@ -183,15 +189,10 @@ export const TOOLS = [
183
189
  description: "Check architecture compliance in a given path. Verifies layer boundaries (Controller→Service→Repository), import direction rules, and strict mode.",
184
190
  inputSchema: zodToMcpSchema(schemas.CheckArchitectureComplianceSchema),
185
191
  },
186
- // ─── LLM Gateway ─────────────────────────────────────────
187
- {
188
- name: "llm_gateway_query",
189
- description: "Send a chat completion request through the ATABEY LLM Gateway. The gateway automatically load-balances across providers (OpenAI, Anthropic, Google, Grok, Ollama) using configurable strategies (failover, round-robin, cost-optimized). Allows any MCP-connected AI to route LLM requests through the gateway.",
190
- inputSchema: zodToMcpSchema(schemas.LLMGatewayQuerySchema),
191
- },
192
+ // ─── Human-in-the-Loop ────────────────────────────────────────
192
193
  {
193
- name: "llm_gateway_status",
194
- description: "Get the current status of the LLM Gateway including provider health, load balancing strategy, usage statistics, and budget information.",
195
- inputSchema: zodToMcpSchema(schemas.LLMGatewayStatusSchema),
194
+ name: "approve_operation",
195
+ description: "Approve, reject, or list pending risk-gated operations. Use this when an operation was blocked by the Risk Gate (risk score ≥ 60). Action: 'approve' | 'reject' | 'list'.",
196
+ inputSchema: zodToMcpSchema(schemas.ApproveOperationSchema),
196
197
  },
197
198
  ];
@@ -1,11 +1,36 @@
1
1
  import { execSync } from "child_process";
2
2
  import { getBackendLanguage, getDefaultTestCommand } from "../../utils/cli.js";
3
+ const TEST_COMMAND_ALLOW_LIST = [
4
+ "npm test",
5
+ "npm run test",
6
+ "npx vitest",
7
+ "pytest",
8
+ "go test",
9
+ "dotnet test",
10
+ "mvn test",
11
+ "./gradlew test",
12
+ "cargo test"
13
+ ];
3
14
  /**
4
15
  * Executes project tests and returns results for agent analysis.
5
16
  */
6
17
  export function handleRunTests(projectRoot, args) {
7
18
  const language = getBackendLanguage(projectRoot);
8
19
  const testCommand = args.command || getDefaultTestCommand(language);
20
+ // Validate command to prevent shell injection / chaining
21
+ const isAllowed = TEST_COMMAND_ALLOW_LIST.some(allowedCmd => testCommand.startsWith(allowedCmd));
22
+ if (!isAllowed) {
23
+ return {
24
+ isError: true,
25
+ content: [{ type: "text", text: `[ERROR] Test command not allowed: "${testCommand}". Must start with one of: ${TEST_COMMAND_ALLOW_LIST.join(", ")}` }]
26
+ };
27
+ }
28
+ if (/[;&|><$`\n\r]/.test(testCommand)) {
29
+ return {
30
+ isError: true,
31
+ content: [{ type: "text", text: "[ERROR] Test command rejected: Shell metacharacters are forbidden to prevent command injection." }]
32
+ };
33
+ }
9
34
  try {
10
35
  const output = execSync(testCommand, { cwd: projectRoot, encoding: "utf8", stdio: "pipe" });
11
36
  return {
@@ -1,3 +1,4 @@
1
+ import { handleMaskPII } from "./compliance/mask_pii.js";
1
2
  import { handleAcquireLock, handleReleaseLock } from "./control_plane/locking.js";
2
3
  import { handleRegisterAgent } from "./control_plane/registry.js";
3
4
  import { TOOLS } from "./definitions.js";
@@ -13,14 +14,13 @@ import { handleRunTests } from "./framework/run_tests.js";
13
14
  import { handleSubmitPlan } from "./framework/submit_plan.js";
14
15
  import { handleUpdateContractHash } from "./framework/update_contract_hash.js";
15
16
  import { handleUpdateProjectMemory } from "./framework/update_memory.js";
16
- import { handleLLMGatewayQuery } from "./gateway/llm_gateway_query.js";
17
- import { handleLLMGatewayStatus } from "./gateway/llm_gateway_status.js";
18
17
  import { handleDeleteKnowledge } from "./memory/delete_knowledge.js";
19
18
  import { handleGetMemoryInsights } from "./memory/get_insights.js";
20
19
  import { handleReadProjectMemory } from "./memory/read_memory.js";
21
20
  import { handleSearchKnowledge } from "./memory/search_knowledge.js";
22
21
  import { handleStoreKnowledge } from "./memory/store_knowledge.js";
23
22
  import { handleAskHuman } from "./messaging/ask_human.js";
23
+ import { handleApproveOperation } from "./messaging/approve_operation.js";
24
24
  import { handleLogAgentAction } from "./messaging/log_action.js";
25
25
  import { handleSendAgentMessage } from "./messaging/send_message.js";
26
26
  import { handleCheckPorts } from "./observability/check_ports.js";
@@ -65,6 +65,7 @@ export const toolHandlers = {
65
65
  send_agent_message: bind(handleSendAgentMessage),
66
66
  log_agent_action: bind(handleLogAgentAction),
67
67
  ask_human: bind(handleAskHuman),
68
+ approve_operation: bind(handleApproveOperation),
68
69
  update_contract_hash: bind(handleUpdateContractHash),
69
70
  acquire_lock: bind(handleAcquireLock),
70
71
  release_lock: bind(handleReleaseLock),
@@ -73,9 +74,7 @@ export const toolHandlers = {
73
74
  check_lint: bind(handleCheckLint),
74
75
  analyze_code_quality: bind(handleAnalyzeCodeQuality),
75
76
  check_architecture_compliance: bind(handleCheckArchitectureCompliance),
76
- // LLM Gateway
77
- llm_gateway_query: bind(handleLLMGatewayQuery),
78
- llm_gateway_status: bind(handleLLMGatewayStatus),
77
+ mask_pii: bind(handleMaskPII),
79
78
  };
80
79
  // Map of tool names to their Zod validation schemas
81
80
  export const toolSchemas = {
@@ -116,11 +115,11 @@ export const toolSchemas = {
116
115
  send_agent_message: schemas.SendAgentMessageSchema,
117
116
  log_agent_action: schemas.LogAgentActionSchema,
118
117
  ask_human: schemas.AskHumanSchema,
118
+ approve_operation: schemas.ApproveOperationSchema,
119
119
  // Code Quality
120
120
  analyze_code_quality: schemas.AnalyzeCodeQualitySchema,
121
121
  check_architecture_compliance: schemas.CheckArchitectureComplianceSchema,
122
- // LLM Gateway
123
- llm_gateway_query: schemas.LLMGatewayQuerySchema,
124
- llm_gateway_status: schemas.LLMGatewayStatusSchema,
122
+ // PII / Compliance
123
+ mask_pii: schemas.MaskPIISchema,
125
124
  };
126
125
  export { TOOLS };
@@ -0,0 +1,80 @@
1
+ import { approveOperation, getPendingApprovals, rejectOperation } from "../../utils/human-in-loop.js";
2
+ /**
3
+ * MCP Tool: approve_operation
4
+ *
5
+ * In AI CLI (Claude Code, Gemini CLI), running "atabey approve <traceId>"
6
+ * is not possible — anything typed in chat is treated as a message, not a CLI command.
7
+ *
8
+ * This tool moves the risk gate approval flow directly into an MCP tool call:
9
+ *
10
+ * 1. Atabey blocks a high-risk operation
11
+ * 2. Tells the developer: "call the approve_operation tool"
12
+ * 3. AI calls this tool → operation is approved/rejected
13
+ *
14
+ * Developer never has to switch to terminal.
15
+ */
16
+ export async function handleApproveOperation(_root, args) {
17
+ const { action, traceId, reason } = args;
18
+ // LIST: Show pending approvals
19
+ if (action === "list") {
20
+ const pending = getPendingApprovals();
21
+ if (pending.length === 0) {
22
+ return {
23
+ content: [{ type: "text", text: "[APPROVALS] No pending operations waiting for approval." }],
24
+ };
25
+ }
26
+ const lines = [
27
+ `[APPROVALS] ${pending.length} pending operation(s):\n`,
28
+ ...pending.map(req => [
29
+ " ─────────────────────────────────────",
30
+ ` Trace ID: ${req.traceId}`,
31
+ ` Tool: ${req.toolName}`,
32
+ ` Agent: ${req.agent}`,
33
+ ` Risk Score: ${req.riskScore}/100 (${req.riskLevel})`,
34
+ ` Reason: ${req.reason}`,
35
+ ` Expires: ${new Date(req.expiresAt).toISOString()}`,
36
+ ].join("\n")),
37
+ "",
38
+ "To approve: call approve_operation with action=\"approve\" and traceId=\"<id>\"",
39
+ "To reject: call approve_operation with action=\"reject\" and traceId=\"<id>\"",
40
+ ];
41
+ return {
42
+ content: [{ type: "text", text: lines.join("\n") }],
43
+ };
44
+ }
45
+ // APPROVE or REJECT: traceId is required
46
+ if (!traceId) {
47
+ return {
48
+ isError: true,
49
+ content: [{ type: "text", text: `[ERROR] traceId is required for "${action}" action.` }],
50
+ };
51
+ }
52
+ if (action === "approve") {
53
+ const result = approveOperation(traceId);
54
+ return {
55
+ content: [{
56
+ type: "text",
57
+ text: result.success
58
+ ? `[APPROVED] ✅ ${result.message}\nYou may retry the blocked operation now.`
59
+ : `[ERROR] ${result.message}`,
60
+ }],
61
+ isError: !result.success,
62
+ };
63
+ }
64
+ if (action === "reject") {
65
+ const result = rejectOperation(traceId);
66
+ return {
67
+ content: [{
68
+ type: "text",
69
+ text: result.success
70
+ ? `[REJECTED] ⛔ ${result.message}${reason ? `\nReason: ${reason}` : ""}`
71
+ : `[ERROR] ${result.message}`,
72
+ }],
73
+ isError: !result.success,
74
+ };
75
+ }
76
+ return {
77
+ isError: true,
78
+ content: [{ type: "text", text: `[ERROR] Unknown action: "${String(action)}". Use "approve", "reject", or "list".` }],
79
+ };
80
+ }
@@ -1,30 +1,99 @@
1
- import chalk from "chalk";
1
+ import fs from "fs";
2
+ import path from "path";
3
+ /**
4
+ * ─── ASK HUMAN — File Bridge ─────────────────────────────────────────
5
+ *
6
+ * AI CLIs (Claude Code, Gemini CLI) start the MCP server as a stdio subprocess.
7
+ * In this subprocess, stdin is isTTY=false (used for MCP JSON-RPC).
8
+ *
9
+ * Solution: File-based Q&A bridge.
10
+ * 1. Question → written to .atabey/hitl/question.txt
11
+ * 2. Developer answers via `atabey hitl` command
12
+ * 3. Answer → written to .atabey/hitl/answer.txt
13
+ * 4. This handler reads the answer and returns it to the AI
14
+ *
15
+ * Dashboard: Can also be answered via /api/approvals endpoint on the web dashboard.
16
+ */
2
17
  export async function handleAskHuman(root, args) {
3
- if (process.env.ATABEY_TEST_DIR || !process.stdin.isTTY) {
4
- return { content: [{ type: "text", text: "[SKIPPED] Non-interactive environment. Cannot ask human." }] };
5
- }
18
+ const timeoutSeconds = args.timeoutSeconds ?? 120;
19
+ const hitlDir = path.join(root, ".atabey", "hitl");
20
+ const questionFile = path.join(hitlDir, "question.txt");
21
+ const answerFile = path.join(hitlDir, "answer.txt");
6
22
  try {
7
- const readline = await import("readline");
8
- const rl = readline.createInterface({
9
- input: process.stdin,
10
- output: process.stdout
11
- });
12
- return new Promise((resolve) => {
13
- process.stdout.write("\n" + chalk.bgMagenta.white.bold(" [HUMAN-IN-THE-LOOP REQUIRED] ") + "\n");
14
- process.stdout.write(chalk.magenta("An agent has paused execution to ask you a question:\n"));
15
- rl.question(`\n${chalk.bold(args.question)}\n${chalk.gray("> ")}`, (answer) => {
16
- rl.close();
17
- resolve({
18
- content: [{ type: "text", text: `[HUMAN RESPONSE] ${answer}` }]
19
- });
20
- });
21
- });
23
+ // Ensure hitl directory exists
24
+ fs.mkdirSync(hitlDir, { recursive: true });
25
+ // Clear any stale answer file
26
+ if (fs.existsSync(answerFile)) {
27
+ fs.unlinkSync(answerFile);
28
+ }
29
+ // Write the question with metadata
30
+ const questionPayload = JSON.stringify({
31
+ timestamp: new Date().toISOString(),
32
+ question: args.question,
33
+ timeoutAt: new Date(Date.now() + timeoutSeconds * 1000).toISOString(),
34
+ }, null, 2);
35
+ fs.writeFileSync(questionFile, questionPayload);
36
+ // Write human-readable prompt file alongside
37
+ fs.writeFileSync(path.join(hitlDir, "PENDING.txt"), [
38
+ "═══════════════════════════════════════════════════",
39
+ " [ATABEY] AGENT WAITING FOR YOUR ANSWER",
40
+ "═══════════════════════════════════════════════════",
41
+ "",
42
+ `QUESTION: ${args.question}`,
43
+ "",
44
+ "To answer, run in your terminal:",
45
+ " atabey hitl answer \"your answer here\"",
46
+ "",
47
+ "Or use the dashboard: http://localhost:5858",
48
+ "═══════════════════════════════════════════════════",
49
+ ].join("\n"));
50
+ process.stderr.write(`[HITL] Question written to ${questionFile}\n`);
51
+ process.stderr.write("[HITL] Run: atabey hitl answer \"your answer\"\n");
52
+ // Poll for answer file
53
+ const pollIntervalMs = 1000;
54
+ const maxAttempts = timeoutSeconds;
55
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
56
+ await new Promise(resolve => setTimeout(resolve, pollIntervalMs));
57
+ if (fs.existsSync(answerFile)) {
58
+ const answer = fs.readFileSync(answerFile, "utf8").trim();
59
+ // Clean up
60
+ try {
61
+ fs.unlinkSync(questionFile);
62
+ fs.unlinkSync(answerFile);
63
+ const pendingFile = path.join(hitlDir, "PENDING.txt");
64
+ if (fs.existsSync(pendingFile))
65
+ fs.unlinkSync(pendingFile);
66
+ }
67
+ catch { /* cleanup is best-effort */ }
68
+ process.stderr.write("[HITL] Answer received.\n");
69
+ return {
70
+ content: [{ type: "text", text: `[HUMAN RESPONSE] ${answer}` }],
71
+ };
72
+ }
73
+ }
74
+ // Timeout — clean up question file
75
+ try {
76
+ if (fs.existsSync(questionFile))
77
+ fs.unlinkSync(questionFile);
78
+ const pendingFile = path.join(hitlDir, "PENDING.txt");
79
+ if (fs.existsSync(pendingFile))
80
+ fs.unlinkSync(pendingFile);
81
+ }
82
+ catch { /* cleanup is best-effort */ }
83
+ return {
84
+ content: [{
85
+ type: "text",
86
+ text: `[HITL TIMEOUT] No answer received within ${timeoutSeconds}s.\n` +
87
+ `Question was: "${args.question}"\n` +
88
+ "To answer pending questions, run: atabey hitl answer \"your answer\"",
89
+ }],
90
+ };
22
91
  }
23
92
  catch (error) {
24
93
  const message = error instanceof Error ? error.message : String(error);
25
94
  return {
26
95
  isError: true,
27
- content: [{ type: "text", text: `[ERROR] Failed to ask human: ${message}` }]
96
+ content: [{ type: "text", text: `[ERROR] ask_human failed: ${message}` }],
28
97
  };
29
98
  }
30
99
  }
@@ -1,16 +1,32 @@
1
- import { execSync } from "child_process";
1
+ import { spawnSync } from "child_process";
2
2
  /**
3
3
  * Checks for active network ports and their status.
4
+ * Uses spawnSync instead of execSync to prevent shell injection.
4
5
  */
5
6
  export function handleCheckPorts(projectRoot, args) {
6
- const filter = args.filter || ""; // Optional filter (e.g., ":3000")
7
+ const rawFilter = args.filter || "";
8
+ // Sanitize filter to prevent command injection (allow only alphanumeric, dots, colons, dashes, underscores)
9
+ const filter = rawFilter.replace(/[^a-zA-Z0-9.:_-]/g, "");
7
10
  try {
8
- // Using 'lsof -i -P -n' to list open files and network connections
9
- // Note: may require permissions or behave differently on non-Unix systems
10
- const command = process.platform === "win32"
11
- ? `netstat -ano | findstr LISTENING ${filter ? `| findstr ${filter}` : ""}`
12
- : `lsof -i -P -n | grep LISTEN ${filter ? `| grep ${filter}` : ""}`;
13
- const output = execSync(command, { encoding: "utf8" });
11
+ let output;
12
+ if (process.platform === "win32") {
13
+ const result = spawnSync("netstat", ["-ano"], { encoding: "utf8" });
14
+ if (result.error)
15
+ throw result.error;
16
+ const lines = (result.stdout || "").split("\n").filter(l => l.includes("LISTENING"));
17
+ output = filter
18
+ ? lines.filter(l => l.includes(filter)).join("\n")
19
+ : lines.join("\n");
20
+ }
21
+ else {
22
+ const result = spawnSync("lsof", ["-i", "-P", "-n"], { encoding: "utf8" });
23
+ if (result.error)
24
+ throw result.error;
25
+ const lines = (result.stdout || "").split("\n").filter(l => l.includes("LISTEN"));
26
+ output = filter
27
+ ? lines.filter(l => l.includes(filter)).join("\n")
28
+ : lines.join("\n");
29
+ }
14
30
  return {
15
31
  content: [{
16
32
  type: "text",
@@ -1,6 +1,7 @@
1
1
  import { execSync } from "child_process";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
+ import { analyzePathQuality } from "../../utils/quality.js";
4
5
  /**
5
6
  * Code quality analysis tool for Atabey MCP.
6
7
  *
@@ -10,6 +11,13 @@ import path from "path";
10
11
  * - Code complexity analysis (checkComplexity)
11
12
  */
12
13
  export function handleAnalyzeCodeQuality(projectRoot, args) {
14
+ // Validate path parameter to prevent command injection
15
+ if (!/^[a-zA-Z0-9_./-]+$/.test(args.path)) {
16
+ return {
17
+ isError: true,
18
+ content: [{ type: "text", text: `[ERROR] Invalid path characters detected: ${args.path}` }]
19
+ };
20
+ }
13
21
  const targetPath = path.resolve(projectRoot, args.path);
14
22
  if (!fs.existsSync(targetPath)) {
15
23
  return {
@@ -81,73 +89,14 @@ export function handleAnalyzeCodeQuality(projectRoot, args) {
81
89
  }
82
90
  // 3. Code Complexity Check (basic heuristic)
83
91
  if (args.checkComplexity !== false) {
84
- const complexityIssues = [];
85
- function scanDirectory(dir) {
86
- if (!fs.existsSync(dir))
87
- return;
88
- const entries = fs.readdirSync(dir, { withFileTypes: true });
89
- for (const entry of entries) {
90
- const fullPath = path.join(dir, entry.name);
91
- if (entry.isDirectory() && !entry.name.startsWith("node_modules") && !entry.name.startsWith(".")) {
92
- scanDirectory(fullPath);
93
- }
94
- else if (entry.isFile() && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"))) {
95
- try {
96
- const content = fs.readFileSync(fullPath, "utf8");
97
- const lines = content.split("\n");
98
- // Check for long functions (>50 lines)
99
- let inFunction = false;
100
- let funcLines = 0;
101
- let funcName = "";
102
- const relativePath = path.relative(projectRoot, fullPath);
103
- for (let i = 0; i < lines.length; i++) {
104
- const line = lines[i];
105
- // Detect function start
106
- const funcMatch = line.match(/(?:public|private|protected|static\s+)?(?:async\s+)?(?:function\s+)?(\w+)\s*\([^)]*\)\s*{/);
107
- if (funcMatch) {
108
- inFunction = true;
109
- funcLines = 1;
110
- funcName = funcMatch[1];
111
- continue;
112
- }
113
- // Detect method in class
114
- const methodMatch = line.match(/^\s*(?:public|private|protected|static\s+)?(\w+)\s*\([^)]*\)\s*{/);
115
- if (methodMatch && !line.includes("function")) {
116
- inFunction = true;
117
- funcLines = 1;
118
- funcName = methodMatch[1];
119
- continue;
120
- }
121
- if (inFunction) {
122
- if (line.includes("}")) {
123
- if (funcLines > 50) {
124
- complexityIssues.push(`- ${relativePath}:${i + 1} — Function \`${funcName}\` is ${funcLines} lines long (max: 50)`);
125
- }
126
- inFunction = false;
127
- }
128
- funcLines++;
129
- }
130
- // Check nesting depth (>4 levels)
131
- const indentMatch = line.match(/^(?:\s{2}){5,}/);
132
- if (indentMatch && !line.trim().startsWith("//") && !line.trim().startsWith("*")) {
133
- const depth = Math.floor(indentMatch[0].length / 2);
134
- if (depth > 4) {
135
- complexityIssues.push(`- ${relativePath}:${i + 1} — Nesting depth ${depth} (max: 4)`);
136
- }
137
- }
138
- }
139
- }
140
- catch {
141
- // Skip files that can't be read
142
- }
143
- }
144
- }
145
- }
146
- scanDirectory(targetPath);
92
+ const qualityResult = analyzePathQuality(projectRoot, args.path);
93
+ const complexityIssues = qualityResult.issues.filter(issue => issue.type === "complexity");
147
94
  if (complexityIssues.length > 0) {
148
95
  hasErrors = true;
149
96
  results.push(`## ⚠️ Code Complexity Issues (${complexityIssues.length})`);
150
- results.push(...complexityIssues);
97
+ complexityIssues.forEach(issue => {
98
+ results.push(`- ${issue.file}:${issue.line} — ${issue.message}`);
99
+ });
151
100
  }
152
101
  else {
153
102
  results.push("## ✅ Code Complexity: OK");
@@ -34,7 +34,7 @@ export const ReplaceTextSchema = z.object({
34
34
  path: z.string().min(1, "Path is required"),
35
35
  oldText: z.string().min(1, "oldText is required"),
36
36
  newText: z.string(),
37
- allowMultiple: z.boolean().default(false),
37
+ allowMultiple: z.boolean().optional().default(false),
38
38
  }).strict();
39
39
  // ─── Search & Exploration
40
40
  export const ListDirSchema = z.object({
@@ -58,7 +58,7 @@ export const BatchSurgicalEditSchema = z.object({
58
58
  path: z.string().min(1),
59
59
  oldText: z.string().min(1),
60
60
  newText: z.string(),
61
- allowMultiple: z.boolean().default(false),
61
+ allowMultiple: z.boolean().optional().default(false),
62
62
  })),
63
63
  }).strict();
64
64
  export const PatchFileSchema = z.object({
@@ -97,7 +97,7 @@ export const SubmitPlanSchema = z.object({
97
97
  export const AcquireLockSchema = z.object({
98
98
  resource: z.string().min(1),
99
99
  agent: AgentIDSchema,
100
- ttl: z.number().int().positive().default(60),
100
+ ttl: z.number().int().positive().optional().default(60),
101
101
  }).strict();
102
102
  export const ReleaseLockSchema = z.object({
103
103
  resource: z.string().min(1),
@@ -106,7 +106,7 @@ export const ReleaseLockSchema = z.object({
106
106
  export const RegisterAgentSchema = z.object({
107
107
  agent: AgentIDSchema,
108
108
  role: z.string().min(1),
109
- capability: z.number().int().min(1).max(10).default(5),
109
+ capability: z.number().int().min(1).max(10).optional().default(5),
110
110
  specialties: z.record(z.number()).optional(),
111
111
  }).strict();
112
112
  export const UpdateContractHashSchema = z.object({}).strict();
@@ -123,7 +123,7 @@ export const StoreKnowledgeSchema = z.object({
123
123
  export const SearchKnowledgeSchema = z.object({
124
124
  query: z.string().min(1, "Query is required"),
125
125
  category: z.enum(["ARCHITECTURE", "DECISION", "CODE_SNIPPET", "RULE", "TASK_HISTORY"]).optional(),
126
- limit: z.number().int().positive().default(5),
126
+ limit: z.number().int().positive().optional().default(5),
127
127
  }).strict();
128
128
  export const DeleteKnowledgeSchema = z.object({
129
129
  id: z.string().optional(),
@@ -137,8 +137,8 @@ export const SendAgentMessageSchema = z.object({
137
137
  content: z.string().min(1, "Content cannot be empty"),
138
138
  traceId: TraceIDSchema,
139
139
  parentId: TaskIDSchema.optional(),
140
- priority: z.enum(["HIGH", "NORMAL", "LOW"]).default("NORMAL"),
141
- requiresApproval: z.boolean().default(false),
140
+ priority: z.enum(["HIGH", "NORMAL", "LOW"]).optional().default("NORMAL"),
141
+ requiresApproval: z.boolean().optional().default(false),
142
142
  }).strict();
143
143
  export const LogAgentActionSchema = z.object({
144
144
  agent: AgentIDSchema,
@@ -150,23 +150,12 @@ export const LogAgentActionSchema = z.object({
150
150
  }).strict();
151
151
  export const AskHumanSchema = z.object({
152
152
  question: z.string().min(10, "Question must be clear and detailed."),
153
+ timeoutSeconds: z.number().int().positive().optional().default(120),
153
154
  }).strict();
154
- // ─── LLM Gateway ────────────────────────────────────────────────────
155
- export const LLMGatewayQuerySchema = z.object({
156
- messages: z.array(z.object({
157
- role: z.enum(["system", "user", "assistant", "tool"]),
158
- content: z.string().min(1),
159
- })).min(1, "At least one message is required"),
160
- system: z.string().optional(),
161
- model: z.string().optional(),
162
- provider: z.enum(["openai", "anthropic", "google", "grok", "ollama"]).optional(),
163
- strategy: z.enum(["round-robin", "least-latency", "cost-optimized", "failover", "priority-based", "model-based"]).optional(),
164
- temperature: z.number().min(0).max(2).optional(),
165
- maxTokens: z.number().int().positive().optional(),
155
+ export const ApproveOperationSchema = z.object({
156
+ action: z.enum(["approve", "reject", "list"]),
166
157
  traceId: z.string().optional(),
167
- }).strict();
168
- export const LLMGatewayStatusSchema = z.object({
169
- detail: z.enum(["overview", "providers", "stats"]).optional().default("overview"),
158
+ reason: z.string().optional(),
170
159
  }).strict();
171
160
  // ─── Code Quality Analysis ──────────────────────────────────────────
172
161
  export const AnalyzeCodeQualitySchema = z.object({
@@ -180,3 +169,10 @@ export const CheckArchitectureComplianceSchema = z.object({
180
169
  path: z.string().min(1, "Path to check is required"),
181
170
  rules: z.array(z.string()).optional(),
182
171
  }).strict();
172
+ // ─── PII / Compliance ───────────────────────────────────────────────
173
+ export const MaskPIISchema = z.object({
174
+ text: z.string().optional(),
175
+ data: z.record(z.unknown()).optional(),
176
+ mode: z.enum(["text", "object", "auto"]).optional().default("auto"),
177
+ strictMode: z.boolean().optional().default(false),
178
+ }).strict();