Plugins
ABG supports local JavaScript plugins loaded by the Gateway. Plugins can transform browser data or add higher-level local commands without moving browser access into a hosted service.
Plugins run inside the local Gateway process through JavaScriptCore, so install only plugins you trust.
Plugin sources
Section titled “Plugin sources”ABG searches plugins in this order:
- Bundled plugins inside
Agent Browser Gateway.app/Contents/Resources/plugins/. - User-installed plugins under
~/.abg/plugins/. - Local development plugins from the repository checkout when running from the checkout.
Development Gateway runs on port 8766 use ~/.abg-dev/plugins/ instead of ~/.abg/plugins/.
That keeps production and development plugin state separate.
Install and manage
Section titled “Install and manage”abg plugin listabg plugin list --loadedabg plugin install user/repo --yesabg plugin install https://github.com/user/repo.git --yesabg plugin install git@github.com:user/private-plugin.git --yesabg plugin install ./my-plugin --name my-plugin --yesabg plugin updateabg plugin update my-pluginabg plugin disable my-pluginabg plugin enable my-pluginabg plugin reload my-pluginabg plugin uninstall my-plugininstall requires --yes because plugin code is arbitrary JavaScript loaded by the local Gateway.
Repository installs use the local git command, so private repositories use the user’s existing SSH
keys, git credential helper, or GitHub CLI-backed git authentication. ABG does not ask for or store
GitHub tokens, and HTTPS URLs with embedded credentials are rejected.
Update runs git pull --ff-only for git-backed user plugins. Disable keeps the plugin directory in
place and writes profile-local state to plugin-state.json. ABG does not use an app database for
plugin enablement.
Plugin layout
Section titled “Plugin layout”my-plugin/ index.js plugin.jsonindex.js is required. plugin.json is optional but recommended because it powers plugin listings
and command help.
{ "name": "my-plugin", "version": "0.1.0", "description": "Short human-readable summary.", "domains": ["https://mail.google.com/*"], "transforms": ["gmail-clean-markdown"], "commands": [ { "name": "greet", "description": "Return a greeting.", "args": [ { "name": "name", "type": "string", "required": false, "default": "ABG" } ] } ]}Host API
Section titled “Host API”The host API is intentionally small:
abg.log("loaded " + abg.plugin.name);
abg.registerTransform("my-transform", function (input) { return String(input).trim();});Transforms are synchronous string-to-string functions. For abg read --format markdown, ABG uses
the generic Markdown transform first and can select a domain-specific Markdown transform when the
shared tab URL matches a plugin’s domains globs.
Command API
Section titled “Command API”Plugins can expose first-class CLI commands:
abg.registerCommand("greet", async function (args, context) { return { ok: true, message: "Hello, " + (args.name || "ABG"), plugin: context.plugin.name };});Invoke commands as dynamic ABG subcommands:
abg my-plugin greet --name "Ada"abg my-plugin greet --tab t1abg my-plugin greet --json '{"name":"Ada"}'printf '{"name":"Ada"}' | abg my-plugin greet --stdinCommand results are JSON. Handler failures are returned as structured JSON errors. Audit logs record the plugin name, command name, argument key list, and serialized argument byte length; argument values are not written to the audit log.
Tab API
Section titled “Tab API”Command handlers can drive the shared tab with context.tab.<action>(options). These methods route
through the same Gateway path as CLI calls, so per-tab consent, operation approval, and audit logging
apply uniformly.
abg.registerCommand("clear-and-paste", async function (args, context) { if (context.tabId == null) { return { ok: false, error: "no_tab_context" }; } await context.tab.clear({ selector: args.selector }); await context.tab.paste({ selector: args.selector, value: args.value }); return { ok: true };});Do not shell out from JavaScript to bypass ABG’s browser access path. Use the tab API so approvals and audit logs remain consistent.