moderado 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +208 -0
  3. package/dist/args.d.ts +26 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +108 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/commands/chat.d.ts +121 -0
  8. package/dist/commands/chat.d.ts.map +1 -0
  9. package/dist/commands/chat.js +1484 -0
  10. package/dist/commands/chat.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +3 -0
  12. package/dist/commands/doctor.d.ts.map +1 -0
  13. package/dist/commands/doctor.js +61 -0
  14. package/dist/commands/doctor.js.map +1 -0
  15. package/dist/commands/init.d.ts +27 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +172 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/interactive_menu.d.ts +3 -0
  20. package/dist/commands/interactive_menu.d.ts.map +1 -0
  21. package/dist/commands/interactive_menu.js +98 -0
  22. package/dist/commands/interactive_menu.js.map +1 -0
  23. package/dist/commands/models.d.ts +8 -0
  24. package/dist/commands/models.d.ts.map +1 -0
  25. package/dist/commands/models.js +81 -0
  26. package/dist/commands/models.js.map +1 -0
  27. package/dist/commands/run.d.ts +3 -0
  28. package/dist/commands/run.d.ts.map +1 -0
  29. package/dist/commands/run.js +140 -0
  30. package/dist/commands/run.js.map +1 -0
  31. package/dist/config.d.ts +44 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +195 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/credentials.d.ts +14 -0
  36. package/dist/credentials.d.ts.map +1 -0
  37. package/dist/credentials.js +23 -0
  38. package/dist/credentials.js.map +1 -0
  39. package/dist/diagnostic_log.d.ts +2 -0
  40. package/dist/diagnostic_log.d.ts.map +1 -0
  41. package/dist/diagnostic_log.js +21 -0
  42. package/dist/diagnostic_log.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +83 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/model_pricing.d.ts +4 -0
  48. package/dist/model_pricing.d.ts.map +1 -0
  49. package/dist/model_pricing.js +10 -0
  50. package/dist/model_pricing.js.map +1 -0
  51. package/dist/sessions.d.ts +203 -0
  52. package/dist/sessions.d.ts.map +1 -0
  53. package/dist/sessions.js +82 -0
  54. package/dist/sessions.js.map +1 -0
  55. package/dist/ui/box.d.ts +14 -0
  56. package/dist/ui/box.d.ts.map +1 -0
  57. package/dist/ui/box.js +52 -0
  58. package/dist/ui/box.js.map +1 -0
  59. package/dist/ui/file_mentions.d.ts +38 -0
  60. package/dist/ui/file_mentions.d.ts.map +1 -0
  61. package/dist/ui/file_mentions.js +119 -0
  62. package/dist/ui/file_mentions.js.map +1 -0
  63. package/dist/ui/help_modal.d.ts +2 -0
  64. package/dist/ui/help_modal.d.ts.map +1 -0
  65. package/dist/ui/help_modal.js +101 -0
  66. package/dist/ui/help_modal.js.map +1 -0
  67. package/dist/ui/model_selector.d.ts +48 -0
  68. package/dist/ui/model_selector.d.ts.map +1 -0
  69. package/dist/ui/model_selector.js +829 -0
  70. package/dist/ui/model_selector.js.map +1 -0
  71. package/dist/ui/popup.d.ts +78 -0
  72. package/dist/ui/popup.d.ts.map +1 -0
  73. package/dist/ui/popup.js +274 -0
  74. package/dist/ui/popup.js.map +1 -0
  75. package/dist/ui/prompt.d.ts +21 -0
  76. package/dist/ui/prompt.d.ts.map +1 -0
  77. package/dist/ui/prompt.js +128 -0
  78. package/dist/ui/prompt.js.map +1 -0
  79. package/dist/ui/provider_connect.d.ts +33 -0
  80. package/dist/ui/provider_connect.d.ts.map +1 -0
  81. package/dist/ui/provider_connect.js +175 -0
  82. package/dist/ui/provider_connect.js.map +1 -0
  83. package/dist/ui/renderer.d.ts +19 -0
  84. package/dist/ui/renderer.d.ts.map +1 -0
  85. package/dist/ui/renderer.js +147 -0
  86. package/dist/ui/renderer.js.map +1 -0
  87. package/dist/ui/session_screen.d.ts +32 -0
  88. package/dist/ui/session_screen.d.ts.map +1 -0
  89. package/dist/ui/session_screen.js +148 -0
  90. package/dist/ui/session_screen.js.map +1 -0
  91. package/dist/ui/session_terminal.d.ts +46 -0
  92. package/dist/ui/session_terminal.d.ts.map +1 -0
  93. package/dist/ui/session_terminal.js +342 -0
  94. package/dist/ui/session_terminal.js.map +1 -0
  95. package/dist/ui/terminal_approval.d.ts +14 -0
  96. package/dist/ui/terminal_approval.d.ts.map +1 -0
  97. package/dist/ui/terminal_approval.js +98 -0
  98. package/dist/ui/terminal_approval.js.map +1 -0
  99. package/dist/ui/welcome.d.ts +130 -0
  100. package/dist/ui/welcome.d.ts.map +1 -0
  101. package/dist/ui/welcome.js +990 -0
  102. package/dist/ui/welcome.js.map +1 -0
  103. package/dist/vendor/contracts/approvals.d.ts +91 -0
  104. package/dist/vendor/contracts/approvals.d.ts.map +1 -0
  105. package/dist/vendor/contracts/approvals.js +22 -0
  106. package/dist/vendor/contracts/approvals.js.map +1 -0
  107. package/dist/vendor/contracts/events.d.ts +1215 -0
  108. package/dist/vendor/contracts/events.d.ts.map +1 -0
  109. package/dist/vendor/contracts/events.js +94 -0
  110. package/dist/vendor/contracts/events.js.map +1 -0
  111. package/dist/vendor/contracts/index.d.ts +7 -0
  112. package/dist/vendor/contracts/index.d.ts.map +1 -0
  113. package/dist/vendor/contracts/index.js +7 -0
  114. package/dist/vendor/contracts/index.js.map +1 -0
  115. package/dist/vendor/contracts/messages.d.ts +181 -0
  116. package/dist/vendor/contracts/messages.d.ts.map +1 -0
  117. package/dist/vendor/contracts/messages.js +40 -0
  118. package/dist/vendor/contracts/messages.js.map +1 -0
  119. package/dist/vendor/contracts/models.d.ts +117 -0
  120. package/dist/vendor/contracts/models.d.ts.map +1 -0
  121. package/dist/vendor/contracts/models.js +37 -0
  122. package/dist/vendor/contracts/models.js.map +1 -0
  123. package/dist/vendor/contracts/provider.d.ts +121 -0
  124. package/dist/vendor/contracts/provider.d.ts.map +1 -0
  125. package/dist/vendor/contracts/provider.js +64 -0
  126. package/dist/vendor/contracts/provider.js.map +1 -0
  127. package/dist/vendor/contracts/tools.d.ts +305 -0
  128. package/dist/vendor/contracts/tools.d.ts.map +1 -0
  129. package/dist/vendor/contracts/tools.js +65 -0
  130. package/dist/vendor/contracts/tools.js.map +1 -0
  131. package/dist/vendor/core/agent.d.ts +39 -0
  132. package/dist/vendor/core/agent.d.ts.map +1 -0
  133. package/dist/vendor/core/agent.js +710 -0
  134. package/dist/vendor/core/agent.js.map +1 -0
  135. package/dist/vendor/core/host_event_stream.d.ts +9 -0
  136. package/dist/vendor/core/host_event_stream.d.ts.map +1 -0
  137. package/dist/vendor/core/host_event_stream.js +12 -0
  138. package/dist/vendor/core/host_event_stream.js.map +1 -0
  139. package/dist/vendor/core/index.d.ts +7 -0
  140. package/dist/vendor/core/index.d.ts.map +1 -0
  141. package/dist/vendor/core/index.js +7 -0
  142. package/dist/vendor/core/index.js.map +1 -0
  143. package/dist/vendor/core/policy.d.ts +19 -0
  144. package/dist/vendor/core/policy.d.ts.map +1 -0
  145. package/dist/vendor/core/policy.js +31 -0
  146. package/dist/vendor/core/policy.js.map +1 -0
  147. package/dist/vendor/core/router.d.ts +26 -0
  148. package/dist/vendor/core/router.d.ts.map +1 -0
  149. package/dist/vendor/core/router.js +222 -0
  150. package/dist/vendor/core/router.js.map +1 -0
  151. package/dist/vendor/core/subagent.d.ts +29 -0
  152. package/dist/vendor/core/subagent.d.ts.map +1 -0
  153. package/dist/vendor/core/subagent.js +66 -0
  154. package/dist/vendor/core/subagent.js.map +1 -0
  155. package/dist/vendor/core/think_filter.d.ts +14 -0
  156. package/dist/vendor/core/think_filter.d.ts.map +1 -0
  157. package/dist/vendor/core/think_filter.js +136 -0
  158. package/dist/vendor/core/think_filter.js.map +1 -0
  159. package/dist/vendor/providers/fake/fake_provider.d.ts +16 -0
  160. package/dist/vendor/providers/fake/fake_provider.d.ts.map +1 -0
  161. package/dist/vendor/providers/fake/fake_provider.js +89 -0
  162. package/dist/vendor/providers/fake/fake_provider.js.map +1 -0
  163. package/dist/vendor/providers/index.d.ts +6 -0
  164. package/dist/vendor/providers/index.d.ts.map +1 -0
  165. package/dist/vendor/providers/index.js +6 -0
  166. package/dist/vendor/providers/index.js.map +1 -0
  167. package/dist/vendor/providers/model_discovery.d.ts +28 -0
  168. package/dist/vendor/providers/model_discovery.d.ts.map +1 -0
  169. package/dist/vendor/providers/model_discovery.js +106 -0
  170. package/dist/vendor/providers/model_discovery.js.map +1 -0
  171. package/dist/vendor/providers/nvidia/nvidia_adapter.d.ts +23 -0
  172. package/dist/vendor/providers/nvidia/nvidia_adapter.d.ts.map +1 -0
  173. package/dist/vendor/providers/nvidia/nvidia_adapter.js +197 -0
  174. package/dist/vendor/providers/nvidia/nvidia_adapter.js.map +1 -0
  175. package/dist/vendor/providers/nvidia/sse_parser.d.ts +3 -0
  176. package/dist/vendor/providers/nvidia/sse_parser.d.ts.map +1 -0
  177. package/dist/vendor/providers/nvidia/sse_parser.js +84 -0
  178. package/dist/vendor/providers/nvidia/sse_parser.js.map +1 -0
  179. package/dist/vendor/providers/openai_compatible_adapter.d.ts +10 -0
  180. package/dist/vendor/providers/openai_compatible_adapter.d.ts.map +1 -0
  181. package/dist/vendor/providers/openai_compatible_adapter.js +8 -0
  182. package/dist/vendor/providers/openai_compatible_adapter.js.map +1 -0
  183. package/dist/vendor/tools/checkpoints.d.ts +27 -0
  184. package/dist/vendor/tools/checkpoints.d.ts.map +1 -0
  185. package/dist/vendor/tools/checkpoints.js +145 -0
  186. package/dist/vendor/tools/checkpoints.js.map +1 -0
  187. package/dist/vendor/tools/diagnostics.d.ts +11 -0
  188. package/dist/vendor/tools/diagnostics.d.ts.map +1 -0
  189. package/dist/vendor/tools/diagnostics.js +16 -0
  190. package/dist/vendor/tools/diagnostics.js.map +1 -0
  191. package/dist/vendor/tools/diff.d.ts +7 -0
  192. package/dist/vendor/tools/diff.d.ts.map +1 -0
  193. package/dist/vendor/tools/diff.js +48 -0
  194. package/dist/vendor/tools/diff.js.map +1 -0
  195. package/dist/vendor/tools/errors.d.ts +17 -0
  196. package/dist/vendor/tools/errors.d.ts.map +1 -0
  197. package/dist/vendor/tools/errors.js +33 -0
  198. package/dist/vendor/tools/errors.js.map +1 -0
  199. package/dist/vendor/tools/git_workspace.d.ts +14 -0
  200. package/dist/vendor/tools/git_workspace.d.ts.map +1 -0
  201. package/dist/vendor/tools/git_workspace.js +42 -0
  202. package/dist/vendor/tools/git_workspace.js.map +1 -0
  203. package/dist/vendor/tools/index.d.ts +22 -0
  204. package/dist/vendor/tools/index.d.ts.map +1 -0
  205. package/dist/vendor/tools/index.js +22 -0
  206. package/dist/vendor/tools/index.js.map +1 -0
  207. package/dist/vendor/tools/jail.d.ts +17 -0
  208. package/dist/vendor/tools/jail.d.ts.map +1 -0
  209. package/dist/vendor/tools/jail.js +221 -0
  210. package/dist/vendor/tools/jail.js.map +1 -0
  211. package/dist/vendor/tools/lsp.d.ts +3 -0
  212. package/dist/vendor/tools/lsp.d.ts.map +1 -0
  213. package/dist/vendor/tools/lsp.js +43 -0
  214. package/dist/vendor/tools/lsp.js.map +1 -0
  215. package/dist/vendor/tools/mcp.d.ts +9 -0
  216. package/dist/vendor/tools/mcp.d.ts.map +1 -0
  217. package/dist/vendor/tools/mcp.js +54 -0
  218. package/dist/vendor/tools/mcp.js.map +1 -0
  219. package/dist/vendor/tools/mcp_adapter.d.ts +15 -0
  220. package/dist/vendor/tools/mcp_adapter.d.ts.map +1 -0
  221. package/dist/vendor/tools/mcp_adapter.js +29 -0
  222. package/dist/vendor/tools/mcp_adapter.js.map +1 -0
  223. package/dist/vendor/tools/registry.d.ts +10 -0
  224. package/dist/vendor/tools/registry.d.ts.map +1 -0
  225. package/dist/vendor/tools/registry.js +126 -0
  226. package/dist/vendor/tools/registry.js.map +1 -0
  227. package/dist/vendor/tools/tools/apply_patch.d.ts +3 -0
  228. package/dist/vendor/tools/tools/apply_patch.d.ts.map +1 -0
  229. package/dist/vendor/tools/tools/apply_patch.js +49 -0
  230. package/dist/vendor/tools/tools/apply_patch.js.map +1 -0
  231. package/dist/vendor/tools/tools/edit_file.d.ts +3 -0
  232. package/dist/vendor/tools/tools/edit_file.d.ts.map +1 -0
  233. package/dist/vendor/tools/tools/edit_file.js +71 -0
  234. package/dist/vendor/tools/tools/edit_file.js.map +1 -0
  235. package/dist/vendor/tools/tools/git_diff.d.ts +3 -0
  236. package/dist/vendor/tools/tools/git_diff.d.ts.map +1 -0
  237. package/dist/vendor/tools/tools/git_diff.js +91 -0
  238. package/dist/vendor/tools/tools/git_diff.js.map +1 -0
  239. package/dist/vendor/tools/tools/language_intelligence.d.ts +4 -0
  240. package/dist/vendor/tools/tools/language_intelligence.d.ts.map +1 -0
  241. package/dist/vendor/tools/tools/language_intelligence.js +13 -0
  242. package/dist/vendor/tools/tools/language_intelligence.js.map +1 -0
  243. package/dist/vendor/tools/tools/list_files.d.ts +9 -0
  244. package/dist/vendor/tools/tools/list_files.d.ts.map +1 -0
  245. package/dist/vendor/tools/tools/list_files.js +165 -0
  246. package/dist/vendor/tools/tools/list_files.js.map +1 -0
  247. package/dist/vendor/tools/tools/read_file.d.ts +3 -0
  248. package/dist/vendor/tools/tools/read_file.d.ts.map +1 -0
  249. package/dist/vendor/tools/tools/read_file.js +72 -0
  250. package/dist/vendor/tools/tools/read_file.js.map +1 -0
  251. package/dist/vendor/tools/tools/run_command.d.ts +12 -0
  252. package/dist/vendor/tools/tools/run_command.d.ts.map +1 -0
  253. package/dist/vendor/tools/tools/run_command.js +421 -0
  254. package/dist/vendor/tools/tools/run_command.js.map +1 -0
  255. package/dist/vendor/tools/tools/run_diagnostics.d.ts +3 -0
  256. package/dist/vendor/tools/tools/run_diagnostics.d.ts.map +1 -0
  257. package/dist/vendor/tools/tools/run_diagnostics.js +11 -0
  258. package/dist/vendor/tools/tools/run_diagnostics.js.map +1 -0
  259. package/dist/vendor/tools/tools/search_files.d.ts +3 -0
  260. package/dist/vendor/tools/tools/search_files.d.ts.map +1 -0
  261. package/dist/vendor/tools/tools/search_files.js +120 -0
  262. package/dist/vendor/tools/tools/search_files.js.map +1 -0
  263. package/dist/vendor/tools/tools/web_search.d.ts +46 -0
  264. package/dist/vendor/tools/tools/web_search.d.ts.map +1 -0
  265. package/dist/vendor/tools/tools/web_search.js +187 -0
  266. package/dist/vendor/tools/tools/web_search.js.map +1 -0
  267. package/dist/vendor/tools/tools/write_file.d.ts +3 -0
  268. package/dist/vendor/tools/tools/write_file.d.ts.map +1 -0
  269. package/dist/vendor/tools/tools/write_file.js +52 -0
  270. package/dist/vendor/tools/tools/write_file.js.map +1 -0
  271. package/dist/windows_credentials.d.ts +15 -0
  272. package/dist/windows_credentials.d.ts.map +1 -0
  273. package/dist/windows_credentials.js +23 -0
  274. package/dist/windows_credentials.js.map +1 -0
  275. package/package.json +28 -0
@@ -0,0 +1,22 @@
1
+ export * from './errors.js';
2
+ export * from './jail.js';
3
+ export * from './diff.js';
4
+ export * from './git_workspace.js';
5
+ export * from './checkpoints.js';
6
+ export * from './registry.js';
7
+ export * from './tools/read_file.js';
8
+ export * from './tools/write_file.js';
9
+ export * from './tools/edit_file.js';
10
+ export * from './tools/apply_patch.js';
11
+ export * from './tools/list_files.js';
12
+ export * from './tools/search_files.js';
13
+ export * from './tools/run_command.js';
14
+ export * from './tools/git_diff.js';
15
+ export * from './diagnostics.js';
16
+ export * from './tools/run_diagnostics.js';
17
+ export * from './lsp.js';
18
+ export * from './tools/language_intelligence.js';
19
+ export * from './tools/web_search.js';
20
+ export * from './mcp.js';
21
+ export * from './mcp_adapter.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC;AACvC,cAAc,qBAAqB,CAAC;AAEpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAE3C,cAAc,UAAU,CAAC;AACzB,cAAc,kCAAkC,CAAC;AACjD,cAAc,uBAAuB,CAAC;AAEtC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Normalizes Windows/WSL path representations to the platform/workspace-appropriate format.
3
+ *
4
+ * Supported conversions:
5
+ * - \\?\C:\... -> C:\... (Windows verbatim disk namespace)
6
+ * - \\wsl$\<distro>\mnt\<drive>\... or //wsl$/... -> <drive>:\...
7
+ * - \\wsl.localhost\<distro>\mnt\<drive>\... -> <drive>:\...
8
+ * - /mnt/<drive>/... -> <drive>:\... (when running on Windows or against a Windows drive root)
9
+ * - <drive>:\... -> /mnt/<drive>/... (when running on POSIX/WSL against a POSIX root)
10
+ * - \\wsl$\<distro>\<path> -> <path> (when referenceRoot is a POSIX root matching <path>)
11
+ * - Drive letters are normalized to uppercase on Windows.
12
+ */
13
+ export declare function normalizeCrossPlatformPath(targetPath: string, referenceRoot?: string): string;
14
+ export declare function isProtectedPath(relativePath: string): boolean;
15
+ export declare function canonicalizeRoot(workspaceRoot: string): string;
16
+ export declare function resolveInJail(workspaceRoot: string, targetPath: string): string;
17
+ //# sourceMappingURL=jail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jail.d.ts","sourceRoot":"","sources":["../src/jail.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;GAWG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAuF7F;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CA+B7D;AA4BD,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAe9D;AAED,wBAAgB,aAAa,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAmE/E"}
@@ -0,0 +1,221 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { SecurityViolationError } from './errors.js';
4
+ const SENSITIVE_PATTERNS = [
5
+ /^\.git([\\/]|$)/i,
6
+ /^\.env(\.[a-zA-Z0-9_\-]+)?$/i,
7
+ /\.pem$/i,
8
+ /\.key$/i,
9
+ /^id_[a-zA-Z0-9_]+/i,
10
+ /credentials\.json$/i,
11
+ ];
12
+ /**
13
+ * Normalizes Windows/WSL path representations to the platform/workspace-appropriate format.
14
+ *
15
+ * Supported conversions:
16
+ * - \\?\C:\... -> C:\... (Windows verbatim disk namespace)
17
+ * - \\wsl$\<distro>\mnt\<drive>\... or //wsl$/... -> <drive>:\...
18
+ * - \\wsl.localhost\<distro>\mnt\<drive>\... -> <drive>:\...
19
+ * - /mnt/<drive>/... -> <drive>:\... (when running on Windows or against a Windows drive root)
20
+ * - <drive>:\... -> /mnt/<drive>/... (when running on POSIX/WSL against a POSIX root)
21
+ * - \\wsl$\<distro>\<path> -> <path> (when referenceRoot is a POSIX root matching <path>)
22
+ * - Drive letters are normalized to uppercase on Windows.
23
+ */
24
+ export function normalizeCrossPlatformPath(targetPath, referenceRoot) {
25
+ if (!targetPath || typeof targetPath !== 'string') {
26
+ return targetPath;
27
+ }
28
+ let p = targetPath.trim();
29
+ if (p === '') {
30
+ return p;
31
+ }
32
+ // Strip Windows extended-length prefix (\\?\ or //?/)
33
+ if (p.startsWith('\\\\?\\UNC\\') || p.startsWith('//?/UNC/')) {
34
+ p = '\\\\' + p.slice(8);
35
+ }
36
+ else if (p.startsWith('\\\\?\\') || p.startsWith('//?/')) {
37
+ p = p.slice(4);
38
+ }
39
+ const isWin = process.platform === 'win32';
40
+ const rootIsDrive = referenceRoot ? /^[a-zA-Z]:/i.test(referenceRoot) : isWin;
41
+ // 1. Check WSL UNC path: \\wsl$\<distro>\... or \\wsl.localhost\<distro>\... (also //)
42
+ const wslUncMatch = p.match(/^[\\/]{2}(wsl\$|wsl\.localhost)[\\/]([^\\/]+)([\\/].*)?$/i);
43
+ if (wslUncMatch) {
44
+ const subPath = wslUncMatch[3] || '';
45
+ const mntMatch = subPath.match(/^[\\/]mnt[\\/]([a-zA-Z])([\\/].*)?$/i);
46
+ if (mntMatch) {
47
+ // Points to a Windows drive mount inside WSL (e.g. \\wsl$\Ubuntu\mnt\c\...)
48
+ const drive = mntMatch[1].toUpperCase() + ':';
49
+ const rest = mntMatch[2] ? mntMatch[2].replace(/\//g, '\\') : '\\';
50
+ if (rootIsDrive) {
51
+ return `${drive}${rest}`;
52
+ }
53
+ return `/mnt/${mntMatch[1].toLowerCase()}${mntMatch[2] ? mntMatch[2].replace(/\\/g, '/') : ''}`;
54
+ }
55
+ // It's a Linux path inside the WSL distro (e.g. \\wsl$\Ubuntu\home\alice\...)
56
+ if (!rootIsDrive && referenceRoot && !referenceRoot.startsWith('\\\\')) {
57
+ return subPath ? subPath.replace(/\\/g, '/') : '/';
58
+ }
59
+ if (referenceRoot) {
60
+ const refWsl = referenceRoot.match(/^[\\/]{2}(wsl\$|wsl\.localhost)[\\/]([^\\/]+)([\\/].*)?$/i);
61
+ if (refWsl) {
62
+ const canonicalPrefix = `\\\\${refWsl[1]}\\${refWsl[2]}`;
63
+ const rest = subPath ? subPath.replace(/\//g, '\\') : '';
64
+ return `${canonicalPrefix}${rest}`;
65
+ }
66
+ }
67
+ return p;
68
+ }
69
+ // 2. Check WSL /mnt/<drive>/... (or \mnt\<drive>\...)
70
+ const mntMatch = p.match(/^[\\/]mnt[\\/]([a-zA-Z])([\\/].*)?$/i);
71
+ if (mntMatch) {
72
+ if (rootIsDrive) {
73
+ const drive = mntMatch[1].toUpperCase() + ':';
74
+ const rest = mntMatch[2] ? mntMatch[2].replace(/\//g, '\\') : '\\';
75
+ return `${drive}${rest}`;
76
+ }
77
+ const drive = mntMatch[1].toLowerCase();
78
+ const rest = mntMatch[2] ? mntMatch[2].replace(/\\/g, '/') : '';
79
+ return `/mnt/${drive}${rest}`;
80
+ }
81
+ // 3. Check Windows drive letter: C:\... or C:/...
82
+ const driveMatch = p.match(/^([a-zA-Z]):([\\/].*)?$/);
83
+ if (driveMatch) {
84
+ if (!rootIsDrive && referenceRoot && !referenceRoot.startsWith('\\\\')) {
85
+ // Map to /mnt/<drive>/... for POSIX/WSL reference root
86
+ const drive = driveMatch[1].toLowerCase();
87
+ const rest = driveMatch[2] ? driveMatch[2].replace(/\\/g, '/') : '';
88
+ return `/mnt/${drive}${rest}`;
89
+ }
90
+ const drive = driveMatch[1].toUpperCase();
91
+ const rest = driveMatch[2] ? driveMatch[2].replace(/\//g, '\\') : '\\';
92
+ return `${drive}:${rest}`;
93
+ }
94
+ // 4. POSIX absolute path when referenceRoot is a WSL UNC path
95
+ if (p.startsWith('/') && referenceRoot) {
96
+ const refWsl = referenceRoot.match(/^[\\/]{2}(wsl\$|wsl\.localhost)[\\/]([^\\/]+)([\\/].*)?$/i);
97
+ if (refWsl) {
98
+ return `\\\\${refWsl[1]}\\${refWsl[2]}${p.replace(/\//g, '\\')}`;
99
+ }
100
+ }
101
+ return p;
102
+ }
103
+ export function isProtectedPath(relativePath) {
104
+ if (!relativePath || relativePath.trim() === '') {
105
+ return false;
106
+ }
107
+ // Strip Windows NTFS Alternate Data Streams suffix like ::$DATA
108
+ const cleanPath = relativePath.replace(/::\$[a-zA-Z0-9_]+$/i, '');
109
+ const segments = cleanPath.split(/[\\/]/).filter(Boolean);
110
+ // Check if any segment is .git (case-insensitive for Windows/WSL)
111
+ if (segments.some(s => s.toLowerCase() === '.git')) {
112
+ return true;
113
+ }
114
+ // Check each segment against sensitive patterns
115
+ for (const segment of segments) {
116
+ for (const pattern of SENSITIVE_PATTERNS) {
117
+ if (pattern.test(segment)) {
118
+ return true;
119
+ }
120
+ }
121
+ }
122
+ const basename = path.basename(cleanPath);
123
+ for (const pattern of SENSITIVE_PATTERNS) {
124
+ if (pattern.test(cleanPath) || pattern.test(basename)) {
125
+ return true;
126
+ }
127
+ }
128
+ return false;
129
+ }
130
+ function normalizeDriveLetter(p) {
131
+ if (/^[a-zA-Z]:/.test(p)) {
132
+ return p[0].toUpperCase() + p.slice(1);
133
+ }
134
+ return p;
135
+ }
136
+ function isContainedInRoot(root, target) {
137
+ if (root === target) {
138
+ return true;
139
+ }
140
+ if (process.platform === 'win32') {
141
+ const rootNorm = root.toLowerCase().replace(/[\\/]+$/, '');
142
+ const targetNorm = target.toLowerCase().replace(/[\\/]+$/, '');
143
+ if (rootNorm === targetNorm) {
144
+ return true;
145
+ }
146
+ return targetNorm.startsWith(rootNorm + '\\') || targetNorm.startsWith(rootNorm + '/');
147
+ }
148
+ const rootNorm = root.replace(/[\\/]+$/, '');
149
+ const targetNorm = target.replace(/[\\/]+$/, '');
150
+ return targetNorm.startsWith(rootNorm + path.sep);
151
+ }
152
+ export function canonicalizeRoot(workspaceRoot) {
153
+ if (!workspaceRoot || workspaceRoot.trim() === '') {
154
+ throw new SecurityViolationError('Workspace root cannot be empty.');
155
+ }
156
+ const normalized = normalizeCrossPlatformPath(workspaceRoot);
157
+ if (!fs.existsSync(normalized)) {
158
+ throw new SecurityViolationError(`Workspace root directory does not exist: '${workspaceRoot}'`);
159
+ }
160
+ const stat = fs.statSync(normalized);
161
+ if (!stat.isDirectory()) {
162
+ throw new SecurityViolationError(`Workspace root is not a directory: '${workspaceRoot}'`);
163
+ }
164
+ const canonical = fs.realpathSync(normalized);
165
+ return normalizeDriveLetter(canonical);
166
+ }
167
+ export function resolveInJail(workspaceRoot, targetPath) {
168
+ if (!targetPath || targetPath.trim() === '') {
169
+ throw new SecurityViolationError('Path argument cannot be empty.');
170
+ }
171
+ const canonicalRoot = canonicalizeRoot(workspaceRoot);
172
+ const normalizedTarget = normalizeCrossPlatformPath(targetPath, canonicalRoot);
173
+ let absoluteTarget = path.resolve(canonicalRoot, normalizedTarget);
174
+ if (process.platform === 'win32') {
175
+ absoluteTarget = normalizeDriveLetter(absoluteTarget);
176
+ }
177
+ // Pre-check containment before touching filesystem/network to prevent
178
+ // Windows SMB timeout hangs and NetNTLM hash leaks on malicious UNC paths.
179
+ if (!isContainedInRoot(canonicalRoot, absoluteTarget)) {
180
+ throw new SecurityViolationError(`Access denied: path '${targetPath}' resolves to '${absoluteTarget}', which escapes workspace jail '${canonicalRoot}'.`);
181
+ }
182
+ // Check if target exists; if so, resolve canonical symlinks
183
+ let canonicalTarget;
184
+ if (fs.existsSync(absoluteTarget)) {
185
+ canonicalTarget = fs.realpathSync(absoluteTarget);
186
+ }
187
+ else {
188
+ // For non-existent paths (e.g. write_file to new file), resolve the deepest existing parent
189
+ let currentDir = path.dirname(absoluteTarget);
190
+ const uncreatedSegments = [path.basename(absoluteTarget)];
191
+ while (!fs.existsSync(currentDir)) {
192
+ const parent = path.dirname(currentDir);
193
+ if (parent === currentDir) {
194
+ break;
195
+ }
196
+ uncreatedSegments.unshift(path.basename(currentDir));
197
+ currentDir = parent;
198
+ }
199
+ if (fs.existsSync(currentDir)) {
200
+ const canonicalParent = fs.realpathSync(currentDir);
201
+ canonicalTarget = path.resolve(canonicalParent, ...uncreatedSegments);
202
+ }
203
+ else {
204
+ canonicalTarget = absoluteTarget;
205
+ }
206
+ }
207
+ if (process.platform === 'win32') {
208
+ canonicalTarget = normalizeDriveLetter(canonicalTarget);
209
+ }
210
+ // Jail containment check (guards against symlink escapes)
211
+ if (!isContainedInRoot(canonicalRoot, canonicalTarget)) {
212
+ throw new SecurityViolationError(`Access denied: path '${targetPath}' resolves to '${canonicalTarget}', which escapes workspace jail '${canonicalRoot}'.`);
213
+ }
214
+ // Relative path from canonical root to check protected file blacklist
215
+ const relativeFromRoot = path.relative(canonicalRoot, canonicalTarget);
216
+ if (isProtectedPath(relativeFromRoot)) {
217
+ throw new SecurityViolationError(`Access denied: path '${targetPath}' refers to protected or sensitive metadata.`);
218
+ }
219
+ return canonicalTarget;
220
+ }
221
+ //# sourceMappingURL=jail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jail.js","sourceRoot":"","sources":["../src/jail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { SourceLocation, SourcePosition } from '@moderado/contracts';
2
+ export declare function requestLanguageServer(root: string, executable: string, method: 'textDocument/definition' | 'textDocument/references', position: SourcePosition): Promise<SourceLocation[]>;
3
+ //# sourceMappingURL=lsp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.d.ts","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrE,wBAAsB,qBAAqB,CAAC,IAAI,EAAC,MAAM,EAAE,UAAU,EAAC,MAAM,EAAE,MAAM,EAAC,yBAAyB,GAAC,yBAAyB,EAAE,QAAQ,EAAC,cAAc,GAAE,OAAO,CAAC,cAAc,EAAE,CAAC,CAGzL"}
@@ -0,0 +1,43 @@
1
+ import { spawn } from 'node:child_process';
2
+ import path from 'node:path';
3
+ import { resolveInJail } from './jail.js';
4
+ import { getSanitizedEnv } from './tools/run_command.js';
5
+ export async function requestLanguageServer(root, executable, method, position) {
6
+ const file = resolveInJail(root, position.path);
7
+ const uri = new URL(`file:///${file.replace(/\\/g, '/')}`).href;
8
+ return new Promise((resolve, reject) => { const child = spawn(executable, ['--stdio'], { cwd: resolveInJail(root, '.'), env: getSanitizedEnv(), shell: false, windowsHide: true }); let buffer = ''; let done = false; const finish = (value) => { if (done)
9
+ return; done = true; clearTimeout(timer); child.kill(); value instanceof Error ? reject(value) : resolve(value); }; const send = (body) => { const text = JSON.stringify({ jsonrpc: '2.0', ...body }); child.stdin?.write(`Content-Length: ${Buffer.byteLength(text)}\r\n\r\n${text}`); }; const timer = setTimeout(() => finish(new Error('TypeScript language server timed out. Configure typescriptLanguageServer or install typescript-language-server.')), 10000); child.on('error', () => finish(new Error(`Unable to start TypeScript language server '${executable}'. Install it and configure typescriptLanguageServer.`))); child.stdout?.on('data', (chunk) => { buffer += chunk.toString(); if (buffer.length > 1048576)
10
+ return finish(new Error('Language server response exceeded 1 MB.')); let split; while ((split = buffer.indexOf('\r\n\r\n')) >= 0) {
11
+ const header = buffer.slice(0, split);
12
+ const m = header.match(/Content-Length:\s*(\d+)/i);
13
+ if (!m)
14
+ return finish(new Error('Malformed language server response.'));
15
+ const end = split + 4 + Number(m[1]);
16
+ if (buffer.length < end)
17
+ return;
18
+ const text = buffer.slice(split + 4, end);
19
+ buffer = buffer.slice(end);
20
+ let msg;
21
+ try {
22
+ msg = JSON.parse(text);
23
+ }
24
+ catch {
25
+ return finish(new Error('Malformed language server JSON response.'));
26
+ }
27
+ if (msg.id === 3) {
28
+ const raw = Array.isArray(msg.result) ? msg.result : msg.result ? [msg.result] : [];
29
+ const locations = [];
30
+ for (const item of raw) {
31
+ try {
32
+ const target = new URL(item.uri ?? item.targetUri);
33
+ const targetFile = resolveInJail(root, decodeURIComponent(target.pathname));
34
+ const range = item.range ?? item.targetSelectionRange;
35
+ locations.push({ path: path.relative(resolveInJail(root, '.'), targetFile).split(path.sep).join('/'), line: range.start.line + 1, column: range.start.character + 1, endLine: range.end.line + 1, endColumn: range.end.character + 1 });
36
+ }
37
+ catch { }
38
+ }
39
+ finish(locations);
40
+ }
41
+ } }); send({ id: 1, method: 'initialize', params: { processId: process.pid, rootUri: new URL(`file:///${resolveInJail(root, '.').replace(/\\/g, '/')}`).href, capabilities: {} } }); send({ method: 'initialized', params: {} }); send({ method: 'textDocument/didOpen', params: { textDocument: { uri, languageId: 'typescript', version: 1, text: require('node:fs').readFileSync(file, 'utf8') } } }); send({ id: 3, method, params: { textDocument: { uri }, position: { line: position.line - 1, character: position.column - 1 }, ...(method.endsWith('references') ? { context: { includeDeclaration: true } } : {}) } }); });
42
+ }
43
+ //# sourceMappingURL=lsp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lsp.js","sourceRoot":"","sources":["../src/lsp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { McpServerConfig } from '@moderado/contracts';
2
+ interface McpTool {
3
+ name: string;
4
+ description?: string;
5
+ }
6
+ export declare function listMcpTools(server: McpServerConfig): Promise<McpTool[]>;
7
+ export declare function callMcpTool(server: McpServerConfig, name: string, args: Record<string, unknown>): Promise<string>;
8
+ export {};
9
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,UAAU,OAAO;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAAE;AAgBzD,wBAAsB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAsT;AACrY,wBAAsB,WAAW,CAAC,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAA2W"}
@@ -0,0 +1,54 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { getSanitizedEnv } from './tools/run_command.js';
3
+ function request(server, method, params) {
4
+ return new Promise((resolve, reject) => {
5
+ const child = spawn(server.executable, server.args, { env: getSanitizedEnv(), shell: false, windowsHide: true });
6
+ let buffer = '';
7
+ let settled = false;
8
+ let nextId = 1;
9
+ const finish = (value) => { if (settled)
10
+ return; settled = true; clearTimeout(timer); child.kill(); value instanceof Error ? reject(value) : resolve(value); };
11
+ const send = (name, value) => { const id = nextId++; const body = JSON.stringify({ jsonrpc: '2.0', id, method: name, params: value }); child.stdin?.write(`Content-Length: ${Buffer.byteLength(body)}\r\n\r\n${body}`); return id; };
12
+ const timer = setTimeout(() => finish(new Error('MCP server timed out.')), 10_000);
13
+ child.on('error', () => finish(new Error(`Unable to start configured MCP server '${server.executable}'.`)));
14
+ child.stdout?.on('data', (chunk) => {
15
+ buffer += chunk.toString();
16
+ if (buffer.length > 1_048_576)
17
+ return finish(new Error('MCP response exceeded 1 MB.'));
18
+ while (true) {
19
+ const at = buffer.indexOf('\r\n\r\n');
20
+ if (at < 0)
21
+ return;
22
+ const match = buffer.slice(0, at).match(/Content-Length:\s*(\d+)/i);
23
+ if (!match)
24
+ return finish(new Error('Malformed MCP response.'));
25
+ const end = at + 4 + Number(match[1]);
26
+ if (buffer.length < end)
27
+ return;
28
+ const text = buffer.slice(at + 4, end);
29
+ buffer = buffer.slice(end);
30
+ try {
31
+ const message = JSON.parse(text);
32
+ if (message.id === 1) {
33
+ send(method, params);
34
+ }
35
+ else if (message.id === 2) {
36
+ if (message.error)
37
+ finish(new Error(String(message.error.message ?? 'MCP request failed.')));
38
+ else
39
+ finish(message.result);
40
+ }
41
+ }
42
+ catch {
43
+ return finish(new Error('Malformed MCP JSON response.'));
44
+ }
45
+ }
46
+ });
47
+ send('initialize', { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'moderado', version: '0.2.0' } });
48
+ });
49
+ }
50
+ export async function listMcpTools(server) { const result = await request(server, 'tools/list'); if (!Array.isArray(result.tools))
51
+ throw new Error('Malformed MCP tools/list response.'); return result.tools.filter((tool) => !!tool && typeof tool === 'object' && /^[a-zA-Z0-9_-]+$/.test(tool.name)); }
52
+ export async function callMcpTool(server, name, args) { const result = await request(server, 'tools/call', { name, arguments: args }); if (!Array.isArray(result.content))
53
+ throw new Error('Malformed MCP tools/call response.'); return result.content.map((part) => typeof part?.text === 'string' ? part.text : '').join('\n').slice(0, 65_536) || 'MCP tool completed without text output.'; }
54
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { IToolDefinition, McpServerConfig } from '@moderado/contracts';
2
+ export interface McpTool {
3
+ name: string;
4
+ description?: string;
5
+ }
6
+ export interface McpServerStatus {
7
+ name: string;
8
+ enabled: boolean;
9
+ tools: McpTool[];
10
+ error?: string;
11
+ }
12
+ export declare function createMcpTool(serverName: string, server: McpServerConfig, toolName: string): IToolDefinition<Record<string, unknown>>;
13
+ export declare function discoverMcpServers(servers?: Record<string, McpServerConfig>): Promise<McpServerStatus[]>;
14
+ export declare function createMcpTools(servers: Record<string, McpServerConfig> | undefined): Promise<IToolDefinition<Record<string, unknown>>[]>;
15
+ //# sourceMappingURL=mcp_adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp_adapter.d.ts","sourceRoot":"","sources":["../src/mcp_adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAoC,MAAM,qBAAqB,CAAC;AAIzG,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,aAAa,CAAC,UAAU,EAAC,MAAM,EAAE,MAAM,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,GAAE,eAAe,CAAC,MAAM,CAAC,MAAM,EAAC,OAAO,CAAC,CAAC,CAA8nB;AAE/vB,wBAAsB,kBAAkB,CAAC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAUlH;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,SAAS,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,CAI9I"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ import { callMcpTool, listMcpTools } from './mcp.js';
3
+ export function createMcpTool(serverName, server, toolName) { if (!/^[a-z0-9_-]+$/i.test(serverName) || !/^[a-z0-9_-]+$/i.test(toolName))
4
+ throw new Error('MCP server and tool names must be alphanumeric, dash, or underscore.'); return { name: `mcp.${serverName}.${toolName}`, description: `Configured MCP tool ${toolName}.`, requiresApproval: true, parametersSchema: z.record(z.unknown()), async execute(params, _context) { try {
5
+ return { toolName: `mcp.${serverName}.${toolName}`, status: 'success', output: await callMcpTool(server, toolName, params) };
6
+ }
7
+ catch (err) {
8
+ return { toolName: `mcp.${serverName}.${toolName}`, status: 'error', output: err.message };
9
+ } } }; }
10
+ export async function discoverMcpServers(servers = {}) {
11
+ return Promise.all(Object.entries(servers).map(async ([name, server]) => {
12
+ const enabled = server.enabled !== false;
13
+ if (!enabled)
14
+ return { name, enabled, tools: [] };
15
+ try {
16
+ return { name, enabled, tools: await listMcpTools(server) };
17
+ }
18
+ catch (error) {
19
+ return { name, enabled, tools: [], error: error instanceof Error ? error.message : 'MCP discovery failed.' };
20
+ }
21
+ }));
22
+ }
23
+ export async function createMcpTools(servers) {
24
+ if (!servers)
25
+ return [];
26
+ const discovered = await discoverMcpServers(servers);
27
+ return discovered.flatMap((server) => server.tools.map((tool) => createMcpTool(server.name, servers[server.name], tool.name)));
28
+ }
29
+ //# sourceMappingURL=mcp_adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp_adapter.js","sourceRoot":"","sources":["../src/mcp_adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAcrD,MAAM,UAAU,aAAa,CAAC,UAAiB,EAAE,MAAsB,EAAE,QAAe,IAA4C,IAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;IAAE,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC,CAAC,OAAO,EAAC,IAAI,EAAC,OAAO,UAAU,IAAI,QAAQ,EAAE,EAAC,WAAW,EAAC,uBAAuB,QAAQ,GAAG,EAAC,gBAAgB,EAAC,IAAI,EAAC,gBAAgB,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAC,KAAK,CAAC,OAAO,CAAC,MAA6B,EAAC,QAA6B,IAAsB,IAAG,CAAC;QAAA,OAAO,EAAC,QAAQ,EAAC,OAAO,UAAU,IAAI,QAAQ,EAAE,EAAC,MAAM,EAAC,SAAS,EAAC,MAAM,EAAC,MAAM,WAAW,CAAC,MAAM,EAAC,QAAQ,EAAC,MAAM,CAAC,EAAC,CAAC;IAAA,CAAC;IAAA,OAAM,GAAO,EAAC,CAAC;QAAA,OAAO,EAAC,QAAQ,EAAC,OAAO,UAAU,IAAI,QAAQ,EAAE,EAAC,MAAM,EAAC,OAAO,EAAC,MAAM,EAAC,GAAG,CAAC,OAAO,EAAC,CAAC;IAAA,CAAC,CAAA,CAAC,EAAC,CAAC,CAAA,CAAC;AAE/vB,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAA2C,EAAE;IACpF,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;QACtE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,KAAK,KAAK,CAAC;QACzC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAClD,IAAI,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,EAAE,CAAC;QAC/G,CAAC;IACH,CAAC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAoD;IACvF,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,UAAU,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjI,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { IToolDefinition, IToolRegistry, ProviderToolDeclaration } from '@moderado/contracts';
2
+ export declare class ToolRegistry implements IToolRegistry {
3
+ private readonly tools;
4
+ register(tool: IToolDefinition<any>): void;
5
+ get(name: string): IToolDefinition<any> | undefined;
6
+ list(): IToolDefinition<any>[];
7
+ getDeclarations(): ProviderToolDeclaration[];
8
+ }
9
+ export declare function createDefaultToolRegistry(extraTools?: IToolDefinition<any>[]): IToolRegistry;
10
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,aAAa,EACb,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAa7B,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2C;IAEjE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,GAAG,IAAI;IAI1C,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,SAAS;IAInD,IAAI,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE;IAI9B,eAAe,IAAI,uBAAuB,EAAE;CAU7C;AAyFD,wBAAgB,yBAAyB,CAAC,UAAU,GAAE,eAAe,CAAC,GAAG,CAAC,EAAO,GAAG,aAAa,CAgBhG"}
@@ -0,0 +1,126 @@
1
+ import { ReadFileTool } from './tools/read_file.js';
2
+ import { WriteFileTool } from './tools/write_file.js';
3
+ import { EditFileTool } from './tools/edit_file.js';
4
+ import { ListFilesTool } from './tools/list_files.js';
5
+ import { SearchFilesTool } from './tools/search_files.js';
6
+ import { RunCommandTool } from './tools/run_command.js';
7
+ import { GitDiffTool } from './tools/git_diff.js';
8
+ import { ApplyPatchTool } from './tools/apply_patch.js';
9
+ import { RunDiagnosticsTool } from './tools/run_diagnostics.js';
10
+ import { FindReferencesTool, GetDefinitionTool } from './tools/language_intelligence.js';
11
+ import { WebSearchTool } from './tools/web_search.js';
12
+ export class ToolRegistry {
13
+ tools = new Map();
14
+ register(tool) {
15
+ this.tools.set(tool.name, tool);
16
+ }
17
+ get(name) {
18
+ return this.tools.get(name);
19
+ }
20
+ list() {
21
+ return Array.from(this.tools.values());
22
+ }
23
+ getDeclarations() {
24
+ return this.list().map((tool) => {
25
+ // Generate basic JSON Schema representation from Zod schema
26
+ return {
27
+ name: tool.name,
28
+ description: tool.description,
29
+ parameters: zodToJsonSchema(tool.parametersSchema),
30
+ };
31
+ });
32
+ }
33
+ }
34
+ /**
35
+ * Minimalist JSON schema extractor from Zod schemas adhering to Ponytail Decision Ladder.
36
+ */
37
+ function zodToJsonSchema(schema) {
38
+ const def = schema._def;
39
+ if (!def) {
40
+ return { type: 'object' };
41
+ }
42
+ if (def.typeName === 'ZodObject') {
43
+ const shape = def.shape();
44
+ const properties = {};
45
+ const required = [];
46
+ for (const [key, propSchema] of Object.entries(shape)) {
47
+ const propDef = propSchema._def;
48
+ const isOptional = propDef.typeName === 'ZodOptional' ||
49
+ propDef.typeName === 'ZodDefault';
50
+ if (!isOptional) {
51
+ required.push(key);
52
+ }
53
+ properties[key] = extractPropertySchema(propSchema);
54
+ }
55
+ return {
56
+ type: 'object',
57
+ properties,
58
+ required: required.length > 0 ? required : undefined,
59
+ };
60
+ }
61
+ return { type: 'object' };
62
+ }
63
+ function extractPropertySchema(propSchema) {
64
+ let current = propSchema;
65
+ let description;
66
+ while (current._def?.innerType) {
67
+ current = current._def.innerType;
68
+ }
69
+ description = current.description;
70
+ const typeName = current._def?.typeName;
71
+ let schema = { type: 'string' };
72
+ switch (typeName) {
73
+ case 'ZodString':
74
+ schema = { type: 'string' };
75
+ break;
76
+ case 'ZodNumber':
77
+ schema = { type: 'number' };
78
+ break;
79
+ case 'ZodBoolean':
80
+ schema = { type: 'boolean' };
81
+ break;
82
+ case 'ZodArray':
83
+ schema = {
84
+ type: 'array',
85
+ items: extractPropertySchema(current._def.type),
86
+ };
87
+ break;
88
+ case 'ZodEnum':
89
+ schema = {
90
+ type: 'string',
91
+ enum: current._def.values,
92
+ };
93
+ break;
94
+ case 'ZodRecord':
95
+ schema = {
96
+ type: 'object',
97
+ };
98
+ break;
99
+ default:
100
+ schema = { type: 'string' };
101
+ break;
102
+ }
103
+ if (description) {
104
+ schema.description = description;
105
+ }
106
+ return schema;
107
+ }
108
+ export function createDefaultToolRegistry(extraTools = []) {
109
+ const registry = new ToolRegistry();
110
+ registry.register(ReadFileTool);
111
+ registry.register(WriteFileTool);
112
+ registry.register(EditFileTool);
113
+ registry.register(ListFilesTool);
114
+ registry.register(SearchFilesTool);
115
+ registry.register(RunCommandTool);
116
+ registry.register(GitDiffTool);
117
+ registry.register(ApplyPatchTool);
118
+ registry.register(RunDiagnosticsTool);
119
+ registry.register(GetDefinitionTool);
120
+ registry.register(FindReferencesTool);
121
+ registry.register(WebSearchTool);
122
+ for (const tool of extraTools)
123
+ registry.register(tool);
124
+ return registry;
125
+ }
126
+ //# sourceMappingURL=registry.js.map