CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
LM Studio plugin (mbagley/agent-browser) that exposes Vercel's agent-browser
CLI (vercel-labs/agent-browser, npm agent-browser) as 13 model tools. The
plugin is a thin spawn-based wrapper — it does not implement browser
automation itself, only argument marshalling and process lifecycle.
CONTEXT.md is a written-down history of the build (bugs hit, fixes, why
things are shaped the way they are). Read it before changing
src/agentBrowser.ts.
There is no unit test runner. test/verify-nytimes.js is a single Node script
that drives the compiled dist/agentBrowser.js end-to-end against a real
site. To run a subset, edit the script — it is procedural, not a framework.
The integration test makes real network calls to nytimes.com and requires
agent-browser install to have been run once on the host (downloads Chrome
for Testing).
Three source files under src/, all consumed by src/index.ts's
main(context) which calls withConfigSchematics and withToolsProvider per
the LM Studio plugin contract:
configSchematics.ts — declares the user-facing settings: process plumbing
(binCommand, session, headed, timeoutMs, screenshotDir) and the
human-emulation block (userAgent, viewport, acceptLanguage,
colorScheme, extraBrowserArgs) which is on by default. Field types are
validated against @lmstudio/sdk's basicKVValueTypesLibrary.agentBrowser.ts — runAgentBrowser(settings, args, opts) is the only
thing that spawns a process. Owns PATH discovery, command resolution,
argument ordering, abort signals, and stdout/stderr capture.toolsProvider.ts — registers 13 tools, each one a thin call into
runAgentBrowser with a curated subset of agent-browser's 100+ subcommand
surface. Tool descriptions are part of the user-visible contract — they
steer LLM tool selection, edit them deliberately.These are load-bearing. The repo's history (see CONTEXT.md) is two debug
sessions of these going wrong:
PATH discovery, not PATH inheritance. LM Studio's plugin runtime
launches Node with a stripped PATH (~/usr/bin:/bin), so spawn("npx")
fails with ENOENT. resolveAbsolute(cmd) scans known toolchain dirs
(Homebrew, Volta, fnm, nvm, asdf, bun, npm-global, system bins) and falls
back to /bin/sh -lc 'command -v <cmd>'. Spawned children also receive an
enrichedPath() so descendants (e.g. npx finding node) work. The
integration test deliberately strips process.env.PATH to exercise this.
Argument order: subcommand args first, global flags last.
agent-browser open https://... --session lmstudio --timeout 30000 is
correct; putting --timeout before open makes the CLI parse it as the
subcommand and exit. Inside runAgentBrowser, the order is
[...prefix, ...args, ...globalFlags] — preserve this. The
human-emulation flags (--user-agent, --headers, --color-scheme,
--args) live in the globalFlags tail alongside --session/--timeout.
Do not add agent-browser as an npm dependency of this plugin. The plugin
must work via the host's npx / agent-browser. The binCommand setting
exists so users can override discovery with an absolute path when the scan
misses.
rootDir=src, outDir=dist. The integration test
require()s the compiled output from dist/, so changes to src/ need a
build before re-running test:verify (the npm script chains tsc for
you)..lmstudio/ is generated by lms dev; do not edit by hand.npm install
npm run build # tsc → dist/
npm run dev # lms dev — auto-rebuilds and reloads in LM Studio
npm run push # lms push — publish to LM Studio Hub
npm run test:verify # build + integration test against nytimes.com (network)