Skip to content

Add dedicated Firefox connection approval#2

Merged
Nek-12 merged 11 commits into
mainfrom
fix-extension-approval-persistence
Jun 11, 2026
Merged

Add dedicated Firefox connection approval#2
Nek-12 merged 11 commits into
mainfrom
fix-extension-approval-persistence

Conversation

@Nek-12

@Nek-12 Nek-12 commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

  • add a dedicated Firefox approval request page for firefox-cli connect
  • handle deny, approve, already-approved, rate-limit, tab-cleanup, and notification outcomes in implementation/tests
  • bump package and extension versions to 0.2.0
  • include intentional follow-up cleanup commits for wait help examples and firefox-cli skill guidance wording

Verification

  • bun run check
  • live manual QA for deny, approve, already-approved, and notification flows
  • no-Firefox behavior was verified earlier before the rename; after the rename it is covered by tests/copy but the live retry was skipped

Summary by CodeRabbit

  • New Features

    • Added firefox-cli connect command to request Firefox control approval with dedicated approval interface.
    • Added firefox-cli notify command to display browser notifications.
  • Changes

    • Revised approval workflow to use firefox-cli connect instead of extension popup approval process.
    • Updated extension to display dedicated approval request UI.
    • Updated setup documentation and error messages to reflect new approval flow.
  • Version

    • Bumped to version 0.2.0 across all packages.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Nek-12, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 20 minutes and 54 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a97c9019-47e0-4a73-b61c-0e265ba703c1

📥 Commits

Reviewing files that changed from the base of the PR and between 643717b and 0939615.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (26)
  • biome.json
  • docs/dependency-migrations.md
  • package.json
  • packages/extension/src/approval-request-service.ts
  • packages/extension/src/approval-request.css
  • packages/extension/src/approval-request.test.ts
  • packages/extension/src/approval-request.ts
  • packages/extension/src/background-bootstrap-storage.test.ts
  • packages/extension/src/background-bootstrap-test-cases.ts
  • packages/extension/src/background-bootstrap.ts
  • packages/extension/src/background-controller-approval-race-test-cases.ts
  • packages/extension/src/background-controller-approval-test-cases.ts
  • packages/extension/src/background-controller-approval.test.ts
  • packages/extension/src/background-controller-test-cases.ts
  • packages/extension/src/background-controller.ts
  • packages/extension/src/background-pairing-service.ts
  • packages/extension/src/browser-commands-test-utils.ts
  • packages/extension/src/webextension.d.ts
  • packages/extension/vite.config.ts
  • packages/protocol/src/protocol-compatibility.ts
  • packages/protocol/src/protocol-metadata-behavior.test.ts
  • packages/protocol/src/registry/phase8.ts
  • scripts/manifest-validation.ts
  • scripts/marionette-client.ts
  • scripts/signed-extension-signature.ts
  • tsconfig.base.json
📝 Walkthrough

Walkthrough

This PR v0.2.0 introduces an approval request system with dedicated firefox-cli connect CLI command and pair.requestApproval protocol command, adds browser notification support via the notify command, implements an extension approval service with rate limiting and approval UI, gates pre-approval CLI commands at the native host, and updates documentation and build scripts accordingly. All package versions are bumped to 0.2.0 and protocol version to 4.

Changes

Approval Flow & Notification Commands

Layer / File(s) Summary
Protocol contracts and version
packages/protocol/src/constants.ts, packages/protocol/src/pairing.ts, packages/protocol/src/browser/output.ts, packages/protocol/src/metadata.ts, packages/protocol/src/extension-requirements.ts, packages/protocol/src/registry/pairing.ts, packages/protocol/src/registry/phase8.ts, packages/protocol/src/registry/index.ts, packages/protocol/src/protocol-metadata*.test.ts
Protocol version incremented to 4; new Zod schemas for pair.requestApproval, pair.openApproval, and notify commands; CommandPrivilegeReason extended with "notifications"; FirefoxManifestPermission includes "notifications"; commandAllowedBeforeApproval() predicate introduced; pairing command registry extended with two new approval commands routed to connect CLI.
Extension approval service with rate limiting
packages/extension/src/approval-request-service.ts, packages/extension/src/background-bootstrap-storage.test.ts
ApprovalRequestService class manages pending approval requests, enforces rate limiting with exponential backoff, opens approval pages/notifications, and resolves user approval/denial with proper protocol responses and tab cleanup; storage persistence of pair tokens via browser.storage.local.
Approval request UI page and styles
packages/extension/src/approval-request.html, packages/extension/src/approval-request.css, packages/extension/src/approval-request.ts, packages/extension/src/approval-request.test.ts
New HTML document defining approval dialog structure with state/error placeholders and Approve/Deny buttons; dark-theme CSS with constrained dialog layout and button variants; TypeScript client handles user actions, permission requests, and extension messaging for approval/denial flow.
Extension background controller and adapter updates
packages/extension/src/background-bootstrap.ts, packages/extension/src/background-browser-adapter.ts, packages/extension/src/background-controller.ts, packages/extension/src/background-request-handler.ts, packages/extension/src/browser-command/types.ts, packages/extension/src/browser-handlers/phase8-browser.ts, packages/extension/src/background-controller-test*.ts, packages/extension/src/popup.ts, packages/extension/src/webextension.d.ts, packages/extension/src/manifest.json
Background controller wires ApprovalRequestService via request forwarder intercept for pair.requestApproval/pair.openApproval; runtime message handler extended for approval state queries and approve/deny flows; createBackgroundStorageAdapter() persists pair tokens; new browser adapter methods showNotification(), getExtensionInstance(), openExtensionPage(); handleRequest gates commands via commandAllowedBeforeApproval; WebExtension type declarations updated for runtime.onMessage sender parameter, browser.notifications, and browser.runtime.getURL; manifest includes notifications permission; popup refactored to import requestHostAccess from dedicated module.
Native host approval command gating
packages/native-host/src/host-broker.ts, packages/native-host/src/host-broker-helpers.ts, packages/native-host/src/host-broker.test.ts
Broker's #getReadyExtension conditionally applies approval verification based on commandAllowedBeforeApproval(); approval-required commands return NOT_APPROVED error; approval commands bypass gate and proceed to extension forwarding; error messages updated to direct users to firefox-cli connect.
CLI connect and notify command implementation
packages/cli/src/argv-contracts.ts, packages/cli/src/commands/pairing.ts, packages/cli/src/commands/content.ts, packages/cli/src/format.ts, packages/cli/src/route-registry.ts, packages/cli/src/help.ts, packages/cli/src/parse-options.ts, packages/cli/src/cli*.test.ts, packages/cli/src/runner.ts, packages/cli/src/transport.ts
New route parser specs for connect and notify; buildOpenApprovalRequest() creates pair.requestApproval requests; buildNotifyRequest() parses notification title/message and optional --id; formatApprovalRequest() formats approval responses; route registry binds both commands with handlers and formatters; help system extended with connect setup/diagnostics entry and notify browser utilities entry; optionalStringOption overload extended for "id" output key; error messages updated to reference firefox-cli connect for NOT_APPROVED and NATIVE_HOST_UNAVAILABLE states; unpair success message instructs re-running connect.
Version bumps, build and asset scripts
.claude-plugin/plugin.json, package.json, packages/*/package.json, scripts/build-extension.ts, scripts/copy-extension-assets.ts, scripts/extension-payload-check.ts, scripts/test/copy-extension-assets.test.ts, scripts/test/package-check-test-utils.ts
All package versions bumped from 0.1.1 to 0.2.0; extension build script extended to emit approval-request.js bundle; asset copy script includes approval-request.html and approval-request.css; payload validation enforces presence of new approval-request artifacts and validates chunk imports for approval-request.js; test fixtures extended with approval-request assets.
Documentation updates and skill description
README.md, docs/setup.md, docs/commands.md, docs/firefox-cli-spec.md, docs/architecture.md, docs/all-commands-qa.md, docs/firefox-cli/updates.json, skills/firefox-cli/SKILL.md
README and setup docs updated to describe firefox-cli connect approval flow; command docs list connect and notify with signatures; spec clarifies initial approval via connect flow and pairing handshake, tightens native host behavior to reject non-approval commands with NOT_APPROVED (except approval commands), updates extension permissions list; architecture docs reframed pairing/unpairing to reference connect for re-approval; E2E command walkthrough reflects already-approved rejection output; updates.json includes v0.2.0 release info; SKILL.md revised description emphasizes authenticated session control, removed "when to use" section, replaced "boundaries" with "usage rules" including approval guidance.

🎯 4 (Complex) | ⏱️ ~60 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-extension-approval-persistence

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 643717b1a0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/protocol/src/registry/phase8.ts
Comment thread packages/extension/src/approval-request-service.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/cli/src/commands/content.ts (1)

249-267: 💤 Low value

Consider the trade-off of filtering --json.

Line 251 filters all occurrences of "--json" from argv before parsing. This is necessary because with payloadStartPositionals: 0 and variadicAfterMin: true, any --json appearing after the title would be captured as part of the notification message rather than as a global output flag.

However, this means users cannot include the literal string "--json" in notification messages. For example:

firefox-cli notify "Alert" "The --json flag is useful"  # "--json" will be filtered out

This trade-off is reasonable for CLI ergonomics (most users expect --json to control output format anywhere in the command), but it's worth being aware of this limitation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/cli/src/commands/content.ts` around lines 249 - 267, The current
implementation filters every "--json" from argv which prevents users from
including the literal "--json" in messages; instead stop globally filtering and
let parsePayloadPositionalsAndOptions handle flags so "--json" can be parsed as
an option while preserving occurrences in message text: remove the
argv.filter((arg) => arg !== "--json") step in buildNotifyRequest and pass the
raw argv.slice(1) into parsePayloadPositionalsAndOptions (keeping the same
payloadStartPositionals/minPositionals/variadicAfterMin options), then read
parsed.optionArgs for the global --json flag as needed so messageParts can
contain literal "--json".
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/extension/src/approval-request-service.ts`:
- Around line 116-127: approvePairing() can throw and leave pending.status as
"approving" and the promise unresolved; wrap the await approvePairing() call in
a try/catch. In the catch, if this.#pending === pending, reset pending.status
back to "pending", clear this.#pending / this.#rateLimitIndex /
this.#nextAllowedAtMs if appropriate, and ensure the pending promise is settled
(reject or resolve with an error response) so it doesn't remain unresolved; keep
the successful-path behavior (this.#pending = undefined, reset indexes,
pending.resolve(...), await this.#closeSourceTab(sourceTabId)) inside the try
block. Ensure you reference approvePairing(), pending, this.#pending,
pending.status, pending.resolve and this.#closeSourceTab(sourceTabId) when
making the change.

In `@packages/extension/src/approval-request.css`:
- Around line 11-12: The CSS custom properties --base-font and --heading-font
use fallback tokens that trigger Stylelint value-keyword-case violations; update
the fallback font-family tokens inside both --base-font and --heading-font to
use lowercase keywords (e.g., system-ui, -apple-system, blinkmacsystemfont,
segoe ui, helvetica, arial, sans-serif) so Stylelint passes while preserving the
same fallback order and quoted multi-word names.

In `@packages/extension/src/browser-commands-test-utils.ts`:
- Around line 276-279: The method showNotification currently uses a type
assertion (`ok: true as const`); instead, add an explicit return type to the
method (e.g. Promise<{ ok: true; id: string }>) and return a plain boolean
literal (`ok: true`) without `as const`, keeping the existing id expression
(options.id ?? `notification-${String(this.notifications.length)}`) and pushing
options into this.notifications so the runtime behavior is unchanged.

---

Nitpick comments:
In `@packages/cli/src/commands/content.ts`:
- Around line 249-267: The current implementation filters every "--json" from
argv which prevents users from including the literal "--json" in messages;
instead stop globally filtering and let parsePayloadPositionalsAndOptions handle
flags so "--json" can be parsed as an option while preserving occurrences in
message text: remove the argv.filter((arg) => arg !== "--json") step in
buildNotifyRequest and pass the raw argv.slice(1) into
parsePayloadPositionalsAndOptions (keeping the same
payloadStartPositionals/minPositionals/variadicAfterMin options), then read
parsed.optionArgs for the global --json flag as needed so messageParts can
contain literal "--json".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2e1a8038-bc98-4b88-be7c-32f725c9b1da

📥 Commits

Reviewing files that changed from the base of the PR and between 7fbab0f and 643717b.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (84)
  • .claude-plugin/plugin.json
  • AMO_SOURCE_REVIEW.md
  • README.md
  • docs/all-commands-qa.md
  • docs/architecture.md
  • docs/commands.md
  • docs/firefox-cli-spec.md
  • docs/firefox-cli/updates.json
  • docs/setup.md
  • package.json
  • packages/cli/package.json
  • packages/cli/src/argv-contracts.ts
  • packages/cli/src/cli-help.test.ts
  • packages/cli/src/cli-phase8.test.ts
  • packages/cli/src/cli-setup-doctor.test.ts
  • packages/cli/src/cli-test-support.ts
  • packages/cli/src/cli.test.ts
  • packages/cli/src/commands/content.ts
  • packages/cli/src/commands/pairing.ts
  • packages/cli/src/commands/setup-doctor.ts
  • packages/cli/src/format.test.ts
  • packages/cli/src/format.ts
  • packages/cli/src/help.ts
  • packages/cli/src/parse-options.ts
  • packages/cli/src/route-registry.ts
  • packages/cli/src/runner.ts
  • packages/cli/src/transport.ts
  • packages/extension/package.json
  • packages/extension/src/approval-permissions.ts
  • packages/extension/src/approval-request-service.ts
  • packages/extension/src/approval-request.css
  • packages/extension/src/approval-request.html
  • packages/extension/src/approval-request.test.ts
  • packages/extension/src/approval-request.ts
  • packages/extension/src/background-bootstrap-storage.test.ts
  • packages/extension/src/background-bootstrap-test-cases.ts
  • packages/extension/src/background-bootstrap.test.ts
  • packages/extension/src/background-bootstrap.ts
  • packages/extension/src/background-browser-adapter.ts
  • packages/extension/src/background-controller-approval-race-test-cases.ts
  • packages/extension/src/background-controller-approval-test-cases.ts
  • packages/extension/src/background-controller-approval.test.ts
  • packages/extension/src/background-controller-test-cases.ts
  • packages/extension/src/background-controller-test-support.ts
  • packages/extension/src/background-controller.test.ts
  • packages/extension/src/background-controller.ts
  • packages/extension/src/background-default-browser-adapter.ts
  • packages/extension/src/background-native-session.ts
  • packages/extension/src/background-request-forwarder.ts
  • packages/extension/src/background-request-handler.ts
  • packages/extension/src/browser-command/types.ts
  • packages/extension/src/browser-commands-content.test.ts
  • packages/extension/src/browser-commands-test-cases.ts
  • packages/extension/src/browser-commands-test-smoke.ts
  • packages/extension/src/browser-commands-test-utils.ts
  • packages/extension/src/browser-handlers/phase8-browser.ts
  • packages/extension/src/manifest.json
  • packages/extension/src/popup.ts
  • packages/extension/src/webextension.d.ts
  • packages/native-host/package.json
  • packages/native-host/src/host-broker-helpers.ts
  • packages/native-host/src/host-broker.test.ts
  • packages/native-host/src/host-broker.ts
  • packages/protocol/package.json
  • packages/protocol/src/browser/output.ts
  • packages/protocol/src/capabilities.ts
  • packages/protocol/src/constants.ts
  • packages/protocol/src/extension-requirements.ts
  • packages/protocol/src/metadata.ts
  • packages/protocol/src/pairing.ts
  • packages/protocol/src/protocol-metadata-behavior.test.ts
  • packages/protocol/src/protocol-metadata.test.ts
  • packages/protocol/src/protocol-test-support.ts
  • packages/protocol/src/registry/index.ts
  • packages/protocol/src/registry/pairing.ts
  • packages/protocol/src/registry/phase8.ts
  • packages/protocol/src/registry/registry.test.ts
  • packages/test-support/package.json
  • scripts/build-extension.ts
  • scripts/copy-extension-assets.ts
  • scripts/extension-payload-check.ts
  • scripts/test/copy-extension-assets.test.ts
  • scripts/test/package-check-test-utils.ts
  • skills/firefox-cli/SKILL.md
💤 Files with no reviewable changes (2)
  • AMO_SOURCE_REVIEW.md
  • packages/protocol/src/capabilities.ts

Comment thread packages/extension/src/approval-request-service.ts
Comment thread packages/extension/src/approval-request.css Outdated
Comment thread packages/extension/src/browser-commands-test-utils.ts Outdated
Nek-12 added 2 commits June 11, 2026 16:27
Gate notify on protocol v4, including batch children, and let approval request pages reload before closing themselves after terminal approve or deny flows.

Update development tooling dependencies to latest, resolve the shell-quote audit through an override to 1.8.4, and record the major-tooling migration plan in docs/dependency-migrations.md.

Major release-age evidence: eslint 10.0.0 published 2026-02-06; @eslint/js 10.0.1 published 2026-02-06; @types/node 25.0.0 published 2025-12-10; installed typescript 6.0.3 published 2026-04-16; vite 8.0.0 published 2026-03-12.

Verification: bun run deps:check; bun run check; bun run release:check:local.
Resolve follow-up review findings by settling approval requests when native approval throws, keeping in-memory approval false when pair-token persistence fails, normalizing approval request CSS fallback casing, and removing the showNotification test assertion.

Verification: bun run test packages/extension/src/background-controller-approval.test.ts packages/extension/src/approval-request.test.ts packages/extension/src/background-controller.test.ts; bun run typecheck; bun run lint; bun run check.
@Nek-12 Nek-12 self-assigned this Jun 11, 2026
@Nek-12 Nek-12 merged commit 36d0d1d into main Jun 11, 2026
11 checks passed
@Nek-12 Nek-12 deleted the fix-extension-approval-persistence branch June 11, 2026 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant