[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6RTSEMB6H6DEN79BK9KDEE7":3,"skill-same:01M6RTSEMB6H6DEN79BK9KDEE7":77},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":45,"commitSha":46,"skillDirectory":47,"forksCount":13,"repositoryHtmlUrl":48,"repositoryHomepageUrl":6,"ownerHtmlUrl":49,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":50,"install":51,"resources":64},"01M6RTSEMB6H6DEN79BK9KDEE7","continuous-learning",null,"[DEPRECATED - use continuous-learning-v2] Legacy v1 stop-hook skill extractor. v2 is a strict superset with instinct-based, project-scoped, hook-reliable learning. Do not invoke v1; route continuous learning, session learning, and pattern extraction requests to continuous-learning-v2.","sakamoto-family-smile\u002Fagent_monorepo","sakamoto-family-smile","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F132812403?v=4","01M6RTAT3H8PMWX5SJ65KP3VYF","01M6RTAV321WB5RAHCWTZMX5CV",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fcontinuous-learning\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"learning","continuous learning","invoke","superset","skill extractor","scoped","deprecated","v1","requests","hook","with","pattern extraction","project","pattern","route","do","stop","Legacy","use","session","2026-11-10 10:12:30",false,"---\nname: debug-ui\ndescription: Drive and visually QA the dev-3.0 UI in a real browser (headless Chromium via agent-browser). Use when verifying a UI\u002FUX change, reproducing a visual bug, taking screenshots of the running app, or self-QA before review. Triggers — \"check the UI\", \"screenshot the app\", \"does this render\", \"QA this screen\", \"verify the UI change in a browser\", \"drive the app\".\n---\n\n# debug-ui — QA the dev-3.0 UI in a real browser\n\nSee and drive the running dev-3.0 UI in headless Chromium — click, type, screenshot, read\nconsole errors — instead of guessing whether a UI change works. No desktop\u002Fnative dependency;\nit works the same in a plain terminal session.\n\nThis is **dev-internal tooling for the dev-3.0 repo** — NOT one of the skills dev3 ships to\nits users (those live in `src\u002Fbun\u002Fagent-skills.ts`).\n\n## Prerequisite: `agent-browser` on PATH\n\nCheck with `agent-browser --version`. If it is missing, install it once per machine, not in the\nproject `setupScript` (that runs for every new worktree):\n\n```bash\nbun add -g agent-browser        # or: npm i -g agent-browser\nagent-browser install           # downloads Chromium; on Linux add --with-deps for system libraries (needs sudo)\n```\n\n## One rule before the flow: the app starts through `dev3 dev-server`, nothing else\n\nEvery QA run in this skill boots the app with `dev3 dev-server start` and takes it down with\n`dev3 dev-server stop`. **Never start the app any other way** — not a bare `bun run dev`, not\n`bun run dev --qa`, and not `dev3 pane run \"bun run dev …\"`. A pane run looks like a shortcut\nand costs you everything the dev-server owns: the port wait (`--wait`), `status` with its port\nconflicts, a verified stop that frees `DEV3_PORT0`, the Dev Server button in the task UI that\nshows the user what is running, and the `show-image` \u002F `attention` routing rules below. If you\nneed the app to behave differently (a throwaway board, an env flag), change what the dev-server\nruns — see \"Scoped QA\" — do not route around it.\n\n## The whole flow\n\nThis task's dev-server **is** the web UI: `bun run dev` serves the full app in local remote\nmode at a stable per-machine token and a CLI-derivable port — no separate `dev3 remote`. The\nloop is always the same four beats: **values → server → browser → clean up.**\n\n```bash\n# 1. Values. AGENT_BROWSER_SESSION isolates THIS task's browser from every other agent's —\n#    without it all agents share one global \"default\" session and stomp each other (see\n#    Gotchas). Derived from the always-present $DEV3_TASK_ID, so this exact line is\n#    copy-paste-safe at the top of ANY block that calls agent-browser.\nexport AGENT_BROWSER_SESSION=\"dev3-${DEV3_TASK_ID%%-*}\"\nCODE=$(cat \"$HOME\u002F.dev3.0\u002Fdev-web-access-code\" 2>\u002Fdev\u002Fnull || bun scripts\u002Fdev-web-code.ts)\nPORT=${DEV3_PORT0:-$(dev3 dev-server status | grep -oE 'DEV3_PORT0=[0-9]+' | cut -d= -f2)}\n\n# 2. Start a FRESH dev-server and wait for it to come up. (Skip the start only if one is\n#    already running for THIS task — but see the build-snapshot gotcha: stale code needs a\n#    restart, so when in doubt restart.)\ndev3 dev-server start\nuntil curl -sf \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE\" >\u002Fdev\u002Fnull; do sleep 2; done\n\n# 3. Drive it. Every agent-browser call inherits AGENT_BROWSER_SESSION, so it all runs in\n#    this task's own session. (Load \u002Fagent-browser for the full command set.) The screenshot\n#    path is task-scoped too, so parallel agents never overwrite each other's PNG.\n#    `&streamer=on` is MANDATORY: it enables streamer mode (privacy masking), so screenshots\n#    can't leak the developer's real emails\u002Faccounts\u002Fpaths\u002Ftunnel URLs (see Gotchas).\n#    Keep `set viewport` BEFORE `open`, and keep the width ≥ 1024 for desktop QA — the app's\n#    mobile gate reads `screen.width` (see Gotchas).\nagent-browser set viewport 1440 900\nagent-browser open \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE&streamer=on\"\nagent-browser wait --load networkidle\nsleep 2                                       # networkidle can still land mid-render — let it settle\nagent-browser snapshot -i -d 6                # prove it's DRIVABLE, not just screenshot-able\nagent-browser screenshot \"\u002Ftmp\u002Fdev3-ui-${DEV3_TASK_ID%%-*}.png\"   # then Read it back to look\nagent-browser errors                          # confirm no console errors\n\n# 4. Always clean up what you started. `close` closes only THIS session's browser.\nagent-browser close\ndev3 dev-server stop          # the port frees a second or two later (graceful shutdown)\n```\n\nThat's it. `DEV3_REMOTE_PORT=${DEV3_PORT0:-0}` is wired into the repo's `dev` script and\n`portCount: 1` is committed in `.dev3\u002Fconfig.json`, so the dev app binds the exact port shown\nabove (see [decision 093](..\u002F..\u002F..\u002Fdecisions\u002F2026\u002F06\u002F30\u002Fdev-remote-port-from-pool.md)).\n\n## Linux without a display: the dev-server goes headless\n\nOn Linux with no `DISPLAY`\u002F`WAYLAND_DISPLAY`, or without `libwebkit2gtk-4.1` (WSL without WSLg,\nSSH, containers), the desktop window cannot open. `bun run dev` detects that and serves the same\nUI through `dev3 remote`, run from source, on the same port and access code. The flow above does\nnot change: `agent-browser` only ever talked to the web server. The pane prints\n`[dev] headless (\u003Creason>)` when this happens.\n\n- **Headless defaults to the scoped `seeded` board**, because the real `~\u002F.dev3.0` usually\n  belongs to an installed `dev3 remote` on the same machine. `--env DEV3_QA_SCOPE=0` opts back\n  into the real board.\n- **Headless on request** where the window could open:\n  `dev3 dev-server start --wait --env DEV3_DEV_HEADLESS=1`.\n- **What it cannot show:** the native window, the application menu and OS notifications.\n  Everything rendered in the page is the same code.\n\n## Scoped QA: a throwaway board instead of the real one\n\n`dev3 dev-server start` boots a full dev3 instance on **your real board** — another task's\n\"Branch Merged — mark completed?\" dialog is live and clickable in your browser, and another task's\nterminal is reachable by navigation. It stays the default anyway, because it is the build the user\nruns; reach for the scoped board when the QA would touch real tasks, real accounts, or a live dialog\n— creating or launching a task from the New Task dialog counts.\n\nThe switch is an env var the `dev` script reads (`DEV3_QA_SCOPE`, see `scripts\u002Fdev.ts` and\n`scripts\u002Fqa-scope.ts`), and the dev-server passes caller-supplied variables straight through. So\nthe scoped board is **the same dev-server**, one flag longer:\n\n```bash\ndev3 dev-server start --wait --env DEV3_QA_SCOPE=seeded    # or virgin\n```\n\n`seeded` = one fixture project, zero tasks; `virgin` = completely empty home, the first-run state.\nSteps 1, 3 and 4 of the flow above are unchanged — same port, same access code, same `stop`. The\ndev-server pane prints the scoped `DEV3_HOME` and an `rm -rf` reset line; the scoped root is stable\nper worktree, so the board survives a restart.\n\nThree things worth knowing about the flag:\n\n- **A plain `dev3 dev-server restart` stays on the scoped board** — a restart with no `--env`\n  reuses the last start's env, which is also what the Dev Server button in the task UI does.\n- **A plain `dev3 dev-server start` goes back to the real board.** A start defines its\n  configuration whole, and a `stop` clears the remembered env — so there is nothing to delete\n  and nothing left to forget about.\n- **`dev3 dev-server status` names the extra keys** (names only, never values), so you can see at\n  a glance which board the running server is on.\n\nDo **not** put `DEV3_QA_SCOPE` in `.dev3\u002Fconfig.local.json`. That was the old recipe and its trap\nis exactly what the flag removes: the file also reaches the agent sessions of this worktree, and a\nforgotten one silently boots the next QA run on the throwaway board.\n\n**What it does NOT isolate** — name these rather than assuming a clean room: the tmux socket\ndirectory (only `TMUX_TMPDIR` moves it, and dev3 sets it nowhere), the PowerShell history file on\nWindows, the user's own `~\u002F.codex` \u002F `~\u002F.claude` agent configs, and `dev3` CLI commands run from\ninside a REAL worktree (cwd-based task detection outranks `$DEV3_HOME` by design).\n\n## Gotchas\n\n- **The browser is a machine-global singleton — isolate per task or agents stomp each other.**\n  Every `agent-browser` call with no session lands in one shared `\"default\"` session: one\n  browser process, one global viewport. When two task agents QA at the same time they collide\n  — agent B's `open` silently replaces agent A's page, so A's next `screenshot` captures B's\n  UI. The fix is step 1: `export AGENT_BROWSER_SESSION=\"dev3-${DEV3_TASK_ID%%-*}\"` gives each\n  task its own isolated session\u002Fprofile (verify with `agent-browser session` \u002F `session\n  list`), and `agent-browser close` then closes only your session. **The Bash tool\n  reinitializes the shell per call, so an `export` does not carry across separate\n  invocations** — the line derives from the always-present `$DEV3_TASK_ID`, so just repeat it\n  at the top of each block, or pass `--session \"dev3-${DEV3_TASK_ID%%-*}\"` on every command.\n  (If you ever must share one browser machine-wide instead, serialize QA across agents so only\n  one drives at a time.)\n- **The dev-server is a build snapshot — no watch\u002FHMR.** Your code only appears after a\n  (re)start. After changing code, `dev3 dev-server restart`, re-wait for the port, then\n  `agent-browser reload` — a bare reload re-serves the *old* bundle. Don't keep a stale server\n  around; never hand-run `vite build`.\n- **Is the running build actually yours?** An already-running app\u002Fremote is often production or\n  *another* worktree — it won't have your changes. (Re)start THIS task's dev-server and confirm\n  with `dev3 --version` (commit hash should match `git log -1`) + that your change actually\n  renders. Don't assume.\n- **Tell the user before you start the app any way at all** (visible side effect), and stop it\n  after (step 4) unless they want it kept.\n- **`dev3` says `app not running`? Stop and tell the user.** Every route in this skill needs the\n  CLI, so there is nothing to fall back to. Never launch the app yourself — a bare `bun run dev`\n  (with or without `--qa`, in your shell or in a `dev3 pane run`) opens a native window on the\n  user's screen that no dev-server owns, so nothing can `status` or `stop` it for you.\n- **No `DEV3_PORT0`?** (portCount 0, or an older worktree where it was never allocated) — run\n  your own fixed-port server instead:\n  `dev3 remote --no-detach --no-tunnel --static-code $CODE --port 47823` → `:47823\u002F?token=$CODE`.\n- **Every screenshot in streamer mode — no exceptions by default.** The app shows the\n  developer's REAL identity (account emails, orgs, home-dir paths, tunnel URLs, QR codes), and\n  a QA screenshot easily ends up in a PR\u002Fissue\u002Frecording. `&streamer=on` in the URL forces the\n  privacy masking on for the whole session (it persists in this session's localStorage;\n  `&streamer=off` forces it back off). The masking is CSS blur on `.streamer-private` elements\n  — see `src\u002Fmainview\u002Fstreamer-mode.tsx` and decision 161. Only capture unmasked when the task\n  is explicitly about those values (e.g. testing the accounts UI itself), and say so when\n  presenting the image.\n- **App renders but nothing clicks? That's the mobile gate, not the tooling.** The app decides\n  mobile from the *physical* `screen.width` (`\u003C 1024` → mobile; `src\u002Fmainview\u002Fhooks\u002FuseMobile.tsx`,\n  deliberately not `innerWidth`), and a mobile device held in landscape gets\n  `MobilePortraitGate`: a \"rotate your device\" overlay plus `inert` on the whole app — screenshots\n  still work, clicks do nothing. `agent-browser` 0.6.0 emulated `screen.*` together with the\n  viewport, so `set viewport 1440 900` before `open` was enough. **0.34.0 does not** — `screen`\n  stays at the headless display's 800×600 no matter the viewport (`--window-size` in `--args`\n  does not move it either), so every desktop QA run lands in the gate. Override it with an init\n  script instead, registered before the first navigation:\n\n  ```bash\n  printf 'for (const k of [\"width\",\"availWidth\"]) Object.defineProperty(screen, k, { get: () => 1600, configurable: true });\\nfor (const k of [\"height\",\"availHeight\"]) Object.defineProperty(screen, k, { get: () => 1000, configurable: true });\\n' > \u002Ftmp\u002Fscreen-desktop.js\n  agent-browser close                      # a running session keeps its old init scripts\n  agent-browser set viewport 1600 1000\n  agent-browser open \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE&streamer=on\" --init-script \u002Ftmp\u002Fscreen-desktop.js\n  ```\n\n  With that, `screen.width` reports 1600 and the gate stays off. You otherwise only hit the gate\n  by asking for a phone-sized landscape viewport — that is the app working as designed.\n  Measured across the common sizes: `2560×1440`, `1920×1080`, `1600×900`, `1440×900`, `1366×768`,\n  `1280×720`, `1024×768`, `768×1024` and phone portrait `390×844` all render and click fine\n  (`screen.width` always equals the requested width); only landscape `844×390` shows the gate, goes\n  `inert`, and reports **zero** interactive elements in `snapshot -i` — that count is the fastest\n  tell. Diagnose in one call:\n  `agent-browser eval \"JSON.stringify({sw:screen.width,gate:!!document.querySelector('[data-testid=\\\"mobile-portrait-gate\\\"]'),inert:!!document.querySelector('[inert]')})\"`.\n  If a future browser tool pins `screen.*` to the real headless display and desktop QA goes inert,\n  that's the moment to add an escape hatch to the app — not before (see\n  [the headless-QA decision](..\u002F..\u002F..\u002Fdecisions\u002F2026\u002F08\u002F14\u002Fheadless-qa-mobile-gate-stays-as-is.md)).\n- **No native dialogs** in browser mode. If a confirm\u002Ffile-picker flow silently no-ops, that's\n  an app bug, not a tooling problem — report it.\n- **Show images to the user AFTER you stop this dev-server, not while it runs.**\n  `dev3 show-image` (and `dev3 attention` \u002F `dev3 notify`) route to the app instance that owns\n  the task — and this QA dev-server is itself a full dev3 instance. While it's up, those\n  UI-attention calls can land in *it* (the browser only you see) instead of the user's main\n  app, so the user never sees the image. Screenshots persist on disk, so the correct order is\n  **capture → `dev3 dev-server stop` (confirm `State: stopped`) → `dev3 show-image`**.\n","# debug-ui — QA the dev-3.0 UI in a real browser\n\nSee and drive the running dev-3.0 UI in headless Chromium — click, type, screenshot, read\nconsole errors — instead of guessing whether a UI change works. No desktop\u002Fnative dependency;\nit works the same in a plain terminal session.\n\nThis is **dev-internal tooling for the dev-3.0 repo** — NOT one of the skills dev3 ships to\nits users (those live in `src\u002Fbun\u002Fagent-skills.ts`).\n\n## Prerequisite: `agent-browser` on PATH\n\nCheck with `agent-browser --version`. If it is missing, install it once per machine, not in the\nproject `setupScript` (that runs for every new worktree):\n\n```bash\nbun add -g agent-browser        # or: npm i -g agent-browser\nagent-browser install           # downloads Chromium; on Linux add --with-deps for system libraries (needs sudo)\n```\n\n## One rule before the flow: the app starts through `dev3 dev-server`, nothing else\n\nEvery QA run in this skill boots the app with `dev3 dev-server start` and takes it down with\n`dev3 dev-server stop`. **Never start the app any other way** — not a bare `bun run dev`, not\n`bun run dev --qa`, and not `dev3 pane run \"bun run dev …\"`. A pane run looks like a shortcut\nand costs you everything the dev-server owns: the port wait (`--wait`), `status` with its port\nconflicts, a verified stop that frees `DEV3_PORT0`, the Dev Server button in the task UI that\nshows the user what is running, and the `show-image` \u002F `attention` routing rules below. If you\nneed the app to behave differently (a throwaway board, an env flag), change what the dev-server\nruns — see \"Scoped QA\" — do not route around it.\n\n## The whole flow\n\nThis task's dev-server **is** the web UI: `bun run dev` serves the full app in local remote\nmode at a stable per-machine token and a CLI-derivable port — no separate `dev3 remote`. The\nloop is always the same four beats: **values → server → browser → clean up.**\n\n```bash\n# 1. Values. AGENT_BROWSER_SESSION isolates THIS task's browser from every other agent's —\n#    without it all agents share one global \"default\" session and stomp each other (see\n#    Gotchas). Derived from the always-present $DEV3_TASK_ID, so this exact line is\n#    copy-paste-safe at the top of ANY block that calls agent-browser.\nexport AGENT_BROWSER_SESSION=\"dev3-${DEV3_TASK_ID%%-*}\"\nCODE=$(cat \"$HOME\u002F.dev3.0\u002Fdev-web-access-code\" 2>\u002Fdev\u002Fnull || bun scripts\u002Fdev-web-code.ts)\nPORT=${DEV3_PORT0:-$(dev3 dev-server status | grep -oE 'DEV3_PORT0=[0-9]+' | cut -d= -f2)}\n\n# 2. Start a FRESH dev-server and wait for it to come up. (Skip the start only if one is\n#    already running for THIS task — but see the build-snapshot gotcha: stale code needs a\n#    restart, so when in doubt restart.)\ndev3 dev-server start\nuntil curl -sf \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE\" >\u002Fdev\u002Fnull; do sleep 2; done\n\n# 3. Drive it. Every agent-browser call inherits AGENT_BROWSER_SESSION, so it all runs in\n#    this task's own session. (Load \u002Fagent-browser for the full command set.) The screenshot\n#    path is task-scoped too, so parallel agents never overwrite each other's PNG.\n#    `&streamer=on` is MANDATORY: it enables streamer mode (privacy masking), so screenshots\n#    can't leak the developer's real emails\u002Faccounts\u002Fpaths\u002Ftunnel URLs (see Gotchas).\n#    Keep `set viewport` BEFORE `open`, and keep the width ≥ 1024 for desktop QA — the app's\n#    mobile gate reads `screen.width` (see Gotchas).\nagent-browser set viewport 1440 900\nagent-browser open \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE&streamer=on\"\nagent-browser wait --load networkidle\nsleep 2                                       # networkidle can still land mid-render — let it settle\nagent-browser snapshot -i -d 6                # prove it's DRIVABLE, not just screenshot-able\nagent-browser screenshot \"\u002Ftmp\u002Fdev3-ui-${DEV3_TASK_ID%%-*}.png\"   # then Read it back to look\nagent-browser errors                          # confirm no console errors\n\n# 4. Always clean up what you started. `close` closes only THIS session's browser.\nagent-browser close\ndev3 dev-server stop          # the port frees a second or two later (graceful shutdown)\n```\n\nThat's it. `DEV3_REMOTE_PORT=${DEV3_PORT0:-0}` is wired into the repo's `dev` script and\n`portCount: 1` is committed in `.dev3\u002Fconfig.json`, so the dev app binds the exact port shown\nabove (see [decision 093](..\u002F..\u002F..\u002Fdecisions\u002F2026\u002F06\u002F30\u002Fdev-remote-port-from-pool.md)).\n\n## Linux without a display: the dev-server goes headless\n\nOn Linux with no `DISPLAY`\u002F`WAYLAND_DISPLAY`, or without `libwebkit2gtk-4.1` (WSL without WSLg,\nSSH, containers), the desktop window cannot open. `bun run dev` detects that and serves the same\nUI through `dev3 remote`, run from source, on the same port and access code. The flow above does\nnot change: `agent-browser` only ever talked to the web server. The pane prints\n`[dev] headless (\u003Creason>)` when this happens.\n\n- **Headless defaults to the scoped `seeded` board**, because the real `~\u002F.dev3.0` usually\n  belongs to an installed `dev3 remote` on the same machine. `--env DEV3_QA_SCOPE=0` opts back\n  into the real board.\n- **Headless on request** where the window could open:\n  `dev3 dev-server start --wait --env DEV3_DEV_HEADLESS=1`.\n- **What it cannot show:** the native window, the application menu and OS notifications.\n  Everything rendered in the page is the same code.\n\n## Scoped QA: a throwaway board instead of the real one\n\n`dev3 dev-server start` boots a full dev3 instance on **your real board** — another task's\n\"Branch Merged — mark completed?\" dialog is live and clickable in your browser, and another task's\nterminal is reachable by navigation. It stays the default anyway, because it is the build the user\nruns; reach for the scoped board when the QA would touch real tasks, real accounts, or a live dialog\n— creating or launching a task from the New Task dialog counts.\n\nThe switch is an env var the `dev` script reads (`DEV3_QA_SCOPE`, see `scripts\u002Fdev.ts` and\n`scripts\u002Fqa-scope.ts`), and the dev-server passes caller-supplied variables straight through. So\nthe scoped board is **the same dev-server**, one flag longer:\n\n```bash\ndev3 dev-server start --wait --env DEV3_QA_SCOPE=seeded    # or virgin\n```\n\n`seeded` = one fixture project, zero tasks; `virgin` = completely empty home, the first-run state.\nSteps 1, 3 and 4 of the flow above are unchanged — same port, same access code, same `stop`. The\ndev-server pane prints the scoped `DEV3_HOME` and an `rm -rf` reset line; the scoped root is stable\nper worktree, so the board survives a restart.\n\nThree things worth knowing about the flag:\n\n- **A plain `dev3 dev-server restart` stays on the scoped board** — a restart with no `--env`\n  reuses the last start's env, which is also what the Dev Server button in the task UI does.\n- **A plain `dev3 dev-server start` goes back to the real board.** A start defines its\n  configuration whole, and a `stop` clears the remembered env — so there is nothing to delete\n  and nothing left to forget about.\n- **`dev3 dev-server status` names the extra keys** (names only, never values), so you can see at\n  a glance which board the running server is on.\n\nDo **not** put `DEV3_QA_SCOPE` in `.dev3\u002Fconfig.local.json`. That was the old recipe and its trap\nis exactly what the flag removes: the file also reaches the agent sessions of this worktree, and a\nforgotten one silently boots the next QA run on the throwaway board.\n\n**What it does NOT isolate** — name these rather than assuming a clean room: the tmux socket\ndirectory (only `TMUX_TMPDIR` moves it, and dev3 sets it nowhere), the PowerShell history file on\nWindows, the user's own `~\u002F.codex` \u002F `~\u002F.claude` agent configs, and `dev3` CLI commands run from\ninside a REAL worktree (cwd-based task detection outranks `$DEV3_HOME` by design).\n\n## Gotchas\n\n- **The browser is a machine-global singleton — isolate per task or agents stomp each other.**\n  Every `agent-browser` call with no session lands in one shared `\"default\"` session: one\n  browser process, one global viewport. When two task agents QA at the same time they collide\n  — agent B's `open` silently replaces agent A's page, so A's next `screenshot` captures B's\n  UI. The fix is step 1: `export AGENT_BROWSER_SESSION=\"dev3-${DEV3_TASK_ID%%-*}\"` gives each\n  task its own isolated session\u002Fprofile (verify with `agent-browser session` \u002F `session\n  list`), and `agent-browser close` then closes only your session. **The Bash tool\n  reinitializes the shell per call, so an `export` does not carry across separate\n  invocations** — the line derives from the always-present `$DEV3_TASK_ID`, so just repeat it\n  at the top of each block, or pass `--session \"dev3-${DEV3_TASK_ID%%-*}\"` on every command.\n  (If you ever must share one browser machine-wide instead, serialize QA across agents so only\n  one drives at a time.)\n- **The dev-server is a build snapshot — no watch\u002FHMR.** Your code only appears after a\n  (re)start. After changing code, `dev3 dev-server restart`, re-wait for the port, then\n  `agent-browser reload` — a bare reload re-serves the *old* bundle. Don't keep a stale server\n  around; never hand-run `vite build`.\n- **Is the running build actually yours?** An already-running app\u002Fremote is often production or\n  *another* worktree — it won't have your changes. (Re)start THIS task's dev-server and confirm\n  with `dev3 --version` (commit hash should match `git log -1`) + that your change actually\n  renders. Don't assume.\n- **Tell the user before you start the app any way at all** (visible side effect), and stop it\n  after (step 4) unless they want it kept.\n- **`dev3` says `app not running`? Stop and tell the user.** Every route in this skill needs the\n  CLI, so there is nothing to fall back to. Never launch the app yourself — a bare `bun run dev`\n  (with or without `--qa`, in your shell or in a `dev3 pane run`) opens a native window on the\n  user's screen that no dev-server owns, so nothing can `status` or `stop` it for you.\n- **No `DEV3_PORT0`?** (portCount 0, or an older worktree where it was never allocated) — run\n  your own fixed-port server instead:\n  `dev3 remote --no-detach --no-tunnel --static-code $CODE --port 47823` → `:47823\u002F?token=$CODE`.\n- **Every screenshot in streamer mode — no exceptions by default.** The app shows the\n  developer's REAL identity (account emails, orgs, home-dir paths, tunnel URLs, QR codes), and\n  a QA screenshot easily ends up in a PR\u002Fissue\u002Frecording. `&streamer=on` in the URL forces the\n  privacy masking on for the whole session (it persists in this session's localStorage;\n  `&streamer=off` forces it back off). The masking is CSS blur on `.streamer-private` elements\n  — see `src\u002Fmainview\u002Fstreamer-mode.tsx` and decision 161. Only capture unmasked when the task\n  is explicitly about those values (e.g. testing the accounts UI itself), and say so when\n  presenting the image.\n- **App renders but nothing clicks? That's the mobile gate, not the tooling.** The app decides\n  mobile from the *physical* `screen.width` (`\u003C 1024` → mobile; `src\u002Fmainview\u002Fhooks\u002FuseMobile.tsx`,\n  deliberately not `innerWidth`), and a mobile device held in landscape gets\n  `MobilePortraitGate`: a \"rotate your device\" overlay plus `inert` on the whole app — screenshots\n  still work, clicks do nothing. `agent-browser` 0.6.0 emulated `screen.*` together with the\n  viewport, so `set viewport 1440 900` before `open` was enough. **0.34.0 does not** — `screen`\n  stays at the headless display's 800×600 no matter the viewport (`--window-size` in `--args`\n  does not move it either), so every desktop QA run lands in the gate. Override it with an init\n  script instead, registered before the first navigation:\n\n  ```bash\n  printf 'for (const k of [\"width\",\"availWidth\"]) Object.defineProperty(screen, k, { get: () => 1600, configurable: true });\\nfor (const k of [\"height\",\"availHeight\"]) Object.defineProperty(screen, k, { get: () => 1000, configurable: true });\\n' > \u002Ftmp\u002Fscreen-desktop.js\n  agent-browser close                      # a running session keeps its old init scripts\n  agent-browser set viewport 1600 1000\n  agent-browser open \"http:\u002F\u002Flocalhost:$PORT\u002F?token=$CODE&streamer=on\" --init-script \u002Ftmp\u002Fscreen-desktop.js\n  ```\n\n  With that, `screen.width` reports 1600 and the gate stays off. You otherwise only hit the gate\n  by asking for a phone-sized landscape viewport — that is the app working as designed.\n  Measured across the common sizes: `2560×1440`, `1920×1080`, `1600×900`, `1440×900`, `1366×768`,\n  `1280×720`, `1024×768`, `768×1024` and phone portrait `390×844` all render and click fine\n  (`screen.width` always equals the requested width); only landscape `844×390` shows the gate, goes\n  `inert`, and reports **zero** interactive elements in `snapshot -i` — that count is the fastest\n  tell. Diagnose in one call:\n  `agent-browser eval \"JSON.stringify({sw:screen.width,gate:!!document.querySelector('[data-testid=\\\"mobile-portrait-gate\\\"]'),inert:!!document.querySelector('[inert]')})\"`.\n  If a future browser tool pins `screen.*` to the real headless display and desktop QA goes inert,\n  that's the moment to add an escape hatch to the app — not before (see\n  [the headless-QA decision](..\u002F..\u002F..\u002Fdecisions\u002F2026\u002F08\u002F14\u002Fheadless-qa-mobile-gate-stays-as-is.md)).\n- **No native dialogs** in browser mode. If a confirm\u002Ffile-picker flow silently no-ops, that's\n  an app bug, not a tooling problem — report it.\n- **Show images to the user AFTER you stop this dev-server, not while it runs.**\n  `dev3 show-image` (and `dev3 attention` \u002F `dev3 notify`) route to the app instance that owns\n  the task — and this QA dev-server is itself a full dev3 instance. While it's up, those\n  UI-attention calls can land in *it* (the browser only you see) instead of the user's main\n  app, so the user never sees the image. Screenshots persist on disk, so the correct order is\n  **capture → `dev3 dev-server stop` (confirm `State: stopped`) → `dev3 show-image`**.\n",{"name":43,"description":44},"debug-ui","Drive and visually QA the dev-3.0 UI in a real browser (headless Chromium via agent-browser). Use when verifying a UI\u002FUX change, reproducing a visual bug, taking screenshots of the running app, or self-QA before review. Triggers — \"check the UI\", \"screenshot the app\", \"does this render\", \"QA this screen\", \"verify the UI change in a browser\", \"drive the app\".","main","3db9a9b6377076d26a40115e7edb086277a807d3",".claude\u002Fskills\u002Fecc\u002Fcontinuous-learning","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile","2026-11-08 20:29:14",{"source":8,"skillName":43,"commands":52,"prompt":62,"zipAvailable":63},[53,56,59],{"tool":54,"command":55},"npx","npx skills add sakamoto-family-smile\u002Fagent_monorepo --skill debug-ui",{"tool":57,"command":58},"bunx","bunx skills add sakamoto-family-smile\u002Fagent_monorepo --skill debug-ui",{"tool":60,"command":61},"pnpm","pnpm dlx skills add sakamoto-family-smile\u002Fagent_monorepo --skill debug-ui","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fcontinuous-learning\u002FSKILL.md",true,[65,71],{"path":66,"resourceType":67,"resourceTypeDesc":68,"sizeBytes":69,"sourceHtmlUrl":70},"config.json","REFERENCE","参考文档",391,"https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fcontinuous-learning\u002Fconfig.json",{"path":72,"resourceType":73,"resourceTypeDesc":74,"sizeBytes":75,"sourceHtmlUrl":76},"evaluate-session.sh","SCRIPT","脚本",2391,"https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fcontinuous-learning\u002Fevaluate-session.sh",[78,113,121,141,164,191],{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":92,"publishedAt":38},"01M6RW50THEFSKK42YNR8XFZA1","remotion-video-creation","Best practices for Remotion - Video creation in React. 29 domain-specific rules covering 3D, animations, audio, captions, charts, transitions, and more.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fremotion-video-creation\u002FSKILL.md",[84,89],{"categoryNo":85,"categoryName":86,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":90,"categoryName":91,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000016","图像与多媒体",[93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112],"Video","remotion video","remotion video creation","creation","Remotion","Charts","Captions","Audio","3D","Composition","Animation","best practices","more","animations","domain-specific","domain","three","Rules","Lottie","for",{"skillNo":114,"name":115,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":118,"publishedAt":38},"01M6VCJ23NPECPSZJKGY691F75","hotcook-recipes","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fhotcook-agent\u002Fdata\u002Fskills\u002Fhotcook-recipes\u002FSKILL.md",[],[119,120],"hotcook recipes","recipes",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":135,"publishedAt":38},"01M6VCHHE00X5XHSDRD1KH1BW2","code-helper","Code review and assistance skill","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fagent-system-2\u002Fskills\u002Fcode-helper\u002Fskill.md",[127,130],{"categoryNo":128,"categoryName":129,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":131,"categoryName":132,"taxonomyType":133,"taxonomyTypeDesc":134},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[136,137,138,139,140],"code helper","helper","code","code review","review",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":153,"publishedAt":38},"01M6VCH3Q31A20H6SQ1H0J7JB2","research-assistant","Web research assistant skill using Brave Search MCP","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002Fagent-system-1\u002Fskills\u002Fresearch-assistant\u002Fskill.md",[147,150],{"categoryNo":148,"categoryName":149,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000021","资料检索与研究",{"categoryNo":151,"categoryName":152,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000023","Skill与智能体开发",[154,155,156,157,158,159,160,161,162,163],"research assistant","research","assistant","MCP","web","search","brave search","web research","brave","web research assistant",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":168,"categories":169,"keywords":174,"publishedAt":38},"01M6VCGZZGPNVJSCZ1JTMNZAHY","x-api","X\u002FTwitter API integration for posting tweets, threads, reading timelines, search, and analytics. Covers OAuth auth patterns, rate limits, and platform-native content posting. Use when the user wants to interact with X programmatically.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fx-api\u002FSKILL.md",[170,173],{"categoryNo":171,"categoryName":172,"taxonomyType":87,"taxonomyTypeDesc":88},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":131,"categoryName":132,"taxonomyType":133,"taxonomyTypeDesc":134},[175,176,28,177,178,179,112,180,181,182,183,184,185,186,187,36,188,189,159,190],"x api","api","when","limits","rate","threads","reading","native","posting","platform","patterns","api integration","twitter","auth","analytics","OAuth",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":198,"publishedAt":38},"01M6VCGVX6DGB1FKTA53QBBCQB","workspace-surface-audit","Audit the active repo, MCP servers, plugins, connectors, env surfaces, and harness setup, then recommend the highest-value ECC-native skills, hooks, agents, and operator workflows. Use when the user wants help setting up Claude Code or understanding what capabilities are actually available in their environment.","https:\u002F\u002Fgithub.com\u002Fsakamoto-family-smile\u002Fagent_monorepo\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fecc\u002Fworkspace-surface-audit\u002FSKILL.md",[197],{"categoryNo":151,"categoryName":152,"taxonomyType":87,"taxonomyTypeDesc":88},[199,200,201,202,157,203,204,138,205,206,207,208,36,209,210,211,212,182,213,177],"workspace surface audit","workspace","audit","hooks","workflows","connectors","capabilities","harness","repo","environment","up","harness setup","active","env","value"]