@agentrhq/webcmd 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) hide show
  1. package/README.md +317 -24
  2. package/dist/src/adapter-shadow.d.ts +11 -0
  3. package/dist/src/adapter-shadow.js +72 -0
  4. package/dist/src/adapter-shadow.test.d.ts +1 -0
  5. package/dist/src/adapter-shadow.test.js +49 -0
  6. package/dist/src/adapter-source.d.ts +11 -0
  7. package/dist/src/adapter-source.js +24 -0
  8. package/dist/src/adapter-source.test.d.ts +1 -0
  9. package/dist/src/adapter-source.test.js +29 -0
  10. package/dist/src/brand.d.ts +9 -0
  11. package/dist/src/brand.js +9 -0
  12. package/dist/src/brand.test.d.ts +1 -0
  13. package/dist/src/brand.test.js +15 -0
  14. package/dist/src/browser/analyze.d.ts +118 -0
  15. package/dist/src/browser/analyze.js +405 -0
  16. package/dist/src/browser/analyze.test.d.ts +1 -0
  17. package/dist/src/browser/analyze.test.js +209 -0
  18. package/dist/src/browser/article-extract.d.ts +57 -0
  19. package/dist/src/browser/article-extract.e2e.test.d.ts +1 -0
  20. package/dist/src/browser/article-extract.e2e.test.js +105 -0
  21. package/dist/src/browser/article-extract.js +169 -0
  22. package/dist/src/browser/article-extract.test.d.ts +1 -0
  23. package/dist/src/browser/article-extract.test.js +94 -0
  24. package/dist/src/browser/ax-snapshot.d.ts +37 -0
  25. package/dist/src/browser/ax-snapshot.js +217 -0
  26. package/dist/src/browser/ax-snapshot.test.d.ts +1 -0
  27. package/dist/src/browser/ax-snapshot.test.js +91 -0
  28. package/dist/src/browser/base-page.d.ts +151 -0
  29. package/dist/src/browser/base-page.js +1060 -0
  30. package/dist/src/browser/base-page.test.d.ts +1 -0
  31. package/dist/src/browser/base-page.test.js +803 -0
  32. package/dist/src/browser/bridge-readiness.d.ts +14 -0
  33. package/dist/src/browser/bridge-readiness.js +24 -0
  34. package/dist/src/browser/bridge-readiness.test.d.ts +1 -0
  35. package/dist/src/browser/bridge-readiness.test.js +58 -0
  36. package/dist/src/browser/bridge.d.ts +26 -0
  37. package/dist/src/browser/bridge.js +58 -0
  38. package/dist/src/browser/cdp-click-fixture.test.d.ts +1 -0
  39. package/dist/src/browser/cdp-click-fixture.test.js +87 -0
  40. package/dist/src/browser/cdp.d.ts +46 -0
  41. package/dist/src/browser/cdp.js +536 -0
  42. package/dist/src/browser/cdp.test.d.ts +1 -0
  43. package/dist/src/browser/cdp.test.js +79 -0
  44. package/dist/src/browser/compound.d.ts +59 -0
  45. package/dist/src/browser/compound.js +112 -0
  46. package/dist/src/browser/compound.test.d.ts +1 -0
  47. package/dist/src/browser/compound.test.js +175 -0
  48. package/dist/src/browser/config.d.ts +2 -0
  49. package/dist/src/browser/config.js +14 -0
  50. package/dist/src/browser/daemon-client.d.ts +32 -0
  51. package/dist/src/browser/daemon-client.js +135 -0
  52. package/dist/src/browser/daemon-client.test.d.ts +1 -0
  53. package/dist/src/browser/daemon-client.test.js +326 -0
  54. package/dist/src/browser/daemon-lifecycle.d.ts +37 -0
  55. package/dist/src/browser/daemon-lifecycle.js +147 -0
  56. package/dist/src/browser/daemon-transport.d.ts +54 -0
  57. package/dist/src/browser/daemon-transport.js +68 -0
  58. package/dist/src/browser/daemon-version.d.ts +4 -0
  59. package/dist/src/browser/daemon-version.js +12 -0
  60. package/dist/src/browser/dom-helpers.d.ts +41 -0
  61. package/dist/src/browser/dom-helpers.js +239 -0
  62. package/dist/src/browser/dom-helpers.test.d.ts +1 -0
  63. package/dist/src/browser/dom-helpers.test.js +106 -0
  64. package/dist/src/browser/dom-snapshot.d.ts +93 -0
  65. package/dist/src/browser/dom-snapshot.js +894 -0
  66. package/dist/src/browser/dom-snapshot.test.d.ts +11 -0
  67. package/dist/src/browser/dom-snapshot.test.js +313 -0
  68. package/dist/src/browser/errors.d.ts +38 -0
  69. package/dist/src/browser/errors.js +79 -0
  70. package/dist/src/browser/errors.test.d.ts +1 -0
  71. package/dist/src/browser/errors.test.js +60 -0
  72. package/dist/src/browser/extract.d.ts +69 -0
  73. package/dist/src/browser/extract.js +132 -0
  74. package/dist/src/browser/extract.test.d.ts +1 -0
  75. package/dist/src/browser/extract.test.js +129 -0
  76. package/dist/src/browser/find.d.ts +84 -0
  77. package/dist/src/browser/find.js +398 -0
  78. package/dist/src/browser/find.test.d.ts +1 -0
  79. package/dist/src/browser/find.test.js +180 -0
  80. package/dist/src/browser/html-tree.d.ts +75 -0
  81. package/dist/src/browser/html-tree.js +112 -0
  82. package/dist/src/browser/html-tree.test.d.ts +1 -0
  83. package/dist/src/browser/html-tree.test.js +181 -0
  84. package/dist/src/browser/index.d.ts +14 -0
  85. package/dist/src/browser/index.js +12 -0
  86. package/dist/src/browser/network-cache.d.ts +49 -0
  87. package/dist/src/browser/network-cache.js +78 -0
  88. package/dist/src/browser/network-cache.test.d.ts +1 -0
  89. package/dist/src/browser/network-cache.test.js +75 -0
  90. package/dist/src/browser/network-interceptor.d.ts +11 -0
  91. package/dist/src/browser/network-interceptor.js +11 -0
  92. package/dist/src/browser/network-key.d.ts +22 -0
  93. package/dist/src/browser/network-key.js +66 -0
  94. package/dist/src/browser/network-key.test.d.ts +1 -0
  95. package/dist/src/browser/network-key.test.js +49 -0
  96. package/dist/src/browser/page.d.ts +83 -0
  97. package/dist/src/browser/page.js +453 -0
  98. package/dist/src/browser/page.test.d.ts +1 -0
  99. package/dist/src/browser/page.test.js +406 -0
  100. package/dist/src/browser/profile.d.ts +14 -0
  101. package/dist/src/browser/profile.js +86 -0
  102. package/dist/src/browser/protocol.d.ts +63 -0
  103. package/dist/src/browser/protocol.js +1 -0
  104. package/dist/src/browser/runtime/local-cloak/actions.d.ts +3 -0
  105. package/dist/src/browser/runtime/local-cloak/actions.js +240 -0
  106. package/dist/src/browser/runtime/local-cloak/downloads.d.ts +3 -0
  107. package/dist/src/browser/runtime/local-cloak/downloads.js +28 -0
  108. package/dist/src/browser/runtime/local-cloak/network.d.ts +28 -0
  109. package/dist/src/browser/runtime/local-cloak/network.js +120 -0
  110. package/dist/src/browser/runtime/local-cloak/network.test.d.ts +1 -0
  111. package/dist/src/browser/runtime/local-cloak/network.test.js +124 -0
  112. package/dist/src/browser/runtime/local-cloak/profiles.d.ts +6 -0
  113. package/dist/src/browser/runtime/local-cloak/profiles.js +17 -0
  114. package/dist/src/browser/runtime/local-cloak/profiles.test.d.ts +1 -0
  115. package/dist/src/browser/runtime/local-cloak/profiles.test.js +19 -0
  116. package/dist/src/browser/runtime/local-cloak/provider.d.ts +15 -0
  117. package/dist/src/browser/runtime/local-cloak/provider.js +27 -0
  118. package/dist/src/browser/runtime/local-cloak/provider.test.d.ts +1 -0
  119. package/dist/src/browser/runtime/local-cloak/provider.test.js +244 -0
  120. package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +77 -0
  121. package/dist/src/browser/runtime/local-cloak/session-manager.js +280 -0
  122. package/dist/src/browser/runtime/local-cloak/session-manager.test.d.ts +1 -0
  123. package/dist/src/browser/runtime/local-cloak/session-manager.test.js +92 -0
  124. package/dist/src/browser/runtime/provider.d.ts +9 -0
  125. package/dist/src/browser/runtime/provider.js +1 -0
  126. package/dist/src/browser/runtime/provider.test.d.ts +2 -0
  127. package/dist/src/browser/runtime/provider.test.js +49 -0
  128. package/dist/src/browser/shape-filter.d.ts +52 -0
  129. package/dist/src/browser/shape-filter.js +101 -0
  130. package/dist/src/browser/shape-filter.test.d.ts +1 -0
  131. package/dist/src/browser/shape-filter.test.js +101 -0
  132. package/dist/src/browser/shape.d.ts +23 -0
  133. package/dist/src/browser/shape.js +95 -0
  134. package/dist/src/browser/shape.test.d.ts +1 -0
  135. package/dist/src/browser/shape.test.js +82 -0
  136. package/dist/src/browser/stealth.d.ts +11 -0
  137. package/dist/src/browser/stealth.js +359 -0
  138. package/dist/src/browser/stealth.test.d.ts +1 -0
  139. package/dist/src/browser/stealth.test.js +134 -0
  140. package/dist/src/browser/tabs.d.ts +13 -0
  141. package/dist/src/browser/tabs.js +70 -0
  142. package/dist/src/browser/target-errors.d.ts +39 -0
  143. package/dist/src/browser/target-errors.js +45 -0
  144. package/dist/src/browser/target-errors.test.d.ts +1 -0
  145. package/dist/src/browser/target-errors.test.js +94 -0
  146. package/dist/src/browser/target-resolver.d.ts +158 -0
  147. package/dist/src/browser/target-resolver.js +570 -0
  148. package/dist/src/browser/target-resolver.test.d.ts +1 -0
  149. package/dist/src/browser/target-resolver.test.js +118 -0
  150. package/dist/src/browser/utils.d.ts +20 -0
  151. package/dist/src/browser/utils.js +64 -0
  152. package/dist/src/browser/utils.test.d.ts +1 -0
  153. package/dist/src/browser/utils.test.js +29 -0
  154. package/dist/src/browser/verify-fixture.d.ts +65 -0
  155. package/dist/src/browser/verify-fixture.js +318 -0
  156. package/dist/src/browser/verify-fixture.test.d.ts +1 -0
  157. package/dist/src/browser/verify-fixture.test.js +219 -0
  158. package/dist/src/browser/visual-refs.d.ts +11 -0
  159. package/dist/src/browser/visual-refs.js +108 -0
  160. package/dist/src/browser.test.d.ts +1 -0
  161. package/dist/src/browser.test.js +297 -0
  162. package/dist/src/build-manifest.d.ts +103 -0
  163. package/dist/src/build-manifest.js +363 -0
  164. package/dist/src/build-manifest.test.d.ts +1 -0
  165. package/dist/src/build-manifest.test.js +341 -0
  166. package/dist/src/capabilityRouting.d.ts +19 -0
  167. package/dist/src/capabilityRouting.js +56 -0
  168. package/dist/src/capabilityRouting.test.d.ts +1 -0
  169. package/dist/src/capabilityRouting.test.js +63 -0
  170. package/dist/src/cli-argv-preprocess.d.ts +63 -0
  171. package/dist/src/cli-argv-preprocess.js +303 -0
  172. package/dist/src/cli-argv-preprocess.test.d.ts +1 -0
  173. package/dist/src/cli-argv-preprocess.test.js +304 -0
  174. package/dist/src/cli.d.ts +79 -0
  175. package/dist/src/cli.js +3350 -0
  176. package/dist/src/cli.test.d.ts +1 -0
  177. package/dist/src/cli.test.js +3041 -0
  178. package/dist/src/commanderAdapter.d.ts +21 -0
  179. package/dist/src/commanderAdapter.js +208 -0
  180. package/dist/src/commanderAdapter.test.d.ts +1 -0
  181. package/dist/src/commanderAdapter.test.js +352 -0
  182. package/dist/src/commands/auth.d.ts +40 -0
  183. package/dist/src/commands/auth.js +434 -0
  184. package/dist/src/commands/auth.test.d.ts +1 -0
  185. package/dist/src/commands/auth.test.js +252 -0
  186. package/dist/src/commands/daemon.d.ts +9 -0
  187. package/dist/src/commands/daemon.js +91 -0
  188. package/dist/src/commands/daemon.test.d.ts +1 -0
  189. package/dist/src/commands/daemon.test.js +293 -0
  190. package/dist/src/completion-fast.d.ts +22 -0
  191. package/dist/src/completion-fast.js +88 -0
  192. package/dist/src/completion-shared.d.ts +13 -0
  193. package/dist/src/completion-shared.js +61 -0
  194. package/dist/src/completion.d.ts +21 -0
  195. package/dist/src/completion.js +68 -0
  196. package/dist/src/completion.test.d.ts +1 -0
  197. package/dist/src/completion.test.js +24 -0
  198. package/dist/src/constants.d.ts +18 -0
  199. package/dist/src/constants.js +41 -0
  200. package/dist/src/convention-audit.d.ts +50 -0
  201. package/dist/src/convention-audit.js +553 -0
  202. package/dist/src/convention-audit.test.d.ts +1 -0
  203. package/dist/src/convention-audit.test.js +255 -0
  204. package/dist/src/daemon/server.d.ts +13 -0
  205. package/dist/src/daemon/server.js +185 -0
  206. package/dist/src/daemon/server.test.d.ts +1 -0
  207. package/dist/src/daemon/server.test.js +132 -0
  208. package/dist/src/daemon-utils.d.ts +18 -0
  209. package/dist/src/daemon-utils.js +37 -0
  210. package/dist/src/daemon.d.ts +1 -0
  211. package/dist/src/daemon.js +27 -0
  212. package/dist/src/daemon.test.d.ts +1 -0
  213. package/dist/src/daemon.test.js +60 -0
  214. package/dist/src/discovery.d.ts +46 -0
  215. package/dist/src/discovery.js +341 -0
  216. package/dist/src/doctor.d.ts +39 -0
  217. package/dist/src/doctor.js +168 -0
  218. package/dist/src/doctor.test.d.ts +1 -0
  219. package/dist/src/doctor.test.js +302 -0
  220. package/dist/src/download/article-download.d.ts +72 -0
  221. package/dist/src/download/article-download.js +305 -0
  222. package/dist/src/download/article-download.test.d.ts +1 -0
  223. package/dist/src/download/article-download.test.js +235 -0
  224. package/dist/src/download/index.d.ts +71 -0
  225. package/dist/src/download/index.js +363 -0
  226. package/dist/src/download/index.test.d.ts +1 -0
  227. package/dist/src/download/index.test.js +174 -0
  228. package/dist/src/download/media-download.d.ts +49 -0
  229. package/dist/src/download/media-download.js +127 -0
  230. package/dist/src/download/media-download.test.d.ts +1 -0
  231. package/dist/src/download/media-download.test.js +112 -0
  232. package/dist/src/download/progress.d.ts +36 -0
  233. package/dist/src/download/progress.js +120 -0
  234. package/dist/src/download/progress.test.d.ts +1 -0
  235. package/dist/src/download/progress.test.js +36 -0
  236. package/dist/src/electron-apps.d.ts +31 -0
  237. package/dist/src/electron-apps.js +91 -0
  238. package/dist/src/electron-apps.test.d.ts +1 -0
  239. package/dist/src/electron-apps.test.js +76 -0
  240. package/dist/src/engine.test.d.ts +1 -0
  241. package/dist/src/engine.test.js +312 -0
  242. package/dist/src/errors.d.ts +114 -0
  243. package/dist/src/errors.js +174 -0
  244. package/dist/src/errors.test.d.ts +1 -0
  245. package/dist/src/errors.test.js +109 -0
  246. package/dist/src/execution.d.ts +24 -0
  247. package/dist/src/execution.js +509 -0
  248. package/dist/src/execution.test.d.ts +1 -0
  249. package/dist/src/execution.test.js +645 -0
  250. package/dist/src/external.d.ts +49 -0
  251. package/dist/src/external.js +211 -0
  252. package/dist/src/external.test.d.ts +1 -0
  253. package/dist/src/external.test.js +110 -0
  254. package/dist/src/help.d.ts +88 -0
  255. package/dist/src/help.js +556 -0
  256. package/dist/src/help.test.d.ts +1 -0
  257. package/dist/src/help.test.js +58 -0
  258. package/dist/src/hooks.d.ts +46 -0
  259. package/dist/src/hooks.js +58 -0
  260. package/dist/src/hooks.test.d.ts +4 -0
  261. package/dist/src/hooks.test.js +92 -0
  262. package/dist/src/interceptor.d.ts +44 -0
  263. package/dist/src/interceptor.js +183 -0
  264. package/dist/src/interceptor.test.d.ts +4 -0
  265. package/dist/src/interceptor.test.js +81 -0
  266. package/dist/src/launcher.d.ts +41 -0
  267. package/dist/src/launcher.js +226 -0
  268. package/dist/src/launcher.test.d.ts +1 -0
  269. package/dist/src/launcher.test.js +153 -0
  270. package/dist/src/logger.d.ts +26 -0
  271. package/dist/src/logger.js +49 -0
  272. package/dist/src/main.d.ts +5 -0
  273. package/dist/src/main.js +177 -0
  274. package/dist/src/manifest-types.d.ts +43 -0
  275. package/dist/src/manifest-types.js +9 -0
  276. package/dist/src/node-network.d.ts +10 -0
  277. package/dist/src/node-network.js +174 -0
  278. package/dist/src/node-network.test.d.ts +1 -0
  279. package/dist/src/node-network.test.js +55 -0
  280. package/dist/src/observation/artifact.d.ts +16 -0
  281. package/dist/src/observation/artifact.js +260 -0
  282. package/dist/src/observation/artifact.test.d.ts +1 -0
  283. package/dist/src/observation/artifact.test.js +121 -0
  284. package/dist/src/observation/events.d.ts +89 -0
  285. package/dist/src/observation/events.js +1 -0
  286. package/dist/src/observation/index.d.ts +7 -0
  287. package/dist/src/observation/index.js +7 -0
  288. package/dist/src/observation/manager.d.ts +9 -0
  289. package/dist/src/observation/manager.js +27 -0
  290. package/dist/src/observation/manager.test.d.ts +1 -0
  291. package/dist/src/observation/manager.test.js +13 -0
  292. package/dist/src/observation/redaction.d.ts +11 -0
  293. package/dist/src/observation/redaction.js +81 -0
  294. package/dist/src/observation/redaction.test.d.ts +1 -0
  295. package/dist/src/observation/redaction.test.js +32 -0
  296. package/dist/src/observation/retention.d.ts +32 -0
  297. package/dist/src/observation/retention.js +160 -0
  298. package/dist/src/observation/retention.test.d.ts +1 -0
  299. package/dist/src/observation/retention.test.js +118 -0
  300. package/dist/src/observation/ring-buffer.d.ts +22 -0
  301. package/dist/src/observation/ring-buffer.js +45 -0
  302. package/dist/src/observation/ring-buffer.test.d.ts +1 -0
  303. package/dist/src/observation/ring-buffer.test.js +22 -0
  304. package/dist/src/observation/session.d.ts +25 -0
  305. package/dist/src/observation/session.js +50 -0
  306. package/dist/src/output.d.ts +14 -0
  307. package/dist/src/output.js +152 -0
  308. package/dist/src/output.test.d.ts +1 -0
  309. package/dist/src/output.test.js +53 -0
  310. package/dist/src/package-exports.test.d.ts +1 -0
  311. package/dist/src/package-exports.test.js +112 -0
  312. package/dist/src/package-paths.d.ts +8 -0
  313. package/dist/src/package-paths.js +41 -0
  314. package/dist/src/pipeline/executor.d.ts +11 -0
  315. package/dist/src/pipeline/executor.js +93 -0
  316. package/dist/src/pipeline/executor.test.d.ts +4 -0
  317. package/dist/src/pipeline/executor.test.js +182 -0
  318. package/dist/src/pipeline/index.d.ts +5 -0
  319. package/dist/src/pipeline/index.js +5 -0
  320. package/dist/src/pipeline/registry.d.ts +28 -0
  321. package/dist/src/pipeline/registry.js +55 -0
  322. package/dist/src/pipeline/steps/browser.d.ts +13 -0
  323. package/dist/src/pipeline/steps/browser.js +86 -0
  324. package/dist/src/pipeline/steps/download.d.ts +18 -0
  325. package/dist/src/pipeline/steps/download.js +252 -0
  326. package/dist/src/pipeline/steps/download.test.d.ts +1 -0
  327. package/dist/src/pipeline/steps/download.test.js +102 -0
  328. package/dist/src/pipeline/steps/fetch.d.ts +5 -0
  329. package/dist/src/pipeline/steps/fetch.js +122 -0
  330. package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
  331. package/dist/src/pipeline/steps/fetch.test.js +117 -0
  332. package/dist/src/pipeline/steps/intercept.d.ts +5 -0
  333. package/dist/src/pipeline/steps/intercept.js +50 -0
  334. package/dist/src/pipeline/steps/tap.d.ts +12 -0
  335. package/dist/src/pipeline/steps/tap.js +93 -0
  336. package/dist/src/pipeline/steps/transform.d.ts +9 -0
  337. package/dist/src/pipeline/steps/transform.js +70 -0
  338. package/dist/src/pipeline/template.d.ts +17 -0
  339. package/dist/src/pipeline/template.js +344 -0
  340. package/dist/src/pipeline/template.test.d.ts +4 -0
  341. package/dist/src/pipeline/template.test.js +197 -0
  342. package/dist/src/pipeline/transform.test.d.ts +4 -0
  343. package/dist/src/pipeline/transform.test.js +133 -0
  344. package/dist/src/plugin-manifest.d.ts +70 -0
  345. package/dist/src/plugin-manifest.js +160 -0
  346. package/dist/src/plugin-manifest.test.d.ts +4 -0
  347. package/dist/src/plugin-manifest.test.js +179 -0
  348. package/dist/src/plugin-scaffold.d.ts +28 -0
  349. package/dist/src/plugin-scaffold.js +143 -0
  350. package/dist/src/plugin-scaffold.test.d.ts +4 -0
  351. package/dist/src/plugin-scaffold.test.js +83 -0
  352. package/dist/src/plugin.d.ts +146 -0
  353. package/dist/src/plugin.js +1303 -0
  354. package/dist/src/plugin.test.d.ts +4 -0
  355. package/dist/src/plugin.test.js +1363 -0
  356. package/dist/src/registry-api.d.ts +13 -0
  357. package/dist/src/registry-api.js +10 -0
  358. package/dist/src/registry.d.ts +123 -0
  359. package/dist/src/registry.js +125 -0
  360. package/dist/src/registry.test.d.ts +4 -0
  361. package/dist/src/registry.test.js +209 -0
  362. package/dist/src/runtime-copy.test.d.ts +1 -0
  363. package/dist/src/runtime-copy.test.js +29 -0
  364. package/dist/src/runtime-detect.d.ts +31 -0
  365. package/dist/src/runtime-detect.js +47 -0
  366. package/dist/src/runtime-detect.test.d.ts +1 -0
  367. package/dist/src/runtime-detect.test.js +39 -0
  368. package/dist/src/runtime-identity.test.d.ts +1 -0
  369. package/dist/src/runtime-identity.test.js +18 -0
  370. package/dist/src/runtime.d.ts +47 -0
  371. package/dist/src/runtime.js +54 -0
  372. package/dist/src/scripts/framework.d.ts +7 -0
  373. package/dist/src/scripts/framework.js +25 -0
  374. package/dist/src/scripts/interact.d.ts +4 -0
  375. package/dist/src/scripts/interact.js +20 -0
  376. package/dist/src/scripts/store.d.ts +13 -0
  377. package/dist/src/scripts/store.js +48 -0
  378. package/dist/src/serialization.d.ts +42 -0
  379. package/dist/src/serialization.js +103 -0
  380. package/dist/src/serialization.test.d.ts +1 -0
  381. package/dist/src/serialization.test.js +78 -0
  382. package/dist/src/skills.d.ts +14 -0
  383. package/dist/src/skills.js +127 -0
  384. package/dist/src/skills.test.d.ts +1 -0
  385. package/dist/src/skills.test.js +71 -0
  386. package/dist/src/snapshotFormatter.d.ts +11 -0
  387. package/dist/src/snapshotFormatter.js +338 -0
  388. package/dist/src/snapshotFormatter.test.d.ts +7 -0
  389. package/dist/src/snapshotFormatter.test.js +521 -0
  390. package/dist/src/tui.d.ts +28 -0
  391. package/dist/src/tui.js +179 -0
  392. package/dist/src/tui.test.d.ts +1 -0
  393. package/dist/src/tui.test.js +19 -0
  394. package/dist/src/types.d.ts +236 -0
  395. package/dist/src/types.js +7 -0
  396. package/dist/src/update-check.d.ts +66 -0
  397. package/dist/src/update-check.js +206 -0
  398. package/dist/src/update-check.test.d.ts +1 -0
  399. package/dist/src/update-check.test.js +117 -0
  400. package/dist/src/utils.d.ts +57 -0
  401. package/dist/src/utils.js +152 -0
  402. package/dist/src/utils.test.d.ts +1 -0
  403. package/dist/src/utils.test.js +155 -0
  404. package/dist/src/validate.d.ts +21 -0
  405. package/dist/src/validate.js +130 -0
  406. package/dist/src/validate.test.d.ts +9 -0
  407. package/dist/src/validate.test.js +90 -0
  408. package/dist/src/verify.d.ts +26 -0
  409. package/dist/src/verify.js +67 -0
  410. package/dist/src/version.d.ts +4 -0
  411. package/dist/src/version.js +22 -0
  412. package/dist/src/weixin-download.test.d.ts +1 -0
  413. package/dist/src/weixin-download.test.js +45 -0
  414. package/package.json +4 -3
  415. package/scripts/check-package-bin.mjs +95 -0
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Electron app launcher — auto-detect, confirm, launch, and connect.
3
+ *
4
+ * Flow:
5
+ * 1. Probe CDP port → already running with debug? connect directly
6
+ * 2. Detect process → running without CDP? prompt to restart
7
+ * 3. Discover app path → not installed? error
8
+ * 4. Launch with --remote-debugging-port
9
+ * 5. Poll /json until ready
10
+ */
11
+ import { execFileSync, spawn } from 'node:child_process';
12
+ import { request as httpRequest } from 'node:http';
13
+ import * as path from 'node:path';
14
+ import { getElectronApp } from './electron-apps.js';
15
+ import { confirmPrompt } from './tui.js';
16
+ import { CommandExecutionError } from './errors.js';
17
+ import { log } from './logger.js';
18
+ const POLL_INTERVAL_MS = 500;
19
+ const POLL_TIMEOUT_MS = 15_000;
20
+ const PROBE_TIMEOUT_MS = 2_000;
21
+ const KILL_GRACE_MS = 3_000;
22
+ /**
23
+ * Probe whether a CDP endpoint is listening on the given port.
24
+ * Returns true if http://127.0.0.1:{port}/json responds successfully.
25
+ */
26
+ export function probeCDP(port, timeoutMs = PROBE_TIMEOUT_MS) {
27
+ return new Promise((resolve) => {
28
+ const req = httpRequest({ hostname: '127.0.0.1', port, path: '/json', method: 'GET', timeout: timeoutMs }, (res) => {
29
+ res.resume();
30
+ resolve(res.statusCode !== undefined && res.statusCode >= 200 && res.statusCode < 300);
31
+ });
32
+ req.on('error', () => resolve(false));
33
+ req.on('timeout', () => { req.destroy(); resolve(false); });
34
+ req.end();
35
+ });
36
+ }
37
+ /**
38
+ * Check if a process with the given name is running.
39
+ * Uses pgrep on macOS/Linux.
40
+ */
41
+ export function detectProcess(processName) {
42
+ if (process.platform === 'win32')
43
+ return false; // pgrep not available on Windows
44
+ try {
45
+ execFileSync('pgrep', ['-x', processName], { encoding: 'utf-8', stdio: 'pipe' });
46
+ return true;
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ /**
53
+ * Kill a process by name. Sends SIGTERM first, then SIGKILL after grace period.
54
+ */
55
+ export async function killProcess(processName) {
56
+ if (process.platform === 'win32')
57
+ return; // pkill not available on Windows
58
+ try {
59
+ execFileSync('pkill', ['-x', processName], { stdio: 'pipe' });
60
+ }
61
+ catch {
62
+ // Process may have already exited
63
+ }
64
+ const deadline = Date.now() + KILL_GRACE_MS;
65
+ while (Date.now() < deadline) {
66
+ if (!detectProcess(processName))
67
+ return;
68
+ await new Promise((r) => setTimeout(r, 200));
69
+ }
70
+ try {
71
+ execFileSync('pkill', ['-9', '-x', processName], { stdio: 'pipe' });
72
+ }
73
+ catch {
74
+ // Ignore
75
+ }
76
+ }
77
+ /**
78
+ * Discover the app installation path on macOS.
79
+ * Uses osascript to resolve the app name to a POSIX path.
80
+ * Returns null if the app is not installed.
81
+ */
82
+ export function discoverAppPath(displayName) {
83
+ if (process.platform !== 'darwin') {
84
+ return null;
85
+ }
86
+ try {
87
+ const result = execFileSync('osascript', [
88
+ '-e', `POSIX path of (path to application "${displayName}")`,
89
+ ], { encoding: 'utf-8', stdio: 'pipe', timeout: 5_000 });
90
+ return result.trim().replace(/\/$/, '');
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
96
+ function resolveExecutable(appPath, processName) {
97
+ return `${appPath}/Contents/MacOS/${processName}`;
98
+ }
99
+ function isMissingExecutableError(err, label) {
100
+ return err instanceof CommandExecutionError
101
+ && err.message.startsWith(`Could not launch ${label}: executable not found at `);
102
+ }
103
+ export function resolveExecutableCandidates(appPath, app) {
104
+ const executableNames = app.executableNames?.length ? app.executableNames : [app.processName];
105
+ return [...new Set(executableNames)].map((name) => resolveExecutable(appPath, name));
106
+ }
107
+ export async function launchDetachedApp(executable, args, label) {
108
+ await new Promise((resolve, reject) => {
109
+ const child = spawn(executable, args, {
110
+ detached: true,
111
+ stdio: 'ignore',
112
+ });
113
+ const onError = (err) => {
114
+ if (err.code === 'ENOENT') {
115
+ reject(new CommandExecutionError(`Could not launch ${label}: executable not found at ${executable}`, `Install ${label}, reinstall it, or register a custom app path in ~/.webcmd/apps.yaml`));
116
+ return;
117
+ }
118
+ reject(new CommandExecutionError(`Failed to launch ${label}`, err.message));
119
+ };
120
+ child.once('error', onError);
121
+ child.once('spawn', () => {
122
+ child.off('error', onError);
123
+ child.unref();
124
+ resolve();
125
+ });
126
+ });
127
+ }
128
+ export async function launchElectronApp(appPath, app, args, label) {
129
+ const executables = resolveExecutableCandidates(appPath, app);
130
+ let lastMissingExecutableError;
131
+ for (const executable of executables) {
132
+ log.debug(`[launcher] Launching: ${executable} ${args.join(' ')}`);
133
+ try {
134
+ await launchDetachedApp(executable, args, label);
135
+ return;
136
+ }
137
+ catch (err) {
138
+ if (isMissingExecutableError(err, label)) {
139
+ lastMissingExecutableError = err;
140
+ continue;
141
+ }
142
+ throw err;
143
+ }
144
+ }
145
+ if (executables.length > 1) {
146
+ throw new CommandExecutionError(`Could not launch ${label}: no compatible executable found in ${path.join(appPath, 'Contents', 'MacOS')}`, `Tried: ${executables.map((executable) => path.basename(executable)).join(', ')}. Install ${label}, reinstall it, or register a custom app path in ~/.webcmd/apps.yaml`);
147
+ }
148
+ throw lastMissingExecutableError ?? new CommandExecutionError(`Could not launch ${label}`, `Install ${label}, reinstall it, or register a custom app path in ~/.webcmd/apps.yaml`);
149
+ }
150
+ export function electronLaunchArgs(port, extraArgs = []) {
151
+ return [
152
+ `--remote-debugging-port=${port}`,
153
+ '--remote-allow-origins=*',
154
+ ...extraArgs,
155
+ ];
156
+ }
157
+ function manualElectronLaunchHint(label, port) {
158
+ return `Start ${label} manually with --remote-debugging-port=${port} --remote-allow-origins=*, then either:`;
159
+ }
160
+ async function pollForReady(port) {
161
+ const deadline = Date.now() + POLL_TIMEOUT_MS;
162
+ while (Date.now() < deadline) {
163
+ if (await probeCDP(port, 1_000))
164
+ return;
165
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
166
+ }
167
+ throw new CommandExecutionError(`App launched but CDP not available on port ${port} after ${POLL_TIMEOUT_MS / 1000}s`, 'The app may be slow to start. Try running the command again.');
168
+ }
169
+ /**
170
+ * Main entry point: resolve an Electron app to a CDP endpoint URL.
171
+ *
172
+ * Returns the endpoint URL: http://127.0.0.1:{port}
173
+ */
174
+ export async function resolveElectronEndpoint(site) {
175
+ const app = getElectronApp(site);
176
+ if (!app) {
177
+ throw new CommandExecutionError(`No Electron app registered for site "${site}"`, 'Register the app in ~/.webcmd/apps.yaml or check the site name.');
178
+ }
179
+ const { port, processName, displayName } = app;
180
+ const label = displayName ?? processName;
181
+ const endpoint = `http://127.0.0.1:${port}`;
182
+ // Step 1: Already running with CDP?
183
+ log.debug(`[launcher] Probing CDP on port ${port}...`);
184
+ if (await probeCDP(port)) {
185
+ log.debug(`[launcher] CDP already available on port ${port}`);
186
+ return endpoint;
187
+ }
188
+ // Step 2: Running without CDP? (process detection requires Unix tools)
189
+ if (process.platform !== 'darwin' && process.platform !== 'linux') {
190
+ throw new CommandExecutionError(`${label} is not reachable on CDP port ${port}.`, `Auto-launch is not yet supported on ${process.platform}.\n` +
191
+ `${manualElectronLaunchHint(label, port)}\n` +
192
+ ` • Set WEBCMD_CDP_ENDPOINT=http://127.0.0.1:${port}\n` +
193
+ ` • Or just re-run the command once ${label} is listening on port ${port}.`);
194
+ }
195
+ const isRunning = detectProcess(processName);
196
+ if (isRunning) {
197
+ log.debug(`[launcher] ${label} is running but CDP not available`);
198
+ const confirmed = await confirmPrompt(`${label} is running but CDP is not enabled. Restart with debug port?`, true);
199
+ if (!confirmed) {
200
+ throw new CommandExecutionError(`${label} needs to be restarted with CDP enabled.`, `Manually restart: kill the app and relaunch with --remote-debugging-port=${port} --remote-allow-origins=*`);
201
+ }
202
+ process.stderr.write(` Restarting ${label}...\n`);
203
+ await killProcess(processName);
204
+ }
205
+ // Step 3: Discover path
206
+ const appPath = discoverAppPath(label);
207
+ if (!appPath) {
208
+ throw new CommandExecutionError(`Could not find ${label} on this machine.`, `Install ${label} or register a custom path in ~/.webcmd/apps.yaml`);
209
+ }
210
+ // Step 4: Launch
211
+ //
212
+ // Chrome / Electron 142+ enforces an Origin allow-list on the CDP
213
+ // WebSocket upgrade (ws://127.0.0.1:<port>/devtools/page/<id>). Without
214
+ // --remote-allow-origins=* every ws client other than chrome://inspect
215
+ // gets HTTP 403 "Rejected an incoming WebSocket connection from the
216
+ // http://127.0.0.1:<port> origin". This affects every Electron app
217
+ // webcmd launches because they all bundle a recent Chromium. Same
218
+ // mitigation as Puppeteer / Playwright / chrome-devtools-mcp.
219
+ const args = electronLaunchArgs(port, app.extraArgs ?? []);
220
+ await launchElectronApp(appPath, app, args, label);
221
+ // Step 5: Poll for readiness
222
+ process.stderr.write(` Waiting for ${label} on port ${port}...\n`);
223
+ await pollForReady(port);
224
+ process.stderr.write(` Connected to ${label} on port ${port}.\n`);
225
+ return endpoint;
226
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,153 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { detectProcess, discoverAppPath, electronLaunchArgs, launchDetachedApp, launchElectronApp, probeCDP, resolveExecutableCandidates } from './launcher.js';
3
+ function createMockChildProcess() {
4
+ const listeners = new Map();
5
+ return {
6
+ once: vi.fn((event, handler) => {
7
+ listeners.set(event, [...(listeners.get(event) ?? []), handler]);
8
+ }),
9
+ off: vi.fn((event, handler) => {
10
+ listeners.set(event, (listeners.get(event) ?? []).filter((listener) => listener !== handler));
11
+ }),
12
+ unref: vi.fn(),
13
+ emit: (event, value) => {
14
+ for (const listener of listeners.get(event) ?? [])
15
+ listener(value);
16
+ },
17
+ };
18
+ }
19
+ vi.mock('node:child_process', () => ({
20
+ execFileSync: vi.fn(),
21
+ spawn: vi.fn(),
22
+ }));
23
+ const cp = vi.mocked(await import('node:child_process'));
24
+ describe('probeCDP', () => {
25
+ it('returns false when CDP endpoint is unreachable', async () => {
26
+ const result = await probeCDP(59999, 500);
27
+ expect(result).toBe(false);
28
+ });
29
+ });
30
+ describe('detectProcess', () => {
31
+ beforeEach(() => {
32
+ vi.restoreAllMocks();
33
+ });
34
+ it('returns false when pgrep finds no process', () => {
35
+ cp.execFileSync.mockImplementation(() => {
36
+ const err = new Error('exit 1');
37
+ err.status = 1;
38
+ throw err;
39
+ });
40
+ const result = detectProcess('NonExistentApp');
41
+ expect(result).toBe(false);
42
+ });
43
+ it.skipIf(process.platform === 'win32')('returns true when pgrep finds a process', () => {
44
+ cp.execFileSync.mockReturnValue('12345\n');
45
+ const result = detectProcess('Cursor');
46
+ expect(result).toBe(true);
47
+ });
48
+ });
49
+ describe('discoverAppPath', () => {
50
+ beforeEach(() => {
51
+ vi.restoreAllMocks();
52
+ });
53
+ it.skipIf(process.platform !== 'darwin')('returns path when osascript succeeds', () => {
54
+ cp.execFileSync.mockReturnValue('/Applications/Cursor.app/\n');
55
+ const result = discoverAppPath('Cursor');
56
+ expect(result).toBe('/Applications/Cursor.app');
57
+ });
58
+ it.skipIf(process.platform !== 'darwin')('returns null when osascript fails', () => {
59
+ cp.execFileSync.mockImplementation(() => {
60
+ throw new Error('app not found');
61
+ });
62
+ const result = discoverAppPath('NonExistent');
63
+ expect(result).toBeNull();
64
+ });
65
+ it.skipIf(process.platform === 'darwin')('returns null on non-darwin platform', () => {
66
+ const result = discoverAppPath('Cursor');
67
+ expect(result).toBeNull();
68
+ });
69
+ });
70
+ describe('launchDetachedApp', () => {
71
+ beforeEach(() => {
72
+ vi.restoreAllMocks();
73
+ cp.spawn.mockReset();
74
+ });
75
+ it('unrefs the process after spawn succeeds', async () => {
76
+ const child = createMockChildProcess();
77
+ cp.spawn.mockImplementation(() => {
78
+ queueMicrotask(() => child.emit('spawn'));
79
+ return child;
80
+ });
81
+ await expect(launchDetachedApp('/Applications/Antigravity.app/Contents/MacOS/Antigravity', ['--remote-debugging-port=9234'], 'Antigravity'))
82
+ .resolves
83
+ .toBeUndefined();
84
+ expect(child.unref).toHaveBeenCalledTimes(1);
85
+ });
86
+ it('converts ENOENT into a controlled launch error', async () => {
87
+ const child = createMockChildProcess();
88
+ cp.spawn.mockImplementation(() => {
89
+ queueMicrotask(() => child.emit('error', Object.assign(new Error('missing binary'), { code: 'ENOENT' })));
90
+ return child;
91
+ });
92
+ await expect(launchDetachedApp('/Applications/Antigravity.app/Contents/MacOS/Antigravity', ['--remote-debugging-port=9234'], 'Antigravity'))
93
+ .rejects
94
+ .toThrow('Could not launch Antigravity');
95
+ expect(child.unref).not.toHaveBeenCalled();
96
+ });
97
+ });
98
+ describe('resolveExecutableCandidates', () => {
99
+ it('prefers explicit executable candidates over processName', () => {
100
+ const app = {
101
+ port: 9234,
102
+ processName: 'Antigravity',
103
+ executableNames: ['Electron', 'Antigravity'],
104
+ };
105
+ expect(resolveExecutableCandidates('/Applications/Antigravity.app', app)).toEqual([
106
+ '/Applications/Antigravity.app/Contents/MacOS/Electron',
107
+ '/Applications/Antigravity.app/Contents/MacOS/Antigravity',
108
+ ]);
109
+ });
110
+ });
111
+ describe('electronLaunchArgs', () => {
112
+ it('includes Chromium 142 WebSocket origin allow-list for auto-launched Electron apps', () => {
113
+ expect(electronLaunchArgs(9234)).toEqual([
114
+ '--remote-debugging-port=9234',
115
+ '--remote-allow-origins=*',
116
+ ]);
117
+ });
118
+ it('preserves app-specific extra launch args after the required CDP flags', () => {
119
+ expect(electronLaunchArgs(9234, ['--foo=bar'])).toEqual([
120
+ '--remote-debugging-port=9234',
121
+ '--remote-allow-origins=*',
122
+ '--foo=bar',
123
+ ]);
124
+ });
125
+ });
126
+ describe('launchElectronApp', () => {
127
+ beforeEach(() => {
128
+ vi.restoreAllMocks();
129
+ cp.spawn.mockReset();
130
+ });
131
+ it('falls back to the next executable candidate when the first is missing', async () => {
132
+ const firstChild = createMockChildProcess();
133
+ const secondChild = createMockChildProcess();
134
+ const app = {
135
+ port: 9234,
136
+ processName: 'Antigravity',
137
+ executableNames: ['Electron', 'Antigravity'],
138
+ };
139
+ cp.spawn
140
+ .mockImplementationOnce(() => {
141
+ queueMicrotask(() => firstChild.emit('error', Object.assign(new Error('missing binary'), { code: 'ENOENT' })));
142
+ return firstChild;
143
+ })
144
+ .mockImplementationOnce(() => {
145
+ queueMicrotask(() => secondChild.emit('spawn'));
146
+ return secondChild;
147
+ });
148
+ await expect(launchElectronApp('/Applications/Antigravity.app', app, ['--remote-debugging-port=9234'], 'Antigravity')).resolves.toBeUndefined();
149
+ expect(cp.spawn).toHaveBeenNthCalledWith(1, '/Applications/Antigravity.app/Contents/MacOS/Electron', ['--remote-debugging-port=9234'], { detached: true, stdio: 'ignore' });
150
+ expect(cp.spawn).toHaveBeenNthCalledWith(2, '/Applications/Antigravity.app/Contents/MacOS/Antigravity', ['--remote-debugging-port=9234'], { detached: true, stdio: 'ignore' });
151
+ expect(secondChild.unref).toHaveBeenCalledTimes(1);
152
+ });
153
+ });
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Unified logging for webcmd.
3
+ *
4
+ * All framework output (warnings, debug info, errors) should go through
5
+ * this module so that verbosity levels are respected consistently.
6
+ */
7
+ export declare const log: {
8
+ /** Informational message (always shown) */
9
+ info(msg: string): void;
10
+ /** Lightweight status line for adapter progress updates */
11
+ status(msg: string): void;
12
+ /** Positive completion/status line without the heavier info prefix */
13
+ success(msg: string): void;
14
+ /** Warning (always shown) */
15
+ warn(msg: string): void;
16
+ /** Error (always shown) */
17
+ error(msg: string): void;
18
+ /** Verbose output (shown when -v flag or WEBCMD_VERBOSE is set) */
19
+ verbose(msg: string): void;
20
+ /** Alias for verbose output. */
21
+ debug(msg: string): void;
22
+ /** Step-style debug (for pipeline steps, etc.) */
23
+ step(stepNum: number, total: number, op: string, preview?: string): void;
24
+ /** Step result summary */
25
+ stepResult(summary: string): void;
26
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Unified logging for webcmd.
3
+ *
4
+ * All framework output (warnings, debug info, errors) should go through
5
+ * this module so that verbosity levels are respected consistently.
6
+ */
7
+ function isVerbose() {
8
+ return !!process.env.WEBCMD_VERBOSE;
9
+ }
10
+ export const log = {
11
+ /** Informational message (always shown) */
12
+ info(msg) {
13
+ process.stderr.write(`ℹ ${msg}\n`);
14
+ },
15
+ /** Lightweight status line for adapter progress updates */
16
+ status(msg) {
17
+ process.stderr.write(`${msg}\n`);
18
+ },
19
+ /** Positive completion/status line without the heavier info prefix */
20
+ success(msg) {
21
+ process.stderr.write(`${msg}\n`);
22
+ },
23
+ /** Warning (always shown) */
24
+ warn(msg) {
25
+ process.stderr.write(`⚠ ${msg}\n`);
26
+ },
27
+ /** Error (always shown) */
28
+ error(msg) {
29
+ process.stderr.write(`✖ ${msg}\n`);
30
+ },
31
+ /** Verbose output (shown when -v flag or WEBCMD_VERBOSE is set) */
32
+ verbose(msg) {
33
+ if (isVerbose()) {
34
+ process.stderr.write(`[verbose] ${msg}\n`);
35
+ }
36
+ },
37
+ /** Alias for verbose output. */
38
+ debug(msg) {
39
+ this.verbose(msg);
40
+ },
41
+ /** Step-style debug (for pipeline steps, etc.) */
42
+ step(stepNum, total, op, preview = '') {
43
+ process.stderr.write(` [${stepNum}/${total}] ${op}${preview}\n`);
44
+ },
45
+ /** Step result summary */
46
+ stepResult(summary) {
47
+ process.stderr.write(` → ${summary}\n`);
48
+ },
49
+ };
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * webcmd — Make any website your CLI. AI-powered.
4
+ */
5
+ export {};
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * webcmd — Make any website your CLI. AI-powered.
4
+ */
5
+ // Ensure standard system paths are available for child processes.
6
+ // Some environments (GUI apps, cron, IDE terminals) launch with a minimal PATH
7
+ // that excludes /usr/local/bin, /usr/sbin, etc., causing external CLIs to fail.
8
+ if (process.platform !== 'win32') {
9
+ const std = ['/usr/local/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin'];
10
+ const cur = new Set((process.env.PATH ?? '').split(':').filter(Boolean));
11
+ for (const p of std)
12
+ cur.add(p);
13
+ process.env.PATH = [...cur].join(':');
14
+ }
15
+ import * as fs from 'node:fs';
16
+ import * as os from 'node:os';
17
+ import * as path from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { getCompletionsFromManifest, hasAllManifests, printCompletionScriptFast } from './completion-fast.js';
20
+ import { findPackageRoot, getCliManifestPath } from './package-paths.js';
21
+ import { PKG_VERSION } from './version.js';
22
+ import { EXIT_CODES } from './errors.js';
23
+ import { isSupportedNodeVersion, MIN_SUPPORTED_NODE_MAJOR } from './runtime-detect.js';
24
+ import { unsupportedDaemonPortEnvMessage } from './constants.js';
25
+ import { CONFIG_DIR_NAME } from './brand.js';
26
+ const __filename = fileURLToPath(import.meta.url);
27
+ const __dirname = path.dirname(__filename);
28
+ // Adapters are JS-first and live at <package-root>/clis/.
29
+ // Use findPackageRoot so the path works both in dev (src/main.ts) and prod (dist/src/main.js).
30
+ const BUILTIN_CLIS = path.join(findPackageRoot(__filename), 'clis');
31
+ const USER_CLIS = path.join(os.homedir(), CONFIG_DIR_NAME, 'clis');
32
+ // ── Ultra-fast path: lightweight commands bypass full discovery ──────────
33
+ // These are high-frequency or trivial paths that must not pay the startup tax.
34
+ const argv = process.argv.slice(2);
35
+ if (typeof globalThis.Bun === 'undefined' && !isSupportedNodeVersion(process.version)) {
36
+ process.stderr.write([
37
+ `Webcmd requires Node.js >= ${MIN_SUPPORTED_NODE_MAJOR}.0.0.`,
38
+ `Current runtime: ${process.version}`,
39
+ 'Upgrade Node.js, then retry the same command.',
40
+ '',
41
+ ].join('\n'));
42
+ process.exit(EXIT_CODES.CONFIG_ERROR);
43
+ }
44
+ if (process.env.WEBCMD_DAEMON_PORT) {
45
+ process.stderr.write(`error: ${unsupportedDaemonPortEnvMessage(process.env.WEBCMD_DAEMON_PORT)}\n`);
46
+ process.exit(EXIT_CODES.CONFIG_ERROR);
47
+ }
48
+ // Fast path: --version (only when it's the top-level intent, not passed to a subcommand)
49
+ // e.g. `webcmd --version` or `webcmd -V`, but NOT `webcmd gh --version`
50
+ if (argv[0] === '--version' || argv[0] === '-V') {
51
+ process.stdout.write(PKG_VERSION + '\n');
52
+ process.exit(EXIT_CODES.SUCCESS);
53
+ }
54
+ // Fast path: completion <shell> — print shell script without discovery
55
+ if (argv[0] === 'completion' && argv.length >= 2) {
56
+ if (printCompletionScriptFast(argv[1])) {
57
+ process.exit(EXIT_CODES.SUCCESS);
58
+ }
59
+ // Unknown shell — fall through to full path for proper error handling
60
+ }
61
+ // Fast path: --get-completions — read from manifest, skip discovery
62
+ const getCompIdx = process.argv.indexOf('--get-completions');
63
+ if (getCompIdx !== -1) {
64
+ // Only include manifests that actually exist on disk.
65
+ // With sparse override, the user clis dir may exist but have no manifest.
66
+ const manifestPaths = [getCliManifestPath(BUILTIN_CLIS)];
67
+ const userManifest = getCliManifestPath(USER_CLIS);
68
+ try {
69
+ fs.accessSync(userManifest);
70
+ manifestPaths.push(userManifest);
71
+ }
72
+ catch { /* no user manifest */ }
73
+ if (hasAllManifests(manifestPaths)) {
74
+ const rest = process.argv.slice(getCompIdx + 1);
75
+ let cursor;
76
+ const words = [];
77
+ for (let i = 0; i < rest.length; i++) {
78
+ if (rest[i] === '--cursor' && i + 1 < rest.length) {
79
+ cursor = parseInt(rest[i + 1], 10);
80
+ i++;
81
+ }
82
+ else {
83
+ words.push(rest[i]);
84
+ }
85
+ }
86
+ if (cursor === undefined)
87
+ cursor = words.length;
88
+ const candidates = getCompletionsFromManifest(words, cursor, manifestPaths);
89
+ process.stdout.write(candidates.join('\n') + '\n');
90
+ process.exit(EXIT_CODES.SUCCESS);
91
+ }
92
+ // No manifest — fall through to full discovery path below
93
+ }
94
+ // ── Full startup path ───────────────────────────────────────────────────
95
+ // Dynamic imports: these are deferred so the fast path above never pays the cost.
96
+ const { discoverClis, discoverPlugins, ensureUserCliCompatShims, ensureUserAdapters } = await import('./discovery.js');
97
+ const { getCompletions } = await import('./completion.js');
98
+ const { runCli } = await import('./cli.js');
99
+ const { emitHook } = await import('./hooks.js');
100
+ const { installNodeNetwork } = await import('./node-network.js');
101
+ const { registerUpdateNoticeOnExit, checkForUpdateBackground } = await import('./update-check.js');
102
+ installNodeNetwork();
103
+ // Parallelise independent startup I/O:
104
+ // - Built-in adapter discovery has no dependency on user-dir setup.
105
+ // - ensureUserCliCompatShims and ensureUserAdapters operate on different paths
106
+ // (~/.webcmd/node_modules/ vs ~/.webcmd/clis/ + adapter-manifest.json).
107
+ // - registerCommand() overwrites on name collision (see registry.ts), so
108
+ // user-CLI discovery MUST run after built-in discovery to preserve the
109
+ // intended override order (user adapters override built-in ones).
110
+ // - discoverPlugins runs last: plugins may override both built-in and user CLIs.
111
+ const skipUserDiscovery = argv[0] === 'convention-audit';
112
+ if (skipUserDiscovery) {
113
+ await discoverClis(BUILTIN_CLIS);
114
+ }
115
+ else {
116
+ const [, ,] = await Promise.all([
117
+ ensureUserCliCompatShims(),
118
+ ensureUserAdapters(),
119
+ discoverClis(BUILTIN_CLIS),
120
+ ]);
121
+ await discoverClis(USER_CLIS);
122
+ await discoverPlugins();
123
+ }
124
+ // Register exit hook: notice appears after command output (same as npm/gh/yarn)
125
+ registerUpdateNoticeOnExit();
126
+ // Kick off background fetch for next run (non-blocking)
127
+ checkForUpdateBackground();
128
+ // ── Fallback completion: manifest unavailable, use full registry ─────────
129
+ if (getCompIdx !== -1) {
130
+ const rest = process.argv.slice(getCompIdx + 1);
131
+ let cursor;
132
+ const words = [];
133
+ for (let i = 0; i < rest.length; i++) {
134
+ if (rest[i] === '--cursor' && i + 1 < rest.length) {
135
+ cursor = parseInt(rest[i + 1], 10);
136
+ i++;
137
+ }
138
+ else {
139
+ words.push(rest[i]);
140
+ }
141
+ }
142
+ if (cursor === undefined)
143
+ cursor = words.length;
144
+ const candidates = getCompletions(words, cursor);
145
+ process.stdout.write(candidates.join('\n') + '\n');
146
+ process.exit(EXIT_CODES.SUCCESS);
147
+ }
148
+ // Rewrite `webcmd browser <session> <subcommand> ...` so commander (which
149
+ // can't combine a parent positional with subcommand dispatch) sees the internal
150
+ // `--session <name>` flag form. Also refuses the retired `webcmd browser
151
+ // --session foo ...` user form with a friendly usage error.
152
+ const { rewriteBrowserArgv, BrowserSessionArgvError, escapeLeadingDashPositional } = await import('./cli-argv-preprocess.js');
153
+ try {
154
+ let rewritten = rewriteBrowserArgv(process.argv.slice(2));
155
+ // Insert a `--` separator before a required positional whose value starts
156
+ // with `-` (e.g. BOSS 直聘 securityId tokens; #1160). Skipped when the
157
+ // manifest is unavailable so the user-cli / dev paths still work.
158
+ try {
159
+ const manifestPath = getCliManifestPath(BUILTIN_CLIS);
160
+ if (fs.existsSync(manifestPath)) {
161
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));
162
+ if (Array.isArray(manifest))
163
+ rewritten = escapeLeadingDashPositional(rewritten, manifest);
164
+ }
165
+ }
166
+ catch { /* manifest unavailable; skip the dash escape */ }
167
+ process.argv.splice(2, process.argv.length - 2, ...rewritten);
168
+ }
169
+ catch (err) {
170
+ if (err instanceof BrowserSessionArgvError) {
171
+ process.stderr.write(`error: ${err.message}\n`);
172
+ process.exit(EXIT_CODES.GENERIC_ERROR);
173
+ }
174
+ throw err;
175
+ }
176
+ await emitHook('onStartup', { command: '__startup__', args: {} });
177
+ runCli(BUILTIN_CLIS, USER_CLIS);