Skip to content

[STG-2191] feat(cli): static browse skill nudge + de-spam update notice#2200

Open
shrey150 wants to merge 10 commits into
mainfrom
shrey/browse-skill-nudge
Open

[STG-2191] feat(cli): static browse skill nudge + de-spam update notice#2200
shrey150 wants to merge 10 commits into
mainfrom
shrey/browse-skill-nudge

Conversation

@shrey150

@shrey150 shrey150 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Port of browserbase/cli#142 into the monorepo, de-scoped to a static model after team review.

How it works

When What you see
browse or browse --help Help opens with a "Start here (for AI agents)" banner pointing to browse skills install. Always shown.
Starting a browser session without the skill installed A stderr tip — run browse skills install — on the command that starts each session (when the driver daemon spawns). Repeats once per session until the skill is installed. Skipped in CI and with BROWSE_DISABLE_SKILL_NUDGE=1.
Any command while the CLI is outdated "Update available" on stderr — at most once per 20 hours, repeating until you upgrade (same semantics as Codex's upgrade banner). browse --help and browse doctor always show it.
Everything else Nothing.

Today the update notice prints on every command while outdated; with this PR it's one line per ~day. The nudge is stateless — no marker files; the daemon spawn is the session boundary. Skill detection is two filesystem checks (~/.agents/skills/browse and <cwd>/.agents/skills/browse — the two locations npx skills installs to). skill_present is reported on telemetry so adoption is measurable.

E2E Test Matrix

Run against the local build. <fake home> = machine without the skill; <real home> has it.

Command / flow Observed output Proves
HOME=<fake home> browse open <url> --local (daemon spawns) stderr tip; stdout clean JSON Tip fires at browser-session start
browse get title in the same session No tip One tip per session, not per command
browse stop, then open again Tip again Repeats each new session until installed
Real home (skill installed), fresh session No tip Detection suppresses the tip
browse / --help ×2, both homes Banner present on every run Banner is static, always-on
Fake cache version: 99.0.0browse status ×2 → rewind lastNotifiedAt 21h → run again → run as v99 Prints once → silent same sitting → reminds at +21h → silent once upgraded Update reminder: once per 20h until upgrade
pnpm test / pnpm lint (packages/cli) 225/225 tests, format+eslint+tsc clean Full suite incl. nudge, presence, and reminder-semantics tests

https://linear.app/browserbase/issue/STG-2191

…notice

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jun 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cae6087

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When 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

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 13 files

Confidence score: 3/5

  • There is moderate merge risk: one issue is user-facing (packages/cli/src/lib/help.ts) and another can disrupt release/versioning behavior (.changeset/browse-skill-nudge.md with .changeset/config.json ignore rules).
  • Most severe issue: the changeset for browse is marked as a patch, but browse is in the ignore list, so the intended version bump/changelog flow may be skipped and cause release confusion.
  • Pay close attention to .changeset/browse-skill-nudge.md, .changeset/config.json, and packages/cli/src/lib/help.ts - ensure the browse release path is valid and the banner logic only triggers for detected AI agents.
Architecture diagram
sequenceDiagram
    participant CLI as browse CLI (init)
    participant Hook as Init Hook
    participant Nudge as skillNudge
    participant Presence as skillPresence
    participant Agent as Agent Detector
    participant Help as Custom Help
    participant Updater as updateNotice
    participant Telemetry as Telemetry

    Note over CLI,Help: NEW: Agent skill discovery & update routing

    CLI->>Hook: init hook runs (every command)
    Hook->>Updater: scheduleBackgroundUpdateCheck() [silent]
    Updater-->>Hook: cache refreshed (no output)
    Hook->>Nudge: maybeNudgeInstallSkill()
    Nudge->>Agent: detectAgent()
    alt Agent detected AND not CI/test AND not disabled
        Agent-->>Nudge: agent name
        Nudge->>Presence: isBrowseSkillInstalled(agent)
        alt Skill MISSING
            Presence-->>Nudge: false
            Nudge->>Nudge: resolveNudgeKey (session or time window)
            alt Session not seen before (or window expired)
                Nudge->>Nudge: writeNudge() to stderr
                Nudge->>Nudge: persist to cache file
            else Already nudged this session/window
                Note over Nudge: Silent skip
            end
        else Skill present
            Presence-->>Nudge: true
            Note over Nudge: Silent skip
        end
    else Human OR CI OR test OR disabled
        Note over Nudge: Silent skip
    end
    Hook-->>CLI: ready

    alt Root help (browse / browse --help)
        CLI->>Help: showRootHelp()
        Help->>Agent: detectAgent()
        Agent-->>Help: agent name
        Help->>Presence: isBrowseSkillInstalled(agent)
        alt Skill MISSING
            Presence-->>Help: false
            Help->>Help: log(AGENT_START_HERE banner)
        else Skill present
            Presence-->>Help: true
            Note over Help: Skip banner
        end
        Help->>Updater: getUpdateNotice() [read-only]
        Updater-->>Help: notice text or null
        alt Notice available
            Help->>Help: process.stderr.write(notice)
        end
        Help-->>CLI: help output
    else Doctor command
        CLI->>Doctor: doctor.run()
        Doctor->>Updater: getUpdateNotice()
        Updater-->>Doctor: notice text or null
        alt Notice available
            Doctor->>Doctor: process.stderr.write(notice)
        end
    else Regular commands (status, get, etc.)
        Note over CLI: NO update notice shown
    end

    par Telemetry (each command)
        CLI->>Telemetry: capture("cli.command_invoked")
        Telemetry->>Agent: detectAgent()
        Telemetry->>Presence: isBrowseSkillInstalled(agent)
        Presence-->>Telemetry: skill_present boolean
        Telemetry-->>CLI: event with skill_present property
    end
Loading

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread .changeset/browse-skill-nudge.md
Comment thread packages/cli/src/lib/help.ts Outdated
shrey150 and others added 2 commits June 6, 2026 18:20
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
browse is released via the decoupled release-cli.yml workflow, which
consumes "browse" changesets; the core ignore list only keeps the
main stagehand release from bumping it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread packages/cli/src/commands/doctor.ts
…anner + once-per-install hint)

Removes agent detection, session keys, and TTL windowing per team review
feedback; detection reduced to one canonical-path check
(~/.agents/skills/browse) plus a once-per-install marker file in the CLI
cache dir (same mechanism as update-check.json / open-nudge.json).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@shrey150 shrey150 changed the title [STG-2191] feat: nudge agents to install the browse skill + de-spam update notice [STG-2191] feat(cli): static browse skill nudge + de-spam update notice Jun 12, 2026
@shrey150

shrey150 commented Jun 12, 2026

Copy link
Copy Markdown
Contributor Author

@Kylejeong2 + team — de-scoped per the review discussion (19921e1 and follow-ups): all dynamic nudge logic (agent detection, session keys, TTL windows) is gone. Current behavior and test evidence are in the PR description.

@shrey150 shrey150 marked this pull request as ready for review June 12, 2026 20:00

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 13 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant User as User / Agent
    participant CLI as browse CLI (oclif)
    participant InitHook as init Hook
    participant HelpClass as BrowseHelp class
    participant DoctorCmd as doctor Command
    participant SkillNudge as maybeNudgeInstallSkill
    participant SkillPres as isBrowseSkillInstalled
    participant UpdateSvc as scheduleBackgroundUpdateCheck
    participant UpdateNotice as getUpdateNotice
    participant FileSys as Filesystem (cache / skill dir)
    participant Telemetry as Telemetry (PostHog)

    Note over User,Telemetry: Initialization (every command)
    CLI->>InitHook: init hook fires
    InitHook->>UpdateSvc: Check cache age (silent, never prints)
    UpdateSvc->>FileSys: Read update-check.json
    alt Cache stale or missing
        UpdateSvc->>FileSys: Spawn background fetch from npm
    end
    InitHook->>SkillNudge: Maybe nudge for skill install
    SkillNudge->>SkillNudge: Check env opt-outs (BROWSE_DISABLE_SKILL_NUDGE, CI, NODE_ENV)
    alt Nudge disabled
        SkillNudge-->>InitHook: Return early
    else Eligible command
        SkillNudge->>SkillNudge: Check commandId is not help/skills
        SkillNudge->>FileSys: Check marker file (skill-nudge.json)
        alt Marker exists
            SkillNudge-->>InitHook: Return early
        else No marker
            SkillNudge->>SkillPres: Check canonical skill dir (~/.agents/skills/browse)
            alt Skill installed
                SkillNudge-->>InitHook: Return early
            else Skill absent
                SkillNudge->>FileSys: Write marker file first
                alt Write succeeds
                    SkillNudge->>User: Print stderr tip ("browse skills install")
                else Write fails
                    SkillNudge-->>InitHook: Silent failure, no nudge
                end
            end
        end
    end

    Note over User,Telemetry: Help surface (browse / browse --help)
    User->>CLI: browse or browse --help
    CLI->>HelpClass: showRootHelp()
    HelpClass->>User: Print "Start here (for AI agents)" banner (always-on)
    HelpClass->>CLI: super.showRootHelp()
    HelpClass->>UpdateNotice: Get update notice from cache
    UpdateNotice->>FileSys: Read update-check.json
    alt Fresh cache with newer version
        UpdateNotice-->>HelpClass: Formatted notice string
        HelpClass->>User: Print stderr update notice
    else No update or stale cache
        UpdateNotice-->>HelpClass: null (silent)
    end

    Note over User,Telemetry: Doctor surface (browse doctor)
    User->>CLI: browse doctor
    CLI->>DoctorCmd: run()
    DoctorCmd->>DoctorCmd: Build & print doctor report
    DoctorCmd->>UpdateNotice: Get update notice from cache
    UpdateNotice->>FileSys: Read update-check.json
    alt Fresh cache with newer version
        UpdateNotice-->>DoctorCmd: Formatted notice string
        DoctorCmd->>User: Print stderr update notice
    end

    Note over User,Telemetry: Telemetry (every command)
    CLI->>Telemetry: capture(command_invoked/command_completed)
    Telemetry->>SkillPres: Check skill installation
    SkillPres->>FileSys: access(~/.agents/skills/browse)
    FileSys-->>SkillPres: Exists or not
    SkillPres-->>Telemetry: boolean
    Telemetry->>Telemetry: Include skill_present property
    Telemetry-->>PostHog: Send event

    Note over User,Telemetry: Regular commands (no update notice)
    User->>CLI: browse get / screenshot / status
    CLI->>CLI: Execute command (no update notice, no nudge after first run)
Loading

Re-trigger cubic

Comment thread packages/cli/src/commands/doctor.ts
Comment thread packages/cli/src/lib/update.ts
…lar commands

Any command (browse [X]) prints the notice the first time a new release is
seen in the cache, then stays silent until the next release. No time windows
or session keys — state is a notifiedVersion field in the existing
update-check.json. help/doctor keep rendering it and mark it as seen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Fix all with cubic | Re-trigger cubic

Comment thread packages/cli/src/lib/update.ts
shrey150 and others added 5 commits June 12, 2026 16:39
…arity)

Replaces the once-per-release push with codex's semantics
(codex-rs/tui/src/updates.rs: upgrade banner every session until upgraded,
20h check interval): regular commands remind while outdated, deduped to
once per 20h via lastNotifiedAt in update-check.json. help/doctor always
render and refresh the marker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The skills CLI resolves join(global ? homedir() : cwd, '.agents', 'skills'),
so a project-scoped install lands at <cwd>/.agents/skills/browse — check
both canonical scopes (still just two access() calls, no detection logic).
The public 'browser' skill folder is deliberately not checked: it is being
deprecated in favor of this bundled, CLI-version-pinned skill.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ce per install

The daemon spawn is the natural session boundary: the tip now shows on the
command that starts each browser session while the skill is absent, every
session, until it is installed. Deletes the skill-nudge.json marker and all
cacheFile plumbing — the nudge is now stateless.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants