Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 8 additions & 16 deletions .agents/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,17 @@ When using the following skills, override the default behavior.
- For issue-backed work, start the filename with the ticket number instead of `date+ticket`. Example: `docs/plans/4510-fix-schema.md`
- For non-ticket work, keep the date-based format. Example: `docs/plans/2026-02-07-fix-schema.md`

`dev-browser`:

- Use `dev-browser --connect http://127.0.0.1:9222` by default for browser work. Do not preflight `9222` first.
- Only inspect `9222` or use `browser-debug-setup` after a direct `dev-browser --connect http://127.0.0.1:9222` attempt fails.
- Reuse one persistent debug Chrome on `127.0.0.1:9222`. Do not spin up disposable browser instances unless the user asks.
- Use a dedicated Chrome `--user-data-dir` for that debug browser, not the user's normal daily Chrome data dir.
- Clone the signed-in Chrome profile into the dedicated debug dir, then launch the debug browser from that clone.
- On macOS, launch the debug browser with `open -na "Google Chrome" --args ... --remote-debugging-port=9222` so it opens as a separate Chrome instance without hijacking the user's normal window.
- Do not close or stop the user's connected debug browser. Leave that debug window open and reuse it. Close named pages only when needed.
- Keep scripts small and direct. Prefer `browser.getPage("persistent-main")` for the main app.
- Use `dev-browser` instead of `agent-browser` or next-devtools `browser_eval`.
- If `dev-browser` gets blocked by a human prompt or loops on the same step, stop and ask the user to unblock. After the unblock works:
- For Plate registry/browser proof, prefer `/blocks/[id]-demo` over docs wrappers when that standalone demo route exists.
Browser usage:

- Always try `[@browser-use](plugin://browser-use@openai-bundled)` first for browser usage.
- Do not substitute Puppeteer, standalone Playwright, or raw Chrome DevTools for browser usage.
- For Plate registry/browser proof, prefer `/blocks/[id]-demo` over docs wrappers when that standalone demo route exists.

`ce-*`:

- **plan:** Include `dev-browser` in acceptance criteria for browser features
- **plan:** Include Browser Use in acceptance criteria for browser features
- **deepen-plan:** Context7 only when not covered by skills
- **work:** UI tasks require `dev-browser` BEFORE marking complete. Never guess.
- **work:** UI tasks require Browser Use BEFORE marking complete. Never guess.

## Commands

Expand Down Expand Up @@ -185,7 +177,7 @@ pnpm --filter @platejs/core lint:fix
- [ ] Typecheck (IF updated `.ts` files or typed test/build config): For package-scoped verification, follow the build-first sequence: `pnpm install` -> `pnpm turbo build --filter=...` -> `pnpm turbo typecheck --filter=...`. If unresolved workspace imports remain, run `pnpm build` at repo root, then rerun the package typecheck. For full repo verification, use `pnpm typecheck`. Do not default to `pnpm typecheck` for package verification.
- [ ] Lint: Run `lint:fix`
- [ ] PR gate (IF creating/updating a PR): Run `check`
- [ ] Browser verification (IF a browser surface changed): verify with `dev-browser` before done
- [ ] Browser verification (IF a browser surface changed): verify with Browser Use before done
- [ ] ce-compound (SKIP if trivial): CRITICAL: After completing this request, you MUST evaluate whether it produced extractable knowledge. EVALUATION PROTOCOL (NON-NEGOTIABLE): (1) COMPLETE the user's request first (2) EVALUATE - Did this require non-obvious investigation or debugging? Was the solution something that would help in future similar situations? Did I discover something not immediately obvious from documentation? (3) IF YES to any: load `ce-compound` after the fix is verified and follow its workflow to capture the solution in `docs/solutions/` (4) IF NO to all: Skip - no extraction needed This is NOT optional. Failing to evaluate = valuable knowledge lost.

### Post Compact Recovery
Expand Down
2 changes: 1 addition & 1 deletion .agents/rules/agent-browser-issue.mdc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: Open a concise GitHub follow-up for reusable dev-browser or agent-browser limitations. Use when browser automation is blocked by a likely tool-side issue that is worth fixing separately, especially for clicks, dropdowns, file inputs, focus traps, or other repeatable agent/browser failures.
description: Open a concise GitHub follow-up for reusable browser-use limitations. Use when browser automation is blocked by a likely tool-side issue that is worth fixing separately, especially for clicks, dropdowns, file inputs, focus traps, or other repeatable agent/browser failures.
argument-hint: '[browser block summary]'
disable-model-invocation: true
---
Expand Down
124 changes: 0 additions & 124 deletions .agents/rules/browser-debug-setup.mdc

This file was deleted.

130 changes: 130 additions & 0 deletions .agents/rules/dev-browser.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
description: Fallback browser automation with persistent Chrome state. Use only when Browser Use is unavailable or blocked.
---

# Dev Browser

Use this only as the fallback browser path when `[@browser-use](plugin://browser-use@openai-bundled)` is unavailable or blocked.

Do not substitute Puppeteer, standalone Playwright, or raw Chrome DevTools for this fallback path.

## Installation

```bash
npm install -g dev-browser
dev-browser install
```

Run `dev-browser --help` to learn more.

## Plate Defaults

- Use `dev-browser --connect http://127.0.0.1:9222` by default. Do not preflight `9222` first.
- Only inspect `9222` after a direct `dev-browser --connect http://127.0.0.1:9222` attempt fails.
- Reuse one persistent debug Chrome on `127.0.0.1:9222`. Do not spin up disposable browser instances unless the user asks.
- Use a dedicated Chrome `--user-data-dir` for that debug browser, not the user's normal daily Chrome data dir.
- Clone the signed-in Chrome profile into the dedicated debug dir, then launch the debug browser from that clone.
- On macOS, launch the debug browser with `open -na "Google Chrome" --args ... --remote-debugging-port=9222` so it opens as a separate Chrome instance without hijacking the user's normal window.
- Do not close or stop the user's connected debug browser. Leave that debug window open and reuse it. Close named pages only when needed.
- Keep scripts small and direct. Prefer `browser.getPage("persistent-main")` for the main app.
- Use `dev-browser` instead of `agent-browser` or next-devtools `browser_eval`.
- For Plate registry/browser proof, prefer `/blocks/[id]-demo` over docs wrappers when that standalone demo route exists.
- If `dev-browser` gets blocked by a human prompt or loops on the same step, stop and ask the user to unblock.

## Fallback Setup

Use this only after `dev-browser --connect http://127.0.0.1:9222` fails because no reusable debug Chrome is available or the CDP endpoint is broken.

## Rules

- Prefer one permanent debug browser/profile over disposable automation browsers.
- Treat a custom `--user-data-dir` as mandatory, not optional. Chrome 136+ expects remote debugging to happen from a dedicated profile.
- Keep auth in that profile. Do not fall back to cookie dumps or state files unless the user asks.
- Use a separate signed-in Chrome profile for browser work, like `dev`. Do not use the user's normal daily `Default` profile as the source profile.
- Clone that separate signed-in Chrome profile into the dedicated debug `--user-data-dir`; do not point `9222` straight at the user's daily Chrome data dir.
- On macOS, use `open -na "Google Chrome" --args ...` for the debug browser. That starts a separate Chrome instance with the dedicated debug profile without touching the user's normal Chrome window.

## Preferred Shape

Use a dedicated browser/profile with:

- `--remote-debugging-address=127.0.0.1`
- `--remote-debugging-port=9222`
- a persistent `--user-data-dir=<debug-profile-dir>`

Sign in once in that dedicated browser and keep reusing it for agent work.

Quick sanity check:

```bash
curl -sS http://127.0.0.1:9222/json/version
```

Healthy output includes a JSON object with `webSocketDebuggerUrl`. Empty output or `404` means the wrong process owns `9222`.

Then verify:

```bash
dev-browser --connect http://127.0.0.1:9222 <<'EOF'
const page = await browser.getPage("persistent-main");
console.log(await page.title());
EOF
```

If direct connect still cannot resolve CDP even though `/json/version` is healthy, connect with the exact websocket URL:

```bash
WS=$(curl -sS http://127.0.0.1:9222/json/version | jq -r '.webSocketDebuggerUrl')

dev-browser --connect "$WS" <<'EOF'
const page = await browser.getPage("persistent-main");
console.log(await page.title());
EOF
```

## Google Chrome Path

Default setup on macOS:

1. Pick a separate signed-in Chrome profile for agent work, like `dev`, not the daily `Default` profile.
2. Map that human-facing Chrome profile name to the real folder in `Local State`.
3. Clone that profile into the dedicated debug dir.
4. Launch a separate Chrome instance on `9222`.
5. Leave that debug window open and reuse it.

```bash
python3 - <<'PY'
import json, pathlib
p = pathlib.Path('~/Library/Application Support/Google/Chrome/Local State').expanduser()
obj = json.loads(p.read_text())
for key, val in obj.get('profile', {}).get('info_cache', {}).items():
print(f"{key}\tname={val.get('name')}\tgaia_name={val.get('gaia_name')}")
PY

# Example: if `dev` maps to `Profile 1`, clone `Profile 1`.
mkdir -p "$HOME/.config/google-chrome-debug-profile/Default"
rsync -a --delete \
--exclude='Singleton*' \
--exclude='DevToolsActivePort' \
--exclude='lockfile' \
"$HOME/Library/Application Support/Google/Chrome/Profile 1/" \
"$HOME/.config/google-chrome-debug-profile/Default/"
cp "$HOME/Library/Application Support/Google/Chrome/Local State" \
"$HOME/.config/google-chrome-debug-profile/Local State"

open -na "Google Chrome" --args \
--user-data-dir="$HOME/.config/google-chrome-debug-profile" \
--profile-directory="Default" \
--remote-debugging-address=127.0.0.1 \
--remote-debugging-port=9222
```

Do not point `9222` at the normal daily `Default` Chrome profile.

If the wrong Chrome steals `9222`, identify it with:

```bash
lsof -nP -iTCP:9222 -sTCP:LISTEN
```

Kill that listener and relaunch the dedicated debug browser. Do not keep debugging against a stale `404` or empty `/json/version` owner.
Loading
Loading