@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,118 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import * as fs from 'node:fs';
3
+ import * as os from 'node:os';
4
+ import * as path from 'node:path';
5
+ import { parseByteSize, pruneTraceArtifacts } from './retention.js';
6
+ describe('trace artifact retention', () => {
7
+ let tmpDir;
8
+ let tracesDir;
9
+ beforeEach(() => {
10
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'webcmd-trace-retention-'));
11
+ tracesDir = path.join(tmpDir, 'profiles', 'default', 'traces');
12
+ fs.mkdirSync(tracesDir, { recursive: true });
13
+ });
14
+ afterEach(() => {
15
+ fs.rmSync(tmpDir, { recursive: true, force: true });
16
+ });
17
+ it('parses byte budgets with units', () => {
18
+ expect(parseByteSize(128)).toBe(128);
19
+ expect(parseByteSize('128')).toBe(128);
20
+ expect(parseByteSize('2KB')).toBe(2 * 1024);
21
+ expect(parseByteSize('1.5MB')).toBe(Math.floor(1.5 * 1024 * 1024));
22
+ expect(parseByteSize('1 GB')).toBe(1024 ** 3);
23
+ expect(() => parseByteSize('many')).toThrow('Invalid byte size');
24
+ });
25
+ it('prunes traces older than the age budget', () => {
26
+ const now = Date.parse('2026-05-03T00:00:00.000Z');
27
+ const old = createTraceDir('old', '2026-04-24T00:00:00.000Z');
28
+ const recent = createTraceDir('recent', '2026-05-02T00:00:00.000Z');
29
+ const result = pruneTraceArtifacts(tracesDir, {
30
+ now: () => now,
31
+ policy: { maxAgeDays: 7, maxCountPerProfile: 20, maxBytesPerProfile: '500MB' },
32
+ warn: vi.fn(),
33
+ });
34
+ expect(result.deleted).toEqual([old]);
35
+ expect(fs.existsSync(old)).toBe(false);
36
+ expect(fs.existsSync(recent)).toBe(true);
37
+ });
38
+ it('prunes oldest traces over the count budget', () => {
39
+ const oldest = createTraceDir('oldest', '2026-05-01T00:00:00.000Z');
40
+ const middle = createTraceDir('middle', '2026-05-02T00:00:00.000Z');
41
+ const newest = createTraceDir('newest', '2026-05-03T00:00:00.000Z');
42
+ const result = pruneTraceArtifacts(tracesDir, {
43
+ now: () => Date.parse('2026-05-03T12:00:00.000Z'),
44
+ policy: { maxAgeDays: 30, maxCountPerProfile: 2, maxBytesPerProfile: '500MB' },
45
+ warn: vi.fn(),
46
+ });
47
+ expect(result.deleted).toEqual([oldest]);
48
+ expect(fs.existsSync(oldest)).toBe(false);
49
+ expect(fs.existsSync(middle)).toBe(true);
50
+ expect(fs.existsSync(newest)).toBe(true);
51
+ });
52
+ it('prunes oldest traces over the byte budget', () => {
53
+ const oldest = createTraceDir('oldest', '2026-05-01T00:00:00.000Z', 512);
54
+ const middle = createTraceDir('middle', '2026-05-02T00:00:00.000Z', 64);
55
+ const newest = createTraceDir('newest', '2026-05-03T00:00:00.000Z', 64);
56
+ const budget = directorySize(middle) + directorySize(newest) + 1;
57
+ const result = pruneTraceArtifacts(tracesDir, {
58
+ now: () => Date.parse('2026-05-03T12:00:00.000Z'),
59
+ policy: { maxAgeDays: 30, maxCountPerProfile: 20, maxBytesPerProfile: budget },
60
+ warn: vi.fn(),
61
+ });
62
+ expect(result.deleted).toEqual([oldest]);
63
+ expect(fs.existsSync(oldest)).toBe(false);
64
+ expect(fs.existsSync(middle)).toBe(true);
65
+ expect(fs.existsSync(newest)).toBe(true);
66
+ });
67
+ it('falls back to directory mtime when receipt is missing', () => {
68
+ const now = Date.parse('2026-05-03T00:00:00.000Z');
69
+ const old = createTraceDir('old-no-receipt', undefined);
70
+ const recent = createTraceDir('recent', '2026-05-02T00:00:00.000Z');
71
+ const oldDate = new Date('2026-04-20T00:00:00.000Z');
72
+ fs.utimesSync(old, oldDate, oldDate);
73
+ const result = pruneTraceArtifacts(tracesDir, {
74
+ now: () => now,
75
+ policy: { maxAgeDays: 7, maxCountPerProfile: 20, maxBytesPerProfile: '500MB' },
76
+ warn: vi.fn(),
77
+ });
78
+ expect(result.deleted).toEqual([old]);
79
+ expect(fs.existsSync(old)).toBe(false);
80
+ expect(fs.existsSync(recent)).toBe(true);
81
+ });
82
+ it('does not delete the protected trace exported by the current run', () => {
83
+ const old = createTraceDir('oldest', '2026-05-01T00:00:00.000Z');
84
+ const current = createTraceDir('current', '2026-04-01T00:00:00.000Z', 1024);
85
+ const result = pruneTraceArtifacts(tracesDir, {
86
+ now: () => Date.parse('2026-05-03T12:00:00.000Z'),
87
+ policy: { maxAgeDays: 0, maxCountPerProfile: 0, maxBytesPerProfile: 1 },
88
+ protectedTraceDirs: [current],
89
+ warn: vi.fn(),
90
+ });
91
+ expect(result.deleted).toEqual([old]);
92
+ expect(fs.existsSync(old)).toBe(false);
93
+ expect(fs.existsSync(current)).toBe(true);
94
+ });
95
+ function createTraceDir(name, createdAt, payloadBytes = 8) {
96
+ const dir = path.join(tracesDir, name);
97
+ fs.mkdirSync(dir, { recursive: true });
98
+ fs.writeFileSync(path.join(dir, 'trace.jsonl'), 'x'.repeat(payloadBytes), 'utf-8');
99
+ if (createdAt) {
100
+ fs.writeFileSync(path.join(dir, 'receipt.json'), JSON.stringify({ createdAt }, null, 2), 'utf-8');
101
+ const date = new Date(createdAt);
102
+ fs.utimesSync(dir, date, date);
103
+ }
104
+ return dir;
105
+ }
106
+ });
107
+ function directorySize(dir) {
108
+ let total = 0;
109
+ for (const name of fs.readdirSync(dir)) {
110
+ const item = path.join(dir, name);
111
+ const stat = fs.lstatSync(item);
112
+ if (stat.isDirectory())
113
+ total += directorySize(item);
114
+ else
115
+ total += stat.size;
116
+ }
117
+ return total;
118
+ }
@@ -0,0 +1,22 @@
1
+ export interface RingBufferOptions {
2
+ maxAgeMs?: number;
3
+ maxItems?: number;
4
+ now?: () => number;
5
+ }
6
+ export declare class RingBuffer<T extends {
7
+ ts: number;
8
+ }> {
9
+ private readonly maxAgeMs;
10
+ private readonly maxItems;
11
+ private readonly now;
12
+ private items;
13
+ constructor(opts?: RingBufferOptions);
14
+ push(item: T): void;
15
+ values(opts?: {
16
+ since?: number;
17
+ until?: number;
18
+ }): T[];
19
+ clear(): void;
20
+ get size(): number;
21
+ private prune;
22
+ }
@@ -0,0 +1,45 @@
1
+ export class RingBuffer {
2
+ maxAgeMs;
3
+ maxItems;
4
+ now;
5
+ items = [];
6
+ constructor(opts = {}) {
7
+ this.maxAgeMs = opts.maxAgeMs ?? 120_000;
8
+ this.maxItems = opts.maxItems ?? 1_000;
9
+ this.now = opts.now ?? Date.now;
10
+ }
11
+ push(item) {
12
+ this.items.push(item);
13
+ this.prune();
14
+ }
15
+ values(opts = {}) {
16
+ this.prune();
17
+ return this.items.filter((item) => {
18
+ if (opts.since !== undefined && item.ts < opts.since)
19
+ return false;
20
+ if (opts.until !== undefined && item.ts > opts.until)
21
+ return false;
22
+ return true;
23
+ });
24
+ }
25
+ clear() {
26
+ this.items = [];
27
+ }
28
+ get size() {
29
+ this.prune();
30
+ return this.items.length;
31
+ }
32
+ prune() {
33
+ const minTs = this.now() - this.maxAgeMs;
34
+ if (this.items.length > this.maxItems) {
35
+ this.items = this.items.slice(this.items.length - this.maxItems);
36
+ }
37
+ if (this.maxAgeMs > 0) {
38
+ const firstKept = this.items.findIndex((item) => item.ts >= minTs);
39
+ if (firstKept > 0)
40
+ this.items = this.items.slice(firstKept);
41
+ else if (firstKept === -1)
42
+ this.items = [];
43
+ }
44
+ }
45
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { RingBuffer } from './ring-buffer.js';
3
+ describe('RingBuffer', () => {
4
+ it('keeps items in event order and filters by time window', () => {
5
+ let now = 10_000;
6
+ const buffer = new RingBuffer({ maxAgeMs: 5_000, now: () => now });
7
+ buffer.push({ ts: 4_000, value: 'old' });
8
+ buffer.push({ ts: 7_000, value: 'kept' });
9
+ buffer.push({ ts: 9_000, value: 'new' });
10
+ expect(buffer.values().map((item) => item.value)).toEqual(['kept', 'new']);
11
+ expect(buffer.values({ since: 8_000 }).map((item) => item.value)).toEqual(['new']);
12
+ now = 13_000;
13
+ expect(buffer.values().map((item) => item.value)).toEqual(['new']);
14
+ });
15
+ it('caps by item count', () => {
16
+ const buffer = new RingBuffer({ maxItems: 2, maxAgeMs: 100_000, now: () => 10 });
17
+ buffer.push({ ts: 1, value: 1 });
18
+ buffer.push({ ts: 2, value: 2 });
19
+ buffer.push({ ts: 3, value: 3 });
20
+ expect(buffer.values().map((item) => item.value)).toEqual([2, 3]);
21
+ });
22
+ });
@@ -0,0 +1,25 @@
1
+ import type { ObservationEvent, ObservationEventInput, ObservationScope, ObservationStream } from './events.js';
2
+ export declare const DEFAULT_OBSERVATION_WINDOW_MS = 120000;
3
+ export interface ObservationSessionOptions {
4
+ id?: string;
5
+ scope: ObservationScope;
6
+ windowMs?: number;
7
+ maxEventsPerStream?: number;
8
+ now?: () => number;
9
+ }
10
+ export declare class ObservationSession {
11
+ readonly id: string;
12
+ readonly scope: ObservationScope;
13
+ readonly startedAt: number;
14
+ private readonly now;
15
+ private counter;
16
+ private readonly buffers;
17
+ constructor(opts: ObservationSessionOptions);
18
+ record(input: ObservationEventInput): ObservationEvent;
19
+ events(opts?: {
20
+ stream?: ObservationStream;
21
+ since?: number;
22
+ until?: number;
23
+ }): ObservationEvent[];
24
+ }
25
+ export declare function createTraceId(now?: number | (() => number)): string;
@@ -0,0 +1,50 @@
1
+ import { RingBuffer } from './ring-buffer.js';
2
+ import { randomBytes } from 'node:crypto';
3
+ export const DEFAULT_OBSERVATION_WINDOW_MS = 120_000;
4
+ export class ObservationSession {
5
+ id;
6
+ scope;
7
+ startedAt;
8
+ now;
9
+ counter = 0;
10
+ buffers;
11
+ constructor(opts) {
12
+ this.id = opts.id ?? createTraceId(opts.now?.() ?? Date.now());
13
+ this.scope = opts.scope;
14
+ this.now = opts.now ?? Date.now;
15
+ this.startedAt = this.now();
16
+ const bufferOpts = {
17
+ maxAgeMs: opts.windowMs ?? DEFAULT_OBSERVATION_WINDOW_MS,
18
+ maxItems: opts.maxEventsPerStream ?? 1_000,
19
+ now: this.now,
20
+ };
21
+ this.buffers = {
22
+ action: new RingBuffer(bufferOpts),
23
+ network: new RingBuffer(bufferOpts),
24
+ console: new RingBuffer(bufferOpts),
25
+ screenshot: new RingBuffer({ ...bufferOpts, maxItems: Math.min(opts.maxEventsPerStream ?? 50, 50) }),
26
+ state: new RingBuffer({ ...bufferOpts, maxItems: Math.min(opts.maxEventsPerStream ?? 50, 50) }),
27
+ error: new RingBuffer(bufferOpts),
28
+ };
29
+ }
30
+ record(input) {
31
+ const event = {
32
+ ...input,
33
+ id: input.id ?? `${this.id}-${++this.counter}`,
34
+ ts: input.ts ?? this.now(),
35
+ };
36
+ this.buffers[event.stream].push(event);
37
+ return event;
38
+ }
39
+ events(opts = {}) {
40
+ const streams = opts.stream ? [opts.stream] : Object.keys(this.buffers);
41
+ return streams
42
+ .flatMap((stream) => this.buffers[stream].values({ since: opts.since, until: opts.until }))
43
+ .sort((a, b) => a.ts - b.ts || a.id.localeCompare(b.id));
44
+ }
45
+ }
46
+ export function createTraceId(now = Date.now) {
47
+ const ts = typeof now === 'function' ? now() : now;
48
+ const rand = randomBytes(4).toString('hex');
49
+ return `${new Date(ts).toISOString().replace(/[-:.TZ]/g, '').slice(0, 14)}-${rand}`;
50
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Output formatting: table, JSON, Markdown, CSV, YAML.
3
+ */
4
+ export interface RenderOptions {
5
+ fmt?: string;
6
+ /** True when the user explicitly passed -f on the command line */
7
+ fmtExplicit?: boolean;
8
+ columns?: string[];
9
+ title?: string;
10
+ elapsed?: number;
11
+ source?: string;
12
+ footerExtra?: string;
13
+ }
14
+ export declare function render(data: unknown, opts?: RenderOptions): void;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Output formatting: table, JSON, Markdown, CSV, YAML.
3
+ */
4
+ import Table from 'cli-table3';
5
+ import yaml from 'js-yaml';
6
+ function normalizeRows(data) {
7
+ if (Array.isArray(data))
8
+ return data;
9
+ if (data && typeof data === 'object')
10
+ return [data];
11
+ return [{ value: data }];
12
+ }
13
+ function resolveColumns(rows, opts) {
14
+ return opts.columns ?? Object.keys(rows[0] ?? {});
15
+ }
16
+ export function render(data, opts = {}) {
17
+ let fmt = opts.fmt ?? 'table';
18
+ // Non-TTY auto-downgrade only when format was NOT explicitly passed by user.
19
+ if (!opts.fmtExplicit) {
20
+ if (fmt === 'table' && !process.stdout.isTTY)
21
+ fmt = 'yaml';
22
+ }
23
+ if (data === null || data === undefined) {
24
+ console.log(data);
25
+ return;
26
+ }
27
+ switch (fmt) {
28
+ case 'json':
29
+ renderJson(data);
30
+ break;
31
+ case 'plain':
32
+ renderPlain(data, opts);
33
+ break;
34
+ case 'md':
35
+ case 'markdown':
36
+ renderMarkdown(data, opts);
37
+ break;
38
+ case 'csv':
39
+ renderCsv(data, opts);
40
+ break;
41
+ case 'yaml':
42
+ case 'yml':
43
+ renderYaml(data);
44
+ break;
45
+ default:
46
+ renderTable(data, opts);
47
+ break;
48
+ }
49
+ }
50
+ function renderTable(data, opts) {
51
+ const rows = normalizeRows(data);
52
+ if (!rows.length) {
53
+ console.log('(no data)');
54
+ return;
55
+ }
56
+ const columns = resolveColumns(rows, opts);
57
+ const header = columns.map(c => capitalize(c));
58
+ const table = new Table({
59
+ head: header.map(h => h),
60
+ style: { head: [], border: [] },
61
+ wordWrap: true,
62
+ wrapOnWordBoundary: true,
63
+ });
64
+ for (const row of rows) {
65
+ table.push(columns.map(c => {
66
+ const v = row[c];
67
+ return v === null || v === undefined ? '' : String(v);
68
+ }));
69
+ }
70
+ console.log();
71
+ if (opts.title)
72
+ console.log(` ${opts.title}`);
73
+ console.log(table.toString());
74
+ const footer = [];
75
+ footer.push(`${rows.length} items`);
76
+ if (opts.elapsed !== undefined)
77
+ footer.push(`${opts.elapsed.toFixed(1)}s`);
78
+ if (opts.source)
79
+ footer.push(opts.source);
80
+ if (opts.footerExtra)
81
+ footer.push(opts.footerExtra);
82
+ console.log(footer.join(' · '));
83
+ }
84
+ function renderJson(data) {
85
+ console.log(JSON.stringify(data, null, 2));
86
+ }
87
+ function renderPlain(data, opts) {
88
+ const rows = normalizeRows(data);
89
+ if (!rows.length)
90
+ return;
91
+ // Single-row single-field shortcuts for chat-style commands.
92
+ if (rows.length === 1) {
93
+ const row = rows[0];
94
+ const entries = Object.entries(row);
95
+ if (entries.length === 1) {
96
+ const [key, value] = entries[0];
97
+ if (key === 'response' || key === 'content' || key === 'markdown' || key === 'text' || key === 'value') {
98
+ console.log(String(value ?? ''));
99
+ return;
100
+ }
101
+ }
102
+ }
103
+ rows.forEach((row, index) => {
104
+ const entries = Object.entries(row).filter(([, value]) => value !== undefined && value !== null && String(value) !== '');
105
+ entries.forEach(([key, value]) => {
106
+ console.log(`${key}: ${value}`);
107
+ });
108
+ if (index < rows.length - 1)
109
+ console.log('');
110
+ });
111
+ }
112
+ function renderMarkdown(data, opts) {
113
+ const rows = normalizeRows(data);
114
+ if (!rows.length)
115
+ return;
116
+ if (rows.length === 1) {
117
+ const entries = Object.entries(rows[0]);
118
+ if (entries.length === 1) {
119
+ const [key, value] = entries[0];
120
+ if (key === 'content' || key === 'markdown' || key === 'text' || key === 'value') {
121
+ console.log(String(value ?? ''));
122
+ return;
123
+ }
124
+ }
125
+ }
126
+ const columns = resolveColumns(rows, opts);
127
+ console.log('| ' + columns.join(' | ') + ' |');
128
+ console.log('| ' + columns.map(() => '---').join(' | ') + ' |');
129
+ for (const row of rows) {
130
+ console.log('| ' + columns.map(c => String(row[c] ?? '')).join(' | ') + ' |');
131
+ }
132
+ }
133
+ function renderCsv(data, opts) {
134
+ const rows = normalizeRows(data);
135
+ if (!rows.length)
136
+ return;
137
+ const columns = resolveColumns(rows, opts);
138
+ console.log(columns.join(','));
139
+ for (const row of rows) {
140
+ console.log(columns.map(c => {
141
+ const v = String(row[c] ?? '');
142
+ return v.includes(',') || v.includes('"') || v.includes('\n') || v.includes('\r')
143
+ ? `"${v.replace(/"/g, '""')}"` : v;
144
+ }).join(','));
145
+ }
146
+ }
147
+ function renderYaml(data) {
148
+ console.log(yaml.dump(data, { sortKeys: false, lineWidth: 120, noRefs: true }));
149
+ }
150
+ function capitalize(s) {
151
+ return s.charAt(0).toUpperCase() + s.slice(1);
152
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
2
+ import { render } from './output.js';
3
+ describe('output TTY detection', () => {
4
+ const originalIsTTY = process.stdout.isTTY;
5
+ let logSpy;
6
+ beforeEach(() => {
7
+ logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
8
+ });
9
+ afterEach(() => {
10
+ Object.defineProperty(process.stdout, 'isTTY', { value: originalIsTTY, writable: true });
11
+ logSpy.mockRestore();
12
+ });
13
+ it('outputs YAML in non-TTY when format is default table', () => {
14
+ Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
15
+ // commanderAdapter always passes fmt:'table' as default — this must still trigger downgrade
16
+ render([{ name: 'alice', score: 10 }], { fmt: 'table', columns: ['name', 'score'] });
17
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
18
+ expect(out).toContain('name: alice');
19
+ expect(out).toContain('score: 10');
20
+ });
21
+ it('outputs table in TTY when format is default table', () => {
22
+ Object.defineProperty(process.stdout, 'isTTY', { value: true, writable: true });
23
+ render([{ name: 'alice', score: 10 }], { fmt: 'table', columns: ['name', 'score'] });
24
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
25
+ expect(out).toContain('alice');
26
+ });
27
+ it('respects explicit -f json even in non-TTY', () => {
28
+ Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
29
+ render([{ name: 'alice' }], { fmt: 'json' });
30
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
31
+ expect(JSON.parse(out)).toEqual([{ name: 'alice' }]);
32
+ });
33
+ it('shows elapsed time when elapsed is 0', () => {
34
+ Object.defineProperty(process.stdout, 'isTTY', { value: true, writable: true });
35
+ render([{ name: 'alice' }], { fmt: 'table', columns: ['name'], elapsed: 0 });
36
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
37
+ expect(out).toContain('0.0s');
38
+ });
39
+ it('explicit -f table overrides non-TTY auto-downgrade', () => {
40
+ Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
41
+ render([{ name: 'alice' }], { fmt: 'table', fmtExplicit: true, columns: ['name'] });
42
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
43
+ // Should be table output, not YAML
44
+ expect(out).not.toContain('name: alice');
45
+ expect(out).toContain('alice');
46
+ });
47
+ it('prints single markdown payloads without wrapping them in a table', () => {
48
+ render([{ markdown: '# Title\n\nBody' }], { fmt: 'md' });
49
+ const out = logSpy.mock.calls.map((c) => c[0]).join('\n');
50
+ expect(out).toBe('# Title\n\nBody');
51
+ expect(out).not.toContain('| markdown |');
52
+ });
53
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Regression tests for package exports.
3
+ *
4
+ * Ensures adapter files use @agentrhq/webcmd public package imports
5
+ * (not fragile relative paths) and that all declared exports resolve
6
+ * to real files.
7
+ */
8
+ import { describe, it, expect } from 'vitest';
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import { builtinModules } from 'node:module';
12
+ import { fileURLToPath } from 'node:url';
13
+ import ts from 'typescript';
14
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
+ const ROOT = path.resolve(__dirname, '..');
16
+ const CLIS_DIR = path.join(ROOT, 'clis');
17
+ /** Recursively collect all JS adapter files in a directory. */
18
+ function collectAdapterFiles(dir, opts) {
19
+ const results = [];
20
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
21
+ const full = path.join(dir, entry.name);
22
+ if (entry.isDirectory()) {
23
+ results.push(...collectAdapterFiles(full, opts));
24
+ }
25
+ else if (entry.name.endsWith('.js') && !entry.name.endsWith('.d.js')) {
26
+ if (opts?.excludeTests && (entry.name.endsWith('.test.js') || entry.name.startsWith('test-')))
27
+ continue;
28
+ results.push(full);
29
+ }
30
+ }
31
+ return results;
32
+ }
33
+ const ALLOWED_BARE_IMPORTS = new Set([
34
+ '@agentrhq/webcmd',
35
+ ...builtinModules.flatMap((name) => name.startsWith('node:')
36
+ ? [name, name.slice(5)]
37
+ : [name, `node:${name}`]),
38
+ ]);
39
+ function isAllowedImport(specifier) {
40
+ return specifier.startsWith('./')
41
+ || specifier.startsWith('../')
42
+ || specifier.startsWith('/')
43
+ || specifier.startsWith('@agentrhq/webcmd/')
44
+ || ALLOWED_BARE_IMPORTS.has(specifier);
45
+ }
46
+ /** Forbidden relative import patterns that should have been replaced.
47
+ * Uses (?:\.\./)+ to catch any depth of ../ traversal.
48
+ * Covers: import/export from, vi.mock(), vi.importActual(). */
49
+ const FORBIDDEN_PATTERNS = [
50
+ /(?:from|mock|importActual)\s*\(?['"](?:\.\.\/)+src\//,
51
+ /(?:from|mock|importActual)\s*\(?['"](?:\.\.\/)+browser\//,
52
+ /(?:from|mock|importActual)\s*\(?['"](?:\.\.\/)+download\//,
53
+ /(?:from|mock|importActual)\s*\(?['"](?:\.\.\/)+pipeline\//,
54
+ ];
55
+ describe('adapter imports use package exports', () => {
56
+ const adapterFiles = collectAdapterFiles(CLIS_DIR);
57
+ const runtimeAdapterFiles = collectAdapterFiles(CLIS_DIR, { excludeTests: true });
58
+ it('found adapter files to check', () => {
59
+ expect(adapterFiles.length).toBeGreaterThan(100);
60
+ });
61
+ it('no adapter uses relative imports to src/, browser/, download/, or pipeline/', () => {
62
+ const violations = [];
63
+ for (const file of adapterFiles) {
64
+ const content = fs.readFileSync(file, 'utf-8');
65
+ for (const pattern of FORBIDDEN_PATTERNS) {
66
+ if (pattern.test(content)) {
67
+ const rel = path.relative(ROOT, file);
68
+ const match = content.match(pattern)?.[0];
69
+ violations.push(`${rel}: ${match}`);
70
+ }
71
+ }
72
+ }
73
+ expect(violations).toEqual([]);
74
+ });
75
+ it('non-test adapters only import node builtins, relative modules, or webcmd public APIs', () => {
76
+ const violations = [];
77
+ for (const file of runtimeAdapterFiles) {
78
+ const source = fs.readFileSync(file, 'utf-8');
79
+ const module = ts.createSourceFile(file, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS);
80
+ for (const stmt of module.statements) {
81
+ if (!ts.isImportDeclaration(stmt) && !ts.isExportDeclaration(stmt))
82
+ continue;
83
+ const specifier = stmt.moduleSpecifier?.getText(module).slice(1, -1);
84
+ if (specifier && !isAllowedImport(specifier)) {
85
+ violations.push({
86
+ file: path.relative(ROOT, file),
87
+ specifier,
88
+ });
89
+ }
90
+ }
91
+ }
92
+ expect(violations).toEqual([]);
93
+ });
94
+ });
95
+ describe('package.json exports resolve to real files', () => {
96
+ const pkgJson = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf-8'));
97
+ const exports = pkgJson.exports;
98
+ it('has exports defined', () => {
99
+ expect(Object.keys(exports).length).toBeGreaterThan(5);
100
+ });
101
+ for (const [exportPath, target] of Object.entries(exports)) {
102
+ it(`export "${exportPath}" → ${target} has a source file`, () => {
103
+ // Export targets point to dist/ (compiled). Verify the source .ts exists.
104
+ // dist/src/foo.js → src/foo.ts
105
+ const sourcePath = target
106
+ .replace(/^\.\/dist\//, './')
107
+ .replace(/\.js$/, '.ts');
108
+ const fullPath = path.join(ROOT, sourcePath);
109
+ expect(fs.existsSync(fullPath), `Missing source: ${sourcePath}`).toBe(true);
110
+ });
111
+ }
112
+ });
@@ -0,0 +1,8 @@
1
+ export interface PackageJsonLike {
2
+ bin?: string | Record<string, string>;
3
+ main?: string;
4
+ }
5
+ export declare function findPackageRoot(startFile: string, fileExists?: (candidate: string) => boolean): string;
6
+ export declare function getBuiltEntryCandidates(packageRoot: string, readFile?: (filePath: string) => string): string[];
7
+ export declare function getCliManifestPath(clisDir: string): string;
8
+ export declare function getFetchAdaptersScriptPath(packageRoot: string): string;