[STG-2511] feat: add browse skills show and agent-facing --help header#2335
Merged
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 2a74053 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 7 files
Confidence score: 5/5
- Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
participant Agent as AI Agent
participant CLI as browse CLI (oclif)
participant Help as BrowseHelp (custom Help class)
participant CmdShow as SkillsShow command
participant FS as Node.js File System
participant BundledSkill as bundled SKILL.md
Note over Agent,BundledSkill: Agent-Facing Root Help Flow (browse --help / browse)
Agent->>CLI: browse --help (or bare browse)
CLI->>Help: showRootHelp()
Help->>Help: log AGENT_HEADER ("Start here (for AI agents):…")
Help->>CLI: super.showRootHelp() – auto-generated VERSION, USAGE, TOPICS, COMMANDS
CLI-->>Agent: Full help output with agent header prepended
Note over Agent,BundledSkill: Per-Command Help Flow (unaffected)
Agent->>CLI: browse open --help
CLI->>CLI: default oclif command help
CLI-->>Agent: Standard command help (no agent header)
Note over Agent,BundledSkill: Skills Show Flow
Agent->>CLI: browse skills show
CLI->>CmdShow: run()
CmdShow->>CmdShow: bundledCliSkillPath() → path to skills/browse/ directory
CmdShow->>FS: join(path, "SKILL.md")
FS-->>CmdShow: resolved absolute path to SKILL.md
alt Success: SKILL.md exists and is readable
CmdShow->>FS: readFileSync(skillMdPath, "utf8")
FS-->>CmdShow: file contents (markdown string)
CmdShow->>CmdShow: this.log(contents) – print to stdout
CmdShow-->>CLI: exit code 0
CLI-->>Agent: Full SKILL.md content printed
else Error: SKILL.md missing or unreadable
CmdShow->>FS: readFileSync(skillMdPath, "utf8")
FS-->>CmdShow: error (ENOENT, EACCES, etc.)
CmdShow->>CmdShow: this.error("Could not read…") – non-zero exit
CmdShow-->>CLI: exit code non-zero (oclif handles formatted error display)
CLI-->>Agent: Error message to stderr
end
Note over Agent,FS: Path Resolution (handles both src and dist layouts)
CmdShow->>CmdShow: packageRoot() – based on __dirname of module file
CmdShow->>FS: join(packageRoot(), "skills", "browse")
FS-->>CmdShow: path → works from any process.cwd()
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Use the project's fail() error convention (exit code 1) instead of oclif's default this.error() (exit 2), make the different-cwd test platform-agnostic via os.tmpdir(), and add a missing-SKILL.md error-path test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ajmcquilkin
approved these changes
Jul 9, 2026
shrey150
added a commit
that referenced
this pull request
Jul 9, 2026
…idance (#2336) ## Summary A 3-provider bare-loop smoke test (E2B/Modal/Vercel, real sandboxes, local CLI build) surfaced two systematic gaps in the bundled `browse` skill (`packages/cli/skills/browse/SKILL.md`): 1. **3/3 agents ignored the pre-wired `BROWSE_SESSION` env var** and self-named sessions via `--session <name>` (one run orphaned a Browserbase session as a result). The skill taught named `--session` usage but never said "if `BROWSE_SESSION` is already set, every command already targets that session — don't pass `--session` or invent a new name." This defeats the sandbox-template env-steering pattern (`BROWSERBASE_API_KEY` + `BROWSE_SESSION=<name>` → flagless remote commands). 2. **2/3 agents tried `--local` first inside Chrome-less containers**, hit "No Chrome or Chromium found", then recovered on retry. The skill lacked explicit guidance that `--local` requires local Chrome/Chromium and that containers/CI/sandboxes without Chrome should go straight to `--remote`. ## What changed Two minimal additions to `packages/cli/skills/browse/SKILL.md`, both in the existing "Browser Target Selection" section (the section that already teaches local/remote choice and named-session usage) — no restructuring, no new sections: ``` `--local` requires Chrome or Chromium already installed on the machine. In containers, CI, and sandboxes with no browser installed, use `--remote` instead of `--local`. If `--local` fails with "No Chrome or Chromium found" and `BROWSERBASE_API_KEY` is set, switch to `--remote` — do not retry `--local`. ``` ``` If `BROWSE_SESSION` is already set in the environment, every command already targets that session — do not pass `--session` or invent a new name. An explicit `--session <name>` always overrides `BROWSE_SESSION` for that command, so only pass it to deliberately target a different session. ``` Verified the precedence claim against the actual implementation before writing the wording (not just trusting the smoke-test writeup): - `packages/cli/src/lib/driver/flags.ts:73` — `export function sessionName(value?: string): string { return value ?? process.env.BROWSE_SESSION ?? "default"; }`. An explicit `--session` flag always wins over `BROWSE_SESSION`; when omitted, `BROWSE_SESSION` becomes the effective session; with neither, it's `"default"`. - `packages/cli/src/lib/driver/command-cli.ts:75` — `runDriverCommandFromFlags` calls `sessionName(flags.session)` for every driver command, so this precedence applies uniformly across `open`, `snapshot`, `click`, `stop`, etc. - `packages/cli/src/lib/driver/remote.ts:130` — exact no-Chrome error string is `"No Chrome or Chromium found on this machine. Install one (Linux: apt install chromium · macOS: brew install --cask google-chrome, or Chromium with CHROME_PATH set), attach to a running browser with --cdp <port>, or set BROWSERBASE_API_KEY to use a remote browser."` ## No changeset This is a skill-text-only change (`SKILL.md`), same category as PR #2329 (skill-text-only fix, no changeset). The updated text ships with the next `browse` release — a release is already queued by #2335's changeset — and is consumed at runtime by the evals harness added in #2334. ## E2E Test Matrix | Command / flow | Observed output | Confidence / sufficiency | | --- | --- | --- | | `pnpm install && pnpm turbo run build --filter=browse` (worktree, local build) | `Tasks: 4 successful, 4 total` | Proves the local CLI build succeeds with the change in place; no build regressions from a docs-only edit. | | Resolve `bundledCliSkillPath()` from the compiled `dist/lib/skills/install.js` via `require.resolve` + manual path join (no `skills show` command exists on `main` yet — it ships in PR #2335, unmerged at time of this PR) | `resolved bundledCliSkillPath: <worktree>/packages/cli/skills/browse` | Proves the exact file `browse skills install` resolves to at runtime is the file this PR edits, not a stale copy. | | `grep -n "already set in the environment\|do not retry" packages/cli/skills/browse/SKILL.md` | `76:If \`BROWSE_SESSION\` is already set in the environment, every command already targets that session...` `68:...If \`--local\` fails with "No Chrome or Chromium found"...do not retry \`--local\`.` | Confirms the exact new lines are present at the bundled path resolved above — the new guidance flows through to the real command path. | | `node bin/run.js skills install --help` | Prints usage for `browse skills install` (no side effects triggered — did not run the real install, which mutates the global `~/.agents/skills` pool via `npx skills add --global`) | Confirms the command is wired and reachable; deliberately did not execute the real install to avoid mutating local global skill state outside this change's scope. | | `pnpm test:cli` (vitest, worktree build) | `Test Files 23 passed (23)` / `Tests 344 passed (344)` | Full existing CLI test suite still green; this change touches no runtime code. | | `pnpm eslint .` | No output / exit 0 | Lint clean. | | `pnpm format:check` (prettier) | `All matched files use Prettier code style!` | Formatting clean, including the edited Markdown. | | `tsc --noEmit -p tsconfig.json` | No output / exit 0 | Typecheck clean (unaffected by a Markdown-only change, included for completeness). | ## Related - Linear: https://linear.app/browserbase/issue/STG-2513/browse-skill-document-browse-session-precedence-container-remote - Evidence source: 3-provider (E2B/Modal/Vercel) bare-loop smoke test, 2026-07-09 - Text will be exercised by the evals harness landing in #2334 - Release vehicle: changeset already queued in #2335 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Clarifies the `browse` skill docs to prevent session misrouting and container failures by documenting `BROWSE_SESSION` precedence and when to use `--remote` instead of `--local`. Addresses Linear STG-2513. - **Bug Fixes** - Documented that if `BROWSE_SESSION` is set, commands target that session; only pass `--session` to override (precedence: `--session` > `BROWSE_SESSION` > `default`). - Stated that `--local` requires Chrome/Chromium; in containers/CI/sandboxes use `--remote`. If you see "No Chrome or Chromium found," switch to `--remote` instead of retrying `--local`. <sup>Written for commit 829ff7b. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2336?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
shrey150
added a commit
that referenced
this pull request
Jul 9, 2026
… 22 (#2344) ## Why Every stagehand release since 2026-07-09 18:52 UTC is broken. The Release workflow's "Update npm for Trusted Publishing" step runs `npm install -g npm@latest`; npm@12.0.0 was published 2026-07-08 21:06 UTC and became `latest`, and it requires node `^22.22.2 || ^24.15.0 || >=26` — the release job runs node 20, so the step dies with `EBADENGINE` before versioning even starts. - Last green Release: 2026-07-08 17:50 UTC - First failure: 2026-07-09 18:52 UTC ([run](https://github.com/browserbase/stagehand/actions/runs/29043380120) — `npm error notsup Required: {"node":"^22.22.2 || ^24.15.0 || >=26.0.0"} / Actual: {"npm":"10.8.2","node":"v20.20.2"}`) - This currently blocks the browse release carrying `browse skills show` (#2335) and the browse-skill guidance fixes (#2336), whose changeset is pending on main. ## What Pin the step to `npm@11` (currently 11.18.0): supports node >= 20.17 **and** Trusted Publishing/OIDC (needs npm >= 11.5.1) — the reason this step exists, since node 20 bundles npm 10.8.2 which predates it. One line + a comment stating the constraint. The alternative (bump the job to node 22/24 and keep `@latest`) changes the entire release build environment (SEA binaries, prebuilds) and isn't hotfix material; it can be considered separately. ## Validation | Command / flow | Observed output | Confidence / sufficiency | | --- | --- | --- | | Failure-log inspection of both failed Release runs | `EBADENGINE ... npm@12.0.0 ... Required node ^22.22.2 \|\| ^24.15.0 \|\| >=26 / Actual node v20.20.2`, exit 1 at the pinned step | Proves the failure mechanism exactly at this line | | `curl registry.npmjs.org/npm` → dist-tags + publish times | `latest = 12.0.0`, published 2026-07-08T21:06Z — inside the 07-08 17:50 → 07-09 18:52 breakage window | Proves `@latest` drift is the trigger; nothing repo-side changed | | npm 11.x engine range vs job node | npm 11.18.0 supports node >= 20.17; job runs 20.20.2 | Proves the pin resolves the engine conflict while keeping Trusted Publishing (>= 11.5.1) | | Real release exercise | Not possible pre-merge — the Release workflow only runs from main. Merging this PR pushes to main, which itself triggers Release with the pending browse changeset — that run is the live verification | The one path that cannot be tested from a branch | Linear: STG-2520 🤖 Generated with [Claude Code](https://claude.com/claude-code) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Pin `npm` in the Release workflow to `11.18.0` to avoid `npm@12` requiring Node >=22. Restores releases on Node 20 and keeps Trusted Publishing (Linear: STG-2520). <sup>Written for commit 90a6d71. Summary will update on new commits.</sup> <a href="https://cubic.dev/pr/browserbase/stagehand/pull/2344?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Agents run
browseinside sandboxes/harnesses we don't control, so they can't rely on a copied SKILL.md or a docs URL staying in sync with the installed CLI version. Serving the skill straight from the binary means the guidance is always version-matched to whateverbrowsethe agent actually has.This converges with the shape competitors have already landed on:
agent-browser skills get core --full+ a top-of---help"Start here (for AI agents)" headermodal skills showskill showWhat changed
browse skills show(packages/cli/src/commands/skills/show.ts), following the existingskillstopic command style (BrowseCommandbase, single-line description,examples). It resolves and prints the bundledSKILL.mdvia the samebundledCliSkillPath()helperskills installalready uses (exported frompackages/cli/src/lib/skills/install.ts), so path resolution is shared and works in bothsrcanddistlayouts. Reads the file synchronously and callsthis.error(...)with a clear message + non-zero exit if it's missing/unreadable.Helpclass (packages/cli/src/help.ts) that prepends a short agent-facing block before oclif's auto-generated VERSION/USAGE/DESCRIPTION/TOPICS/COMMANDS sections on root help only (browse --helpand barebrowse). Wired via"helpClass": "./dist/help.js"inpackages/cli/package.json's oclif config. Per-command--helpviews (e.g.browse open --help) are unaffected.browseis in the changesetsignorelist by default, but per team convention it still gets patch changesets for release-impacting CLI changes.packages/cli/tests/skills-show.test.ts(happy path + resolution from a different cwd), plus updates topackages/cli/tests/cli-surface.test.tsfor the newskills showcommand help, the agent header appearing beforeUSAGEon root help, and its absence on command help.E2E Test Matrix
node packages/cli/bin/run.js skills show | head -20SKILL.mdfrontmatter:name: browse,description: Use the browse CLI for...,# Browse CLIheadingnode packages/cli/bin/run.js skills show | wc -lc369 17221(369 lines, 17221 bytes)node packages/cli/bin/run.js --help | head -25Start here (for AI agents):/browse skills show/ rationale block, thenUnified Browserbase CLI...,VERSION,USAGE,TOPICS(incl.skills)--helpnode packages/cli/bin/run.js | head -25browsewith no args--help) also gets the headernode packages/cli/bin/run.js open --help | head -15Open a URL in a browse driver session.,USAGE,ARGUMENTS,FLAGS) with no agent headercd /tmp && node <worktree>/packages/cli/bin/run.js skills show | head -3SKILL.mdfrontmatter, run from an unrelated cwdprocess.cwd()— required for the dist-layout published packagepnpm test:cli(vitest)Test Files 24 passed (24),Tests 349 passed (349)pnpm lint(prettier + eslint + tsc)Linear
https://linear.app/browserbase/issue/STG-2511/add-browse-skills-show-agent-facing-help-header
🤖 Generated with Claude Code
Summary by cubic
Adds
browse skills showto print the bundledSKILL.mdfor version-matched guidance, and adds an agent-facing header on root help pointing to it. Addresses STG-2511.New Features
browse skills showprints the bundled skill viabundledCliSkillPath()and, on error, usesfail()(exit 1 withresultCode: "skill_show_missing").browse --helpand barebrowse) prepends a short “Start here” header; per-command help is unchanged. Wired viahelpClassinpackages/cli/package.json.bundledCliSkillPath()so path resolution works in bothsrcanddist.Refactors
fs/promises.readFilefor async skill file reads.Written for commit 2a74053. Summary will update on new commits.