@zenalexa/unicli 0.217.0 → 0.218.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (437) hide show
  1. package/AGENTS.md +36 -196
  2. package/README.md +59 -19
  3. package/README.zh-CN.md +36 -15
  4. package/crates/unicli-atspi/Cargo.toml +47 -0
  5. package/crates/unicli-atspi/README.md +6 -0
  6. package/crates/unicli-atspi/src/errors.rs +213 -0
  7. package/crates/unicli-atspi/src/input.rs +1004 -0
  8. package/crates/unicli-atspi/src/invoke.rs +1132 -0
  9. package/crates/unicli-atspi/src/main.rs +130 -0
  10. package/crates/unicli-atspi/src/refs.rs +24 -0
  11. package/crates/unicli-atspi/src/screenshot.rs +756 -0
  12. package/crates/unicli-atspi/src/tree.rs +2319 -0
  13. package/crates/unicli-shared/Cargo.toml +13 -0
  14. package/crates/unicli-shared/src/lib.rs +77 -0
  15. package/crates/unicli-uia/Cargo.toml +29 -0
  16. package/crates/unicli-uia/README.md +6 -0
  17. package/crates/unicli-uia/src/errors.rs +179 -0
  18. package/crates/unicli-uia/src/input.rs +790 -0
  19. package/crates/unicli-uia/src/invoke.rs +977 -0
  20. package/crates/unicli-uia/src/main.rs +130 -0
  21. package/crates/unicli-uia/src/refs.rs +24 -0
  22. package/crates/unicli-uia/src/screenshot.rs +685 -0
  23. package/crates/unicli-uia/src/tree.rs +2135 -0
  24. package/dist/adapters/macos/actions.d.ts +9 -0
  25. package/dist/adapters/macos/actions.d.ts.map +1 -0
  26. package/dist/adapters/macos/actions.js +55 -0
  27. package/dist/adapters/macos/actions.js.map +1 -0
  28. package/dist/browser/bridge.d.ts +2 -0
  29. package/dist/browser/bridge.d.ts.map +1 -1
  30. package/dist/browser/bridge.js +39 -0
  31. package/dist/browser/bridge.js.map +1 -1
  32. package/dist/browser/cdp-client.d.ts +2 -0
  33. package/dist/browser/cdp-client.d.ts.map +1 -1
  34. package/dist/browser/cdp-client.js +7 -0
  35. package/dist/browser/cdp-client.js.map +1 -1
  36. package/dist/browser/page.d.ts +2 -0
  37. package/dist/browser/page.d.ts.map +1 -1
  38. package/dist/browser/page.js +35 -0
  39. package/dist/browser/page.js.map +1 -1
  40. package/dist/cli.d.ts.map +1 -1
  41. package/dist/cli.js +25 -2
  42. package/dist/cli.js.map +1 -1
  43. package/dist/commands/approvals.d.ts +3 -0
  44. package/dist/commands/approvals.d.ts.map +1 -0
  45. package/dist/commands/approvals.js +123 -0
  46. package/dist/commands/approvals.js.map +1 -0
  47. package/dist/commands/auth.d.ts +1 -0
  48. package/dist/commands/auth.d.ts.map +1 -1
  49. package/dist/commands/auth.js +250 -0
  50. package/dist/commands/auth.js.map +1 -1
  51. package/dist/commands/browser-operator-runtime.d.ts.map +1 -1
  52. package/dist/commands/browser-operator-runtime.js +1 -0
  53. package/dist/commands/browser-operator-runtime.js.map +1 -1
  54. package/dist/commands/browser-operator.d.ts.map +1 -1
  55. package/dist/commands/browser-operator.js +84 -12
  56. package/dist/commands/browser-operator.js.map +1 -1
  57. package/dist/commands/compute.d.ts +3 -0
  58. package/dist/commands/compute.d.ts.map +1 -0
  59. package/dist/commands/compute.js +324 -0
  60. package/dist/commands/compute.js.map +1 -0
  61. package/dist/commands/dev.js +1 -0
  62. package/dist/commands/dev.js.map +1 -1
  63. package/dist/commands/dispatch.d.ts.map +1 -1
  64. package/dist/commands/dispatch.js +10 -4
  65. package/dist/commands/dispatch.js.map +1 -1
  66. package/dist/commands/doctor-compute.d.ts +38 -0
  67. package/dist/commands/doctor-compute.d.ts.map +1 -0
  68. package/dist/commands/doctor-compute.js +376 -0
  69. package/dist/commands/doctor-compute.js.map +1 -0
  70. package/dist/commands/health.d.ts.map +1 -1
  71. package/dist/commands/health.js +1 -0
  72. package/dist/commands/health.js.map +1 -1
  73. package/dist/commands/lint.d.ts.map +1 -1
  74. package/dist/commands/lint.js +78 -1
  75. package/dist/commands/lint.js.map +1 -1
  76. package/dist/commands/mcp.d.ts.map +1 -1
  77. package/dist/commands/mcp.js +4 -0
  78. package/dist/commands/mcp.js.map +1 -1
  79. package/dist/commands/repair.d.ts +1 -0
  80. package/dist/commands/repair.d.ts.map +1 -1
  81. package/dist/commands/repair.js +103 -61
  82. package/dist/commands/repair.js.map +1 -1
  83. package/dist/commands/runs.d.ts +3 -0
  84. package/dist/commands/runs.d.ts.map +1 -0
  85. package/dist/commands/runs.js +367 -0
  86. package/dist/commands/runs.js.map +1 -0
  87. package/dist/core/envelope.d.ts +8 -0
  88. package/dist/core/envelope.d.ts.map +1 -1
  89. package/dist/core/envelope.js +1 -0
  90. package/dist/core/envelope.js.map +1 -1
  91. package/dist/discovery/aliases.d.ts.map +1 -1
  92. package/dist/discovery/aliases.js +15 -0
  93. package/dist/discovery/aliases.js.map +1 -1
  94. package/dist/discovery/loader.d.ts.map +1 -1
  95. package/dist/discovery/loader.js +9 -0
  96. package/dist/discovery/loader.js.map +1 -1
  97. package/dist/discovery/macos-dynamic.d.ts +58 -0
  98. package/dist/discovery/macos-dynamic.d.ts.map +1 -0
  99. package/dist/discovery/macos-dynamic.js +429 -0
  100. package/dist/discovery/macos-dynamic.js.map +1 -0
  101. package/dist/discovery/search.d.ts.map +1 -1
  102. package/dist/discovery/search.js +152 -3
  103. package/dist/discovery/search.js.map +1 -1
  104. package/dist/electron-apps.d.ts +1 -0
  105. package/dist/electron-apps.d.ts.map +1 -1
  106. package/dist/electron-apps.js +1 -0
  107. package/dist/electron-apps.js.map +1 -1
  108. package/dist/engine/approval-store.d.ts +43 -0
  109. package/dist/engine/approval-store.d.ts.map +1 -0
  110. package/dist/engine/approval-store.js +193 -0
  111. package/dist/engine/approval-store.js.map +1 -0
  112. package/dist/engine/browser/action-evidence.d.ts +2 -0
  113. package/dist/engine/browser/action-evidence.d.ts.map +1 -1
  114. package/dist/engine/browser/action-evidence.js +35 -1
  115. package/dist/engine/browser/action-evidence.js.map +1 -1
  116. package/dist/engine/browser/evidence.d.ts +22 -0
  117. package/dist/engine/browser/evidence.d.ts.map +1 -1
  118. package/dist/engine/browser/evidence.js +72 -0
  119. package/dist/engine/browser/evidence.js.map +1 -1
  120. package/dist/engine/browser/session-lease.d.ts +53 -0
  121. package/dist/engine/browser/session-lease.d.ts.map +1 -0
  122. package/dist/engine/browser/session-lease.js +100 -0
  123. package/dist/engine/browser/session-lease.js.map +1 -0
  124. package/dist/engine/browser/session-lock.d.ts +17 -0
  125. package/dist/engine/browser/session-lock.d.ts.map +1 -0
  126. package/dist/engine/browser/session-lock.js +114 -0
  127. package/dist/engine/browser/session-lock.js.map +1 -0
  128. package/dist/engine/browser/session-runtime.d.ts +10 -0
  129. package/dist/engine/browser/session-runtime.d.ts.map +1 -0
  130. package/dist/engine/browser/session-runtime.js +87 -0
  131. package/dist/engine/browser/session-runtime.js.map +1 -0
  132. package/dist/engine/capability-policy.d.ts +13 -2
  133. package/dist/engine/capability-policy.d.ts.map +1 -1
  134. package/dist/engine/capability-policy.js +113 -3
  135. package/dist/engine/capability-policy.js.map +1 -1
  136. package/dist/engine/chromium-cookies-platform.d.ts +69 -0
  137. package/dist/engine/chromium-cookies-platform.d.ts.map +1 -0
  138. package/dist/engine/chromium-cookies-platform.js +315 -0
  139. package/dist/engine/chromium-cookies-platform.js.map +1 -0
  140. package/dist/engine/chromium-cookies-types.d.ts +26 -0
  141. package/dist/engine/chromium-cookies-types.d.ts.map +1 -0
  142. package/dist/engine/chromium-cookies-types.js +16 -0
  143. package/dist/engine/chromium-cookies-types.js.map +1 -0
  144. package/dist/engine/chromium-cookies.d.ts +56 -0
  145. package/dist/engine/chromium-cookies.d.ts.map +1 -0
  146. package/dist/engine/chromium-cookies.js +361 -0
  147. package/dist/engine/chromium-cookies.js.map +1 -0
  148. package/dist/engine/cookies.d.ts +13 -5
  149. package/dist/engine/cookies.d.ts.map +1 -1
  150. package/dist/engine/cookies.js +55 -9
  151. package/dist/engine/cookies.js.map +1 -1
  152. package/dist/engine/executor.d.ts +16 -3
  153. package/dist/engine/executor.d.ts.map +1 -1
  154. package/dist/engine/executor.js +10 -3
  155. package/dist/engine/executor.js.map +1 -1
  156. package/dist/engine/kernel/execute.d.ts +1 -0
  157. package/dist/engine/kernel/execute.d.ts.map +1 -1
  158. package/dist/engine/kernel/execute.js +126 -3
  159. package/dist/engine/kernel/execute.js.map +1 -1
  160. package/dist/engine/kernel/types.d.ts +13 -0
  161. package/dist/engine/kernel/types.d.ts.map +1 -1
  162. package/dist/engine/operation-policy.d.ts +9 -1
  163. package/dist/engine/operation-policy.d.ts.map +1 -1
  164. package/dist/engine/operation-policy.js +6 -2
  165. package/dist/engine/operation-policy.js.map +1 -1
  166. package/dist/engine/permission-rules.d.ts +43 -0
  167. package/dist/engine/permission-rules.d.ts.map +1 -0
  168. package/dist/engine/permission-rules.js +401 -0
  169. package/dist/engine/permission-rules.js.map +1 -0
  170. package/dist/engine/permission-runtime.d.ts +11 -0
  171. package/dist/engine/permission-runtime.d.ts.map +1 -0
  172. package/dist/engine/permission-runtime.js +21 -0
  173. package/dist/engine/permission-runtime.js.map +1 -0
  174. package/dist/engine/repair/quarantine-discovery.d.ts +25 -0
  175. package/dist/engine/repair/quarantine-discovery.d.ts.map +1 -0
  176. package/dist/engine/repair/quarantine-discovery.js +78 -0
  177. package/dist/engine/repair/quarantine-discovery.js.map +1 -0
  178. package/dist/engine/repair/remedies.d.ts +4 -0
  179. package/dist/engine/repair/remedies.d.ts.map +1 -0
  180. package/dist/engine/repair/remedies.js +169 -0
  181. package/dist/engine/repair/remedies.js.map +1 -0
  182. package/dist/engine/runtime-resource-guard.d.ts +23 -0
  183. package/dist/engine/runtime-resource-guard.d.ts.map +1 -0
  184. package/dist/engine/runtime-resource-guard.js +85 -0
  185. package/dist/engine/runtime-resource-guard.js.map +1 -0
  186. package/dist/engine/session/args.d.ts +3 -0
  187. package/dist/engine/session/args.d.ts.map +1 -0
  188. package/dist/engine/session/args.js +17 -0
  189. package/dist/engine/session/args.js.map +1 -0
  190. package/dist/engine/session/compare.d.ts +92 -0
  191. package/dist/engine/session/compare.d.ts.map +1 -0
  192. package/dist/engine/session/compare.js +324 -0
  193. package/dist/engine/session/compare.js.map +1 -0
  194. package/dist/engine/session/environment.d.ts +4 -0
  195. package/dist/engine/session/environment.d.ts.map +1 -0
  196. package/dist/engine/session/environment.js +25 -0
  197. package/dist/engine/session/environment.js.map +1 -0
  198. package/dist/engine/session/events.d.ts +2 -0
  199. package/dist/engine/session/events.d.ts.map +1 -1
  200. package/dist/engine/session/events.js +12 -0
  201. package/dist/engine/session/events.js.map +1 -1
  202. package/dist/engine/session/query.d.ts +47 -0
  203. package/dist/engine/session/query.d.ts.map +1 -0
  204. package/dist/engine/session/query.js +299 -0
  205. package/dist/engine/session/query.js.map +1 -0
  206. package/dist/engine/session/replay.d.ts +35 -0
  207. package/dist/engine/session/replay.d.ts.map +1 -0
  208. package/dist/engine/session/replay.js +144 -0
  209. package/dist/engine/session/replay.js.map +1 -0
  210. package/dist/engine/session/run-loop.d.ts.map +1 -1
  211. package/dist/engine/session/run-loop.js +62 -23
  212. package/dist/engine/session/run-loop.js.map +1 -1
  213. package/dist/engine/session/store.d.ts +7 -0
  214. package/dist/engine/session/store.d.ts.map +1 -1
  215. package/dist/engine/session/store.js +131 -1
  216. package/dist/engine/session/store.js.map +1 -1
  217. package/dist/engine/session/types.d.ts +3 -1
  218. package/dist/engine/session/types.d.ts.map +1 -1
  219. package/dist/engine/steps/compute.d.ts +41 -0
  220. package/dist/engine/steps/compute.d.ts.map +1 -0
  221. package/dist/engine/steps/compute.js +55 -0
  222. package/dist/engine/steps/compute.js.map +1 -0
  223. package/dist/engine/steps/desktop-ax.d.ts +8 -0
  224. package/dist/engine/steps/desktop-ax.d.ts.map +1 -1
  225. package/dist/engine/steps/desktop-ax.js +16 -0
  226. package/dist/engine/steps/desktop-ax.js.map +1 -1
  227. package/dist/engine/steps/desktop-sidecar.d.ts +49 -0
  228. package/dist/engine/steps/desktop-sidecar.d.ts.map +1 -0
  229. package/dist/engine/steps/desktop-sidecar.js +50 -0
  230. package/dist/engine/steps/desktop-sidecar.js.map +1 -0
  231. package/dist/engine/steps/download.d.ts +1 -1
  232. package/dist/engine/steps/download.d.ts.map +1 -1
  233. package/dist/engine/steps/download.js +24 -2
  234. package/dist/engine/steps/download.js.map +1 -1
  235. package/dist/engine/steps/exec.d.ts +1 -1
  236. package/dist/engine/steps/exec.d.ts.map +1 -1
  237. package/dist/engine/steps/exec.js +23 -7
  238. package/dist/engine/steps/exec.js.map +1 -1
  239. package/dist/engine/steps/fetch-text.d.ts +1 -1
  240. package/dist/engine/steps/fetch-text.d.ts.map +1 -1
  241. package/dist/engine/steps/fetch-text.js +12 -4
  242. package/dist/engine/steps/fetch-text.js.map +1 -1
  243. package/dist/engine/steps/fetch.d.ts +2 -1
  244. package/dist/engine/steps/fetch.d.ts.map +1 -1
  245. package/dist/engine/steps/fetch.js +29 -6
  246. package/dist/engine/steps/fetch.js.map +1 -1
  247. package/dist/engine/steps/index.d.ts +2 -0
  248. package/dist/engine/steps/index.d.ts.map +1 -1
  249. package/dist/engine/steps/index.js +2 -0
  250. package/dist/engine/steps/index.js.map +1 -1
  251. package/dist/engine/steps/navigate.d.ts +1 -1
  252. package/dist/engine/steps/navigate.d.ts.map +1 -1
  253. package/dist/engine/steps/navigate.js +33 -2
  254. package/dist/engine/steps/navigate.js.map +1 -1
  255. package/dist/engine/template.d.ts +14 -4
  256. package/dist/engine/template.d.ts.map +1 -1
  257. package/dist/engine/template.js +93 -65
  258. package/dist/engine/template.js.map +1 -1
  259. package/dist/engine/verify-row-shape.d.ts +17 -0
  260. package/dist/engine/verify-row-shape.d.ts.map +1 -0
  261. package/dist/engine/verify-row-shape.js +36 -0
  262. package/dist/engine/verify-row-shape.js.map +1 -0
  263. package/dist/fast-path/handlers/adapter.d.ts +15 -0
  264. package/dist/fast-path/handlers/adapter.d.ts.map +1 -0
  265. package/dist/fast-path/handlers/adapter.js +169 -0
  266. package/dist/fast-path/handlers/adapter.js.map +1 -0
  267. package/dist/fast-path/handlers/discovery.d.ts +14 -0
  268. package/dist/fast-path/handlers/discovery.d.ts.map +1 -0
  269. package/dist/fast-path/handlers/discovery.js +280 -0
  270. package/dist/fast-path/handlers/discovery.js.map +1 -0
  271. package/dist/fast-path/manifest.d.ts +47 -0
  272. package/dist/fast-path/manifest.d.ts.map +1 -0
  273. package/dist/fast-path/manifest.js +32 -0
  274. package/dist/fast-path/manifest.js.map +1 -0
  275. package/dist/fast-path/parsed-argv.d.ts +16 -0
  276. package/dist/fast-path/parsed-argv.d.ts.map +1 -0
  277. package/dist/fast-path/parsed-argv.js +6 -0
  278. package/dist/fast-path/parsed-argv.js.map +1 -0
  279. package/dist/fast-path/policy.d.ts +25 -0
  280. package/dist/fast-path/policy.d.ts.map +1 -0
  281. package/dist/fast-path/policy.js +96 -0
  282. package/dist/fast-path/policy.js.map +1 -0
  283. package/dist/fast-path/render.d.ts +26 -0
  284. package/dist/fast-path/render.d.ts.map +1 -0
  285. package/dist/fast-path/render.js +200 -0
  286. package/dist/fast-path/render.js.map +1 -0
  287. package/dist/fast-path.d.ts +8 -10
  288. package/dist/fast-path.d.ts.map +1 -1
  289. package/dist/fast-path.js +66 -726
  290. package/dist/fast-path.js.map +1 -1
  291. package/dist/manifest-compact.txt +2 -2
  292. package/dist/manifest-search.json +1 -1
  293. package/dist/manifest.json +1030 -6
  294. package/dist/mcp/handler.d.ts +2 -2
  295. package/dist/mcp/handler.d.ts.map +1 -1
  296. package/dist/mcp/handler.js +59 -5
  297. package/dist/mcp/handler.js.map +1 -1
  298. package/dist/mcp/profiles/computer-use.d.ts +4 -0
  299. package/dist/mcp/profiles/computer-use.d.ts.map +1 -0
  300. package/dist/mcp/profiles/computer-use.js +305 -0
  301. package/dist/mcp/profiles/computer-use.js.map +1 -0
  302. package/dist/mcp/server.d.ts.map +1 -1
  303. package/dist/mcp/server.js +30 -6
  304. package/dist/mcp/server.js.map +1 -1
  305. package/dist/mcp/tools.d.ts +9 -0
  306. package/dist/mcp/tools.d.ts.map +1 -1
  307. package/dist/mcp/tools.js +20 -0
  308. package/dist/mcp/tools.js.map +1 -1
  309. package/dist/output/envelope.d.ts +6 -0
  310. package/dist/output/envelope.d.ts.map +1 -1
  311. package/dist/output/envelope.js.map +1 -1
  312. package/dist/output/error-map.d.ts.map +1 -1
  313. package/dist/output/error-map.js +4 -0
  314. package/dist/output/error-map.js.map +1 -1
  315. package/dist/registry.d.ts +1 -0
  316. package/dist/registry.d.ts.map +1 -1
  317. package/dist/registry.js +5 -0
  318. package/dist/registry.js.map +1 -1
  319. package/dist/transport/adapters/cdp-browser.d.ts +44 -8
  320. package/dist/transport/adapters/cdp-browser.d.ts.map +1 -1
  321. package/dist/transport/adapters/cdp-browser.js +356 -29
  322. package/dist/transport/adapters/cdp-browser.js.map +1 -1
  323. package/dist/transport/adapters/desktop-atspi.d.ts +23 -17
  324. package/dist/transport/adapters/desktop-atspi.d.ts.map +1 -1
  325. package/dist/transport/adapters/desktop-atspi.js +143 -32
  326. package/dist/transport/adapters/desktop-atspi.js.map +1 -1
  327. package/dist/transport/adapters/desktop-ax-helpers.d.ts +24 -0
  328. package/dist/transport/adapters/desktop-ax-helpers.d.ts.map +1 -0
  329. package/dist/transport/adapters/desktop-ax-helpers.js +190 -0
  330. package/dist/transport/adapters/desktop-ax-helpers.js.map +1 -0
  331. package/dist/transport/adapters/desktop-ax-swift.d.ts +13 -0
  332. package/dist/transport/adapters/desktop-ax-swift.d.ts.map +1 -1
  333. package/dist/transport/adapters/desktop-ax-swift.js +176 -2
  334. package/dist/transport/adapters/desktop-ax-swift.js.map +1 -1
  335. package/dist/transport/adapters/desktop-ax.d.ts +11 -2
  336. package/dist/transport/adapters/desktop-ax.d.ts.map +1 -1
  337. package/dist/transport/adapters/desktop-ax.js +131 -16
  338. package/dist/transport/adapters/desktop-ax.js.map +1 -1
  339. package/dist/transport/adapters/desktop-sidecar-errors.d.ts +3 -0
  340. package/dist/transport/adapters/desktop-sidecar-errors.d.ts.map +1 -0
  341. package/dist/transport/adapters/desktop-sidecar-errors.js +34 -0
  342. package/dist/transport/adapters/desktop-sidecar-errors.js.map +1 -0
  343. package/dist/transport/adapters/desktop-sidecar-snapshot.d.ts +10 -0
  344. package/dist/transport/adapters/desktop-sidecar-snapshot.d.ts.map +1 -0
  345. package/dist/transport/adapters/desktop-sidecar-snapshot.js +89 -0
  346. package/dist/transport/adapters/desktop-sidecar-snapshot.js.map +1 -0
  347. package/dist/transport/adapters/desktop-uia.d.ts +23 -17
  348. package/dist/transport/adapters/desktop-uia.d.ts.map +1 -1
  349. package/dist/transport/adapters/desktop-uia.js +142 -32
  350. package/dist/transport/adapters/desktop-uia.js.map +1 -1
  351. package/dist/transport/adapters/subprocess.d.ts +11 -4
  352. package/dist/transport/adapters/subprocess.d.ts.map +1 -1
  353. package/dist/transport/adapters/subprocess.js +68 -4
  354. package/dist/transport/adapters/subprocess.js.map +1 -1
  355. package/dist/transport/bus.d.ts +2 -0
  356. package/dist/transport/bus.d.ts.map +1 -1
  357. package/dist/transport/bus.js +7 -11
  358. package/dist/transport/bus.js.map +1 -1
  359. package/dist/transport/capability.d.ts.map +1 -1
  360. package/dist/transport/capability.js +123 -98
  361. package/dist/transport/capability.js.map +1 -1
  362. package/dist/transport/cascade.d.ts +5 -0
  363. package/dist/transport/cascade.d.ts.map +1 -0
  364. package/dist/transport/cascade.js +550 -0
  365. package/dist/transport/cascade.js.map +1 -0
  366. package/dist/transport/cdp-session.d.ts +11 -0
  367. package/dist/transport/cdp-session.d.ts.map +1 -0
  368. package/dist/transport/cdp-session.js +52 -0
  369. package/dist/transport/cdp-session.js.map +1 -0
  370. package/dist/transport/refs.d.ts +51 -0
  371. package/dist/transport/refs.d.ts.map +1 -0
  372. package/dist/transport/refs.js +135 -0
  373. package/dist/transport/refs.js.map +1 -0
  374. package/dist/transport/sidecar-binary.d.ts +18 -0
  375. package/dist/transport/sidecar-binary.d.ts.map +1 -0
  376. package/dist/transport/sidecar-binary.js +55 -0
  377. package/dist/transport/sidecar-binary.js.map +1 -0
  378. package/dist/transport/sidecar.d.ts +35 -0
  379. package/dist/transport/sidecar.d.ts.map +1 -0
  380. package/dist/transport/sidecar.js +134 -0
  381. package/dist/transport/sidecar.js.map +1 -0
  382. package/dist/transport/snapshot-encoder.d.ts +34 -0
  383. package/dist/transport/snapshot-encoder.d.ts.map +1 -0
  384. package/dist/transport/snapshot-encoder.js +139 -0
  385. package/dist/transport/snapshot-encoder.js.map +1 -0
  386. package/dist/transport/types.d.ts +6 -1
  387. package/dist/transport/types.d.ts.map +1 -1
  388. package/dist/types.d.ts +2 -0
  389. package/dist/types.d.ts.map +1 -1
  390. package/dist/types.js.map +1 -1
  391. package/docs/mcp/clients/claude-code.md +29 -0
  392. package/docs/mcp/clients/claude-desktop.md +47 -0
  393. package/docs/mcp/clients/codex.md +29 -0
  394. package/docs/mcp/clients/cursor.md +38 -0
  395. package/docs/mcp/clients/gemini-cli.md +38 -0
  396. package/docs/operate/compute.md +172 -0
  397. package/docs/operate/electron.md +87 -0
  398. package/docs/operate/focus-behavior.md +40 -0
  399. package/docs/operate/troubleshooting.md +379 -0
  400. package/package.json +29 -4
  401. package/src/adapters/adguardhome/rules.yaml +1 -1
  402. package/src/adapters/adguardhome/stats.yaml +1 -1
  403. package/src/adapters/adguardhome/status.yaml +1 -1
  404. package/src/adapters/apple-music/rate-album.yaml +1 -2
  405. package/src/adapters/arxiv/trending.yaml +1 -1
  406. package/src/adapters/az/account.yaml +1 -1
  407. package/src/adapters/coupang/hot.yaml +2 -1
  408. package/src/adapters/ctrip/hot.yaml +2 -1
  409. package/src/adapters/ctrip/search.yaml +2 -1
  410. package/src/adapters/douban/top250.yaml +1 -1
  411. package/src/adapters/figma/export-selected.yaml +1 -2
  412. package/src/adapters/gcloud/projects.yaml +1 -1
  413. package/src/adapters/github-trending/developers.yaml +1 -1
  414. package/src/adapters/github-trending/weekly.yaml +1 -1
  415. package/src/adapters/homebrew/search.yaml +1 -1
  416. package/src/adapters/imdb/top.yaml +1 -1
  417. package/src/adapters/itch-io/popular.yaml +1 -1
  418. package/src/adapters/itch-io/top.yaml +1 -1
  419. package/src/adapters/juejin/hot.test.ts +25 -0
  420. package/src/adapters/juejin/hot.yaml +52 -0
  421. package/src/adapters/juejin/search.test.ts +27 -0
  422. package/src/adapters/juejin/search.yaml +58 -0
  423. package/src/adapters/leetcode/discuss-search.test.ts +29 -0
  424. package/src/adapters/leetcode/discuss-search.yaml +56 -0
  425. package/src/adapters/macos/actions.ts +63 -0
  426. package/src/adapters/mastodon/timeline.yaml +1 -1
  427. package/src/adapters/openrouter/search.yaml +1 -1
  428. package/src/adapters/pypi/search.yaml +2 -1
  429. package/src/adapters/sspai/hot.yaml +4 -1
  430. package/src/adapters/sspai/latest.yaml +3 -3
  431. package/src/adapters/tieba/hot.yaml +1 -1
  432. package/src/adapters/wikipedia/today.yaml +1 -1
  433. package/src/adapters/zoom/toggle-mute.yaml +1 -2
  434. package/dist/engine/yaml-runner.d.ts +0 -11
  435. package/dist/engine/yaml-runner.d.ts.map +0 -1
  436. package/dist/engine/yaml-runner.js +0 -18
  437. package/dist/engine/yaml-runner.js.map +0 -1
package/dist/fast-path.js CHANGED
@@ -1,291 +1,83 @@
1
1
  /**
2
- * Fast-path handlers for discovery-only commands.
3
- *
4
- * The full Commander tree loads every adapter before it can dispatch. That is
5
- * correct for execution commands, but wasteful for discovery surfaces that can
6
- * be answered from the generated manifest and search index.
2
+ * @owner src/fast-path.ts
3
+ * @does Argv parsing and dispatch for discovery surfaces (list/search/describe/repair, plus pre-Commander adapter dry-run, policy gate, and site help).
4
+ * @needs ./fast-path/{manifest,parsed-argv,render,policy,handlers/discovery,handlers/adapter}, ./types (OutputFormat)
5
+ * @feeds src/main.ts (dispatched before the full Commander tree loads)
6
+ * @breaks Missing dist/manifest.json returns false so caller falls through to Commander; structured errors propagate via emitStderrAndExit.
7
7
  */
8
- import { existsSync, readFileSync, writeSync } from "node:fs";
9
- import { dirname, join } from "node:path";
10
- import { fileURLToPath } from "node:url";
11
- import { search } from "./discovery/search.js";
12
- import { buildDefaultConfig } from "./engine/repair/config.js";
13
- import { evaluateOperationPolicy, InvalidPermissionProfileError, resolveOperationAdapterPath, resolveOperationTargetSurface, } from "./engine/operation-policy.js";
14
- import { defaultErrorNextActions } from "./output/next-actions.js";
15
- import { format, detectFormat } from "./output/formatter.js";
16
- import { ExitCode } from "./types.js";
17
- const DEFAULT_IO = {
18
- stdout: (text) => process.stdout.write(`${text}\n`),
19
- stderr: (text) => process.stderr.write(`${text}\n`),
20
- };
21
- function emitStderrAndExit(io, text, code) {
22
- if (io === DEFAULT_IO) {
23
- writeSync(process.stderr.fd, `${text}\n`);
24
- process.exit(code);
25
- }
26
- io.stderr(text);
27
- process.exitCode = code;
28
- }
29
- function isOutputFormat(value) {
30
- return (value === "json" ||
31
- value === "yaml" ||
32
- value === "md" ||
33
- value === "csv" ||
34
- value === "compact" ||
35
- value === "table");
36
- }
37
- function isHelpToken(value) {
38
- return value === "-h" || value === "--help" || value === "help";
39
- }
40
- function jsonSchemaType(type) {
41
- switch (type) {
42
- case "int":
43
- return "integer";
44
- case "float":
45
- return "number";
46
- case "bool":
47
- return "boolean";
48
- default:
49
- return "string";
50
- }
51
- }
52
- function argsToJsonSchema(args) {
53
- const properties = {};
54
- const required = [];
55
- for (const arg of args) {
56
- const prop = {
57
- type: jsonSchemaType(arg.type),
58
- };
59
- if (arg.description)
60
- prop.description = arg.description;
61
- if (arg.default !== undefined)
62
- prop.default = arg.default;
63
- if (arg.choices && arg.choices.length > 0)
64
- prop.enum = arg.choices;
65
- if (arg.format)
66
- prop.format = arg.format;
67
- if (arg["x-unicli-kind"])
68
- prop["x-unicli-kind"] = arg["x-unicli-kind"];
69
- if (arg["x-unicli-accepts"]) {
70
- prop["x-unicli-accepts"] = arg["x-unicli-accepts"];
8
+ import { handleAdapterDryRun, handleAdapterPolicyGate, handleSiteHelp, } from "./fast-path/handlers/adapter.js";
9
+ import { handleDescribe, handleList, handleRepair, handleSearch, } from "./fast-path/handlers/discovery.js";
10
+ import { isMissingManifestError } from "./fast-path/manifest.js";
11
+ import { DEFAULT_IO, isOutputFormat } from "./fast-path/render.js";
12
+ /**
13
+ * Try to consume one global flag at `args[i]`. Returns the new index
14
+ * (i + skipped tokens) or `null` when the arg is not a recognized flag.
15
+ * The single source of truth — adding a flag means editing one branch
16
+ * here, not two parallel passes (rule 02 third-copy halt).
17
+ */
18
+ function tryConsumeFlag(args, i, acc) {
19
+ const arg = args[i];
20
+ if (arg === "-f" || arg === "--format") {
21
+ const next = args[i + 1];
22
+ if (next && isOutputFormat(next)) {
23
+ acc.formatValue = next;
24
+ return i + 1;
71
25
  }
72
- properties[arg.name] = prop;
73
- if (arg.required)
74
- required.push(arg.name);
26
+ return null;
75
27
  }
76
- return {
77
- $schema: "https://json-schema.org/draft/2020-12/schema",
78
- type: "object",
79
- properties,
80
- required,
81
- additionalProperties: true,
82
- };
83
- }
84
- function buildExample(args) {
85
- const example = {};
86
- for (const arg of args) {
87
- if (arg.default !== undefined) {
88
- example[arg.name] = arg.default;
89
- continue;
90
- }
91
- if (arg.choices && arg.choices.length > 0) {
92
- example[arg.name] = arg.choices[0];
93
- continue;
94
- }
95
- switch (arg.type) {
96
- case "int":
97
- example[arg.name] = 10;
98
- break;
99
- case "float":
100
- example[arg.name] = 0.5;
101
- break;
102
- case "bool":
103
- example[arg.name] = false;
104
- break;
105
- default:
106
- example[arg.name] = `<${arg.name}>`;
28
+ if (arg.startsWith("--format=")) {
29
+ const next = arg.slice("--format=".length);
30
+ if (isOutputFormat(next)) {
31
+ acc.formatValue = next;
32
+ return i;
107
33
  }
34
+ return null;
108
35
  }
109
- return example;
110
- }
111
- function buildChannels(site, command, args) {
112
- const positionals = args
113
- .filter((arg) => arg.positional)
114
- .map((arg) => (arg.required ? `<${arg.name}>` : `[${arg.name}]`))
115
- .join(" ");
116
- const options = args
117
- .filter((arg) => !arg.positional)
118
- .map((arg) => `[--${arg.name} <${arg.type ?? "value"}>]`)
119
- .join(" ");
120
- const shell = `unicli ${site} ${command}` +
121
- (positionals ? ` ${positionals}` : "") +
122
- (options ? ` ${options}` : "");
123
- return {
124
- shell: shell.trim(),
125
- args_file: `unicli ${site} ${command} --args-file <path.json>`,
126
- stdin: `echo '{...}' | unicli ${site} ${command}`,
127
- };
128
- }
129
- function summarizeArgs(args = []) {
130
- return args.map((arg) => ({
131
- name: arg.name,
132
- type: arg.type ?? "str",
133
- required: arg.required === true,
134
- positional: arg.positional === true,
135
- }));
136
- }
137
- function coerceArgValue(value, type) {
138
- if (type === "int") {
139
- const parsed = parseInt(String(value), 10);
140
- return Number.isNaN(parsed) ? value : parsed;
36
+ if (arg === "--dry-run") {
37
+ acc.dryRun = true;
38
+ return i;
141
39
  }
142
- if (type === "float") {
143
- const parsed = parseFloat(String(value));
144
- return Number.isNaN(parsed) ? value : parsed;
40
+ if (arg === "--permission-profile") {
41
+ acc.permissionProfile = args[i + 1];
42
+ return i + 1;
145
43
  }
146
- if (type === "bool") {
147
- if (typeof value === "boolean")
148
- return value;
149
- const text = String(value).toLowerCase();
150
- return text === "1" || text === "true" || text === "yes";
44
+ if (arg.startsWith("--permission-profile=")) {
45
+ acc.permissionProfile = arg.slice("--permission-profile=".length);
46
+ return i;
151
47
  }
152
- return value;
153
- }
154
- function resolveDryRunArgs(schema = [], tokens) {
155
- const values = {};
156
- for (const arg of schema) {
157
- if (arg.default !== undefined)
158
- values[arg.name] = arg.default;
48
+ if (arg === "--yes") {
49
+ acc.yes = true;
50
+ return i;
159
51
  }
160
- const positionals = schema.filter((arg) => arg.positional);
161
- let positionalIndex = 0;
162
- for (let i = 0; i < tokens.length; i += 1) {
163
- const token = tokens[i];
164
- if (token.startsWith("--")) {
165
- const eqIdx = token.indexOf("=");
166
- const name = eqIdx === -1 ? token.slice(2) : token.slice(2, Math.max(2, eqIdx));
167
- const arg = schema.find((candidate) => candidate.name === name);
168
- if (!arg) {
169
- if (eqIdx === -1 && tokens[i + 1] && !tokens[i + 1].startsWith("-")) {
170
- i += 1;
171
- }
172
- continue;
173
- }
174
- let raw;
175
- if (arg.type === "bool" && eqIdx === -1) {
176
- raw = true;
177
- }
178
- else if (eqIdx !== -1) {
179
- raw = token.slice(eqIdx + 1);
180
- }
181
- else {
182
- raw = tokens[i + 1];
183
- i += 1;
184
- }
185
- values[arg.name] = coerceArgValue(raw, arg.type);
186
- continue;
187
- }
188
- const arg = positionals[positionalIndex];
189
- if (arg) {
190
- values[arg.name] = coerceArgValue(token, arg.type);
191
- positionalIndex += 1;
192
- }
52
+ if (arg === "--remember-approval") {
53
+ acc.rememberApproval = true;
54
+ return i;
193
55
  }
194
- for (const arg of schema) {
195
- if (arg.required && values[arg.name] === undefined)
196
- return null;
56
+ if (arg === "--record") {
57
+ acc.record = true;
58
+ return i;
197
59
  }
198
- return values;
60
+ return null;
199
61
  }
200
62
  function parseArgv(argv) {
201
63
  const args = argv.slice(2);
202
- let formatValue;
203
- let dryRun = false;
204
- let permissionProfile;
205
- let yes = false;
206
- let record = false;
64
+ const acc = {
65
+ dryRun: false,
66
+ yes: false,
67
+ rememberApproval: false,
68
+ record: false,
69
+ };
207
70
  let command;
208
71
  const rest = [];
209
72
  for (let i = 0; i < args.length; i += 1) {
210
- const arg = args[i];
211
- if (!command) {
212
- if (arg === "-f" || arg === "--format") {
213
- const next = args[i + 1];
214
- if (next && isOutputFormat(next)) {
215
- formatValue = next;
216
- i += 1;
217
- continue;
218
- }
219
- }
220
- if (arg.startsWith("--format=")) {
221
- const next = arg.slice("--format=".length);
222
- if (isOutputFormat(next)) {
223
- formatValue = next;
224
- continue;
225
- }
226
- }
227
- if (arg === "--dry-run") {
228
- dryRun = true;
229
- continue;
230
- }
231
- if (arg === "--permission-profile") {
232
- permissionProfile = args[i + 1];
233
- i += 1;
234
- continue;
235
- }
236
- if (arg.startsWith("--permission-profile=")) {
237
- permissionProfile = arg.slice("--permission-profile=".length);
238
- continue;
239
- }
240
- if (arg === "--yes") {
241
- yes = true;
242
- continue;
243
- }
244
- if (arg === "--record") {
245
- record = true;
246
- continue;
247
- }
248
- if (!arg.startsWith("-")) {
249
- command = arg;
250
- continue;
251
- }
252
- rest.push(arg);
253
- continue;
254
- }
255
- if (arg === "-f" || arg === "--format") {
256
- const next = args[i + 1];
257
- if (next && isOutputFormat(next)) {
258
- formatValue = next;
259
- i += 1;
260
- continue;
261
- }
262
- }
263
- if (arg.startsWith("--format=")) {
264
- const next = arg.slice("--format=".length);
265
- if (isOutputFormat(next)) {
266
- formatValue = next;
267
- continue;
268
- }
269
- }
270
- if (arg === "--dry-run") {
271
- dryRun = true;
272
- continue;
273
- }
274
- if (arg === "--permission-profile") {
275
- permissionProfile = args[i + 1];
276
- i += 1;
277
- continue;
278
- }
279
- if (arg.startsWith("--permission-profile=")) {
280
- permissionProfile = arg.slice("--permission-profile=".length);
281
- continue;
282
- }
283
- if (arg === "--yes") {
284
- yes = true;
73
+ const consumed = tryConsumeFlag(args, i, acc);
74
+ if (consumed !== null) {
75
+ i = consumed;
285
76
  continue;
286
77
  }
287
- if (arg === "--record") {
288
- record = true;
78
+ const arg = args[i];
79
+ if (!command && !arg.startsWith("-")) {
80
+ command = arg;
289
81
  continue;
290
82
  }
291
83
  rest.push(arg);
@@ -293,466 +85,14 @@ function parseArgv(argv) {
293
85
  return {
294
86
  command,
295
87
  rest,
296
- format: formatValue,
297
- dryRun,
298
- permissionProfile,
299
- yes,
300
- record,
88
+ format: acc.formatValue,
89
+ dryRun: acc.dryRun,
90
+ permissionProfile: acc.permissionProfile,
91
+ yes: acc.yes,
92
+ rememberApproval: acc.rememberApproval,
93
+ record: acc.record,
301
94
  };
302
95
  }
303
- function manifestPath() {
304
- const here = dirname(fileURLToPath(import.meta.url));
305
- const candidates = [
306
- join(here, "manifest.json"),
307
- join(here, "..", "dist", "manifest.json"),
308
- join(here, "..", "..", "dist", "manifest.json"),
309
- ];
310
- const found = candidates.find((candidate) => existsSync(candidate));
311
- if (!found) {
312
- throw new Error("Missing dist/manifest.json. Run: npm run build:manifest");
313
- }
314
- return found;
315
- }
316
- function readManifest() {
317
- return JSON.parse(readFileSync(manifestPath(), "utf8"));
318
- }
319
- function isMissingManifestError(error) {
320
- return (error instanceof Error &&
321
- error.message.includes("Missing dist/manifest.json"));
322
- }
323
- function emit(io, data, columns, fmt, command, startedAt) {
324
- io.stdout(format(data, columns, detectFormat(fmt), {
325
- command,
326
- duration_ms: Date.now() - startedAt,
327
- surface: "web",
328
- }));
329
- }
330
- function evaluateManifestOperationPolicy(input) {
331
- try {
332
- return evaluateOperationPolicy({
333
- site: input.site,
334
- command: input.commandName,
335
- description: input.command.description,
336
- adapterType: input.adapterType,
337
- targetSurface: input.targetSurface,
338
- strategy: input.command.strategy,
339
- browser: input.command.browser === true,
340
- args: input.command.args,
341
- profile: input.parsed.permissionProfile,
342
- approved: input.parsed.yes,
343
- });
344
- }
345
- catch (error) {
346
- if (!(error instanceof InvalidPermissionProfileError))
347
- throw error;
348
- emitStderrAndExit(input.io, format([], input.command.columns, detectFormat(input.parsed.format), {
349
- command: `${input.site}.${input.commandName}`,
350
- duration_ms: Date.now() - input.startedAt,
351
- surface: input.targetSurface,
352
- error: {
353
- code: "invalid_input",
354
- message: error.message,
355
- adapter_path: input.adapterPath,
356
- step: 0,
357
- suggestion: "use one of: open, confirm, locked",
358
- retryable: false,
359
- },
360
- next_actions: defaultErrorNextActions(input.site, input.commandName, "invalid_input"),
361
- }), ExitCode.USAGE_ERROR);
362
- return null;
363
- }
364
- }
365
- function handleList(parsed, io) {
366
- const startedAt = Date.now();
367
- let siteFilter;
368
- let typeFilter;
369
- for (let i = 0; i < parsed.rest.length; i += 1) {
370
- const arg = parsed.rest[i];
371
- if (arg === "--site") {
372
- siteFilter = parsed.rest[i + 1];
373
- i += 1;
374
- continue;
375
- }
376
- if (arg.startsWith("--site=")) {
377
- siteFilter = arg.slice("--site=".length);
378
- continue;
379
- }
380
- if (arg === "--type") {
381
- typeFilter = parsed.rest[i + 1];
382
- i += 1;
383
- continue;
384
- }
385
- if (arg.startsWith("--type=")) {
386
- typeFilter = arg.slice("--type=".length);
387
- continue;
388
- }
389
- return false;
390
- }
391
- const manifest = readManifest();
392
- const rows = Object.entries(manifest.sites)
393
- .flatMap(([site, info]) => info.commands.map((command) => {
394
- const strategy = command.strategy ?? "public";
395
- const tags = [];
396
- if (strategy !== "public")
397
- tags.push("[auth]");
398
- if (command.quarantined === true)
399
- tags.push("[quarantined]");
400
- return {
401
- site,
402
- command: command.name,
403
- description: command.description ?? "",
404
- type: command.type ?? "web-api",
405
- auth: tags.join(" "),
406
- };
407
- }))
408
- .filter((row) => !siteFilter || row.site.includes(siteFilter))
409
- .filter((row) => !typeFilter || row.type === typeFilter)
410
- .sort((a, b) => a.site.localeCompare(b.site) || a.command.localeCompare(b.command));
411
- emit(io, rows, ["site", "command", "description", "type", "auth"], parsed.format, "core.list", startedAt);
412
- return true;
413
- }
414
- function handleSearch(parsed, io) {
415
- const startedAt = Date.now();
416
- let limit = 8;
417
- let category;
418
- const queryParts = [];
419
- for (let i = 0; i < parsed.rest.length; i += 1) {
420
- const arg = parsed.rest[i];
421
- if (arg === "-n" || arg === "--limit") {
422
- limit = parseInt(parsed.rest[i + 1] ?? "", 10) || 8;
423
- i += 1;
424
- continue;
425
- }
426
- if (arg.startsWith("--limit=")) {
427
- limit = parseInt(arg.slice("--limit=".length), 10) || 8;
428
- continue;
429
- }
430
- if (arg === "--category") {
431
- category = parsed.rest[i + 1];
432
- i += 1;
433
- continue;
434
- }
435
- if (arg.startsWith("--category=")) {
436
- category = arg.slice("--category=".length);
437
- continue;
438
- }
439
- queryParts.push(arg);
440
- }
441
- const query = queryParts.join(" ");
442
- if (!query && !category) {
443
- io.stderr("Usage: unicli search <query> or unicli search --category <cat>");
444
- process.exitCode = 2;
445
- return true;
446
- }
447
- const effectiveQuery = category ? `${category} ${query}`.trim() : query;
448
- const results = search(effectiveQuery, limit);
449
- if (results.length === 0) {
450
- io.stderr(`No commands found for: ${effectiveQuery}`);
451
- process.exitCode = 66;
452
- return true;
453
- }
454
- const rows = results.map((result) => ({
455
- command: `${result.site} ${result.command}`,
456
- description: result.description || `${result.command} for ${result.site}`,
457
- score: result.score,
458
- category: result.category,
459
- usage: result.usage,
460
- }));
461
- emit(io, rows, ["command", "description", "score", "usage"], parsed.format, "core.search", startedAt);
462
- return true;
463
- }
464
- function handleDescribe(parsed, io) {
465
- const startedAt = Date.now();
466
- const manifest = readManifest();
467
- const [site, cmdName] = parsed.rest;
468
- if (!site) {
469
- const sites = Object.entries(manifest.sites).map(([name, info]) => ({
470
- name,
471
- display_name: name,
472
- type: info.commands[0]?.type ?? "web-api",
473
- strategy: info.commands[0]?.strategy ?? "public",
474
- commands_count: info.commands.length,
475
- description: "",
476
- }));
477
- io.stdout(JSON.stringify({ sites, total: sites.length }, null, 2));
478
- return true;
479
- }
480
- const info = manifest.sites[site];
481
- if (!info) {
482
- io.stdout(JSON.stringify({ error: `unknown site: ${site}` }, null, 2));
483
- process.exitCode = 64;
484
- return true;
485
- }
486
- if (!cmdName) {
487
- const commands = info.commands.map((command) => ({
488
- name: command.name,
489
- description: command.description ?? "",
490
- quarantined: command.quarantined === true,
491
- strategy: command.strategy ?? "public",
492
- auth: (command.strategy ?? "public") !== "public",
493
- browser: command.browser === true,
494
- args: summarizeArgs(command.args),
495
- }));
496
- io.stdout(JSON.stringify({
497
- site,
498
- display_name: site,
499
- type: info.commands[0]?.type ?? "web-api",
500
- strategy: info.commands[0]?.strategy ?? "public",
501
- commands,
502
- }, null, 2));
503
- return true;
504
- }
505
- const command = info.commands.find((candidate) => candidate.name === cmdName);
506
- if (!command) {
507
- io.stdout(JSON.stringify({ error: `unknown command: ${site} ${cmdName}` }, null, 2));
508
- process.exitCode = 64;
509
- return true;
510
- }
511
- const adapterType = command.type ?? info.commands[0]?.type ?? "web-api";
512
- const targetSurface = resolveOperationTargetSurface({
513
- adapterType,
514
- targetSurface: command.target_surface,
515
- });
516
- const adapterPath = resolveOperationAdapterPath(site, cmdName, command.adapter_path);
517
- const operationPolicy = evaluateManifestOperationPolicy({
518
- parsed,
519
- io,
520
- site,
521
- commandName: cmdName,
522
- command,
523
- adapterType,
524
- targetSurface,
525
- adapterPath,
526
- startedAt,
527
- });
528
- if (!operationPolicy)
529
- return true;
530
- io.stdout(JSON.stringify({
531
- command: `unicli ${site} ${cmdName}`,
532
- description: command.description ?? "",
533
- quarantined: command.quarantined === true,
534
- strategy: command.strategy ?? "public",
535
- auth: (command.strategy ?? "public") !== "public",
536
- browser: command.browser === true,
537
- target_surface: targetSurface,
538
- adapter_path: adapterPath,
539
- operation_policy: operationPolicy,
540
- args_schema: argsToJsonSchema(command.args ?? []),
541
- example_stdin: buildExample(command.args ?? []),
542
- channels: buildChannels(site, cmdName, command.args ?? []),
543
- next_actions: [
544
- {
545
- command: `unicli ${site} ${cmdName} --dry-run`,
546
- description: "Preview the resolved argument bag and pipeline plan",
547
- },
548
- {
549
- command: `unicli ${site} ${cmdName}`,
550
- description: "Run the command (shell channel)",
551
- params: {
552
- note: {
553
- description: "For payloads with quotes/emoji/JSON, pipe stdin-JSON instead.",
554
- },
555
- },
556
- },
557
- {
558
- command: `unicli repair ${site} ${cmdName}`,
559
- description: "If the command fails due to upstream drift",
560
- },
561
- ],
562
- }, null, 2));
563
- return true;
564
- }
565
- function handleRepair(parsed, io) {
566
- const startedAt = Date.now();
567
- let dryRun = parsed.dryRun;
568
- let max = 20;
569
- let timeout = 90;
570
- const positionals = [];
571
- for (let i = 0; i < parsed.rest.length; i += 1) {
572
- const arg = parsed.rest[i];
573
- if (arg === "--dry-run") {
574
- dryRun = true;
575
- continue;
576
- }
577
- if (arg === "--max") {
578
- max = parseInt(parsed.rest[i + 1] ?? "", 10) || 20;
579
- i += 1;
580
- continue;
581
- }
582
- if (arg.startsWith("--max=")) {
583
- max = parseInt(arg.slice("--max=".length), 10) || 20;
584
- continue;
585
- }
586
- if (arg === "--timeout") {
587
- timeout = parseInt(parsed.rest[i + 1] ?? "", 10) || 90;
588
- i += 1;
589
- continue;
590
- }
591
- if (arg.startsWith("--timeout=")) {
592
- timeout = parseInt(arg.slice("--timeout=".length), 10) || 90;
593
- continue;
594
- }
595
- if (arg.startsWith("-"))
596
- return false;
597
- positionals.push(arg);
598
- }
599
- if (!dryRun)
600
- return false;
601
- const [site, command] = positionals;
602
- if (!site)
603
- return false;
604
- const config = buildDefaultConfig(site, command);
605
- config.maxIterations = max;
606
- config.timeout = timeout * 1000;
607
- emit(io, {
608
- mode: "dry-run",
609
- site,
610
- command: command ?? null,
611
- config: {
612
- ...config,
613
- metricPattern: config.metricPattern.source,
614
- },
615
- }, undefined, parsed.format, "repair.run", startedAt);
616
- return true;
617
- }
618
- function handleAdapterDryRun(parsed, io) {
619
- if (!parsed.command || !parsed.dryRun || parsed.rest.length === 0) {
620
- return false;
621
- }
622
- const manifest = readManifest();
623
- const info = manifest.sites[parsed.command];
624
- if (!info)
625
- return false;
626
- const [cmdName, ...tokens] = parsed.rest;
627
- if (!cmdName || cmdName === "help" || cmdName.startsWith("-"))
628
- return false;
629
- const command = info.commands.find((candidate) => candidate.name === cmdName);
630
- if (!command)
631
- return false;
632
- const startedAt = Date.now();
633
- const args = resolveDryRunArgs(command.args, tokens);
634
- if (!args)
635
- return false;
636
- const adapterType = command.type ?? info.commands[0]?.type ?? "web-api";
637
- const targetSurface = resolveOperationTargetSurface({
638
- adapterType,
639
- targetSurface: command.target_surface,
640
- });
641
- const adapterPath = resolveOperationAdapterPath(parsed.command, cmdName, command.adapter_path);
642
- const operationPolicy = evaluateManifestOperationPolicy({
643
- parsed,
644
- io,
645
- site: parsed.command,
646
- commandName: cmdName,
647
- command,
648
- adapterType,
649
- targetSurface,
650
- adapterPath,
651
- startedAt,
652
- });
653
- if (!operationPolicy)
654
- return true;
655
- io.stdout(JSON.stringify({
656
- command: `${parsed.command}.${cmdName}`,
657
- adapter_type: adapterType,
658
- strategy: command.strategy ?? "public",
659
- args,
660
- args_source: tokens.length > 0 ? "shell" : "defaults",
661
- operation_policy: operationPolicy,
662
- trace_id: `fast-${Date.now().toString(36)}`,
663
- surface: "cli",
664
- target_surface: targetSurface,
665
- pipeline_steps: command.pipeline_steps ?? 0,
666
- adapter_path: adapterPath,
667
- }, null, 2));
668
- return true;
669
- }
670
- function handleAdapterPolicyGate(parsed, io) {
671
- if (!parsed.command || parsed.dryRun || parsed.rest.length === 0) {
672
- return false;
673
- }
674
- const [cmdName] = parsed.rest;
675
- if (!cmdName || cmdName === "help" || cmdName.startsWith("-"))
676
- return false;
677
- if (parsed.rest.slice(1).some(isHelpToken))
678
- return false;
679
- const startedAt = Date.now();
680
- const manifest = readManifest();
681
- const info = manifest.sites[parsed.command];
682
- if (!info)
683
- return false;
684
- const command = info.commands.find((candidate) => candidate.name === cmdName);
685
- if (!command)
686
- return false;
687
- const adapterType = command.type ?? info.commands[0]?.type ?? "web-api";
688
- const targetSurface = resolveOperationTargetSurface({
689
- adapterType,
690
- targetSurface: command.target_surface,
691
- });
692
- const adapterPath = resolveOperationAdapterPath(parsed.command, cmdName, command.adapter_path);
693
- const operationPolicy = evaluateManifestOperationPolicy({
694
- parsed,
695
- io,
696
- site: parsed.command,
697
- commandName: cmdName,
698
- command,
699
- adapterType,
700
- targetSurface,
701
- adapterPath,
702
- startedAt,
703
- });
704
- if (!operationPolicy)
705
- return true;
706
- if (operationPolicy.enforcement !== "needs_approval")
707
- return false;
708
- emitStderrAndExit(io, format([], command.columns, detectFormat(parsed.format), {
709
- command: `${parsed.command}.${cmdName}`,
710
- duration_ms: Date.now() - startedAt,
711
- surface: targetSurface,
712
- error: {
713
- code: "permission_denied",
714
- message: `permission profile "${operationPolicy.profile}" requires approval for ${operationPolicy.effect}`,
715
- adapter_path: adapterPath,
716
- step: 0,
717
- suggestion: operationPolicy.approval_hint ??
718
- "rerun with --yes or use --permission-profile open",
719
- retryable: false,
720
- alternatives: [
721
- `unicli --dry-run ${parsed.command} ${cmdName}`,
722
- `unicli --yes --permission-profile ${operationPolicy.profile} ${parsed.command} ${cmdName}`,
723
- `unicli --permission-profile open ${parsed.command} ${cmdName}`,
724
- ],
725
- },
726
- next_actions: defaultErrorNextActions(parsed.command, cmdName, "permission_denied"),
727
- }), ExitCode.AUTH_REQUIRED);
728
- return true;
729
- }
730
- function handleSiteHelp(parsed, io) {
731
- const wantsHelp = parsed.rest.length === 0 || parsed.rest.every(isHelpToken);
732
- if (!parsed.command || !wantsHelp)
733
- return false;
734
- const manifest = readManifest();
735
- const info = manifest.sites[parsed.command];
736
- if (!info)
737
- return false;
738
- const commandWidth = Math.max(7, ...info.commands.map((command) => command.name.length));
739
- const lines = [
740
- `Usage: unicli ${parsed.command} [options] [command]`,
741
- "",
742
- `Commands for ${parsed.command}`,
743
- "",
744
- "Options:",
745
- " -h, --help".padEnd(commandWidth + 6) + "display help for command",
746
- "",
747
- "Commands:",
748
- ];
749
- for (const command of info.commands) {
750
- lines.push(` ${command.name.padEnd(commandWidth)} ${command.description ?? ""}`.trimEnd());
751
- }
752
- lines.push(` ${"help [command]".padEnd(commandWidth)} display help for command`);
753
- io.stdout(lines.join("\n"));
754
- return true;
755
- }
756
96
  export function tryRunFastPath(argv = process.argv, io = DEFAULT_IO) {
757
97
  const parsed = parseArgv(argv);
758
98
  try {