mirror of
https://github.com/lukaszraczylo/mcp-readitall.git
synced 2026-10-12 00:45:33 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd8134672b | ||
|
|
9aeb97fed2 | ||
|
|
abbc0727c2 | ||
|
|
d98a395576 | ||
|
|
8c5c556b03 | ||
|
|
3dee25379d | ||
|
|
956aa3c0cb | ||
|
|
5d945156ba | ||
|
|
a3657211ea | ||
|
|
078c1f59fb | ||
|
|
b481e3c53b | ||
|
|
35ecb8e8b7 |
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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
@@ -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(¤tURL)); 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(¤tURL)); 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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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(¤t)); 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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user