Skip to content

feat: headed browser with agent overlay, update command, skill management#88

Open
NisargIO wants to merge 44 commits intomainfrom
first-minor
Open

feat: headed browser with agent overlay, update command, skill management#88
NisargIO wants to merge 44 commits intomainfrom
first-minor

Conversation

@NisargIO
Copy link
Copy Markdown
Member

@NisargIO NisargIO commented Apr 6, 2026

Summary

This PR replaces the rrweb-based live replay system with a headed Chrome browser session that renders an in-page agent overlay, adds an expect update command for CLI self-upgrades, overhauls skill installation logic, and cleans up replay-related dead code throughout the stack.


Headed browser + agent overlay (@expect/browser)

New: System Chrome launcher (chrome-launcher.ts)

  • Discovers system Chrome/Chromium/Edge/Brave/Arc across macOS, Linux, and Windows
  • Launches with --remote-debugging-port=0 and polls DevToolsActivePort for the CDP WebSocket URL
  • New parseDevToolsActivePort utility for parsing Chrome's debug port file
  • Container-aware: adds --no-sandbox / --disable-dev-shm-usage in CI
  • New errors: ChromeNotFoundError, ChromeLaunchTimeoutError

New: In-page overlay (runtime/overlay/)

  • React-based overlay injected into the browser page with animated cursor (pointer/hand/text variants), action markers, toolbar controls, spiral spinner, and glow effects
  • OverlayController service manages cursor positioning, element highlighting, and action logging
  • Parses ref("...") patterns and CSS selectors from Playwright code to position the cursor on the target element
  • Overlay is hidden during screenshots/snapshots via withHidden to keep captures clean
  • Tailwind CSS build with a css-rem-to-px.js postprocessor for consistent sizing in injected contexts

Removed: rrweb + live replay system

  • Deleted recorder.ts (rrweb injection), replay-viewer.ts (HTML replay builder), rrvideo.ts (session-to-MP4 converter), live-view-server.ts (SSE server for live replay), viewer-events.ts
  • Deleted corresponding tests: recorder.test.ts, rrvideo.test.ts, live-view-server.test.ts
  • Removed rrweb, @rrweb/types, rrweb-player, rrvideo dependencies
  • Runtime files reorganized: overlay.tslib/annotation-overlay.ts, performance.ts and scroll-detection.ts moved under lib/

McpSession changes

  • Default mode is now headed (was headless). EXPECT_HEADED_ENV_NAME replaces EXPECT_LIVE_VIEW_URL_ENV_NAME
  • Removed replayOutputPath, accumulatedReplayEvents, replay polling fiber, and LiveViewHandle from session state
  • Added cleanup callback and isExternalBrowser flag to BrowserSessionData
  • Network request tracking uses a Map<string, NetworkEntry[]> keyed by method:url instead of linear .find() scan
  • Cookie pre-extraction now uses Deferred for proper async coordination instead of fire-and-forget
  • CloseResult no longer includes replaySessionPath, reportPath, tmpReplaySessionPath, tmpReportPath
  • cdpUrl option changed from string | undefined to Option.Option<string>
  • Video dimensions changed from 960x540 to 1920x1080

MCP server changes (server.ts)

  • OverlayController + FileSystem added to the MCP runtime context
  • playwright tool gains a description parameter — shown as the overlay cursor tooltip
  • Every tool call updates the overlay label (e.g. "Navigating to ...", "Taking screenshot", "Running accessibility audit")
  • Overlay cursor is positioned before code execution based on ref/selector extraction
  • Screenshots and snapshots are taken with overlay hidden
  • close tool no longer emits rrweb replay: or rrweb report: lines
  • CDP auto discovery option removed from the open tool; system Chrome is used automatically when headed
  • Performance trace file I/O switched from mkdirSync/writeFileSync to Effect FileSystem

MCP resources cleanup

  • Removed all bundled Effect pattern reference docs (~3,180 lines): effect-patterns/rule.md, effect/rule.md, and 8 reference files under effect/references/
  • Minor whitespace fixes in two React rule files

CLI: expect update command

  • New update subcommand: expect update [version] for global CLI upgrades
  • Detects the package manager that installed expect (npm/pnpm/yarn/bun/deno) and runs the corresponding global install
  • Supports version pins (expect update 0.0.30) and dist-tags (expect update latest)
  • After updating, checks if the installed expect skill is outdated and prompts to update it
  • Both async (runUpdateCommand) and sync (runUpdateCommandSync) variants for different contexts
  • Tests for getGlobalInstallCommand and normalizeVersionSpecifier

Skill management overhaul

New: expect-skill.ts utility

  • getExpectSkillStatus() — checks if the skill is installed and compares content against GitHub's latest via raw URL fetch
  • readInstalledSkill() / fetchLatestSkill() — Effect-based with proper error types (ExpectSkillReadError, ExpectSkillFetchError) and timeout
  • detectInstalledSkillAgents() — finds which agents have the skill installed
  • hasInstalledExpectSkill() — replaces the old isSkillInstalled() check that only looked at .agents/skills/expect
  • Version extracted from SKILL.md via regex (version: "...")

Improved add-skill.ts

  • Skill download wrapped in Effect with ExpectSkillDownloadError and timeout
  • Smart skip: if the installed skill content matches GitHub latest, skips re-download
  • Symlink handling: ensureAgentSymlink now returns "linked" | "already-linked" | string — replaces broken symlinks and non-symlink directories (previously errored)
  • Context-aware messaging: different success messages for "installed", "updated", "current" (already latest), and "unverified" (couldn't reach GitHub) states
  • Tests for new status detection and symlink behavior

CLI UX changes

Default headed mode

  • --headed flag removed, replaced with --headless flag
  • Default is now headed in interactive mode, headless in CI
  • browserHeaded preference now defaults to true (was false)
  • watch command: opts.headless ? false : (opts.headed ?? true)

Results screen

  • Removed all replay URL display (replay URL, local replay URL)
  • Added a RuledBox guidance section telling users to press y to copy, s to save, r to rerun, p to post to PR
  • Copy-to-clipboard feedback messages are more actionable ("Copied test summary. Paste it into your chat or PR.")
  • Added Summary section showing the session summary when present
  • Only video URL shown as artifact link

Plain-text report (models.ts)

  • toPlainText now includes the session summary text when it differs from the pass/fail count line

Execution prompt (prompts.ts)

  • <session-summary> in RUN_COMPLETED now has detailed instructions: must be a single dense line covering what was verified, bugs found, blockers, learnings, and answers to developer questions
  • New step 6 in run completion: "Compose the session summary for RUN_COMPLETED"

Removed replay proxy infrastructure

  • Deleted replay-proxy-server.ts (~209 lines), push-step-state.ts (~57 lines), load-replay-events.ts (~42 lines)
  • Deleted load-replay-events.test.ts
  • execution-atom.ts: removed syncReplayProxy, pushStepState, startReplayProxy, random port picking, replayUrl/localReplayUrl from ExecutionResult
  • extract-close-artifacts.ts: removed replaySessionPath, replayPath, localReplayUrl from CloseArtifacts; uses findLast instead of .slice().reverse().find()

Cookie + browser fixes

  • Browsers.list filters out Chromium's "System Profile" — not a real user profile, was causing noise
  • run-test.ts: removed rrweb-to-MP4 video generation path (RrVideo.convert call); only Playwright video is used now
  • replayHost option removed from preferences store and all CLI flags

Supervisor changes

  • ExecuteOptions: removed liveViewUrl, added isHeadless (passed as EXPECT_HEADED_ENV_NAME to MCP env)
  • Removed EXPECT_REPLAY_OUTPUT_ENV_NAME and replay output path construction from executor
  • Removed EXPECT_STATE_DIR import (no longer needed for replay paths)

Other

  • analytics.ts: Effect.tryPromise for safer async capture
  • Error type cleanup in execution-atom.ts: uses Predicate.isObject and Predicate.isError instead of manual checks
  • detect-project.ts, git.ts, ensure-state-dir.ts: minor import/path adjustments
  • tsconfig.json: added "jsx": "react-jsx" for overlay component compilation
  • pnpm-lock.yaml: updated with removed rrweb deps and added which dependency

Test plan

  • pnpm typecheck passes
  • pnpm test passes (new tests for chrome-launcher, parse-devtools-active-port, mcp-session, update command, expect-skill, add-skill)
  • pnpm build succeeds

Note

Medium Risk
Behavior-changing CLI/setup refactor (browser mode defaults/flags, skill install semantics, new global update path) that can impact developer workflows and installation reliability, though changes are localized to tooling not production runtime.

Overview
CLI setup and runtime flow is reworked to prefer real browser sessions over rrweb replay. The PR removes replay/live-preview plumbing (replay proxy, step-state push, replay artifact parsing/display) and simplifies execution results to only surface Playwright video artifacts.

Init/CLI UX now supports explicit browser connection modes. Adds a persisted .expect/config.json (cdp/headed/headless), updates flags to --browser-mode/--profile, adds CDP detection/onboarding during init, and deprecates the interactive TUI with an in-app warning banner.

Skill + install management is overhauled. Skill install switches from per-agent symlinks to copying, adds version/latest checks against GitHub with timeouts and structured errors, and introduces a new expect update [version] command (with sync variant used by the TUI) that updates the global install and can prompt to update the installed skill. Also removes the audit command and standardizes Node built-in imports to namespace form.

Reviewed by Cursor Bugbot for commit 020fb70. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Apr 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
expect Ready Ready Preview, Comment Apr 7, 2026 8:23am

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 6, 2026

Open in StackBlitz

npm i https://pkg.pr.new/expect-cli@88

commit: 5e9e6bc

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

5 issues found across 34 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/cli/src/commands/add-skill.ts">

<violation number="1" location="apps/cli/src/commands/add-skill.ts:165">
P1: Avoid recursively deleting existing non-symlink skill paths; this can silently remove user data.</violation>
</file>

<file name=".specs/chrome-extension.md">

<violation number="1" location=".specs/chrome-extension.md:128">
P2: The Comlink adapter spec registers wrapped listeners but does not remove the same callback reference, so listener cleanup is broken and can lead to duplicate message handling.</violation>
</file>

<file name="packages/browser/tests/chrome-launcher.test.ts">

<violation number="1" location="packages/browser/tests/chrome-launcher.test.ts:69">
P2: This test claims to verify candidate priority order, but `toHaveBeenCalledWith` does not assert order. Use nth-call assertions so the test fails when lookup sequence changes.</violation>
</file>

<file name="packages/browser/src/utils/parse-devtools-active-port.ts">

<violation number="1" location="packages/browser/src/utils/parse-devtools-active-port.ts:10">
P2: Port validation is too permissive; malformed or out-of-range ports are accepted as valid.</violation>
</file>

<file name="packages/browser/src/browser.ts">

<violation number="1" location="packages/browser/src/browser.ts:280">
P1: CDP-connected sessions are incorrectly marked as internal, so closing a session can shut down the user’s external browser instance.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

@aidenybai aidenybai changed the title feat: first minor feat: headed browser, update command, and UX improvements Apr 7, 2026
@aidenybai aidenybai changed the title feat: headed browser, update command, and UX improvements feat: headed browser with agent overlay, update command, skill management Apr 7, 2026
Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

7 issues found across 97 files (changes from recent commits).

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed. We prioritized the most important files first.

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/browser/src/mcp/resources/react/rules/advanced-effect-event-deps.md">

<violation number="1" location="packages/browser/src/mcp/resources/react/rules/advanced-effect-event-deps.md:3">
P2: The rule metadata block is malformed: `title` was turned into a Markdown heading, which breaks frontmatter parsing for this doc.</violation>
</file>

<file name="packages/browser/src/mcp/mcp-session.ts">

<violation number="1" location="packages/browser/src/mcp/mcp-session.ts:469">
P2: Only set tmpVideoPath when the copy succeeds; otherwise it can reference a file that wasn’t created after a copy failure.</violation>
</file>

<file name="packages/browser/src/runtime/overlay/lib/use-polled-positions.ts">

<violation number="1" location="packages/browser/src/runtime/overlay/lib/use-polled-positions.ts:38">
P1: The effect is missing `enabled` and `compute` in its dependencies, which can leave polling stuck off/on or using stale computation logic.</violation>
</file>

<file name="packages/browser/src/mcp/overlay-controller.ts">

<violation number="1" location="packages/browser/src/mcp/overlay-controller.ts:116">
P2: If selector resolution fails, `moveCursorToSelector` returns without updating the overlay label, and `positionCursorForCode` has already returned. This leaves stale/missing action text for many `getByRole`/`getByText` commands.</violation>
</file>

<file name="packages/browser/package.json">

<violation number="1" location="packages/browser/package.json:13">
P3: `mkdir -p` in the npm script is not Windows-compatible, so `pnpm build:css` will fail on Windows shells. Use a Node-based mkdir to keep the build cross-platform.</violation>
</file>

<file name="packages/browser/src/mcp/resources/react/rules/advanced-use-latest.md">

<violation number="1" location="packages/browser/src/mcp/resources/react/rules/advanced-use-latest.md:3">
P2: The `title` frontmatter key was accidentally converted to Markdown heading syntax, so metadata parsers will not read a `title` field.</violation>
</file>

<file name="packages/browser/src/browser.ts">

<violation number="1" location="packages/browser/src/browser.ts:431">
P2: If injectOverlayLabels fails, the agent overlay stays hidden because the hide call is outside the cleanup. Wrap hide/inject/screenshot in the ensuring block so the overlay is always restored.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment on lines +3 to 8
## title: Do Not Put Effect Events in Dependency Arrays

impact: LOW
impactDescription: avoids unnecessary effect re-runs and lint errors
tags: advanced, hooks, useEffectEvent, dependencies, effects
---

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: The rule metadata block is malformed: title was turned into a Markdown heading, which breaks frontmatter parsing for this doc.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/browser/src/mcp/resources/react/rules/advanced-effect-event-deps.md, line 3:

<comment>The rule metadata block is malformed: `title` was turned into a Markdown heading, which breaks frontmatter parsing for this doc.</comment>

<file context>
@@ -1,9 +1,10 @@
 ---
-title: Do Not Put Effect Events in Dependency Arrays
+
+## title: Do Not Put Effect Events in Dependency Arrays
+
 impact: LOW
</file context>
Suggested change
## title: Do Not Put Effect Events in Dependency Arrays
impact: LOW
impactDescription: avoids unnecessary effect re-runs and lint errors
tags: advanced, hooks, useEffectEvent, dependencies, effects
---
title: Do Not Put Effect Events in Dependency Arrays
impact: LOW
impactDescription: avoids unnecessary effect re-runs and lint errors
tags: advanced, hooks, useEffectEvent, dependencies, effects
---
Fix with Cubic

Comment on lines +3 to 7
## title: useEffectEvent for Stable Callback Refs

impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useEffectEvent, refs, optimization
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: The title frontmatter key was accidentally converted to Markdown heading syntax, so metadata parsers will not read a title field.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/browser/src/mcp/resources/react/rules/advanced-use-latest.md, line 3:

<comment>The `title` frontmatter key was accidentally converted to Markdown heading syntax, so metadata parsers will not read a `title` field.</comment>

<file context>
@@ -1,9 +1,10 @@
 ---
-title: useEffectEvent for Stable Callback Refs
+
+## title: useEffectEvent for Stable Callback Refs
+
 impact: LOW
</file context>
Suggested change
## title: useEffectEvent for Stable Callback Refs
impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useEffectEvent, refs, optimization
title: useEffectEvent for Stable Callback Refs
impact: LOW
impactDescription: prevents effect re-runs
tags: advanced, hooks, useEffectEvent, refs, optimization
---
Fix with Cubic

},
"scripts": {
"build": "node scripts/build-runtime.js",
"build:css": "mkdir -p dist && pnpm exec tailwindcss -i ./src/runtime/overlay/index.css -o ./dist/overlay.css -m && node scripts/css-rem-to-px.js",
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P3: mkdir -p in the npm script is not Windows-compatible, so pnpm build:css will fail on Windows shells. Use a Node-based mkdir to keep the build cross-platform.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/browser/package.json, line 13:

<comment>`mkdir -p` in the npm script is not Windows-compatible, so `pnpm build:css` will fail on Windows shells. Use a Node-based mkdir to keep the build cross-platform.</comment>

<file context>
@@ -10,7 +10,8 @@
   },
   "scripts": {
-    "build": "node scripts/build-runtime.js",
+    "build:css": "mkdir -p dist && pnpm exec tailwindcss -i ./src/runtime/overlay/index.css -o ./dist/overlay.css -m && node scripts/css-rem-to-px.js",
+    "build": "pnpm build:css && node scripts/build-runtime.js",
     "lint": "vp lint && tsc --noEmit",
</file context>
Suggested change
"build:css": "mkdir -p dist && pnpm exec tailwindcss -i ./src/runtime/overlay/index.css -o ./dist/overlay.css -m && node scripts/css-rem-to-px.js",
"build:css": "node -e \"require('fs').mkdirSync('dist', { recursive: true })\" && pnpm exec tailwindcss -i ./src/runtime/overlay/index.css -o ./dist/overlay.css -m && node scripts/css-rem-to-px.js",
Fix with Cubic

cookieBrowserKeys,
baseUrls,
devServerHints,
replayHost,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Missing browserProfile in useEffect dependency array

Medium Severity

The newly added browserProfile state variable is read inside the useEffect callback (passed as profileName: browserProfile) but is not listed in the dependency array. This is a stale closure bug — if the profile preference changes, the effect won't re-trigger, and the execution will use the stale profile value captured at initial render time.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c900492. Configure here.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

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

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/cli/src/components/screens/testing-screen.tsx">

<violation number="1" location="apps/cli/src/components/screens/testing-screen.tsx:423">
P2: `browserProfile` is used inside the `useEffect` that triggers execution, but it is missing from the effect dependency array, causing stale profile values when preferences change.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

changesFor,
instruction,
isHeadless: !browserHeaded,
profileName: browserProfile,
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: browserProfile is used inside the useEffect that triggers execution, but it is missing from the effect dependency array, causing stale profile values when preferences change.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/cli/src/components/screens/testing-screen.tsx, line 423:

<comment>`browserProfile` is used inside the `useEffect` that triggers execution, but it is missing from the effect dependency array, causing stale profile values when preferences change.</comment>

<file context>
@@ -419,6 +420,7 @@ export const TestingScreen = ({
         changesFor,
         instruction,
         isHeadless: !browserHeaded,
+        profileName: browserProfile,
         cookieBrowserKeys: [...cookieBrowserKeys],
         savedFlow,
</file context>
Fix with Cubic

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

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

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/cli/src/commands/init.ts">

<violation number="1" location="apps/cli/src/commands/init.ts:275">
P2: `expect init -y` is no longer non-interactive because browser mode is always prompted when no mode flag is provided.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

Comment on lines +275 to +278
let browserMode = await promptBrowserMode(flagMode);

logger.break();

if (await Effect.runPromise(hasGitHubRemote)) {
let setupGithubAction = nonInteractive;

if (!nonInteractive) {
const response = await prompts({
type: "confirm",
name: "setupGithubAction",
message: `Set up ${highlighter.info("GitHub Actions")} to continuously test every PR in CI?`,
initial: true,
});
setupGithubAction = response.setupGithubAction;
if (browserMode === "cdp") {
const cdpAvailable = await handleCdpSetup(Boolean(flagMode));
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai bot Apr 7, 2026

Choose a reason for hiding this comment

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

P2: expect init -y is no longer non-interactive because browser mode is always prompted when no mode flag is provided.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/cli/src/commands/init.ts, line 275:

<comment>`expect init -y` is no longer non-interactive because browser mode is always prompted when no mode flag is provided.</comment>

<file context>
@@ -91,61 +230,60 @@ export const runInit = async (options: InitOptions = {}) => {
-    );
-  }
+  const flagMode = resolveBrowserModeFromFlags(options);
+  let browserMode = await promptBrowserMode(flagMode);
 
-  logger.break();
</file context>
Suggested change
let browserMode = await promptBrowserMode(flagMode);
logger.break();
if (await Effect.runPromise(hasGitHubRemote)) {
let setupGithubAction = nonInteractive;
if (!nonInteractive) {
const response = await prompts({
type: "confirm",
name: "setupGithubAction",
message: `Set up ${highlighter.info("GitHub Actions")} to continuously test every PR in CI?`,
initial: true,
});
setupGithubAction = response.setupGithubAction;
if (browserMode === "cdp") {
const cdpAvailable = await handleCdpSetup(Boolean(flagMode));
let browserMode = options.yes ? (flagMode ?? "cdp") : await promptBrowserMode(flagMode);
if (browserMode === "cdp") {
const cdpAvailable = await handleCdpSetup(Boolean(flagMode) || Boolean(options.yes));
Fix with Cubic


vi.mock("../src/commands/update", () => ({
detectPackageManager: vi.fn().mockReturnValue("npm"),
getGlobalInstallCommand: vi.fn().mockReturnValue(["npm", ["install", "-g", "expect-cli"]]),
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Test mock returns wrong type for getGlobalInstallCommand

Low Severity

The mock for getGlobalInstallCommand returns a plain array ["npm", ["install", "-g", "expect-cli"]] instead of an InstallCommand object { binary: "npm", args: ["install", "-g", "expect-cli"] }. Since runInstallCommand and formatInstallCommand are also mocked, this doesn't cause test failures currently, but it means tests don't catch regressions if init.ts ever accesses .binary or .args on the command directly.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a73adf2. Configure here.

Copy link
Copy Markdown
Contributor

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

Choose a reason for hiding this comment

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

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

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/cli/tests/init-flow.test.ts">

<violation number="1" location="apps/cli/tests/init-flow.test.ts:156">
P2: This test bypasses the prompt path it claims to validate by passing `cdp: true`, so invalid prompt handling is not actually tested.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

};

const maybePromptForSkillUpdate = async () => {
const projectRoot = process.cwd();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Inconsistent project root resolution in skill update

Medium Severity

maybePromptForSkillUpdate uses process.cwd() for the project root, while all other skill-related functions (runAddSkill, promptSkillInstall, writeExpectConfig) use resolveProjectRoot() which finds the git repository root. When expect update is run from a subdirectory, detectInstalledSkillAgents won't find the skills (installed at the git root), causing the function to silently skip the skill update prompt.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 7380b2e. Configure here.

- Replace --headed/--headless with unified --browser-mode <cdp|headed|headless>
- Warn on invalid browser mode values
- Add apps/demo: Twitter/X-like social feed (Vite + React + shadcn + Lucide)
- Update READMEs with new options table
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 2 potential issues.

There are 5 total unresolved issues (including 3 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9c24e87. Configure here.

node dist/index.js \
-u https://gym.ami.construction/dashboard \
-m "Test the dashboard. Click around, check that pages load, verify navigation works, and look for any broken UI or errors." \
-y
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Accidentally committed project-specific test script

Low Severity

This script hardcodes a URL to a specific external project (https://gym.ami.construction/dashboard) and a specific test instruction. It appears to be a personal development/debugging script that was unintentionally included in the commit, not a general-purpose project utility.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9c24e87. Configure here.

- Introduced an array of usage prompts to guide users on testing changes in the browser.
- Updated the logUsageGuide function to display these prompts instead of a single message.
- Updated the project root resolution to utilize the Effect library for improved error handling and asynchronous behavior.
- Removed the previous synchronous git command execution in favor of a more robust solution in the supervisor package.
NisargIO added 2 commits April 6, 2026 23:34
- Refactored the mock return values for 'node:os' and 'node:fs' to remove the default property, ensuring compatibility with the latest testing framework updates.
- Added '@effect/platform-node' dependency with version 4.0.0-beta.35.
- Updated '@modelcontextprotocol/sdk' dependency to use zod@4.3.6.
- Removed outdated zod-to-json-schema dependency version.
- Introduced new error type 'AcpSessionCreateError' in agent.ts for improved error handling.
- Removed 'AcpSessionCreateError' from the AgentLayerError type definition to streamline error handling and improve code clarity.
- Updated error handling in AcpAdapter to replace 'AcpSessionCreateError' with 'AcpConnectionInitError' for improved clarity and consistency during connection initialization failures.
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.

3 participants