Skip to content

feat: user-facing local file support for open/load (PulsarSession + CLI) #573

Description

@platonai

Summary

PulsarSession.open/normalize/load already support local files, but only through an undocumented internal pseudo-URL: http://localfile.internal?path=<base64url(path)>, produced by URLUtils.pathToLocalURL(Path). There is no user-facing API overload or CLI flag, the docs never mention it, and several edges are fragile.

Current behavior (verified)

Input Result
http://localfile.internal?path=<base64> (from URLUtils.pathToLocalURL) Works end-to-end: session.load(url, "-refresh"), open, and loadDocument load the file through PulsarWebDriver.navigate -> openLocalFile -> Path.toUri() -> Page.navigate(file://...)
file:///abs/path.html normalize accepts it, but isStandard(file://) is false (OkHttp-based) and the driver does not use the localfile branch; it only works "by accident" for simple HTML
C:\x\a.html, /tmp/a.html, ./a.html Not supported: AbstractPulsarContext.normalize treats non-:// strings as base64 or falls back to the default search engine; load then throws on the NIL URL
-ignoreQuery + localfile pseudo-URL Breaks: normalize(..., ignoreUrlQuery=true) strips ?path=..., then localURLToPath throws Missing query parameter 'path'

Pain points

  1. No user-facing entry point: PulsarSession has no Path/File overload, and the CLI open <url> passes the URL through verbatim, so users must hand-construct the base64 pseudo-URL to load a local file.
  2. Undocumented: no mention in skills/browser4-cli/SKILL.md, CLI help, or docs/; only integration tests reference pathToLocalURL.
  3. Fragile edges: the -ignoreQuery conflict, half-supported file://, and raw paths silently becoming search-engine queries.

Proposed scope

  • API: add PulsarSession.openFile(Path) / loadFile(Path, args) overloads that auto-convert via pathToLocalURL.
  • CLI: open/navigate auto-detect an existing local path (or add --file <path>) and build the pseudo-URL.
  • Normalization: preserve the path query parameter for localfile.internal when ignoreUrlQuery is set (or move the encoded path into the URL path segment).
  • Optionally: recognize file:// in the driver's local-file branch so it behaves identically to the pseudo-URL.
  • Docs: document supported forms and pitfalls in skills/browser4-cli/SKILL.md, CLI help, and docs/.
  • Tests: unit tests for normalize with pseudo-URLs and -ignoreQuery; e2e coverage for the CLI entry.
  • Security: if exposed to agentic/MCP calls, consider a workspace whitelist; note that ActionValidator currently allows only http/https and would block file:// once wired.

References

  • AbstractPulsarContext.normalize (base64/search fallback): browser4-core/browser4-skeleton/src/main/kotlin/ai/platon/pulsar/skeleton/context/support/AbstractPulsarContext.kt
  • CombinedUrlNormalizer: browser4-core/browser4-skeleton/src/main/kotlin/ai/platon/pulsar/skeleton/common/urls/CombinedUrlNormalizer.kt
  • Driver local-file branch: pulsar-browser dependency (PulsarWebDriver.navigateInvaded -> openLocalFile); BrowserEmulatorImplBase.kt special-cases localfile.internal
  • Existing test: browser4-tests/pulsar-it-tests/src/test/kotlin/ai/platon/pulsar/basic/session/PulsarSessionTests.kt (testLoadLocalFile)
  • CLI open: cli/browser4-cli/src/commands.rs

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions