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:

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:

@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

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:

  1. The navigated URL is matched against all discovered .bsh entries.
  2. Matching scripts are read from the VFS and evaluated in the target page via Runtime.evaluate.
  3. Each script executes once per navigation match. Re-entrant execution for the same script+URL combination is prevented.
  4. Sub-frame navigations (iframes) are ignored — only top-level navigations trigger scripts.

USE CASES

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

SEE ALSO

man jsh — .jsh script authoring and shell command discovery.