lasso-mcp 1.18.1 → 1.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/.dedao-extract/.qc-v3/fk-14.png +0 -0
  2. package/.dedao-extract/.qc-v3/fkp2-02.png +0 -0
  3. package/.dedao-extract/.qc-v3/l001-6.png +0 -0
  4. package/.dedao-extract/.qc-v3/l001-7.png +0 -0
  5. package/.dedao-extract/.qc-v3/l002-4.png +0 -0
  6. package/.dedao-extract/analyze.mjs +169 -0
  7. package/.dedao-extract/dbg-fixscreen.mjs +43 -0
  8. package/.dedao-extract/dbg-text.mjs +25 -0
  9. package/.dedao-extract/dbg-text2.mjs +20 -0
  10. package/.dedao-extract/dbg-text3.mjs +18 -0
  11. package/.dedao-extract/dbg-text4.mjs +27 -0
  12. package/.dedao-extract/dbg-text5.mjs +31 -0
  13. package/.dedao-extract/extract-v2.mjs +539 -0
  14. package/.dedao-extract/extract-v3.mjs +745 -0
  15. package/.dedao-extract/gapfill.mjs +217 -0
  16. package/.dedao-extract/probe-frag.mjs +125 -0
  17. package/.dedao-extract/prod-chapters-dry.json +2516 -0
  18. package/.dedao-extract/prod-enumeration.json +1682 -0
  19. package/.dedao-extract/produce-all.mjs +555 -0
  20. package/.dedao-extract/qc-final.mjs +65 -0
  21. package/.dedao-extract/qc-v3.mjs +91 -0
  22. package/.dedao-extract/r2-01-navigate.json +14 -0
  23. package/.dedao-extract/r2-98-results.json +697 -0
  24. package/.dedao-extract/r2-99-log.json +15 -0
  25. package/.dedao-extract/r2-analyze.mjs +96 -0
  26. package/.dedao-extract/r2-fk-dump.json +139 -0
  27. package/.dedao-extract/r2-fk-figattr.json +62 -0
  28. package/.dedao-extract/r2-fk-pagemap.json +64 -0
  29. package/.dedao-extract/r2-l001-dump.json +129 -0
  30. package/.dedao-extract/r2-l001-figattr.json +53 -0
  31. package/.dedao-extract/r2-l001-pagemap.json +55 -0
  32. package/.dedao-extract/r2-l002-dump.json +109 -0
  33. package/.dedao-extract/r2-l002-figattr.json +35 -0
  34. package/.dedao-extract/r2-l002-pagemap.json +37 -0
  35. package/.dedao-extract/s8-01-navigate.json +14 -0
  36. package/.dedao-extract/s8-98-results.json +43 -0
  37. package/.dedao-extract/s8-99-log.json +24 -0
  38. package/.dedao-extract/s8-fk-fix.json +15 -0
  39. package/.dedao-extract/s8-fk-pagemap-post.json +58 -0
  40. package/.dedao-extract/s8-fk-pagemap-pre.json +68 -0
  41. package/.dedao-extract/s8-fk-promo.json +11 -0
  42. package/.dedao-extract/s8-ink.mjs +49 -0
  43. package/.dedao-extract/s8-l003-fix.json +21 -0
  44. package/.dedao-extract/s8-l003-pagemap-post.json +38 -0
  45. package/.dedao-extract/s8-l003-pagemap-pre.json +48 -0
  46. package/.dedao-extract/s8-l003-promo.json +11 -0
  47. package/.dedao-extract/s9-sikao.json +394 -0
  48. package/.dedao-extract/scout7-round2.mjs +386 -0
  49. package/.dedao-extract/scout7b.mjs +121 -0
  50. package/.dedao-extract/scout7c.mjs +99 -0
  51. package/.dedao-extract/scout8.mjs +334 -0
  52. package/.dedao-extract/scout9.mjs +121 -0
  53. package/.dedao-extract/scratch/fk-01.pgm +75 -0
  54. package/.dedao-extract/scratch/fk-02.pgm +4 -0
  55. package/.dedao-extract/scratch/fk-03.pgm +207 -0
  56. package/.dedao-extract/scratch/fk-04.pgm +986 -0
  57. package/.dedao-extract/scratch/fk-05.pgm +4 -0
  58. package/.dedao-extract/scratch/fk-06.pgm +4 -0
  59. package/.dedao-extract/scratch/fk-07.pgm +4 -0
  60. package/.dedao-extract/scratch/fk-08.pgm +4 -0
  61. package/.dedao-extract/scratch/fk-09.pgm +4 -0
  62. package/.dedao-extract/scratch/fk-10.pgm +4 -0
  63. package/.dedao-extract/scratch/fk-11.pgm +4 -0
  64. package/.dedao-extract/scratch/fk-12.pgm +4 -0
  65. package/.dedao-extract/scratch/fk-13.pgm +4 -0
  66. package/.dedao-extract/scratch/fk-14.pgm +107 -0
  67. package/.dedao-extract/scratch/fk-analysis.json +47 -0
  68. package/.dedao-extract/scratch/fk-before.pdf +0 -0
  69. package/.dedao-extract/scratch/fk-clean-inner.txt +42 -0
  70. package/.dedao-extract/scratch/fk-dom-inner.txt +381 -0
  71. package/.dedao-extract/scratch/fk-fix-inner.txt +42 -0
  72. package/.dedao-extract/scratch/fk-pdftotext.txt +66 -0
  73. package/.dedao-extract/scratch/fk-r3-base.pdf +0 -0
  74. package/.dedao-extract/scratch/fk-r3-base.txt +66 -0
  75. package/.dedao-extract/scratch/fk-r3-fix.pdf +0 -0
  76. package/.dedao-extract/scratch/fk-r3-fix.txt +66 -0
  77. package/.dedao-extract/scratch/fk-r3-s09.pdf +0 -0
  78. package/.dedao-extract/scratch/l001-1.pgm +6 -0
  79. package/.dedao-extract/scratch/l001-2.pgm +38 -0
  80. package/.dedao-extract/scratch/l001-3.pgm +38 -0
  81. package/.dedao-extract/scratch/l001-4.pgm +4 -0
  82. package/.dedao-extract/scratch/l001-5.pgm +179 -0
  83. package/.dedao-extract/scratch/l001-6.pgm +43 -1
  84. package/.dedao-extract/scratch/l001-7.pgm +4 -0
  85. package/.dedao-extract/scratch/l001-8.pgm +107 -0
  86. package/.dedao-extract/scratch/l001-analysis.json +23 -0
  87. package/.dedao-extract/scratch/l001-before.pdf +0 -0
  88. package/.dedao-extract/scratch/l001-dom-inner.txt +444 -0
  89. package/.dedao-extract/scratch/l001-pdftotext.txt +146 -0
  90. package/.dedao-extract/scratch/l002-1.pgm +6 -0
  91. package/.dedao-extract/scratch/l002-2.pgm +4 -0
  92. package/.dedao-extract/scratch/l002-3.pgm +4 -0
  93. package/.dedao-extract/scratch/l002-4.pgm +4 -0
  94. package/.dedao-extract/scratch/l002-5.pgm +106 -0
  95. package/.dedao-extract/scratch/l002-analysis.json +17 -0
  96. package/.dedao-extract/scratch/l002-before.pdf +0 -0
  97. package/.dedao-extract/scratch/l002-dom-inner.txt +392 -0
  98. package/.dedao-extract/scratch/l002-pdftotext.txt +82 -0
  99. package/.dedao-extract/scratch/l003-clean-inner.txt +74 -0
  100. package/.dedao-extract/scratch/l003-fix-inner.txt +74 -0
  101. package/.dedao-extract/scratch/l003-r3-base.pdf +0 -0
  102. package/.dedao-extract/scratch/l003-r3-base.txt +109 -0
  103. package/.dedao-extract/scratch/l003-r3-fix.pdf +0 -0
  104. package/.dedao-extract/scratch/l003-r3-fix.txt +108 -0
  105. package/.dedao-extract/scratch/pp-fk-r3-base-01.pgm +32 -0
  106. package/.dedao-extract/scratch/pp-fk-r3-base-02.pgm +4 -0
  107. package/.dedao-extract/scratch/pp-fk-r3-base-03.pgm +119 -0
  108. package/.dedao-extract/scratch/pp-fk-r3-base-04.pgm +496 -0
  109. package/.dedao-extract/scratch/pp-fk-r3-base-05.pgm +4 -0
  110. package/.dedao-extract/scratch/pp-fk-r3-base-06.pgm +4 -0
  111. package/.dedao-extract/scratch/pp-fk-r3-base-07.pgm +4 -0
  112. package/.dedao-extract/scratch/pp-fk-r3-base-08.pgm +4 -0
  113. package/.dedao-extract/scratch/pp-fk-r3-base-09.pgm +4 -0
  114. package/.dedao-extract/scratch/pp-fk-r3-base-10.pgm +4 -0
  115. package/.dedao-extract/scratch/pp-fk-r3-base-11.pgm +4 -0
  116. package/.dedao-extract/scratch/pp-fk-r3-base-12.pgm +4 -0
  117. package/.dedao-extract/scratch/pp-fk-r3-base-13.pgm +4 -0
  118. package/.dedao-extract/scratch/pp-fk-r3-base-14.pgm +58 -0
  119. package/.dedao-extract/scratch/pp-fk-r3-fix-01.pgm +32 -0
  120. package/.dedao-extract/scratch/pp-fk-r3-fix-02.pgm +4 -0
  121. package/.dedao-extract/scratch/pp-fk-r3-fix-03.pgm +119 -0
  122. package/.dedao-extract/scratch/pp-fk-r3-fix-04.pgm +496 -0
  123. package/.dedao-extract/scratch/pp-fk-r3-fix-05.pgm +4 -0
  124. package/.dedao-extract/scratch/pp-fk-r3-fix-06.pgm +4 -0
  125. package/.dedao-extract/scratch/pp-fk-r3-fix-07.pgm +4 -0
  126. package/.dedao-extract/scratch/pp-fk-r3-fix-08.pgm +4 -0
  127. package/.dedao-extract/scratch/pp-fk-r3-fix-09.pgm +4 -0
  128. package/.dedao-extract/scratch/pp-fk-r3-fix-10.pgm +4 -0
  129. package/.dedao-extract/scratch/pp-fk-r3-fix-11.pgm +4 -0
  130. package/.dedao-extract/scratch/pp-fk-r3-fix-12.pgm +4 -0
  131. package/.dedao-extract/scratch/pp-fk-r3-fix-13.pgm +4 -0
  132. package/.dedao-extract/scratch/pp-fk-r3-fix-14.pgm +4 -0
  133. package/.dedao-extract/scratch/pp-fk-r3-s09-01.pgm +15 -0
  134. package/.dedao-extract/scratch/pp-fk-r3-s09-02.pgm +4 -0
  135. package/.dedao-extract/scratch/pp-fk-r3-s09-03.pgm +27 -0
  136. package/.dedao-extract/scratch/pp-fk-r3-s09-04.pgm +128 -0
  137. package/.dedao-extract/scratch/pp-fk-r3-s09-05.pgm +4 -0
  138. package/.dedao-extract/scratch/pp-fk-r3-s09-06.pgm +4 -0
  139. package/.dedao-extract/scratch/pp-fk-r3-s09-07.pgm +4 -0
  140. package/.dedao-extract/scratch/pp-fk-r3-s09-08.pgm +4 -0
  141. package/.dedao-extract/scratch/pp-fk-r3-s09-09.pgm +4 -0
  142. package/.dedao-extract/scratch/pp-fk-r3-s09-10.pgm +4 -0
  143. package/.dedao-extract/scratch/pp-fk-r3-s09-11.pgm +4 -0
  144. package/.dedao-extract/scratch/pp-fk-r3-s09-12.pgm +18 -0
  145. package/.dedao-extract/scratch/pp-l003-r3-base-1.pgm +7 -0
  146. package/.dedao-extract/scratch/pp-l003-r3-base-2.pgm +114 -0
  147. package/.dedao-extract/scratch/pp-l003-r3-base-3.pgm +4 -0
  148. package/.dedao-extract/scratch/pp-l003-r3-base-4.pgm +30 -0
  149. package/.dedao-extract/scratch/pp-l003-r3-base-5.pgm +4 -0
  150. package/.dedao-extract/scratch/pp-l003-r3-base-6.pgm +64 -0
  151. package/.dedao-extract/scratch/pp-l003-r3-fix-1.pgm +7 -0
  152. package/.dedao-extract/scratch/pp-l003-r3-fix-2.pgm +114 -0
  153. package/.dedao-extract/scratch/pp-l003-r3-fix-3.pgm +4 -0
  154. package/.dedao-extract/scratch/pp-l003-r3-fix-4.pgm +31 -0
  155. package/.dedao-extract/scratch/pp-l003-r3-fix-5.pgm +4 -0
  156. package/.dedao-extract/scratch/promo-fk-datauri.txt +1 -0
  157. package/.dedao-extract/scratch/promo-fk.jpg +0 -0
  158. package/.dedao-extract/scratch/promo-l001.jpg +0 -0
  159. package/.dedao-extract/scratch/promo-l002.jpg +0 -0
  160. package/.dedao-extract/scratch/s8-ink-report.json +447 -0
  161. package/.dedao-extract/scratch/v2-fk-clean-inner.txt +42 -0
  162. package/.dedao-extract/scratch/v2-fk-it1.pdf +0 -0
  163. package/.dedao-extract/scratch/v2-fk-it2.pdf +0 -0
  164. package/.dedao-extract/scratch/v2-fk-it3.pdf +0 -0
  165. package/.dedao-extract/scratch/v2-l001-clean-inner.txt +99 -0
  166. package/.dedao-extract/scratch/v2-l001-it1.pdf +0 -0
  167. package/.dedao-extract/scratch/v2-l001-it2.pdf +0 -0
  168. package/.dedao-extract/scratch/v2-l002-clean-inner.txt +53 -0
  169. package/.dedao-extract/scratch/v2-l002-it1.pdf +0 -0
  170. package/.dedao-extract/scratch/v2-l002-it2.pdf +0 -0
  171. package/.dedao-extract/scratch/v3-fk-clean-inner.txt +42 -0
  172. package/.dedao-extract/scratch/v3-fk-it1.pdf +0 -0
  173. package/.dedao-extract/scratch/v3-fk-it2.pdf +0 -0
  174. package/.dedao-extract/scratch/v3-fk-it3.pdf +0 -0
  175. package/.dedao-extract/scratch/v3-l001-clean-inner.txt +93 -0
  176. package/.dedao-extract/scratch/v3-l001-it1.pdf +0 -0
  177. package/.dedao-extract/scratch/v3-l001-it2.pdf +0 -0
  178. package/.dedao-extract/scratch/v3-l002-clean-inner.txt +49 -0
  179. package/.dedao-extract/scratch/v3-l002-it1.pdf +0 -0
  180. package/.dedao-extract/scratch/v3-l002-it2.pdf +0 -0
  181. package/.dedao-extract/v2-01-navigate.json +14 -0
  182. package/.dedao-extract/v2-98-results.json +128 -0
  183. package/.dedao-extract/v2-99-log.json +20 -0
  184. package/.dedao-extract/v2-fk-figs-it1.json +76 -0
  185. package/.dedao-extract/v2-fk-figs-it2.json +76 -0
  186. package/.dedao-extract/v2-fk-fix-screen.json +20 -0
  187. package/.dedao-extract/v2-fk-meta.json +145 -0
  188. package/.dedao-extract/v2-fk-promo-audit.json +12 -0
  189. package/.dedao-extract/v2-fk-targets-it1.json +94 -0
  190. package/.dedao-extract/v2-fk-targets-it2.json +94 -0
  191. package/.dedao-extract/v2-l001-figs-it1.json +62 -0
  192. package/.dedao-extract/v2-l001-fix-screen.json +20 -0
  193. package/.dedao-extract/v2-l001-meta.json +147 -0
  194. package/.dedao-extract/v2-l001-promo-audit.json +12 -0
  195. package/.dedao-extract/v2-l001-targets-it1.json +84 -0
  196. package/.dedao-extract/v2-l002-figs-it1.json +34 -0
  197. package/.dedao-extract/v2-l002-fix-screen.json +13 -0
  198. package/.dedao-extract/v2-l002-meta.json +126 -0
  199. package/.dedao-extract/v2-l002-promo-audit.json +12 -0
  200. package/.dedao-extract/v2-l002-targets-it1.json +46 -0
  201. package/.dedao-extract/v2-qc-final.json +60 -0
  202. package/.dedao-extract/v3-01-navigate.json +14 -0
  203. package/.dedao-extract/v3-98-results.json +530 -0
  204. package/.dedao-extract/v3-99-log.json +60 -0
  205. package/.dedao-extract/v3-fk-figs-it1.json +66 -0
  206. package/.dedao-extract/v3-fk-figs-it2.json +66 -0
  207. package/.dedao-extract/v3-fk-fix-screen.json +20 -0
  208. package/.dedao-extract/v3-fk-meta.json +164 -0
  209. package/.dedao-extract/v3-fk-promo-audit.json +12 -0
  210. package/.dedao-extract/v3-fk-sikao.json +6 -0
  211. package/.dedao-extract/v3-fk-targets-it1.json +84 -0
  212. package/.dedao-extract/v3-fk-targets-it2.json +84 -0
  213. package/.dedao-extract/v3-l001-figs-it1.json +54 -0
  214. package/.dedao-extract/v3-l001-fix-screen.json +19 -0
  215. package/.dedao-extract/v3-l001-meta.json +192 -0
  216. package/.dedao-extract/v3-l001-promo-audit.json +12 -0
  217. package/.dedao-extract/v3-l001-sikao.json +41 -0
  218. package/.dedao-extract/v3-l001-targets-it1.json +76 -0
  219. package/.dedao-extract/v3-l002-figs-it1.json +30 -0
  220. package/.dedao-extract/v3-l002-fix-screen.json +12 -0
  221. package/.dedao-extract/v3-l002-meta.json +172 -0
  222. package/.dedao-extract/v3-l002-promo-audit.json +12 -0
  223. package/.dedao-extract/v3-l002-sikao.json +32 -0
  224. package/.dedao-extract/v3-l002-targets-it1.json +42 -0
  225. package/.dedao-extract/v3-qc-final.json +77 -0
  226. package/.dedao-extract/write-version-record.py +43 -0
  227. package/ARCHITECTURE.md +11 -0
  228. package/README.de.md +1 -1
  229. package/README.en.md +10 -2
  230. package/README.es.md +1 -1
  231. package/README.fr.md +1 -1
  232. package/README.ja.md +1 -1
  233. package/README.md +9 -3
  234. package/README.pt.md +1 -1
  235. package/README.ru.md +1 -1
  236. package/dist/browse/StepEngine.d.ts +1 -1
  237. package/dist/browse/StepEngine.d.ts.map +1 -1
  238. package/dist/browse/StepEngine.js +28 -4
  239. package/dist/browse/StepEngine.js.map +1 -1
  240. package/dist/browse/steps-types.d.ts +2 -2
  241. package/dist/browse/steps-types.d.ts.map +1 -1
  242. package/dist/channels/BrowseChannel.d.ts +3 -1
  243. package/dist/channels/BrowseChannel.d.ts.map +1 -1
  244. package/dist/channels/BrowseChannel.js +32 -9
  245. package/dist/channels/BrowseChannel.js.map +1 -1
  246. package/dist/desktop/AppleScriptProvider.d.ts +1 -1
  247. package/dist/desktop/AppleScriptProvider.d.ts.map +1 -1
  248. package/dist/desktop/AppleScriptProvider.js +6 -2
  249. package/dist/desktop/AppleScriptProvider.js.map +1 -1
  250. package/dist/desktop/AxProvider.d.ts +6 -3
  251. package/dist/desktop/AxProvider.d.ts.map +1 -1
  252. package/dist/desktop/AxProvider.js +6 -2
  253. package/dist/desktop/AxProvider.js.map +1 -1
  254. package/dist/desktop/ScreenshotVlmProvider.d.ts.map +1 -1
  255. package/dist/desktop/ScreenshotVlmProvider.js +4 -3
  256. package/dist/desktop/ScreenshotVlmProvider.js.map +1 -1
  257. package/dist/doctor/doctor.d.ts +1 -1
  258. package/dist/doctor/doctor.js +1 -1
  259. package/dist/fallback/BudgetTracker.d.ts +8 -0
  260. package/dist/fallback/BudgetTracker.d.ts.map +1 -1
  261. package/dist/fallback/BudgetTracker.js +13 -0
  262. package/dist/fallback/BudgetTracker.js.map +1 -1
  263. package/dist/fallback/FallbackDecider.d.ts.map +1 -1
  264. package/dist/fallback/FallbackDecider.js +5 -2
  265. package/dist/fallback/FallbackDecider.js.map +1 -1
  266. package/dist/fallback/LongCircuitBreaker.d.ts +40 -10
  267. package/dist/fallback/LongCircuitBreaker.d.ts.map +1 -1
  268. package/dist/fallback/LongCircuitBreaker.js +41 -5
  269. package/dist/fallback/LongCircuitBreaker.js.map +1 -1
  270. package/dist/fallback/outcome.d.ts +1 -0
  271. package/dist/fallback/outcome.d.ts.map +1 -1
  272. package/dist/fallback/outcome.js +48 -4
  273. package/dist/fallback/outcome.js.map +1 -1
  274. package/dist/index.js +33 -3
  275. package/dist/index.js.map +1 -1
  276. package/dist/launcher/chrome-hide.d.ts +50 -0
  277. package/dist/launcher/chrome-hide.d.ts.map +1 -1
  278. package/dist/launcher/chrome-hide.js +129 -12
  279. package/dist/launcher/chrome-hide.js.map +1 -1
  280. package/dist/launcher/chrome-hideshow-cli.d.ts +19 -0
  281. package/dist/launcher/chrome-hideshow-cli.d.ts.map +1 -1
  282. package/dist/launcher/chrome-hideshow-cli.js +114 -21
  283. package/dist/launcher/chrome-hideshow-cli.js.map +1 -1
  284. package/dist/launcher/chrome-idle-reaper.d.ts +8 -6
  285. package/dist/launcher/chrome-idle-reaper.d.ts.map +1 -1
  286. package/dist/launcher/chrome-idle-reaper.js +10 -4
  287. package/dist/launcher/chrome-idle-reaper.js.map +1 -1
  288. package/dist/launcher/desired-hide-state.d.ts +26 -0
  289. package/dist/launcher/desired-hide-state.d.ts.map +1 -0
  290. package/dist/launcher/desired-hide-state.js +110 -0
  291. package/dist/launcher/desired-hide-state.js.map +1 -0
  292. package/dist/launcher/desired-hide-watchdog.d.ts +41 -0
  293. package/dist/launcher/desired-hide-watchdog.d.ts.map +1 -0
  294. package/dist/launcher/desired-hide-watchdog.js +124 -0
  295. package/dist/launcher/desired-hide-watchdog.js.map +1 -0
  296. package/dist/launcher/launch-chrome.d.ts +4 -5
  297. package/dist/launcher/launch-chrome.d.ts.map +1 -1
  298. package/dist/launcher/launch-chrome.js +16 -9
  299. package/dist/launcher/launch-chrome.js.map +1 -1
  300. package/dist/runtime/CallerTierTracker.d.ts +11 -6
  301. package/dist/runtime/CallerTierTracker.d.ts.map +1 -1
  302. package/dist/runtime/CallerTierTracker.js +11 -6
  303. package/dist/runtime/CallerTierTracker.js.map +1 -1
  304. package/dist/ssrf/ssrf-guard.d.ts +23 -0
  305. package/dist/ssrf/ssrf-guard.d.ts.map +1 -1
  306. package/dist/ssrf/ssrf-guard.js +37 -0
  307. package/dist/ssrf/ssrf-guard.js.map +1 -1
  308. package/dist/tools/admin.d.ts.map +1 -1
  309. package/dist/tools/admin.js +24 -3
  310. package/dist/tools/admin.js.map +1 -1
  311. package/dist/tools/browse.d.ts.map +1 -1
  312. package/dist/tools/browse.js +10 -4
  313. package/dist/tools/browse.js.map +1 -1
  314. package/dist/tools/browserbase.d.ts.map +1 -1
  315. package/dist/tools/browserbase.js +7 -4
  316. package/dist/tools/browserbase.js.map +1 -1
  317. package/dist/tools/fetch-feed.d.ts.map +1 -1
  318. package/dist/tools/fetch-feed.js +7 -4
  319. package/dist/tools/fetch-feed.js.map +1 -1
  320. package/dist/tools/fetch-url.d.ts.map +1 -1
  321. package/dist/tools/fetch-url.js +27 -13
  322. package/dist/tools/fetch-url.js.map +1 -1
  323. package/dist/tools/network.d.ts.map +1 -1
  324. package/dist/tools/network.js +17 -8
  325. package/dist/tools/network.js.map +1 -1
  326. package/dist/tools/pdf.d.ts.map +1 -1
  327. package/dist/tools/pdf.js +18 -9
  328. package/dist/tools/pdf.js.map +1 -1
  329. package/dist/tools/screenshot.d.ts.map +1 -1
  330. package/dist/tools/screenshot.js +7 -4
  331. package/dist/tools/screenshot.js.map +1 -1
  332. package/dist/tools/steel.d.ts.map +1 -1
  333. package/dist/tools/steel.js +7 -4
  334. package/dist/tools/steel.js.map +1 -1
  335. package/dist/tools/wayback.d.ts.map +1 -1
  336. package/dist/tools/wayback.js +7 -4
  337. package/dist/tools/wayback.js.map +1 -1
  338. package/dist/types.d.ts +7 -0
  339. package/dist/types.d.ts.map +1 -1
  340. package/dist/util/output-envelope.d.ts +4 -1
  341. package/dist/util/output-envelope.d.ts.map +1 -1
  342. package/dist/util/output-envelope.js +51 -9
  343. package/dist/util/output-envelope.js.map +1 -1
  344. package/doc/29-/351/224/231/351/205/215/346/234/272/345/210/266/345/256/241/350/256/241/enumerate.md +139 -0
  345. package/doc/29-/351/224/231/351/205/215/346/234/272/345/210/266/345/256/241/350/256/241/fixes.md +132 -0
  346. package/doc/29-/351/224/231/351/205/215/346/234/272/345/210/266/345/256/241/350/256/241/verdict.md +104 -0
  347. package/doc/KEY-GUIDE.md +4 -1
  348. package/package.json +1 -1
  349. package/src/browse/StepEngine.ts +32 -5
  350. package/src/browse/steps-types.ts +2 -2
  351. package/src/channels/BrowseChannel.ts +40 -9
  352. package/src/desktop/AppleScriptProvider.ts +7 -3
  353. package/src/desktop/AxProvider.ts +12 -5
  354. package/src/desktop/ScreenshotVlmProvider.ts +3 -2
  355. package/src/doctor/doctor.ts +1 -1
  356. package/src/fallback/BudgetTracker.ts +15 -0
  357. package/src/fallback/FallbackDecider.ts +5 -2
  358. package/src/fallback/LongCircuitBreaker.ts +48 -9
  359. package/src/fallback/outcome.ts +49 -4
  360. package/src/index.ts +33 -2
  361. package/src/launcher/chrome-hide.ts +190 -12
  362. package/src/launcher/chrome-hideshow-cli.ts +123 -21
  363. package/src/launcher/chrome-idle-reaper.ts +16 -6
  364. package/src/launcher/desired-hide-state.ts +126 -0
  365. package/src/launcher/desired-hide-watchdog.ts +147 -0
  366. package/src/launcher/launch-chrome.ts +19 -11
  367. package/src/runtime/CallerTierTracker.ts +11 -6
  368. package/src/ssrf/ssrf-guard.ts +43 -0
  369. package/src/tools/admin.ts +26 -3
  370. package/src/tools/browse.ts +10 -4
  371. package/src/tools/browserbase.ts +7 -4
  372. package/src/tools/fetch-feed.ts +8 -5
  373. package/src/tools/fetch-url.ts +30 -15
  374. package/src/tools/network.ts +18 -9
  375. package/src/tools/pdf.ts +19 -10
  376. package/src/tools/screenshot.ts +8 -5
  377. package/src/tools/steel.ts +7 -4
  378. package/src/tools/wayback.ts +8 -5
  379. package/src/types.ts +7 -0
  380. package/src/util/output-envelope.ts +54 -8
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,169 @@
1
+ #!/usr/bin/env node
2
+ // analyze.mjs — v2 管线共享分析器(零光栅快测 + 墨迹终检 + 文字零丢失)
3
+ // 白盒依据:P14-探察-二轮 §3(S-A' 闭环:pdfimages 0.1s + pdftotext -bbox 0.07s/页;
4
+ // pdftoppm 对含课程表 PDF 约 2min/份,只作出厂终检,禁入主管线)
5
+ import { execFileSync } from "node:child_process";
6
+ import * as fs from "node:fs";
7
+ import * as path from "node:path";
8
+ import * as os from "node:os";
9
+
10
+ // 打印参数(extract-batch3 同款):A4、四边 0.4in → pt 域
11
+ export const PT_PER_IN = 72;
12
+ export const PAGE_W_IN = 8.268, PAGE_H_IN = 11.693, MARGIN_IN = 0.4;
13
+ export const CONTENT_TOP = MARGIN_IN * 72; // 28.8pt
14
+ export const PAGE_H_PT = PAGE_H_IN * 72; // 841.92
15
+ export const CONTENT_BOTTOM = PAGE_H_PT - MARGIN_IN * 72; // 813.12
16
+ export const CONTENT_H_PT = CONTENT_BOTTOM - CONTENT_TOP; // 784.32
17
+ export const PAGE_CSS = Math.round((PAGE_H_IN - 2 * MARGIN_IN) * 96); // 1046 css px/页
18
+ export const PROMO_NAT = { w: 1080, h: 607 }; // P14 §1.1 尾部宣传图自然尺寸指纹
19
+
20
+ function tmp(pdf) {
21
+ return path.join(os.tmpdir(), `dz-ana-${process.pid}-${path.basename(pdf)}`);
22
+ }
23
+
24
+ // ---- pdfimages -list 解析 ----
25
+ export function pdfImages(pdf) {
26
+ const out = execFileSync("pdfimages", ["-list", pdf], { maxBuffer: 64 << 20 }).toString();
27
+ const rows = [];
28
+ for (const line of out.split("\n").slice(2)) {
29
+ const t = line.trim().split(/\s+/);
30
+ if (t.length < 14 || !/^\d+$/.test(t[0])) continue;
31
+ rows.push({
32
+ page: +t[0], num: +t[1], type: t[2], w: +t[3], h: +t[4],
33
+ enc: t[8], xppi: +t[t.length - 4], yppi: +t[t.length - 3],
34
+ });
35
+ }
36
+ return rows.filter((r) => r.type === "image"); // smask=同对象 alpha 通道,不计
37
+ }
38
+
39
+ // ---- pdftotext -bbox 解析(词级坐标) ----
40
+ export function bboxWords(pdf) {
41
+ const out = execFileSync("pdftotext", ["-bbox", pdf, "-"], { maxBuffer: 128 << 20 }).toString();
42
+ const pages = [];
43
+ let page = null;
44
+ const re = /<page width="([\d.]+)" height="([\d.]+)">|<word xMin="([\d.-]+)" yMin="([\d.-]+)" xMax="([\d.-]+)" yMax="([\d.-]+)">([\s\S]*?)<\/word>/g;
45
+ let m;
46
+ while ((m = re.exec(out))) {
47
+ if (m[1]) { page = { w: +m[1], h: +m[2], words: [] }; pages.push(page); }
48
+ else if (page) {
49
+ page.words.push({ x0: +m[3], y0: +m[4], x1: +m[5], y1: +m[6], text: m[7] });
50
+ }
51
+ }
52
+ return pages;
53
+ }
54
+
55
+ // ---- 快测洞报告(S-A' 闭环核心) ----
56
+ // 判定:非末页 ∧ 文本尾空 >12% ∧ 版面充满度 <0.88(文本跨距 + 图显示高 + 图间隙)
57
+ // 课程表切片页(全页图)被充满度豁免;图片收尾页被充满度豁免(bbox 只见文字的假洞)
58
+ // P23 修复:页脚页码(displayHeaderFooter,y≈821-827 > CONTENT_BOTTOM=813.12)必须排除——
59
+ // 路线b 合并 PDF 带页码页脚,计入会把 textBottom 钉死在页脚 → tailPct 恒 0 → 洞检测全盲。
60
+ // 单章管线(engine)无页脚,此过滤为无操作,行为不变。
61
+ export function holeReport(pdf, { tailPct = 12, fullFloor = 0.88, gapPt = 24 } = {}) {
62
+ const imgs = pdfImages(pdf);
63
+ const pages = bboxWords(pdf);
64
+ const n = pages.length;
65
+ const per = pages.map((pg, i) => {
66
+ const contentWords = pg.words.filter((w) => w.y1 <= CONTENT_BOTTOM + 0.75); // 页脚词排除
67
+ const ys = contentWords.map((w) => w.y1);
68
+ const textBottom = ys.length ? Math.max(...ys) : null;
69
+ const textTop = contentWords.length ? Math.min(...contentWords.map((w) => w.y0)) : null;
70
+ const imgsOnPage = imgs.filter((r) => r.page === i + 1);
71
+ const imgPt = Math.min(
72
+ CONTENT_H_PT,
73
+ imgsOnPage.reduce((s, r) => s + (r.yppi > 0 ? (r.h / r.yppi) * PT_PER_IN : 0), 0),
74
+ );
75
+ const textSpan = textBottom !== null ? textBottom - CONTENT_TOP : 0;
76
+ const used = Math.max(textSpan, 0) + imgPt + imgsOnPage.length * gapPt;
77
+ const fullness = +(used / CONTENT_H_PT).toFixed(3);
78
+ const tailPt = textBottom !== null ? CONTENT_BOTTOM - textBottom : CONTENT_H_PT;
79
+ const tailPctV = +(Math.max(0, tailPt) / CONTENT_H_PT * 100).toFixed(1);
80
+ const isLast = i === n - 1;
81
+ const hole = !isLast && tailPctV > tailPct && fullness < fullFloor;
82
+ const freePt = +Math.max(0, CONTENT_H_PT - used).toFixed(1); // 版面自由空间(保守:文本跨距+图高+图间隙的加性模型)
83
+ const freePct = +(freePt / CONTENT_H_PT * 100).toFixed(1);
84
+ return { page: i + 1, textBottom, textTop, imgCount: imgsOnPage.length, imgPt: Math.round(imgPt), fullness, tailPt: +tailPt.toFixed(1), tailPct: tailPctV, freePt, freePct, isLast, hole };
85
+ });
86
+ return { pdf, pages: n, holes: per.filter((p) => p.hole), per };
87
+ }
88
+
89
+ // ---- 宣传图断言:PDF 内不得存在 1080×607 图 ----
90
+ export function promoInPdf(pdf) {
91
+ return pdfImages(pdf).filter((r) => r.w === PROMO_NAT.w && r.h === PROMO_NAT.h);
92
+ }
93
+
94
+ // ---- 文字零丢失(P14 §3 定案:cleanup 态 innerText vs pdftotext,missing 必须为空) ----
95
+ export function textZeroLoss(pdf, innerTxt) {
96
+ const pdftxt = execFileSync("pdftotext", [pdf, "-"], { maxBuffer: 128 << 20 }).toString();
97
+ const norm = (s) => s.normalize("NFC").replace(/[\s­​‌‍]/g, "");
98
+ const a = norm(pdftxt), b = norm(innerTxt); // a=PDF 侧,b=DOM 侧
99
+ // 多重集 diff(字符级,CJK 字≈词;PDF 侧多出字符=良性:CSS 列表序号等)
100
+ const cnt = new Map();
101
+ for (const ch of a) cnt.set(ch, (cnt.get(ch) || 0) + 1);
102
+ const missCnt = new Map();
103
+ for (const ch of b) {
104
+ const left = cnt.get(ch) || 0;
105
+ if (left > 0) cnt.set(ch, left - 1);
106
+ else missCnt.set(ch, (missCnt.get(ch) || 0) + 1);
107
+ }
108
+ const missing = [...missCnt.entries()].map(([ch, c]) => `${ch}x${c}`);
109
+ // 保序检查:b 必须是 a 的子序列
110
+ let j = 0;
111
+ for (let i = 0; i < a.length && j < b.length; i++) if (a[i] === b[j]) j++;
112
+ return { missing, missingEmpty: missing.length === 0, inOrder: j === b.length, pdfChars: a.length, domChars: b.length };
113
+ }
114
+
115
+ // ---- 墨迹终检(慢:pdftoppm PGM,仅出厂抽检/3 章对比证据) ----
116
+ export function inkReport(pdf, { first = 1, last = null, tailInkTh = 242, dpi = 36 } = {}) {
117
+ const dir = tmp(pdf);
118
+ fs.rmSync(dir, { recursive: true, force: true });
119
+ fs.mkdirSync(dir, { recursive: true });
120
+ const npages = last ?? bboxWords(pdf).length;
121
+ const args = ["-f", String(first), "-l", String(last ?? npages), "-r", String(dpi), "-gray", pdf, path.join(dir, "p")];
122
+ execFileSync("pdftoppm", args, { maxBuffer: 64 << 20, timeout: 1_500_000 }); // P27 终局:全419讲 307MB/1360页实测 >9.5min(内存压力),抬到 25min
123
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith(".pgm")).sort();
124
+ const out = [];
125
+ for (const f of files) {
126
+ const buf = fs.readFileSync(path.join(dir, f));
127
+ let p = 0;
128
+ const tok = () => {
129
+ while (p < buf.length && (buf[p] === 0x20 || buf[p] === 0x0a || buf[p] === 0x0d || buf[p] === 0x09)) p++;
130
+ if (buf[p] === 0x23) { while (p < buf.length && buf[p] !== 0x0a) p++; return tok(); }
131
+ const s = p;
132
+ while (p < buf.length && !(buf[p] === 0x20 || buf[p] === 0x0a || buf[p] === 0x0d || buf[p] === 0x09)) p++;
133
+ return buf.toString("latin1", s, p);
134
+ };
135
+ if (tok() !== "P5") continue;
136
+ const w = +tok(), h = +tok(); tok(); p++;
137
+ const data = buf.subarray(p, p + w * h);
138
+ let lastInk = -1, firstInk = -1;
139
+ for (let y = 0; y < h && firstInk < 0; y++)
140
+ for (let x = 0; x < w; x++) if (data[y * w + x] < tailInkTh) { firstInk = y; break; }
141
+ for (let y = h - 1; y >= 0; y--) {
142
+ let ink = false;
143
+ for (let x = 0; x < w; x++) if (data[y * w + x] < tailInkTh) { ink = true; break; }
144
+ if (ink) { lastInk = y; break; }
145
+ }
146
+ out.push({ page: +f.match(/(\d+)\.pgm$/)[1], tailBlankPct: +(((h - 1 - lastInk) / h) * 100).toFixed(1), headBlankPct: firstInk < 0 ? 100 : +((firstInk / h) * 100).toFixed(1) });
147
+ }
148
+ fs.rmSync(dir, { recursive: true, force: true });
149
+ return out;
150
+ }
151
+
152
+ // ---- Chrome 可见性守卫(P16:PID 定向,禁进程名全量) ----
153
+ export function chromeGuard() {
154
+ try {
155
+ const pid = execFileSync("zsh", ["-c", "lsof -nP -iTCP:9226 -sTCP:LISTEN | awk 'NR>1{print $2}' | sort -u | head -1"])
156
+ .toString().trim();
157
+ if (!pid || !/^\d+$/.test(pid)) return { ok: false, err: "no-pid" };
158
+ const vis = execFileSync("osascript", ["-e",
159
+ `tell application "System Events" to get visible of (first process whose unix id is ${pid})`]).toString().trim();
160
+ if (vis === "true") {
161
+ execFileSync("osascript", ["-e",
162
+ `tell application "System Events" to set visible of (first process whose unix id is ${pid}) to false`]);
163
+ return { ok: true, pid, was: "visible", action: "rehidden" };
164
+ }
165
+ return { ok: true, pid, was: "hidden", action: "none" };
166
+ } catch (e) {
167
+ return { ok: false, err: String(e).slice(0, 120) };
168
+ }
169
+ }
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ // dbg-fixscreen.mjs — 捕获 JS_FIX_SCREEN 的原始 evaluate 返回(定位 dropped=undefined 根因)
3
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5
+ import * as path from "node:path";
6
+ import * as fs from "node:fs";
7
+
8
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
9
+ const OUT = path.join(ROOT, ".dedao-extract");
10
+ const TARGET = "https://www.dedao.cn/course/article?id=6EBOqDNZ27YlVdg8oKm4bQ1odMAkgz";
11
+
12
+ // 从 extract-v2.mjs 源码原样抽取 JS_FIX_SCREEN(保证测的就是产线代码)
13
+ const src = fs.readFileSync(path.join(OUT, "extract-v2.mjs"), "utf8");
14
+ const m = src.match(/const JS_FIX_SCREEN = `([\s\S]*?)`;/);
15
+ if (!m) { console.error("extract failed"); process.exit(1); }
16
+ const PAGE_CSS = 1046;
17
+ const JS_FIX_SCREEN = m[1].replace("${PAGE_CSS}", String(PAGE_CSS));
18
+
19
+ const client = new Client({ name: "dedao-dbg-fs", version: "1.0.0" });
20
+ const transport = new StdioClientTransport({
21
+ command: "/bin/zsh",
22
+ args: ["-c", `exec node dist/index.js 2>>${JSON.stringify(path.join(OUT, "server-dbg-stderr.log"))}`],
23
+ cwd: ROOT, env: { ...process.env, LASSO_CDP_PORT: "9226" },
24
+ });
25
+ await client.connect(transport);
26
+ async function browse(action, options = {}, timeoutMs = 180000) {
27
+ const res = await client.callTool({ name: "browse_logged_in", arguments: { url: TARGET, action, options } }, undefined, { timeout: timeoutMs });
28
+ return JSON.parse(res.content[0].text);
29
+ }
30
+
31
+ // navigate 先行(P6:新 server 会话需先绑定 page)
32
+ const nav = await browse("navigate", {});
33
+ console.log("[nav]", JSON.stringify(nav).slice(0, 120));
34
+ await new Promise((r) => setTimeout(r, 2500));
35
+ const t = await browse("evaluate", { js: `return JSON.stringify({title:(document.querySelector('div.article-body-wrap .article-title')||{textContent:''}).textContent.trim().slice(0,30),figs:document.querySelectorAll('div.article-body-wrap figure').length});` });
36
+ console.log("[state]", t.data?.preview ?? JSON.stringify(t).slice(0, 200));
37
+
38
+ const r = await browse("evaluate", { js: JS_FIX_SCREEN }, undefined, { timeout: 120000 });
39
+ console.log("[outcome]", r.outcome, "| [error]", r.error ?? null);
40
+ console.log("[preview]", (r.data?.preview ?? "").slice(0, 1500));
41
+ await transport.close();
42
+ await new Promise((r) => setTimeout(r, 300));
43
+ process.exit(0);
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ // debug text fetch — 看 evaluate 原始返回
3
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
6
+ const client = new Client({ name: "dbg", version: "1" });
7
+ const transport = new StdioClientTransport({
8
+ command: "/bin/zsh",
9
+ args: ["-c", `exec node dist/index.js 2>>/tmp/dbg-stderr.log`],
10
+ cwd: ROOT,
11
+ env: { ...process.env, LASSO_CDP_PORT: "9226" },
12
+ });
13
+ await client.connect(transport);
14
+ const call = (js) =>
15
+ client
16
+ .callTool(
17
+ { name: "browse_logged_in", arguments: { url: "https://www.dedao.cn/course/article?id=1", action: "evaluate", options: { js } } },
18
+ undefined,
19
+ { timeout: 60000 },
20
+ )
21
+ .then((r) => r.content[0].text);
22
+ console.log("A:", await call(`return JSON.stringify((document.body.innerText).slice(0,60));`));
23
+ console.log("B:", await call(`return (document.body.innerText||'').length;`));
24
+ await transport.close();
25
+ setTimeout(() => process.exit(0), 300);
@@ -0,0 +1,20 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
4
+ const client = new Client({ name: "dbg2", version: "1" });
5
+ const transport = new StdioClientTransport({
6
+ command: "/bin/zsh",
7
+ args: ["-c", `exec node dist/index.js 2>>/tmp/dbg2-stderr.log`],
8
+ cwd: ROOT,
9
+ env: { ...process.env, LASSO_CDP_PORT: "9226" },
10
+ });
11
+ await client.connect(transport);
12
+ const call = (action, options) =>
13
+ client.callTool({ name: "browse_logged_in", arguments: { url: "https://www.dedao.cn/course/article?id=6EBOqDNZ27YlVdg8oKm4bQ1odMAkgz", action, options } }, undefined, { timeout: 90000 }).then((r) => r.content[0].text);
14
+ console.log("nav:", (await call("navigate", {})).slice(0, 120));
15
+ await new Promise(r => setTimeout(r, 4000));
16
+ console.log("A body.innerText len:", await call("evaluate", { js: `return (document.body.innerText||'').length + ' | head=' + (document.body.innerText||'').slice(0,30);` }));
17
+ console.log("B wrap innerText len:", await call("evaluate", { js: `return (document.querySelector('div.article-body-wrap').innerText||'').length;` }));
18
+ console.log("C textContent len:", await call("evaluate", { js: `return (document.querySelector('div.article-body-wrap').textContent||'').length;` }));
19
+ await transport.close();
20
+ setTimeout(() => process.exit(0), 300);
@@ -0,0 +1,18 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
4
+ const client = new Client({ name: "dbg3", version: "1" });
5
+ const transport = new StdioClientTransport({
6
+ command: "/bin/zsh",
7
+ args: ["-c", `exec node dist/index.js 2>>/tmp/dbg3-stderr.log`],
8
+ cwd: ROOT,
9
+ env: { ...process.env, LASSO_CDP_PORT: "9226" },
10
+ });
11
+ await client.connect(transport);
12
+ const call = (action, options) =>
13
+ client.callTool({ name: "browse_logged_in", arguments: { url: "https://www.dedao.cn/course/article?id=6EBOqDNZ27YlVdg8oKm4bQ1odMAkgz", action, options } }, undefined, { timeout: 90000 }).then((r) => r.content[0].text);
14
+ console.log("nav FULL:", await call("navigate", {}));
15
+ await new Promise(r => setTimeout(r, 5000));
16
+ console.log("A:", await call("evaluate", { js: `return (document.body.innerText||'').length;` }));
17
+ await transport.close();
18
+ setTimeout(() => process.exit(0), 300);
@@ -0,0 +1,27 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
4
+ const client = new Client({ name: "dbg4", version: "1" });
5
+ const transport = new StdioClientTransport({
6
+ command: "/bin/zsh",
7
+ args: ["-c", `exec node dist/index.js 2>>/tmp/dbg4-stderr.log`],
8
+ cwd: ROOT,
9
+ env: { ...process.env, LASSO_CDP_PORT: "9226" },
10
+ });
11
+ await client.connect(transport);
12
+ const call = (action, options) =>
13
+ client.callTool({ name: "browse_logged_in", arguments: { url: "https://www.dedao.cn/course/article?id=6EBOqDNZ27YlVdg8oKm4bQ1odMAkgz", action, options } }, undefined, { timeout: 90000 }).then((r) => r.content[0].text);
14
+ console.log("nav:", (await call("navigate", {})).slice(0, 80));
15
+ for (let i = 0; i < 10; i++) {
16
+ await new Promise(r => setTimeout(r, 1200));
17
+ const j = JSON.parse(await call("evaluate", { js: `return JSON.stringify({rs:document.readyState,t:!!document.querySelector('.article-title'),len:(document.body.innerText||'').length});` }));
18
+ const p = j?.data?.preview;
19
+ console.log(i, p);
20
+ if (p && p.includes('"t":true')) break;
21
+ }
22
+ // 精确复刻 evText 第一片
23
+ const raw = await call("evaluate", { js: `return JSON.stringify((document.body.innerText).slice(0,1800));` });
24
+ const rj = JSON.parse(raw);
25
+ console.log("outcome:", rj.outcome, "| preview len:", (rj.data?.preview ?? "").length, "| preview head:", JSON.stringify((rj.data?.preview ?? "").slice(0, 80)));
26
+ await transport.close();
27
+ setTimeout(() => process.exit(0), 300);
@@ -0,0 +1,31 @@
1
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
3
+ import * as fs from "node:fs";
4
+ const ROOT = "/Users/wangdong/Documents/Project/cc-control-all/lasso";
5
+ const client = new Client({ name: "dbg5", version: "1" });
6
+ const transport = new StdioClientTransport({
7
+ command: "/bin/zsh",
8
+ args: ["-c", `exec node dist/index.js 2>>/tmp/dbg5-stderr.log`],
9
+ cwd: ROOT,
10
+ env: { ...process.env, LASSO_CDP_PORT: "9226" },
11
+ });
12
+ await client.connect(transport);
13
+ const call = (action, options) =>
14
+ client.callTool({ name: "browse_logged_in", arguments: { url: "https://www.dedao.cn/course/article?id=6EBOqDNZ27YlVdg8oKm4bQ1odMAkgz", action, options } }, undefined, { timeout: 90000 }).then((r) => r.content[0].text);
15
+ console.log("nav ok:", JSON.parse(await call("navigate", {})).outcome);
16
+ await new Promise(r => setTimeout(r, 4000));
17
+ // b3 JS_CLEANUP 原样(从 scout7 文件抽取,保证一字不差)
18
+ const src = fs.readFileSync(".dedao-extract/scout7-round2.mjs", "utf8");
19
+ const m = src.match(/const JS_CLEANUP = `return \(\(\)=>\{[\s\S]*?\}\)\(\)`;/);
20
+ await call("evaluate", { js: m[0].replace("const JS_CLEANUP = ", "").replace(/;$/, "") });
21
+ const raw = await call("evaluate", { js: `return JSON.stringify((document.body.innerText).slice(0,1800));` });
22
+ const rj = JSON.parse(raw);
23
+ const p = rj?.data?.preview ?? "";
24
+ console.log("outcome:", rj.outcome, "| preview len:", p.length);
25
+ console.log("preview head:", JSON.stringify(p.slice(0, 120)));
26
+ console.log("preview tail:", JSON.stringify(p.slice(-120)));
27
+ try { const s = JSON.parse(p); console.log("parse OK, string len:", s.length, "| head:", JSON.stringify(s.slice(0, 40))); } catch (e) { console.log("parse FAIL:", e.message); }
28
+ const raw2 = await call("evaluate", { js: `return JSON.stringify((document.body.innerText||'').length);` });
29
+ console.log("innerText len direct:", JSON.parse(raw2)?.data?.preview);
30
+ await transport.close();
31
+ setTimeout(() => process.exit(0), 300);