12 Commits
Author SHA1 Message Date
github-actions[bot]andGitHub bd8134672b chore(deps): update module golang.org/x/net to v0.60.0
Automated dependency update. All tests passed.
2026-10-11 03:24:21 +00:00
github-actions[bot]andGitHub 9aeb97fed2 chore(deps): update dependencies
Automated dependency update. All tests passed.
2026-10-10 03:22:54 +00:00
github-actions[bot]andGitHub abbc0727c2 chore(deps): update chromedp
Automated dependency update. All tests passed.
2026-10-08 03:23:24 +00:00
github-actions[bot]andGitHub d98a395576 chore(deps): update module github.com/chromedp/cdproto to v0.157.6
Automated dependency update. All tests passed.
2026-10-07 03:23:24 +00:00
github-actions[bot]andGitHub 8c5c556b03 chore(deps): update module github.com/chromedp/cdproto to v0.157.5
Automated dependency update. All tests passed.
2026-10-06 03:21:16 +00:00
lukaszraczylo 3dee25379d fix(ci): run the workflows on Go 1.27 to match go.mod 2026-10-05 11:17:07 +01:00
lukaszraczylo 956aa3c0cb fix(deps): migrate to chromedp 0.19 and drop the cdproto replace
Update chromedp to v0.19.1 and cdproto to v0.157.4, port the browser, reader and login code to the generic Action API, group both modules in Renovate, and move the Docker build to Go 1.27.
2026-10-05 10:32:22 +01:00
github-actions[bot]andGitHub 5d945156ba chore(deps): update dependencies
Automated dependency update. All tests passed.
2026-10-04 04:19:47 +00:00
lukaszraczylo a3657211ea ci(release): publish the readitall cask to the Homebrew tap
Add a homebrew_casks block that writes the cask to
lukaszraczylo/homebrew-taps. The release workflow must have the
HOMEBREW_TAP_TOKEN secret.
2026-10-03 23:11:35 +01:00
lukaszraczylo 078c1f59fb ci(deps): update dependencies with Renovate [skip ci] 2026-10-03 18:44:51 +01:00
b481e3c53b Update go.mod and go.sum (#2)
Co-authored-by: lukaszraczylo <[email protected]>
2026-10-03 11:02:39 +00:00
lukaszraczylo 35ecb8e8b7 fix(deps): hold cdproto back
The cdproto v0.157 tag removes input constants that chromedp v0.16 uses, so the dependency update failed to compile. Pin cdproto to the version chromedp v0.16 requires.
2026-10-03 04:45:03 +01:00
13 changed files with 125 additions and 141 deletions
+8 -8
View File
@@ -1,4 +1,4 @@
name: Autoupdate go.mod and go.sum
name: Update dependencies
on:
workflow_dispatch:
@@ -6,15 +6,15 @@ on:
- cron: "0 3 * * *"
permissions:
contents: write
actions: write
contents: write
issues: write
pull-requests: write
security-events: write
jobs:
autoupdate:
uses: lukaszraczylo/shared-actions/.github/workflows/go-autoupdate.yaml@main
update:
uses: lukaszraczylo/shared-actions/.github/workflows/renovate-autoupdate.yaml@main
with:
go-version: ">=1.26"
release-workflow: "release.yaml"
secrets: inherit
go-version: ">=1.27"
node: false
release-workflow: release.yaml
+1 -1
View File
@@ -19,4 +19,4 @@ jobs:
pr-checks:
uses: lukaszraczylo/shared-actions/.github/workflows/go-pr.yaml@main
with:
go-version: ">=1.26"
go-version: ">=1.27"
+1 -1
View File
@@ -19,5 +19,5 @@ jobs:
release:
uses: lukaszraczylo/shared-actions/.github/workflows/go-release.yaml@main
with:
go-version: ">=1.26"
go-version: ">=1.27"
secrets: inherit
+18
View File
@@ -49,6 +49,24 @@ release:
draft: false
prerelease: auto
homebrew_casks:
- name: readitall
repository:
owner: lukaszraczylo
name: homebrew-taps
token: "{{ .Env.HOMEBREW_TAP_TOKEN }}"
directory: Casks
homepage: https://github.com/lukaszraczylo/mcp-readitall
description: "MCP server that reads web pages through a headless Chromium-family browser"
license: MIT
hooks:
post:
install: |
if OS.mac?
system_command "/usr/bin/xattr",
args: ["-dr", "com.apple.quarantine", "#{staged_path}/readitall"]
end
signs:
- cmd: cosign
signature: "${artifact}.sigstore.json"
+1 -1
View File
@@ -1,5 +1,5 @@
# Build stage
FROM golang:1.26-alpine AS build
FROM golang:1.27-alpine AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download
+13 -21
View File
@@ -1,34 +1,26 @@
module github.com/lukaszraczylo/mcp-readitall
go 1.26.4
go 1.27
require (
github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2
github.com/chromedp/cdproto v0.0.0-20260321001828-e3e3800016bc
github.com/chromedp/chromedp v0.15.1
github.com/modelcontextprotocol/go-sdk v1.6.1
github.com/stretchr/testify v1.11.1
github.com/chromedp/cdproto v0.157.9
github.com/chromedp/chromedp v0.20.1
github.com/modelcontextprotocol/go-sdk v1.8.0
github.com/stretchr/testify v1.12.1
)
require (
github.com/JohannesKaufmann/dom v0.3.1 // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.4.0 // indirect
github.com/go-json-experiment/json v0.0.0-20260213210345-44df1a37e875 // indirect
github.com/google/jsonschema-go v0.4.3 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
github.com/segmentio/asm v1.1.3 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/segmentio/encoding v0.5.4 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
golang.org/x/net v0.55.0 // indirect
golang.org/x/oauth2 v0.35.0 // indirect
golang.org/x/sys v0.45.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/net v0.60.0 // indirect
golang.org/x/oauth2 v0.37.0 // indirect
golang.org/x/sync v0.24.0 // indirect
golang.org/x/sys v0.49.0 // indirect
golang.org/x/time v0.16.0 // indirect
)
+24 -50
View File
@@ -2,73 +2,47 @@ github.com/JohannesKaufmann/dom v0.3.1 h1:J16l9JAHWgkFPR3VIPbQ1gvS0cWab6laK1q7PF
github.com/JohannesKaufmann/dom v0.3.1/go.mod h1:BZPkf8ZeYrBgABjwJn9iiKt8aiCtkxpHkevms+Yp2DE=
github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2 h1:XFJZFWESIWlUEHHjzBuv8RvrtCWnSGlimEX17ysSDb8=
github.com/JohannesKaufmann/html-to-markdown/v2 v2.5.2/go.mod h1:BHWO8lJzttJLqwuV8Rb1B3OG2OSzLbssZDI1FRg2eAA=
github.com/chromedp/cdproto v0.0.0-20260321001828-e3e3800016bc h1:wkN/LMi5vc60pBRWx6qpbk/aEvq3/ZVNpnMvsw8PVVU=
github.com/chromedp/cdproto v0.0.0-20260321001828-e3e3800016bc/go.mod h1:cbyjALe67vDvlvdiG9369P8w5U2w6IshwtyD2f2Tvag=
github.com/chromedp/chromedp v0.15.1 h1:EJWiPm7BNqDqjYy6U0lTSL5wNH+iNt9GjC3a4gfjNyQ=
github.com/chromedp/chromedp v0.15.1/go.mod h1:CdTHtUqD/dqaFw/cvFWtTydoEQS44wLBuwbMR9EkOY4=
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433 h1:vymEbVwYFP/L05h5TKQxvkXoKxNvTpjxYKdF1Nlwuao=
github.com/go-json-experiment/json v0.0.0-20260214004413-d219187c3433/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
github.com/chromedp/cdproto v0.157.9 h1:ICBpkCmLcbma7m0ImhsQLoTGgrJwYsKcoIs55AZ35N0=
github.com/chromedp/cdproto v0.157.9/go.mod h1:h68JaIuFr9o3yiayxEYhBdvaxgYO3shDrPSYhNlyfu0=
github.com/chromedp/chromedp v0.20.1 h1:983T9wmyM09JtROWlxhLQwljKOQovqt8CVE89W3U0NA=
github.com/chromedp/chromedp v0.20.1/go.mod h1:6z1Y5FdKUxRzxx2qcC5h1xjaBJrSWrZp1mjgITfNZig=
github.com/go-json-experiment/json v0.0.0-20260213210345-44df1a37e875 h1:XGPtjxqp0FS8jj1Z7QGcSOSgyq1fUPjNyJXvi3KfI4A=
github.com/go-json-experiment/json v0.0.0-20260213210345-44df1a37e875/go.mod h1:uNVvRXArCGbZ508SxYYTC5v1JWoz2voff5pm25jU1Ok=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/modelcontextprotocol/go-sdk v1.6.1 h1:0zOSupjKUxPKSocPT1Wtago+mUHU2/uZ4xSOY0FGReU=
github.com/modelcontextprotocol/go-sdk v1.6.1/go.mod h1:kzm3kzFL1/+AziGOE0nUs3gvPoNxMCvkxokMkuFapXQ=
github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785 h1:J1//5K/6QF10cZ59zLcVNFGmBfiSrH8Cho/lNrViK9s=
github.com/orisano/pixelmatch v0.0.0-20230914042517-fa304d1dc785/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/modelcontextprotocol/go-sdk v1.8.0 h1:KIvahhYqwtbeniWVPs3TcXEA7b8jEtwfBpOTAI+Urx4=
github.com/modelcontextprotocol/go-sdk v1.8.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/sebdah/goldie/v2 v2.8.0 h1:dZb9wR8q5++oplmEiJT+U/5KyotVD+HNGCAc5gNr8rc=
github.com/sebdah/goldie/v2 v2.8.0/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=
github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=
github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE=
github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/net v0.60.0 h1:79p50tfZlm0J9YfoDsSi639qSXNGVwEzOPLCxM2FsYU=
golang.org/x/net v0.60.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=
golang.org/x/oauth2 v0.37.0 h1:JUlcxA8oAtauLfiH8FX2/FkAWHAdi0QtGCGc+hofE98=
golang.org/x/oauth2 v0.37.0/go.mod h1:IxwZNxUULJmpBFf9K/9NTMSIfZZuvuTy1gGxhigP/58=
golang.org/x/sync v0.24.0 h1:iqiDrGoDgyuvAKrhLQthUEzU/R378N78gXbBjxed7oA=
golang.org/x/sync v0.24.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=
golang.org/x/sys v0.49.0 h1:XbzkgYJHdqh/8m2Uu0W/dQv8nktxx4BFHp1M0gROTXA=
golang.org/x/sys v0.49.0/go.mod h1:hNLxWAXmnKAxqDtdwIYC4bM9oQPEecfsnNMuSxOs3og=
golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=
golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+3 -5
View File
@@ -66,7 +66,7 @@ func (b *Browser) ensureAllocator() (context.Context, error) {
b.allocCtx, b.allocCancel = chromedp.NewExecAllocator(context.Background(), opts...)
browserCtx, cancel := chromedp.NewContext(b.allocCtx)
if err := chromedp.Run(browserCtx, chromedp.Navigate("about:blank")); err != nil {
if err := chromedp.Do(browserCtx, chromedp.Navigate("about:blank")); err != nil {
b.startErr = fmt.Errorf("warm up browser: %w", err)
cancel()
return
@@ -144,10 +144,8 @@ func (b *Browser) NewContext(parentCtx context.Context, statePath string) (conte
// the first step of a fresh login (otherwise stale session cookies from
// a previous attempt can mask the new login's success).
func ClearAllCookies(ctx context.Context) error {
return chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error {
target := chromedp.FromContext(ctx).Target
return network.ClearBrowserCookies().Do(cdp.WithExecutor(ctx, target))
}))
_, err := chromedp.Call(ctx, network.ClearBrowserCookies, cdp.Empty{})
return err
}
// NewHeadedContext spawns a *separate* Chromium process with a visible
+18 -25
View File
@@ -7,7 +7,6 @@ import (
"net/url"
"os"
"strings"
"time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/cdproto/network"
@@ -76,10 +75,8 @@ func ApplyStorageStateCookies(ctx context.Context, statePath string) error {
return nil
}
return chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error {
target := chromedp.FromContext(ctx).Target
return network.SetCookies(cookies).Do(cdp.WithExecutor(ctx, target))
}))
_, err = chromedp.Call(ctx, network.SetCookies, network.SetCookiesParams{Cookies: cookies})
return err
}
// ApplyLocalStorageOnCurrentOrigin sets every localStorage entry that
@@ -99,8 +96,8 @@ func ApplyLocalStorageOnCurrentOrigin(ctx context.Context, statePath string) err
return nil
}
var currentURL string
if err := chromedp.Run(ctx, chromedp.Location(&currentURL)); err != nil {
currentURL, err := chromedp.Run(ctx, chromedp.Location())
if err != nil {
return fmt.Errorf("read current origin: %w", err)
}
currentOrigin := normalizeOrigin(currentURL)
@@ -123,7 +120,8 @@ func ApplyLocalStorageOnCurrentOrigin(ctx context.Context, statePath string) err
return nil
}
return chromedp.Run(ctx, chromedp.Evaluate(buildLocalStorageScript(entries), nil))
_, err = chromedp.Run(ctx, chromedp.Evaluate[chromedp.Void](buildLocalStorageScript(entries)))
return err
}
// CaptureStorageState reads every cookie set on the current target and
@@ -138,8 +136,8 @@ func CaptureStorageState(ctx context.Context, statePath string) error {
}
// 2) Current origin + localStorage
var currentURL string
if err := chromedp.Run(ctx, chromedp.Location(&currentURL)); err != nil {
currentURL, err := chromedp.Run(ctx, chromedp.Location())
if err != nil {
return fmt.Errorf("read location: %w", err)
}
origin := normalizeOrigin(currentURL)
@@ -182,14 +180,11 @@ func CaptureStorageState(ctx context.Context, statePath string) error {
// captureCDPCookies asks the current target for its full cookie list via
// the network domain.
func captureCDPCookies(ctx context.Context) ([]*network.Cookie, error) {
var out []*network.Cookie
err := chromedp.Run(ctx, chromedp.ActionFunc(func(ctx context.Context) error {
target := chromedp.FromContext(ctx).Target
var err error
out, err = network.GetCookies().Do(cdp.WithExecutor(ctx, target))
return err
}))
return out, err
res, err := chromedp.Call(ctx, network.GetCookies, network.GetCookiesParams{})
if err != nil {
return nil, err
}
return res.Cookies, nil
}
// captureLocalStorage serialises the current page's localStorage to a
@@ -200,8 +195,8 @@ func captureLocalStorage(ctx context.Context, origin string) (json.RawMessage, e
return nil, nil
}
const script = `JSON.stringify(Object.fromEntries(Object.keys(localStorage).map(function(k){return [k, localStorage.getItem(k)];})))`
var lsJSON string
if err := chromedp.Run(ctx, chromedp.Evaluate(script, &lsJSON)); err != nil {
lsJSON, err := chromedp.Run(ctx, chromedp.Evaluate[string](script))
if err != nil {
return nil, err
}
if lsJSON == "" || lsJSON == "[]" || lsJSON == "{}" {
@@ -257,9 +252,8 @@ type onDiskCookie struct {
}
// onDiskToCookieParam converts our on-disk shape into a CDP
// network.CookieParam. Session cookies (Expires <= 0) get a nil Expires
// pointer; persistent cookies get a *cdp.TimeSinceEpoch built from the
// Unix timestamp.
// network.CookieParam. Session cookies (Expires <= 0) keep a zero Expires;
// persistent cookies get a cdp.TimeSinceEpoch built from the Unix timestamp.
func onDiskToCookieParam(c onDiskCookie) *network.CookieParam {
p := &network.CookieParam{
Name: c.Name,
@@ -271,8 +265,7 @@ func onDiskToCookieParam(c onDiskCookie) *network.CookieParam {
SameSite: parseSameSite(c.SameSite),
}
if c.Expires > 0 {
t := cdp.TimeSinceEpoch(time.Unix(int64(c.Expires), 0))
p.Expires = &t
p.Expires = cdp.TimeSinceEpoch(float64(int64(c.Expires)))
}
return p
}
+6 -7
View File
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/chromedp"
)
@@ -13,8 +12,8 @@ import (
// a separate chromedp.Run so a slow extraction does not re-do navigation.
func (r *Reader) extractHTML(ctx context.Context, selector string) (string, error) {
if selector == "" {
var html string
if err := chromedp.Run(ctx, chromedp.OuterHTML("html", &html, chromedp.ByQuery)); err != nil {
html, err := chromedp.Run(ctx, chromedp.OuterHTML(chromedp.CSS("html")))
if err != nil {
return "", fmt.Errorf("read document: %w", err)
}
return html, nil
@@ -22,16 +21,16 @@ func (r *Reader) extractHTML(ctx context.Context, selector string) (string, erro
// Verify the selector matches at least one node; an empty result is
// almost always a caller mistake, not an empty page.
var nodes []*cdp.Node
if err := chromedp.Run(ctx, chromedp.Nodes(selector, &nodes, chromedp.ByQuery)); err != nil {
nodes, err := chromedp.Run(ctx, chromedp.Nodes(chromedp.CSS(selector)))
if err != nil {
return "", fmt.Errorf("locate %q: %w", selector, err)
}
if len(nodes) == 0 {
return "", fmt.Errorf("selector %q matched no elements", selector)
}
var html string
if err := chromedp.Run(ctx, chromedp.OuterHTML(selector, &html, chromedp.ByQuery)); err != nil {
html, err := chromedp.Run(ctx, chromedp.OuterHTML(chromedp.CSS(selector)))
if err != nil {
return "", fmt.Errorf("extract %q: %w", selector, err)
}
return html, nil
+11 -8
View File
@@ -94,12 +94,12 @@ func (r *Reader) Read(parentCtx context.Context, opts ReadOptions) (*ReadResult,
// Build the action chain. Cookies were already applied by NewContext
// (if a session exists). localStorage is applied post-navigation
// because it is origin-scoped.
actions := []chromedp.Action{
actions := []chromedp.Action[chromedp.Void]{
chromedp.Navigate(opts.URL),
chromedp.WaitReady("body"),
}
if statePath != "" {
actions = append(actions, chromedp.ActionFunc(func(ctx context.Context) error {
actions = append(actions, chromedp.Func(func(ctx context.Context, _ *chromedp.Target) error {
return browser.ApplyLocalStorageOnCurrentOrigin(ctx, statePath)
}))
}
@@ -109,14 +109,17 @@ func (r *Reader) Read(parentCtx context.Context, opts ReadOptions) (*ReadResult,
chromedp.Sleep(500*time.Millisecond),
)
if opts.WaitSelector != "" {
actions = append(actions, chromedp.WaitVisible(opts.WaitSelector, chromedp.ByQuery))
actions = append(actions, chromedp.WaitVisible(chromedp.CSS(opts.WaitSelector)))
}
actions = append(actions,
chromedp.Title(&title),
chromedp.Location(&finalURL),
)
actions = append(actions, chromedp.Func(func(ctx context.Context, t *chromedp.Target) (err error) {
if title, err = chromedp.Title()(ctx, t); err != nil {
return err
}
finalURL, err = chromedp.Location()(ctx, t)
return err
}))
if err := chromedp.Run(cdpCtx, actions...); err != nil {
if err := chromedp.Do(cdpCtx, actions...); err != nil {
return nil, fmt.Errorf("navigate: %w", err)
}
+10 -14
View File
@@ -8,7 +8,6 @@ import (
"strings"
"time"
"github.com/chromedp/cdproto/cdp"
"github.com/chromedp/chromedp"
"github.com/lukaszraczylo/mcp-readitall/internal/browser"
"github.com/modelcontextprotocol/go-sdk/mcp"
@@ -78,11 +77,9 @@ func RegisterLogin(s *mcp.Server, pw *browser.Browser, sess *browser.SessionStor
return nil, LoginOutput{}, fmt.Errorf("clear cookies: %w", err)
}
var title string
if err := chromedp.Run(browserCtx,
if err := chromedp.Do(browserCtx,
chromedp.Navigate(in.URL),
chromedp.WaitReady("body"),
chromedp.Title(&title),
); err != nil {
return nil, LoginOutput{}, fmt.Errorf("navigate: %w", err)
}
@@ -146,8 +143,8 @@ func waitForLogin(ctx context.Context, pageCtx context.Context, in LoginInput, t
check := func() (bool, error) {
if in.SuccessURL != "" {
var current string
if err := chromedp.Run(pageCtx, chromedp.Location(&current)); err != nil {
current, err := chromedp.Run(pageCtx, chromedp.Location())
if err != nil {
return false, err
}
if strings.Contains(current, in.SuccessURL) {
@@ -155,16 +152,15 @@ func waitForLogin(ctx context.Context, pageCtx context.Context, in LoginInput, t
}
}
if in.SuccessSelector != "" {
var nodes []*cdp.Node
if err := chromedp.Run(pageCtx, chromedp.Nodes(in.SuccessSelector, &nodes, chromedp.ByQuery)); err != nil {
nodes, err := chromedp.Run(pageCtx, chromedp.Nodes(chromedp.CSS(in.SuccessSelector)))
if err != nil {
return false, err
}
if len(nodes) > 0 {
var visible bool
if err := chromedp.Run(pageCtx, chromedp.Evaluate(
visible, err := chromedp.Run(pageCtx, chromedp.Evaluate[bool](
`(()=>{const e=document.querySelector(`+jsQuote(in.SuccessSelector)+`);return !!e && e.getBoundingClientRect().height>0;})()`,
&visible,
)); err != nil {
))
if err != nil {
return false, err
}
if visible {
@@ -205,8 +201,8 @@ func waitForLogin(ctx context.Context, pageCtx context.Context, in LoginInput, t
// currentLocation returns the page's current URL or "" if the query
// fails (e.g. the browser has already been torn down).
func currentLocation(ctx context.Context) string {
var s string
if err := chromedp.Run(ctx, chromedp.Location(&s)); err != nil {
s, err := chromedp.Run(ctx, chromedp.Location())
if err != nil {
return ""
}
return s
+11
View File
@@ -0,0 +1,11 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"packageRules": [
{
"description": "chromedp pins an exact cdproto; bump them together",
"matchManagers": ["gomod"],
"matchPackageNames": ["github.com/chromedp/chromedp", "github.com/chromedp/cdproto"],
"groupName": "chromedp"
}
]
}