| name | notebooklm-firefox-browser-control |
| description | Experimental NotebookLM control path for Firefox using WebDriver BiDi or geckodriver, with verification-first gates and no CDP assumptions. |
NotebookLM Firefox Browser Control
Use this skill only when the user explicitly wants NotebookLM operated through Firefox, or when the Chromium/CDP NotebookLM route is unavailable and the user asks to test Firefox.
Firefox is not a Chromium/CDP route. Do not reuse notebooklm-cdp.mjs or claim CDP support. This skill requires a verified WebDriver BiDi/Marionette route, normally through geckodriver or an already-running WebDriver endpoint.
Inputs
- NotebookLM task or verification request.
- Optional WebDriver endpoint, default
http://127.0.0.1:4444.
- Optional permission to launch Firefox or a driver process.
Non-Goals
- Do not read cookies, localStorage, Firefox profile files, keychain, session tokens, or hidden browser storage.
- Do not launch or restart Firefox without explicit approval.
- Do not claim parity with the Chromium/CDP orchestrator until a live NotebookLM E2E passes.
Required Tool Check
Read references/operation.md, references/failure-modes.md, and references/production-skill-architecture.md before acting.
Before any Firefox UI automation, run:
node scripts/notebooklm-firefox-verify.mjs
The route is usable only when the final report has:
firefox_app.exists=true;
- either
geckodriver.exists=true or webdriver_endpoint.reachable=true;
storage_read=false.
If geckodriver and the endpoint are both missing, return tool_unavailable.
Persistent Profile Mode
Use this mode when the user chooses a repeatable Firefox setup for logged-in NotebookLM work.
Default profile path:
~/.codex/browser-profiles/notebooklm-firefox-webdriver
Setup:
node scripts/notebooklm-firefox-profile.mjs ensure-profile
node scripts/notebooklm-firefox-profile.mjs launch-login
The launch-login command opens a normal visible Firefox window, not WebDriver. The user must log in to Google/NotebookLM in that window and then close that Firefox window. Do not automate credentials.
After the user closes the login window, start geckodriver and verify the same profile through WebDriver:
geckodriver --host 127.0.0.1 --port 4444
node scripts/notebooklm-firefox-profile.mjs webdriver-open
If webdriver-open returns login_state=authenticated_notebooklm_ui, the route can run NotebookLM work. If it returns Google Sign-In, rejected login, profile lock, or any login page, stop with permission_blocked.
Retry Policy
Verify once. If geckodriver or a WebDriver endpoint is missing, do not retry or launch Firefox automatically. After user approval, one narrower retry is allowed with an explicit endpoint or approved driver launch.
Workflow
- Verify Firefox/WebDriver route.
- If route is not verified, stop with
tool_unavailable and include the verify report.
- If route is verified and the user approved browser automation, open or attach to visible NotebookLM.
- Treat the default geckodriver temporary profile as unauthenticated unless the visible UI proves otherwise. If NotebookLM redirects to
accounts.google.com, Google Sign-In, or rejected login, stop with permission_blocked; do not automate credentials or read Firefox profile storage.
- For repeatable NotebookLM work, use a user-approved persistent WebDriver profile that the user has logged into once, then record the profile route without reading profile files.
- Prefer
scripts/notebooklm-firefox-profile.mjs for persistent profile setup and login-state verification.
- Follow the same human NotebookLM UI procedure as
notebooklm-research-orchestrator: import sources first, verify source count, then ask chat or generate Studio artifacts.
- Preserve the
notebooklm-research-orchestrator human-experience YouTube requirement. For practical/comparative/software/workflow research, a Firefox run is incomplete unless relevant YouTube videos were scouted and imported, or context_exhausted/youtube or not_applicable is recorded.
- Apply the localized NotebookLM input-target guard from
references/operation.md: do not confuse source search with chat, use exact visible/aria labels where possible, and fall back to real WebDriver input when DOM value mutation does not enable the UI.
- Apply the answer copy-button extraction gate from
references/operation.md: completed NotebookLM chat answers must be copied through the answer toolbar copy button. Raw DOM/page text is dirty fallback only and does not satisfy completion by default.
Evidence
Every Firefox run must record:
- verify report;
- browser/driver version;
- endpoint URL;
- visible NotebookLM URL/title after attach;
- login/profile state: authenticated NotebookLM UI, Google Sign-In, or rejected login;
- YouTube human-experience attempt/import status for practical research;
- answer extraction method for chat runs, including copy-button status and UI-noise count;
- action log;
- final stop reason.
Scripts
scripts/notebooklm-firefox-verify.mjs: verify Firefox, geckodriver, endpoint, and no-storage-read safety flags.
scripts/notebooklm-firefox-profile.mjs: create a separate persistent Firefox profile, launch it for user login, and verify it through WebDriver without reading storage.
Final Review
This skill is experimental until reviews/review.json is updated with a passing live NotebookLM E2E result. A local verify report alone proves dependency state, not NotebookLM task success.
Failure Modes
tool_unavailable: Firefox, geckodriver, or endpoint missing.
permission_blocked: launch/login/automation approval required.
wrong_input_target: automation filled the wrong visible input.
insert_disabled: URL text exists but the NotebookLM import button remains disabled after validation wait.
copy_button_unavailable: completed answer exists but the answer copy control cannot be found or used.
copy_button_extract_dirty: copied answer contains NotebookLM UI toolbar noise.
regression_detected: visible NotebookLM UI selectors no longer match.
partial_output: route exists but requested output is incomplete.