@easynet/agent-tool 1.0.1 → 1.0.2

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 (309) hide show
  1. package/README.md +92 -50
  2. package/dist/api/adapters/LangChainToolsHub.d.ts +34 -0
  3. package/dist/api/adapters/LangChainToolsHub.d.ts.map +1 -0
  4. package/dist/api/createAgentTools.d.ts +24 -0
  5. package/dist/api/createAgentTools.d.ts.map +1 -0
  6. package/dist/api/expose/index.d.ts +16 -0
  7. package/dist/api/expose/index.d.ts.map +1 -0
  8. package/dist/api/expose/mcp-build/build.d.ts.map +1 -0
  9. package/dist/{codegen → api/expose/mcp-build}/generator.d.ts +3 -3
  10. package/dist/api/expose/mcp-build/generator.d.ts.map +1 -0
  11. package/dist/api/expose/mcp-build/index.d.ts +8 -0
  12. package/dist/api/expose/mcp-build/index.d.ts.map +1 -0
  13. package/dist/api/expose/mcp-build/init.d.ts.map +1 -0
  14. package/dist/api/expose/mcp-build/run.d.ts.map +1 -0
  15. package/dist/api/expose/mcp-build/types.d.ts +25 -0
  16. package/dist/api/expose/mcp-build/types.d.ts.map +1 -0
  17. package/dist/api/expose/mcpServer.d.ts +75 -0
  18. package/dist/api/expose/mcpServer.d.ts.map +1 -0
  19. package/dist/api/expose/openapi.d.ts +23 -0
  20. package/dist/api/expose/openapi.d.ts.map +1 -0
  21. package/dist/api/expose/openapiHttp.d.ts +67 -0
  22. package/dist/api/expose/openapiHttp.d.ts.map +1 -0
  23. package/dist/api/main.cjs +56 -0
  24. package/dist/api/main.cjs.map +1 -0
  25. package/dist/api/main.d.ts +23 -0
  26. package/dist/api/main.d.ts.map +1 -0
  27. package/dist/api/main.js +7 -0
  28. package/dist/api/main.js.map +1 -0
  29. package/dist/api/runtimeFromConfig.d.ts +34 -0
  30. package/dist/api/runtimeFromConfig.d.ts.map +1 -0
  31. package/dist/canonicalCoreSchemas-CTW6CCFY.cjs +20 -0
  32. package/dist/canonicalCoreSchemas-CTW6CCFY.cjs.map +1 -0
  33. package/dist/canonicalCoreSchemas-YLHVHYJZ.js +3 -0
  34. package/dist/canonicalCoreSchemas-YLHVHYJZ.js.map +1 -0
  35. package/dist/{chunk-AXUNV4MK.js → chunk-5SWSNVMI.js} +3 -3
  36. package/dist/chunk-5SWSNVMI.js.map +1 -0
  37. package/dist/chunk-6F5JHLZ7.cjs +243 -0
  38. package/dist/chunk-6F5JHLZ7.cjs.map +1 -0
  39. package/dist/chunk-AE6FSNGY.js +201 -0
  40. package/dist/chunk-AE6FSNGY.js.map +1 -0
  41. package/dist/chunk-BZOKPJMP.cjs +120 -0
  42. package/dist/chunk-BZOKPJMP.cjs.map +1 -0
  43. package/dist/chunk-FA2ZEICE.cjs +1620 -0
  44. package/dist/chunk-FA2ZEICE.cjs.map +1 -0
  45. package/dist/chunk-FR2CXERF.js +239 -0
  46. package/dist/chunk-FR2CXERF.js.map +1 -0
  47. package/dist/chunk-MGEQPAHV.cjs +475 -0
  48. package/dist/chunk-MGEQPAHV.cjs.map +1 -0
  49. package/dist/{chunk-BM4EVYI5.js → chunk-PJ4RUBZL.js} +836 -122
  50. package/dist/chunk-PJ4RUBZL.js.map +1 -0
  51. package/dist/chunk-Q7KPGWC6.js +1584 -0
  52. package/dist/chunk-Q7KPGWC6.js.map +1 -0
  53. package/dist/chunk-QVH6IQKQ.js +469 -0
  54. package/dist/chunk-QVH6IQKQ.js.map +1 -0
  55. package/dist/{chunk-3YLVPZRJ.cjs → chunk-SOFUWEZ6.cjs} +3 -3
  56. package/dist/chunk-SOFUWEZ6.cjs.map +1 -0
  57. package/dist/chunk-TBMWJWQ2.js +116 -0
  58. package/dist/chunk-TBMWJWQ2.js.map +1 -0
  59. package/dist/{chunk-Z7TGIG77.cjs → chunk-ZBNRHRGM.cjs} +843 -127
  60. package/dist/chunk-ZBNRHRGM.cjs.map +1 -0
  61. package/dist/chunk-ZNJBRLKN.cjs +210 -0
  62. package/dist/chunk-ZNJBRLKN.cjs.map +1 -0
  63. package/dist/core/index.cjs +20 -0
  64. package/dist/core/index.cjs.map +1 -0
  65. package/dist/{core.d.ts → core/index.d.ts} +2 -3
  66. package/dist/core/index.d.ts.map +1 -0
  67. package/dist/core/index.js +3 -0
  68. package/dist/core/index.js.map +1 -0
  69. package/dist/core/registry/ToolRegistry.d.ts.map +1 -0
  70. package/dist/core/runtime/Budget.d.ts.map +1 -0
  71. package/dist/core/runtime/Evidence.d.ts.map +1 -0
  72. package/dist/{runtime → core/runtime}/PTCRuntime.d.ts +4 -4
  73. package/dist/core/runtime/PTCRuntime.d.ts.map +1 -0
  74. package/dist/{runtime → core/runtime}/PTCRuntimeObservability.d.ts +4 -4
  75. package/dist/core/runtime/PTCRuntimeObservability.d.ts.map +1 -0
  76. package/dist/{runtime → core/runtime}/PTCRuntimePipeline.d.ts +4 -4
  77. package/dist/core/runtime/PTCRuntimePipeline.d.ts.map +1 -0
  78. package/dist/core/runtime/PolicyEngine.d.ts.map +1 -0
  79. package/dist/core/runtime/Retry.d.ts.map +1 -0
  80. package/dist/core/runtime/SchemaValidator.d.ts.map +1 -0
  81. package/dist/core/runtime.cjs +24 -0
  82. package/dist/core/runtime.cjs.map +1 -0
  83. package/dist/core/runtime.d.ts +12 -0
  84. package/dist/core/runtime.d.ts.map +1 -0
  85. package/dist/core/runtime.js +3 -0
  86. package/dist/core/runtime.js.map +1 -0
  87. package/dist/core/types/Events.d.ts.map +1 -0
  88. package/dist/core/types/ToolIntent.d.ts.map +1 -0
  89. package/dist/{types → core/types}/ToolResult.d.ts +6 -1
  90. package/dist/core/types/ToolResult.d.ts.map +1 -0
  91. package/dist/{types → core/types}/ToolSpec.d.ts +15 -5
  92. package/dist/core/types/ToolSpec.d.ts.map +1 -0
  93. package/dist/core/types/ToolTypeHandler.d.ts +88 -0
  94. package/dist/core/types/ToolTypeHandler.d.ts.map +1 -0
  95. package/dist/{types → core/types}/index.d.ts +2 -1
  96. package/dist/core/types/index.d.ts.map +1 -0
  97. package/dist/index.cjs +249 -2749
  98. package/dist/index.cjs.map +1 -1
  99. package/dist/index.d.ts +61 -55
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +126 -2688
  102. package/dist/index.js.map +1 -1
  103. package/dist/observability/EventLog.d.ts +1 -1
  104. package/dist/observability/EventLog.d.ts.map +1 -1
  105. package/dist/tools/discoveryFactory.d.ts +117 -0
  106. package/dist/tools/discoveryFactory.d.ts.map +1 -0
  107. package/dist/tools/function/index.d.ts +10 -0
  108. package/dist/tools/function/index.d.ts.map +1 -0
  109. package/dist/{codegen/scan → tools/function}/scanner.d.ts +5 -2
  110. package/dist/{codegen/scan → tools/function}/scanner.d.ts.map +1 -1
  111. package/dist/{codegen/scan → tools/function}/schemaFromTs.d.ts +1 -1
  112. package/dist/tools/function/schemaFromTs.d.ts.map +1 -0
  113. package/dist/tools/function/types.d.ts +20 -0
  114. package/dist/tools/function/types.d.ts.map +1 -0
  115. package/dist/tools/index.d.ts +13 -0
  116. package/dist/tools/index.d.ts.map +1 -0
  117. package/dist/{discovery/load → tools/langchain}/LangChainLoader.d.ts +1 -1
  118. package/dist/tools/langchain/LangChainLoader.d.ts.map +1 -0
  119. package/dist/tools/langchain/directoryApply.d.ts +5 -0
  120. package/dist/tools/langchain/directoryApply.d.ts.map +1 -0
  121. package/dist/tools/langchain/directoryLoad.d.ts +13 -0
  122. package/dist/tools/langchain/directoryLoad.d.ts.map +1 -0
  123. package/dist/tools/langchain/index.d.ts +3 -0
  124. package/dist/tools/langchain/index.d.ts.map +1 -0
  125. package/dist/tools/langchain/scanner.d.ts +8 -0
  126. package/dist/tools/langchain/scanner.d.ts.map +1 -0
  127. package/dist/tools/langchain/types.d.ts +5 -0
  128. package/dist/tools/langchain/types.d.ts.map +1 -0
  129. package/dist/{mcp → tools/mcp}/MCPClientAdapter.d.ts +3 -3
  130. package/dist/tools/mcp/MCPClientAdapter.d.ts.map +1 -0
  131. package/dist/{discovery/load → tools/mcp}/MCPLoader.d.ts +1 -1
  132. package/dist/tools/mcp/MCPLoader.d.ts.map +1 -0
  133. package/dist/tools/mcp/MCPProcessManager.d.ts +29 -0
  134. package/dist/tools/mcp/MCPProcessManager.d.ts.map +1 -0
  135. package/dist/{mcp → tools/mcp}/connectMCP.d.ts +3 -3
  136. package/dist/tools/mcp/connectMCP.d.ts.map +1 -0
  137. package/dist/tools/mcp/directoryApply.d.ts +10 -0
  138. package/dist/tools/mcp/directoryApply.d.ts.map +1 -0
  139. package/dist/{mcp → tools/mcp}/index.d.ts +6 -1
  140. package/dist/tools/mcp/index.d.ts.map +1 -0
  141. package/dist/tools/mcp/mcpSpecToToolSpec.d.ts +8 -0
  142. package/dist/tools/mcp/mcpSpecToToolSpec.d.ts.map +1 -0
  143. package/dist/{mcp → tools/mcp}/registerMCPTools.d.ts +2 -2
  144. package/dist/tools/mcp/registerMCPTools.d.ts.map +1 -0
  145. package/dist/tools/mcp/scanner.d.ts +8 -0
  146. package/dist/tools/mcp/scanner.d.ts.map +1 -0
  147. package/dist/tools/mcp/types.d.ts +3 -0
  148. package/dist/tools/mcp/types.d.ts.map +1 -0
  149. package/dist/{discovery/load → tools/n8n}/N8nLoader.d.ts +3 -3
  150. package/dist/tools/n8n/N8nLoader.d.ts.map +1 -0
  151. package/dist/tools/n8n/directoryApply.d.ts +10 -0
  152. package/dist/tools/n8n/directoryApply.d.ts.map +1 -0
  153. package/dist/tools/n8n/index.d.ts +6 -0
  154. package/dist/tools/n8n/index.d.ts.map +1 -0
  155. package/dist/tools/n8n/scanN8n.d.ts +20 -0
  156. package/dist/tools/n8n/scanN8n.d.ts.map +1 -0
  157. package/dist/tools/n8n/types.d.ts +18 -0
  158. package/dist/tools/n8n/types.d.ts.map +1 -0
  159. package/dist/tools/scanPackage.d.ts +42 -0
  160. package/dist/tools/scanPackage.d.ts.map +1 -0
  161. package/dist/{discovery/load → tools/skill}/SkillLoader.d.ts +1 -1
  162. package/dist/tools/skill/SkillLoader.d.ts.map +1 -0
  163. package/dist/tools/skill/SkillManifest.d.ts.map +1 -0
  164. package/dist/tools/skill/SkillMdParser.d.ts.map +1 -0
  165. package/dist/tools/skill/directoryApply.d.ts +10 -0
  166. package/dist/tools/skill/directoryApply.d.ts.map +1 -0
  167. package/dist/tools/skill/index.d.ts +8 -0
  168. package/dist/tools/skill/index.d.ts.map +1 -0
  169. package/dist/tools/skill/scanSkill.d.ts +20 -0
  170. package/dist/tools/skill/scanSkill.d.ts.map +1 -0
  171. package/dist/tools/skill/types.d.ts +19 -0
  172. package/dist/tools/skill/types.d.ts.map +1 -0
  173. package/dist/tools/util/canonicalCoreSchemas.d.ts +19 -0
  174. package/dist/tools/util/canonicalCoreSchemas.d.ts.map +1 -0
  175. package/dist/tools/util/index.d.ts +13 -0
  176. package/dist/tools/util/index.d.ts.map +1 -0
  177. package/dist/tools/util/resolveEntry.d.ts +6 -0
  178. package/dist/tools/util/resolveEntry.d.ts.map +1 -0
  179. package/dist/tools/util/scanUtil.d.ts +9 -0
  180. package/dist/tools/util/scanUtil.d.ts.map +1 -0
  181. package/dist/tools/util/toolConfig.d.ts +32 -0
  182. package/dist/tools/util/toolConfig.d.ts.map +1 -0
  183. package/dist/tools/util/toolDescriptor.d.ts +92 -0
  184. package/dist/tools/util/toolDescriptor.d.ts.map +1 -0
  185. package/dist/utils/cli/index.cjs +419 -0
  186. package/dist/utils/cli/index.cjs.map +1 -0
  187. package/dist/utils/cli/index.d.ts +9 -0
  188. package/dist/utils/cli/index.d.ts.map +1 -0
  189. package/dist/utils/cli/index.js +412 -0
  190. package/dist/utils/cli/index.js.map +1 -0
  191. package/dist/utils/cli/toolRuntime.d.ts +19 -0
  192. package/dist/utils/cli/toolRuntime.d.ts.map +1 -0
  193. package/dist/utils/npmCache.d.ts +28 -0
  194. package/dist/utils/npmCache.d.ts.map +1 -0
  195. package/package.json +20 -11
  196. package/dist/chunk-3YLVPZRJ.cjs.map +0 -1
  197. package/dist/chunk-AXUNV4MK.js.map +0 -1
  198. package/dist/chunk-BM4EVYI5.js.map +0 -1
  199. package/dist/chunk-P3UEAZHK.cjs +0 -171
  200. package/dist/chunk-P3UEAZHK.cjs.map +0 -1
  201. package/dist/chunk-RPAMQCFH.js +0 -167
  202. package/dist/chunk-RPAMQCFH.js.map +0 -1
  203. package/dist/chunk-Z7TGIG77.cjs.map +0 -1
  204. package/dist/cli.cjs +0 -154
  205. package/dist/cli.cjs.map +0 -1
  206. package/dist/cli.d.ts +0 -10
  207. package/dist/cli.d.ts.map +0 -1
  208. package/dist/cli.js +0 -147
  209. package/dist/cli.js.map +0 -1
  210. package/dist/codegen/build.d.ts.map +0 -1
  211. package/dist/codegen/generator.d.ts.map +0 -1
  212. package/dist/codegen/index.d.ts +0 -21
  213. package/dist/codegen/index.d.ts.map +0 -1
  214. package/dist/codegen/init.d.ts.map +0 -1
  215. package/dist/codegen/run.d.ts.map +0 -1
  216. package/dist/codegen/scan/scanN8n.d.ts +0 -17
  217. package/dist/codegen/scan/scanN8n.d.ts.map +0 -1
  218. package/dist/codegen/scan/scanSkill.d.ts +0 -17
  219. package/dist/codegen/scan/scanSkill.d.ts.map +0 -1
  220. package/dist/codegen/scan/scanTools.d.ts +0 -31
  221. package/dist/codegen/scan/scanTools.d.ts.map +0 -1
  222. package/dist/codegen/scan/schemaFromTs.d.ts.map +0 -1
  223. package/dist/codegen/types.d.ts +0 -81
  224. package/dist/codegen/types.d.ts.map +0 -1
  225. package/dist/core.cjs +0 -20
  226. package/dist/core.cjs.map +0 -1
  227. package/dist/core.d.ts.map +0 -1
  228. package/dist/core.js +0 -3
  229. package/dist/core.js.map +0 -1
  230. package/dist/discovery/MCPProcessManager.d.ts +0 -57
  231. package/dist/discovery/MCPProcessManager.d.ts.map +0 -1
  232. package/dist/discovery/errors.d.ts +0 -13
  233. package/dist/discovery/errors.d.ts.map +0 -1
  234. package/dist/discovery/load/LangChainLoader.d.ts.map +0 -1
  235. package/dist/discovery/load/MCPLoader.d.ts.map +0 -1
  236. package/dist/discovery/load/N8nLoader.d.ts.map +0 -1
  237. package/dist/discovery/load/SkillLoader.d.ts.map +0 -1
  238. package/dist/discovery/load/SkillManifest.d.ts.map +0 -1
  239. package/dist/discovery/load/SkillMdParser.d.ts.map +0 -1
  240. package/dist/discovery/load/index.d.ts +0 -6
  241. package/dist/discovery/load/index.d.ts.map +0 -1
  242. package/dist/discovery/load/resolveEntry.d.ts +0 -7
  243. package/dist/discovery/load/resolveEntry.d.ts.map +0 -1
  244. package/dist/discovery/scan/DirectoryScanner.d.ts +0 -37
  245. package/dist/discovery/scan/DirectoryScanner.d.ts.map +0 -1
  246. package/dist/discovery/scan/scanUtil.d.ts +0 -16
  247. package/dist/discovery/scan/scanUtil.d.ts.map +0 -1
  248. package/dist/discovery/types.d.ts +0 -99
  249. package/dist/discovery/types.d.ts.map +0 -1
  250. package/dist/llm/AgentLLMAdapter.d.ts +0 -27
  251. package/dist/llm/AgentLLMAdapter.d.ts.map +0 -1
  252. package/dist/llm/LangChainToolsHub.d.ts +0 -31
  253. package/dist/llm/LangChainToolsHub.d.ts.map +0 -1
  254. package/dist/llm/OpenAICompatibleClient.d.ts +0 -64
  255. package/dist/llm/OpenAICompatibleClient.d.ts.map +0 -1
  256. package/dist/llm/ReActAgent.d.ts +0 -35
  257. package/dist/llm/ReActAgent.d.ts.map +0 -1
  258. package/dist/llm-export.cjs +0 -20
  259. package/dist/llm-export.cjs.map +0 -1
  260. package/dist/llm-export.d.ts +0 -9
  261. package/dist/llm-export.d.ts.map +0 -1
  262. package/dist/llm-export.js +0 -3
  263. package/dist/llm-export.js.map +0 -1
  264. package/dist/mcp/MCPClientAdapter.d.ts.map +0 -1
  265. package/dist/mcp/connectMCP.d.ts.map +0 -1
  266. package/dist/mcp/index.d.ts.map +0 -1
  267. package/dist/mcp/registerMCPTools.d.ts.map +0 -1
  268. package/dist/registry/ToolRegistry.d.ts.map +0 -1
  269. package/dist/report/AgentReportGenerator.d.ts +0 -53
  270. package/dist/report/AgentReportGenerator.d.ts.map +0 -1
  271. package/dist/report/agent-report-template.html +0 -362
  272. package/dist/report/index.d.ts +0 -3
  273. package/dist/report/index.d.ts.map +0 -1
  274. package/dist/report/types.d.ts +0 -101
  275. package/dist/report/types.d.ts.map +0 -1
  276. package/dist/runAgent.d.ts +0 -37
  277. package/dist/runAgent.d.ts.map +0 -1
  278. package/dist/runtime/Budget.d.ts.map +0 -1
  279. package/dist/runtime/Evidence.d.ts.map +0 -1
  280. package/dist/runtime/PTCRuntime.d.ts.map +0 -1
  281. package/dist/runtime/PTCRuntimeObservability.d.ts.map +0 -1
  282. package/dist/runtime/PTCRuntimePipeline.d.ts.map +0 -1
  283. package/dist/runtime/PolicyEngine.d.ts.map +0 -1
  284. package/dist/runtime/Retry.d.ts.map +0 -1
  285. package/dist/runtime/SchemaValidator.d.ts.map +0 -1
  286. package/dist/toolDescriptor.d.ts +0 -38
  287. package/dist/toolDescriptor.d.ts.map +0 -1
  288. package/dist/types/Events.d.ts.map +0 -1
  289. package/dist/types/ToolIntent.d.ts.map +0 -1
  290. package/dist/types/ToolResult.d.ts.map +0 -1
  291. package/dist/types/ToolSpec.d.ts.map +0 -1
  292. package/dist/types/index.d.ts.map +0 -1
  293. package/extensions/examples/README.md +0 -40
  294. package/extensions/examples/scripts/agent-tool-react-stock.mjs +0 -30
  295. package/extensions/examples/tools/instruction-only/skill/SKILL.md +0 -26
  296. package/extensions/examples/tools/web-search/mcp/mcp.json +0 -8
  297. /package/dist/{codegen → api/expose/mcp-build}/build.d.ts +0 -0
  298. /package/dist/{codegen → api/expose/mcp-build}/init.d.ts +0 -0
  299. /package/dist/{codegen → api/expose/mcp-build}/run.d.ts +0 -0
  300. /package/dist/{registry → core/registry}/ToolRegistry.d.ts +0 -0
  301. /package/dist/{runtime → core/runtime}/Budget.d.ts +0 -0
  302. /package/dist/{runtime → core/runtime}/Evidence.d.ts +0 -0
  303. /package/dist/{runtime → core/runtime}/PolicyEngine.d.ts +0 -0
  304. /package/dist/{runtime → core/runtime}/Retry.d.ts +0 -0
  305. /package/dist/{runtime → core/runtime}/SchemaValidator.d.ts +0 -0
  306. /package/dist/{types → core/types}/Events.d.ts +0 -0
  307. /package/dist/{types → core/types}/ToolIntent.d.ts +0 -0
  308. /package/dist/{discovery/load → tools/skill}/SkillManifest.d.ts +0 -0
  309. /package/dist/{discovery/load → tools/skill}/SkillMdParser.d.ts +0 -0
@@ -1,14 +1,15 @@
1
+ import { DEFAULT_OUTPUT_SCHEMA } from './chunk-5SWSNVMI.js';
2
+ import { LANGCHAIN_DIR_NAME, LANGCHAIN_KIND, MCP_KIND } from './chunk-Q7KPGWC6.js';
1
3
  import * as fs3 from 'fs/promises';
2
- import { readdir, readFile } from 'fs/promises';
3
- import * as path5 from 'path';
4
+ import { readdir, readFile, access, stat } from 'fs/promises';
5
+ import * as path9 from 'path';
4
6
  import { join, extname, relative, basename } from 'path';
5
7
  import * as fs2 from 'fs';
6
8
  import * as ts2 from 'typescript';
7
9
  import yaml from 'js-yaml';
8
- import { fileURLToPath } from 'url';
10
+ import { fileURLToPath, pathToFileURL } from 'url';
9
11
  import { spawn } from 'child_process';
10
12
 
11
- // src/codegen/init.ts
12
13
  var TEMPLATES = {
13
14
  "package.json": `{
14
15
  "name": "my-mcp-tools",
@@ -92,12 +93,12 @@ Edit \`src/tools/*.ts\` (add \`@tool\` JSDoc) and/or \`skills/*/SKILL.md\`, then
92
93
  `
93
94
  };
94
95
  async function initProject(options = {}) {
95
- const targetPath = path5.resolve(options.targetPath ?? process.cwd());
96
+ const targetPath = path9.resolve(options.targetPath ?? process.cwd());
96
97
  const filesCreated = [];
97
98
  await fs3.mkdir(targetPath, { recursive: true });
98
99
  for (const [relPath, content] of Object.entries(TEMPLATES)) {
99
- const fullPath = path5.join(targetPath, relPath);
100
- await fs3.mkdir(path5.dirname(fullPath), { recursive: true });
100
+ const fullPath = path9.join(targetPath, relPath);
101
+ await fs3.mkdir(path9.dirname(fullPath), { recursive: true });
101
102
  try {
102
103
  await fs3.access(fullPath);
103
104
  if (relPath === "package.json") continue;
@@ -113,7 +114,7 @@ async function findDirsContainingFile(rootPath, fileName) {
113
114
  await collectDirsWithFile(rootPath, fileName, found);
114
115
  return found;
115
116
  }
116
- async function collectDirsWithFile(dir, fileName, found) {
117
+ async function collectDirsWithFile(dir, fileName, acc) {
117
118
  let entries;
118
119
  try {
119
120
  const e = await readdir(dir, { withFileTypes: true });
@@ -125,22 +126,16 @@ async function collectDirsWithFile(dir, fileName, found) {
125
126
  } catch {
126
127
  return;
127
128
  }
128
- if (entries.some((x) => x.isFile && x.name === fileName)) {
129
- found.push(dir);
130
- }
129
+ if (entries.some((x) => x.isFile && x.name === fileName)) acc.push(dir);
131
130
  for (const entry of entries) {
132
- if (!entry.isDirectory || entry.name === "node_modules" || entry.name.startsWith(".")) {
133
- continue;
134
- }
135
- await collectDirsWithFile(join(dir, entry.name), fileName, found);
131
+ if (!entry.isDirectory || entry.name === "node_modules" || entry.name.startsWith(".")) continue;
132
+ await collectDirsWithFile(join(dir, entry.name), fileName, acc);
136
133
  }
137
134
  }
138
135
  function pathToToolName(sourcePath, programName) {
139
136
  const normalized = sourcePath.replace(/\\/g, "/").replace(/\.(ts|tsx|js|mjs|json)$/i, "");
140
137
  const segments = normalized.split("/").filter(Boolean);
141
- if (segments.length === 0) return programName;
142
- const pathPart = segments.join(".");
143
- return `${pathPart}.${programName}`;
138
+ return segments.length === 0 ? programName : `${segments.join(".")}.${programName}`;
144
139
  }
145
140
  function buildOutputSchemaFromReturnType(node, typeChecker, onWarn) {
146
141
  const sig = typeChecker.getSignatureFromDeclaration(node);
@@ -235,19 +230,60 @@ function typeToJsonSchema(type, typeChecker, onWarn) {
235
230
  return { type: "object" };
236
231
  }
237
232
 
238
- // src/codegen/scan/scanner.ts
233
+ // src/tools/function/types.ts
234
+ var FUNCTION_KIND = "function";
235
+
236
+ // src/tools/skill/types.ts
237
+ var SKILL_KIND = "skill";
238
+ var SKILL_DIR_NAME = "skill";
239
+
240
+ // src/tools/n8n/types.ts
241
+ var N8N_KIND = "n8n";
242
+
243
+ // src/tools/mcp/mcpSpecToToolSpec.ts
244
+ var DEFAULT_OUTPUT = { type: "object", additionalProperties: true };
245
+ function mcpSpecToToolSpec(spec, projectPath) {
246
+ const base = {
247
+ name: spec.name,
248
+ version: "1.0.0",
249
+ kind: spec.kind,
250
+ description: spec.description,
251
+ inputSchema: spec.inputSchema ?? DEFAULT_OUTPUT,
252
+ outputSchema: "outputSchema" in spec && spec.outputSchema ? spec.outputSchema : DEFAULT_OUTPUT_SCHEMA,
253
+ capabilities: [],
254
+ _meta: spec._meta,
255
+ ...spec.kind === N8N_KIND && "webhookUrl" in spec && spec.webhookUrl ? { endpoint: spec.webhookUrl } : {}
256
+ };
257
+ if (spec.kind === FUNCTION_KIND && "sourcePath" in spec && "exportName" in spec) {
258
+ base._meta = {
259
+ ...base._meta,
260
+ sourcePath: spec.sourcePath,
261
+ exportName: spec.exportName,
262
+ ...projectPath && { projectPath }
263
+ };
264
+ }
265
+ if (spec.kind === SKILL_KIND && "sourcePath" in spec && projectPath) {
266
+ base._meta = { ...base._meta, sourcePath: spec.sourcePath, projectPath };
267
+ }
268
+ if (spec.kind === N8N_KIND && "sourcePath" in spec && projectPath) {
269
+ base._meta = { ...base._meta, sourcePath: spec.sourcePath, projectPath };
270
+ }
271
+ return base;
272
+ }
273
+
274
+ // src/tools/function/scanner.ts
239
275
  var TOOL_TAG = "@tool";
240
276
  var EFFECT_VALUES = ["none", "local_write", "external_write", "destructive"];
241
277
  function scanForTools(options) {
242
- const projectPath = path5.resolve(options.projectPath);
243
- const tsconfigPath = options.tsconfigPath ?? path5.join(projectPath, "tsconfig.json");
278
+ const projectPath = path9.resolve(options.projectPath);
279
+ const tsconfigPath = options.tsconfigPath ?? path9.join(projectPath, "tsconfig.json");
244
280
  const include = options.include ?? ["**/*.ts"];
245
281
  const errors = [];
246
282
  const warnings = [];
247
283
  let config;
248
- let configPathResolved = path5.resolve(projectPath, tsconfigPath);
284
+ let configPathResolved = path9.resolve(projectPath, tsconfigPath);
249
285
  if (!fs2.existsSync(configPathResolved)) {
250
- configPathResolved = path5.join(projectPath, "tsconfig.json");
286
+ configPathResolved = path9.join(projectPath, "tsconfig.json");
251
287
  }
252
288
  if (fs2.existsSync(configPathResolved)) {
253
289
  const configFile = ts2.readConfigFile(configPathResolved, ts2.sys.readFile);
@@ -258,7 +294,7 @@ function scanForTools(options) {
258
294
  const parsed = ts2.parseJsonConfigFileContent(
259
295
  configFile.config,
260
296
  ts2.sys,
261
- path5.dirname(configPathResolved)
297
+ path9.dirname(configPathResolved)
262
298
  );
263
299
  if (parsed.errors.length) {
264
300
  for (const e of parsed.errors) {
@@ -287,7 +323,7 @@ function scanForTools(options) {
287
323
  for (const sourceFile of program.getSourceFiles()) {
288
324
  const fileName = sourceFile.fileName;
289
325
  if (fileName.includes("node_modules") || fileName.endsWith(".d.ts")) continue;
290
- if (!config.fileNames.some((f) => path5.resolve(f) === path5.resolve(fileName))) continue;
326
+ if (!config.fileNames.some((f) => path9.resolve(f) === path9.resolve(fileName))) continue;
291
327
  ts2.forEachChild(sourceFile, (node) => {
292
328
  const decl = getExportedFunctionDeclaration(node);
293
329
  if (!decl) return;
@@ -306,10 +342,10 @@ function scanForTools(options) {
306
342
  const { schema } = buildInputSchemaFromParams(func, typeChecker, onWarn);
307
343
  const inputSchema = Object.keys(schema.properties ?? {}).length > 0 ? schema : { type: "object", properties: {} };
308
344
  const outputSchema = buildOutputSchemaFromReturnType(func, typeChecker, onWarn);
309
- const sourcePath = path5.relative(projectPath, fileName) || path5.basename(fileName);
345
+ const sourcePath = path9.relative(projectPath, fileName) || path9.basename(fileName);
310
346
  const toolName = pathToToolName(sourcePath, name);
311
347
  specs.push({
312
- kind: "function",
348
+ kind: FUNCTION_KIND,
313
349
  name: toolName,
314
350
  description: description || humanize(name),
315
351
  inputSchema,
@@ -326,20 +362,20 @@ function resolveGlob(projectPath, patterns) {
326
362
  const result = [];
327
363
  const seen = /* @__PURE__ */ new Set();
328
364
  const add = (f) => {
329
- const abs = path5.resolve(f);
365
+ const abs = path9.resolve(f);
330
366
  if (f.endsWith(".ts") && !f.endsWith(".d.ts") && !seen.has(abs)) {
331
367
  seen.add(abs);
332
368
  result.push(abs);
333
369
  }
334
370
  };
335
371
  for (const p of patterns) {
336
- const full = path5.join(projectPath, p);
372
+ const full = path9.join(projectPath, p);
337
373
  if (full.includes("*")) {
338
374
  const baseDir = full.replace(/\*\*\/.*$/, "").replace(/\*.*$/, "").replace(/\/?$/, "") || ".";
339
- const dir = path5.resolve(projectPath, baseDir);
375
+ const dir = path9.resolve(projectPath, baseDir);
340
376
  if (fs2.existsSync(dir)) walk(dir, add);
341
377
  } else {
342
- const resolved = path5.resolve(projectPath, full);
378
+ const resolved = path9.resolve(projectPath, full);
343
379
  if (fs2.existsSync(resolved)) {
344
380
  if (fs2.statSync(resolved).isFile()) add(resolved);
345
381
  else walk(resolved, add);
@@ -347,14 +383,14 @@ function resolveGlob(projectPath, patterns) {
347
383
  }
348
384
  }
349
385
  if (result.length > 0) return result;
350
- const srcDir = path5.join(projectPath, "src");
386
+ const srcDir = path9.join(projectPath, "src");
351
387
  if (fs2.existsSync(srcDir)) return walkCollect(srcDir);
352
388
  return [];
353
389
  }
354
390
  function walkCollect(dir) {
355
391
  const out = [];
356
392
  walk(dir, (fullPath) => {
357
- if (fullPath.endsWith(".ts") && !fullPath.endsWith(".d.ts")) out.push(path5.resolve(fullPath));
393
+ if (fullPath.endsWith(".ts") && !fullPath.endsWith(".d.ts")) out.push(path9.resolve(fullPath));
358
394
  });
359
395
  return out;
360
396
  }
@@ -363,7 +399,7 @@ function walk(dir, visit) {
363
399
  try {
364
400
  const entries = fs2.readdirSync(dir, { withFileTypes: true });
365
401
  for (const e of entries) {
366
- const full = path5.join(dir, e.name);
402
+ const full = path9.join(dir, e.name);
367
403
  if (e.isDirectory() && !SKIP_DIRS.has(e.name)) walk(full, visit);
368
404
  else if (e.isFile()) visit(full);
369
405
  }
@@ -463,12 +499,26 @@ function getEffect(host) {
463
499
  function humanize(name) {
464
500
  return name.replace(/([A-Z])/g, " $1").replace(/^./, (s) => s.toUpperCase()).trim();
465
501
  }
502
+ function scan(projectPath, options = {}) {
503
+ const root = path9.resolve(projectPath);
504
+ const result = scanForTools({
505
+ projectPath: root,
506
+ include: options.include ?? ["**/*.ts"],
507
+ tsconfigPath: options.tsconfigPath
508
+ });
509
+ const specs = result.specs.map((s) => mcpSpecToToolSpec(s, root));
510
+ return Promise.resolve({
511
+ specs,
512
+ errors: result.errors,
513
+ warnings: result.warnings
514
+ });
515
+ }
466
516
 
467
- // src/discovery/load/SkillManifest.ts
517
+ // src/tools/skill/SkillManifest.ts
468
518
  var SkillManifestError = class extends Error {
469
- constructor(path8, field, message) {
470
- super(`SKILL.md error in ${path8}: ${message}`);
471
- this.path = path8;
519
+ constructor(path12, field, message) {
520
+ super(`SKILL.md error in ${path12}: ${message}`);
521
+ this.path = path12;
472
522
  this.field = field;
473
523
  this.name = "SkillManifestError";
474
524
  }
@@ -722,36 +772,38 @@ async function loadSkillDefinition(dirPath) {
722
772
  skillMdPath
723
773
  };
724
774
  }
725
-
726
- // src/discovery/errors.ts
727
- var DiscoveryError = class extends Error {
728
- /** Absolute path to the tool directory that caused the error */
729
- toolDir;
730
- /** Phase in which the error occurred */
731
- phase;
732
- /** The underlying cause */
733
- cause;
734
- constructor(toolDir, phase, message, cause) {
735
- super(`[${phase}] ${toolDir}: ${message}`);
736
- this.name = "DiscoveryError";
737
- this.toolDir = toolDir;
738
- this.phase = phase;
739
- this.cause = cause;
775
+ var DEFAULT_EXTENSIONS = [".js", ".mjs"];
776
+ async function resolveEntryPoint(dirPath, baseName, extensions = DEFAULT_EXTENSIONS) {
777
+ if (extensions.some((ext) => baseName.endsWith(ext))) {
778
+ const fullPath = join(dirPath, baseName);
779
+ await stat(fullPath);
780
+ return fullPath;
740
781
  }
741
- };
782
+ for (const ext of extensions) {
783
+ const fullPath = join(dirPath, `${baseName}${ext}`);
784
+ try {
785
+ await stat(fullPath);
786
+ return fullPath;
787
+ } catch {
788
+ }
789
+ }
790
+ throw new Error(
791
+ `Could not find entry point in ${dirPath}. Tried: ${extensions.map((e) => baseName + e).join(", ")}`
792
+ );
793
+ }
742
794
  var defaultInputSchema = { type: "object", properties: {}, additionalProperties: true };
743
795
  async function scanForSkill(projectPath) {
744
- const projectRoot = path5.resolve(projectPath);
796
+ const projectRoot = path9.resolve(projectPath);
745
797
  const dirs = await findDirsContainingFile(projectRoot, "SKILL.md");
746
798
  const skills = [];
747
799
  const errors = [];
748
800
  for (const dirPath of dirs) {
749
- const relativePath = path5.relative(projectRoot, dirPath) || path5.basename(dirPath);
801
+ const relativePath = path9.relative(projectRoot, dirPath) || path9.basename(dirPath);
750
802
  try {
751
803
  const skillDef = await loadSkillDefinition(dirPath);
752
804
  const name = pathToToolName(relativePath, skillDef.frontmatter.name);
753
805
  skills.push({
754
- kind: "skill",
806
+ kind: SKILL_KIND,
755
807
  name,
756
808
  description: skillDef.frontmatter.description,
757
809
  inputSchema: defaultInputSchema,
@@ -764,6 +816,15 @@ async function scanForSkill(projectPath) {
764
816
  }
765
817
  return { skills, errors };
766
818
  }
819
+ async function scan2(projectPath, _options = {}) {
820
+ const root = path9.resolve(projectPath);
821
+ const result = await scanForSkill(root);
822
+ const specs = result.skills.map((s) => mcpSpecToToolSpec(s, root));
823
+ return {
824
+ specs,
825
+ errors: result.errors.map((e) => ({ file: e.dir, message: e.message }))
826
+ };
827
+ }
767
828
  async function readWorkflowMeta(dirPath, workflowFileName = "workflow.json") {
768
829
  const workflowPath = join(dirPath, workflowFileName);
769
830
  let raw;
@@ -822,20 +883,20 @@ async function loadN8nTool(dirPath, manifest) {
822
883
  return { manifest, dirPath, workflowDef };
823
884
  }
824
885
 
825
- // src/codegen/scan/scanN8n.ts
886
+ // src/tools/n8n/scanN8n.ts
826
887
  var defaultInputSchema2 = { type: "object", properties: {}, additionalProperties: true };
827
888
  async function scanForN8n(projectPath) {
828
- const projectRoot = path5.resolve(projectPath);
889
+ const projectRoot = path9.resolve(projectPath);
829
890
  const dirs = await findDirsContainingFile(projectRoot, "workflow.json");
830
891
  const n8n = [];
831
892
  const errors = [];
832
893
  for (const dirPath of dirs) {
833
- const relativePath = path5.relative(projectRoot, dirPath) || path5.basename(dirPath);
894
+ const relativePath = path9.relative(projectRoot, dirPath) || path9.basename(dirPath);
834
895
  try {
835
896
  const { name: wfName, description: wfDesc, webhookUrl } = await readWorkflowMeta(dirPath);
836
897
  const toolName = pathToToolName(relativePath, wfName);
837
898
  n8n.push({
838
- kind: "n8n",
899
+ kind: N8N_KIND,
839
900
  name: toolName,
840
901
  description: wfDesc,
841
902
  inputSchema: defaultInputSchema2,
@@ -849,38 +910,683 @@ async function scanForN8n(projectPath) {
849
910
  }
850
911
  return { n8n, errors };
851
912
  }
913
+ async function scan3(projectPath, _options = {}) {
914
+ const root = path9.resolve(projectPath);
915
+ const result = await scanForN8n(root);
916
+ const specs = result.n8n.map((s) => mcpSpecToToolSpec(s, root));
917
+ return {
918
+ specs,
919
+ errors: result.errors.map((e) => ({ file: e.dir, message: e.message }))
920
+ };
921
+ }
922
+ async function scan4(projectPath, options = {}) {
923
+ const root = path9.resolve(projectPath);
924
+ const namespace = options.namespace ?? "dir";
925
+ const errors = [];
926
+ const scanner = new DirectoryScanner({
927
+ roots: [root],
928
+ namespace,
929
+ extensions: options.extensions,
930
+ onError: (dir, err) => {
931
+ errors.push({ file: dir, message: err.message });
932
+ options.onError?.(dir, err);
933
+ }
934
+ });
935
+ let specs;
936
+ try {
937
+ specs = await scanner.scan();
938
+ } catch (err) {
939
+ errors.push({
940
+ file: root,
941
+ message: err instanceof Error ? err.message : String(err)
942
+ });
943
+ return { specs: [], errors };
944
+ }
945
+ const filtered = specs.filter((s) => s.kind === MCP_KIND);
946
+ return { specs: filtered, errors };
947
+ }
948
+ async function scan5(projectPath, options = {}) {
949
+ const root = path9.resolve(projectPath);
950
+ const namespace = options.namespace ?? "dir";
951
+ const errors = [];
952
+ const scanner = new DirectoryScanner({
953
+ roots: [root],
954
+ namespace,
955
+ extensions: options.extensions,
956
+ onError: (dir, err) => {
957
+ errors.push({ file: dir, message: err.message });
958
+ options.onError?.(dir, err);
959
+ }
960
+ });
961
+ let specs;
962
+ try {
963
+ specs = await scanner.scan();
964
+ } catch (err) {
965
+ errors.push({
966
+ file: root,
967
+ message: err instanceof Error ? err.message : String(err)
968
+ });
969
+ return { specs: [], errors };
970
+ }
971
+ const filtered = specs.filter((s) => s.kind === LANGCHAIN_KIND);
972
+ return { specs: filtered, errors };
973
+ }
974
+ async function loadLangChainTool(dirPath, manifest, extensions) {
975
+ let entryFile;
976
+ try {
977
+ entryFile = await resolveEntryPoint(
978
+ dirPath,
979
+ manifest.entryPoint ?? "index",
980
+ extensions
981
+ );
982
+ } catch (err) {
983
+ throw new DiscoveryError(
984
+ dirPath,
985
+ "load",
986
+ `Cannot find LangChain entry point`,
987
+ err
988
+ );
989
+ }
990
+ let mod;
991
+ try {
992
+ mod = await import(pathToFileURL(entryFile).href);
993
+ } catch (err) {
994
+ throw new DiscoveryError(
995
+ dirPath,
996
+ "load",
997
+ `Failed to import ${entryFile}`,
998
+ err
999
+ );
1000
+ }
1001
+ const tool = mod.default ?? mod.tool ?? mod;
1002
+ if (!tool || typeof tool.invoke !== "function") {
1003
+ throw new DiscoveryError(
1004
+ dirPath,
1005
+ "validate",
1006
+ `Entry point must export an object with invoke() method (LangChainToolLike)`
1007
+ );
1008
+ }
1009
+ return { manifest, dirPath, impl: tool };
1010
+ }
1011
+ var DEFAULT_EXTENSIONS2 = [".js", ".mjs"];
1012
+ async function listSkillProgramFiles(dirPath, extensions = DEFAULT_EXTENSIONS2) {
1013
+ let entries;
1014
+ try {
1015
+ const dirEntries = await readdir(dirPath, { withFileTypes: true });
1016
+ entries = dirEntries.map((entry) => ({
1017
+ name: entry.name,
1018
+ isFile: entry.isFile()
1019
+ }));
1020
+ } catch {
1021
+ return [];
1022
+ }
1023
+ return entries.filter((e) => e.isFile).map((e) => e.name).filter((name) => {
1024
+ if (name.startsWith(".") || name.startsWith("_")) return false;
1025
+ if (name.includes(".test.") || name.includes(".spec.")) return false;
1026
+ return extensions.some((ext) => name.endsWith(ext));
1027
+ }).sort((a, b) => {
1028
+ if (a === "handler.js" || a === "index.js") return -1;
1029
+ if (b === "handler.js" || b === "index.js") return 1;
1030
+ return a.localeCompare(b);
1031
+ });
1032
+ }
1033
+ function isLangChainLikeTool(val) {
1034
+ return val != null && typeof val === "object" && "invoke" in val && typeof val.invoke === "function";
1035
+ }
1036
+ function isConstructable(val) {
1037
+ return typeof val === "function" && typeof val.prototype === "object";
1038
+ }
1039
+ async function loadOneSkillProgram(dirPath, manifest, entryFile, skillDef, programKey, extensions) {
1040
+ let impl;
1041
+ try {
1042
+ const fullPath = await resolveEntryPoint(dirPath, entryFile, extensions ?? [".js", ".mjs"]);
1043
+ const mod = await import(pathToFileURL(fullPath).href);
1044
+ const fn = mod.default ?? mod.handler ?? mod.Tool;
1045
+ if (isLangChainLikeTool(fn)) {
1046
+ impl = fn;
1047
+ } else if (isConstructable(fn)) {
1048
+ const instance = new fn();
1049
+ if (isLangChainLikeTool(instance)) impl = instance;
1050
+ } else if (typeof fn === "function") {
1051
+ impl = fn;
1052
+ }
1053
+ } catch {
1054
+ }
1055
+ return {
1056
+ manifest,
1057
+ dirPath,
1058
+ impl,
1059
+ skillDefinition: skillDef,
1060
+ programKey
1061
+ };
1062
+ }
1063
+ async function loadSkillTools(dirPath, manifest, extensions) {
1064
+ let skillDef;
1065
+ try {
1066
+ skillDef = await loadSkillDefinition(dirPath);
1067
+ } catch (err) {
1068
+ throw new DiscoveryError(
1069
+ dirPath,
1070
+ "load",
1071
+ `Failed to parse SKILL.md: ${err.message}`,
1072
+ err
1073
+ );
1074
+ }
1075
+ const programs = manifest.programs;
1076
+ if (programs && typeof programs === "object" && Object.keys(programs).length > 0) {
1077
+ const result = [];
1078
+ for (const [programKey, entryFile2] of Object.entries(programs)) {
1079
+ const loaded2 = await loadOneSkillProgram(
1080
+ dirPath,
1081
+ manifest,
1082
+ entryFile2,
1083
+ skillDef,
1084
+ programKey,
1085
+ extensions
1086
+ );
1087
+ result.push(loaded2);
1088
+ }
1089
+ return result;
1090
+ }
1091
+ const exts = extensions ?? DEFAULT_EXTENSIONS2;
1092
+ const files = await listSkillProgramFiles(dirPath, exts);
1093
+ if (files.length >= 2) {
1094
+ const result = [];
1095
+ for (let i = 0; i < files.length; i++) {
1096
+ const file = files[i];
1097
+ const programKey = i === 0 ? "default" : file.replace(/\.[^.]+$/, "");
1098
+ const loaded2 = await loadOneSkillProgram(
1099
+ dirPath,
1100
+ manifest,
1101
+ file,
1102
+ skillDef,
1103
+ programKey,
1104
+ extensions
1105
+ );
1106
+ result.push(loaded2);
1107
+ }
1108
+ return result;
1109
+ }
1110
+ const entryFile = manifest.entryPoint ?? files[0] ?? "handler";
1111
+ const loaded = await loadOneSkillProgram(
1112
+ dirPath,
1113
+ manifest,
1114
+ entryFile,
1115
+ skillDef,
1116
+ void 0,
1117
+ extensions
1118
+ );
1119
+ return [loaded];
1120
+ }
1121
+ async function listLangchainEntryFiles(dirPath, extensions) {
1122
+ let entries;
1123
+ try {
1124
+ const dirEntries = await readdir(dirPath, { withFileTypes: true });
1125
+ entries = dirEntries.map((entry) => ({
1126
+ name: entry.name,
1127
+ isFile: entry.isFile()
1128
+ }));
1129
+ } catch {
1130
+ return [];
1131
+ }
1132
+ return entries.filter((e) => e.isFile).map((e) => e.name).filter((name) => {
1133
+ if (name.startsWith(".") || name.startsWith("_")) return false;
1134
+ if (name.endsWith(".d.ts")) return false;
1135
+ if (name.includes(".test.") || name.includes(".spec.")) return false;
1136
+ return extensions.some((ext) => name.endsWith(ext));
1137
+ });
1138
+ }
1139
+ async function loadLangChainToolsFromDir(dirPath, dirName, manifest, strict, namespace, extensions, langchainDirName, toSpec, onError) {
1140
+ const entryFiles = await listLangchainEntryFiles(dirPath, extensions);
1141
+ if (entryFiles.length === 0) {
1142
+ if (strict) {
1143
+ throw new DiscoveryError(dirPath, "load", "No LangChain entry files found");
1144
+ }
1145
+ return [];
1146
+ }
1147
+ const specs = [];
1148
+ const useDirNameForSingle = dirName !== langchainDirName;
1149
+ for (const entryFile of entryFiles) {
1150
+ const fileManifest = { ...manifest, entryPoint: entryFile };
1151
+ try {
1152
+ const loaded = await loadLangChainTool(dirPath, fileManifest, extensions);
1153
+ const fileBase = basename(entryFile).replace(/\.[^.]+$/, "");
1154
+ const nameHint = entryFiles.length === 1 && useDirNameForSingle ? dirName : fileBase;
1155
+ specs.push(toSpec(loaded, nameHint, dirPath, namespace));
1156
+ } catch (error) {
1157
+ const err = error;
1158
+ if (err instanceof DiscoveryError && err.phase === "validate") {
1159
+ if (strict) throw err;
1160
+ continue;
1161
+ }
1162
+ onError?.(join(dirPath, entryFile), err);
1163
+ if (strict) throw err;
1164
+ }
1165
+ }
1166
+ return specs;
1167
+ }
1168
+
1169
+ // src/tools/mcp/directoryApply.ts
1170
+ function applyLoadedToSpec(spec, loaded, _manifest, _defaultDirName, _namespace) {
1171
+ if (loaded.mcpConfig?.url) spec.endpoint = loaded.mcpConfig.url;
1172
+ spec.impl = loaded.mcpConfig;
1173
+ }
1174
+ var directoryMarker = {
1175
+ kind: "mcp",
1176
+ markerFile: "mcp.json",
1177
+ defaultEntryPoint: "mcp.json"
1178
+ };
1179
+
1180
+ // src/tools/langchain/directoryApply.ts
1181
+ function applyLoadedToSpec2(spec, loaded, manifest, _defaultDirName, namespace) {
1182
+ spec.impl = loaded.impl;
1183
+ if (!manifest.name && loaded.impl) {
1184
+ const toolName = loaded.impl.name;
1185
+ if (toolName) spec.name = `${namespace}/${toolName}`;
1186
+ }
1187
+ if (!manifest.description && loaded.impl) {
1188
+ const d = loaded.impl.description;
1189
+ if (d) spec.description = d;
1190
+ }
1191
+ if (!manifest.inputSchema && loaded.impl) {
1192
+ const schema = loaded.impl.schema;
1193
+ if (schema) spec.inputSchema = schema;
1194
+ }
1195
+ }
1196
+
1197
+ // src/tools/skill/directoryApply.ts
1198
+ function applyLoadedToSpec3(spec, loaded, manifest, defaultDirName, namespace) {
1199
+ const skillDef = loaded.skillDefinition;
1200
+ if (skillDef) {
1201
+ spec.name = manifest.name ?? skillDef.frontmatter.name;
1202
+ spec.description = skillDef.frontmatter.description;
1203
+ if (loaded.programKey === "default") {
1204
+ spec.name = `${namespace}/${defaultDirName}`;
1205
+ } else if (loaded.programKey) {
1206
+ spec.name = `${namespace}/${defaultDirName}/${loaded.programKey}`;
1207
+ }
1208
+ const impl = loaded.impl;
1209
+ if (impl && typeof impl === "object" && typeof impl.invoke === "function") {
1210
+ if (impl.description != null && impl.description !== "")
1211
+ spec.description = impl.description;
1212
+ if (impl.schema != null && typeof impl.schema === "object")
1213
+ spec.inputSchema = impl.schema;
1214
+ }
1215
+ spec.impl = { ...skillDef, handler: loaded.impl };
1216
+ } else {
1217
+ spec.impl = loaded.impl;
1218
+ }
1219
+ }
1220
+ var directoryMarker2 = {
1221
+ kind: "skill",
1222
+ markerFile: "SKILL.md",
1223
+ defaultEntryPoint: "handler"
1224
+ };
1225
+
1226
+ // src/tools/n8n/directoryApply.ts
1227
+ function applyLoadedToSpec4(spec, loaded, manifest, _defaultDirName, _namespace) {
1228
+ const workflow = loaded.workflowDef;
1229
+ if (workflow?.id) spec.resourceId = String(workflow.id);
1230
+ if (!manifest.description && workflow) {
1231
+ const d = workflow.description ?? workflow.meta?.description ?? (typeof workflow.name === "string" ? workflow.name : void 0);
1232
+ if (d) spec.description = d;
1233
+ }
1234
+ spec.impl = loaded.workflowDef;
1235
+ }
1236
+ var directoryMarker3 = {
1237
+ kind: "n8n",
1238
+ markerFile: "workflow.json",
1239
+ defaultEntryPoint: "workflow.json"
1240
+ };
852
1241
 
853
- // src/codegen/scan/scanTools.ts
1242
+ // src/tools/discoveryFactory.ts
1243
+ var DiscoveryError = class extends Error {
1244
+ toolDir;
1245
+ phase;
1246
+ cause;
1247
+ constructor(toolDir, phase, message, cause) {
1248
+ super(`[${phase}] ${toolDir}: ${message}`);
1249
+ this.name = "DiscoveryError";
1250
+ this.toolDir = toolDir;
1251
+ this.phase = phase;
1252
+ this.cause = cause;
1253
+ }
1254
+ };
1255
+ var DIRECTORY_KINDS = ["mcp", "langchain", "skill", "n8n"];
1256
+ var DIRECTORY_DISCOVERABLE_KINDS = DIRECTORY_KINDS;
1257
+ var DIRECTORY_KIND_MARKERS = [
1258
+ directoryMarker2,
1259
+ directoryMarker3,
1260
+ directoryMarker
1261
+ ];
1262
+ var DIRECTORY_LOADERS = {
1263
+ mcp: async (dirPath, manifest) => [await loadMCPTool(dirPath, manifest)],
1264
+ langchain: async (dirPath, manifest, ext) => [await loadLangChainTool(dirPath, manifest, ext)],
1265
+ skill: (dirPath, manifest, ext) => loadSkillTools(dirPath, manifest, ext),
1266
+ n8n: async (dirPath, manifest) => [await loadN8nTool(dirPath, manifest)]
1267
+ };
1268
+ function getDirectoryLoader(kind) {
1269
+ const loader = DIRECTORY_LOADERS[kind];
1270
+ if (!loader) {
1271
+ throw new DiscoveryError("", "manifest", `Unknown directory tool kind: "${kind}"`);
1272
+ }
1273
+ return loader;
1274
+ }
1275
+ function applyDirectoryLoadedToSpec(spec, loaded, manifest, defaultDirName, namespace) {
1276
+ switch (manifest.kind) {
1277
+ case "mcp":
1278
+ return applyLoadedToSpec(spec, loaded);
1279
+ case "langchain":
1280
+ return applyLoadedToSpec2(spec, loaded, manifest, defaultDirName, namespace);
1281
+ case "skill":
1282
+ return applyLoadedToSpec3(spec, loaded, manifest, defaultDirName, namespace);
1283
+ case "n8n":
1284
+ return applyLoadedToSpec4(spec, loaded, manifest);
1285
+ }
1286
+ }
1287
+ async function discoverTools(type, projectPath, options = {}) {
1288
+ const root = path9.resolve(projectPath);
1289
+ switch (type) {
1290
+ case "function":
1291
+ return scan(root, options);
1292
+ case "skill":
1293
+ return scan2(root, options);
1294
+ case "n8n":
1295
+ return scan3(root, options);
1296
+ case "mcp":
1297
+ return scan4(root, options);
1298
+ case "langchain":
1299
+ return scan5(root, options);
1300
+ default: {
1301
+ const _ = type;
1302
+ return _;
1303
+ }
1304
+ }
1305
+ }
1306
+ var DEFAULT_EXTENSIONS3 = [".js", ".mjs"];
1307
+ var DirectoryScanner = class {
1308
+ roots;
1309
+ extensions;
1310
+ onError;
1311
+ constructor(options) {
1312
+ const defaultNamespace = options.namespace ?? "dir";
1313
+ this.roots = options.roots.map((root) => {
1314
+ if (typeof root === "string") {
1315
+ return { path: root, namespace: defaultNamespace };
1316
+ }
1317
+ return {
1318
+ path: root.path,
1319
+ namespace: root.namespace ?? defaultNamespace
1320
+ };
1321
+ });
1322
+ this.extensions = options.extensions ?? DEFAULT_EXTENSIONS3;
1323
+ this.onError = options.onError;
1324
+ }
1325
+ async scan() {
1326
+ const specs = [];
1327
+ for (const root of this.roots) {
1328
+ const rootSpecs = await this.scanRoot(root.path, root.namespace);
1329
+ specs.push(...rootSpecs);
1330
+ }
1331
+ return specs;
1332
+ }
1333
+ async scanRoot(rootPath, namespace) {
1334
+ return this.scanRecursive(rootPath, namespace);
1335
+ }
1336
+ async scanRecursive(dirPath, namespace) {
1337
+ const specs = [];
1338
+ let dirEntries;
1339
+ try {
1340
+ const entries = await readdir(dirPath, { withFileTypes: true });
1341
+ dirEntries = entries.map((entry) => ({
1342
+ name: entry.name,
1343
+ isDirectory: entry.isDirectory()
1344
+ }));
1345
+ } catch (error) {
1346
+ this.onError?.(dirPath, error);
1347
+ return specs;
1348
+ }
1349
+ const dirName = basename(dirPath);
1350
+ try {
1351
+ const loadedSpecs = await this.loadToolDir(dirPath, dirName, namespace);
1352
+ if (loadedSpecs.length > 0) specs.push(...loadedSpecs);
1353
+ } catch (error) {
1354
+ this.onError?.(dirPath, error);
1355
+ }
1356
+ for (const entry of dirEntries) {
1357
+ if (!entry.isDirectory) continue;
1358
+ const childPath = join(dirPath, entry.name);
1359
+ try {
1360
+ const childSpecs = await this.scanRecursive(childPath, namespace);
1361
+ specs.push(...childSpecs);
1362
+ } catch (error) {
1363
+ this.onError?.(childPath, error);
1364
+ }
1365
+ }
1366
+ return specs;
1367
+ }
1368
+ async loadToolDir(dirPath, dirName, namespace) {
1369
+ const manifestPath = join(dirPath, "tool.json");
1370
+ let manifestRaw;
1371
+ try {
1372
+ manifestRaw = await readFile(manifestPath, "utf-8");
1373
+ } catch {
1374
+ const inferred = await this.inferManifest(dirPath, dirName);
1375
+ if (!inferred) return [];
1376
+ if (inferred.kind === "langchain") {
1377
+ if (inferred.entryPoint) {
1378
+ const loaded3 = await loadLangChainTool(dirPath, inferred, this.extensions);
1379
+ return [this.toToolSpec(loaded3, dirName, dirPath, namespace)];
1380
+ }
1381
+ return loadLangChainToolsFromDir(
1382
+ dirPath,
1383
+ dirName,
1384
+ inferred,
1385
+ false,
1386
+ namespace,
1387
+ this.extensions,
1388
+ LANGCHAIN_DIR_NAME,
1389
+ (loaded3, nameHint, dp, ns) => this.toToolSpec(loaded3, nameHint, dp, ns),
1390
+ this.onError
1391
+ );
1392
+ }
1393
+ if (inferred.kind === "skill") {
1394
+ const loadedList = await loadSkillTools(dirPath, inferred, this.extensions);
1395
+ return loadedList.map(
1396
+ (loaded3) => this.toToolSpec(loaded3, dirName, dirPath, namespace)
1397
+ );
1398
+ }
1399
+ const loaded2 = await this.loadByKind(dirPath, inferred);
1400
+ return [this.toToolSpec(loaded2, dirName, dirPath, namespace)];
1401
+ }
1402
+ let manifest;
1403
+ try {
1404
+ manifest = JSON.parse(manifestRaw);
1405
+ } catch (err) {
1406
+ throw new DiscoveryError(dirPath, "manifest", "Invalid JSON in tool.json", err);
1407
+ }
1408
+ if (!manifest.kind) {
1409
+ throw new DiscoveryError(dirPath, "manifest", `tool.json must have a "kind" field`);
1410
+ }
1411
+ if (manifest.enabled === false) return [];
1412
+ if (manifest.kind === "langchain") {
1413
+ if (manifest.entryPoint) {
1414
+ const loaded2 = await loadLangChainTool(dirPath, manifest, this.extensions);
1415
+ return [this.toToolSpec(loaded2, dirName, dirPath, namespace)];
1416
+ }
1417
+ return loadLangChainToolsFromDir(
1418
+ dirPath,
1419
+ dirName,
1420
+ manifest,
1421
+ true,
1422
+ namespace,
1423
+ this.extensions,
1424
+ LANGCHAIN_DIR_NAME,
1425
+ (loaded2, nameHint, dp, ns) => this.toToolSpec(loaded2, nameHint, dp, ns),
1426
+ this.onError
1427
+ );
1428
+ }
1429
+ if (manifest.kind === "skill") {
1430
+ const loadedList = await loadSkillTools(dirPath, manifest, this.extensions);
1431
+ return loadedList.map(
1432
+ (loaded2) => this.toToolSpec(loaded2, dirName, dirPath, namespace)
1433
+ );
1434
+ }
1435
+ const loaded = await this.loadByKind(dirPath, manifest);
1436
+ return [this.toToolSpec(loaded, dirName, dirPath, namespace)];
1437
+ }
1438
+ async inferManifest(dirPath, dirName) {
1439
+ const kinds = [];
1440
+ for (const m of DIRECTORY_KIND_MARKERS) {
1441
+ if (await this.fileExists(join(dirPath, m.markerFile))) kinds.push(m.kind);
1442
+ }
1443
+ const isLangchainDir = dirName === LANGCHAIN_DIR_NAME;
1444
+ const hasLangchain = isLangchainDir ? (await listLangchainEntryFiles(dirPath, this.extensions)).length > 0 : dirName !== SKILL_DIR_NAME && await this.hasEntryPoint(dirPath, "index");
1445
+ if (hasLangchain) kinds.push("langchain");
1446
+ if (kinds.length === 0) return null;
1447
+ if (kinds.length > 1) {
1448
+ throw new DiscoveryError(
1449
+ dirPath,
1450
+ "manifest",
1451
+ `Ambiguous tool kind (found ${kinds.join(", ")}). Add tool.json to disambiguate.`
1452
+ );
1453
+ }
1454
+ const kind = kinds[0];
1455
+ const manifest = { kind };
1456
+ const marker = DIRECTORY_KIND_MARKERS.find((m) => m.kind === kind);
1457
+ if (marker) {
1458
+ manifest.entryPoint = marker.defaultEntryPoint;
1459
+ }
1460
+ if (kind === "langchain" && !isLangchainDir) manifest.entryPoint = "index";
1461
+ return manifest;
1462
+ }
1463
+ async fileExists(path12) {
1464
+ try {
1465
+ await access(path12);
1466
+ return true;
1467
+ } catch {
1468
+ return false;
1469
+ }
1470
+ }
1471
+ async hasEntryPoint(dirPath, baseName) {
1472
+ try {
1473
+ await resolveEntryPoint(dirPath, baseName, this.extensions);
1474
+ return true;
1475
+ } catch {
1476
+ return false;
1477
+ }
1478
+ }
1479
+ async loadByKind(dirPath, manifest) {
1480
+ const kind = manifest.kind;
1481
+ const loader = getDirectoryLoader(kind);
1482
+ const result = await loader(dirPath, manifest, this.extensions);
1483
+ const list = Array.isArray(result) ? result : [result];
1484
+ if (list.length === 0) {
1485
+ throw new DiscoveryError(dirPath, "load", "No tools loaded", new Error("empty"));
1486
+ }
1487
+ return list[0];
1488
+ }
1489
+ toToolSpec(loaded, dirName, dirPath, namespace) {
1490
+ const { manifest } = loaded;
1491
+ const kindDirNames = new Set(DIRECTORY_DISCOVERABLE_KINDS);
1492
+ const parentName = basename(join(dirPath, ".."));
1493
+ const isKindDir = kindDirNames.has(dirName);
1494
+ const defaultDirName = isKindDir ? parentName : dirName;
1495
+ const inferredName = isKindDir ? `${namespace}/${defaultDirName}-${dirName}` : `${namespace}/${defaultDirName}`;
1496
+ const name = manifest.name ?? inferredName;
1497
+ const spec = this.buildBaseSpec(manifest, name, dirName);
1498
+ applyDirectoryLoadedToSpec(spec, loaded, manifest, defaultDirName, namespace);
1499
+ return spec;
1500
+ }
1501
+ buildBaseSpec(manifest, name, dirName) {
1502
+ return {
1503
+ name,
1504
+ version: manifest.version ?? "1.0.0",
1505
+ kind: manifest.kind,
1506
+ description: manifest.description ?? `${manifest.kind} tool: ${dirName}`,
1507
+ tags: manifest.tags,
1508
+ inputSchema: manifest.inputSchema ?? { type: "object", additionalProperties: true },
1509
+ outputSchema: manifest.outputSchema ?? { type: "object", additionalProperties: true },
1510
+ capabilities: manifest.capabilities ?? [],
1511
+ costHints: manifest.costHints
1512
+ };
1513
+ }
1514
+ };
1515
+
1516
+ // src/tools/mcp/MCPLoader.ts
1517
+ function isCursorFormat(obj) {
1518
+ return typeof obj === "object" && obj !== null && "mcpServers" in obj && typeof obj.mcpServers === "object" && obj.mcpServers !== null;
1519
+ }
1520
+ function extractMCPConfig(parsed, toolName) {
1521
+ if (isCursorFormat(parsed)) {
1522
+ const servers = parsed.mcpServers;
1523
+ const keys = Object.keys(servers);
1524
+ if (keys.length === 0) {
1525
+ return {};
1526
+ }
1527
+ const name = toolName && keys.includes(toolName) ? toolName : keys[0];
1528
+ return servers[name];
1529
+ }
1530
+ return parsed;
1531
+ }
1532
+ async function loadMCPTool(dirPath, manifest) {
1533
+ const mcpPath = join(dirPath, manifest.entryPoint ?? "mcp.json");
1534
+ let raw;
1535
+ try {
1536
+ raw = await readFile(mcpPath, "utf-8");
1537
+ } catch (err) {
1538
+ throw new DiscoveryError(
1539
+ dirPath,
1540
+ "load",
1541
+ `Failed to read MCP config: ${mcpPath}`,
1542
+ err
1543
+ );
1544
+ }
1545
+ let parsed;
1546
+ try {
1547
+ parsed = JSON.parse(raw);
1548
+ } catch (err) {
1549
+ throw new DiscoveryError(
1550
+ dirPath,
1551
+ "load",
1552
+ `Invalid JSON in ${mcpPath}`,
1553
+ err
1554
+ );
1555
+ }
1556
+ const baseName = manifest.name?.split("/").pop();
1557
+ const config = extractMCPConfig(parsed, baseName);
1558
+ if (!config.command && !config.url) {
1559
+ throw new DiscoveryError(
1560
+ dirPath,
1561
+ "validate",
1562
+ `mcp.json must have either "command" or "url" field`
1563
+ );
1564
+ }
1565
+ return { manifest, dirPath, mcpConfig: config };
1566
+ }
854
1567
  async function scanForAllTools(projectPath, options = {}) {
855
1568
  const include = options.include ?? ["**/*.ts"];
856
1569
  const tsconfigPath = options.tsconfigPath;
857
1570
  const includeN8n = options.includeN8n === true;
858
- const [functionResult, skillResult, n8nResult] = await Promise.all([
859
- Promise.resolve(scanForTools({ projectPath, include, tsconfigPath })),
860
- scanForSkill(projectPath),
861
- includeN8n ? scanForN8n(projectPath) : Promise.resolve({ n8n: [], errors: [] })
1571
+ const opts = { include, tsconfigPath };
1572
+ const results = await Promise.all([
1573
+ discoverTools("function", projectPath, opts),
1574
+ discoverTools("skill", projectPath, opts),
1575
+ ...includeN8n ? [discoverTools("n8n", projectPath, opts)] : []
862
1576
  ]);
863
- const specs = [
864
- ...functionResult.specs,
865
- ...skillResult.skills,
866
- ...n8nResult.n8n
867
- ];
868
- const errors = [
869
- ...functionResult.errors,
870
- ...skillResult.errors.map((e) => ({ file: e.dir, message: e.message })),
871
- ...includeN8n ? n8nResult.errors.map((e) => ({ file: e.dir, message: e.message })) : []
872
- ];
873
- const warnings = [...functionResult.warnings];
1577
+ const specs = results.flatMap((r) => r.specs);
1578
+ const errors = results.flatMap((r) => r.errors);
1579
+ const warnings = results.flatMap((r) => r.warnings ?? []);
874
1580
  return { specs, errors, warnings };
875
1581
  }
876
- var __dirname$1 = path5.dirname(fileURLToPath(import.meta.url));
1582
+ var __dirname$1 = path9.dirname(fileURLToPath(import.meta.url));
877
1583
  async function loadTemplate(name) {
878
1584
  for (const dir of [
879
- path5.join(__dirname$1, "templates"),
880
- path5.join(__dirname$1, "..", "templates")
1585
+ path9.join(__dirname$1, "templates"),
1586
+ path9.join(__dirname$1, "..", "templates")
881
1587
  ]) {
882
1588
  try {
883
- return await fs3.readFile(path5.join(dir, name), "utf-8");
1589
+ return await fs3.readFile(path9.join(dir, name), "utf-8");
884
1590
  } catch {
885
1591
  continue;
886
1592
  }
@@ -895,14 +1601,14 @@ var TEMPLATE_NAMES = {
895
1601
  };
896
1602
  function buildToolIndexCases(specs, fromGeneratedToProject) {
897
1603
  return specs.map((s) => {
898
- const modPath = path5.join(fromGeneratedToProject, s.sourcePath).replace(/\\/g, "/");
899
- return ` case "${s.name}": return (await import("${modPath}")).${s.exportName};`;
1604
+ const modPath = path9.join(fromGeneratedToProject, s._meta.sourcePath).replace(/\\/g, "/");
1605
+ return ` case "${s.name}": return (await import("${modPath}")).${s._meta.exportName};`;
900
1606
  }).join("\n");
901
1607
  }
902
1608
  function buildSkillInvokerCases(specs, fromGeneratedToProject) {
903
1609
  return specs.map((s) => {
904
- const handlerPath = path5.join(fromGeneratedToProject, s.sourcePath, "handler").replace(/\\/g, "/");
905
- const descEscaped = s.description.replace(/"/g, '\\"');
1610
+ const handlerPath = path9.join(fromGeneratedToProject, s._meta.sourcePath, "handler").replace(/\\/g, "/");
1611
+ const descEscaped = (s.description ?? "").replace(/"/g, '\\"');
906
1612
  return ` case "${s.name}": {
907
1613
  const mod = await import("${handlerPath}.js").catch(() => import("${handlerPath}.mjs"));
908
1614
  const fn = mod.default ?? mod.handler;
@@ -915,7 +1621,8 @@ function buildSkillInvokerCases(specs, fromGeneratedToProject) {
915
1621
  }
916
1622
  function buildN8nInvokerCases(specs) {
917
1623
  return specs.map((s) => {
918
- const url = s.webhookUrl ? `"${s.webhookUrl}"` : "process.env.N8N_WEBHOOK_" + s.name.replace(/[^a-zA-Z0-9]/g, "_").toUpperCase() + " ?? null";
1624
+ const webhookUrl = s.endpoint;
1625
+ const url = webhookUrl ? `"${webhookUrl}"` : "process.env.N8N_WEBHOOK_" + s.name.replace(/[^a-zA-Z0-9]/g, "_").toUpperCase() + " ?? null";
919
1626
  return ` case "${s.name}": {
920
1627
  const url = ${url};
921
1628
  if (!url) throw new Error("n8n webhook not configured for ${s.name}. Set N8N_WEBHOOK_* or add webhook to workflow.");
@@ -928,32 +1635,39 @@ function buildN8nInvokerCases(specs) {
928
1635
  async function generate(options) {
929
1636
  const { specs, outDir, projectPath } = options;
930
1637
  await fs3.mkdir(outDir, { recursive: true });
931
- const functionSpecs = specs.filter((s) => s.kind === "function");
932
- const skillSpecs = specs.filter((s) => s.kind === "skill");
933
- const n8nSpecs = specs.filter((s) => s.kind === "n8n");
1638
+ const functionSpecs = specs.filter(
1639
+ (s) => s.kind === FUNCTION_KIND && s._meta?.sourcePath != null && s._meta?.exportName != null
1640
+ );
1641
+ const skillSpecs = specs.filter(
1642
+ (s) => s.kind === SKILL_KIND && s._meta?.sourcePath != null
1643
+ );
1644
+ const n8nSpecs = specs.filter((s) => s.kind === N8N_KIND);
934
1645
  const toolSpecsJson = specs.map((s) => ({
935
1646
  kind: s.kind,
936
1647
  name: s.name,
937
1648
  description: s.description,
938
1649
  inputSchema: s.inputSchema,
939
- ...s.kind === "function" && {
1650
+ ...s.kind === FUNCTION_KIND && s._meta?.sourcePath != null && s._meta?.exportName != null && {
940
1651
  outputSchema: s.outputSchema ?? { type: "object", additionalProperties: true },
941
- sourcePath: s.sourcePath,
942
- exportName: s.exportName
1652
+ sourcePath: s._meta.sourcePath,
1653
+ exportName: s._meta.exportName
943
1654
  },
944
1655
  _meta: s._meta,
945
- ...s.kind === "skill" && { sourcePath: s.sourcePath },
946
- ...s.kind === "n8n" && { sourcePath: s.sourcePath, webhookUrl: s.webhookUrl }
1656
+ ...s.kind === SKILL_KIND && s._meta?.sourcePath != null && { sourcePath: s._meta.sourcePath },
1657
+ ...s.kind === N8N_KIND && {
1658
+ sourcePath: s._meta?.sourcePath,
1659
+ webhookUrl: s.endpoint
1660
+ }
947
1661
  }));
948
1662
  await fs3.writeFile(
949
- path5.join(outDir, "tool-specs.json"),
1663
+ path9.join(outDir, "tool-specs.json"),
950
1664
  JSON.stringify(toolSpecsJson, null, 2),
951
1665
  "utf-8"
952
1666
  );
953
- const configJson = { projectPath: path5.resolve(projectPath) };
954
- await fs3.writeFile(path5.join(outDir, "config.json"), JSON.stringify(configJson, null, 2), "utf-8");
955
- const rel = path5.relative(outDir, projectPath) || ".";
956
- const fromGeneratedToProject = rel.split(path5.sep).length ? rel : ".";
1667
+ const configJson = { projectPath: path9.resolve(projectPath) };
1668
+ await fs3.writeFile(path9.join(outDir, "config.json"), JSON.stringify(configJson, null, 2), "utf-8");
1669
+ const rel = path9.relative(outDir, projectPath) || ".";
1670
+ const fromGeneratedToProject = rel.split(path9.sep).length ? rel : ".";
957
1671
  const [mcpServerTemplate, toolIndexTemplate, skillInvokerTemplate, n8nInvokerTemplate] = await Promise.all([
958
1672
  loadTemplate(TEMPLATE_NAMES.mcpServer),
959
1673
  loadTemplate(TEMPLATE_NAMES.toolIndex),
@@ -961,21 +1675,21 @@ async function generate(options) {
961
1675
  loadTemplate(TEMPLATE_NAMES.n8nInvoker)
962
1676
  ]);
963
1677
  const toolIndexTs = toolIndexTemplate.replace("{{CASES}}", buildToolIndexCases(functionSpecs, fromGeneratedToProject));
964
- await fs3.writeFile(path5.join(outDir, "tool-index.ts"), toolIndexTs, "utf-8");
1678
+ await fs3.writeFile(path9.join(outDir, "tool-index.ts"), toolIndexTs, "utf-8");
965
1679
  const skillCases = buildSkillInvokerCases(skillSpecs, fromGeneratedToProject);
966
1680
  const skillDefaultCase = skillSpecs.length === 0 ? "default: throw new Error('Unknown skill: ' + name);" : 'default: throw new Error("Unknown skill: " + name);';
967
1681
  const skillInvokerTs = skillInvokerTemplate.replace("{{CASES}}", skillCases).replace("{{DEFAULT_CASE}}", skillDefaultCase);
968
- await fs3.writeFile(path5.join(outDir, "skill-invoker.ts"), skillInvokerTs, "utf-8");
1682
+ await fs3.writeFile(path9.join(outDir, "skill-invoker.ts"), skillInvokerTs, "utf-8");
969
1683
  const n8nCases = buildN8nInvokerCases(n8nSpecs);
970
1684
  const n8nDefaultCase = n8nSpecs.length === 0 ? "default: throw new Error('Unknown n8n tool: ' + name);" : 'default: throw new Error("Unknown n8n tool: " + name);';
971
1685
  const n8nInvokerTs = n8nInvokerTemplate.replace("{{CASES}}", n8nCases).replace("{{DEFAULT_CASE}}", n8nDefaultCase);
972
- await fs3.writeFile(path5.join(outDir, "n8n-invoker.ts"), n8nInvokerTs, "utf-8");
973
- await fs3.writeFile(path5.join(outDir, "mcp-server.ts"), mcpServerTemplate, "utf-8");
1686
+ await fs3.writeFile(path9.join(outDir, "n8n-invoker.ts"), n8nInvokerTs, "utf-8");
1687
+ await fs3.writeFile(path9.join(outDir, "mcp-server.ts"), mcpServerTemplate, "utf-8");
974
1688
  const mcpJson = {
975
1689
  command: "npx",
976
- args: ["-y", "tsx", path5.join(outDir, "mcp-server.ts")]
1690
+ args: ["-y", "tsx", path9.join(outDir, "mcp-server.ts")]
977
1691
  };
978
- await fs3.writeFile(path5.join(outDir, "mcp.json"), JSON.stringify(mcpJson, null, 2), "utf-8");
1692
+ await fs3.writeFile(path9.join(outDir, "mcp.json"), JSON.stringify(mcpJson, null, 2), "utf-8");
979
1693
  const packageJson = {
980
1694
  name: "function-tools-mcp",
981
1695
  version: "1.0.0",
@@ -989,17 +1703,17 @@ async function generate(options) {
989
1703
  tsx: ">=4.0.0"
990
1704
  }
991
1705
  };
992
- await fs3.writeFile(path5.join(outDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
1706
+ await fs3.writeFile(path9.join(outDir, "package.json"), JSON.stringify(packageJson, null, 2), "utf-8");
993
1707
  return {
994
- entryPath: path5.join(outDir, "mcp-server.ts"),
995
- mcpJsonPath: path5.join(outDir, "mcp.json")
1708
+ entryPath: path9.join(outDir, "mcp-server.ts"),
1709
+ mcpJsonPath: path9.join(outDir, "mcp.json")
996
1710
  };
997
1711
  }
998
1712
 
999
- // src/codegen/build.ts
1713
+ // src/api/expose/mcp-build/build.ts
1000
1714
  async function buildMcpPackage(options = {}) {
1001
- const projectPath = path5.resolve(options.projectPath ?? process.cwd());
1002
- const outDir = path5.resolve(projectPath, options.outDir ?? "dist");
1715
+ const projectPath = path9.resolve(options.projectPath ?? process.cwd());
1716
+ const outDir = path9.resolve(projectPath, options.outDir ?? "dist");
1003
1717
  const include = options.include ?? ["**/*.ts"];
1004
1718
  const tsconfigPath = options.tsconfigPath;
1005
1719
  const scanResult = await scanForAllTools(projectPath, {
@@ -1033,12 +1747,12 @@ var buildFunctionToTool = buildMcpPackage;
1033
1747
  async function runMcpServer(options = {}) {
1034
1748
  const base = options.path ?? process.cwd();
1035
1749
  const candidates = [
1036
- path5.join(base, "mcp-server.ts"),
1037
- path5.join(base, "mcp-server.js"),
1038
- path5.join(base, "dist", "mcp-server.ts"),
1039
- path5.join(base, "dist", "mcp-server.js"),
1040
- path5.join(base, "generated", "mcp-server.ts"),
1041
- path5.join(base, "generated", "mcp-server.js")
1750
+ path9.join(base, "mcp-server.ts"),
1751
+ path9.join(base, "mcp-server.js"),
1752
+ path9.join(base, "dist", "mcp-server.ts"),
1753
+ path9.join(base, "dist", "mcp-server.js"),
1754
+ path9.join(base, "generated", "mcp-server.ts"),
1755
+ path9.join(base, "generated", "mcp-server.js")
1042
1756
  ];
1043
1757
  let entry = "";
1044
1758
  for (const p of candidates) {
@@ -1054,8 +1768,8 @@ async function runMcpServer(options = {}) {
1054
1768
  `MCP entrypoint not found. Run "agent-tool build" first, or pass --path to a directory containing mcp-server.ts. Tried: ${candidates.join(", ")}`
1055
1769
  );
1056
1770
  }
1057
- const dir = path5.dirname(entry);
1058
- const child = spawn("npx", ["-y", "tsx", path5.basename(entry)], {
1771
+ const dir = path9.dirname(entry);
1772
+ const child = spawn("npx", ["-y", "tsx", path9.basename(entry)], {
1059
1773
  cwd: dir,
1060
1774
  stdio: ["pipe", "pipe", "inherit"],
1061
1775
  shell: false
@@ -1064,6 +1778,6 @@ async function runMcpServer(options = {}) {
1064
1778
  }
1065
1779
  var runGeneratedMCP = runMcpServer;
1066
1780
 
1067
- export { DiscoveryError, SkillManifestError, buildFunctionToTool, buildMcpPackage, initProject, loadN8nTool, loadSkillDefinition, parseSkillMd, runGeneratedMCP, runMcpServer, scanForTools, scanSkillResources, validateFrontmatter };
1068
- //# sourceMappingURL=chunk-BM4EVYI5.js.map
1069
- //# sourceMappingURL=chunk-BM4EVYI5.js.map
1781
+ export { DirectoryScanner, DiscoveryError, SkillManifestError, buildFunctionToTool, buildMcpPackage, initProject, loadMCPTool, loadSkillDefinition, parseSkillMd, runGeneratedMCP, runMcpServer, scan, scanForTools, scanSkillResources, validateFrontmatter };
1782
+ //# sourceMappingURL=chunk-PJ4RUBZL.js.map
1783
+ //# sourceMappingURL=chunk-PJ4RUBZL.js.map