@zenalexa/unicli 0.213.1 → 0.213.3

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 (350) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +4 -4
  3. package/README.zh-CN.md +3 -3
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +11 -2
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/describe.d.ts +26 -0
  8. package/dist/commands/describe.d.ts.map +1 -0
  9. package/dist/commands/describe.js +230 -0
  10. package/dist/commands/describe.js.map +1 -0
  11. package/dist/commands/dev.js +1 -1
  12. package/dist/commands/dev.js.map +1 -1
  13. package/dist/commands/dispatch.d.ts +14 -3
  14. package/dist/commands/dispatch.d.ts.map +1 -1
  15. package/dist/commands/dispatch.js +141 -81
  16. package/dist/commands/dispatch.js.map +1 -1
  17. package/dist/commands/health.d.ts.map +1 -1
  18. package/dist/commands/health.js +1 -1
  19. package/dist/commands/health.js.map +1 -1
  20. package/dist/commands/skills.d.ts.map +1 -1
  21. package/dist/commands/skills.js +1 -1
  22. package/dist/commands/skills.js.map +1 -1
  23. package/dist/constants.d.ts +2 -0
  24. package/dist/constants.d.ts.map +1 -1
  25. package/dist/constants.js +2 -0
  26. package/dist/constants.js.map +1 -1
  27. package/dist/discovery/loader.d.ts +8 -0
  28. package/dist/discovery/loader.d.ts.map +1 -1
  29. package/dist/discovery/loader.js +22 -1
  30. package/dist/discovery/loader.js.map +1 -1
  31. package/dist/engine/args.d.ts +83 -0
  32. package/dist/engine/args.d.ts.map +1 -0
  33. package/dist/engine/args.js +260 -0
  34. package/dist/engine/args.js.map +1 -0
  35. package/dist/engine/executor.d.ts +20 -1
  36. package/dist/engine/executor.d.ts.map +1 -1
  37. package/dist/engine/executor.js +11 -2
  38. package/dist/engine/executor.js.map +1 -1
  39. package/dist/engine/harden.d.ts +48 -0
  40. package/dist/engine/harden.d.ts.map +1 -0
  41. package/dist/engine/harden.js +327 -0
  42. package/dist/engine/harden.js.map +1 -0
  43. package/dist/engine/invoke.d.ts +16 -0
  44. package/dist/engine/invoke.d.ts.map +1 -0
  45. package/dist/engine/invoke.js +15 -0
  46. package/dist/engine/invoke.js.map +1 -0
  47. package/dist/engine/kernel/compile.d.ts +30 -0
  48. package/dist/engine/kernel/compile.d.ts.map +1 -0
  49. package/dist/engine/kernel/compile.js +167 -0
  50. package/dist/engine/kernel/compile.js.map +1 -0
  51. package/dist/engine/kernel/execute.d.ts +35 -0
  52. package/dist/engine/kernel/execute.d.ts.map +1 -0
  53. package/dist/engine/kernel/execute.js +221 -0
  54. package/dist/engine/kernel/execute.js.map +1 -0
  55. package/dist/engine/kernel/types.d.ts +49 -0
  56. package/dist/engine/kernel/types.d.ts.map +1 -0
  57. package/dist/engine/kernel/types.js +9 -0
  58. package/dist/engine/kernel/types.js.map +1 -0
  59. package/dist/engine/kernel/ulid.d.ts +21 -0
  60. package/dist/engine/kernel/ulid.d.ts.map +1 -0
  61. package/dist/engine/kernel/ulid.js +76 -0
  62. package/dist/engine/kernel/ulid.js.map +1 -0
  63. package/dist/engine/template.d.ts.map +1 -1
  64. package/dist/engine/template.js +11 -0
  65. package/dist/engine/template.js.map +1 -1
  66. package/dist/manifest.json +1 -1
  67. package/dist/mcp/dispatch.d.ts +46 -0
  68. package/dist/mcp/dispatch.d.ts.map +1 -0
  69. package/dist/mcp/dispatch.js +109 -0
  70. package/dist/mcp/dispatch.js.map +1 -0
  71. package/dist/mcp/handler.d.ts +30 -0
  72. package/dist/mcp/handler.d.ts.map +1 -0
  73. package/dist/mcp/handler.js +293 -0
  74. package/dist/mcp/handler.js.map +1 -0
  75. package/dist/mcp/http-transport.d.ts +16 -0
  76. package/dist/mcp/http-transport.d.ts.map +1 -0
  77. package/dist/mcp/http-transport.js +124 -0
  78. package/dist/mcp/http-transport.js.map +1 -0
  79. package/dist/mcp/server.d.ts +17 -33
  80. package/dist/mcp/server.d.ts.map +1 -1
  81. package/dist/mcp/server.js +31 -742
  82. package/dist/mcp/server.js.map +1 -1
  83. package/dist/mcp/sse-transport.js.map +1 -1
  84. package/dist/mcp/streamable-http/handle-post.d.ts +23 -0
  85. package/dist/mcp/streamable-http/handle-post.d.ts.map +1 -0
  86. package/dist/mcp/streamable-http/handle-post.js +357 -0
  87. package/dist/mcp/streamable-http/handle-post.js.map +1 -0
  88. package/dist/mcp/streamable-http/index.d.ts +45 -0
  89. package/dist/mcp/streamable-http/index.d.ts.map +1 -0
  90. package/dist/mcp/streamable-http/index.js +150 -0
  91. package/dist/mcp/streamable-http/index.js.map +1 -0
  92. package/dist/mcp/streamable-http/session.d.ts +85 -0
  93. package/dist/mcp/streamable-http/session.d.ts.map +1 -0
  94. package/dist/mcp/streamable-http/session.js +104 -0
  95. package/dist/mcp/streamable-http/session.js.map +1 -0
  96. package/dist/mcp/streamable-http.d.ts +7 -85
  97. package/dist/mcp/streamable-http.d.ts.map +1 -1
  98. package/dist/mcp/streamable-http.js +6 -568
  99. package/dist/mcp/streamable-http.js.map +1 -1
  100. package/dist/mcp/tools.d.ts +57 -0
  101. package/dist/mcp/tools.d.ts.map +1 -0
  102. package/dist/mcp/tools.js +237 -0
  103. package/dist/mcp/tools.js.map +1 -0
  104. package/dist/output/envelope.d.ts +29 -0
  105. package/dist/output/envelope.d.ts.map +1 -1
  106. package/dist/output/envelope.js +6 -0
  107. package/dist/output/envelope.js.map +1 -1
  108. package/dist/output/next-actions.d.ts +18 -0
  109. package/dist/output/next-actions.d.ts.map +1 -0
  110. package/dist/output/next-actions.js +64 -0
  111. package/dist/output/next-actions.js.map +1 -0
  112. package/dist/output/projection.d.ts +93 -0
  113. package/dist/output/projection.d.ts.map +1 -0
  114. package/dist/output/projection.js +255 -0
  115. package/dist/output/projection.js.map +1 -0
  116. package/dist/protocol/acp-helpers.d.ts +32 -0
  117. package/dist/protocol/acp-helpers.d.ts.map +1 -0
  118. package/dist/protocol/acp-helpers.js +175 -0
  119. package/dist/protocol/acp-helpers.js.map +1 -0
  120. package/dist/protocol/acp.d.ts +2 -27
  121. package/dist/protocol/acp.d.ts.map +1 -1
  122. package/dist/protocol/acp.js +7 -170
  123. package/dist/protocol/acp.js.map +1 -1
  124. package/dist/types.d.ts +32 -0
  125. package/dist/types.d.ts.map +1 -1
  126. package/dist/types.js.map +1 -1
  127. package/package.json +13 -2
  128. package/src/adapters/1688/item.yaml +1 -0
  129. package/src/adapters/1688/store.yaml +1 -0
  130. package/src/adapters/36kr/article.yaml +1 -0
  131. package/src/adapters/amazon/bestsellers.yaml +2 -0
  132. package/src/adapters/amazon/movers-shakers.yaml +2 -0
  133. package/src/adapters/amazon/new-releases.yaml +2 -0
  134. package/src/adapters/amazon/rankings.yaml +1 -0
  135. package/src/adapters/apple-podcasts/episodes.yaml +1 -0
  136. package/src/adapters/arxiv/paper.yaml +1 -0
  137. package/src/adapters/audacity/convert.yaml +1 -0
  138. package/src/adapters/audacity/effects.yaml +1 -0
  139. package/src/adapters/audacity/info.yaml +1 -0
  140. package/src/adapters/audacity/mix.yaml +1 -0
  141. package/src/adapters/audacity/normalize.yaml +1 -0
  142. package/src/adapters/audacity/spectrogram.yaml +1 -0
  143. package/src/adapters/audacity/split-channels.yaml +1 -0
  144. package/src/adapters/audacity/trim.yaml +1 -0
  145. package/src/adapters/bilibili/favorites.yaml +1 -0
  146. package/src/adapters/blender/animation.yaml +2 -0
  147. package/src/adapters/blender/camera.yaml +1 -0
  148. package/src/adapters/blender/convert.yaml +1 -0
  149. package/src/adapters/blender/export.yaml +1 -0
  150. package/src/adapters/blender/import.yaml +1 -0
  151. package/src/adapters/blender/info.yaml +1 -0
  152. package/src/adapters/blender/lighting.yaml +1 -0
  153. package/src/adapters/blender/materials.yaml +1 -0
  154. package/src/adapters/blender/objects.yaml +1 -0
  155. package/src/adapters/blender/render.yaml +2 -0
  156. package/src/adapters/blender/scene.yaml +1 -0
  157. package/src/adapters/blender/screenshot.yaml +2 -0
  158. package/src/adapters/blender/script.yaml +1 -0
  159. package/src/adapters/boss/detail.yaml +2 -0
  160. package/src/adapters/cloudcompare/info.yaml +1 -0
  161. package/src/adapters/coupang/add-to-cart.yaml +1 -0
  162. package/src/adapters/ctrip/search.yaml +1 -0
  163. package/src/adapters/douban/download.yaml +1 -0
  164. package/src/adapters/douban/photos.yaml +1 -0
  165. package/src/adapters/douban/subject.yaml +2 -0
  166. package/src/adapters/doubao-web/detail.yaml +1 -0
  167. package/src/adapters/doubao-web/meeting-summary.yaml +1 -0
  168. package/src/adapters/doubao-web/meeting-transcript.yaml +1 -0
  169. package/src/adapters/drawio/export.yaml +2 -0
  170. package/src/adapters/facebook/join-group.yaml +2 -0
  171. package/src/adapters/ffmpeg/compress.yaml +2 -0
  172. package/src/adapters/ffmpeg/concat.yaml +1 -0
  173. package/src/adapters/ffmpeg/convert.yaml +1 -0
  174. package/src/adapters/ffmpeg/extract-audio.yaml +2 -0
  175. package/src/adapters/ffmpeg/gif.yaml +2 -0
  176. package/src/adapters/ffmpeg/normalize.yaml +2 -0
  177. package/src/adapters/ffmpeg/probe.yaml +1 -0
  178. package/src/adapters/ffmpeg/resize.yaml +2 -0
  179. package/src/adapters/ffmpeg/subtitles.yaml +2 -0
  180. package/src/adapters/ffmpeg/thumbnail.yaml +2 -0
  181. package/src/adapters/ffmpeg/trim.yaml +2 -0
  182. package/src/adapters/freecad/assembly.yaml +1 -0
  183. package/src/adapters/freecad/bom.yaml +1 -0
  184. package/src/adapters/freecad/boolean.yaml +1 -0
  185. package/src/adapters/freecad/check.yaml +1 -0
  186. package/src/adapters/freecad/convert.yaml +1 -0
  187. package/src/adapters/freecad/export-stl.yaml +1 -0
  188. package/src/adapters/freecad/import.yaml +1 -0
  189. package/src/adapters/freecad/info.yaml +1 -0
  190. package/src/adapters/freecad/macro.yaml +1 -0
  191. package/src/adapters/freecad/measure.yaml +1 -0
  192. package/src/adapters/freecad/mesh.yaml +1 -0
  193. package/src/adapters/freecad/properties.yaml +1 -0
  194. package/src/adapters/freecad/render.yaml +1 -0
  195. package/src/adapters/freecad/section.yaml +1 -0
  196. package/src/adapters/freecad/sketch.yaml +1 -0
  197. package/src/adapters/gimp/adjust.yaml +1 -0
  198. package/src/adapters/gimp/batch.yaml +1 -0
  199. package/src/adapters/gimp/convert.yaml +1 -0
  200. package/src/adapters/gimp/crop.yaml +1 -0
  201. package/src/adapters/gimp/filter.yaml +1 -0
  202. package/src/adapters/gimp/flip.yaml +1 -0
  203. package/src/adapters/gimp/info.yaml +1 -0
  204. package/src/adapters/gimp/layers.yaml +1 -0
  205. package/src/adapters/gimp/merge-layers.yaml +1 -0
  206. package/src/adapters/gimp/resize.yaml +1 -0
  207. package/src/adapters/gimp/rotate.yaml +1 -0
  208. package/src/adapters/gimp/text.yaml +1 -0
  209. package/src/adapters/godot/scene-export.yaml +1 -0
  210. package/src/adapters/hackernews/comments.yaml +1 -0
  211. package/src/adapters/hackernews/item.yaml +1 -0
  212. package/src/adapters/hf/top.yaml +1 -0
  213. package/src/adapters/imagemagick/composite.yaml +1 -0
  214. package/src/adapters/imagemagick/convert.yaml +1 -0
  215. package/src/adapters/imagemagick/identify.yaml +1 -0
  216. package/src/adapters/imagemagick/montage.yaml +1 -0
  217. package/src/adapters/imagemagick/resize.yaml +1 -0
  218. package/src/adapters/imdb/person.yaml +1 -0
  219. package/src/adapters/imdb/reviews.yaml +1 -0
  220. package/src/adapters/imdb/title.yaml +1 -0
  221. package/src/adapters/inkscape/convert.yaml +2 -0
  222. package/src/adapters/inkscape/export.yaml +2 -0
  223. package/src/adapters/inkscape/optimize.yaml +2 -0
  224. package/src/adapters/instagram/stories.yaml +1 -0
  225. package/src/adapters/jd/item.yaml +1 -0
  226. package/src/adapters/jike/post.yaml +2 -0
  227. package/src/adapters/jike/topic.yaml +2 -0
  228. package/src/adapters/kdenlive/info.yaml +1 -0
  229. package/src/adapters/kdenlive/render.yaml +1 -0
  230. package/src/adapters/krita/batch.yaml +1 -0
  231. package/src/adapters/krita/convert.yaml +1 -0
  232. package/src/adapters/krita/export.yaml +1 -0
  233. package/src/adapters/krita/info.yaml +1 -0
  234. package/src/adapters/libreoffice/convert.yaml +1 -0
  235. package/src/adapters/libreoffice/print.yaml +1 -0
  236. package/src/adapters/linear/issue-update.yaml +1 -0
  237. package/src/adapters/linux-do/category.yaml +1 -0
  238. package/src/adapters/linux-do/topic.yaml +1 -0
  239. package/src/adapters/macos/calendar-create.yaml +1 -0
  240. package/src/adapters/macos/finder-copy.yaml +1 -0
  241. package/src/adapters/macos/finder-move.yaml +1 -0
  242. package/src/adapters/macos/finder-new-folder.yaml +1 -0
  243. package/src/adapters/macos/finder-tags.yaml +1 -0
  244. package/src/adapters/macos/open.yaml +2 -0
  245. package/src/adapters/macos/screen-recording.yaml +1 -0
  246. package/src/adapters/macos/screenshot.yaml +1 -0
  247. package/src/adapters/macos/spotlight.yaml +1 -0
  248. package/src/adapters/macos/wallpaper.yaml +1 -0
  249. package/src/adapters/medium/article.yaml +1 -0
  250. package/src/adapters/mermaid/render.yaml +1 -0
  251. package/src/adapters/minimax/tts.yaml +1 -0
  252. package/src/adapters/motion-studio/component-get.yaml +1 -0
  253. package/src/adapters/musescore/convert.yaml +2 -0
  254. package/src/adapters/musescore/export.yaml +2 -0
  255. package/src/adapters/musescore/info.yaml +1 -0
  256. package/src/adapters/musescore/instruments.yaml +1 -0
  257. package/src/adapters/musescore/transpose.yaml +1 -0
  258. package/src/adapters/netease-music/playlist.yaml +1 -0
  259. package/src/adapters/netease-music/top.yaml +1 -0
  260. package/src/adapters/notebooklm/get.yaml +1 -0
  261. package/src/adapters/notebooklm/history.yaml +1 -0
  262. package/src/adapters/notebooklm/note-list.yaml +1 -0
  263. package/src/adapters/notebooklm/notes-get.yaml +1 -0
  264. package/src/adapters/notebooklm/open.yaml +1 -0
  265. package/src/adapters/notebooklm/source-fulltext.yaml +1 -0
  266. package/src/adapters/notebooklm/source-get.yaml +1 -0
  267. package/src/adapters/notebooklm/source-guide.yaml +1 -0
  268. package/src/adapters/notebooklm/source-list.yaml +1 -0
  269. package/src/adapters/notebooklm/summary.yaml +1 -0
  270. package/src/adapters/novita/status.yaml +1 -0
  271. package/src/adapters/obs/screenshot.yaml +1 -0
  272. package/src/adapters/obsidian/open.yaml +1 -0
  273. package/src/adapters/ones/login.yaml +1 -0
  274. package/src/adapters/ones/task.yaml +1 -0
  275. package/src/adapters/pandoc/convert.yaml +1 -0
  276. package/src/adapters/paperreview/feedback.yaml +2 -0
  277. package/src/adapters/paperreview/review.yaml +2 -0
  278. package/src/adapters/paperreview/submit.yaml +2 -0
  279. package/src/adapters/pixiv/detail.yaml +1 -0
  280. package/src/adapters/pixiv/download.yaml +2 -0
  281. package/src/adapters/quark/ls.yaml +1 -0
  282. package/src/adapters/reddit/comments.yaml +2 -0
  283. package/src/adapters/renderdoc/capture-list.yaml +1 -0
  284. package/src/adapters/renderdoc/frame-export.yaml +1 -0
  285. package/src/adapters/reuters/article.yaml +2 -0
  286. package/src/adapters/shotcut/info.yaml +1 -0
  287. package/src/adapters/shotcut/render.yaml +1 -0
  288. package/src/adapters/sinablog/article.yaml +1 -0
  289. package/src/adapters/sinablog/user.yaml +1 -0
  290. package/src/adapters/sketch/artboards.yaml +1 -0
  291. package/src/adapters/sketch/export.yaml +1 -0
  292. package/src/adapters/sketch/symbols.yaml +1 -0
  293. package/src/adapters/smzdm/article.yaml +1 -0
  294. package/src/adapters/stackoverflow/question.yaml +1 -0
  295. package/src/adapters/stagehand/wrap-observe.yaml +1 -0
  296. package/src/adapters/steam/wishlist.yaml +1 -0
  297. package/src/adapters/tieba/read.yaml +1 -0
  298. package/src/adapters/tiktok/comment.yaml +1 -0
  299. package/src/adapters/tiktok/like.yaml +1 -0
  300. package/src/adapters/tiktok/save.yaml +1 -0
  301. package/src/adapters/tiktok/unlike.yaml +1 -0
  302. package/src/adapters/tiktok/unsave.yaml +1 -0
  303. package/src/adapters/twitch/streams.yaml +1 -0
  304. package/src/adapters/twitter/quotes.yaml +2 -0
  305. package/src/adapters/twitter/retweets.yaml +1 -0
  306. package/src/adapters/v2ex/replies.yaml +1 -0
  307. package/src/adapters/v2ex/topic.yaml +1 -0
  308. package/src/adapters/vscode/install-ext.yaml +1 -0
  309. package/src/adapters/vscode/open.yaml +1 -0
  310. package/src/adapters/web/read.yaml +1 -0
  311. package/src/adapters/weibo/comments.yaml +1 -0
  312. package/src/adapters/weibo/post.yaml +1 -0
  313. package/src/adapters/weixin/download.yaml +1 -0
  314. package/src/adapters/wiremock/create-stub.yaml +2 -0
  315. package/src/adapters/wiremock/delete-stub.yaml +1 -0
  316. package/src/adapters/wiremock/verify.yaml +1 -0
  317. package/src/adapters/xianyu/item.yaml +1 -0
  318. package/src/adapters/xiaoe/catalog.yaml +1 -0
  319. package/src/adapters/xiaoe/content.yaml +1 -0
  320. package/src/adapters/xiaoe/detail.yaml +1 -0
  321. package/src/adapters/xiaoe/play-url.yaml +1 -0
  322. package/src/adapters/xiaoyuzhou/podcast.yaml +2 -0
  323. package/src/adapters/yollomi/edit.yaml +2 -0
  324. package/src/adapters/yollomi/remove-bg.yaml +2 -0
  325. package/src/adapters/yollomi/restore.yaml +2 -0
  326. package/src/adapters/yollomi/upload.yaml +2 -0
  327. package/src/adapters/yollomi/upscale.yaml +2 -0
  328. package/src/adapters/youtube/playlist.yaml +1 -0
  329. package/src/adapters/yt-dlp/download.yaml +2 -0
  330. package/src/adapters/yt-dlp/extract-audio.yaml +2 -0
  331. package/src/adapters/yt-dlp/info.yaml +1 -0
  332. package/src/adapters/zhihu/answer.yaml +1 -0
  333. package/src/adapters/zhihu/answers.yaml +2 -0
  334. package/src/adapters/zhihu/article.yaml +1 -0
  335. package/src/adapters/zhihu/articles.yaml +2 -0
  336. package/src/adapters/zhihu/collections.yaml +2 -0
  337. package/src/adapters/zhihu/columns.yaml +2 -0
  338. package/src/adapters/zhihu/comment.yaml +1 -0
  339. package/src/adapters/zhihu/download.yaml +1 -0
  340. package/src/adapters/zhihu/followers.yaml +2 -0
  341. package/src/adapters/zhihu/following.yaml +2 -0
  342. package/src/adapters/zhihu/pins.yaml +2 -0
  343. package/src/adapters/zhihu/question.yaml +1 -0
  344. package/src/adapters/zhihu/topic.yaml +1 -0
  345. package/src/adapters/zhihu/topics.yaml +1 -0
  346. package/src/adapters/zhihu/user.yaml +2 -0
  347. package/src/adapters/zoom/join.yaml +1 -0
  348. package/src/adapters/zsxq/search.yaml +1 -0
  349. package/src/adapters/zsxq/topic.yaml +1 -0
  350. package/src/adapters/zsxq/topics.yaml +1 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * Input hardening — agents hallucinate differently from humans. A typo
3
+ * like `../../../.ssh` is near-impossible for a person but routine for an
4
+ * LLM confusing path segments. This module validates the resolved ArgBag
5
+ * against the schema the adapter *declares*, not regex heuristics on arg
6
+ * names (v0.213.3: D5 locked — no fallback to `looksLike*`).
7
+ *
8
+ * Dispatch order for each string arg:
9
+ * 1. Always-on: ASCII control-char check (below 0x20, except \t\n\r)
10
+ * 2. `format: "uri"` (+ the other draft-2020-12 standard formats)
11
+ * → ajv format-assertion — fails closed
12
+ * 3. `x-unicli-kind: "path"` → validatePathArg (traversal + NUL + sandbox)
13
+ * 4. `x-unicli-kind: "adapter-ref"` → `<site>/<command>` regex
14
+ * 5. `x-unicli-kind: "selector"` → reject `<script` or unescaped backtick
15
+ * 6. `x-unicli-kind: "shell-safe"` → reject `$` `` ` `` `;` `|` `&` `>`
16
+ * 7. `x-unicli-kind: "id"` → reject URL punctuation (`?` `#`) and
17
+ * percent-escapes; IDs are bare tokens
18
+ * 8. If a kind check fails, `x-unicli-accepts` lists secondary kinds
19
+ * that can salvage the value (dual-accept fallback).
20
+ * 9. No format / kind declared → freeform; only the control-char gate
21
+ * applies (codemod in Phase 4 migrates YAML adapters; unannotated
22
+ * args stay permissive until then).
23
+ *
24
+ * Violations throw `InputHardeningError` with a directional suggestion
25
+ * that completes the self-repair contract (Banach convergence principle).
26
+ *
27
+ * NOTE: kept the `InputHardeningError` class and its `{argName, suggestion}`
28
+ * fields intact — MCP/ACP surfaces depend on them for `structuredContent`.
29
+ */
30
+ import { isAbsolute, resolve as resolvePath, relative, sep } from "node:path";
31
+ import Ajv2020 from "ajv/dist/2020.js";
32
+ import addFormats from "ajv-formats";
33
+ export class InputHardeningError extends Error {
34
+ argName;
35
+ suggestion;
36
+ constructor(message, argName, suggestion) {
37
+ super(message);
38
+ this.argName = argName;
39
+ this.suggestion = suggestion;
40
+ this.name = "InputHardeningError";
41
+ }
42
+ }
43
+ /** Does the value contain an ASCII control char we never want to see? */
44
+ function hasControlChars(value) {
45
+ // Allow \t (0x09), \n (0x0A), \r (0x0D); reject anything else <0x20 or DEL (0x7F).
46
+ for (let i = 0; i < value.length; i++) {
47
+ const c = value.charCodeAt(i);
48
+ if ((c < 0x20 && c !== 0x09 && c !== 0x0a && c !== 0x0d) || c === 0x7f) {
49
+ return true;
50
+ }
51
+ }
52
+ return false;
53
+ }
54
+ /**
55
+ * Sandbox a path to the current working directory. Absolute paths outside
56
+ * CWD / home-dir, or any path that escapes CWD via `..`, are rejected.
57
+ * Explicit home-dir paths (starting with `~`) are allowed after expansion.
58
+ */
59
+ function validatePathArg(name, value) {
60
+ if (value.includes("\0")) {
61
+ throw new InputHardeningError(`path arg "${name}" contains NUL byte`, name, "remove NUL bytes and retry; NUL is never valid in filesystem paths");
62
+ }
63
+ // Expand ~ manually; node doesn't do it for us.
64
+ let expanded = value;
65
+ if (expanded.startsWith("~")) {
66
+ expanded =
67
+ (process.env.HOME ?? process.env.USERPROFILE ?? "") + expanded.slice(1);
68
+ }
69
+ const cwd = process.cwd();
70
+ // Always run through resolvePath so mixed `/` and `\` separators normalize
71
+ // to the platform's canonical form before any prefix comparison. Without
72
+ // this, a Windows caller passing `${USERPROFILE}/file.txt` (the literal
73
+ // shape Node emits when interpolating $HOME on win32) leaves a mid-path `/`
74
+ // that the normalized `homeDir + sep` ("\\") prefix-match cannot see.
75
+ const abs = resolvePath(cwd, expanded);
76
+ const rel = relative(cwd, abs);
77
+ // Rejected if the relative path starts with `..` AND also isn't within
78
+ // the user's home directory (agents often legitimately target ~/.unicli).
79
+ // Use strict boundary match (dir === base || startsWith(base + sep)) so
80
+ // `$HOME=/Users/foo` does NOT match `/Users/foobar/...` — raw `startsWith`
81
+ // would allow a prefix-collision escape on shared machines.
82
+ const homeRaw = process.env.HOME ?? process.env.USERPROFILE ?? "";
83
+ const homeDir = homeRaw ? resolvePath(homeRaw) : "";
84
+ const withinHome = Boolean(homeDir && (abs === homeDir || abs.startsWith(homeDir + sep)));
85
+ const withinCwd = !rel.startsWith("..") && !isAbsolute(rel);
86
+ if (!withinCwd && !withinHome) {
87
+ throw new InputHardeningError(`path arg "${name}" escapes CWD and is not inside $HOME: "${value}"`, name, `pass a path inside ${cwd} or inside $HOME (${homeDir})`);
88
+ }
89
+ }
90
+ /** `<site>/<command>` token (alphanumeric + _ - on each side). */
91
+ function validateAdapterRefArg(name, value) {
92
+ if (!/^[a-z0-9_-]+\/[a-z0-9_-]+$/.test(value)) {
93
+ throw new InputHardeningError(`adapter-ref arg "${name}" must match "<site>/<command>": "${value}"`, name, "pass the adapter reference as `<site>/<command>` (lowercase alphanumerics, `_`, `-`)");
94
+ }
95
+ }
96
+ /** CSS/XPath-ish selector — reject the two punctuations agents use to smuggle code. */
97
+ function validateSelectorArg(name, value) {
98
+ if (/<script/i.test(value)) {
99
+ throw new InputHardeningError(`selector arg "${name}" contains "<script" — likely XSS payload: "${value}"`, name, "pass a bare CSS or XPath selector; never include HTML tags");
100
+ }
101
+ // Reject any backtick — `querySelector` does not need them and they are
102
+ // the classic JS template-literal escape.
103
+ if (/`/.test(value)) {
104
+ throw new InputHardeningError(`selector arg "${name}" contains backtick — selectors never need them: "${value}"`, name, "remove backticks; use single or double quotes in attribute selectors");
105
+ }
106
+ }
107
+ /**
108
+ * Resource id token — reject anything that is a URL fragment rather than a
109
+ * bare identifier. Agents frequently paste a full URL into an `id` slot; the
110
+ * adapter then either double-encodes it or 404s. We reject `?`/`#` (query or
111
+ * fragment) and `%XX` (already URL-encoded). Adapters that legitimately accept
112
+ * both a bare id AND a URL declare `x-unicli-accepts: [url]` so the URL
113
+ * salvage path kicks in.
114
+ */
115
+ function validateIdArg(name, value) {
116
+ if (/[?#]/.test(value)) {
117
+ throw new InputHardeningError(`id arg "${name}" contains URL punctuation (? or #): "${value}"`, name, "strip query string/fragment — resource ids are bare tokens, not URLs");
118
+ }
119
+ if (/%[0-9a-fA-F]{2}/.test(value)) {
120
+ throw new InputHardeningError(`id arg "${name}" contains URL-encoded characters (%XX): "${value}"`, name, "strip query string/fragment — resource ids are bare tokens, not URLs");
121
+ }
122
+ // A full URL ("https://…") is not a bare id. Adapters that legitimately
123
+ // accept both a token and a URL declare `x-unicli-accepts: [url]`; the
124
+ // caller's try/catch salvage path picks that up without widening this
125
+ // validator's contract.
126
+ if (/^[a-z][a-z0-9+.-]*:\/\//i.test(value)) {
127
+ throw new InputHardeningError(`id arg "${name}" looks like a URL ("${value}") but kind is "id"`, name, "strip query string/fragment — resource ids are bare tokens, not URLs");
128
+ }
129
+ }
130
+ /** Shell-safe string — reject the injection chars a subprocess arg would expand. */
131
+ function validateShellSafeArg(name, value) {
132
+ // The order of chars in the regex is irrelevant — we reject any occurrence.
133
+ // Keep `>` even though stdout redirection requires adjacent space; an
134
+ // agent that wrote `>` in a shell-safe arg has already misunderstood it.
135
+ if (/[$`;|&>]/.test(value)) {
136
+ throw new InputHardeningError(`shell-safe arg "${name}" contains shell metacharacter ($ \` ; | & >): "${value}"`, name, "pass only literal values; the adapter will construct any subprocess args safely");
137
+ }
138
+ }
139
+ /** Warn (non-throwing) when a URL arg looks double-encoded. */
140
+ function warnDoubleEncoded(name, value) {
141
+ // Look for %25 followed by two hex — that's `%` itself being encoded twice.
142
+ if (/%25[0-9a-fA-F]{2}/.test(value)) {
143
+ return `arg "${name}" looks double-URL-encoded (contains %25XX). Pass a single-encoded or raw URL.`;
144
+ }
145
+ return undefined;
146
+ }
147
+ /** Treat URL fallback as "succeeds if it parses as an http(s) URL". */
148
+ function tryAcceptUrl(value) {
149
+ try {
150
+ const u = new URL(value);
151
+ return u.protocol === "http:" || u.protocol === "https:";
152
+ }
153
+ catch {
154
+ return false;
155
+ }
156
+ }
157
+ /** Treat ID fallback as "succeeds if it has no URL punctuation and no percent-escapes". */
158
+ function tryAcceptId(value) {
159
+ return !/[?#]/.test(value) && !/%[0-9a-fA-F]{2}/.test(value);
160
+ }
161
+ let cachedFormatValidators;
162
+ /**
163
+ * Lazy-init ajv with the draft-2020-12 format-assertion vocabulary and
164
+ * build one compiled validator per standard format. Ajv treats `format` as
165
+ * an annotation by default — opting into `meta/format-assertion` is what
166
+ * makes it fail-closed (spec §7.3).
167
+ *
168
+ * Module-level so that per-arg validation is O(1) once the first call has
169
+ * primed the cache. The cost is bounded (7 validators total).
170
+ */
171
+ function getFormatValidators() {
172
+ if (cachedFormatValidators)
173
+ return cachedFormatValidators;
174
+ // Normalise CJS/ESM interop: Node wraps `module.exports = class` as a
175
+ // default-keyed namespace when imported into an ESM file.
176
+ const AjvCtor = (Ajv2020.default ??
177
+ Ajv2020);
178
+ const addFormatsFn = (addFormats
179
+ .default ?? addFormats);
180
+ // `validateFormats: true` with `mode: "full"` makes `format:` a hard
181
+ // precondition rather than a silent annotation (JSON Schema draft-2020-12
182
+ // format-assertion semantics, §7.3).
183
+ const ajv = new AjvCtor({
184
+ strict: true,
185
+ allErrors: false,
186
+ validateFormats: true,
187
+ });
188
+ addFormatsFn(ajv, { mode: "full" });
189
+ const formats = [
190
+ "uri",
191
+ "uuid",
192
+ "date-time",
193
+ "email",
194
+ "hostname",
195
+ "ipv4",
196
+ "ipv6",
197
+ "regex",
198
+ ];
199
+ const map = new Map();
200
+ for (const f of formats) {
201
+ const schema = {
202
+ $schema: "https://json-schema.org/draft/2020-12/schema",
203
+ type: "string",
204
+ format: f,
205
+ };
206
+ map.set(f, ajv.compile(schema));
207
+ }
208
+ cachedFormatValidators = map;
209
+ return map;
210
+ }
211
+ function validateFormatArg(name, value, format) {
212
+ const validator = getFormatValidators().get(format);
213
+ if (!validator)
214
+ return;
215
+ const ok = validator(value);
216
+ if (ok)
217
+ return;
218
+ const detail = validator.errors?.[0]?.message ?? `does not match format "${format}"`;
219
+ throw new InputHardeningError(`arg "${name}" ${detail}: "${value}"`, name, `pass a value matching JSON Schema format "${format}"`);
220
+ }
221
+ function validateKind(name, value, kind) {
222
+ switch (kind) {
223
+ case "path":
224
+ validatePathArg(name, value);
225
+ return;
226
+ case "adapter-ref":
227
+ validateAdapterRefArg(name, value);
228
+ return;
229
+ case "selector":
230
+ validateSelectorArg(name, value);
231
+ return;
232
+ case "shell-safe":
233
+ validateShellSafeArg(name, value);
234
+ return;
235
+ case "id":
236
+ validateIdArg(name, value);
237
+ return;
238
+ }
239
+ }
240
+ /**
241
+ * Validate the resolved ArgBag against the adapter schema. Returns any
242
+ * non-fatal warnings (double-encoded URLs, etc.); throws InputHardeningError
243
+ * for anything unsafe.
244
+ *
245
+ * `argByName` is the Map already built by the invocation kernel. Callers
246
+ * that hold the raw `AdapterArg[]` can pass it directly — the function
247
+ * tolerates either shape via an internal normalisation.
248
+ */
249
+ export function hardenArgs(args, schemaOrMap) {
250
+ const warnings = [];
251
+ const byName = schemaOrMap instanceof Map
252
+ ? schemaOrMap
253
+ : new Map(schemaOrMap.map((a) => [a.name, a]));
254
+ for (const [name, raw] of Object.entries(args)) {
255
+ if (typeof raw !== "string")
256
+ continue;
257
+ const value = raw;
258
+ // Always-on control-char gate — applies regardless of kind declaration.
259
+ if (hasControlChars(value)) {
260
+ throw new InputHardeningError(`arg "${name}" contains control characters (ASCII <0x20 or 0x7F)`, name, "remove control characters; only \\t \\n \\r are allowed in string args");
261
+ }
262
+ const declared = byName.get(name);
263
+ if (!declared)
264
+ continue; // unknown field — left freeform until codemod
265
+ // Standard-vocab format check (fails closed).
266
+ if (declared.format) {
267
+ try {
268
+ validateFormatArg(name, value, declared.format);
269
+ }
270
+ catch (err) {
271
+ if (!(err instanceof InputHardeningError))
272
+ throw err;
273
+ // If the format is `uri` and dual-accept lists `id`, allow a bare
274
+ // token to pass; otherwise rethrow.
275
+ const accepts = declared["x-unicli-accepts"] ?? [];
276
+ if (declared.format === "uri" && accepts.includes("id")) {
277
+ if (tryAcceptId(value)) {
278
+ // primary failed but secondary passed
279
+ }
280
+ else {
281
+ throw err;
282
+ }
283
+ }
284
+ else {
285
+ throw err;
286
+ }
287
+ }
288
+ // Double-URL-encoding warning applies even on success.
289
+ if (declared.format === "uri") {
290
+ const w = warnDoubleEncoded(name, value);
291
+ if (w)
292
+ warnings.push(w);
293
+ }
294
+ continue;
295
+ }
296
+ // Bespoke kind dispatch.
297
+ const kind = declared["x-unicli-kind"];
298
+ if (kind) {
299
+ try {
300
+ validateKind(name, value, kind);
301
+ }
302
+ catch (err) {
303
+ if (!(err instanceof InputHardeningError))
304
+ throw err;
305
+ const accepts = declared["x-unicli-accepts"] ?? [];
306
+ let salvaged = false;
307
+ for (const alt of accepts) {
308
+ if (alt === "url" && tryAcceptUrl(value)) {
309
+ salvaged = true;
310
+ break;
311
+ }
312
+ if (alt === "id" && tryAcceptId(value)) {
313
+ salvaged = true;
314
+ break;
315
+ }
316
+ }
317
+ if (!salvaged)
318
+ throw err;
319
+ }
320
+ continue;
321
+ }
322
+ // Missing kind declaration = freeform. Codemod (Phase 4) will
323
+ // annotate the remaining 1324/1355 args.
324
+ }
325
+ return { warnings };
326
+ }
327
+ //# sourceMappingURL=harden.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harden.js","sourceRoot":"","sources":["../../src/engine/harden.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Invocation Kernel — backward-compat re-export surface.
3
+ *
4
+ * v0.213.3 R2 split this file into `src/engine/kernel/{types,ulid,compile,execute}.ts`
5
+ * so each concern owns its own 100-220 LOC module. This file exists solely
6
+ * to keep the historic `src/engine/invoke.js` import path stable for any
7
+ * external callers (tests, third-party scripts, downstream plugins).
8
+ *
9
+ * New code should import from `./kernel/{types,ulid,compile,execute}.js`
10
+ * directly; the re-export is a compatibility shim, not a recommended path.
11
+ */
12
+ export type { Invocation, CompiledCommand, InvocationResult, AjvValidateFn, } from "./kernel/types.js";
13
+ export { newULID, _resetULIDForTests } from "./kernel/ulid.js";
14
+ export { compileAll, getCompiled, compileCommand, _resetCompiledCacheForTests, } from "./kernel/compile.js";
15
+ export { buildInvocation, execute, KernelLookupError, } from "./kernel/execute.js";
16
+ //# sourceMappingURL=invoke.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.d.ts","sourceRoot":"","sources":["../../src/engine/invoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,OAAO,EACP,iBAAiB,GAClB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Invocation Kernel — backward-compat re-export surface.
3
+ *
4
+ * v0.213.3 R2 split this file into `src/engine/kernel/{types,ulid,compile,execute}.ts`
5
+ * so each concern owns its own 100-220 LOC module. This file exists solely
6
+ * to keep the historic `src/engine/invoke.js` import path stable for any
7
+ * external callers (tests, third-party scripts, downstream plugins).
8
+ *
9
+ * New code should import from `./kernel/{types,ulid,compile,execute}.js`
10
+ * directly; the re-export is a compatibility shim, not a recommended path.
11
+ */
12
+ export { newULID, _resetULIDForTests } from "./kernel/ulid.js";
13
+ export { compileAll, getCompiled, compileCommand, _resetCompiledCacheForTests, } from "./kernel/compile.js";
14
+ export { buildInvocation, execute, KernelLookupError, } from "./kernel/execute.js";
15
+ //# sourceMappingURL=invoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invoke.js","sourceRoot":"","sources":["../../src/engine/invoke.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EACL,UAAU,EACV,WAAW,EACX,cAAc,EACd,2BAA2B,GAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,OAAO,EACP,iBAAiB,GAClB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Compile step — converts adapter manifests into immutable `CompiledCommand`
3
+ * entries keyed by `${site}.${cmd}`. Called once at loader boot; every
4
+ * subsequent invocation looks up O(1).
5
+ *
6
+ * Built on ajv 2020-12 strict mode + format-assertion so adapter schemas
7
+ * fail closed. `x-unicli` extension keywords are stripped before handing to
8
+ * ajv (strict mode rejects unknowns) but preserved in the introspection
9
+ * schema returned to describe.ts / MCP tools/list.
10
+ */
11
+ import type { AdapterCommand, AdapterManifest } from "../../types.js";
12
+ import type { CompiledCommand } from "./types.js";
13
+ /**
14
+ * Compile one `AdapterCommand` into an immutable `CompiledCommand`. Called
15
+ * once per command per process; the validator is reused on every call.
16
+ */
17
+ export declare function compileCommand(cmd: AdapterCommand): CompiledCommand;
18
+ /**
19
+ * Eagerly compile every (adapter, command) in the registry. Intended to be
20
+ * called once at the tail of `loadAllAdapters()`; subsequent CLI / MCP /
21
+ * ACP calls look up by `${site}.${cmd}` in O(1).
22
+ */
23
+ export declare function compileAll(registry: AdapterManifest[]): Map<string, CompiledCommand>;
24
+ /** Expose the cache read-only for introspection (tests, describe.ts). */
25
+ export declare function getCompiled(site: string, cmd: string): CompiledCommand | undefined;
26
+ /** Internal — used by execute() for lazy cache fill on isolated unit tests. */
27
+ export declare function setCompiled(key: string, compiled: CompiledCommand): void;
28
+ /** Test hook — clear the cache between independent test files. */
29
+ export declare function _resetCompiledCacheForTests(): void;
30
+ //# sourceMappingURL=compile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../src/engine/kernel/compile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAEV,cAAc,EACd,eAAe,EAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAiB,eAAe,EAAE,MAAM,YAAY,CAAC;AAmGjE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe,CAiCnE;AAID;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,eAAe,EAAE,GAC1B,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAQ9B;AAED,yEAAyE;AACzE,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,eAAe,GAAG,SAAS,CAE7B;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAExE;AAED,kEAAkE;AAClE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Compile step — converts adapter manifests into immutable `CompiledCommand`
3
+ * entries keyed by `${site}.${cmd}`. Called once at loader boot; every
4
+ * subsequent invocation looks up O(1).
5
+ *
6
+ * Built on ajv 2020-12 strict mode + format-assertion so adapter schemas
7
+ * fail closed. `x-unicli` extension keywords are stripped before handing to
8
+ * ajv (strict mode rejects unknowns) but preserved in the introspection
9
+ * schema returned to describe.ts / MCP tools/list.
10
+ */
11
+ import Ajv2020 from "ajv/dist/2020.js";
12
+ import addFormats from "ajv-formats";
13
+ let ajvSingleton;
14
+ function getAjv() {
15
+ if (ajvSingleton)
16
+ return ajvSingleton;
17
+ const Ctor = (Ajv2020.default ??
18
+ Ajv2020);
19
+ const addFormatsFn = (addFormats
20
+ .default ?? addFormats);
21
+ ajvSingleton = new Ctor({
22
+ strict: true,
23
+ allErrors: false,
24
+ validateFormats: true,
25
+ });
26
+ addFormatsFn(ajvSingleton, { mode: "full" });
27
+ return ajvSingleton;
28
+ }
29
+ /** Map adapter-arg type tokens to JSON Schema `type` strings. */
30
+ function jsonSchemaType(t) {
31
+ switch (t) {
32
+ case "int":
33
+ return "integer";
34
+ case "float":
35
+ return "number";
36
+ case "bool":
37
+ return "boolean";
38
+ default:
39
+ return "string";
40
+ }
41
+ }
42
+ function buildJsonSchema(args) {
43
+ const properties = {};
44
+ const required = [];
45
+ for (const a of args) {
46
+ const prop = { type: jsonSchemaType(a.type) };
47
+ if (a.description)
48
+ prop.description = a.description;
49
+ if (a.default !== undefined)
50
+ prop.default = a.default;
51
+ if (a.choices && a.choices.length > 0)
52
+ prop.enum = a.choices;
53
+ if (a.format)
54
+ prop.format = a.format;
55
+ // x-unicli-kind / x-unicli-accepts are non-standard extension keywords;
56
+ // Ajv is strict about unknown keywords, so we pass them through as
57
+ // annotations under a nested `x-unicli` bag that Ajv's schema cloner
58
+ // strips before compilation.
59
+ const ext = {};
60
+ if (a["x-unicli-kind"])
61
+ ext.kind = a["x-unicli-kind"];
62
+ if (a["x-unicli-accepts"])
63
+ ext.accepts = a["x-unicli-accepts"];
64
+ if (Object.keys(ext).length > 0)
65
+ prop["x-unicli"] = ext;
66
+ properties[a.name] = prop;
67
+ if (a.required)
68
+ required.push(a.name);
69
+ }
70
+ return {
71
+ $schema: "https://json-schema.org/draft/2020-12/schema",
72
+ type: "object",
73
+ properties,
74
+ required,
75
+ additionalProperties: false,
76
+ };
77
+ }
78
+ function buildExample(args) {
79
+ const example = {};
80
+ for (const a of args) {
81
+ if (a.default !== undefined) {
82
+ example[a.name] = a.default;
83
+ }
84
+ else if (a.choices && a.choices.length > 0) {
85
+ example[a.name] = a.choices[0];
86
+ }
87
+ else {
88
+ switch (a.type) {
89
+ case "int":
90
+ example[a.name] = 10;
91
+ break;
92
+ case "float":
93
+ example[a.name] = 0.5;
94
+ break;
95
+ case "bool":
96
+ example[a.name] = false;
97
+ break;
98
+ default:
99
+ example[a.name] = `<${a.name}>`;
100
+ }
101
+ }
102
+ }
103
+ return example;
104
+ }
105
+ /**
106
+ * Compile one `AdapterCommand` into an immutable `CompiledCommand`. Called
107
+ * once per command per process; the validator is reused on every call.
108
+ */
109
+ export function compileCommand(cmd) {
110
+ const args = cmd.adapterArgs ?? [];
111
+ const jsonSchema = buildJsonSchema(args);
112
+ const ajv = getAjv();
113
+ // Strip `x-unicli` from the schema passed to Ajv — Ajv's strict mode
114
+ // rejects unknown keywords, but the original `jsonSchema` (kept for
115
+ // introspection) preserves them. Clone + prune.
116
+ const ajvSchema = JSON.parse(JSON.stringify(jsonSchema));
117
+ const props = ajvSchema.properties;
118
+ for (const key of Object.keys(props)) {
119
+ if ("x-unicli" in props[key])
120
+ delete props[key]["x-unicli"];
121
+ }
122
+ const validator = ajv.compile(ajvSchema);
123
+ const argByName = new Map(args.map((a) => [a.name, a]));
124
+ return {
125
+ jsonSchema,
126
+ example: buildExample(args),
127
+ channels: ["shell", "file", "stdin"],
128
+ argByName,
129
+ validate: (input) => {
130
+ const ok = validator(input);
131
+ if (ok)
132
+ return { ok: true };
133
+ return {
134
+ ok: false,
135
+ errors: validator.errors ?? [],
136
+ };
137
+ },
138
+ };
139
+ }
140
+ const compiledCache = new Map();
141
+ /**
142
+ * Eagerly compile every (adapter, command) in the registry. Intended to be
143
+ * called once at the tail of `loadAllAdapters()`; subsequent CLI / MCP /
144
+ * ACP calls look up by `${site}.${cmd}` in O(1).
145
+ */
146
+ export function compileAll(registry) {
147
+ compiledCache.clear();
148
+ for (const adapter of registry) {
149
+ for (const [cmdName, cmd] of Object.entries(adapter.commands)) {
150
+ compiledCache.set(`${adapter.name}.${cmdName}`, compileCommand(cmd));
151
+ }
152
+ }
153
+ return compiledCache;
154
+ }
155
+ /** Expose the cache read-only for introspection (tests, describe.ts). */
156
+ export function getCompiled(site, cmd) {
157
+ return compiledCache.get(`${site}.${cmd}`);
158
+ }
159
+ /** Internal — used by execute() for lazy cache fill on isolated unit tests. */
160
+ export function setCompiled(key, compiled) {
161
+ compiledCache.set(key, compiled);
162
+ }
163
+ /** Test hook — clear the cache between independent test files. */
164
+ export function _resetCompiledCacheForTests() {
165
+ compiledCache.clear();
166
+ }
167
+ //# sourceMappingURL=compile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/engine/kernel/compile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * execute() — the bag-to-envelope pipeline every surface shares.
3
+ *
4
+ * Flow per invocation:
5
+ * 1. ajv validate(bag.args) → fail-closed USAGE_ERROR on reject
6
+ * 2. hardenArgs(bag.args, argByName) → schema-driven hardening
7
+ * 3. runPipeline() / command.func() → actual work
8
+ * 4. build success envelope with live next_actions (runtime, not templated)
9
+ *
10
+ * Callers (CLI/MCP/ACP) format the returned `InvocationResult` for their
11
+ * transport; they do not rebuild envelopes.
12
+ */
13
+ import type { ResolvedArgs } from "../args.js";
14
+ import type { Invocation, InvocationResult } from "./types.js";
15
+ /**
16
+ * Raised when execute() is called for a (site, cmd) pair that was not seen
17
+ * by `compileAll()` at loader boot. Signals a wiring bug (the loader forgot
18
+ * to prime the cache), not a user error.
19
+ */
20
+ export declare class KernelLookupError extends Error {
21
+ constructor(key: string);
22
+ }
23
+ /**
24
+ * Look up an adapter + command pair and return an Invocation ready for
25
+ * execute(). Returns `null` if either the site or command is unknown —
26
+ * callers can emit their own "unknown command" envelope.
27
+ */
28
+ export declare function buildInvocation(surface: Invocation["surface"], site: string, cmd: string, bag: ResolvedArgs): Invocation | null;
29
+ /**
30
+ * Run a validated, hardened invocation end-to-end. Failure paths never
31
+ * throw — every error surfaces as `{ exitCode, error }` on the returned
32
+ * result so transport code can do uniform error handling.
33
+ */
34
+ export declare function execute(inv: Invocation): Promise<InvocationResult>;
35
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../../src/engine/kernel/execute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAgBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAG/D;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;gBAC9B,GAAG,EAAE,MAAM;CAOxB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,EAC9B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,YAAY,GAChB,UAAU,GAAG,IAAI,CAWnB;AAED;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsLxE"}