Commit Graph
63 Commits
Author SHA1 Message Date
Chris Tate c00dd44750 fix: improve daemon startup error handling and diagnostics (#337)
* fixes

* add debugging
2026-02-02 13:47:15 -06:00
Li Yang e831b07f47 chore(cli): save screenshots to tmp dir when no path provided (#247)
* fix(cli): save screenshots to tmp dir when no path provided

Instead of outputting base64 to stdout (which is not useful for most CLI use cases),
screenshots without a path now save to ~/.agent-browser/tmp/screenshots/ with a
generated filename and return the path.

This makes the behavior more ergonomic for AI agents and CLI users alike.

* cleanup

* cleanup

* just revert the cargo.lock version for now

* refactor: extract getAppDir() from getSocketDir()

* docs: improve screenshot help text consistency
2026-01-26 09:08:39 -06:00
Chris Tate 1b26ff886c Fix tab list command not recognizing new pages opened via clicks (#275)
## Summary

Fixed an issue where the `tab list` command couldn't recognize new pages that were opened externally (e.g., via `target="_blank"` links or popup windows). The problem occurred because context-level page tracking wasn't properly set up for all browser launch methods, causing new pages created outside of explicit `newTab()` calls to go untracked.

## Changes

- Added `setupContextTracking(context)` calls to `launch()`, `launchIncognito()`, and other context creation methods to ensure all contexts listen for new page events
- Added duplicate page checks (`!this.pages.includes(page)`) in `setupContextTracking()`, `newTab()`, and `launchIncognito()` to prevent the same page from being tracked multiple times
- Fixed `activePageIndex` calculation in `launch()` to properly set the active page index
- Enhanced comments to clarify that `setupContextTracking()` handles externally created pages (popups, new tabs from links)

## Implementation Details

The fix ensures that when a user clicks an element that opens a new tab/window, the browser context's 'page' event listener will automatically detect and track the new page. The duplicate prevention logic handles cases where both the context listener and manual page creation might try to add the same page.

Fixes #273
2026-01-26 01:25:49 -06:00
Chris Tate f862e2f7df Security: Reject cross-origin connections to daemon and stream server (#274) 2026-01-26 00:42:00 -06:00
RafaelandClaude Opus 4.5 fcee8f70d1 feat: add Kernel as cloud browser provider (#200)
Add Kernel (https://kernel.sh) as a third-party cloud browser provider,
following the same pattern as Browserbase and Browser Use integrations.

Features:
- Launch browser with `-p kernel` flag or `AGENT_BROWSER_PROVIDER=kernel`
- Configurable via environment variables:
  - KERNEL_API_KEY (required)
  - KERNEL_HEADLESS (default: false)
  - KERNEL_STEALTH (default: true)
  - KERNEL_TIMEOUT_SECONDS (default: 300)
  - KERNEL_PROFILE_NAME (optional, for persistent sessions)
- Profile find-or-create: automatically creates profile if it doesn't exist
- Profile persistence: cookies/logins saved back to profile on session close
- Uses raw fetch() calls for API communication (no SDK dependency)

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 00:22:25 -06:00
Chris Tate a99f59cd20 Fix: check command hangs indefinitely (#272)
Fixes #257
2026-01-25 23:58:53 -06:00
Chris Tate 45506fbff0 Fix: set device does not apply deviceScaleFactor - HiDPI screenshots not possible (#270)
Fixes #255
2026-01-25 15:27:03 -06:00
Chris Tate 79863a5180 Fix: CLI: state load / profile persistence not usable in v0.7.6 (#268)
* Fix: CLI: state load / profile persistence not usable in v0.7.6

This PR addresses issue #259

* Fix issues identified in code review
2026-01-25 13:45:17 -06:00
Zhiwei Li 53187a603c feat: add support for ignoring HTTPS certificate errors (#93)
* feat: add support for ignoring HTTPS certificate errors

* fix: update warning message for already running daemon to include ignore HTTPS errors option

* docs: add documentation for --ignore-https-errors option in README and SKILL.md

* feat: initialize ignore_https_errors flag in command context

* fix: change launch_cmd to mutable for cdp value handling
2026-01-24 23:54:33 -06:00
Zach Warunek 36ea8ecb55 fix: allow null selector in screenshot command schema (#236)
The screenshot command was failing with 'Validation error: selector: Expected string, received null' when only a path was provided (e.g., 'agent-browser screenshot ~/Desktop/test.png').

The Rust CLI serializes None values as null in JSON, but the Zod schema only allowed undefined (via .optional()), not null. Changed selector field to use .nullish() which accepts both null and undefined.

Fixes issue where screenshot command without selector fails validation.
2026-01-23 17:50:11 -06:00
Chris Tate fff4312d16 update provider flag (#217)
* auto-release

* fixes

* fix secret name

* update provider flag
2026-01-23 11:41:17 -06:00
Danila PoyarkovandChris Tate 9f3c3ad933 fix(screenshot): support refs and improve error messages (#141)
* fix(screenshot): support refs and improve error messages

* fix(cli): support selector argument in screenshot command

* Fix CSS class selectors being treated as file paths

* fix(test): update screenshot test assertions

---------

Co-authored-by: Chris Tate <chris@ctate.dev>
2026-01-22 10:06:38 -06:00
55f4eaa728 feat: add download CLI commands with ref support (#183)
* feat: add download and waitfordownload CLI commands

Add CLI support for the existing download functionality in the daemon:

- `download <selector> <path>`: Click an element to trigger download
  and save to specified path
- `wait --download [path] [--timeout ms]`: Wait for any download to
  complete, optionally save to path with configurable timeout

Includes comprehensive unit tests and help documentation.

* fix: download command ref support and output message

- Fix handleDownload to use browser.getLocator() for ref selector support
- Fix CLI output to show "Downloaded to" instead of "Screenshot saved"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Chris Tate <chris@ctate.dev>
2026-01-22 08:55:19 -06:00
Lindsey SimonandChris Tate 36cca10c10 Add --profile flag for persistent browser profiles (#68)
* Add --profile flag for persistent browser profiles

Adds support for persistent browser profiles that preserve cookies,
localStorage, and login sessions across browser restarts.

Changes:
- Add --profile <path> CLI flag (flags.rs)
- Add AGENT_BROWSER_PROFILE environment variable support
- Add profile field to LaunchCommand type (types.ts)
- Use launchPersistentContext when profile is specified (browser.ts)
- Update help text and README with documentation

Usage:
  agent-browser --profile ~/.myapp-profile open myapp.com

This enables AI agents to maintain authenticated sessions across
browser restarts without re-authenticating each time.

* Expand tilde in profile path to home directory

* fix: add missing profile field to test Flags struct

---------

Co-authored-by: Chris Tate <chris@ctate.dev>
2026-01-22 08:05:25 -06:00
mmhiyokoandClaude Opus 4.5 946d236d9f fix: use ~/.agent-browser for socket files instead of TMPDIR (#180)
* fix: use ~/.agent-browser for socket files instead of TMPDIR

This fixes issue #163 where different TMPDIR values (common with
tmux/screen/VSCode/IntelliJ) caused the CLI and daemon to use
different socket paths.

Socket directory priority:
1. AGENT_BROWSER_SOCKET_DIR (explicit override)
2. $XDG_RUNTIME_DIR/agent-browser (Linux standard)
3. ~/.agent-browser (fallback, like Docker Desktop)

Both CLI (Rust) and daemon (Node.js) now use the same logic.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: session list now looks in correct socket directory

- Make get_socket_dir() public in connection.rs
- Update session list to use get_socket_dir() instead of temp_dir()
- Update pid file pattern from agent-browser-{session}.pid to {session}.pid
- Add tmpdir fallback to daemon.ts when homedir is unavailable

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add unit tests for socket directory resolution

Add comprehensive tests for get_socket_dir/getSocketDir to verify:
- AGENT_BROWSER_SOCKET_DIR takes priority
- Empty strings are ignored (fixes Rust/TypeScript consistency)
- XDG_RUNTIME_DIR fallback works correctly
- Home directory fallback when env vars unset

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 01:15:25 -06:00
OanakiajaandChris Tate 083a946aac feat: add browser launch --args, --user-agent, --proxy-bypass configuration support. (#35)
* feat: add browser launch args, user-agent, and proxy configuration support

* fix: User Agent env need added

* fix: command pass error

---------

Co-authored-by: Chris Tate <chris@ctate.dev>
2026-01-22 00:19:37 -06:00
RafaelandClaude Opus 4.5 e892bceadf feat: support remote CDP WebSocket URLs in --cdp flag (#99)
Previously, the --cdp flag only accepted a port number and connected via
http://localhost:{port}. This made it impossible to connect to remote
browser services like Kernel, Browserless, etc. that provide WebSocket URLs.

The --cdp flag now accepts either:
- A port number (e.g., 9222) for local connections
- A full WebSocket URL (e.g., wss://...) for remote browser services

Changes:
- Added cdpUrl field to LaunchCommand type
- Updated protocol validation to accept URL format with scheme validation
- Modified connectViaCDP to detect and handle both formats
- Handle numeric strings for JSON serialization edge cases
- Updated CLI to send cdpUrl or cdpPort based on input format
- Updated README with examples for remote connections

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 21:11:14 -06:00
Aitor c4139fa389 feat: add Browser Use cloud browser as available provider (#138)
* feat: add Browser Use cloud browser
  integration

* feat: enhance Browser Use integration with provider flag support

- Updated README to reflect new usage instructions for enabling Browser Use with the `-p` flag.
- Modified CLI to parse and handle the `-p` flag for specifying the provider.
- Implemented logic in the main application to launch with the specified cloud provider.
- Adjusted BrowserManager to connect to Browser Use based on the provider flag or environment variable.
- Updated types and protocol schemas to include provider information.

* feat: add validation for mutually exclusive CLI options

- Implemented checks to prevent the use of both --cdp and --provider flags simultaneously.
- Added validation to ensure --extension cannot be used with the --provider flag.
- Enhanced error handling to provide clear feedback in both JSON and console output formats.
2026-01-21 18:01:19 -06:00
Paul KleinandKylejeong2 7123d46e7f Add Browserbase support for remote browser over CDP (#3)
* Add Browserbase support for remote browser over CDP

When BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID env vars are set,
connect to a Browserbase session via CDP instead of launching a local browser.

* Update URLs to browserbase repo

* Add Browserbase support for remote browser over CDP

When BROWSERBASE_API_KEY and BROWSERBASE_PROJECT_ID env vars are set,
connect to a Browserbase session via CDP instead of launching a local browser.

* Update link to Browserbase Dashboard in README

* bump browserbase sdk to latest version

* remove sdk as a dep

* change name back to vercel labs

* added try catch blocks, functions to close session

* revert package names

* remove extra if statement

---------

Co-authored-by: Kylejeong2 <kylejeong21@gmail.com>
2026-01-21 17:49:21 -06:00
Chris Tate 818d9fa95e format code (#152) 2026-01-18 11:21:28 -06:00
Nicenonecb 28740acecf Fix CLI/protocol mismatches for select, frame main, and headers (#45)
* fix: align CLI command payloads with protocol

* fix(cli): support multi-value select in CLI
2026-01-17 20:25:19 -06:00
Sanchay 42879c337a fix: respect AGENT_BROWSER_HEADED env var for headed mode (#92)
The headless option was hardcoded to true in the auto-launch section,
ignoring the AGENT_BROWSER_HEADED environment variable. This fix checks
the env var so users can run the browser in headed mode by setting
AGENT_BROWSER_HEADED=1.

Fixes #90
2026-01-17 19:22:59 -06:00
Leon Gao 412ac63b68 fix: resolve refs in input value (#139) 2026-01-17 19:05:06 -06:00
Danila Poyarkov e6e832d2bc feat: add 'get styles' command for computed styles extraction (#142) 2026-01-17 18:56:52 -06:00
Dharma b19ca760aa fix: support URL parameter in tab new command (#64)
* fix: support URL parameter in tab new command

The CLI was correctly sending the URL parameter when running
`agent-browser tab new <url>`, but the TypeScript daemon was
ignoring it because:

1. The schema didn't include the url field (stripped during validation)
2. The TabNewCommand type didn't have a url property
3. The handler didn't pass the URL to browser.newTab()
4. browser.newTab() didn't accept or use a URL parameter

This fix adds URL support throughout the chain so that
`agent-browser tab new https://example.com` now correctly
opens a new tab and navigates to the specified URL.

Fixes #62

* fix: omit url field when not provided in tab new command

Previously, the CLI always sent "url": null when no URL was provided,
which caused Zod validation to fail with "Expected string, received null".

Now the url field is only included when a URL is actually provided.

Fixes issue reported by @ctate in PR review.

* refactor: move navigation logic from BrowserManager to handleTabNew

Address review feedback:
- Add .min(1) to URL validation for consistency with navigateSchema
- Keep BrowserManager.newTab() simple (single responsibility)
- Handle navigation in handleTabNew following same pattern as handleNavigate
2026-01-17 18:53:24 -06:00
Sheingandgoogle-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> e7c4936bc7 fix(cli): allow null path in screenshot command validation (#101)
The Rust CLI sends `null` for the `path` argument when it is not provided,
but the Zod schema only accepted `undefined`. This change updates the
`screenshotSchema` to allow `null` values for `path`, enabling the
`screenshot` command to work without a file path argument (outputting to stdout).

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
2026-01-17 18:41:55 -06:00
Sheinggoogle-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>sheing-google
7aad47d3bd fix: Prevent CDP timeout on empty URL tabs (#102)
When connecting to a browser via CDP, particularly on Android, tabs with an empty URL can cause Playwright commands to hang indefinitely. This leads to a timeout in agent-browser.

This commit fixes the issue by filtering out any pages that have an empty `page.url()` during the CDP connection process. This prevents agent-browser from attempting to interact with these problematic tabs, resolving the timeout while preserving normal pages.

Added a unit test to verify that pages with empty URLs are correctly ignored. Also increased the timeout for a flaky screencast test to improve test suite stability.

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: sheing-google <231310897+sheing-google@users.noreply.github.com>
2026-01-17 18:16:37 -06:00
1f31452fea feat: Add video recording with Playwright native video (#116)
* feat: add video recording with Playwright native video

Adds `record start/stop` commands using Playwright's built-in video
recording. No external dependencies required (no FFmpeg).

Usage:
  agent-browser record start ./demo.webm https://example.com
  agent-browser click @e1
  agent-browser record stop

Recording creates a fresh browser context with video enabled. For smooth
demos, explore the page first to plan actions, then start recording.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: auto-capture URL and transfer state for recording

When starting a recording without a URL:
- Automatically captures current page URL
- Preserves cookies and localStorage from current session

This enables a seamless workflow:
  agent-browser open https://app.example.com
  agent-browser snapshot -i  # explore, plan
  agent-browser record start ./demo.webm  # picks up URL + auth state
  agent-browser click @e3
  agent-browser record stop

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: error on non-webm recording path instead of silent coercion

Previously, specifying a non-.webm path like ./demo.mp4 would silently
change it to ./demo.webm. Now it throws a clear error telling the user
that Playwright native recording only supports WebM format.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: clean up recording temp directory after stopRecording

Previously the temp directory was created but never deleted, relying on
OS cleanup. Now we explicitly remove it after saving the video, in both
success and error paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: add record restart command

Adds `record restart` command that stops the current recording (if any)
and starts a new one. Also improves the error message when trying to
start recording while already recording.

Changes:
- Add restartRecording method to BrowserManager
- Add recording_restart action to protocol, types, and actions
- Add CLI parsing for `record restart <path> [url]`
- Update help text and skill documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* test: add CLI tests for record restart command

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Chris Tate <chris@ctate.dev>
2026-01-16 12:27:58 -06:00
NMW 3675e6bd7a feat: add --proxy flag for browser proxy configuration (#16)
* feat: add --proxy flag for browser proxy support

Add CLI flag to configure HTTP/SOCKS proxy for Playwright browser context.
Supports URL format with optional credentials: http://user:pass@host:port

* fix: improve proxy parsing error handling

- Handle malformed credentials (@ without :) by ignoring incomplete creds
- Replace unwrap() with expect() for better error messages
- Addresses Vercel bot code review suggestions

* Restaura cambios locales: soporte AGENT_BROWSER_HOME y timeout aumentado

- Agrega soporte para variable de entorno AGENT_BROWSER_HOME en connection.rs
- Aumenta timeout por defecto de 10s a 60s para conexiones más lentas

* feat: add --proxy flag for browser proxy configuration

Implements proxy support based on PR #16 with reviewer feedback:

Features:
- Parse proxy URLs: http://[user:pass@]host:port
- Support for HTTP, HTTPS, and SOCKS5 protocols
- Handle username-only auth (preserves username with empty password)
- Apply proxy to both standard and persistent contexts

Changes:
- cli/src/flags.rs: Add proxy flag parsing
- cli/src/main.rs: Add parse_proxy() with comprehensive tests
- cli/src/output.rs: Add --proxy to help output
- cli/src/commands.rs: Fix test helper to include proxy field
- src/types.ts: Add proxy to LaunchCommand interface
- src/protocol.ts: Add proxy validation schema
- src/browser.ts: Apply proxy to context creation

Tests:
- 7 unit tests for parse_proxy() covering all edge cases
- All Rust tests passing (69 tests)
- All TypeScript tests passing (168 tests)
- TypeScript typecheck passing

Resolves feedback from PR #16:
- Fixed username-only proxy handling (issue #2681046975)
- Added comprehensive unit tests
- Added --proxy to help documentation
- Used expect() instead of unwrap() for better error messages

* refactor: simplify parse_proxy function

- Remove redundant comments
- Extract server variable to reduce duplication
- Inline trivial username/password variables

All 7 proxy tests still passing.
2026-01-16 11:56:35 -06:00
NoelandClaude Sonnet 4.5 7b43d408da fix: improve error message when element is blocked by overlay (#59)
When clicking an element that is blocked by a cookie banner or modal overlay,
the error message incorrectly showed "Element not found or not visible" even
though the element was found and visible.

The issue was in toAIFriendlyError(): the check for "Timeout" was evaluated
before "intercepts pointer events", causing the wrong error message to be
returned.

Changes:
- Reorder error detection to check "intercepts pointer events" before "Timeout"
- Improve error message to suggest dismissing modals/cookie banners
- Export toAIFriendlyError for testing
- Add focused tests for overlay blocking behavior

Before:
  Element "@e4" not found or not visible. Run 'snapshot' to see current page elements.

After:
  Element "@e4" is blocked by another element (likely a modal or overlay).
  Try dismissing any modals/cookie banners first.

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-13 15:25:46 -06:00
Chris TateandVercel <vercel[bot]@users.noreply.github.com> 2dc093cd62 add screencast (#67)
* docs

* updates

* Fix: The handleCopy function fails to handle errors from navigator.clipboard.writeText(), causing unhandled exceptions and misleading UI feedback when clipboard operations fail.

Co-authored-by: ctate <chris@ctate.dev>

* Fix: The benchmark file uses emojis (📊, 🚀, 🔨, 📈, 📋, , ⏱️, ⚠) in console output, violating repository guidelines that forbid emojis in code and output.

Co-authored-by: ctate <chris@ctate.dev>

* Remove benchmark/run.ts from PR

* screencast

* update docs

* address comments

---------

Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
2026-01-13 14:53:27 -06:00
Shirshak 673e2e266e feat: Add extension support (#48)
* Rebase: Add extension support

* Fix logs
2026-01-13 14:34:59 -06:00
Alan JeonClaude Opus 4.5vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
95675e9d55 feat: add CDP connection support for external browsers (#24)
* feat: add CDP connection support for external browsers

Add --cdp flag to connect to browsers via Chrome DevTools Protocol.
This enables control of Electron apps, Chrome instances, or any browser
exposing a CDP endpoint.

- Add cdpPort option to launch command schema
- Implement connectViaCDP() using chromium.connectOverCDP()
- Track browser connection type for proper reconnection handling
- Collect all pages from all contexts for CDP connections

Usage: agent-browser --cdp 9222 snapshot

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* feat: enhance CDP connection handling and improve page tracking

* main.rs update

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* fix: verify CDP connection is alive before early return in launch()

Prevents misleading errors when the remote browser crashes by checking
isConnected() before reusing an existing browser reference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* fix: reconnect when CDP port changes instead of reusing existing browser

Ensures --cdp flag is respected even when a browser session already exists.
Adds tests for launch() reconnection behavior.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* Update src/browser.ts

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* fix: improve CDP connection handling and validation

* feat: add CDP connection validation to ensure browser context accessibility

* Update src/browser.ts

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>

* feat: enhance CDP connection handling and add reconnect logic

* fix: improve CDP connection handling during browser closure

* fix: reset cdpPort to null during browser initialization

* feat: enhance browser launch logic to handle CDP connection switching

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
2026-01-13 00:52:47 -06:00
Chris Tate 1a88d7f585 custom headers via --headers (#30)
* add custom headers via --headers

* add tests

* better parsing
2026-01-12 12:01:19 -06:00
Chris Tate 4f6fd8ec5c support serverless environments (#29)
* add --executable-path

* tests

* test vercel

* fixes
2026-01-12 11:41:25 -06:00
Chris Tate a0802b1863 fix locator issues (#14)
* fix locator issues

* address feedback
2026-01-12 00:29:53 -06:00
Chris Tate 5a7c7440c0 add ci action (#12)
* add ci action

* pre-commit hook

* format
2026-01-12 00:02:38 -06:00
Chris Tate 9f7d7d6447 fix cookies/storage (#10) 2026-01-11 23:27:49 -06:00
Chris Tate 3bd331b97f cleanup 2026-01-11 10:08:08 -06:00
Chris Tate c0ed5c443e remove ts cli 2026-01-11 09:57:41 -06:00
Chris Tate 36b1af29f6 windows 2026-01-11 09:54:51 -06:00
Chris Tate 82079d6d20 update unit tests 2026-01-11 09:48:44 -06:00
Chris Tate 6b3bae760b fixes 2026-01-11 03:23:39 -06:00
Chris Tate 7443a4a4c5 smart snapshots 2026-01-11 02:44:27 -06:00
Chris Tate 34821f001e bun 2026-01-11 02:28:51 -06:00
Chris Tate 71b1c50533 refs 2026-01-11 02:06:17 -06:00
Chris Tate 68115b85ce prevent relaunch 2026-01-11 01:05:25 -06:00
Chris Tate 627c88888e fix console/errors 2026-01-11 00:21:26 -06:00
Chris Tate e7c25e9030 --with-deps 2026-01-10 23:50:09 -06:00
Chris Tate a7e5de5e4f install 2026-01-10 23:47:30 -06:00