forked from vercel-labs/agent-browser
-
Notifications
You must be signed in to change notification settings - Fork 0
Compile the browser-automation core for wasm32: lib/bin split, rt abstraction, injected CDP transport, embedding seams #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
3f0749c
refactor: split crate into lib and bin
devin-ai-integration[bot] 878e421
feat: add rt module abstracting task spawning and timers over tokio/wasm
devin-ai-integration[bot] 376604c
feat: inject CDP transport behind CdpTransportSink so non-native host…
devin-ai-integration[bot] dbef264
feat: gate native-only modules and dependencies for wasm32 target
devin-ai-integration[bot] 40c5b03
chore: add Default impls to satisfy clippy on the new lib target
devin-ai-integration[bot] efce6ab
fix: make run_read native-only and track wasm task completion
devin-ai-integration[bot] 7850bbd
refactor: keep tokio in test modules and native-only code, use rt onl…
devin-ai-integration[bot] dfa0536
feat: add BrowserManager::from_client for injected CDP transports
devin-ai-integration[bot] 3c715a9
feat: buffer CLI output behind a capture seam for library hosts
devin-ai-integration[bot] 1be33dd
feat: route artifact writes through a pluggable artifact writer
devin-ai-integration[bot] b1dd1a2
fix: make gen_id use js time on wasm32 where SystemTime panics
devin-ai-integration[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| //! Pluggable artifact persistence. Commands that produce files (screenshots, | ||
| //! PDFs, HARs, diffs) write through [`write`] so library hosts without a real | ||
| //! filesystem (e.g. wasm) can install their own writer via | ||
| //! [`set_artifact_writer`]. When no writer is installed, [`write`] falls back | ||
| //! to `std::fs::write`, preserving native CLI behavior. | ||
|
|
||
| #[cfg(not(target_arch = "wasm32"))] | ||
| mod imp { | ||
| use std::sync::OnceLock; | ||
|
|
||
| pub type ArtifactWriter = Box<dyn Fn(&str, &[u8]) -> Result<(), String> + Send + Sync>; | ||
|
|
||
| static WRITER: OnceLock<ArtifactWriter> = OnceLock::new(); | ||
|
|
||
| /// Install a process-global artifact writer. Returns an error if a writer | ||
| /// was already installed. | ||
| pub fn set_artifact_writer(writer: ArtifactWriter) -> Result<(), String> { | ||
| WRITER | ||
| .set(writer) | ||
| .map_err(|_| "artifact writer already installed".to_string()) | ||
| } | ||
|
|
||
| pub fn write(path: &str, bytes: &[u8]) -> Result<(), String> { | ||
| if let Some(writer) = WRITER.get() { | ||
| return writer(path, bytes); | ||
| } | ||
| std::fs::write(path, bytes).map_err(|e| format!("Failed to write {}: {}", path, e)) | ||
| } | ||
| } | ||
|
|
||
| #[cfg(target_arch = "wasm32")] | ||
| mod imp { | ||
| use std::cell::RefCell; | ||
|
|
||
| pub type ArtifactWriter = Box<dyn Fn(&str, &[u8]) -> Result<(), String>>; | ||
|
|
||
| thread_local! { | ||
| static WRITER: RefCell<Option<ArtifactWriter>> = const { RefCell::new(None) }; | ||
| } | ||
|
|
||
| /// Install a process-global artifact writer. Returns an error if a writer | ||
| /// was already installed. | ||
| pub fn set_artifact_writer(writer: ArtifactWriter) -> Result<(), String> { | ||
| WRITER.with(|w| { | ||
| let mut slot = w.borrow_mut(); | ||
| if slot.is_some() { | ||
| return Err("artifact writer already installed".to_string()); | ||
| } | ||
| *slot = Some(writer); | ||
| Ok(()) | ||
| }) | ||
| } | ||
|
|
||
| pub fn write(path: &str, bytes: &[u8]) -> Result<(), String> { | ||
| WRITER.with(|w| match w.borrow().as_ref() { | ||
| Some(writer) => writer(path, bytes), | ||
| None => Err(format!( | ||
| "cannot write {}: no artifact writer installed on this platform", | ||
| path | ||
| )), | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| pub use imp::{set_artifact_writer, write, ArtifactWriter}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| pub mod artifacts; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| pub mod chat; | ||
| pub mod color; | ||
| pub mod commands; | ||
| pub mod connection; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| pub mod doctor; | ||
| pub mod flags; | ||
| pub mod install; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| pub mod mcp; | ||
| pub mod native; | ||
| pub mod output; | ||
| pub mod plugins; | ||
| pub mod read; | ||
| pub mod rt; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| pub mod skills; | ||
| #[cfg(test)] | ||
| pub mod test_utils; | ||
| #[cfg(not(target_arch = "wasm32"))] | ||
| pub mod upgrade; | ||
| pub mod validation; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🟨 wasm reqwest client drops rustls-webpki-roots feature used on native
The new wasm dependency block configures
reqwestwithout therustls-tls-webpki-rootsfeature that the native block keeps (cli/Cargo.toml:38vscli/Cargo.toml:46). On wasm32 reqwest delegates TLS to the host fetch implementation, so this is not directly exploitable, but the asymmetry means any future non-browser wasm host would get a reqwest build with no configured trust anchors rather than the pinned webpki root set the native build relies on.Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentional: on wasm32 reqwest uses the browser/host
fetchbackend and delegates TLS entirely to the host, sorustls-tls-webpki-rootshas no effect there — and the rustls/ring stack it pulls in does not build forwasm32-unknown-unknown. Enabling it in the wasm block would break the wasm build without adding any trust-anchor behavior. Noted the rationale in the PR description.