bsh - browser shell scripts (.bsh files)
OVERVIEW
.bsh files are JavaScript browser-navigation helpers that auto-execute when the browser navigates to a matching URL. They run in the target browser page context via CDP Runtime.evaluate — you have direct access to document, window, and all page globals.
NOT available: process, fs, exec(), or any Node/shell globals. Those belong to .jsh scripts. A .bsh script is injected into the web page, not the agent's runtime.
DISCOVERY
The BshWatchdog scans two roots for .bsh files, recursively:
/workspace//shared/
Scripts can live at any depth under these roots. Discovery is periodic (default: every 10 seconds), so newly created scripts are picked up automatically.
HOSTNAME MATCHING
The filename (without the .bsh extension) determines which hostnames trigger the script:
- Wildcard:
-.okta.com.bsh— the leading dash-dot (-.) becomes*., matching*.okta.com(any subdomain of okta.com, plus okta.com itself). - Exact:
login.okta.com.bsh— matches only the exact hostnamelogin.okta.com.
@MATCH DIRECTIVES
Optional // @match directives in the first 10 lines further restrict which URLs trigger the script. When present, the hostname must match the filename pattern and the full URL must match at least one @match pattern.
// @match *://login.okta.com/*
// @match https://example.com/app/*
Pattern format: scheme://host/path
*in scheme — matches http and https*in host — wildcard subdomain (same rules as filename matching)*in path — matches any path segment(s)
If no @match directives are present, the script runs on every navigation that matches the hostname pattern.
EXECUTION
The BshWatchdog subscribes to CDP Page.frameNavigated events. On each main-frame navigation to an http/https URL:
- The navigated URL is matched against all discovered
.bshentries. - Matching scripts are read from the VFS and evaluated in the target page via
Runtime.evaluate. - Each script executes once per navigation match. Re-entrant execution for the same script+URL combination is prevented.
- Sub-frame navigations (iframes) are ignored — only top-level navigations trigger scripts.
USE CASES
- Auto-login — fill credentials and submit login forms
- Page customization — hide elements, inject styles, modify DOM
- Data extraction — scrape page content into structured data
- Cookie/session management — set or read cookies on specific domains
- Form pre-filling — populate form fields on specific pages
EXAMPLE
File: /workspace/-.example.com.bsh
// @match *://login.example.com/signin*
//
// Auto-fill the login form on example.com
const emailField = document.querySelector('input[type="email"]');
const passwordField = document.querySelector('input[type="password"]');
if (emailField && passwordField) {
emailField.value = 'user@example.com';
passwordField.value = 'hunter2';
emailField.dispatchEvent(new Event('input', { bubbles: true }));
passwordField.dispatchEvent(new Event('input', { bubbles: true }));
const submitBtn = document.querySelector('button[type="submit"]');
if (submitBtn) submitBtn.click();
}
BSH vs JSH
- .bsh — runs in the browser page (CDP Runtime.evaluate). Has
document,window, page DOM. No Node.js globals. - .jsh — runs in the agent's shell runtime. Has
process,fs,exec(). No access to browser page DOM.
SEE ALSO
man jsh — .jsh script authoring and shell command discovery.