lasso-mcp 1.25.0 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +97 -23
- package/README.en.md +4 -3
- package/README.md +4 -3
- package/dist/browse/StepEngine.d.ts +31 -2
- package/dist/browse/StepEngine.d.ts.map +1 -1
- package/dist/browse/StepEngine.js +87 -5
- package/dist/browse/StepEngine.js.map +1 -1
- package/dist/browse/stealth-profiles.d.ts +19 -0
- package/dist/browse/stealth-profiles.d.ts.map +1 -1
- package/dist/browse/stealth-profiles.js +38 -0
- package/dist/browse/stealth-profiles.js.map +1 -1
- package/dist/browse/steps-types.d.ts +43 -0
- package/dist/browse/steps-types.d.ts.map +1 -1
- package/dist/channels/BrowseChannel.d.ts +192 -37
- package/dist/channels/BrowseChannel.d.ts.map +1 -1
- package/dist/channels/BrowseChannel.js +830 -138
- package/dist/channels/BrowseChannel.js.map +1 -1
- package/dist/channels/HeadedChannel.d.ts +131 -0
- package/dist/channels/HeadedChannel.d.ts.map +1 -0
- package/dist/channels/HeadedChannel.js +407 -0
- package/dist/channels/HeadedChannel.js.map +1 -0
- package/dist/channels/HeadlessChannel.d.ts +80 -22
- package/dist/channels/HeadlessChannel.d.ts.map +1 -1
- package/dist/channels/HeadlessChannel.js +210 -9
- package/dist/channels/HeadlessChannel.js.map +1 -1
- package/dist/channels/LoggedInChannel.d.ts +54 -2
- package/dist/channels/LoggedInChannel.d.ts.map +1 -1
- package/dist/channels/LoggedInChannel.js +184 -30
- package/dist/channels/LoggedInChannel.js.map +1 -1
- package/dist/channels/headless-fresh-profile.d.ts +58 -0
- package/dist/channels/headless-fresh-profile.d.ts.map +1 -0
- package/dist/channels/headless-fresh-profile.js +108 -0
- package/dist/channels/headless-fresh-profile.js.map +1 -0
- package/dist/config/config.d.ts +46 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +69 -0
- package/dist/config/config.js.map +1 -1
- package/dist/doctor/doctor.d.ts +9 -3
- package/dist/doctor/doctor.d.ts.map +1 -1
- package/dist/doctor/doctor.js +44 -12
- package/dist/doctor/doctor.js.map +1 -1
- package/dist/fallback/FallbackDecider.d.ts.map +1 -1
- package/dist/fallback/FallbackDecider.js +21 -1
- package/dist/fallback/FallbackDecider.js.map +1 -1
- package/dist/index.js +112 -9
- package/dist/index.js.map +1 -1
- package/dist/runtime/runtime-types.d.ts +1 -1
- package/dist/runtime/runtime-types.d.ts.map +1 -1
- package/dist/subprocess/McpClient.d.ts +33 -2
- package/dist/subprocess/McpClient.d.ts.map +1 -1
- package/dist/subprocess/McpClient.js +47 -3
- package/dist/subprocess/McpClient.js.map +1 -1
- package/dist/subprocess/SubprocessManager.d.ts +71 -1
- package/dist/subprocess/SubprocessManager.d.ts.map +1 -1
- package/dist/subprocess/SubprocessManager.js +184 -21
- package/dist/subprocess/SubprocessManager.js.map +1 -1
- package/dist/subprocess/headless-stack-ledger.d.ts +80 -0
- package/dist/subprocess/headless-stack-ledger.d.ts.map +1 -0
- package/dist/subprocess/headless-stack-ledger.js +281 -0
- package/dist/subprocess/headless-stack-ledger.js.map +1 -0
- package/dist/tools/admin.d.ts +24 -1
- package/dist/tools/admin.d.ts.map +1 -1
- package/dist/tools/admin.js +53 -0
- package/dist/tools/admin.js.map +1 -1
- package/dist/tools/annotations.d.ts +2 -0
- package/dist/tools/annotations.d.ts.map +1 -1
- package/dist/tools/annotations.js +5 -0
- package/dist/tools/annotations.js.map +1 -1
- package/dist/tools/browse.d.ts +211 -11
- package/dist/tools/browse.d.ts.map +1 -1
- package/dist/tools/browse.js +43 -14
- package/dist/tools/browse.js.map +1 -1
- package/dist/tools/descriptions.d.ts +6 -0
- package/dist/tools/descriptions.d.ts.map +1 -1
- package/dist/tools/descriptions.js +165 -13
- package/dist/tools/descriptions.js.map +1 -1
- package/dist/tools/fetch-url.d.ts +12 -0
- package/dist/tools/fetch-url.d.ts.map +1 -1
- package/dist/tools/fetch-url.js +44 -1
- package/dist/tools/fetch-url.js.map +1 -1
- package/dist/tools/headed.d.ts +26 -0
- package/dist/tools/headed.d.ts.map +1 -0
- package/dist/tools/headed.js +85 -0
- package/dist/tools/headed.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -1
- package/doc/README.md +42 -13
- package/doc/architecture/02-/345/256/236/346/226/275/346/216/222/346/234/237.md +11 -1
- package/doc/bugs/08-2026-09-15-/345/225/206/346/240/207/346/237/245/350/257/242/351/251/254/346/213/211/346/235/276-/344/272/224/347/273/204/344/277/256/345/244/215/345/206/263/350/256/256.md +297 -0
- package/doc/bugs/09-2026-09-16-/345/217/215/347/210/254/346/240/271/346/262/273/351/200/232/351/201/223/344/270/216url/350/257/255/344/271/211/347/273/237/344/270/200/345/206/263/350/256/256.md +497 -0
- package/doc/testing/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/270/205/345/215/225.md +10 -1
- package/doc/usage/01-KEY-GUIDE.md +5 -1
- package/doc/usage/02-TROUBLESHOOTING.md +61 -0
- package/doc//346/225/264/347/220/206/345/206/263/350/256/256-2026-09-16.md +136 -0
- package/package.json +1 -1
- package/src/browse/StepEngine.ts +101 -4
- package/src/browse/stealth-profiles.ts +40 -0
- package/src/browse/steps-types.ts +44 -0
- package/src/channels/BrowseChannel.ts +864 -139
- package/src/channels/HeadedChannel.ts +470 -0
- package/src/channels/HeadlessChannel.ts +231 -4
- package/src/channels/LoggedInChannel.ts +181 -32
- package/src/channels/headless-fresh-profile.ts +151 -0
- package/src/config/config.ts +88 -1
- package/src/doctor/doctor.ts +53 -12
- package/src/fallback/FallbackDecider.ts +24 -1
- package/src/index.ts +120 -8
- package/src/invariants/check-invariants.mjs +633 -27
- package/src/runtime/runtime-types.ts +6 -1
- package/src/subprocess/McpClient.ts +53 -5
- package/src/subprocess/SubprocessManager.ts +225 -23
- package/src/subprocess/headless-stack-ledger.ts +328 -0
- package/src/tools/admin.ts +78 -1
- package/src/tools/annotations.ts +6 -0
- package/src/tools/browse.ts +47 -14
- package/src/tools/descriptions.ts +167 -14
- package/src/tools/fetch-url.ts +47 -1
- package/src/tools/headed.ts +139 -0
- package/src/types.ts +45 -0
- package/vitest.workspace.ts +24 -0
- package/doc/archive/parse/parse1.md +0 -1611
- package/doc/archive/parse/parse10-acceptance.md +0 -224
- package/doc/archive/parse/parse10.md +0 -29
- package/doc/archive/parse/parse11-acceptance.md +0 -325
- package/doc/archive/parse/parse11.md +0 -987
- package/doc/archive/parse/parse12-acceptance.md +0 -182
- package/doc/archive/parse/parse12.md +0 -777
- package/doc/archive/parse/parse13-acceptance.md +0 -331
- package/doc/archive/parse/parse13.md +0 -405
- package/doc/archive/parse/parse14-acceptance.md +0 -400
- package/doc/archive/parse/parse14.md +0 -580
- package/doc/archive/parse/parse15-acceptance.md +0 -189
- package/doc/archive/parse/parse15.md +0 -463
- package/doc/archive/parse/parse16.md +0 -310
- package/doc/archive/parse/parse17-rca-lifecycle.md +0 -225
- package/doc/archive/parse/parse17.md +0 -452
- package/doc/archive/parse/parse18-acceptance.md +0 -37
- package/doc/archive/parse/parse18-frontier.md +0 -94
- package/doc/archive/parse/parse18-oss-experiments.md +0 -212
- package/doc/archive/parse/parse18-rca-whitebox.md +0 -163
- package/doc/archive/parse/parse18.md +0 -418
- package/doc/archive/parse/parse2.md +0 -1421
- package/doc/archive/parse/parse3.md +0 -960
- package/doc/archive/parse/parse4-acceptance.md +0 -225
- package/doc/archive/parse/parse4.md +0 -1096
- package/doc/archive/parse/parse5-acceptance.md +0 -170
- package/doc/archive/parse/parse5.md +0 -1490
- package/doc/archive/parse/parse6-acceptance.md +0 -277
- package/doc/archive/parse/parse6.md +0 -1007
- package/doc/archive/parse/parse7-acceptance.md +0 -205
- package/doc/archive/parse/parse7.md +0 -1060
- package/doc/archive/parse/parse8-acceptance.md +0 -168
- package/doc/archive/parse/parse8.md +0 -893
- package/doc/archive/parse/parse9-acceptance.md +0 -334
- package/doc/archive/parse/parse9.md +0 -805
- package/doc/archive/parse/v14-acceptance.md +0 -182
- package/doc/archive/research/00-/346/200/273/350/247/210/344/270/216/350/220/275/345/234/260/346/216/250/350/215/220.md +0 -173
- package/doc/archive/research/01-/346/226/271/345/220/221A-/346/265/217/350/247/210/345/231/250/346/216/247/345/210/266.md +0 -178
- package/doc/archive/research/02-/346/226/271/345/220/221B-/346/241/214/351/235/242/350/256/241/347/256/227/346/234/272/346/216/247/345/210/266.md +0 -167
- package/doc/archive/research/03-/346/226/271/345/220/221C-/346/226/260/345/245/207/346/226/271/346/241/210/344/270/216/346/200/247/350/203/275/346/264/236/345/257/237.md +0 -129
- package/doc/archive/research/04-CC/351/233/206/346/210/220/346/223/215/344/275/234/346/211/213/345/206/214.md +0 -246
- package/doc/archive/research/05-/346/250/252/345/220/221/345/257/271/346/257/224/347/237/251/351/230/265.md +0 -141
- package/doc/archive/research/06-/346/226/271/345/220/221D-AI/346/265/217/350/247/210/345/231/250/344/270/216Agent/346/265/217/350/247/210/345/231/250.md +0 -309
- package/doc/archive/research/07-CC/347/273/237/344/270/200/344/272/244/344/272/222/346/212/223/346/211/213MCP-/345/217/257/350/241/214/346/200/247/345/210/206/346/236/220.md +0 -394
- package/doc/archive/research/10-/346/220/234/347/264/242MCP/350/260/203/347/240/224/345/257/271/346/236/266/346/236/204/347/232/204/345/220/257/345/217/221.md +0 -336
- package/doc/archive/research/11-/347/256/200/345/215/225/346/236/266/346/236/204/345/256/241/346/237/245/346/212/245/345/221/212.md +0 -151
- package/doc/archive/research/12-pi-computer-use/345/217/212/347/224/237/346/200/201/346/267/261/345/272/246/345/210/206/346/236/220.md +0 -461
- package/doc/archive/research/13-/345/205/250/344/272/244/344/272/222/346/212/223/346/211/213/351/207/215/350/256/276/350/256/241.md +0 -819
- package/doc/archive/research/14-AI/347/210/254/350/231/253/350/260/203/347/240/224/344/270/216/345/200/237/351/211/264/345/210/206/346/236/220.md +0 -355
- package/doc/archive/research/15-/347/231/273/345/275/225/346/200/201/346/214/201/344/271/205/345/214/226/344/270/216/346/227/240/345/244/264/345/244/215/347/224/250/350/260/203/347/240/224.md +0 -272
- package/doc/archive/research/16-/345/274/200/346/272/220/347/224/237/346/200/201/347/231/275/347/233/222/345/256/241/346/237/245/344/270/216/345/200/237/351/211/264/345/210/206/346/236/220.md +0 -558
- package/doc/archive/research/18-/350/265/204/346/272/220/345/215/240/347/224/250/344/274/230/345/214/226/350/260/203/347/240/224.md +0 -167
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/01-/346/200/273/350/247/210/344/270/216/346/216/250/350/215/220/346/216/222/345/220/215.md +0 -120
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/02-/345/200/231/351/200/211/346/226/271/346/241/210/350/257/246/350/247/243.md +0 -222
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/03-/351/205/215/347/275/256/347/244/272/344/276/213/344/270/216/351/203/250/347/275/262/346/214/207/345/215/227.md +0 -272
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/04-/346/200/247/350/203/275/345/237/272/345/207/206/344/270/216/345/205/215/350/264/271/351/242/235/345/272/246/345/257/271/346/257/224.md +0 -79
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/05-/351/201/277/345/235/221-/350/242/253/345/220/246/345/206/263/347/232/204/350/257/257/345/257/274/347/273/223/350/256/272.md +0 -76
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/06-/345/261/200/351/231/220/344/270/216/345/274/200/346/224/276/351/227/256/351/242/230.md +0 -105
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/07-/350/260/203/347/240/224/346/226/271/346/263/225/344/270/216/345/256/214/346/225/264/346/235/245/346/272/220/346/270/205/345/215/225.md +0 -185
- package/doc/archive/research//346/220/234/347/264/242mcp/345/267/245/345/205/267/README.md +0 -66
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/probe.mjs +0 -128
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/s7fix-l3-result.json +0 -54
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/s7fix-l3.mjs +0 -224
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t1-network.mjs +0 -89
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t1-result.json +0 -259
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t2-asn-poll.jsonl +0 -25
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t2-headless.mjs +0 -149
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t2-result.json +0 -144
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t2b-asn-type.mjs +0 -37
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t2b-lsappinfo-during.txt +0 -567
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t3-hidden.mjs +0 -74
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t3-result.json +0 -67
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4a-hidden-loggedin.mjs +0 -75
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4a-result.json +0 -195
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4b-focus.mjs +0 -167
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4b-result.json +0 -382
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4c-gaps.mjs +0 -134
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4c-result.json +0 -282
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4c-snapshot-ddg.txt +0 -399
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4c-snapshot-example.txt +0 -6
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4d-final.mjs +0 -118
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4d-result.json +0 -202
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4d-snapshot.txt +0 -4
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e-clickfill.mjs +0 -89
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e-result.json +0 -105
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e-snapshot-ddg-full.txt +0 -357
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e-snapshot-example-full.txt +0 -6
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e2-fill.mjs +0 -66
- package/doc/governance/08-/351/235/231/351/273/230/346/200/247/345/205/250/351/235/242/345/256/241/350/256/241/verify-data/t4e2-result.json +0 -30
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/admin-tool_list.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/admin1.jsonl +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/admin2.jsonl +0 -5
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/caps.jsonl +0 -10
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/doctor-cli.json +0 -184
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/doctor-mcp.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/fetch1.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/forest.jsonl +0 -6
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/forest2.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-00-/346/200/273/347/273/223.md +0 -134
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-admin-flow.json +0 -174
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-admin-flow.mjs +0 -169
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-badcmd.err +0 -25
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-badcmd.out +0 -0
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-h.out +0 -23
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-help.err +0 -0
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-help.out +0 -23
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-v.out +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-version.err +0 -0
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-version.exit +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-cli-version.out +0 -2
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-doctor-cli.json +0 -186
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-doctor-mcp.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-doctor-stealth.json +0 -187
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-doctor-stealth2.json +0 -187
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-forest-flow.json +0 -51
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-forest-flow.mjs +0 -107
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-http-fixture.mjs +0 -39
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-meter.mjs +0 -89
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-a1.json +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-a2.json +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-browse-out.json +0 -1762
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-browse.mjs +0 -166
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-cost-out.json +0 -245
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-cost.mjs +0 -56
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-e1.json +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-e2.mjs +0 -64
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-e3.mjs +0 -74
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-l1-launch.json +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-l2-launch.json +0 -16
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-l5-launch.json +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life-loggedin.mjs +0 -43
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life-reaper-watch.mjs +0 -62
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life-res-after.json +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life-res-before.json +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life.sh +0 -60
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life2-res-after.json +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life2-res-before.json +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-life2.sh +0 -61
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-meter.mjs +0 -53
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-probe2-out.json +0 -534
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-probe2.mjs +0 -91
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-r11-verify.mjs +0 -73
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-read-flow.json +0 -55
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-read-flow.mjs +0 -131
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-replay-strict.out +0 -70
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-replay.out +0 -70
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-browse.md +0 -210
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-infra.md +0 -246
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-lib.mjs +0 -74
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-probe.mjs +0 -18
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-probe2.mjs +0 -26
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runA.mjs +0 -63
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runA2.mjs +0 -41
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runB.mjs +0 -73
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runC.mjs +0 -80
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runC2.mjs +0 -58
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf-runD.mjs +0 -68
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-perf.md +0 -229
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-search.md +0 -273
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-round1-verdict.md +0 -124
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-sighup-flow.json +0 -24
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-sighup-flow.mjs +0 -91
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-sighup-flow2.json +0 -24
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-ssrf-fall.json +0 -98
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft-ssrf-fall.mjs +0 -87
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-run.mjs +0 -118
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s1.json +0 -30
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s1.jsonl +0 -26
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s10.json +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s10.jsonl +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s1b.json +0 -14
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s1b.jsonl +0 -10
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s2.json +0 -13
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s2.jsonl +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s2b.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s2b.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s3.json +0 -17
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s3.jsonl +0 -13
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s4.json +0 -15
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s4.jsonl +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s5.json +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s5.jsonl +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s6.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s6.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rec.json +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rec.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rep.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rep.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rep2.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7rep2.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7stale.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s7stale.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9.json +0 -9
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9b.json +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9b.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9c.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ft1-s9c.jsonl +0 -4
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/mcp-batch.mjs +0 -60
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/mcp-wave1.mjs +0 -48
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/mcp.mjs +0 -67
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/search1.jsonl +0 -14
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/search2.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-acceptance.md +0 -147
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/gate-output.txt +0 -13
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts01-02-result.json +0 -155
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts01-02.mjs +0 -103
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts03-result.json +0 -373
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts03.mjs +0 -131
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts04-result.json +0 -40
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts04.mjs +0 -75
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts05-result.json +0 -73
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts05.mjs +0 -144
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts05b-result.json +0 -257
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts05b.mjs +0 -150
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts06-result.json +0 -339
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/silence-data/ts06.mjs +0 -136
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ssrf.jsonl +0 -7
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/ssrf2.jsonl +0 -2
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/t-entry-04.jsonl +0 -6
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/tools-full.json +0 -1111
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/u085.jsonl +0 -1
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/u085b.mjs +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/upstream-probe.mjs +0 -13
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v1-idle.mjs +0 -114
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v19-v1-idle.json +0 -31
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v19-v2-chrome-stop.json +0 -49
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v19-v3-tab-restore.json +0 -40
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v19-v4-shutdown.json +0 -46
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v19-v5-perf.json +0 -119
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v2-chrome-stop.mjs +0 -105
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v3-tab-restore.mjs +0 -130
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v4-shutdown.mjs +0 -119
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19/v5-perf.mjs +0 -99
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v19-verify.md +0 -88
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/resource-sampling.json +0 -19
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v1-launch.json +0 -8
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v1-screen.png +0 -0
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v3-idle-reap.json +0 -79
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v3-idle-reap.mjs +0 -61
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v3b-a5-and-stop.json +0 -44
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v3b-a5-and-stop.mjs +0 -52
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v5-silent-tab.json +0 -72
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v5-silent-tab.mjs +0 -84
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-data/v6-headless.json +0 -2
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/v1x-silent-verify.md +0 -126
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/w2-browse-session.mjs +0 -29
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/w2-netprobe.mjs +0 -10
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/w2-steps-full.mjs +0 -30
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/w2-steps2.mjs +0 -24
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/w2-time-call.mjs +0 -11
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-browse.md +0 -132
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-desktop-mcp.mjs +0 -66
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-desktop.md +0 -159
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-entry-cli.md +0 -161
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-gov-search.md +0 -88
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave1-summary.md +0 -134
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-browse.md +0 -241
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-desktop-cli.md +0 -188
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-gov.md +0 -135
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-misc.mjs +0 -50
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-misc2.mjs +0 -33
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-misc3.mjs +0 -35
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-readtext.mjs +0 -33
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-rt06.mjs +0 -60
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-rt06b.mjs +0 -28
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-run.mjs +0 -32
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-search.mjs +0 -38
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-summary.md +0 -134
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-tools.mjs +0 -94
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-tools2.mjs +0 -42
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-tools3.mjs +0 -22
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-tools4.mjs +0 -41
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wave2-zod.mjs +0 -15
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wayback.jsonl +0 -3
- package/doc/history/01-/345/212/237/350/203/275/346/265/213/350/257/225/346/211/247/350/241/214/350/256/260/345/275/225/wayback2.jsonl +0 -2
package/ARCHITECTURE.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# Lasso 架构
|
|
2
2
|
|
|
3
3
|
> 本文是 Lasso **v1.18.7** 的架构概览(user-first;深度架构基线见 [`doc/architecture/01`](./doc/architecture/01-功能架构.md)(冻结于 2026-07-21,头部有现状对齐横幅);实施排期与决策记录见 [`doc/architecture/02`](./doc/architecture/02-实施排期.md);doc/ 目录导读见 [`doc/README.md`](./doc/README.md))。头部版本与全文计数由 P2 处置轮刷新(doc/governance/11 台账 + 本轮 20 条机械对账,2026-08-31,事实基准 = HEAD `4a40b7e` 源码实核 + `tools/list` / `npm test` / `check-invariants` / `cargo test` / `doctor` 实跑)。
|
|
4
|
+
>
|
|
5
|
+
> **现状对齐增补(2026-09-16,DocAudit 轮,基准 HEAD `7ab999b` = v1.26.0 预写态 / npm latest 1.25.0)**:v1.19.0→v1.26.0 共九版(渲染档 + BUG-03~08 五批)的架构面以**增量段落**对齐——§2 渲染档行、§9 浏览器主权三层防线、§11 INV 84→96、新 §16 五批新增面、§14 版本要点、§15 主线第 8-9 条;本实跑核验 = `check-invariants`(96/96 PASS),测试计数引自 BUG-08 gate 实跑(2997+1,见 README v1.26.0 changelog ⑥)——本轮未重跑全量 npm test,全文其余计数仍为 2026-08-31 基准。
|
|
6
|
+
>
|
|
7
|
+
> **现状对齐增补(2026-09-16,BUG-09 批,基准 HEAD `5db1656` = v1.27.0 预写态 / npm latest 1.26.0)**:反爬根治通道 + url 语义统一批(doc/bugs/09)——§1 工具面 17→18(`browse_headed` 默认注册)、§2/§3.1 通道树加 HeadedChannel、§11 INV 编号至 99(收卷时实装 98,INV-98 为哨兵保留位)、新 §16.7 反爬防御梯与 url 单一导航语义、§14 v1.27.0 预写行、§15 主线第 10 条;实跑核验 = `check-invariants`(98/98 PASS)+ vitest 全量(计数见 §10 表,收卷轮实跑)。**尾款轮+合并轮增补(2026-09-16 下午,doc/bugs/09 §8)**:WT4 驱逐哨兵已落地——`eviction_suspected` 三信号漏斗(S1 静默窗 / S2 闸门漂移复核 / S3 错误串合取)+ typed error `page_redirect_eviction_suspected:`,INV-98 转真锚(§8.A/8.F);steps 链 final_url/did_navigate 真值化(§8.B/8.E.1,INV-100)+ macOS occlusion 真机定案(§8.E.2,A.4④ 维持 `8,40`);S/T 双 worktree(bug09-wt4-a/b)合并轮收卷(实装 100/100,3120 passed + 1 skipped / 192 files)。
|
|
4
8
|
|
|
5
9
|
## 1. 项目定位
|
|
6
10
|
|
|
@@ -9,9 +13,9 @@ Lasso 是 Claude Code 的**全交互**对外抓手 MCP(浏览器 + 桌面 +
|
|
|
9
13
|
- media-gen-mcp:「所有图像操作归一个 MCP」(生成 + 识别)
|
|
10
14
|
- **Lasso**:「所有外部交互归一个 MCP」(浏览器 + 桌面 + 搜自己的机器)
|
|
11
15
|
|
|
12
|
-
**工具面(
|
|
16
|
+
**工具面(18 个 MCP 工具,`tools/list` 实跑核;v1.27.0 起 18——`browse_headed` 默认注册)**:`search / browse_headless / browse_headed / browse_logged_in / desktop / fetch_url / screenshot / pdf / network / read_text / search_local / wayback_lookup / fetch_feed / doctor / interact_roots / interact_observe / interact_act / admin`(另有 `browserbase` / `steel` 两个云通道工具按环境条件解锁,不在默认清单;对应 channel 名 `browse_cloud_browserbase` / `browse_cloud_steel`)。
|
|
13
17
|
|
|
14
|
-
四条交互通道:`search` / `browse_headless` / `browse_logged_in` / `desktop`,加 **`search_local` 本地私有搜索**(doc/governance/05 裁决 B1「第四通道」:Chrome 历史 / Spotlight 文件,纯本地只读)与条件解锁的 `browse_cloud_steel`
|
|
18
|
+
四条交互通道:`search` / `browse_headless` / `browse_logged_in` / `desktop`,加 **`search_local` 本地私有搜索**(doc/governance/05 裁决 B1「第四通道」:Chrome 历史 / Spotlight 文件,纯本地只读)与条件解锁的 `browse_cloud_steel` 云通道。v1.27.0 新增 **`browse_headed` 有头强力档**(BUG-09 决议 A:反爬 L2 层——S2 介入型工具,调用即弹真实屏幕窗口,consent 契约钉 description 首行;两态生命周期=未接管 30min idle / 接管粘滞永不回收 + 24h 硬顶,doc/bugs/09 A.4⑤r1)。所有通道共享同一套 fallback 范式 / 状态模型 / 工具风格(R-CI-02 红线:禁第二套做法);`search_local` 是唯一例外——纯本地只读查询无网络面、无 fallback 语义,走「工具直连」范式(照 `read_text` / `doctor-tool` 先例,不建 Channel 子类,防空壳对称 R-ABS-01)。
|
|
15
19
|
|
|
16
20
|
### 部署模型声明(守卫设计判据,v1.18.2 doc/governance/10 确立)
|
|
17
21
|
|
|
@@ -36,11 +40,12 @@ Lasso 的真实部署形态是**单用户、本地、stdio MCP**:一个用户
|
|
|
36
40
|
│ Lasso(单进程 Node.js) │
|
|
37
41
|
│ │
|
|
38
42
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
39
|
-
│ │ Tool Layer(src/tools/,
|
|
40
|
-
│ │ search / browse_headless /
|
|
41
|
-
│ │
|
|
42
|
-
│ │
|
|
43
|
-
│ │
|
|
43
|
+
│ │ Tool Layer(src/tools/,18 工具) │ │
|
|
44
|
+
│ │ search / browse_headless / browse_headed / │ │
|
|
45
|
+
│ │ browse_logged_in / desktop / search_local / fetch_url / │ │
|
|
46
|
+
│ │ fetch_feed / wayback_lookup / screenshot / pdf / network │ │
|
|
47
|
+
│ │ / read_text / interact_* / doctor / admin │ │
|
|
48
|
+
│ │ — 每工具 Zod schema + ToolAnnotations │ │
|
|
44
49
|
│ └────────────────────────┬─────────────────────────────────┘ │
|
|
45
50
|
│ │ typed call │
|
|
46
51
|
│ ┌────────────────────────▼─────────────────────────────────┐ │
|
|
@@ -50,8 +55,9 @@ Lasso 的真实部署形态是**单用户、本地、stdio MCP**:一个用户
|
|
|
50
55
|
│ │ BaseChannel ← MachineMcpSearchChannel / BraveChannel │ │
|
|
51
56
|
│ │ BaseChannel ← UiChannel │ │
|
|
52
57
|
│ │ ← BrowseChannel(abstract) │ │
|
|
53
|
-
│ │ ← HeadlessChannel /
|
|
54
|
-
│ │ /
|
|
58
|
+
│ │ ← HeadlessChannel / HeadedChannel(1.27) │ │
|
|
59
|
+
│ │ / LoggedInChannel / SteelChannel │ │
|
|
60
|
+
│ │ / BrowserbaseChannel │ │
|
|
55
61
|
│ │ ← StagehandChannel / DesktopChannel │ │
|
|
56
62
|
│ └────────────────────────┬─────────────────────────────────┘ │
|
|
57
63
|
│ │ FallbackDecider + tri-state │
|
|
@@ -63,8 +69,9 @@ Lasso 的真实部署形态是**单用户、本地、stdio MCP**:一个用户
|
|
|
63
69
|
│ ┌────────────────────────▼─────────────────────────────────┐ │
|
|
64
70
|
│ │ Subprocess Layer(src/subprocess/) │ │
|
|
65
71
|
│ │ SubprocessManager + RustBridge │ │
|
|
66
|
-
│ │ chrome-devtools-mcp@1.7.0(headless /
|
|
67
|
-
│ │ Steel / browserbase 各自 registerSpec
|
|
72
|
+
│ │ chrome-devtools-mcp@1.7.0(headless / headed / │ │
|
|
73
|
+
│ │ logged_in / Steel / browserbase 各自 registerSpec; │ │
|
|
74
|
+
│ │ headed 不带 --headless,reapPolicy 两态生命周期) │ │
|
|
68
75
|
│ │ lasso-rust-helper(AXAPI/UIA/AT-SPI + cgEvent │ │
|
|
69
76
|
│ │ + screenshot + TCC) │ │
|
|
70
77
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
@@ -81,6 +88,8 @@ Lasso 的真实部署形态是**单用户、本地、stdio MCP**:一个用户
|
|
|
81
88
|
|
|
82
89
|
### 2.1 浏览器驱动契约锁:chrome-devtools-mcp 1.7.0(v1.11 迁移)
|
|
83
90
|
|
|
91
|
+
> **v1.19+ 增补**:分层图之外新增两组面——① `src/render/`(v1.19.0 渲染档,5 文件:render-launcher / render-flags 冻结旗标单一真源 / render-guardian detached 执守 / render-doctor / 配套,`launchMode:"render"` 走台账 7 落点,与日常档机制天然隔离);② Subprocess 层 sidecar 治理(v1.26.0 BUG-08 决议 B:chrome-devtools-mcp 栈 spawn 即登记 sidecar + 任意 spawn 前孤儿扫除 pid 归并/lstart 交叉核对 + `admin browser_recycle` 受控重启正门)。详见 §16。
|
|
92
|
+
|
|
84
93
|
`src/subprocess/SubprocessManager.ts` 的 `LOCKED_CDP_MCP_VERSION = "1.7.0"` 是唯一真源,启动时经 `npx -y chrome-devtools-mcp@1.7.0` 自动拉取。v1.11 从 0.3.0 → 1.7.0 的一次性迁移(11 个月 / 57 个上游版本)要点:
|
|
85
94
|
|
|
86
95
|
- `--chromeArg` 透传机制解锁:launch 级 `--user-agent` / `--viewport` / `--accept-lang` 直达 Chromium(stealth 与反节流都靠它)
|
|
@@ -100,8 +109,9 @@ BaseChannel (src/channels/BaseChannel.ts)
|
|
|
100
109
|
├── MachineMcpSearchChannel (机器 MCP 复用;只通用层,不进 UI)
|
|
101
110
|
├── BraveChannel (Brave API 源;只通用层,不进 UI)
|
|
102
111
|
└── UiChannel (src/channels/UiChannel.ts)
|
|
103
|
-
├── BrowseChannel (abstract;browse_headless + browse_logged_in + cloud 复用)
|
|
112
|
+
├── BrowseChannel (abstract;browse_headless + browse_headed + browse_logged_in + cloud 复用)
|
|
104
113
|
│ ├── HeadlessChannel
|
|
114
|
+
│ ├── HeadedChannel (v1.27 有头强力档,BUG-09 决议 A L2;extends BrowseChannel 平级兄弟)
|
|
105
115
|
│ ├── LoggedInChannel
|
|
106
116
|
│ ├── SteelChannel (v1.6 自托管云浏览器;extends BrowseChannel 平级兄弟)
|
|
107
117
|
│ └── BrowserbaseChannel (v1.11 --wsEndpoint 契约)
|
|
@@ -313,14 +323,18 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
|
|
|
313
323
|
- **诚实边界固化**(不可修,见 KEY-GUIDE/README 矩阵):desktop 物理键鼠设计占用;launch-chrome hidden 的 Dock 图标(有头 Chrome 注册 Foreground ASN,LSUIElement 不可控;headless 无此问题——真机实证无 Foreground ASN);visible 档语义即「看着干」;用户 Chrome 不静音(零注入铁律)+ 操作 tab 的 hasFocus 仿真(不抢 OS 焦点)。
|
|
314
324
|
- **守卫**:INV-78(d) 精化——`bringToFront` token 级零命中(作用域内任何 select_page 都不可能带激活开关)+ `"new_page"` 禁令新增 + S-7 实装锚(select_page 调用形 + 护栏日志事件 grep)。
|
|
315
325
|
- 其余安全 INV 面(cloud 双重解锁 / appleScript 白名单 / stealth profiles / 连接池)见 §11 分类表
|
|
326
|
+
- **浏览器主权三层防线(v1.22.0 BUG-04 + v1.21.0 BUG-03 增补,永不 kill 用户浏览器红线的机械化)**:
|
|
327
|
+
1. **归属鉴定**——`chrome-status [--port N]` 十分类(账本僵尸 / 陈留 / 疑似用户资产…),输出人类决策文案 + 机器可读 `allowed_commands` / `must_report`(「疑似用户资产」分类 = 零允许操作 + 必须上报用户);INV-88 守「鉴定器永不给 kill 出口」;
|
|
328
|
+
2. **PreToolUse hook 硬拦**——`scripts/hooks/deny-browser-kill.mjs`(12 向量,伪模式当场拦 / sleep 放行;样例落仓自带 14 向量测试 + 附录E 文档同步锚,governance/12 制度);
|
|
329
|
+
3. **never_kill 语义内化**——停机三维谓词(modes × ownerPid × userTakenAt 豁免:任何进程退出只许收自己拉起的 Chrome)+ `isUserOwnedRecord`(用户已认领 / visible 登录窗)永不进程序化收尸 + `chrome-stop --zombie-gate` 三重门(台账在案+指纹对+kill 时刻重读台账)唯一机器代杀出口;INV-85/86/87 守。
|
|
316
330
|
|
|
317
331
|
## 10. 测试策略
|
|
318
332
|
|
|
319
|
-
| 层 | 工具 | 覆盖 | 规模(v1.
|
|
333
|
+
| 层 | 工具 | 覆盖 | 规模(v1.26.0 预写态,2026-09-16 对齐:INV/gate 为 BUG-08 批实跑口径) |
|
|
320
334
|
|---|---|---|---|
|
|
321
|
-
| 架构不变量 | `check-invariants.mjs`(自写) | INV-1..
|
|
322
|
-
| INV 自测 | `inv-selftest.mjs`(`npm run inv-selftest`) | 抽样 INV 做「注入违规 → 必红」复证 | **样本覆盖 20/84
|
|
323
|
-
| TS 单测 | vitest | channel / fallback / forest / doctor / launcher / outline-contract / replay-baseline / stealth / lifecycle / cdp-actions / search-local / content-second-hop / elicitation / extract-refs / quality / http-serp / fetch-feed / tool-descriptions-no-leak 等 | **
|
|
335
|
+
| 架构不变量 | `check-invariants.mjs`(自写) | INV-1..100 编号域静态 grep + 形状测 | **实装 100 条**(85-96 = BUG-03~08 五批;97/99 = BUG-09 批;**INV-98 = 驱逐哨兵契约,尾款轮 §8.A/8.F 转真锚;INV-100 = 链真值契约,尾款轮 §8.B/8.E.1**——2026-09-16 合并轮实跑 100/100 PASS) |
|
|
336
|
+
| INV 自测 | `inv-selftest.mjs`(`npm run inv-selftest`) | 抽样 INV 做「注入违规 → 必红」复证 | **样本覆盖 20/84 时代口径 + 26 个 pin 红翻转实证**(外部契约类全覆盖;85-96 批次自带形状测) |
|
|
337
|
+
| TS 单测 | vitest | channel / fallback / forest / doctor / launcher / outline-contract / replay-baseline / stealth / lifecycle / cdp-actions / search-local / content-second-hop / elicitation / extract-refs / quality / http-serp / fetch-feed / tool-descriptions-no-leak / render / bug03-09 批次 spec 等 | **3120 passed + 1 skipped**(192 文件,BUG-09 尾款轮+合并轮实跑;1 skip = linux-only ResourceMonitor 在 macOS 对称跳过) |
|
|
324
338
|
| Rust 单测 | cargo test | ax / applescript / cgevent(+keymap) / screenshot / tcc / windows / protocol / role-map | **207 测试**(cargo test 实跑;`rust-helper/src/*.rs` 自 v1.13 零改——v1.18.4 仅动 `build/sign.sh` ad-hoc 签名链) |
|
|
325
339
|
| 跨平台编译 | cargo check --target | Windows (x86_64-pc-windows-msvc) + Linux (x86_64-unknown-linux-gnu) | 本地手测(CI 为 JS 门禁三件套,不含 Rust 步骤——r4 轮改真口径) |
|
|
326
340
|
| 录制回放回归 | npm run replay-baseline | fixtures/serp-baseline/ 三引擎录制基线 | 6 条 HTML fixture(baidu/bing/google ×2;doctor #32 实跑 detail) |
|
|
@@ -328,7 +342,7 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
|
|
|
328
342
|
| 全量功能测试 | doc/testing/01 清单 + ft 执行记录 | 四面板(search / browse / infra / perf)~170 用例真机 | ft-round1 **ALL-CLEAN**(2026-08-18) |
|
|
329
343
|
| 契约锁 | chrome-devtools-mcp@**1.7.0** version pin(`LOCKED_CDP_MCP_VERSION` 单一真源) | 上游小版本升级不破 Lasso;迁移要点见 §2.1 | SubprocessManager.ts |
|
|
330
344
|
|
|
331
|
-
## 11.
|
|
345
|
+
## 11. 不变量(实装 100 条,编号至 100)分类
|
|
332
346
|
|
|
333
347
|
| 范畴 | INV 编号 | 守的是什么 |
|
|
334
348
|
|---|---|---|
|
|
@@ -348,6 +362,12 @@ engine=auto(默认)→ 多源扇出(machine_mcp + brave 两 API 源)
|
|
|
348
362
|
| v1.14-v1.17 运营事实与死层清除 | INV-54 / 80 | 死层墓碑:Bing(BingChannel 全链删、配置静默忽略)/ zhipu 直连(无 SearchChannel 类 / engine enum 无 "zhipu" / config 键容忍不消费 / doctor 报 retired) |
|
|
349
363
|
| v1.18 用户运行守则生命周期 | **82** | D-5 exit 钩子 modes:['hidden'](visible 登录窗口不被 server 退出杀死)/ C2 自动 hide 默认 off + 只挂 visible 分支永不进 kill 路径 / 四重护栏(见墙→延迟窗→agent 安静→失败降级)/ hide 走 chrome-hide PID 定向 / 延迟窗默认单一真源 |
|
|
350
364
|
| v1.18.7 架构重审轮(2026-08-31) | **83 / 84** | firstText 全仓唯一定义在 browse/upstream-response.ts(5 份私有拷贝收敛后防回潮)/ doctor 层(src/doctor/*.ts,doctor-cli.ts 组合根除外)禁 import ../channels/*(反向 value 依赖 = ESM 循环温床;defaultHeadlessProfileForHost 已迁 browse/stealth-profiles.ts) |
|
|
365
|
+
| v1.21-v1.22 浏览器主权(BUG-03/04) | **85 / 86 / 87 / 88 / 89** | 用户激活让位(归因绑定)/ 停机不连坐(owner-scoped shutdown)/ 永不代杀用户资产 / chrome-status 输出契约(鉴定器无 kill 出口)/ 上游选中页死锁自愈(楔死签名检测 + 后台自建页接管) |
|
|
366
|
+
| v1.23 消费方台账(BUG-05) | **90 / 91 / 92 / 93** | file-guard 默认关 / CONSUMED_OPTIONS 完备性(收了不生效=假接口)/ console 暴露面锚(schema 键与消费同 commit)/ screenshot 写根不变量 |
|
|
367
|
+
| v1.24 幽灵常驻根治(BUG-06) | **94** | 日常档 idle-0 的 24h 硬顶契约(cap 谓词顺序 + render 三文件零 hard-cap tripwire + CLI_USAGE + isUserOwnedRecord 前置短路 + onChromeUse touch 写侧 + 两装配点显式传参) |
|
|
368
|
+
| v1.25 当前页截图(BUG-07) | **95** | url 省略 + action=screenshot = current-page 截图(零导航;有 url 字节级不变)——schema↔description 同 commit 等 A⁺ 六面 |
|
|
369
|
+
| v1.26 马拉松稳定性(BUG-08) | **96** | 五组防线:callTool timeout 透传 / doEvaluate 传预算 / 栈扫除判定序 + chrome-stop 域隔离 / fresh profile 先杀后删 + 陈年双闸 / wait current-page 家族 / fallback 耗尽 primary-first 复合串 |
|
|
370
|
+
| v1.27 反爬通道与 url 统一(BUG-09,预写态) | **97 / 98 / 99 / 100** | HeadedChannel 平级契约(spawn 无 --headless + lasso-owned `--user-data-dir` + 无 StealthEngine 注入 + 装配四处)/ 驱逐哨兵契约(**尾款轮 §8.A/8.F 已实装**:三信号漏斗 + INV-98 a-g 全组)/ 链真值契约(尾款轮 §8.B/8.E.1:尾读真值 + 种子等值守卫 + INV-100)/ 两态生命周期(reapPolicy 判定序 + 探测器并发安全 + 存量 spec 字节级不变回归锚 + C3 逃生门) |
|
|
351
371
|
|
|
352
372
|
完整 INV 列表 + 释义见 `src/invariants/check-invariants.mjs` 顶部注释。
|
|
353
373
|
|
|
@@ -433,16 +453,27 @@ $ lasso launch-chrome
|
|
|
433
453
|
| desktop 四档 | src/desktop/{AxProvider,AxBackend,AxBackendFactory,OutlineMapper,CGEventProvider,ScreenshotVlmProvider}.ts | AxProvider ~330 |
|
|
434
454
|
| FallbackDecider | src/fallback/FallbackDecider.ts | ~350 |
|
|
435
455
|
| Launcher | src/launcher/{launch-chrome,chrome-paths,chrome-stop,chrome-idle-reaper,chrome-ledger,chrome-hide,chrome-hideshow-cli,chrome-touch,desired-hide-state,desired-hide-watchdog,desired-hide-enforcer}.ts(INV-64 不引新 npm dep;chrome-touch / desired-hide-* = v1.18.3~v1.18.6 bug02 链) | 11 文件共 ~2900 |
|
|
456
|
+
| Render 档 | src/render/{render-chrome,render-launcher,render-flags,render-guardian,render-doctor}.ts(v1.19-1.20 五文件;冻结旗标单一真源 + detached 执守 + reused 四条件门,见 §16.2) | — |
|
|
436
457
|
| Doctor | src/doctor/doctor.ts(doctor CLI 默认 34 项实跑核;MCP doctor tool / DesktopChannel 装配 desktopChecks:true 时加 #15-#21 共 41 项;--deep 加 #11b brave_deep_probe;#21 event-synthesis / #36 machine_mcp / #37 steel / #38 creepjs / #39 stagehand / zhipu_keys_retired) | ~3060 |
|
|
437
|
-
| Invariants | src/invariants/check-invariants.mjs
|
|
458
|
+
| Invariants | src/invariants/check-invariants.mjs(实装 100 条 INV;85-96 = BUG-03~08 五批,97-100 = BUG-09 批(98 驱逐哨兵真锚 + 100 链真值),2026-09-16 合并轮实跑全 PASS) | ~6320 |
|
|
438
459
|
| INV 自测 | scripts/inv-selftest.mjs(20 样本红转复证) | ~410 |
|
|
439
460
|
| Subprocess | src/subprocess/SubprocessManager.ts(`LOCKED_CDP_MCP_VERSION = "1.7.0"`);rust-helper-path.ts(模块锚定:`new URL("../../rust-helper/...", import.meta.url)` 与宿主 cwd 解耦——v1.18.4 根治「非仓库根目录启动 desktop 全报 rust_helper_crashed」) | ~750 |
|
|
440
461
|
| Rust helper | rust-helper/src/{ax,uia,atspi,applescript,applescript_whitelist,cgevent,cgevent_keymap,screenshot,tcc,windows,protocol,main,lib,ax_role_map,app_bundle_map}.rs(15 文件);build/sign.sh(v1.18.4 ad-hoc 兜底签名进构建链) | ~5000;src/*.rs 自 v1.13 零改 |
|
|
441
462
|
|
|
442
463
|
## 14. 版本与发布
|
|
443
464
|
|
|
444
|
-
-
|
|
465
|
+
- **当前版本**:npm latest `1.26.0`;工作树 HEAD `6cecb70`(BUG-09 尾款轮+合并轮终态)为 **v1.27.0 预写态**(changelog 已预写、版本行未改,发版归审查循环后用户指令——README v1.27.0 条目)
|
|
445
466
|
- **version 真源**:`package.json` + `src/index.ts:LASSO_SERVER_VERSION` + `src/doctor/doctor.ts:LASSO_VERSION`(INV-63 守:三处必字面量一致)
|
|
467
|
+
- **v1.19.0 → v1.27.0 要点**(2026-09-16 增补;用户向完整版见 README changelog;决策记录见 doc/bugs/03-09 + doc/渲染档文档组):
|
|
468
|
+
- **v1.27.0(预写)**:反爬根治通道 + url 语义统一批(BUG-09)——`browse_headed` 有头强力档(L2 防御梯:真实有头 Chrome、consent 首行、两态生命周期 30min idle/接管粘滞+24h 硬顶、`LASSO_HEADED_IDLE_MS`/`LASSO_HEADED_HARD_CAP_MS`)+ url 单一 ensure-navigation 语义(四族收敛,`did_navigate` 回显,消灭「extract+url 读残留页」假数据形态)+ steps wait 三键统一 + worked⇒error 迁 `warnings` + headless→logged_in 跨通道 fallback 边默认移除(`LASSO_FALLBACK_CROSS_CHANNEL` 逃生门)+ final_url 尾句读剥离 + doctor CDP 报生效端口 + **WT4 驱逐哨兵(尾款轮 §8.A)**:`eviction_suspected:{from,to,at_ms}` 三信号漏斗(S1 5s 静默窗 / S2 闸门漂移复核 / S3「Execution context was destroyed」∧ host 偏离合取 typed error)一次性 advisory 回显 + consent hint,绝不自动升级通道;LoggedInChannel 显式 opt-out + **steps 链回显真值化(尾款轮 §8.B,INV-100)**:链级 `final_url` 改链尾真值读(种子等值守卫,永不回显请求串)+ 链级 `did_navigate` 回显 + 先导导航 sd 双标注透传(链执行语义零变化)+ **macOS occlusion 真机定案(尾款轮 §8.E.2)**:「屏幕外全藏窗口被判 occluded」假设证伪(恒 visible + rAF 满速),A.4④ 窗口终值维持边缘露出 `8,40`(零参数变更、零 INV 迁移)。
|
|
469
|
+
- **v1.19.0**:确定性渲染档(`render-chrome --ensure/--status/--stop/doctor`,`src/render/` 5 文件 + 冻结旗标快照 + detached guardian)+ perf/acc 裁决批(npx registry 税 `--prefer-offline` 等)——设计决议见 doc/渲染档设计决议.md
|
|
470
|
+
- **v1.20.0**:渲染档并行安全批——`--stop` 端口作用域化(显式合法=只收该 port / 未设=全收 / 非法=exit 1,提案 §6 裁决)
|
|
471
|
+
- **v1.21.0**:浏览器主权与生命周期根治批(BUG-03)——CLI 默认 30min 回收 + 停机三维谓词 + 端口占用归因(`ledger_zombie_collected` / `never_kill_user_asset` / `user_taken_asset`)+ `--mode headless` 档
|
|
472
|
+
- **v1.22.0/1**:归属鉴定与通道自愈批(BUG-04)——`chrome-status` 十分类 + `--zombie-gate` + 选中页死锁自愈 + evaluate IIFE 形态;v1.22.1 回告收口(governance/12:交付物自带测试载体制度)
|
|
473
|
+
- **v1.23.0**:本地文件与排障能力批(BUG-05)——`LASSO_ALLOW_FILE_FROM` file 白名单 / navigate 死参数清扫 / console 暴露面
|
|
474
|
+
- **v1.24.0**:幽灵常驻根治批(BUG-06)——`--idle-ms 0` 语义改「不自收 + 24h 硬顶」+ 跨进程活动真源 + 配方治理
|
|
475
|
+
- **v1.25.0**:当前页截图批(BUG-07)——`action=screenshot` 省略 url 截当前受管页(零导航)
|
|
476
|
+
- **v1.26.0(预写)**:反爬马拉松稳定性批(BUG-08)——same-document 导航默认 reload + evaluate url=ensure-navigation + `budget_ms` 超时类型化 + freshProfile 逃生门 + sidecar 治理 `browser_recycle` + logged_in 端口三层解析 + fetch_url 失败细分 + vitest threads 钉死 / gate 超时追杀带
|
|
446
477
|
- **v1.18.1 ~ v1.18.7 要点**(用户向完整版见 README changelog;决策记录见 doc/architecture/02 排期表):
|
|
447
478
|
- **v1.18.0/1.18.1**:静默守则入宪(doc/governance/09)——D-5 exit 钩子 modes:['hidden'](visible 登录窗口不再被 server 退出杀死)+ C2 登录后自动 hide(opt-in)+ INV-82;批量实战五修(求值失败不静默吞 / 无选中 tab 自愈 / visible 冷启动探活 12s / PDF 上游缺失前置如实报)
|
|
448
479
|
- **v1.18.2**:错配机制审计(doc/governance/10)——威胁模型错配守卫四修 + 默认放行(单用户本地 stdio 形态下「多租户滥用」类限额默认 Infinity / opt-in;瞬态 DNS ≠ 策略拦截,语义 unknown 可重试)
|
|
@@ -453,7 +484,7 @@ $ lasso launch-chrome
|
|
|
453
484
|
- **v1.18.7**:架构重审落地——browse 族接口面死参数清扫(诚实化)+ doctor/channels 解耦(INV-84)+ firstText 单一定义(INV-83)+ 文档改真 + INV 82→84;随后 P2 处置轮(doc/governance/11)46 项三档裁决 + `launch-chrome --help` 误启动修复 + CI actions 升 checkout@v7 / setup-node@v6 并加 Node 24
|
|
454
485
|
- **doctor readiness 现状(如实)**:任一 check fail → `ready:false`。**#15 `rust_helper_signed` 现行语义 = ad-hoc 签名 → warn**(2026-08-31 用户裁决降级:ad-hoc 是官方免费合法方案、功能正常,唯一代价 rebuild 后 TCC 重授权;FAIL 把正常配置判成 ready:false 属噪音。Developer ID 长期方案保留在 next_step;Developer ID 正签仍 pass、未签仍 warn——回归测试 rust-helper-signed-warn.spec 三态锚定)
|
|
455
486
|
- **跨平台 backend**:macOS 本机全证;Win/Linux 编译可证 + 契约可证,真机执行待社区反馈
|
|
456
|
-
- **门禁(本地)**:`npm run build` / `npm test
|
|
487
|
+
- **门禁(本地)**:`npm run build` / `npm test`(**2026-09-16 尾款轮+合并轮基准:3120 passed + 1 skipped,192 文件 + readme-sync**——BUG-09 §8 实跑口径)/ `npm run check-invariants`(**100 实装全 PASS**,编号至 100 全实装,2026-09-16 实跑)/ `npm run inv-selftest` + `cargo test`(207,CI 不含);`npm run gate` 后台化 + 60s 轮询读 log(180s stall 防误判;vitest 树超时追杀带 `LASSO_GATE_VITEST_TIMEOUT_MS`,doc/bugs/08 §12)
|
|
457
488
|
- **CI(.github/workflows/ci.yml 实况)**:ubuntu-latest × Node **20/22/24** 矩阵(20=下限锚点 / 22=maintenance LTS / 24=active LTS——search-local 的 `node:sqlite` 依赖 NODE_MAJOR>=23,加 24 后该文件 40 测在 CI 真跑);actions checkout@v7 / setup-node@v6;步骤 = npm ci → build → test → check-invariants(**JS 门禁三件套,无 cargo 步骤**——Rust 面靠本地 cargo test/check 守)
|
|
458
489
|
|
|
459
490
|
## 15. 质量与决策主线(doc/governance/01 → doc/governance/06 → doc/testing/01)
|
|
@@ -467,10 +498,51 @@ $ lasso launch-chrome
|
|
|
467
498
|
5. **全量功能测试轮**(doc/testing/01,v1.17.1):四面板 ~170 用例真机执行,抓出并修复 6 缺陷(🔴IPv6 字面量 SSRF 绕过 / 🔴HighRiskGate 裸 JSON.parse / doWait 假成功 / tab_restore no-op / doctor file 键 / SIGHUP),R1 独立裁决 **ALL-CLEAN**;§6 简单架构 38 条终判见 §6.1。
|
|
468
499
|
6. **静默性 / 守则 / 错配审计三连**(doc/governance/08 / 09 / 10,v1.17.2 → v1.18.2):全通道零抢焦点(S-7/S-10)→ 用户运行守则入宪(S1/S2/S3 三子句 + INV-82)→ 错配机制审计(47 处命中逐个裁决:4 修复 + 5 黄 + 19 保留)。
|
|
469
500
|
7. **全面重审与 P2 处置**(2026-08-31,wf_c02ef3df 15-agent 五路 review + doc/governance/11 台账):首轮五路 34 + 复审 22 = 56 原始 P2 去重合并 46 项,三档裁决 **20 fixed / 25 deferred / 1 rejected(已被 r3 轮修复偿)**;fixed 批次含 types.ts 死字段清理、doctor.spec flake 抬 15s、CI actions 升级 + Node 24 矩阵、`launch-chrome --help` 误启动短路;deferred 项全部留档可追。
|
|
501
|
+
8. **渲染档 + BUG-03~08 五批实战驱动线**(2026-09-01 → 09-15,doc/渲染档文档组 + doc/bugs/03-08):确定性渲染档(v1.19-1.20,media-gen-mcp 消费方托付浏览器生命周期)→ 浏览器主权根治(BUG-03 事故:用户 Chrome 被裸 kill)→ 归属鉴定 chrome-status(BUG-04,消费方实战)→ 消费方台账 L1-L4 两批(BUG-05/07,novel-engine)→ 幽灵常驻 24h 硬顶(BUG-06,用户 12h 实锤)→ 反爬马拉松稳定性(BUG-08,3 小时商标库实战 + F 组用户负载 188 实锤)。每批 = 事故/台账驱动 → 设计决议 → 实施 → 对抗复审 clean 闭环;INV 84 → 96。
|
|
502
|
+
9. **BUG-08 审查循环(2026-09-16,Gauntlet 对抗复核)**:主对象 `git diff 92200d3..7ab999b`(16 commit/43 files)+ 五批累计架构漂移面——R-INT-06 证据修订后记(testing/01 §6:BrowseChannel.ts 磁石效应五批中四批落点 14 commit、doEvaluate 85 行 ≥4 职责类,**下批触碰 navigate/evaluate 语义须抽导航语义模块**,doc/testing/01 表后记)等。
|
|
503
|
+
10. **BUG-09 反爬根治批(2026-09-16,喵虎核验报告驱动,doc/bugs/09)**:消费方核心诉求「强力反爬就完全没办法」→ 四路线裁决矩阵(stealth patch REJECTED〔D-α/β 实效反证〕/ 有头通道采纳为 L2〔WT0 spike 前置定生死 + tm 真机四轮 6/6〕/ 分层防御梯采纳)+ url 语义统一(三分裂 Set 收敛单一 ensure-navigation,P1 假数据面根治)+ P2 批 C1-C5;三 worktree 并行(WT1/2/3)+ WT0 spike + 三轮对抗复审 clean(r3 变异 6 kill 1 存活归类 + 真机六探针)+ 尾款轮(§8):§7.2 移交项 1/2/3 全清偿——WT4 驱逐哨兵(A.5r2 三信号漏斗,INV-98 真锚)+ steps 链真值化(INV-100)+ macOS occlusion 定案(A.4④ 维持 8,40)。**未竟**:R-INT-06「抽导航语义模块」义务触发未执行(doc/bugs/09 §7.2 #6 登记,移交下批)。
|
|
470
504
|
|
|
471
505
|
方法学沉淀(供复用):裁决官不采信文档(关键声称白盒双源亲验);证据阶梯 L0-L3;mutation 即验收;「先拿事实再加参数」;收敛协议前置;零基视角才可见方案级盲区;决策分级(GO/DECISION/WATCH/NOGO)交用户裁决而非默认全做。
|
|
472
506
|
|
|
473
|
-
## 16.
|
|
507
|
+
## 16. v1.19 → v1.27 新增架构面(渲染档 + BUG-03~09 六批;2026-09-16 增补)
|
|
508
|
+
|
|
509
|
+
> 本节为增量对齐段:v1.18.7 基线之后新增、且改变架构形态的面。逐项决策记录见 doc/bugs/03-09 与 doc/渲染档文档组(索引 doc/README.md ⑦/⑤)。
|
|
510
|
+
|
|
511
|
+
### 16.1 台账体系(chrome ledger,v1.9 既有 + 五批扩展为治理中枢)
|
|
512
|
+
|
|
513
|
+
台账 `~/.cache/lasso/launched-chromes.json`(主键 port + 归属标记)从「拉起记录」演进为**全生命周期治理中枢**:`launchMode` 三值(hidden / visible / **render** v1.19)× 停机三维谓词(modes × ownerPid × userTakenAt 豁免,BUG-03——任何进程退出只许收自己拉起的 Chrome)× `userTakenAt`/`isUserOwnedRecord` 用户认领态(永不进程序化收尸)× 24h 硬顶(BUG-06,无窗口实例保命天花板 + `--no-hard-cap` 逃生口)× 跨进程活动真源 `chrome-touch-<port>`(外部 CDP 消费者 touch 续命)。`chrome-status` 十分类把「这个端口被谁占着、我能不能动它」做成可机械判定的归属鉴定(§9 三层防线第 1 层)。
|
|
514
|
+
|
|
515
|
+
### 16.2 渲染档(src/render/,v1.19-1.20)
|
|
516
|
+
|
|
517
|
+
确定性 headless Chrome 档,服务 media-gen-mcp 等渲染消费方:`render-chrome --ensure`(幂等 + reused 四条件门 + 单飞锁 + 退出码 0-5 契约)/ 冻结旗标快照(render-flags.ts 单一真源 + fixture tripwire,同输入同像素)/ detached `render-guardian` 执守(收割调度,Chrome 本体持有者 =「无人」PPID=1 + 磁盘台账共有制)/ profile 三路径连带清理 / 9224 固定口(`LASSO_RENDER_PORT` 可隔离,冲突 exit 3)。并行验收三 env 命名空间配方见 doc/渲染档-并行验收隔离配方.md。设计决议:doc/渲染档设计决议.md(r2/r3 修订在档)。
|
|
518
|
+
|
|
519
|
+
### 16.3 上游楔死自愈(BUG-04,v1.22.0)
|
|
520
|
+
|
|
521
|
+
上游 chrome-devtools-mcp 选中页被关后 navigate/evaluate/snapshot 永久报错的结构性缺陷:lasso 检测楔死签名 → 后台自建页接管(`Target.createBackgroundTarget`,零抢焦)→ 自愈后如实前缀上报(`session_rotated:`);修不掉时诚实报错不伪装。INV-89 守(heal 函数体双锚)。v1.26.0 补齐长 evaluate 维度:上游全局 toolMutex 楔死是**时间性的**(~3min 自愈)——`budget_ms` 调用预算传导 MCP 层(此前恒落 SDK 60s 缺省事故)+ 超时类型化 `mcp_request_timeout:` + 教学 hint(Chrome 没死)。
|
|
522
|
+
|
|
523
|
+
### 16.4 内部栈 sidecar 治理(BUG-08 决议 B,v1.26.0)
|
|
524
|
+
|
|
525
|
+
chrome-devtools-mcp 栈(进程内 spawn,跨进程不可见)与台账(主键 port)两者不对应 → `chrome-stop --all` 返空 + deny-hook 正确拦 OS kill = 死锁。治理:spawn 即登记 sidecar + 任意 spawn 前孤儿扫除(判定序:pid 归并 → alive → 包串 → lstart 交叉核对 → owner 死;绝不触碰非 lasso 进程)+ `admin browser_recycle` 受控重启正门(永不动 detached Chrome;可组 `freshProfile:true` 换脸重启)。域隔离 tripwire:chrome-stop 零 headless-stack 符号。
|
|
526
|
+
|
|
527
|
+
### 16.5 反爬逃生门与假数据面修正(BUG-08 决议 C/D,v1.26.0)
|
|
528
|
+
|
|
529
|
+
- **freshProfile**:headless 被服务端指纹拉黑(静默假 0)后的逃生门——完整新一致身份(临时 profile 归属锚目录名 + 先杀后删 + 24h 陈年双闸防 BUG-03 垃圾重演 + stealth 宿主适用集确定性轮换 + 完整栈 respawn);logged_in 永不支持。
|
|
530
|
+
- **same-document 诚实化**:仅 hash 不同导航默认补 reload(URL 规范化判基 `new URL()` origin+pathname+search,空路径省略斜杠形态不漏检——审查轮 3f73331 封口)+ `evaluate url` = ensure-navigation(final_url 永远真实)——假数据面(比崩溃危险一个数量级)的系统性修正。
|
|
531
|
+
|
|
532
|
+
### 16.6 测试基建自愈(BUG-08 F 组,v1.26.0)
|
|
533
|
+
|
|
534
|
+
vitest 池显式钉死 `threads`(主进程死 = worker 线程随之死,forks 孤儿类结构性消灭——用户负载 188 实锤事故)+ `npm run gate` 对 vitest 树的超时追杀带(到点树根存活即整树 SIGKILL;E1 白盒实锤 spawnSync timeout 形态必漏杀忙 worker,已否决)。gate 运行纪律:后台化 + 60s 轮询读 log(防 180s stall 误判死)。
|
|
535
|
+
|
|
536
|
+
### 16.7 反爬防御梯 + url 单一导航语义(BUG-09,v1.27.0 预写态)
|
|
537
|
+
|
|
538
|
+
- **防御梯三层**:L0 = 既有 headless + stealth 栈(字节级不变,覆盖指纹层);L1 = **url 单一 ensure-navigation 语义的副产品**——`extract/evaluate/snapshot` + url ≠ 当前页在单次调用内「导航→load→抢读」,无 MCP 往返间隔(JS 层延迟驱逐站点的快照窗口机制化;诚实边界:驱逐提前到 DOMContentLoaded 前或服务端 302 则无效);L2 = **`browse_headed` 有头强力档**(`src/channels/HeadedChannel.ts`,SteelChannel 同配方平级兄弟;同上游 chrome-devtools-mcp@1.7.0 不带 `--headless`,零新二进制/依赖——不触新组件红线;真实环境即真实指纹,**不接 StealthEngine**〔与 headless 相反取舍,INV-97 钉〕)。
|
|
539
|
+
- **两态生命周期**(SubprocessManager per-spec `reapPolicy` 三元组,存量 spec 缺省=行为字节级不变):未接管态 30min idle 回收(`LASSO_HEADED_IDLE_MS`,宽于 headless 域 5min);**接管粘滞**——pipe 会话 30s 周期 `document.hasFocus()` 探测,用户聚焦即标记、永不 idle 回收(visible 红线延伸到有头通道;用户关窗 = pipe 断 = 既有清理路径);24h 硬顶 `LASSO_HEADED_HARD_CAP_MS` 是唯一兜底出口(BUG-06 孤儿舰队防线同型)。INV-99 钉判定序/并发安全/回归锚。
|
|
540
|
+
- **consent 契约**:S2 介入型工具(调用即弹真实窗口)——description 首行钉 `opens a real on-screen window — call only after explicit user consent`;不自动升级、不设部署级解锁门(INV-25 式解锁被定向驳回,理由 doc/bugs/09 A.4⑥r1)。SSRF/file-guard 经 BrowseChannel 继承 + 独立入口钉(r3 修复:`headed-tool-ssrf-entry.spec.ts` 真 guard 不 mock)。
|
|
541
|
+
- **url 单一导航语义**(BrowseChannel 语义面净减一个概念):三个 Set(NAV_FIRST / FRESH_PAGE_NAV / ensure-nav)收敛为单一 ensure-navigation + CURRENT_PAGE_ACTIONS 白名单(screenshot/wait/evaluate)——省略 url=当前页(无会话显式 `no_active_session`,不静默空白页)/ url=当前页零导航直执行(保 SPA 状态)/ url≠当前页先导航再执行;全部 url 感知 action 统一 `did_navigate` 回显。消灭的假数据形态:`extract`+url 读会话残留页装成功(喵虎时间线 7 实锤 workaround 流)。有意 breaking 均带可判读回显或一键恢复开关(`LASSO_FALLBACK_CROSS_CHANNEL`)。
|
|
542
|
+
- **驱逐哨兵(尾款轮 §8.A 落地,决议 A.5r2——判据面修订)**:原案 framenavigated 监听在 lasso 层不可达(McpClient 无订阅面,ExpectPoll.ts:32 同型定谳先例)→ 三信号漏斗替代:S1 5s 静默窗采样(did_navigate 后 setTimeout+unref,读后复检 actSeq/client)/ S2 闸门漂移复核(ensure-nav 门既有读上加 host 判等,零新增读)/ S3 错误串合取(「Execution context was destroyed」∧ 确认读 host 偏离 ⇒ typed error `page_redirect_eviction_suspected:` + classify didnt 自持)。三硬守卫(G-placeholder/G-client/S1 读后复检)是判据的一部分。回显 `eviction_suspected:{from,to,at_ms}` 一次性消费 + consent hint(**绝不自动升级通道**——零 FallbackDecider/spawn);LoggedInChannel 显式 opt-out(SSO 跨域流转合法常态)。诚实边界:同 host 驱逐仅 S3 可捕(症状兜底句接手)、www↔apex 异 host 误报可容忍(advisory)。开放项与移交清单见 doc/bugs/09 §7.2/§8。
|
|
543
|
+
- **steps 链回显真值化 + headed 窗口终值(尾款轮 §8.B/§8.E)**:链级 `final_url` 从「恒回显请求串」(残留页上跑链谎称目标页——R2-1 行为面)改为**链尾一次 `readCurrentHref` 真值读**(种子链:最后携带真值的 step partial → entryNav.final_url → 缺席;**种子等值守卫**:候选=请求串视同缺席——doNavigate `?? url` 回退形态不得洗白进链级真值;INV-100 来源判据措辞)+ 链级 `did_navigate` 如实回显 + 先导导航 same-document 双标注透传;**链执行语义零变化**(否决「链入口 ensure-nav」——先导 navigate step 既有范式会双重导航伤 SPA 态)。macOS occlusion 三臂真机实验(§8.E.2)证伪「屏幕外窗被判 occluded」假设(P2 全藏恒 visible + rAF 满速)→ A.4④ 窗口终值维持边缘露出 `8,40`(consent 契约 + 归属锚可见性 + hasFocus 探测器语义三理由否决全藏为默认)。
|
|
544
|
+
|
|
545
|
+
## 17. 相关文档
|
|
474
546
|
|
|
475
547
|
- [README.md](./README.md) — 用户手册(安装 / 配置 / 工具列表 / 隐私 / 故障排查)
|
|
476
548
|
- [doc/README.md](./doc/README.md) — doc/ 目录导读(**七组结构**:usage / architecture / testing / governance / bugs / history / archive,2026-08-27 重整;旧全局编号 08/09/17-29 → 新路径映射表在此;决策时间线 + 新鲜度表)
|
|
@@ -482,8 +554,10 @@ $ lasso launch-chrome
|
|
|
482
554
|
- [doc/usage/03-SELECTOR-MAINTENANCE.md](./doc/usage/03-SELECTOR-MAINTENANCE.md) — selector 债维护手册
|
|
483
555
|
- [doc/governance/07 文档查缺补漏](./doc/governance/07-文档查缺补漏/gap-matrix.md) — 文档盘点矩阵(新鲜度档位 + F 编号映射真源)
|
|
484
556
|
- [doc/governance/11 P2 处置台账](./doc/governance/11-P2处置台账.md) — 全面重审 46 项 P2 三档裁决全记录(20 修 / 25 留档 / 1 已偿)
|
|
485
|
-
- [doc/
|
|
557
|
+
- [doc/governance/12 回告收口决议](./doc/governance/12-回告收口与交付物测试载体决议.md) — 交付物必须自带测试载体制度(deny-hook 样例落仓 + 文档同步锚)
|
|
558
|
+
- [doc/bugs](./doc/bugs/) — BUG 档案(01 rust-helper 路径 / 02 外部消费与隐藏生命周期 / 03 hidden 档劫持 / 04 死锁与 chrome-status+附录E / 05 消费方台账 L1-L3 / 06 幽灵常驻 / 07 消费方台账 L4 / 08 商标马拉松五组 / 09 反爬根治通道与 url 语义统一)
|
|
559
|
+
- [doc/渲染档设计决议](./doc/渲染档设计决议.md) 等根级渲染档文档组 7 件 — 决议/需求/对接契约/并行配方/perf-acc 裁决/stop 作用域提案/登记开项(索引见 doc/README.md ⑦)
|
|
486
560
|
|
|
487
561
|
---
|
|
488
562
|
|
|
489
|
-
本文档是 Lasso
|
|
563
|
+
本文档是 Lasso 架构概览(user-first;2026-08-31 全量对齐刷新至 v1.18.7——事实基准 = HEAD `4a40b7e` 源码实核 + `tools/list` / `npm test` / `check-invariants` / `inv-selftest` / `cargo test` / `doctor` 实跑,20 条机械断言逐条对账零漂移;**2026-09-16 DocAudit 轮增补对齐至 v1.26.0 预写态**——头部横幅 / §2.1 渲染档与 sidecar / §9 三层防线 / §10 计数 / §11 INV 96 / §14 版本要点 / §15 主线 8-9 / 新 §16 五批新增面;**2026-09-16 BUG-09 批增补对齐至 v1.27.0 预写态**——§1 工具面 18 / §2-§3.1 HeadedChannel / §11 INV 编号至 99(实装 98)/ §14-§15 / §16.7 反爬防御梯与 url 单一语义,实跑核验 = check-invariants 98/98 + vitest 全量)。深度架构基线(含 F 编号 / 不变量推导链 / 测试策略)见 [`doc/architecture/01`](./doc/architecture/01-功能架构.md);v0.1 → v1.27.0 实施排期(含每 phase 决策记录)见 [`doc/architecture/02`](./doc/architecture/02-实施排期.md)。
|
package/README.en.md
CHANGED
|
@@ -212,7 +212,7 @@ Goes to the Internet Archive (Wayback Machine) to find the last archived copy of
|
|
|
212
212
|
|
|
213
213
|
## Install
|
|
214
214
|
|
|
215
|
-
**Current version v1.
|
|
215
|
+
**Current version v1.27.0** (changelog in the collapsed block at the end of this section).
|
|
216
216
|
|
|
217
217
|
Prerequisites: Node.js ≥ 20 + Claude Code (or any MCP-capable client).
|
|
218
218
|
|
|
@@ -227,9 +227,10 @@ Restart Claude Code → `/mcp` → `lasso ✓ Connected`. **That's the one line
|
|
|
227
227
|
**Deterministic render browser for other AI tools (render tier)**: if you use rendering tools like media-gen-mcp that demand "same input → same pixels", one line after installing lasso — `npx -y lasso-mcp render-chrome --ensure` — brings up a deterministic headless Chrome on port 9224 (frozen flag snapshot + isolated temp profile) and prints the `wsEndpoint` for the consumer to attach to; **the browser keeps running even if the consumer process is SIGKILLed** (lifecycle owned by lasso), and it is idle-reaped after 10 minutes with its profile cleaned up (tunable via `LASSO_RENDER_IDLE_MS`). Companions: `render-chrome --status` introspection / `--stop` (honors `LASSO_RENDER_PORT`: an explicit valid port stops only that port, unset = all render records, an invalid value exits 1; global teardown remains `chrome-stop --modes render`) / `render-chrome doctor [--clean]` orphan & stale-profile sweep (dry-run by default; honors `LASSO_RENDER_PORT` like `--stop`: an explicit valid port scopes the orphan scan, unset = full scan, an invalid value exits 1; in-use instances with a touch heartbeat within 10 minutes are exempt from orphan judgment). **Multiple parallel acceptance agents on one machine** (whose independent teardown commands would kill each other's instances) need a three-env namespace: `LASSO_RENDER_PORT` + `LASSO_LAUNCHED_CHROMES_PATH` + `LASSO_RENDER_GUARDIAN_PID_PATH` — with all three set, parallel agents are mutually invisible; see the full recipe and teardown discipline in [doc/渲染档-并行验收隔离配方.md](doc/渲染档-并行验收隔离配方.md) (Chinese).
|
|
228
228
|
|
|
229
229
|
<details>
|
|
230
|
-
<summary>📋 Changelog (v1.8 → v1.
|
|
230
|
+
<summary>📋 Changelog (v1.8 → v1.27.0 — click to see what each version changed)</summary>
|
|
231
231
|
|
|
232
|
-
- **v1.
|
|
232
|
+
- **v1.27.0** (unreleased prewrite — release awaits the user's call): anti-scraping root-cause channel + url-semantics unification batch (BUG-09, driven by the Miaohu verification report, doc/bugs/09) — (1) **new tool `browse_headed` (headed power tier — the anti-scraping root-cause channel)**: the root remedy for sites that evict headless automation at the JS layer (the page loads, then redirects itself away 2-3s later — trademark-registry shape): a REAL on-screen headful Chrome window (same upstream chrome-devtools-mcp, just without `--headless`; zero new dependencies); real-machine trademark-site residency 6/6 across four rounds. The stealth trade-off is the opposite of the headless tier (a real environment IS the real fingerprint — nothing injected). **Calling it opens a real window on your screen** — description and hint both pin "call only after explicit user consent". Two-state lifecycle: unclaimed sessions idle-reclaim after 30 minutes (`LASSO_HEADED_IDLE_MS`); the moment you click into the window it is marked user-taken and **never auto-reclaimed** (close the window yourself to reclaim; a 24h hard cap `LASSO_HEADED_HARD_CAP_MS` is the only orphan-fleet backstop). (2) 🔴 **url semantics unified (corrective behavior change — the fake-data face)**: every url-aware action now follows ONE rule — **omit url = current page** (no active session → explicit error, never a silent blank page) / **url == current page = zero-navigation direct execution** (no more reloads wiping SPA state) / **url ≠ current page = navigate first, then execute**; every url-aware action now echoes `did_navigate:true/false`. Fixed: `extract`+url used to **read the stale session page while claiming success** (fake data) → now reads after navigating; `evaluate` with url omitted used to be rejected → now legal (the old description's promise honored); `screenshot`/`pdf`/`network` with the same url as the current page switch from reload to skip (SPA state preserved). (3) `wait` validation inside steps chains is now consistent with the top level (three keys: text/selector/url_contains — chains previously accepted only text). (4) step chains with `outcome:worked` no longer leave transient errors in the `error` field (moved to a new `warnings[]`; contract hardened: worked ⇒ error always empty). (5) **breaking (one-switch recoverable)**: `browse_headless` no longer auto-falls-back to `browse_logged_in` (the logged-in channel must be an explicit choice; cross-channel error cross-contamination was a marathon misdiagnosis root) — set `LASSO_FALLBACK_CROSS_CHANNEL=1` to restore the old behavior. (6) `final_url` trailing punctuation stripped (`.,;:!?` — forensically pinned to upstream prose end-sentences being swallowed; parentheses/quotes untouched); `lasso doctor` CDP-check failure details now carry the effective port. (7) **WT4 eviction sentinel (final-payment round, doc/bugs/09 §8.A)**: `browse_headless`/`browse_headed` responses can now carry `eviction_suspected:{from,to,at_ms}` + hint — when the channel observes the page drifting to a different host after lasso's own navigation settled (three-signal funnel: a 5s silent-window sample / gate-drift re-check / the conjunction of evaluate dying with `Execution context was destroyed` AND a host offset → typed error `page_redirect_eviction_suspected:`), a one-shot advisory signal is attached (consumers can for the first time mechanically tell "my call was wrong" from "the site killed headless"); **signal only, NEVER auto-upgrades the channel** — the hint pins "ASK THE USER FIRST, then retry with browse_headed" (the surprise of opening a real window requires consent); `browse_logged_in` explicitly opts out (cross-domain SSO flows are legitimate there — the signal would be pure noise); (8) **step-chain echo truthification (corrective lie-removal)**: chain-level `final_url` used to echo the request string verbatim (a chain running on a stale session page would claim the target page) → now a tail-of-chain ground-truth read (the page's real href; omitted when no truth is available — **never the request string**) + chain-level `did_navigate` echoed honestly + leading-navigation same-document annotations passed through — chain execution semantics unchanged (zero consumer workflow breakage); (9) macOS occlusion real-machine experiment settled (§8): the "fully offscreen windows get judged occluded by the system" hypothesis is **refuted** (measured constantly visible + full-speed rAF); the `browse_headed` window default stays edge-visible `8,40` (consent-contract and window-attribution-anchor ruling; zero parameter change); Tests 2997→3120 (192 files) / invariants 96→100 implemented (numbered to 100 — INV-98 eviction-sentinel real anchor + INV-100 step-chain URL truth contract; reserved slots cleared to zero).
|
|
233
|
+
- **v1.26.0**: anti-scraping marathon stability batch (BUG-08, driven by a 3-hour trademark-registry session, doc/bugs/08) — (1) 🔴 **corrective behavior changes (the fake-data face — an order of magnitude more dangerous than crashes)**: navigating to a URL that differs ONLY by hash (SPA `#/search?q=` param change) used to be treated as same-document with no reload — the page kept showing OLD query results under the NEW url (in the field this nearly reported a true value of 3718 as "0, clean"); lasso now detects the shape and reloads on the target hash by default, echoing `same_document_navigated/same_document_reloaded` (opt out with `options.no_reload:true` — annotated, not reloaded; the detection basis is normalized URL comparison via `new URL()` origin+pathname+search — the empty-path-omitted-slash form `http://x#/q=b` IS same-document with `http://x/#/q=a`, which raw string comparison misses and would revive the fake-data shape — sealed in the review round). `evaluate` with a `url` used to silently run on the CURRENT page while final_url echoed the target (fabricated); url now means ensure-navigation (different page → navigate first, then run) and final_url is always real. (2) **long-evaluate stability**: per-call budget `options.budget_ms` (default 120s / `LASSO_EVAL_TIMEOUT_MS` / cap 600s) now reaches the MCP call layer — previously every call fell into the SDK's accidental 60s default, so any >60s batch JS timed out; timeouts are typed `mcp_request_timeout:` + a teaching hint (**the browser is NOT dead** — the upstream mutex wedge self-heals in ~3min); fallback-chain exhaustion errors became primary-first composites (the primary channel's own error leads, last-hop excerpt trails — attribution pollution eliminated). (3) **freshProfile escape hatch**: the only remedy once a site server-side-fingerprints the headless instance (silent zero results) — `options.freshProfile:true` swaps in a whole new coherent identity (throwaway profile dir [owner-anchored name + four cleanup paths, no BUG-03 garbage repeat] + deterministic stealth rotation + full stack respawn; logged_in never supports it). (4) **internal stack governance**: chrome-devtools-mcp stacks now register to a sidecar at spawn and any spawn sweeps orphans first (pid-level merge + triple guard + lstart cross-check — never touches non-lasso processes), ending the marathon "two zombie stacks nobody may touch" deadlock; new admin action `browser_recycle` (the sanctioned in-process restart, never touches detached Chrome). (5) `wait` gains current-page mode (omit url, same session contract as screenshot); `browse_logged_in` auto-discovers the newest non-render ledger port when default 9222 has no CDP (three-layer resolution, result carries `+auto_discovered_port:<port>`; explicit `LASSO_CDP_PORT` always wins); `fetch_url` failures classified (`fetch_failed:dns_failed/connect_refused/connect_timeout/tls_failed/aborted_timeout` — local env vs target refusal now distinguishable). (6) test-infra self-healing (BUG-08 F, the real load-188 incident on the user's machine): the vitest pool is explicitly pinned to threads (main process death = worker threads die with it — the forks-pool orphan class is structurally eliminated) and `npm run gate` gains a timeout kill-belt for the whole vitest tree (fires while the tree root is still alive and SIGKILLs the entire tree; `LASSO_GATE_VITEST_TIMEOUT_MS` tunable; the spawnSync-timeout form was disproven by whitebox experiment E1 — it always misses busy workers; doc/bugs/08 §12). Tests 2895→2997 / invariants 95→96 (INV-96); existing consumers (cc-control / media-gen-mcp) zero breaking.
|
|
233
234
|
- **v1.25.0**: current-page screenshot batch (BUG-07, novel-engine animation-forensics driven) — `action=screenshot` **with url omitted now screenshots the current managed page directly** (the standalone `screenshot` tool gains the same semantics): previously both screenshot paths re-navigated unconditionally, wiping whatever page state evaluate had established (a CSS animation paused mid-frame, injected temporary DOM) — state-sensitive screenshots were unreachable and the consumer had to detour through a second browser-automation stack. Now the same session closes the loop across four channels: open with url → `evaluate` freeze/inject → screenshot without url → `console` forensics. With no active session (cold channel / page closed / healed-over), it errors explicitly with guidance — **never silently opening a browser, never faking state with a blank page**; the old url-bearing behavior is unchanged (pinned by regression anchors); three clean adversarial rounds — 6/6 mutations red + session-drift attacks on live dual channels with zero penetration (concurrent races refused / popup vectors pinned to the managed page / silent page-swap invalidated at the commit point). Upstream research verdict: the industry-universal screenshot semantic IS "capture the current state" — this version realigns lasso with the standard.
|
|
234
235
|
- **v1.24.0**: ghost-instance root-fix batch (BUG-06, driven by a live 12-hour instance) — ① 🔴 **behavior change**: `launch-chrome --idle-ms 0` changes from "never reap" to "**no self-reaping, but a 24-hour hard cap as a safety net**" — a windowless hidden instance can no longer linger indefinitely as an "invisible, uncloseable ghost" (this batch's trigger: a 12-hour instance invisible in the Dock and menu bar with no way to close it). True unlimited now requires the additional explicit `--no-hard-cap` (**double intent** — prevents scripts passing 0 casually); deployments can tune or disable via `LASSO_LAUNCH_HARD_CAP_MS` (`=0` disables entirely); failure direction is always safe (invalid values fall back to capped). Old scripts relying on "0 = forever" should add `--no-hard-cap`. ② **cross-process liveness truth**: before hard-cap reaping, the touch-file heartbeat is consulted (any session / any consumer still using it → no wrongful kill); userTakenAt / visible exemptions carry over natively (re-evaluated at kill time, the race window sealed). ③ **over-age observability**: `doctor` / `chrome-status` warn early on instances past half the hard cap (no new kill surface added). Six live-machine acceptance checks all PASS + two clean adversarial rounds (three mutations all red / wrongful-kill panorama replayed with live stand-in processes, zero casualties / render tier zero cross-contamination).
|
|
235
236
|
- **v1.23.0**: local-file & debugging batch (BUG-05, novel-engine field driven) — ① **`LASSO_ALLOW_FILE_FROM` file:// directory allowlist**: testing local single-file HTML (a staple for offline-artifact acceptance) used to be flat-blocked by the SSRF guard — now, with `LASSO_ALLOW_FILE_FROM=/your/project/dir`, `browse_*` can navigate/snapshot/extract/screenshot local files **inside the designated directory subtree** (still denied by default; zero-config = zero behavior change; `../` traversal, symlink escapes, prefix forgery and trailing-symlink write escapes all sealed — 18 read-side + 10 write-side attack variants, zero escapes); ② new **`console` action**: read the current page's console messages since the last navigation (severity filter + most-recent-N) — no more window.onerror injection detours when debugging rendering defects; ③ **`ignored_options` honesty contract**: options keys you passed that the current action doesn't consume are listed verbatim in the response (never silently dropped — one root cause of the "worked but no screenshot" trap the consumer hit); and to be explicit: navigate-then-screenshot in one step **is already what `action=screenshot` does**; ④ **`LASSO_SCREENSHOT_DIR` screenshot write-root constraint**: custom screenshot output paths are denied by default (arbitrary-write protection), opt-in and confined to the designated subtree. Two clean adversarial rounds: 6/6 mutations killed + proof the core SSRF guard is unweakened + consumer scenario (real single-file HTML over both http and file://) fully verified on a live machine.
|
package/README.md
CHANGED
|
@@ -221,7 +221,7 @@ macOS 上能控 Finder / Mail / Safari / Notes / 系统设置等任何原生 app
|
|
|
221
221
|
|
|
222
222
|
## 安装
|
|
223
223
|
|
|
224
|
-
**当前版本 v1.
|
|
224
|
+
**当前版本 v1.27.0**(更新日志见本节末尾折叠块)。
|
|
225
225
|
|
|
226
226
|
前提:Node.js ≥ 20 + Claude Code(或任何支持 MCP 的客户端)。
|
|
227
227
|
|
|
@@ -236,9 +236,10 @@ claude mcp add lasso -- npx -y lasso-mcp
|
|
|
236
236
|
**给其它 AI 工具当确定性渲染浏览器(渲染档)**:如果你在用 media-gen-mcp 这类要求「同一输入必须产出同一像素」的渲染工具,装好 lasso 后只需一行 `npx -y lasso-mcp render-chrome --ensure`——它会在 9224 端口拉起一个确定性 headless Chrome(冻结旗标快照 + 独立临时 profile),输出消费方直连用的 `wsEndpoint`;**消费方进程被强杀浏览器也照常存活**(生命周期归属 lasso),空闲 10 分钟自动回收并连带清理 profile(`LASSO_RENDER_IDLE_MS` 可调)。配套:`render-chrome --status` 自省 / `--stop` 收尾(认 `LASSO_RENDER_PORT`:显式设 port 只收该 port,未设=全部 render 记录,非法值 exit 1;全局收口仍可用 `chrome-stop --modes render`)/ `render-chrome doctor [--clean]` 孤儿与陈年 profile 清理(默认只报告;认 `LASSO_RENDER_PORT`,同 `--stop`:显式设 port 只判该 port,未设=全扫,非法值 exit 1;touch 心跳 10 分钟内的在用实例豁免不判孤儿)。**同机多 agent 并行验收**(多个 agent 各自清场会互杀对方实例)需配三 env 契命名空间隔离:`LASSO_RENDER_PORT` + `LASSO_LAUNCHED_CHROMES_PATH` + `LASSO_RENDER_GUARDIAN_PID_PATH`,配齐后并行互不可见,配方与清场纪律见 [doc/渲染档-并行验收隔离配方.md](doc/渲染档-并行验收隔离配方.md)。
|
|
237
237
|
|
|
238
238
|
<details>
|
|
239
|
-
<summary>📋 更新日志(v1.8 → v1.
|
|
239
|
+
<summary>📋 更新日志(v1.8 → v1.27.0,点开看每版改了什么)</summary>
|
|
240
240
|
|
|
241
|
-
- **v1.
|
|
241
|
+
- **v1.27.0**(未发版预写——发版归用户指令):反爬根治通道 + url 语义统一批(BUG-09,喵虎核验报告驱动,doc/bugs/09)——① **新工具 `browse_headed`(有头强力档——反爬根治通道)**:针对「无头被站点 JS 层驱逐」类反爬(页面加载 2-3 秒后自己跳走,商标库/查询库形态)的根治层:真实有头 Chrome 窗口(同一上游 chrome-devtools-mcp、只是不带 `--headless`,零新依赖),真机商标站四轮驻留 6/6 存活;stealth 取舍与无头档相反(真实环境即真实指纹,不做注入)。**调用即在你屏幕弹真实窗口**——description 与 hint 都钉死「先获用户明确同意再调」;两态生命周期:未接管 30 分钟 idle 回收(`LASSO_HEADED_IDLE_MS`),你一旦点击聚焦该窗口即标记「已接管」、**永不自动回收**(自己关窗即回收;24h 硬顶 `LASSO_HEADED_HARD_CAP_MS` 是防孤儿舰队的唯一兜底)。② 🔴 **url 语义统一(修正型行为变更——假数据面)**:全部 url 感知 action 收敛为单一规则——**省略 url = 当前页**(无活动会话显式报错,不静默开空白页)/ **url = 当前页 = 零导航直执行**(不再 reload 洗掉 SPA 状态)/ **url ≠ 当前页 = 先导航再执行**;返回体统一新增 `did_navigate:true/false` 如实回显。修复面:`extract`+url 此前会**读会话残留页并伪装成功**(假数据)→ 现在导航后读;`evaluate` 省略 url 此前被拒 → 现在合法(描述承诺兑现);`screenshot`/`pdf`/`network` 传与当前页相同的 url 从 reload 改为跳过(SPA 状态保留)。③ steps 链内 `wait` 条件校验与顶层统一(text/selector/url_contains 三键——此前链内只认 text)。④ steps 链 `outcome:worked` 时瞬态错误不再留在 `error` 字段(迁入新 `warnings[]`;契约固化:worked ⇒ error 必空)。⑤ **breaking(一键可恢复)**:`browse_headless` 失败不再自动回退 `browse_logged_in`(登录态通道必须显式选择;跨通道错误串染曾是马拉松误判根)——配 `LASSO_FALLBACK_CROSS_CHANNEL=1` 恢复旧行为。⑥ `final_url` 剥尾部句读(`.,;:!?`——上游散文句末被吞入的取证定案,括号引号不剥);`lasso doctor` CDP 检查失败明细带当前生效端口。⑦ **WT4 驱逐哨兵(尾款轮,doc/bugs/09 §8.A)**:`browse_headless`/`browse_headed` 的返回体现在可携带 `eviction_suspected:{from,to,at_ms}` + hint——通道层观测到「本 lasso 导航 settle 后页面漂移到异 host」(三信号漏斗:5s 静默窗采样 / 闸门漂移复核 / evaluate 死于 `Execution context was destroyed` ∧ host 偏离的合取 typed error `page_redirect_eviction_suspected:`)即附一次性 advisory 信号(消费方首次能机械区分「我的调用错了」vs「站点杀了无头」);**只供信号绝不自动升级通道**——hint 内钉死「先问用户再转 browse_headed」(弹真实窗口的惊讶面必须经同意);`browse_logged_in` 显式 opt-out(SSO 跨域流转是合法常态,信号在那边纯噪音);⑧ **steps 链回显真值化(修正型消谎)**:链级 `final_url` 此前恒回显请求串(残留页上跑链会谎称目标页)→ 改为链尾真值读(页面真实 href;读不到且无真值种子时省略,**永不回显请求串**)+ 链级 `did_navigate` 如实回显 + 先导导航 same-document 双标注透传——链执行语义零变化(消费方工作流零破坏);⑨ macOS occlusion 真机实验定案(§8):「屏幕外全藏窗口会被系统判 occluded」假设**证伪**(实测恒 visible + rAF 满速),`browse_headed` 窗口默认维持边缘可见 `8,40`(consent 契约与窗口归属锚裁定,零参数变更);测试 2997→3120(192 文件)/ 不变量 96→100 实装(编号至 100——INV-98 驱逐哨兵真锚 + INV-100 steps 链 URL 真值契约,保留位清零)。
|
|
242
|
+
- **v1.26.0**:反爬马拉松稳定性批(BUG-08,3 小时商标库查询实战驱动,doc/bugs/08)——① 🔴 **修正型行为变更(假数据面,比崩溃危险一个数量级)**:`navigate` 到**仅 hash 不同**的 URL(SPA `#/search?q=` 换词)此前按 same-document 处理不重载——页面留旧查询结果、URL 已新词(实战差点把真值 3718 写成 0 条干净);现在默认检测命中即补 reload,回显 `same_document_navigated/same_document_reloaded` 双标注(`options.no_reload:true` opt-out 只标注;判定基为 URL 规范化比较 `new URL()` origin+pathname+search——空路径省略斜杠形态 `http://x#/q=b` 是 `http://x/#/q=a` 的 same-document,raw 串比较会漏检致假数据复活,审查轮已封口)。`evaluate` 传 `url` 此前**静默跑在当前页 + final_url 伪造目标 URL**;现在 url ≠ 当前页先导航再执行(=ensure-navigation),final_url 永远真实。② **长 evaluate 稳定性**:单调用预算 `options.budget_ms`(默认 120s / `LASSO_EVAL_TIMEOUT_MS` 可调 / 上限 600s)传导 MCP 调用层——此前恒落 SDK 60s 缺省事故,>60s 批量 JS 必超时;超时错误类型化 `mcp_request_timeout:` + 教学 hint(**Chrome 没死**,上游互斥锁楔死 ~3min 自愈);全链 fallback 耗尽的错误改为 primary-first 复合串(主通道错误打头,fallback 尾跳摘录在尾——归因污染消灭)。③ **freshProfile 换脸逃生门**:headless 被服务端指纹拉黑(静默假 0)后的唯一解——`options.freshProfile:true` 换完整新一致身份(临时 profile【归属锚目录名+四路清理防 BUG-03 垃圾重演】+ stealth 宿主适用集确定性轮换 + 完整栈 respawn;logged_in 永不支持)。④ **内部栈治理**:chrome-devtools-mcp 栈 spawn 即登记 sidecar、任意 spawn 前孤儿扫除(pid 归并 + 三重守卫 + lstart 交叉核对,绝不触碰非 lasso 进程)——marathon「两代栈并存 + 谁也动不了」死锁根治;admin 新 action `browser_recycle`(内部栈受控重启正门,永不动 detached Chrome)。⑤ `wait` 支持当前页(省 url,与截图同会话契约);`browse_logged_in` 默认 9222 失败时自动发现台账最新非 render 口(三层解析,结果带 `+auto_discovered_port:<port>` 标注;显式 `LASSO_CDP_PORT` 恒赢);`fetch_url` 失败细分(`fetch_failed:dns_failed/connect_refused/connect_timeout/tls_failed/aborted_timeout`——本机环境 vs 目标站拒绝可分辨)。⑥ 测试基建自愈(BUG-08 F,用户实锤负载 188 事故):vitest 池显式钉死 threads(主进程死 = worker 线程随之死,forks 孤儿类结构性消灭)+ `npm run gate` 对 vitest 树的超时追杀带(belt 到点在树根存活时整树 SIGKILL,`LASSO_GATE_VITEST_TIMEOUT_MS` 可调;E1 白盒实锤:spawnSync timeout 形态必漏杀忙 worker,已否决——doc/bugs/08 §12)。测试 2895→2997 / 不变量 95→96(INV-96 五组防线);既有消费方(cc-control / media-gen-mcp)零 breaking。
|
|
242
243
|
- **v1.25.0**:当前页截图批(BUG-07,novel-engine 动画取证驱动)——`action=screenshot` **省略 url 即对当前受管页面直接截屏**(独立 `screenshot` 工具同义):此前两条截图路径都必经重导航,把 evaluate 建立的页面现场(冻结的 CSS 动画中间帧、注入的临时 DOM)全部洗掉——状态敏感截图不可达,消费方被迫借道第二套浏览器栈。现在同会话四通道闭环:带 url 建会话 → `evaluate` 冻结/注入 → 无 url 截当前帧 → `console` 取证。无活动会话(冷通道/页面已关/被自愈换页)显式报错带指引,**绝不静默新开、绝不截空白页伪造状态**;带 url 的旧行为零变化(回归锚钉死);对抗三轮 clean——6 变异全红 + 会话漂移攻击真机双通道零穿透(并发竞态拒/弹窗钉受管页/静默换页 invalidate 封口)。上游调研定谳:截图的业界普适语义就是「截当前状态」——本版把 lasso 对齐回行业标准。
|
|
243
244
|
- **v1.24.0**:幽灵常驻根治批(BUG-06,用户 12 小时实例实锤驱动)——① 🔴 **行为变更**:`launch-chrome --idle-ms 0` 的语义从「永不回收」改为「**不自收,但 24 小时硬顶保命**」——无窗口的隐藏实例从此不可能无限常驻成「看不见也关不掉的幽灵」(本轮用户实锤:一个 12 小时实例,Dock/菜单栏不可见无从关闭)。要真正无限需再显式 `--no-hard-cap`(**双重意图**,防脚本顺手传 0);部署级可用 `LASSO_LAUNCH_HARD_CAP_MS` 调整或 `=0` 全禁;失效方向恒安全(非法值回退有顶)。旧脚本若依赖「0=无限」请加 `--no-hard-cap`。② **跨进程活动真源**:硬顶收割前看 touch 文件心跳(任何会话/任何消费方还在用 → 不误杀);userTakenAt / visible 豁免天然继承(kill 时刻二次重估,竞态窗口封口)。③ **超龄可观测**:`doctor` / `chrome-status` 对过半硬顶的实例提前 warn(不新增任何 kill 面)。真机验收六项全 PASS + 对抗两轮 clean(三变异全红 / 误杀全景真活替身重放零误伤 / 渲染档零交叉)。
|
|
244
245
|
- **v1.23.0**:本地文件与排障能力批(BUG-05,novel-engine 实测驱动)——① **`LASSO_ALLOW_FILE_FROM` file:// 目录白名单**:测本地单文件 HTML(离线产物验收的标配场景)此前被 SSRF 守卫一刀切拦——现在设 `LASSO_ALLOW_FILE_FROM=/你的项目目录` 后 `browse_*` 可导航/快照/抽取/截图**指定目录子树内**的本地文件(默认仍拒、零配置零行为变化;`../` 穿越、symlink 逃逸、目录前缀伪造、末段 symlink 写逃逸全封口——读面 18+写面 10 攻击变体零逃逸);② 新 **`console` action**:直接读当前页自上次导航以来的 console 消息(按严重度过滤 + 最近 N 条)——渲染类缺陷排查不再需要注入 window.onerror 绕路;③ **`ignored_options` 诚实契约**:你传了但当前 action 用不上的 options 键会在响应里如实列出(不再静默丢弃——novel-engine 实测踩到的「worked 但截图没生成」根因之一);顺带明确:navigate+截图一步走**本就是 `action=screenshot` 的行为**(先导航再截图);④ **`LASSO_SCREENSHOT_DIR` 截图写根约束**:自定义截图落盘路径默认拒(防任意写盘),opt-in 且限指定目录子树内。对抗两轮 clean:6 变异全红+SSRF 守卫本体零削弱证明+消费方场景(真实单文件 HTML http/file:// 双路径)真机全通。
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import type { InteractResult } from "../types.js";
|
|
38
38
|
import type { BudgetTracker } from "../fallback/BudgetTracker.js";
|
|
39
|
-
import type { Step, ChainResult } from "./steps-types.js";
|
|
39
|
+
import type { Step, ChainResult, ChainEntryNav } from "./steps-types.js";
|
|
40
40
|
import type { BrowseChannel } from "../channels/BrowseChannel.js";
|
|
41
41
|
/**
|
|
42
42
|
* Phase C 仅声明接口;Phase D 实装 HighRiskGate 时替换为真实 import。
|
|
@@ -99,8 +99,37 @@ export declare class StepEngine {
|
|
|
99
99
|
* - data.actions_and_results: Skyvern 审计链
|
|
100
100
|
* - data.stopped_at: 终止边界(worked 时不填)
|
|
101
101
|
* - data.budget_used_ms: 整 chain 实际耗时
|
|
102
|
+
* - data.final_url: §8.B 种子(等值守卫后;链尾真值读在 channel 层覆盖)
|
|
103
|
+
* - data.did_navigate: §8.B 链级导航回显(entryNav ∨ worked navigate step)
|
|
102
104
|
*/
|
|
103
|
-
runChain(url: string, steps: Step[], onProgress?: ProgressCallback
|
|
105
|
+
runChain(url: string, steps: Step[], onProgress?: ProgressCallback,
|
|
106
|
+
/**
|
|
107
|
+
* §8.B(doc/bugs/09 尾款轮):先导导航透传(browse() steps 分支的
|
|
108
|
+
* action:"navigate" 先导结果——W1-DEF-2b 路径此前直接丢弃)。参与
|
|
109
|
+
* final_url 种子链(等值守卫后)+ 链级 did_navigate 判定。
|
|
110
|
+
*/
|
|
111
|
+
entryNav?: ChainEntryNav): Promise<InteractResult<ChainResult>>;
|
|
112
|
+
/**
|
|
113
|
+
* runChain 实体(§8.B 拆出:外层包装做 did_navigate 后处理——stop() 七个
|
|
114
|
+
* 早退点无需逐点穿参,单一 choke point)。
|
|
115
|
+
*/
|
|
116
|
+
private runChainInner;
|
|
117
|
+
/**
|
|
118
|
+
* 审计行落链前收口:**outcome=worked ⇒ error 必空**(消费方契约)。
|
|
119
|
+
*
|
|
120
|
+
* 背景(喵虎报告 P2-A 现象二):wait 步 `outcome:"worked"` + `expect_check:
|
|
121
|
+
* "verified"` + `error` 非空三字段并存——worked 与 error 语义互斥,消费方
|
|
122
|
+
* 不知道该信哪个。成因:expect verified 把 outcome 升级/保留为 worked 时,
|
|
123
|
+
* handler 的瞬态 error 仍留在行上(:262-266 覆写点只改 outcome)。
|
|
124
|
+
*
|
|
125
|
+
* 处置:瞬态诊断信息不丢弃——非空 error 迁入 `warnings: string[]`,error
|
|
126
|
+
* 字段删除(含空串——契约绝对化)。非 worked 行零动作(didnt/unknown 的
|
|
127
|
+
* error 语义不变)。
|
|
128
|
+
*
|
|
129
|
+
* 单一 choke point:所有落链路径(verified 升级 / handler 直返 worked+error /
|
|
130
|
+
* expectErrored 分支)都调用本方法——同类收口一种做法(R-CI-02)。
|
|
131
|
+
*/
|
|
132
|
+
private normalizeWorkedResult;
|
|
104
133
|
/**
|
|
105
134
|
* @param reason stopped_at.reason
|
|
106
135
|
* @param idx step_index(当前 step 索引)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StepEngine.d.ts","sourceRoot":"","sources":["../../src/browse/StepEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EACV,IAAI,EAGJ,WAAW,
|
|
1
|
+
{"version":3,"file":"StepEngine.d.ts","sourceRoot":"","sources":["../../src/browse/StepEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EACV,IAAI,EAGJ,WAAW,EACX,aAAa,EACd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAKlE;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3F;AAKD;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;AAK9D;;;;;;;;;GASG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,kDAAkD;IAClD,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAHZ,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,aAAa;IACtC,kDAAkD;IACjC,YAAY,GAAE,gBAAgB,GAAG,IAAW;IAM/D;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,QAAQ,CACZ,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,EAAE,EACb,UAAU,CAAC,EAAE,gBAAgB;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;IAgBvC;;;OAGG;YACW,aAAa;IA8P3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,qBAAqB;IAY7B;;;;;;OAMG;IACH,OAAO,CAAC,IAAI;CA+Bb"}
|