@cursor/july 0.1.1

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 (623) hide show
  1. package/AGENTS.md +290 -0
  2. package/LICENSE.md +3 -0
  3. package/README.md +1233 -0
  4. package/dist/ab.d.ts +290 -0
  5. package/dist/ab.d.ts.map +1 -0
  6. package/dist/ab.js +386 -0
  7. package/dist/bin/agent-serve.d.ts +15 -0
  8. package/dist/bin/agent-serve.d.ts.map +1 -0
  9. package/dist/bin/agent-serve.js +754 -0
  10. package/dist/channels/github/api.d.ts +101 -0
  11. package/dist/channels/github/api.d.ts.map +1 -0
  12. package/dist/channels/github/api.js +229 -0
  13. package/dist/channels/github/auth.d.ts +67 -0
  14. package/dist/channels/github/auth.d.ts.map +1 -0
  15. package/dist/channels/github/auth.js +239 -0
  16. package/dist/channels/github/binding.d.ts +73 -0
  17. package/dist/channels/github/binding.d.ts.map +1 -0
  18. package/dist/channels/github/binding.js +114 -0
  19. package/dist/channels/github/defaults.d.ts +24 -0
  20. package/dist/channels/github/defaults.d.ts.map +1 -0
  21. package/dist/channels/github/defaults.js +100 -0
  22. package/dist/channels/github/events.d.ts +18 -0
  23. package/dist/channels/github/events.d.ts.map +1 -0
  24. package/dist/channels/github/events.js +59 -0
  25. package/dist/channels/github/forward.d.ts +137 -0
  26. package/dist/channels/github/forward.d.ts.map +1 -0
  27. package/dist/channels/github/forward.js +271 -0
  28. package/dist/channels/github/github-channel.d.ts +127 -0
  29. package/dist/channels/github/github-channel.d.ts.map +1 -0
  30. package/dist/channels/github/github-channel.js +1688 -0
  31. package/dist/channels/github/index.d.ts +52 -0
  32. package/dist/channels/github/index.d.ts.map +1 -0
  33. package/dist/channels/github/index.js +51 -0
  34. package/dist/channels/github/replay.d.ts +115 -0
  35. package/dist/channels/github/replay.d.ts.map +1 -0
  36. package/dist/channels/github/replay.js +282 -0
  37. package/dist/channels/github/state.d.ts +26 -0
  38. package/dist/channels/github/state.d.ts.map +1 -0
  39. package/dist/channels/github/state.js +50 -0
  40. package/dist/channels/github/types.d.ts +385 -0
  41. package/dist/channels/github/types.d.ts.map +1 -0
  42. package/dist/channels/github/types.js +1 -0
  43. package/dist/channels/slack/api.d.ts +117 -0
  44. package/dist/channels/slack/api.d.ts.map +1 -0
  45. package/dist/channels/slack/api.js +437 -0
  46. package/dist/channels/slack/approvals.d.ts +32 -0
  47. package/dist/channels/slack/approvals.d.ts.map +1 -0
  48. package/dist/channels/slack/approvals.js +157 -0
  49. package/dist/channels/slack/assistant.d.ts +23 -0
  50. package/dist/channels/slack/assistant.d.ts.map +1 -0
  51. package/dist/channels/slack/assistant.js +67 -0
  52. package/dist/channels/slack/auth.d.ts +40 -0
  53. package/dist/channels/slack/auth.d.ts.map +1 -0
  54. package/dist/channels/slack/auth.js +71 -0
  55. package/dist/channels/slack/channel-watch.d.ts +46 -0
  56. package/dist/channels/slack/channel-watch.d.ts.map +1 -0
  57. package/dist/channels/slack/channel-watch.js +180 -0
  58. package/dist/channels/slack/constants.d.ts +17 -0
  59. package/dist/channels/slack/constants.d.ts.map +1 -0
  60. package/dist/channels/slack/constants.js +27 -0
  61. package/dist/channels/slack/credentials.d.ts +35 -0
  62. package/dist/channels/slack/credentials.d.ts.map +1 -0
  63. package/dist/channels/slack/credentials.js +88 -0
  64. package/dist/channels/slack/cursor-account.d.ts +76 -0
  65. package/dist/channels/slack/cursor-account.d.ts.map +1 -0
  66. package/dist/channels/slack/cursor-account.js +88 -0
  67. package/dist/channels/slack/defaults.d.ts +32 -0
  68. package/dist/channels/slack/defaults.d.ts.map +1 -0
  69. package/dist/channels/slack/defaults.js +380 -0
  70. package/dist/channels/slack/dispatch.d.ts +43 -0
  71. package/dist/channels/slack/dispatch.d.ts.map +1 -0
  72. package/dist/channels/slack/dispatch.js +185 -0
  73. package/dist/channels/slack/doctor.d.ts +24 -0
  74. package/dist/channels/slack/doctor.d.ts.map +1 -0
  75. package/dist/channels/slack/doctor.js +115 -0
  76. package/dist/channels/slack/event-id-dedupe.d.ts +10 -0
  77. package/dist/channels/slack/event-id-dedupe.d.ts.map +1 -0
  78. package/dist/channels/slack/event-id-dedupe.js +23 -0
  79. package/dist/channels/slack/inbound.d.ts +41 -0
  80. package/dist/channels/slack/inbound.d.ts.map +1 -0
  81. package/dist/channels/slack/inbound.js +166 -0
  82. package/dist/channels/slack/index.d.ts +45 -0
  83. package/dist/channels/slack/index.d.ts.map +1 -0
  84. package/dist/channels/slack/index.js +44 -0
  85. package/dist/channels/slack/init.d.ts +32 -0
  86. package/dist/channels/slack/init.d.ts.map +1 -0
  87. package/dist/channels/slack/init.js +82 -0
  88. package/dist/channels/slack/interactive.d.ts +19 -0
  89. package/dist/channels/slack/interactive.d.ts.map +1 -0
  90. package/dist/channels/slack/interactive.js +142 -0
  91. package/dist/channels/slack/links.d.ts +10 -0
  92. package/dist/channels/slack/links.d.ts.map +1 -0
  93. package/dist/channels/slack/links.js +19 -0
  94. package/dist/channels/slack/live-delivery.d.ts +75 -0
  95. package/dist/channels/slack/live-delivery.d.ts.map +1 -0
  96. package/dist/channels/slack/live-delivery.js +143 -0
  97. package/dist/channels/slack/log.d.ts +25 -0
  98. package/dist/channels/slack/log.d.ts.map +1 -0
  99. package/dist/channels/slack/log.js +47 -0
  100. package/dist/channels/slack/manifest.d.ts +57 -0
  101. package/dist/channels/slack/manifest.d.ts.map +1 -0
  102. package/dist/channels/slack/manifest.js +110 -0
  103. package/dist/channels/slack/pr-ref.d.ts +18 -0
  104. package/dist/channels/slack/pr-ref.d.ts.map +1 -0
  105. package/dist/channels/slack/pr-ref.js +36 -0
  106. package/dist/channels/slack/setup.d.ts +14 -0
  107. package/dist/channels/slack/setup.d.ts.map +1 -0
  108. package/dist/channels/slack/setup.js +86 -0
  109. package/dist/channels/slack/slack-channel.d.ts +15 -0
  110. package/dist/channels/slack/slack-channel.d.ts.map +1 -0
  111. package/dist/channels/slack/slack-channel.js +281 -0
  112. package/dist/channels/slack/socket-mode.d.ts +26 -0
  113. package/dist/channels/slack/socket-mode.d.ts.map +1 -0
  114. package/dist/channels/slack/socket-mode.js +116 -0
  115. package/dist/channels/slack/stream.d.ts +26 -0
  116. package/dist/channels/slack/stream.d.ts.map +1 -0
  117. package/dist/channels/slack/stream.js +39 -0
  118. package/dist/channels/slack/tool-approval-events.d.ts +33 -0
  119. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -0
  120. package/dist/channels/slack/tool-approval-events.js +129 -0
  121. package/dist/channels/slack/types.d.ts +326 -0
  122. package/dist/channels/slack/types.d.ts.map +1 -0
  123. package/dist/channels/slack/types.js +4 -0
  124. package/dist/channels.d.ts +116 -0
  125. package/dist/channels.d.ts.map +1 -0
  126. package/dist/channels.js +294 -0
  127. package/dist/connections.d.ts +75 -0
  128. package/dist/connections.d.ts.map +1 -0
  129. package/dist/connections.js +75 -0
  130. package/dist/docs/404.html +22 -0
  131. package/dist/docs/ab.html +87 -0
  132. package/dist/docs/assets/ab.md.COdXkces.js +63 -0
  133. package/dist/docs/assets/ab.md.COdXkces.lean.js +1 -0
  134. package/dist/docs/assets/app.DqfFEmJd.js +1 -0
  135. package/dist/docs/assets/building-with-agents.md.CJCtZCyi.js +13 -0
  136. package/dist/docs/assets/building-with-agents.md.CJCtZCyi.lean.js +1 -0
  137. package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +1 -0
  138. package/dist/docs/assets/chunks/VPLocalSearchBox.BaLEdS15.js +9 -0
  139. package/dist/docs/assets/chunks/framework.CAZyNGu9.js +19 -0
  140. package/dist/docs/assets/chunks/theme.CZRvu_0q.js +2 -0
  141. package/dist/docs/assets/concepts.md.Cfb9b-k1.js +4 -0
  142. package/dist/docs/assets/concepts.md.Cfb9b-k1.lean.js +1 -0
  143. package/dist/docs/assets/deployment.md.Dx1TYNk5.js +14 -0
  144. package/dist/docs/assets/deployment.md.Dx1TYNk5.lean.js +1 -0
  145. package/dist/docs/assets/evals.md.DPZ_MAnI.js +85 -0
  146. package/dist/docs/assets/evals.md.DPZ_MAnI.lean.js +1 -0
  147. package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.js +10 -0
  148. package/dist/docs/assets/guides_agent-to-agent.md.CrtrsySy.lean.js +1 -0
  149. package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.js +9 -0
  150. package/dist/docs/assets/guides_cloud-runtime.md.CYlNMTNp.lean.js +1 -0
  151. package/dist/docs/assets/guides_github.md.DwbKhCeS.js +20 -0
  152. package/dist/docs/assets/guides_github.md.DwbKhCeS.lean.js +1 -0
  153. package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.js +28 -0
  154. package/dist/docs/assets/guides_human-in-the-loop.md.Dvuctx7s.lean.js +1 -0
  155. package/dist/docs/assets/guides_slack.md.bv41fHfW.js +37 -0
  156. package/dist/docs/assets/guides_slack.md.bv41fHfW.lean.js +1 -0
  157. package/dist/docs/assets/guides_webhooks.md.hFTik3lf.js +50 -0
  158. package/dist/docs/assets/guides_webhooks.md.hFTik3lf.lean.js +1 -0
  159. package/dist/docs/assets/hillclimbing.md.DHNast08.js +4 -0
  160. package/dist/docs/assets/hillclimbing.md.DHNast08.lean.js +1 -0
  161. package/dist/docs/assets/index.md.BPKcj5AI.js +20 -0
  162. package/dist/docs/assets/index.md.BPKcj5AI.lean.js +1 -0
  163. package/dist/docs/assets/inter-italic-cyrillic-ext.r48I6akx.woff2 +0 -0
  164. package/dist/docs/assets/inter-italic-cyrillic.By2_1cv3.woff2 +0 -0
  165. package/dist/docs/assets/inter-italic-greek-ext.1u6EdAuj.woff2 +0 -0
  166. package/dist/docs/assets/inter-italic-greek.DJ8dCoTZ.woff2 +0 -0
  167. package/dist/docs/assets/inter-italic-latin-ext.CN1xVJS-.woff2 +0 -0
  168. package/dist/docs/assets/inter-italic-latin.C2AdPX0b.woff2 +0 -0
  169. package/dist/docs/assets/inter-italic-vietnamese.BSbpV94h.woff2 +0 -0
  170. package/dist/docs/assets/inter-roman-cyrillic-ext.BBPuwvHQ.woff2 +0 -0
  171. package/dist/docs/assets/inter-roman-cyrillic.C5lxZ8CY.woff2 +0 -0
  172. package/dist/docs/assets/inter-roman-greek-ext.CqjqNYQ-.woff2 +0 -0
  173. package/dist/docs/assets/inter-roman-greek.BBVDIX6e.woff2 +0 -0
  174. package/dist/docs/assets/inter-roman-latin-ext.4ZJIpNVo.woff2 +0 -0
  175. package/dist/docs/assets/inter-roman-latin.Di8DUHzh.woff2 +0 -0
  176. package/dist/docs/assets/inter-roman-vietnamese.BjW4sHH5.woff2 +0 -0
  177. package/dist/docs/assets/quickstart.md.tVPiGK_L.js +35 -0
  178. package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +1 -0
  179. package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.js +34 -0
  180. package/dist/docs/assets/reference_agent-config.md.Bpd7HQwf.lean.js +1 -0
  181. package/dist/docs/assets/reference_channels.md.D7JTR03W.js +53 -0
  182. package/dist/docs/assets/reference_channels.md.D7JTR03W.lean.js +1 -0
  183. package/dist/docs/assets/reference_cli.md.DA730zCu.js +33 -0
  184. package/dist/docs/assets/reference_cli.md.DA730zCu.lean.js +1 -0
  185. package/dist/docs/assets/reference_connections.md.C3vNH_DE.js +26 -0
  186. package/dist/docs/assets/reference_connections.md.C3vNH_DE.lean.js +1 -0
  187. package/dist/docs/assets/reference_hooks.md.BCEc3MyM.js +12 -0
  188. package/dist/docs/assets/reference_hooks.md.BCEc3MyM.lean.js +1 -0
  189. package/dist/docs/assets/reference_http-api.md.DBAahtdz.js +11 -0
  190. package/dist/docs/assets/reference_http-api.md.DBAahtdz.lean.js +1 -0
  191. package/dist/docs/assets/reference_instructions.md.BC05LEQ8.js +12 -0
  192. package/dist/docs/assets/reference_instructions.md.BC05LEQ8.lean.js +1 -0
  193. package/dist/docs/assets/reference_playground.md.CPZhfYaO.js +1 -0
  194. package/dist/docs/assets/reference_playground.md.CPZhfYaO.lean.js +1 -0
  195. package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.js +31 -0
  196. package/dist/docs/assets/reference_project-layout.md.Bd_CKtNS.lean.js +1 -0
  197. package/dist/docs/assets/reference_schedules.md.D7qijxLk.js +82 -0
  198. package/dist/docs/assets/reference_schedules.md.D7qijxLk.lean.js +1 -0
  199. package/dist/docs/assets/reference_sessions.md.DdjWabnN.js +8 -0
  200. package/dist/docs/assets/reference_sessions.md.DdjWabnN.lean.js +1 -0
  201. package/dist/docs/assets/reference_skills.md.VQnlBT3Q.js +15 -0
  202. package/dist/docs/assets/reference_skills.md.VQnlBT3Q.lean.js +1 -0
  203. package/dist/docs/assets/reference_subagents.md.CIRAVcPK.js +10 -0
  204. package/dist/docs/assets/reference_subagents.md.CIRAVcPK.lean.js +1 -0
  205. package/dist/docs/assets/reference_tools.md.DF5kwlt0.js +46 -0
  206. package/dist/docs/assets/reference_tools.md.DF5kwlt0.lean.js +1 -0
  207. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +1 -0
  208. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +1 -0
  209. package/dist/docs/assets/style.Bj-IXa5W.css +1 -0
  210. package/dist/docs/assets/troubleshooting.md.DkovjS7h.js +1 -0
  211. package/dist/docs/assets/troubleshooting.md.DkovjS7h.lean.js +1 -0
  212. package/dist/docs/building-with-agents.html +37 -0
  213. package/dist/docs/concepts.html +28 -0
  214. package/dist/docs/deployment.html +38 -0
  215. package/dist/docs/evals.html +109 -0
  216. package/dist/docs/guides/agent-to-agent.html +34 -0
  217. package/dist/docs/guides/cloud-runtime.html +33 -0
  218. package/dist/docs/guides/github.html +44 -0
  219. package/dist/docs/guides/human-in-the-loop.html +52 -0
  220. package/dist/docs/guides/slack.html +61 -0
  221. package/dist/docs/guides/webhooks.html +74 -0
  222. package/dist/docs/hashmap.json +1 -0
  223. package/dist/docs/hillclimbing.html +28 -0
  224. package/dist/docs/index.html +44 -0
  225. package/dist/docs/quickstart.html +59 -0
  226. package/dist/docs/reference/agent-config.html +58 -0
  227. package/dist/docs/reference/channels.html +77 -0
  228. package/dist/docs/reference/cli.html +57 -0
  229. package/dist/docs/reference/connections.html +50 -0
  230. package/dist/docs/reference/hooks.html +36 -0
  231. package/dist/docs/reference/http-api.html +35 -0
  232. package/dist/docs/reference/instructions.html +36 -0
  233. package/dist/docs/reference/playground.html +25 -0
  234. package/dist/docs/reference/project-layout.html +55 -0
  235. package/dist/docs/reference/schedules.html +106 -0
  236. package/dist/docs/reference/sessions.html +32 -0
  237. package/dist/docs/reference/skills.html +39 -0
  238. package/dist/docs/reference/subagents.html +34 -0
  239. package/dist/docs/reference/tools.html +70 -0
  240. package/dist/docs/scaffolding-agents.html +25 -0
  241. package/dist/docs/troubleshooting.html +25 -0
  242. package/dist/docs/vp-icons.css +0 -0
  243. package/dist/evals.d.ts +312 -0
  244. package/dist/evals.d.ts.map +1 -0
  245. package/dist/evals.js +254 -0
  246. package/dist/hooks.d.ts +23 -0
  247. package/dist/hooks.d.ts.map +1 -0
  248. package/dist/hooks.js +23 -0
  249. package/dist/index.d.ts +71 -0
  250. package/dist/index.d.ts.map +1 -0
  251. package/dist/index.js +101 -0
  252. package/dist/internal/ab-collector.d.ts +42 -0
  253. package/dist/internal/ab-collector.d.ts.map +1 -0
  254. package/dist/internal/ab-collector.js +153 -0
  255. package/dist/internal/ab-fold.d.ts +36 -0
  256. package/dist/internal/ab-fold.d.ts.map +1 -0
  257. package/dist/internal/ab-fold.js +171 -0
  258. package/dist/internal/ab-snapshot.d.ts +70 -0
  259. package/dist/internal/ab-snapshot.d.ts.map +1 -0
  260. package/dist/internal/ab-snapshot.js +208 -0
  261. package/dist/internal/approval-gate.d.ts +34 -0
  262. package/dist/internal/approval-gate.d.ts.map +1 -0
  263. package/dist/internal/approval-gate.js +85 -0
  264. package/dist/internal/auth.d.ts +8 -0
  265. package/dist/internal/auth.d.ts.map +1 -0
  266. package/dist/internal/auth.js +27 -0
  267. package/dist/internal/authored-alias-hooks.d.ts +31 -0
  268. package/dist/internal/authored-alias-hooks.d.ts.map +1 -0
  269. package/dist/internal/authored-alias-hooks.js +43 -0
  270. package/dist/internal/authored-loaders.d.ts +25 -0
  271. package/dist/internal/authored-loaders.d.ts.map +1 -0
  272. package/dist/internal/authored-loaders.js +129 -0
  273. package/dist/internal/bounded-int.d.ts +11 -0
  274. package/dist/internal/bounded-int.d.ts.map +1 -0
  275. package/dist/internal/bounded-int.js +13 -0
  276. package/dist/internal/brand.d.ts +6 -0
  277. package/dist/internal/brand.d.ts.map +1 -0
  278. package/dist/internal/brand.js +17 -0
  279. package/dist/internal/chat-client.d.ts +19 -0
  280. package/dist/internal/chat-client.d.ts.map +1 -0
  281. package/dist/internal/chat-client.js +327 -0
  282. package/dist/internal/cli-ax.d.ts +58 -0
  283. package/dist/internal/cli-ax.d.ts.map +1 -0
  284. package/dist/internal/cli-ax.js +345 -0
  285. package/dist/internal/cli-cursor.d.ts +20 -0
  286. package/dist/internal/cli-cursor.d.ts.map +1 -0
  287. package/dist/internal/cli-cursor.js +227 -0
  288. package/dist/internal/cli-github.d.ts +47 -0
  289. package/dist/internal/cli-github.d.ts.map +1 -0
  290. package/dist/internal/cli-github.js +644 -0
  291. package/dist/internal/cli-slack.d.ts +18 -0
  292. package/dist/internal/cli-slack.d.ts.map +1 -0
  293. package/dist/internal/cli-slack.js +144 -0
  294. package/dist/internal/cloud-merge.d.ts +23 -0
  295. package/dist/internal/cloud-merge.d.ts.map +1 -0
  296. package/dist/internal/cloud-merge.js +28 -0
  297. package/dist/internal/cron.d.ts +17 -0
  298. package/dist/internal/cron.d.ts.map +1 -0
  299. package/dist/internal/cron.js +60 -0
  300. package/dist/internal/cursor/account-mcp.d.ts +95 -0
  301. package/dist/internal/cursor/account-mcp.d.ts.map +1 -0
  302. package/dist/internal/cursor/account-mcp.js +342 -0
  303. package/dist/internal/cursor/backend-client.d.ts +118 -0
  304. package/dist/internal/cursor/backend-client.d.ts.map +1 -0
  305. package/dist/internal/cursor/backend-client.js +477 -0
  306. package/dist/internal/cursor/credentials.d.ts +112 -0
  307. package/dist/internal/cursor/credentials.d.ts.map +1 -0
  308. package/dist/internal/cursor/credentials.js +329 -0
  309. package/dist/internal/cursor-event-relay.d.ts +111 -0
  310. package/dist/internal/cursor-event-relay.d.ts.map +1 -0
  311. package/dist/internal/cursor-event-relay.js +181 -0
  312. package/dist/internal/cursor-relay-core.d.ts +113 -0
  313. package/dist/internal/cursor-relay-core.d.ts.map +1 -0
  314. package/dist/internal/cursor-relay-core.js +364 -0
  315. package/dist/internal/cursor-slack-relay.d.ts +94 -0
  316. package/dist/internal/cursor-slack-relay.d.ts.map +1 -0
  317. package/dist/internal/cursor-slack-relay.js +171 -0
  318. package/dist/internal/describe-error.d.ts +3 -0
  319. package/dist/internal/describe-error.d.ts.map +1 -0
  320. package/dist/internal/describe-error.js +4 -0
  321. package/dist/internal/dev-mode.d.ts +13 -0
  322. package/dist/internal/dev-mode.d.ts.map +1 -0
  323. package/dist/internal/dev-mode.js +17 -0
  324. package/dist/internal/discovery.d.ts +55 -0
  325. package/dist/internal/discovery.d.ts.map +1 -0
  326. package/dist/internal/discovery.js +1427 -0
  327. package/dist/internal/distribution.d.ts +47 -0
  328. package/dist/internal/distribution.d.ts.map +1 -0
  329. package/dist/internal/distribution.js +82 -0
  330. package/dist/internal/docs-site.d.ts +28 -0
  331. package/dist/internal/docs-site.d.ts.map +1 -0
  332. package/dist/internal/docs-site.js +169 -0
  333. package/dist/internal/duration.d.ts +8 -0
  334. package/dist/internal/duration.d.ts.map +1 -0
  335. package/dist/internal/duration.js +35 -0
  336. package/dist/internal/eval-run-store.d.ts +81 -0
  337. package/dist/internal/eval-run-store.d.ts.map +1 -0
  338. package/dist/internal/eval-run-store.js +396 -0
  339. package/dist/internal/eval-runner.d.ts +76 -0
  340. package/dist/internal/eval-runner.d.ts.map +1 -0
  341. package/dist/internal/eval-runner.js +336 -0
  342. package/dist/internal/event-log.d.ts +51 -0
  343. package/dist/internal/event-log.d.ts.map +1 -0
  344. package/dist/internal/event-log.js +167 -0
  345. package/dist/internal/event-mapper.d.ts +46 -0
  346. package/dist/internal/event-mapper.d.ts.map +1 -0
  347. package/dist/internal/event-mapper.js +226 -0
  348. package/dist/internal/frontmatter.d.ts +12 -0
  349. package/dist/internal/frontmatter.d.ts.map +1 -0
  350. package/dist/internal/frontmatter.js +61 -0
  351. package/dist/internal/github-fanout.d.ts +32 -0
  352. package/dist/internal/github-fanout.d.ts.map +1 -0
  353. package/dist/internal/github-fanout.js +122 -0
  354. package/dist/internal/handleAgentServeTrigger.d.ts +59 -0
  355. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -0
  356. package/dist/internal/handleAgentServeTrigger.js +115 -0
  357. package/dist/internal/host-platforms.d.ts +40 -0
  358. package/dist/internal/host-platforms.d.ts.map +1 -0
  359. package/dist/internal/host-platforms.js +113 -0
  360. package/dist/internal/http-channel.d.ts +54 -0
  361. package/dist/internal/http-channel.d.ts.map +1 -0
  362. package/dist/internal/http-channel.js +382 -0
  363. package/dist/internal/ids.d.ts +19 -0
  364. package/dist/internal/ids.d.ts.map +1 -0
  365. package/dist/internal/ids.js +34 -0
  366. package/dist/internal/init-project.d.ts +22 -0
  367. package/dist/internal/init-project.d.ts.map +1 -0
  368. package/dist/internal/init-project.js +125 -0
  369. package/dist/internal/json-dir-store.d.ts +32 -0
  370. package/dist/internal/json-dir-store.d.ts.map +1 -0
  371. package/dist/internal/json-dir-store.js +100 -0
  372. package/dist/internal/json-schema.d.ts +18 -0
  373. package/dist/internal/json-schema.d.ts.map +1 -0
  374. package/dist/internal/json-schema.js +53 -0
  375. package/dist/internal/log-ring.d.ts +23 -0
  376. package/dist/internal/log-ring.d.ts.map +1 -0
  377. package/dist/internal/log-ring.js +42 -0
  378. package/dist/internal/map-pool.d.ts +6 -0
  379. package/dist/internal/map-pool.d.ts.map +1 -0
  380. package/dist/internal/map-pool.js +41 -0
  381. package/dist/internal/mcp-endpoint.d.ts +59 -0
  382. package/dist/internal/mcp-endpoint.d.ts.map +1 -0
  383. package/dist/internal/mcp-endpoint.js +355 -0
  384. package/dist/internal/mcp-host.d.ts +28 -0
  385. package/dist/internal/mcp-host.d.ts.map +1 -0
  386. package/dist/internal/mcp-host.js +162 -0
  387. package/dist/internal/net.d.ts +5 -0
  388. package/dist/internal/net.d.ts.map +1 -0
  389. package/dist/internal/net.js +30 -0
  390. package/dist/internal/peer-connections.d.ts +44 -0
  391. package/dist/internal/peer-connections.d.ts.map +1 -0
  392. package/dist/internal/peer-connections.js +67 -0
  393. package/dist/internal/playground/static.d.ts +35 -0
  394. package/dist/internal/playground/static.d.ts.map +1 -0
  395. package/dist/internal/playground/static.js +162 -0
  396. package/dist/internal/playground/toolchain.d.ts +57 -0
  397. package/dist/internal/playground/toolchain.d.ts.map +1 -0
  398. package/dist/internal/playground/toolchain.js +226 -0
  399. package/dist/internal/reminder-runner.d.ts +62 -0
  400. package/dist/internal/reminder-runner.d.ts.map +1 -0
  401. package/dist/internal/reminder-runner.js +582 -0
  402. package/dist/internal/reminder-schedule.d.ts +22 -0
  403. package/dist/internal/reminder-schedule.d.ts.map +1 -0
  404. package/dist/internal/reminder-schedule.js +82 -0
  405. package/dist/internal/reminder-store.d.ts +58 -0
  406. package/dist/internal/reminder-store.d.ts.map +1 -0
  407. package/dist/internal/reminder-store.js +106 -0
  408. package/dist/internal/resolved-connections.d.ts +41 -0
  409. package/dist/internal/resolved-connections.d.ts.map +1 -0
  410. package/dist/internal/resolved-connections.js +73 -0
  411. package/dist/internal/review-comments.d.ts +50 -0
  412. package/dist/internal/review-comments.d.ts.map +1 -0
  413. package/dist/internal/review-comments.js +194 -0
  414. package/dist/internal/router.d.ts +33 -0
  415. package/dist/internal/router.d.ts.map +1 -0
  416. package/dist/internal/router.js +93 -0
  417. package/dist/internal/run-client.d.ts +49 -0
  418. package/dist/internal/run-client.d.ts.map +1 -0
  419. package/dist/internal/run-client.js +208 -0
  420. package/dist/internal/schedule-runner.d.ts +31 -0
  421. package/dist/internal/schedule-runner.d.ts.map +1 -0
  422. package/dist/internal/schedule-runner.js +126 -0
  423. package/dist/internal/sdk-runner.d.ts +41 -0
  424. package/dist/internal/sdk-runner.d.ts.map +1 -0
  425. package/dist/internal/sdk-runner.js +221 -0
  426. package/dist/internal/server.d.ts +25 -0
  427. package/dist/internal/server.d.ts.map +1 -0
  428. package/dist/internal/server.js +1374 -0
  429. package/dist/internal/session-engine.d.ts +287 -0
  430. package/dist/internal/session-engine.d.ts.map +1 -0
  431. package/dist/internal/session-engine.js +1377 -0
  432. package/dist/internal/session-store.d.ts +29 -0
  433. package/dist/internal/session-store.d.ts.map +1 -0
  434. package/dist/internal/session-store.js +140 -0
  435. package/dist/internal/session-urls.d.ts +10 -0
  436. package/dist/internal/session-urls.d.ts.map +1 -0
  437. package/dist/internal/session-urls.js +25 -0
  438. package/dist/internal/stream-progress.d.ts +14 -0
  439. package/dist/internal/stream-progress.d.ts.map +1 -0
  440. package/dist/internal/stream-progress.js +195 -0
  441. package/dist/internal/tool-result.d.ts +20 -0
  442. package/dist/internal/tool-result.d.ts.map +1 -0
  443. package/dist/internal/tool-result.js +45 -0
  444. package/dist/internal/trajectory.d.ts +56 -0
  445. package/dist/internal/trajectory.d.ts.map +1 -0
  446. package/dist/internal/trajectory.js +248 -0
  447. package/dist/internal/workspace.d.ts +42 -0
  448. package/dist/internal/workspace.d.ts.map +1 -0
  449. package/dist/internal/workspace.js +199 -0
  450. package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
  451. package/dist/playground/assets/index-1K-hG-7p.css +1 -0
  452. package/dist/playground/assets/index-FlWjhg3x.js +79 -0
  453. package/dist/playground/index.html +17 -0
  454. package/dist/reminders.d.ts +23 -0
  455. package/dist/reminders.d.ts.map +1 -0
  456. package/dist/reminders.js +22 -0
  457. package/dist/schedules.d.ts +23 -0
  458. package/dist/schedules.d.ts.map +1 -0
  459. package/dist/schedules.js +26 -0
  460. package/dist/skills.d.ts +22 -0
  461. package/dist/skills.d.ts.map +1 -0
  462. package/dist/skills.js +22 -0
  463. package/dist/tools.d.ts +92 -0
  464. package/dist/tools.d.ts.map +1 -0
  465. package/dist/tools.js +68 -0
  466. package/dist/types.d.ts +1609 -0
  467. package/dist/types.d.ts.map +1 -0
  468. package/dist/types.js +80 -0
  469. package/docs/README.md +174 -0
  470. package/docs/ab.md +355 -0
  471. package/docs/building-with-agents.md +129 -0
  472. package/docs/concepts.md +177 -0
  473. package/docs/deployment.md +218 -0
  474. package/docs/evals.md +383 -0
  475. package/docs/guides/agent-to-agent.md +118 -0
  476. package/docs/guides/cloud-runtime.md +122 -0
  477. package/docs/guides/github.md +172 -0
  478. package/docs/guides/human-in-the-loop.md +131 -0
  479. package/docs/guides/slack.md +245 -0
  480. package/docs/guides/webhooks.md +201 -0
  481. package/docs/hillclimbing.md +93 -0
  482. package/docs/quickstart.md +183 -0
  483. package/docs/reference/agent-config.md +154 -0
  484. package/docs/reference/channels.md +206 -0
  485. package/docs/reference/cli.md +257 -0
  486. package/docs/reference/connections.md +137 -0
  487. package/docs/reference/hooks.md +74 -0
  488. package/docs/reference/http-api.md +219 -0
  489. package/docs/reference/instructions.md +77 -0
  490. package/docs/reference/playground.md +67 -0
  491. package/docs/reference/project-layout.md +119 -0
  492. package/docs/reference/schedules.md +220 -0
  493. package/docs/reference/sessions.md +165 -0
  494. package/docs/reference/skills.md +79 -0
  495. package/docs/reference/subagents.md +74 -0
  496. package/docs/reference/tools.md +203 -0
  497. package/docs/scaffolding-agents.md +113 -0
  498. package/docs/troubleshooting.md +95 -0
  499. package/package.json +185 -0
  500. package/skills/ab/SKILL.md +139 -0
  501. package/skills/create-agent/SKILL.md +219 -0
  502. package/skills/debug/SKILL.md +71 -0
  503. package/skills/evals/SKILL.md +217 -0
  504. package/skills/framework-map/SKILL.md +142 -0
  505. package/skills/github/SKILL.md +144 -0
  506. package/skills/hillclimb/SKILL.md +162 -0
  507. package/skills/setup-slack/SKILL.md +180 -0
  508. package/src/ab.ts +675 -0
  509. package/src/bin/agent-serve.ts +949 -0
  510. package/src/channels/github/api.ts +374 -0
  511. package/src/channels/github/auth.ts +275 -0
  512. package/src/channels/github/binding.ts +223 -0
  513. package/src/channels/github/defaults.ts +111 -0
  514. package/src/channels/github/events.ts +72 -0
  515. package/src/channels/github/forward.ts +381 -0
  516. package/src/channels/github/github-channel.ts +2270 -0
  517. package/src/channels/github/index.ts +52 -0
  518. package/src/channels/github/replay.ts +387 -0
  519. package/src/channels/github/state.ts +95 -0
  520. package/src/channels/github/types.ts +490 -0
  521. package/src/channels/slack/api.ts +580 -0
  522. package/src/channels/slack/approvals.ts +198 -0
  523. package/src/channels/slack/assistant.ts +76 -0
  524. package/src/channels/slack/auth.ts +112 -0
  525. package/src/channels/slack/channel-watch.ts +219 -0
  526. package/src/channels/slack/constants.ts +30 -0
  527. package/src/channels/slack/credentials.ts +90 -0
  528. package/src/channels/slack/cursor-account.ts +166 -0
  529. package/src/channels/slack/defaults.ts +450 -0
  530. package/src/channels/slack/dispatch.ts +293 -0
  531. package/src/channels/slack/doctor.ts +135 -0
  532. package/src/channels/slack/event-id-dedupe.ts +30 -0
  533. package/src/channels/slack/inbound.ts +219 -0
  534. package/src/channels/slack/index.ts +45 -0
  535. package/src/channels/slack/init.ts +133 -0
  536. package/src/channels/slack/interactive.ts +194 -0
  537. package/src/channels/slack/links.ts +23 -0
  538. package/src/channels/slack/live-delivery.ts +201 -0
  539. package/src/channels/slack/log.ts +83 -0
  540. package/src/channels/slack/manifest.ts +179 -0
  541. package/src/channels/slack/pr-ref.ts +50 -0
  542. package/src/channels/slack/setup.ts +97 -0
  543. package/src/channels/slack/slack-channel.ts +374 -0
  544. package/src/channels/slack/socket-mode.ts +154 -0
  545. package/src/channels/slack/stream.ts +63 -0
  546. package/src/channels/slack/tool-approval-events.ts +136 -0
  547. package/src/channels/slack/types.ts +349 -0
  548. package/src/channels.ts +385 -0
  549. package/src/connections.ts +89 -0
  550. package/src/evals.ts +501 -0
  551. package/src/hooks.ts +33 -0
  552. package/src/index.ts +184 -0
  553. package/src/internal/ab-collector.ts +210 -0
  554. package/src/internal/ab-fold.ts +228 -0
  555. package/src/internal/ab-snapshot.ts +335 -0
  556. package/src/internal/approval-gate.ts +115 -0
  557. package/src/internal/auth.ts +39 -0
  558. package/src/internal/authored-alias-hooks.ts +69 -0
  559. package/src/internal/authored-loaders.ts +138 -0
  560. package/src/internal/bounded-int.ts +27 -0
  561. package/src/internal/brand.ts +29 -0
  562. package/src/internal/chat-client.ts +407 -0
  563. package/src/internal/cli-ax.ts +474 -0
  564. package/src/internal/cli-cursor.ts +275 -0
  565. package/src/internal/cli-github.ts +849 -0
  566. package/src/internal/cli-slack.ts +175 -0
  567. package/src/internal/cloud-merge.ts +41 -0
  568. package/src/internal/cron.ts +78 -0
  569. package/src/internal/cursor/account-mcp.ts +472 -0
  570. package/src/internal/cursor/backend-client.ts +614 -0
  571. package/src/internal/cursor/credentials.ts +401 -0
  572. package/src/internal/cursor-event-relay.ts +281 -0
  573. package/src/internal/cursor-relay-core.ts +444 -0
  574. package/src/internal/cursor-slack-relay.ts +242 -0
  575. package/src/internal/describe-error.ts +4 -0
  576. package/src/internal/dev-mode.ts +20 -0
  577. package/src/internal/discovery.ts +1709 -0
  578. package/src/internal/distribution.ts +97 -0
  579. package/src/internal/docs-site.ts +191 -0
  580. package/src/internal/duration.ts +39 -0
  581. package/src/internal/eval-run-store.ts +519 -0
  582. package/src/internal/eval-runner.ts +522 -0
  583. package/src/internal/event-log.ts +175 -0
  584. package/src/internal/event-mapper.ts +272 -0
  585. package/src/internal/frontmatter.ts +77 -0
  586. package/src/internal/github-fanout.ts +159 -0
  587. package/src/internal/handleAgentServeTrigger.ts +156 -0
  588. package/src/internal/host-platforms.ts +144 -0
  589. package/src/internal/http-channel.ts +546 -0
  590. package/src/internal/ids.ts +44 -0
  591. package/src/internal/init-project.ts +165 -0
  592. package/src/internal/json-dir-store.ts +109 -0
  593. package/src/internal/json-schema.ts +69 -0
  594. package/src/internal/log-ring.ts +59 -0
  595. package/src/internal/map-pool.ts +32 -0
  596. package/src/internal/mcp-endpoint.ts +518 -0
  597. package/src/internal/mcp-host.ts +211 -0
  598. package/src/internal/net.ts +31 -0
  599. package/src/internal/peer-connections.ts +100 -0
  600. package/src/internal/playground/static.ts +189 -0
  601. package/src/internal/playground/toolchain.ts +277 -0
  602. package/src/internal/reminder-runner.ts +756 -0
  603. package/src/internal/reminder-schedule.ts +106 -0
  604. package/src/internal/reminder-store.ts +145 -0
  605. package/src/internal/resolved-connections.ts +145 -0
  606. package/src/internal/review-comments.ts +268 -0
  607. package/src/internal/router.ts +145 -0
  608. package/src/internal/run-client.ts +320 -0
  609. package/src/internal/schedule-runner.ts +161 -0
  610. package/src/internal/sdk-runner.ts +315 -0
  611. package/src/internal/server.ts +1737 -0
  612. package/src/internal/session-engine.ts +1810 -0
  613. package/src/internal/session-store.ts +147 -0
  614. package/src/internal/session-urls.ts +40 -0
  615. package/src/internal/stream-progress.ts +254 -0
  616. package/src/internal/tool-result.ts +54 -0
  617. package/src/internal/trajectory.ts +306 -0
  618. package/src/internal/workspace.ts +223 -0
  619. package/src/reminders.ts +35 -0
  620. package/src/schedules.ts +37 -0
  621. package/src/skills.ts +27 -0
  622. package/src/tools.ts +127 -0
  623. package/src/types.ts +1848 -0
@@ -0,0 +1,1427 @@
1
+ /**
2
+ * Filesystem discovery: walks a project's `agent/` directory and compiles
3
+ * the authored files (markdown and TypeScript) into an {@link AgentProject}
4
+ * manifest. Identity comes from the path — a tool at `agent/tools/foo.ts`
5
+ * is named `foo`, a subagent at `agent/subagents/researcher/` is named
6
+ * `researcher` — so no definition carries a `name` field.
7
+ */
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __rest = (this && this.__rest) || function (s, e) {
18
+ var t = {};
19
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
20
+ t[p] = s[p];
21
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
22
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
23
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
24
+ t[p[i]] = s[p[i]];
25
+ }
26
+ return t;
27
+ };
28
+ import { readdir, readFile, stat } from "node:fs/promises";
29
+ import { basename, extname, isAbsolute, join, relative, resolve, } from "node:path";
30
+ import { pathToFileURL } from "node:url";
31
+ import { resolveABMaxPlaygroundSessions } from "../ab.js";
32
+ import { httpChannel } from "../channels.js";
33
+ import { DEFAULT_MODEL, toPublicCloudInfo, } from "../types.js";
34
+ import { registerAuthoredModuleLoaders } from "./authored-loaders.js";
35
+ import { getDefinitionKind } from "./brand.js";
36
+ import { isValidCron } from "./cron.js";
37
+ import { parseFrontmatter } from "./frontmatter.js";
38
+ import { toolInputJsonSchema } from "./json-schema.js";
39
+ import { MCP_ENDPOINT_PATH, mcpEndpointToolNames } from "./mcp-endpoint.js";
40
+ const MODULE_EXTENSIONS = new Set([".ts", ".mts", ".js", ".mjs"]);
41
+ const NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
42
+ const SKILL_DESCRIPTION_FALLBACK = (name) => `Instructions for the ${name} skill.`;
43
+ function defaultImportModule(absolutePath) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ return (yield import(pathToFileURL(absolutePath).href));
46
+ });
47
+ }
48
+ /**
49
+ * True when `dir` looks like an agent project root: it has a nested `agent/`
50
+ * directory, or flat-layout markers (`agent.ts` / `instructions.md`) directly
51
+ * inside it.
52
+ */
53
+ export function isAgentProjectDir(dir) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ const resolved = resolve(dir);
56
+ if (!(yield isDirectory(resolved))) {
57
+ return false;
58
+ }
59
+ if (yield isDirectory(join(resolved, "agent"))) {
60
+ return true;
61
+ }
62
+ return hasFlatLayoutMarkers(resolved);
63
+ });
64
+ }
65
+ /**
66
+ * Discover the agent projects directly under `rootDir` (one level deep):
67
+ * each immediate child directory that is itself an agent project becomes a
68
+ * mounted agent, keyed by a slug derived from its directory name. Used for
69
+ * multi-agent serving, where one server hosts many agents under
70
+ * `/<slug>/...`. Throws when no child projects are found.
71
+ */
72
+ export function loadAgentProjects(rootDir_1) {
73
+ return __awaiter(this, arguments, void 0, function* (rootDir, options = {}) {
74
+ const resolved = resolve(rootDir);
75
+ if (!(yield isDirectory(resolved))) {
76
+ throw new Error(`Agent projects directory does not exist: ${resolved}`);
77
+ }
78
+ const results = [];
79
+ const seenSlugs = new Set();
80
+ for (const entry of yield sortedEntries(resolved)) {
81
+ if (!entry.isDirectory() || entry.name.startsWith(".")) {
82
+ continue;
83
+ }
84
+ if (entry.name === "node_modules") {
85
+ continue;
86
+ }
87
+ const childDir = join(resolved, entry.name);
88
+ if (!(yield isAgentProjectDir(childDir))) {
89
+ continue;
90
+ }
91
+ const slug = assertSlug(entry.name, resolved);
92
+ if (seenSlugs.has(slug)) {
93
+ throw new Error(`Duplicate agent slug "${slug}" under ${resolved}.`);
94
+ }
95
+ seenSlugs.add(slug);
96
+ results.push({ slug, project: yield loadAgentProject(childDir, options) });
97
+ }
98
+ if (results.length === 0) {
99
+ throw new Error(`No agent projects found directly under ${resolved}. Each agent should be a subdirectory with its own agent/ directory (or flat-layout markers).`);
100
+ }
101
+ return results;
102
+ });
103
+ }
104
+ /**
105
+ * Resolve mounts for `serve` / CLI. Defaults to multi-agent layout:
106
+ * - `mode: "single"` — one agent at `/v1/*` (empty slug).
107
+ * - otherwise, if `rootDir` is itself an agent project — one agent under
108
+ * `/<dirname>/...`.
109
+ * - otherwise, every immediate child agent project under `/<slug>/...`.
110
+ */
111
+ export function resolveAgentMounts(rootDir_1) {
112
+ return __awaiter(this, arguments, void 0, function* (rootDir, options = {}) {
113
+ const { mode = "multi" } = options, discovery = __rest(options, ["mode"]);
114
+ if (mode === "single") {
115
+ return [{ slug: "", project: yield loadAgentProject(rootDir, discovery) }];
116
+ }
117
+ if (yield isAgentProjectDir(rootDir)) {
118
+ const resolved = resolve(rootDir);
119
+ const slug = assertSlug(basename(resolved), resolved);
120
+ return [
121
+ {
122
+ slug,
123
+ project: yield loadAgentProject(rootDir, discovery),
124
+ },
125
+ ];
126
+ }
127
+ return loadAgentProjects(rootDir, discovery);
128
+ });
129
+ }
130
+ function assertSlug(name, parentDir) {
131
+ if (!NAME_PATTERN.test(name) || RESERVED_SLUGS.has(name)) {
132
+ throw new Error(`Cannot mount agent directory "${name}" under ${parentDir}: its name must match ${NAME_PATTERN} and not be one of ${[...RESERVED_SLUGS].join(", ")}.`);
133
+ }
134
+ return name;
135
+ }
136
+ /** URL path segments reserved by the server; agents cannot use them as slugs. */
137
+ export const RESERVED_SLUGS = new Set([
138
+ "v1",
139
+ "playground",
140
+ "docs",
141
+ ]);
142
+ export function loadAgentProject(dir_1) {
143
+ return __awaiter(this, arguments, void 0, function* (dir, options = {}) {
144
+ var _a, _b;
145
+ // Public API: embedders can call discovery directly (without `serve()` or
146
+ // the CLI), and it dynamically imports authored TypeScript.
147
+ yield registerAuthoredModuleLoaders();
148
+ const rootDir = resolve(dir);
149
+ if (!(yield isDirectory(rootDir))) {
150
+ throw new Error(`Agent project directory does not exist: ${rootDir}`);
151
+ }
152
+ const nestedAgentDir = join(rootDir, "agent");
153
+ let agentDir;
154
+ if (yield isDirectory(nestedAgentDir)) {
155
+ agentDir = nestedAgentDir;
156
+ }
157
+ else if (yield hasFlatLayoutMarkers(rootDir)) {
158
+ agentDir = rootDir;
159
+ }
160
+ else {
161
+ throw new Error(`No agent found under ${rootDir}: expected an agent/ directory (or a flat layout with agent.ts / instructions.md at the root)`);
162
+ }
163
+ const diagnostics = [];
164
+ const ctx = {
165
+ rootDir,
166
+ diagnostics,
167
+ importModule: (_a = options.importModule) !== null && _a !== void 0 ? _a : defaultImportModule,
168
+ };
169
+ const name = (_b = (yield readPackageName(rootDir))) !== null && _b !== void 0 ? _b : basename(rootDir);
170
+ const agent = yield loadAgent(ctx, agentDir, {
171
+ name,
172
+ isRoot: true,
173
+ });
174
+ const { channels, httpChannelDefinition } = yield loadChannels(ctx, join(agentDir, "channels"));
175
+ const schedules = yield loadSchedules(ctx, join(agentDir, "schedules"));
176
+ const hooks = yield loadHooks(ctx, join(agentDir, "hooks"));
177
+ const abs = yield loadABs(ctx, agentDir);
178
+ const abConfig = yield loadABConfig(ctx, agentDir);
179
+ if (agentDir !== rootDir) {
180
+ yield warnUnknownSlots(ctx, agentDir);
181
+ }
182
+ return Object.assign(Object.assign({ rootDir,
183
+ agentDir, name: agent.name, agent, httpChannel: httpChannelDefinition !== null && httpChannelDefinition !== void 0 ? httpChannelDefinition : httpChannel(), channels,
184
+ schedules,
185
+ hooks,
186
+ abs }, (abConfig === undefined ? {} : { abConfig })), { diagnostics });
187
+ });
188
+ }
189
+ /** True when the project has diagnostics that must block serving. */
190
+ export function hasErrorDiagnostics(project) {
191
+ return project.diagnostics.some((d) => d.severity === "error");
192
+ }
193
+ export function formatDiagnostics(diagnostics) {
194
+ return diagnostics
195
+ .map((d) => {
196
+ const location = d.path === undefined ? "" : ` (${d.path})`;
197
+ return `${d.severity}: ${d.message}${location}`;
198
+ })
199
+ .join("\n");
200
+ }
201
+ // ============================================================================
202
+ // Agents (root + subagents)
203
+ // ============================================================================
204
+ function loadAgent(ctx, agentDir, options) {
205
+ return __awaiter(this, void 0, void 0, function* () {
206
+ var _a;
207
+ var _b, _c;
208
+ const config = yield loadAgentConfig(ctx, agentDir, options.isRoot);
209
+ const instructions = yield loadInstructions(ctx, agentDir, config, options.isRoot);
210
+ // Subagents run as Cursor SDK custom subagents (prompt + description +
211
+ // model); their other slots are inert today, so don't load them — just
212
+ // warn that they exist.
213
+ if (!options.isRoot) {
214
+ yield warnUnsupportedSubagentSlots(ctx, agentDir);
215
+ return Object.assign(Object.assign(Object.assign(Object.assign({ name: (_b = config === null || config === void 0 ? void 0 : config.name) !== null && _b !== void 0 ? _b : options.name }, ((config === null || config === void 0 ? void 0 : config.description) === undefined
216
+ ? {}
217
+ : { description: config.description })), ((config === null || config === void 0 ? void 0 : config.model) === undefined ? {} : { model: config.model })), (instructions === undefined ? {} : { instructions })), { runtime: "local", tools: [], skills: [], connections: [], subagents: [], seedFiles: [] });
218
+ }
219
+ const tools = yield loadTools(ctx, join(agentDir, "tools"));
220
+ const skills = yield loadSkills(ctx, join(agentDir, "skills"));
221
+ const connections = yield loadConnections(ctx, yield resolveMcpConnectionsDir(ctx, agentDir));
222
+ const seedFiles = yield loadSeedFiles(ctx, agentDir);
223
+ const subagents = yield loadSubagents(ctx, join(agentDir, "subagents"));
224
+ const runtime = (config === null || config === void 0 ? void 0 : config.runtime) === "cloud" ? "cloud" : "local";
225
+ // Keep authored `cloud` even when default runtime is local — per-session
226
+ // `send({ cloud })` merges it under cloudOverride for handoff sessions.
227
+ const cloud = config === null || config === void 0 ? void 0 : config.cloud;
228
+ const localCwd = resolveAgentCwd(ctx, (_a = config === null || config === void 0 ? void 0 : config.local) === null || _a === void 0 ? void 0 : _a.cwd);
229
+ const local = localCwd === undefined
230
+ ? undefined
231
+ : {
232
+ cwd: localCwd,
233
+ };
234
+ if (runtime === "cloud") {
235
+ warnCloudRuntimeLimitations(ctx, agentDir, {
236
+ serverTools: tools.filter((tool) => tool.execution === "server").length,
237
+ agentTools: tools.filter((tool) => tool.execution === "agent").length,
238
+ skills: skills.length,
239
+ seedFiles: seedFiles.length,
240
+ hasCloudOptions: cloud !== undefined,
241
+ });
242
+ }
243
+ return {
244
+ name: (_c = config === null || config === void 0 ? void 0 : config.name) !== null && _c !== void 0 ? _c : options.name,
245
+ description: config === null || config === void 0 ? void 0 : config.description,
246
+ // Root agents always get a concrete model: authored value or DEFAULT_MODEL.
247
+ model: isValidModelSetting(config === null || config === void 0 ? void 0 : config.model) ? config.model : DEFAULT_MODEL,
248
+ instructions,
249
+ runtime,
250
+ cloud,
251
+ local,
252
+ tools,
253
+ skills,
254
+ connections,
255
+ subagents,
256
+ seedFiles,
257
+ };
258
+ });
259
+ }
260
+ /** Absolute harness cwd parent, or undefined when unset / blank. */
261
+ function resolveAgentCwd(ctx, authored) {
262
+ if (authored === undefined) {
263
+ return undefined;
264
+ }
265
+ const trimmed = authored.trim();
266
+ if (trimmed === "") {
267
+ return undefined;
268
+ }
269
+ return isAbsolute(trimmed) ? trimmed : resolve(ctx.rootDir, trimmed);
270
+ }
271
+ function loadAgentConfig(ctx, agentDir, isRoot) {
272
+ return __awaiter(this, void 0, void 0, function* () {
273
+ const configPath = yield findModuleFile(agentDir, "agent");
274
+ if (configPath === undefined) {
275
+ ctx.diagnostics.push({
276
+ severity: "error",
277
+ path: displayPath(ctx, join(agentDir, "agent.ts")),
278
+ message: isRoot
279
+ ? "agent.ts is required on the root agent: default-export defineAgent({ ... })"
280
+ : "agent.ts is required on a subagent: default-export defineAgent({ description: ... })",
281
+ });
282
+ return undefined;
283
+ }
284
+ const definition = yield importDefault(ctx, configPath, "agent");
285
+ if (definition === undefined) {
286
+ return undefined;
287
+ }
288
+ const config = definition;
289
+ if (!isRoot && isBlank(config.description)) {
290
+ ctx.diagnostics.push({
291
+ severity: "error",
292
+ path: displayPath(ctx, configPath),
293
+ message: "Subagents require a description; the parent model reads it to decide when to delegate.",
294
+ });
295
+ }
296
+ return config;
297
+ });
298
+ }
299
+ function loadInstructions(ctx, agentDir, config, isRoot) {
300
+ return __awaiter(this, void 0, void 0, function* () {
301
+ const parts = [];
302
+ const markdownPath = join(agentDir, "instructions.md");
303
+ if (yield isFile(markdownPath)) {
304
+ parts.push((yield readFile(markdownPath, "utf8")).trim());
305
+ }
306
+ const modulePath = yield findModuleFile(agentDir, "instructions");
307
+ if (modulePath !== undefined) {
308
+ const loaded = yield loadInstructionsModule(ctx, modulePath);
309
+ if (loaded !== undefined) {
310
+ parts.push(loaded);
311
+ }
312
+ }
313
+ const instructionsDir = join(agentDir, "instructions");
314
+ if (yield isDirectory(instructionsDir)) {
315
+ for (const entry of yield sortedEntries(instructionsDir)) {
316
+ if (!entry.isFile()) {
317
+ continue;
318
+ }
319
+ const entryPath = join(instructionsDir, entry.name);
320
+ if (entry.name.endsWith(".md")) {
321
+ parts.push((yield readFile(entryPath, "utf8")).trim());
322
+ }
323
+ else if (isModuleFile(entry.name)) {
324
+ const loaded = yield loadInstructionsModule(ctx, entryPath);
325
+ if (loaded !== undefined) {
326
+ parts.push(loaded);
327
+ }
328
+ }
329
+ }
330
+ }
331
+ if ((config === null || config === void 0 ? void 0 : config.instructions) !== undefined && !isBlank(config.instructions)) {
332
+ parts.push(config.instructions.trim());
333
+ }
334
+ const combined = parts.filter((part) => part !== "").join("\n\n");
335
+ if (combined === "") {
336
+ if (isRoot) {
337
+ ctx.diagnostics.push({
338
+ severity: "error",
339
+ path: displayPath(ctx, markdownPath),
340
+ message: "instructions.md is required on the root agent (the always-on system prompt).",
341
+ });
342
+ }
343
+ return undefined;
344
+ }
345
+ return combined;
346
+ });
347
+ }
348
+ function loadInstructionsModule(ctx, modulePath) {
349
+ return __awaiter(this, void 0, void 0, function* () {
350
+ let mod;
351
+ try {
352
+ mod = yield ctx.importModule(modulePath);
353
+ }
354
+ catch (error) {
355
+ ctx.diagnostics.push({
356
+ severity: "error",
357
+ path: displayPath(ctx, modulePath),
358
+ message: `Failed to load module: ${errorMessage(error)}`,
359
+ });
360
+ return undefined;
361
+ }
362
+ const value = mod.default;
363
+ if (typeof value === "string") {
364
+ return value.trim();
365
+ }
366
+ if (getDefinitionKind(value) === "instructions") {
367
+ return value.markdown.trim();
368
+ }
369
+ ctx.diagnostics.push({
370
+ severity: "error",
371
+ path: displayPath(ctx, modulePath),
372
+ message: "Instructions modules must default-export a string or defineInstructions({ markdown }).",
373
+ });
374
+ return undefined;
375
+ });
376
+ }
377
+ // ============================================================================
378
+ // Tools
379
+ // ============================================================================
380
+ function loadTools(ctx, toolsDir) {
381
+ return __awaiter(this, void 0, void 0, function* () {
382
+ if (!(yield isDirectory(toolsDir))) {
383
+ return [];
384
+ }
385
+ const tools = [];
386
+ for (const entry of yield sortedEntries(toolsDir)) {
387
+ const entryPath = join(toolsDir, entry.name);
388
+ if (entry.isDirectory()) {
389
+ ctx.diagnostics.push({
390
+ severity: "warning",
391
+ path: displayPath(ctx, entryPath),
392
+ message: "Nested tool directories are not supported; ignoring.",
393
+ });
394
+ continue;
395
+ }
396
+ if (!entry.isFile() || !isModuleFile(entry.name)) {
397
+ continue;
398
+ }
399
+ const name = moduleStem(entry.name);
400
+ if (!NAME_PATTERN.test(name)) {
401
+ ctx.diagnostics.push({
402
+ severity: "error",
403
+ path: displayPath(ctx, entryPath),
404
+ message: `Tool name "${name}" must match ${NAME_PATTERN} (the filename becomes the tool name the model sees).`,
405
+ });
406
+ continue;
407
+ }
408
+ const definition = yield importDefault(ctx, entryPath, "tool");
409
+ if (definition === undefined) {
410
+ continue;
411
+ }
412
+ const tool = definition;
413
+ if (isBlank(tool.description)) {
414
+ ctx.diagnostics.push({
415
+ severity: "error",
416
+ path: displayPath(ctx, entryPath),
417
+ message: "Tools require a non-empty description.",
418
+ });
419
+ continue;
420
+ }
421
+ const execution = tool.execution === "agent" ? "agent" : "server";
422
+ const needsApprovalConfigured = tool.needsApproval === true || typeof tool.needsApproval === "function";
423
+ if (execution === "agent") {
424
+ if (isBlank(tool.script)) {
425
+ ctx.diagnostics.push({
426
+ severity: "error",
427
+ path: displayPath(ctx, entryPath),
428
+ message: 'Tools with execution: "agent" require a non-empty `script` (shell body; JSON on stdin, result on stdout).',
429
+ });
430
+ continue;
431
+ }
432
+ if (typeof tool.execute === "function") {
433
+ ctx.diagnostics.push({
434
+ severity: "warning",
435
+ path: displayPath(ctx, entryPath),
436
+ message: '`execute` is ignored when execution is "agent"; the Cursor agent runs `script` instead.',
437
+ });
438
+ }
439
+ if (needsApprovalConfigured) {
440
+ ctx.diagnostics.push({
441
+ severity: "error",
442
+ path: displayPath(ctx, entryPath),
443
+ message: '`needsApproval` is only supported for execution: "server" tools (in-process).',
444
+ });
445
+ continue;
446
+ }
447
+ }
448
+ else if (typeof tool.execute !== "function") {
449
+ ctx.diagnostics.push({
450
+ severity: "error",
451
+ path: displayPath(ctx, entryPath),
452
+ message: 'Tools require an execute(input, ctx) function (or set execution: "agent" with a script).',
453
+ });
454
+ continue;
455
+ }
456
+ let inputSchema;
457
+ try {
458
+ inputSchema = toolInputJsonSchema(tool.inputSchema);
459
+ }
460
+ catch (error) {
461
+ ctx.diagnostics.push({
462
+ severity: "error",
463
+ path: displayPath(ctx, entryPath),
464
+ message: `Failed to convert inputSchema to JSON Schema: ${errorMessage(error)}`,
465
+ });
466
+ continue;
467
+ }
468
+ tools.push(Object.assign(Object.assign({ name, description: tool.description, inputSchema,
469
+ execution, needsApproval: needsApprovalConfigured }, (execution === "agent" && tool.script !== undefined
470
+ ? { script: tool.script }
471
+ : {})), { definition: tool }));
472
+ }
473
+ return tools;
474
+ });
475
+ }
476
+ // ============================================================================
477
+ // Skills
478
+ // ============================================================================
479
+ function loadSkills(ctx, skillsDir) {
480
+ return __awaiter(this, void 0, void 0, function* () {
481
+ var _a, _b, _c, _d, _e;
482
+ if (!(yield isDirectory(skillsDir))) {
483
+ return [];
484
+ }
485
+ const skills = [];
486
+ for (const entry of yield sortedEntries(skillsDir)) {
487
+ const entryPath = join(skillsDir, entry.name);
488
+ if (entry.isDirectory()) {
489
+ const skill = yield loadPackagedSkill(ctx, entryPath, entry.name);
490
+ if (skill !== undefined) {
491
+ skills.push(skill);
492
+ }
493
+ continue;
494
+ }
495
+ if (!entry.isFile()) {
496
+ continue;
497
+ }
498
+ if (entry.name.endsWith(".md")) {
499
+ const name = entry.name.slice(0, -".md".length);
500
+ if (!validateSkillName(ctx, name, entryPath)) {
501
+ continue;
502
+ }
503
+ const { data, body } = parseFrontmatter(yield readFile(entryPath, "utf8"));
504
+ skills.push({
505
+ name,
506
+ description: (_b = (_a = data.description) !== null && _a !== void 0 ? _a : deriveSkillDescription(body)) !== null && _b !== void 0 ? _b : SKILL_DESCRIPTION_FALLBACK(name),
507
+ markdown: body.trim(),
508
+ files: {},
509
+ });
510
+ continue;
511
+ }
512
+ if (isModuleFile(entry.name)) {
513
+ const name = moduleStem(entry.name);
514
+ if (!validateSkillName(ctx, name, entryPath)) {
515
+ continue;
516
+ }
517
+ const definition = yield importDefault(ctx, entryPath, "skill");
518
+ if (definition === undefined) {
519
+ continue;
520
+ }
521
+ const skill = definition;
522
+ const files = {};
523
+ for (const [rel, contents] of Object.entries((_c = skill.files) !== null && _c !== void 0 ? _c : {})) {
524
+ files[rel] = { contents };
525
+ }
526
+ skills.push({
527
+ name,
528
+ description: (_e = (_d = skill.description) !== null && _d !== void 0 ? _d : deriveSkillDescription(skill.markdown)) !== null && _e !== void 0 ? _e : SKILL_DESCRIPTION_FALLBACK(name),
529
+ markdown: skill.markdown.trim(),
530
+ files,
531
+ });
532
+ }
533
+ }
534
+ return skills;
535
+ });
536
+ }
537
+ function loadPackagedSkill(ctx, skillDir, name) {
538
+ return __awaiter(this, void 0, void 0, function* () {
539
+ const skillMdPath = join(skillDir, "SKILL.md");
540
+ if (!(yield isFile(skillMdPath))) {
541
+ ctx.diagnostics.push({
542
+ severity: "warning",
543
+ path: displayPath(ctx, skillDir),
544
+ message: "Skill directories must contain a SKILL.md; ignoring.",
545
+ });
546
+ return undefined;
547
+ }
548
+ if (!validateSkillName(ctx, name, skillDir)) {
549
+ return undefined;
550
+ }
551
+ const { data, body } = parseFrontmatter(yield readFile(skillMdPath, "utf8"));
552
+ if (data.description === undefined || isBlank(data.description)) {
553
+ ctx.diagnostics.push({
554
+ severity: "error",
555
+ path: displayPath(ctx, skillMdPath),
556
+ message: "Packaged skills require `description` frontmatter in SKILL.md (there is no filename slug to fall back on).",
557
+ });
558
+ return undefined;
559
+ }
560
+ const files = {};
561
+ for (const filePath of yield walkFiles(skillDir)) {
562
+ const rel = toPosix(relative(skillDir, filePath));
563
+ if (rel === "SKILL.md") {
564
+ continue;
565
+ }
566
+ files[rel] = { sourcePath: filePath };
567
+ }
568
+ return {
569
+ name,
570
+ description: data.description,
571
+ markdown: body.trim(),
572
+ files,
573
+ };
574
+ });
575
+ }
576
+ /** One-line `/v1/info` label for a connection transport. */
577
+ function connectionTransportLabel(transport) {
578
+ if ("cursorAccount" in transport) {
579
+ return transport.servers === undefined
580
+ ? "cursor-account"
581
+ : `cursor-account:${transport.servers.join(",")}`;
582
+ }
583
+ if ("agent" in transport) {
584
+ return `agent:${transport.agent}`;
585
+ }
586
+ if ("url" in transport) {
587
+ return transport.url;
588
+ }
589
+ return transport.command;
590
+ }
591
+ function connectionTransport(connection) {
592
+ if ("cursorAccount" in connection && connection.cursorAccount === true) {
593
+ return Object.assign({ cursorAccount: true }, (connection.servers === undefined
594
+ ? {}
595
+ : { servers: connection.servers }));
596
+ }
597
+ if ("agent" in connection && !isBlank(connection.agent)) {
598
+ return { agent: connection.agent };
599
+ }
600
+ if ("url" in connection && !isBlank(connection.url)) {
601
+ return Object.assign(Object.assign(Object.assign({}, (connection.type === undefined ? {} : { type: connection.type })), { url: connection.url }), (connection.headers === undefined
602
+ ? {}
603
+ : { headers: connection.headers }));
604
+ }
605
+ if ("command" in connection && !isBlank(connection.command)) {
606
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (connection.type === undefined ? {} : { type: connection.type })), { command: connection.command }), (connection.args === undefined ? {} : { args: connection.args })), (connection.env === undefined ? {} : { env: connection.env })), (connection.cwd === undefined ? {} : { cwd: connection.cwd }));
607
+ }
608
+ return undefined;
609
+ }
610
+ function validateSkillName(ctx, name, entryPath) {
611
+ if (NAME_PATTERN.test(name)) {
612
+ return true;
613
+ }
614
+ ctx.diagnostics.push({
615
+ severity: "error",
616
+ path: displayPath(ctx, entryPath),
617
+ message: `Skill name "${name}" must match ${NAME_PATTERN}.`,
618
+ });
619
+ return false;
620
+ }
621
+ /**
622
+ * Advertise the first non-empty, non-code-fence line of the body, with any
623
+ * leading `#`, `>`, `*`, or `-` markers stripped.
624
+ */
625
+ export function deriveSkillDescription(markdown) {
626
+ let inFence = false;
627
+ for (const rawLine of markdown.split(/\r?\n/)) {
628
+ const line = rawLine.trim();
629
+ if (line.startsWith("```")) {
630
+ inFence = !inFence;
631
+ continue;
632
+ }
633
+ if (inFence || line === "") {
634
+ continue;
635
+ }
636
+ const stripped = line.replace(/^[#>*\s-]+/, "").trim();
637
+ if (stripped !== "") {
638
+ return stripped.length > 200 ? `${stripped.slice(0, 197)}...` : stripped;
639
+ }
640
+ }
641
+ return undefined;
642
+ }
643
+ // ============================================================================
644
+ // MCP connections
645
+ // ============================================================================
646
+ /**
647
+ * Prefer `agent/mcp-connections/`. Keep loading `agent/connections/` with a
648
+ * deprecation warning so existing agents keep working during the rename.
649
+ */
650
+ function resolveMcpConnectionsDir(ctx, agentDir) {
651
+ return __awaiter(this, void 0, void 0, function* () {
652
+ const preferred = join(agentDir, "mcp-connections");
653
+ const legacy = join(agentDir, "connections");
654
+ const hasPreferred = yield isDirectory(preferred);
655
+ const hasLegacy = yield isDirectory(legacy);
656
+ if (hasPreferred && hasLegacy) {
657
+ ctx.diagnostics.push({
658
+ severity: "warning",
659
+ path: displayPath(ctx, legacy),
660
+ message: "Both agent/mcp-connections/ and agent/connections/ exist; using mcp-connections/ and ignoring connections/. Rename or remove the legacy directory.",
661
+ });
662
+ return preferred;
663
+ }
664
+ if (hasLegacy) {
665
+ ctx.diagnostics.push({
666
+ severity: "warning",
667
+ path: displayPath(ctx, legacy),
668
+ message: "agent/connections/ is deprecated; rename it to agent/mcp-connections/. Loading from the legacy path for now.",
669
+ });
670
+ return legacy;
671
+ }
672
+ return preferred;
673
+ });
674
+ }
675
+ function loadConnections(ctx, connectionsDir) {
676
+ return __awaiter(this, void 0, void 0, function* () {
677
+ if (!(yield isDirectory(connectionsDir))) {
678
+ return [];
679
+ }
680
+ const connections = [];
681
+ for (const entry of yield sortedEntries(connectionsDir)) {
682
+ const entryPath = join(connectionsDir, entry.name);
683
+ if (!entry.isFile() || !isModuleFile(entry.name)) {
684
+ continue;
685
+ }
686
+ const name = moduleStem(entry.name);
687
+ if (!NAME_PATTERN.test(name)) {
688
+ ctx.diagnostics.push({
689
+ severity: "error",
690
+ path: displayPath(ctx, entryPath),
691
+ message: `MCP connection name "${name}" must match ${NAME_PATTERN}.`,
692
+ });
693
+ continue;
694
+ }
695
+ const definition = yield importDefault(ctx, entryPath, "connection");
696
+ if (definition === undefined) {
697
+ continue;
698
+ }
699
+ const connection = definition;
700
+ const transport = connectionTransport(connection);
701
+ if (transport === undefined) {
702
+ ctx.diagnostics.push({
703
+ severity: "error",
704
+ path: displayPath(ctx, entryPath),
705
+ message: "MCP connections require a `url` (http/sse), a `command` (stdio), an `agent` (peer agent slug on the same serve host), or `cursorAccount: true` (the Cursor account's MCP connectors).",
706
+ });
707
+ continue;
708
+ }
709
+ if ("cursorAccount" in transport &&
710
+ transport.servers !== undefined &&
711
+ (transport.servers.length === 0 ||
712
+ transport.servers.some((server) => isBlank(server)))) {
713
+ ctx.diagnostics.push({
714
+ severity: "error",
715
+ path: displayPath(ctx, entryPath),
716
+ message: "Cursor account MCP connection `servers` must be a non-empty list of connector names (or omitted to expose every connected server).",
717
+ });
718
+ continue;
719
+ }
720
+ if ("agent" in transport && !NAME_PATTERN.test(transport.agent)) {
721
+ ctx.diagnostics.push({
722
+ severity: "error",
723
+ path: displayPath(ctx, entryPath),
724
+ message: `Peer MCP connection agent "${transport.agent}" must be a mount slug matching ${NAME_PATTERN}.`,
725
+ });
726
+ continue;
727
+ }
728
+ connections.push(Object.assign({ name,
729
+ transport }, (connection.description === undefined
730
+ ? {}
731
+ : { description: connection.description })));
732
+ }
733
+ return connections;
734
+ });
735
+ }
736
+ // ============================================================================
737
+ // Subagents
738
+ // ============================================================================
739
+ function loadSubagents(ctx, subagentsDir) {
740
+ return __awaiter(this, void 0, void 0, function* () {
741
+ if (!(yield isDirectory(subagentsDir))) {
742
+ return [];
743
+ }
744
+ const subagents = [];
745
+ for (const entry of yield sortedEntries(subagentsDir)) {
746
+ if (!entry.isDirectory()) {
747
+ continue;
748
+ }
749
+ const subagentDir = join(subagentsDir, entry.name);
750
+ if (!NAME_PATTERN.test(entry.name)) {
751
+ ctx.diagnostics.push({
752
+ severity: "error",
753
+ path: displayPath(ctx, subagentDir),
754
+ message: `Subagent name "${entry.name}" must match ${NAME_PATTERN}.`,
755
+ });
756
+ continue;
757
+ }
758
+ subagents.push(yield loadAgent(ctx, subagentDir, { name: entry.name, isRoot: false }));
759
+ }
760
+ return subagents;
761
+ });
762
+ }
763
+ function warnUnsupportedSubagentSlots(ctx, subagentDir) {
764
+ return __awaiter(this, void 0, void 0, function* () {
765
+ const unsupported = [
766
+ ["tools", "tools"],
767
+ ["skills", "skills"],
768
+ ["mcp-connections", "MCP connections"],
769
+ ["connections", "MCP connections"],
770
+ ["subagents", "nested subagents"],
771
+ ["channels", "channels"],
772
+ ["schedules", "schedules"],
773
+ ["hooks", "hooks"],
774
+ ["sandbox", "sandbox files"],
775
+ ];
776
+ for (const [slot, label] of unsupported) {
777
+ if (yield isDirectory(join(subagentDir, slot))) {
778
+ ctx.diagnostics.push({
779
+ severity: "warning",
780
+ path: displayPath(ctx, join(subagentDir, slot)),
781
+ message: `Subagent ${label} are not supported on the Cursor harness yet; the subagent runs with the parent's execution surface. Ignoring.`,
782
+ });
783
+ }
784
+ }
785
+ });
786
+ }
787
+ function warnCloudRuntimeLimitations(ctx, agentDir, counts) {
788
+ const agentPath = displayPath(ctx, join(agentDir, "agent.ts"));
789
+ if (!counts.hasCloudOptions) {
790
+ ctx.diagnostics.push({
791
+ severity: "warning",
792
+ path: agentPath,
793
+ message: 'runtime: "cloud" usually needs a `cloud` block (e.g. repos / env). Without it the Cursor cloud API may reject create.',
794
+ });
795
+ }
796
+ if (counts.serverTools > 0) {
797
+ ctx.diagnostics.push({
798
+ severity: "warning",
799
+ path: displayPath(ctx, join(agentDir, "tools")),
800
+ message: 'In-process tools (execution: "server", the default) are not available on cloud agents. Use execution: "agent", MCP connections, or tools that already live in the cloud workspace.',
801
+ });
802
+ }
803
+ if (counts.agentTools > 0) {
804
+ ctx.diagnostics.push({
805
+ severity: "warning",
806
+ path: displayPath(ctx, join(agentDir, "tools")),
807
+ message: 'Agent tools (execution: "agent") are described on the first cloud prompt (with script bodies); they are not written into the cloud VM filesystem automatically.',
808
+ });
809
+ }
810
+ if (counts.skills > 0) {
811
+ ctx.diagnostics.push({
812
+ severity: "warning",
813
+ path: displayPath(ctx, join(agentDir, "skills")),
814
+ message: "Authored skills are materialized into the local session workspace only; cloud agents see skills that already exist in the cloud repo.",
815
+ });
816
+ }
817
+ if (counts.seedFiles > 0) {
818
+ ctx.diagnostics.push({
819
+ severity: "warning",
820
+ path: displayPath(ctx, join(agentDir, "sandbox")),
821
+ message: "sandbox/workspace seed files apply to the local session workspace only; cloud agents use the configured cloud repos.",
822
+ });
823
+ }
824
+ }
825
+ // ============================================================================
826
+ // Channels
827
+ // ============================================================================
828
+ function loadChannels(ctx, channelsDir) {
829
+ return __awaiter(this, void 0, void 0, function* () {
830
+ const channels = [];
831
+ let httpChannelDefinition;
832
+ if (!(yield isDirectory(channelsDir))) {
833
+ return { channels, httpChannelDefinition };
834
+ }
835
+ for (const entry of yield sortedEntries(channelsDir)) {
836
+ const entryPath = join(channelsDir, entry.name);
837
+ if (!entry.isFile() || !isModuleFile(entry.name)) {
838
+ continue;
839
+ }
840
+ const id = moduleStem(entry.name);
841
+ if (!NAME_PATTERN.test(id)) {
842
+ ctx.diagnostics.push({
843
+ severity: "error",
844
+ path: displayPath(ctx, entryPath),
845
+ message: `Channel id "${id}" must match ${NAME_PATTERN}.`,
846
+ });
847
+ continue;
848
+ }
849
+ let mod;
850
+ try {
851
+ mod = yield ctx.importModule(entryPath);
852
+ }
853
+ catch (error) {
854
+ ctx.diagnostics.push({
855
+ severity: "error",
856
+ path: displayPath(ctx, entryPath),
857
+ message: `Failed to load module: ${errorMessage(error)}`,
858
+ });
859
+ continue;
860
+ }
861
+ const kind = getDefinitionKind(mod.default);
862
+ if (kind === "http-channel") {
863
+ if (id !== "http") {
864
+ ctx.diagnostics.push({
865
+ severity: "error",
866
+ path: displayPath(ctx, entryPath),
867
+ message: "httpChannel() configures the built-in HTTP channel and must be authored at channels/http.ts.",
868
+ });
869
+ continue;
870
+ }
871
+ httpChannelDefinition = mod.default;
872
+ continue;
873
+ }
874
+ if (kind !== "channel") {
875
+ ctx.diagnostics.push({
876
+ severity: "error",
877
+ path: displayPath(ctx, entryPath),
878
+ message: id === "http"
879
+ ? "channels/http.ts must default-export httpChannel({ ... })."
880
+ : "Channel modules must default-export defineChannel({ ... }).",
881
+ });
882
+ continue;
883
+ }
884
+ if (id === "http") {
885
+ ctx.diagnostics.push({
886
+ severity: "error",
887
+ path: displayPath(ctx, entryPath),
888
+ message: "The channel id `http` is reserved for the built-in HTTP channel; use httpChannel() to configure it.",
889
+ });
890
+ continue;
891
+ }
892
+ channels.push({ id, definition: mod.default });
893
+ }
894
+ return { channels, httpChannelDefinition };
895
+ });
896
+ }
897
+ // ============================================================================
898
+ // Schedules
899
+ // ============================================================================
900
+ function loadSchedules(ctx, schedulesDir) {
901
+ return __awaiter(this, void 0, void 0, function* () {
902
+ if (!(yield isDirectory(schedulesDir))) {
903
+ return [];
904
+ }
905
+ const schedules = [];
906
+ for (const filePath of yield walkFiles(schedulesDir)) {
907
+ const rel = toPosix(relative(schedulesDir, filePath));
908
+ if (rel.endsWith(".md")) {
909
+ const name = rel.slice(0, -".md".length);
910
+ const { data, body } = parseFrontmatter(yield readFile(filePath, "utf8"));
911
+ const cron = data.cron;
912
+ if (cron === undefined || !isValidCron(cron)) {
913
+ ctx.diagnostics.push({
914
+ severity: "error",
915
+ path: displayPath(ctx, filePath),
916
+ message: cron === undefined
917
+ ? "Markdown schedules require `cron` frontmatter."
918
+ : `Invalid cron expression: "${cron}".`,
919
+ });
920
+ continue;
921
+ }
922
+ const markdown = body.trim();
923
+ if (markdown === "") {
924
+ ctx.diagnostics.push({
925
+ severity: "error",
926
+ path: displayPath(ctx, filePath),
927
+ message: "Markdown schedules require a non-empty prompt body.",
928
+ });
929
+ continue;
930
+ }
931
+ schedules.push({
932
+ name,
933
+ cron,
934
+ kind: "markdown",
935
+ definition: {
936
+ __agentServe: "schedule",
937
+ cron,
938
+ markdown,
939
+ },
940
+ });
941
+ continue;
942
+ }
943
+ if (!isModuleFile(basename(filePath))) {
944
+ continue;
945
+ }
946
+ const name = rel.slice(0, -extname(rel).length);
947
+ const definition = yield importDefault(ctx, filePath, "schedule");
948
+ if (definition === undefined) {
949
+ continue;
950
+ }
951
+ const schedule = definition;
952
+ if ((schedule.markdown === undefined) === (schedule.run === undefined)) {
953
+ ctx.diagnostics.push({
954
+ severity: "error",
955
+ path: displayPath(ctx, filePath),
956
+ message: "Schedules require exactly one of `markdown` or `run`.",
957
+ });
958
+ continue;
959
+ }
960
+ if (!isValidCron(schedule.cron)) {
961
+ ctx.diagnostics.push({
962
+ severity: "error",
963
+ path: displayPath(ctx, filePath),
964
+ message: `Invalid cron expression: "${schedule.cron}".`,
965
+ });
966
+ continue;
967
+ }
968
+ schedules.push({
969
+ name,
970
+ cron: schedule.cron,
971
+ kind: schedule.run === undefined ? "markdown" : "run",
972
+ definition: schedule,
973
+ });
974
+ }
975
+ return schedules;
976
+ });
977
+ }
978
+ // ============================================================================
979
+ // Hooks
980
+ // ============================================================================
981
+ function loadHooks(ctx, hooksDir) {
982
+ return __awaiter(this, void 0, void 0, function* () {
983
+ if (!(yield isDirectory(hooksDir))) {
984
+ return [];
985
+ }
986
+ const hooks = [];
987
+ for (const filePath of yield walkFiles(hooksDir)) {
988
+ if (!isModuleFile(basename(filePath))) {
989
+ continue;
990
+ }
991
+ const rel = toPosix(relative(hooksDir, filePath));
992
+ const name = rel.slice(0, -extname(rel).length);
993
+ const definition = yield importDefault(ctx, filePath, "hook");
994
+ if (definition === undefined) {
995
+ continue;
996
+ }
997
+ const hook = definition;
998
+ if (typeof hook.events !== "object" ||
999
+ hook.events === null ||
1000
+ Object.keys(hook.events).length === 0) {
1001
+ ctx.diagnostics.push({
1002
+ severity: "warning",
1003
+ path: displayPath(ctx, filePath),
1004
+ message: "Hook declares no event handlers.",
1005
+ });
1006
+ continue;
1007
+ }
1008
+ hooks.push({ name, definition: hook });
1009
+ }
1010
+ return hooks;
1011
+ });
1012
+ }
1013
+ // ============================================================================
1014
+ // A/B metrics (agent/ab.ts or agent/ab/*.ts) + agent/ab.config.ts
1015
+ // ============================================================================
1016
+ function loadABs(ctx, agentDir) {
1017
+ return __awaiter(this, void 0, void 0, function* () {
1018
+ const abs = [];
1019
+ const seen = new Set();
1020
+ const single = yield findModuleFile(agentDir, "ab");
1021
+ if (single !== undefined) {
1022
+ const definition = yield importDefault(ctx, single, "ab");
1023
+ if (definition !== undefined) {
1024
+ const name = resolveABName(definition, "ab");
1025
+ seen.add(name);
1026
+ abs.push({
1027
+ name,
1028
+ definition: definition,
1029
+ });
1030
+ }
1031
+ }
1032
+ const absDir = join(agentDir, "ab");
1033
+ if (yield isDirectory(absDir)) {
1034
+ for (const filePath of yield walkFiles(absDir)) {
1035
+ if (!isModuleFile(basename(filePath))) {
1036
+ continue;
1037
+ }
1038
+ const rel = toPosix(relative(absDir, filePath));
1039
+ const stem = rel.slice(0, -extname(rel).length);
1040
+ const definition = yield importDefault(ctx, filePath, "ab");
1041
+ if (definition === undefined) {
1042
+ continue;
1043
+ }
1044
+ const name = resolveABName(definition, stem);
1045
+ if (seen.has(name)) {
1046
+ ctx.diagnostics.push({
1047
+ severity: "error",
1048
+ path: displayPath(ctx, filePath),
1049
+ message: `Duplicate A/B experiment name ${JSON.stringify(name)}.`,
1050
+ });
1051
+ continue;
1052
+ }
1053
+ seen.add(name);
1054
+ abs.push({
1055
+ name,
1056
+ definition: definition,
1057
+ });
1058
+ }
1059
+ }
1060
+ return abs;
1061
+ });
1062
+ }
1063
+ function loadABConfig(ctx, agentDir) {
1064
+ return __awaiter(this, void 0, void 0, function* () {
1065
+ const path = yield findModuleFile(agentDir, "ab.config");
1066
+ if (path === undefined) {
1067
+ return undefined;
1068
+ }
1069
+ try {
1070
+ const mod = yield ctx.importModule(path);
1071
+ if (mod.default === null || typeof mod.default !== "object") {
1072
+ ctx.diagnostics.push({
1073
+ severity: "error",
1074
+ path: displayPath(ctx, path),
1075
+ message: "ab.config.ts must default-export defineABConfig({ ... }) from @anysphere/agent-serve/ab.",
1076
+ });
1077
+ return undefined;
1078
+ }
1079
+ return mod.default;
1080
+ }
1081
+ catch (error) {
1082
+ ctx.diagnostics.push({
1083
+ severity: "error",
1084
+ path: displayPath(ctx, path),
1085
+ message: `Failed to load ab.config: ${error instanceof Error ? error.message : String(error)}`,
1086
+ });
1087
+ return undefined;
1088
+ }
1089
+ });
1090
+ }
1091
+ function resolveABName(definition, fallback) {
1092
+ if (typeof definition === "object" &&
1093
+ definition !== null &&
1094
+ "name" in definition &&
1095
+ typeof definition.name === "string" &&
1096
+ definition.name.length > 0) {
1097
+ return definition.name;
1098
+ }
1099
+ return fallback;
1100
+ }
1101
+ // ============================================================================
1102
+ // Sandbox seed files
1103
+ // ============================================================================
1104
+ function loadSeedFiles(ctx, agentDir) {
1105
+ return __awaiter(this, void 0, void 0, function* () {
1106
+ const sandboxDir = join(agentDir, "sandbox");
1107
+ for (const candidate of ["sandbox.ts", join("sandbox", "sandbox.ts")]) {
1108
+ if (yield isFile(join(agentDir, candidate))) {
1109
+ ctx.diagnostics.push({
1110
+ severity: "warning",
1111
+ path: displayPath(ctx, join(agentDir, candidate)),
1112
+ message: "Custom sandbox backends are not supported; the agent runs in the session workspace directory. Ignoring.",
1113
+ });
1114
+ }
1115
+ }
1116
+ const workspaceDir = join(sandboxDir, "workspace");
1117
+ if (!(yield isDirectory(workspaceDir))) {
1118
+ return [];
1119
+ }
1120
+ const seedFiles = [];
1121
+ for (const filePath of yield walkFiles(workspaceDir)) {
1122
+ seedFiles.push({
1123
+ relativePath: toPosix(relative(workspaceDir, filePath)),
1124
+ sourcePath: filePath,
1125
+ });
1126
+ }
1127
+ return seedFiles;
1128
+ });
1129
+ }
1130
+ // ============================================================================
1131
+ // Info projection
1132
+ // ============================================================================
1133
+ export function projectInfo(project) {
1134
+ var _a, _b, _c;
1135
+ const agent = project.agent;
1136
+ const httpRoutes = [
1137
+ { method: "POST", path: "/v1/session", url: "/v1/session" },
1138
+ {
1139
+ method: "POST",
1140
+ path: "/v1/session/:sessionId",
1141
+ url: "/v1/session/:sessionId",
1142
+ },
1143
+ {
1144
+ method: "POST",
1145
+ path: "/v1/session/:sessionId/stop",
1146
+ url: "/v1/session/:sessionId/stop",
1147
+ },
1148
+ {
1149
+ method: "GET",
1150
+ path: "/v1/session/:sessionId/stream",
1151
+ url: "/v1/session/:sessionId/stream",
1152
+ },
1153
+ {
1154
+ method: "GET",
1155
+ path: "/v1/session/:sessionId/approvals",
1156
+ url: "/v1/session/:sessionId/approvals",
1157
+ },
1158
+ {
1159
+ method: "POST",
1160
+ path: "/v1/session/:sessionId/approvals/:callId",
1161
+ url: "/v1/session/:sessionId/approvals/:callId",
1162
+ },
1163
+ ];
1164
+ return Object.assign(Object.assign({ name: project.name, model: agent.model, runtime: agent.runtime, cloud: agent.cloud === undefined ? undefined : toPublicCloudInfo(agent.cloud), local: agent.local, mcp: { path: MCP_ENDPOINT_PATH, tools: mcpEndpointToolNames(project) }, instructions: agent.instructions === undefined
1165
+ ? undefined
1166
+ : {
1167
+ chars: agent.instructions.length,
1168
+ preview: agent.instructions.length > 280
1169
+ ? `${agent.instructions.slice(0, 277)}...`
1170
+ : agent.instructions,
1171
+ }, tools: agent.tools.map((tool) => ({
1172
+ name: tool.name,
1173
+ description: tool.description,
1174
+ execution: tool.execution,
1175
+ needsApproval: tool.needsApproval,
1176
+ inputSchema: tool.inputSchema,
1177
+ })), skills: agent.skills.map((skill) => ({
1178
+ name: skill.name,
1179
+ description: skill.description,
1180
+ })), connections: agent.connections.map((connection) => ({
1181
+ name: connection.name,
1182
+ transport: connectionTransportLabel(connection.transport),
1183
+ })), subagents: agent.subagents.map((subagent) => ({
1184
+ name: subagent.name,
1185
+ description: subagent.description,
1186
+ model: subagent.model,
1187
+ })), channels: [
1188
+ { id: "http", routes: httpRoutes },
1189
+ ...project.channels.map((channel) => {
1190
+ var _a;
1191
+ const info = {
1192
+ id: channel.id,
1193
+ routes: ((_a = channel.definition.routes) !== null && _a !== void 0 ? _a : []).map((r) => {
1194
+ const routeInfo = {
1195
+ method: r.method,
1196
+ path: r.path,
1197
+ url: `/v1/channels/${channel.id}${r.path}`,
1198
+ };
1199
+ if (r.description !== undefined) {
1200
+ routeInfo.description = r.description;
1201
+ }
1202
+ if (r.bodySchema !== undefined) {
1203
+ routeInfo.bodySchema = toolInputJsonSchema(r.bodySchema);
1204
+ }
1205
+ if (r.querySchema !== undefined) {
1206
+ routeInfo.querySchema = toolInputJsonSchema(r.querySchema);
1207
+ }
1208
+ return routeInfo;
1209
+ }),
1210
+ };
1211
+ const meta = channel.definition.meta;
1212
+ if ((meta === null || meta === void 0 ? void 0 : meta.kind) !== undefined) {
1213
+ info.kind = meta.kind;
1214
+ }
1215
+ if ((meta === null || meta === void 0 ? void 0 : meta.githubWebhookEvents) !== undefined) {
1216
+ info.githubWebhookEvents = meta.githubWebhookEvents;
1217
+ }
1218
+ if ((meta === null || meta === void 0 ? void 0 : meta.slackChannelPosts) !== undefined) {
1219
+ info.slackChannelPosts = meta.slackChannelPosts;
1220
+ }
1221
+ return info;
1222
+ }),
1223
+ ], schedules: project.schedules.map((schedule) => ({
1224
+ name: schedule.name,
1225
+ cron: schedule.cron,
1226
+ kind: schedule.kind,
1227
+ })), hooks: project.hooks.map((hook) => hook.name), abs: project.abs.map((experiment) => experiment.name) }, (project.abConfig === undefined && project.abs.length === 0
1228
+ ? {}
1229
+ : {
1230
+ abConfig: {
1231
+ maxPlaygroundSessions: resolveABMaxPlaygroundSessions((_a = project.abConfig) === null || _a === void 0 ? void 0 : _a.maxPlaygroundSessions),
1232
+ durableSamples: ((_b = project.abConfig) === null || _b === void 0 ? void 0 : _b.persistSamples) !== undefined,
1233
+ durableSnapshots: ((_c = project.abConfig) === null || _c === void 0 ? void 0 : _c.persistSnapshots) !== undefined,
1234
+ },
1235
+ })), { diagnostics: project.diagnostics });
1236
+ }
1237
+ // ============================================================================
1238
+ // Shared helpers
1239
+ // ============================================================================
1240
+ function importDefault(ctx, modulePath, expectedKind) {
1241
+ return __awaiter(this, void 0, void 0, function* () {
1242
+ var _a;
1243
+ let mod;
1244
+ try {
1245
+ mod = yield ctx.importModule(modulePath);
1246
+ }
1247
+ catch (error) {
1248
+ ctx.diagnostics.push({
1249
+ severity: "error",
1250
+ path: displayPath(ctx, modulePath),
1251
+ message: `Failed to load module: ${errorMessage(error)}`,
1252
+ });
1253
+ return undefined;
1254
+ }
1255
+ const kind = getDefinitionKind(mod.default);
1256
+ if (kind !== expectedKind) {
1257
+ const helper = expectedKind === "ab"
1258
+ ? "defineAB"
1259
+ : `define${(_a = expectedKind[0]) === null || _a === void 0 ? void 0 : _a.toUpperCase()}${expectedKind.slice(1)}`;
1260
+ ctx.diagnostics.push({
1261
+ severity: "error",
1262
+ path: displayPath(ctx, modulePath),
1263
+ message: kind === undefined
1264
+ ? `Module must default-export ${helper}({ ... }).`
1265
+ : `Expected a ${expectedKind} definition but found "${kind}" (wrong authored slot?).`,
1266
+ });
1267
+ return undefined;
1268
+ }
1269
+ return mod.default;
1270
+ });
1271
+ }
1272
+ function warnUnknownSlots(ctx, agentDir) {
1273
+ return __awaiter(this, void 0, void 0, function* () {
1274
+ const known = new Set([
1275
+ "agent",
1276
+ "instructions",
1277
+ "tools",
1278
+ "skills",
1279
+ "mcp-connections",
1280
+ // Legacy slot name; resolveMcpConnectionsDir warns and still loads it.
1281
+ "connections",
1282
+ "subagents",
1283
+ "channels",
1284
+ "schedules",
1285
+ "hooks",
1286
+ "ab",
1287
+ "sandbox",
1288
+ "lib",
1289
+ // Vite playground custom tool chips (examples/*/agent/playground/tools).
1290
+ "playground",
1291
+ ]);
1292
+ for (const entry of yield sortedEntries(agentDir)) {
1293
+ if (!entry.isDirectory() || entry.name.startsWith(".")) {
1294
+ continue;
1295
+ }
1296
+ if (entry.name === "node_modules" || known.has(entry.name)) {
1297
+ continue;
1298
+ }
1299
+ // Footgun: evals live at project-root `evals/`, not under `agent/`.
1300
+ if (entry.name === "evals") {
1301
+ ctx.diagnostics.push({
1302
+ severity: "warning",
1303
+ path: displayPath(ctx, join(agentDir, entry.name)),
1304
+ message: 'Directory "evals" under agent/ is ignored — put defineEval files at project-root evals/ instead.',
1305
+ });
1306
+ continue;
1307
+ }
1308
+ ctx.diagnostics.push({
1309
+ severity: "warning",
1310
+ path: displayPath(ctx, join(agentDir, entry.name)),
1311
+ message: `Unrecognized directory "${entry.name}" under agent/ (not an authored slot; use lib/ for shared code).`,
1312
+ });
1313
+ }
1314
+ });
1315
+ }
1316
+ function hasFlatLayoutMarkers(rootDir) {
1317
+ return __awaiter(this, void 0, void 0, function* () {
1318
+ if (yield isFile(join(rootDir, "instructions.md"))) {
1319
+ return true;
1320
+ }
1321
+ return (yield findModuleFile(rootDir, "agent")) !== undefined;
1322
+ });
1323
+ }
1324
+ function readPackageName(rootDir) {
1325
+ return __awaiter(this, void 0, void 0, function* () {
1326
+ const packageJsonPath = join(rootDir, "package.json");
1327
+ if (!(yield isFile(packageJsonPath))) {
1328
+ return undefined;
1329
+ }
1330
+ try {
1331
+ const parsed = JSON.parse(yield readFile(packageJsonPath, "utf8"));
1332
+ if (typeof parsed.name === "string" && parsed.name !== "") {
1333
+ return parsed.name;
1334
+ }
1335
+ }
1336
+ catch (_a) {
1337
+ // Malformed package.json falls back to the directory name.
1338
+ }
1339
+ return undefined;
1340
+ });
1341
+ }
1342
+ function findModuleFile(dir, stem) {
1343
+ return __awaiter(this, void 0, void 0, function* () {
1344
+ for (const extension of [".ts", ".mts", ".js", ".mjs"]) {
1345
+ const candidate = join(dir, `${stem}${extension}`);
1346
+ if (yield isFile(candidate)) {
1347
+ return candidate;
1348
+ }
1349
+ }
1350
+ return undefined;
1351
+ });
1352
+ }
1353
+ function isModuleFile(fileName) {
1354
+ if (fileName.endsWith(".d.ts") || fileName.startsWith(".")) {
1355
+ return false;
1356
+ }
1357
+ return MODULE_EXTENSIONS.has(extname(fileName));
1358
+ }
1359
+ function moduleStem(fileName) {
1360
+ return fileName.slice(0, -extname(fileName).length);
1361
+ }
1362
+ function sortedEntries(dir) {
1363
+ return __awaiter(this, void 0, void 0, function* () {
1364
+ const entries = yield readdir(dir, { withFileTypes: true });
1365
+ return entries.sort((a, b) => a.name.localeCompare(b.name));
1366
+ });
1367
+ }
1368
+ function walkFiles(dir) {
1369
+ return __awaiter(this, void 0, void 0, function* () {
1370
+ const files = [];
1371
+ for (const entry of yield sortedEntries(dir)) {
1372
+ if (entry.name.startsWith(".")) {
1373
+ continue;
1374
+ }
1375
+ const entryPath = join(dir, entry.name);
1376
+ if (entry.isDirectory()) {
1377
+ files.push(...(yield walkFiles(entryPath)));
1378
+ }
1379
+ else if (entry.isFile()) {
1380
+ files.push(entryPath);
1381
+ }
1382
+ }
1383
+ return files;
1384
+ });
1385
+ }
1386
+ function isDirectory(path) {
1387
+ return __awaiter(this, void 0, void 0, function* () {
1388
+ try {
1389
+ return (yield stat(path)).isDirectory();
1390
+ }
1391
+ catch (_a) {
1392
+ return false;
1393
+ }
1394
+ });
1395
+ }
1396
+ function isFile(path) {
1397
+ return __awaiter(this, void 0, void 0, function* () {
1398
+ try {
1399
+ return (yield stat(path)).isFile();
1400
+ }
1401
+ catch (_a) {
1402
+ return false;
1403
+ }
1404
+ });
1405
+ }
1406
+ function isValidModelSetting(model) {
1407
+ if (typeof model === "string") {
1408
+ return model.trim() !== "";
1409
+ }
1410
+ return (typeof model === "object" &&
1411
+ model !== null &&
1412
+ typeof model.id === "string" &&
1413
+ model.id.trim() !== "");
1414
+ }
1415
+ function isBlank(value) {
1416
+ return typeof value !== "string" || value.trim() === "";
1417
+ }
1418
+ function toPosix(path) {
1419
+ return path.split("\\").join("/");
1420
+ }
1421
+ function displayPath(ctx, absolutePath) {
1422
+ const rel = relative(ctx.rootDir, absolutePath);
1423
+ return rel.startsWith("..") ? absolutePath : toPosix(rel);
1424
+ }
1425
+ function errorMessage(error) {
1426
+ return error instanceof Error ? error.message : String(error);
1427
+ }