Skip to content

feat(auth): auto-open browser for device flow verification URL#243

Open
meijing0114 wants to merge 2 commits intolarksuite:mainfrom
meijing0114:feat/auto-open-browser
Open

feat(auth): auto-open browser for device flow verification URL#243
meijing0114 wants to merge 2 commits intolarksuite:mainfrom
meijing0114:feat/auto-open-browser

Conversation

@meijing0114
Copy link
Copy Markdown

@meijing0114 meijing0114 commented Apr 3, 2026

Summary

  • Auto-open the user's default browser after printing the device flow verification URL
  • Applies to both auth login and config init --new flows
  • On failure, silently continues — the plain-text URL is always printed

Changes

  • New: internal/cmdutil/browser.goOpenBrowser(url) using platform commands (open/xdg-open/start)
  • New: internal/cmdutil/browser_test.go — smoke test
  • Edit: cmd/auth/login.go — call OpenBrowser() after printing URL (both --no-wait and normal paths)
  • Edit: cmd/auth/login_messages.go — add BrowserOpened message (zh/en)
  • Edit: cmd/config/init_interactive.go — call OpenBrowser() after printing app registration URL
  • Edit: cmd/config/init_messages.go — add BrowserOpened message (zh/en)

Test plan

  • ./lark-cli auth login --domain calendar opens browser on macOS
  • Plain-text URL is always present in output regardless of browser open result
  • Unit tests pass: go test ./cmd/auth/... ./internal/cmdutil/... ./cmd/config/...

Spec: docs/spec-auto-open-browser.md

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Automatically open the verification URL in the system browser during authentication and "create new app" flows on supported platforms
    • Display a confirmation message when the browser is successfully opened
  • Tests

    • Added a test ensuring the browser-open call completes without panicking

After printing the verification URL, attempt to open the user's default
browser via platform command (open/xdg-open/start). On success, print a
hint; on failure, silently continue — the plain-text URL is always shown.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 3, 2026

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions bot added the size/L Large or sensitive change across domains or core paths label Apr 3, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1cbbae87-82f3-4445-b348-465da18311aa

📥 Commits

Reviewing files that changed from the base of the PR and between 39c5b25 and 2db9318.

📒 Files selected for processing (2)
  • cmd/auth/login.go
  • internal/cmdutil/browser.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • cmd/auth/login.go
  • internal/cmdutil/browser.go

📝 Walkthrough

Walkthrough

Adds a cross-platform helper to open URLs in the system browser and invokes it from interactive verification flows, printing a localized "BrowserOpened" message only when the browser-launch attempt reports success.

Changes

Cohort / File(s) Summary
Browser Utility
internal/cmdutil/browser.go, internal/cmdutil/browser_test.go
New exported OpenBrowser(url string) bool implementing OS-specific launch (darwin: open, linux: xdg-open, windows: cmd /c start), returns true if process starts; basic no-panic test added.
Authentication Integration
cmd/auth/login.go, cmd/auth/login_messages.go
In the non-JSON device-authorization path, attempt cmdutil.OpenBrowser(authResp.VerificationUriComplete) and, only if it returns true, print localized BrowserOpened to f.IOStreams.ErrOut. Added BrowserOpened field and localized texts. (JSON/device auth output and polling/token flow unchanged.)
Configuration Integration
cmd/config/init_interactive.go, cmd/config/init_messages.go
During interactive "create new app" flow, after showing verification URL (and QR), call cmdutil.OpenBrowser(verificationURL) and print localized BrowserOpened if it returns true. Added BrowserOpened message field and localized texts.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as "CLI"
    participant CmdUtil as "cmdutil.OpenBrowser"
    participant OS as "OS / Shell"
    participant Auth as "Auth Server (polling)"

    CLI->>CLI: print verification URL (and QR)
    CLI->>CmdUtil: OpenBrowser(url)
    CmdUtil->>OS: start platform command (open/xdg-open/start)
    OS-->>CmdUtil: process started
    CmdUtil-->>CLI: returns true
    CLI->>CLI: print localized BrowserOpened
    CLI->>Auth: begin polling for token
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nudged the link with eager paws,
The browser leapt without a cause,
A tiny message, snug and cheered,
"Opened for you" — the path cleared. 🌷

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main change: adding auto-open browser functionality for device flow verification URLs.
Description check ✅ Passed The PR description includes all required template sections (Summary, Changes, Test Plan, Related Issues) with substantive content and clear details about the implementation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 3, 2026

Greptile Summary

This PR adds automatic browser-opening to the device-flow verification URL in both auth login and config init --new flows, with graceful silent fallback when the browser cannot be launched. All three concerns from the previous review round have been addressed: the Windows start window-title quirk is fixed via an explicit empty-string title argument, zombie processes are reaped with go cmd.Wait(), and --no-wait is correctly excluded because it returns early before OpenBrowser is ever called.

Confidence Score: 5/5

Safe to merge — all previously raised issues are resolved and no new issues found.

All three prior P1 concerns (Windows start title, zombie process, --no-wait headless launch) are correctly addressed in the current diff. The change is small, well-scoped, and fails silently without affecting the core auth flow.

No files require special attention.

Important Files Changed

Filename Overview
internal/cmdutil/browser.go New utility: platform-aware browser opener; correctly uses empty title for Windows start, reaps child with go cmd.Wait(), and silently returns false on failure or unsupported OS.
internal/cmdutil/browser_test.go Smoke test verifying no panic; minimal but appropriate for a fire-and-forget OS-command wrapper.
cmd/auth/login.go OpenBrowser called only in the interactive non-JSON path; the --no-wait early return at line 240 correctly prevents browser launch in headless/agent contexts.
cmd/auth/login_messages.go Adds BrowserOpened message in both zh and en; alignment-only reformatting of existing fields.
cmd/config/init_interactive.go Adds OpenBrowser after printing the app-registration URL; follows the same pattern as the auth login flow.
cmd/config/init_messages.go Adds BrowserOpened message in both zh and en locales; no issues.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[auth login / config init] --> B[RequestDeviceAuthorization]
    B --> C{--no-wait flag?}
    C -- yes --> D[Emit JSON output\nreturn early]
    C -- no --> E{--json flag?}
    E -- yes --> F[Emit JSON event]
    E -- no --> G[Print verification URL]
    G --> H[OpenBrowser url]
    H --> I{Launched OK?}
    I -- yes --> J[Print BrowserOpened message]
    I -- no --> K[Silent fallback\nURL already printed]
    J --> L[PollDeviceToken]
    K --> L
    F --> L
    L --> M[Login / Init complete]
Loading

Reviews (2): Last reviewed commit: "fix(auth): address PR review feedback fo..." | Re-trigger Greptile

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
cmd/auth/login.go (1)

240-242: Deduplicate the browser-open print block to avoid drift.

The same open-and-notify logic appears twice. Extract a small helper/closure in authLoginRun and call it from both branches.

♻️ Minimal refactor sketch
+	openAndNotify := func(url string) {
+		if cmdutil.OpenBrowser(url) {
+			fmt.Fprintf(f.IOStreams.ErrOut, "%s\n", msg.BrowserOpened)
+		}
+	}
@@
-		if cmdutil.OpenBrowser(authResp.VerificationUriComplete) {
-			fmt.Fprintf(f.IOStreams.ErrOut, "%s\n", msg.BrowserOpened)
-		}
+		openAndNotify(authResp.VerificationUriComplete)
@@
-		if cmdutil.OpenBrowser(authResp.VerificationUriComplete) {
-			fmt.Fprintf(f.IOStreams.ErrOut, "%s\n", msg.BrowserOpened)
-		}
+		openAndNotify(authResp.VerificationUriComplete)

Also applies to: 263-265

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/auth/login.go` around lines 240 - 242, The browser-open-and-notify logic
is duplicated; inside authLoginRun extract a small helper (e.g., openAndNotify
or a closure) that takes the verification URL and handles
cmdutil.OpenBrowser(authResp.VerificationUriComplete) plus
fmt.Fprintf(f.IOStreams.ErrOut, "%s\n", msg.BrowserOpened) so both places (the
current block using authResp.VerificationUriComplete and the other branch around
lines 263-265) simply call that helper; reference cmdutil.OpenBrowser,
authResp.VerificationUriComplete, msg.BrowserOpened and f.IOStreams.ErrOut when
implementing the helper and replace the duplicated blocks with calls to it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/cmdutil/browser_test.go`:
- Around line 8-12: TestOpenBrowser_NoPanic currently calls
OpenBrowser("https://example.com") with no assertions and may spawn a real
browser; refactor OpenBrowser to accept an injectable command starter (e.g., a
function type like cmdStarter or an interface) so tests can supply a fake
executor, then update TestOpenBrowser_NoPanic to inject a stubbed starter that
records the command and does not spawn a process and assert the expected command
selection/arguments for each runtime.GOOS (windows, darwin, linux) by
table-driven subtests; reference the OpenBrowser function and
TestOpenBrowser_NoPanic when making these changes and ensure the production call
site uses the real starter by default.

In `@internal/cmdutil/browser.go`:
- Around line 14-23: The Windows branch in OpenBrowser incorrectly uses
exec.Command("cmd","/c","start", url) which allows cmd.exe to parse
metacharacters (e.g., & in query strings); update the Windows case inside the
OpenBrowser function to call start with an empty title placeholder so the URL is
passed safely (use the form equivalent to exec.Command("cmd", "/c", "start", "",
url)); optionally, as a defense-in-depth step, validate the URL with
url.ParseRequestURI() before launching to avoid passing malformed input to the
command.

---

Nitpick comments:
In `@cmd/auth/login.go`:
- Around line 240-242: The browser-open-and-notify logic is duplicated; inside
authLoginRun extract a small helper (e.g., openAndNotify or a closure) that
takes the verification URL and handles
cmdutil.OpenBrowser(authResp.VerificationUriComplete) plus
fmt.Fprintf(f.IOStreams.ErrOut, "%s\n", msg.BrowserOpened) so both places (the
current block using authResp.VerificationUriComplete and the other branch around
lines 263-265) simply call that helper; reference cmdutil.OpenBrowser,
authResp.VerificationUriComplete, msg.BrowserOpened and f.IOStreams.ErrOut when
implementing the helper and replace the duplicated blocks with calls to it.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83cd1d5d-c79c-46d3-a7d2-d827d3bf0401

📥 Commits

Reviewing files that changed from the base of the PR and between 51a6ada and 39c5b25.

📒 Files selected for processing (6)
  • cmd/auth/login.go
  • cmd/auth/login_messages.go
  • cmd/config/init_interactive.go
  • cmd/config/init_messages.go
  • internal/cmdutil/browser.go
  • internal/cmdutil/browser_test.go

Comment on lines +8 to +12
func TestOpenBrowser_NoPanic(t *testing.T) {
// Verify OpenBrowser doesn't panic on any URL.
// On CI/headless this may return true (process spawned) or false — both are fine.
_ = OpenBrowser("https://example.com")
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

This test is non-hermetic and effectively assertion-free.

Line 11 may launch a real browser, and the test passes even if command selection regresses. Please make OpenBrowser testable via an injected command starter and assert expected behavior per runtime.GOOS.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/cmdutil/browser_test.go` around lines 8 - 12,
TestOpenBrowser_NoPanic currently calls OpenBrowser("https://example.com") with
no assertions and may spawn a real browser; refactor OpenBrowser to accept an
injectable command starter (e.g., a function type like cmdStarter or an
interface) so tests can supply a fake executor, then update
TestOpenBrowser_NoPanic to inject a stubbed starter that records the command and
does not spawn a process and assert the expected command selection/arguments for
each runtime.GOOS (windows, darwin, linux) by table-driven subtests; reference
the OpenBrowser function and TestOpenBrowser_NoPanic when making these changes
and ensure the production call site uses the real starter by default.

- Fix Windows `cmd /c start` URL handling: add empty title arg to
  prevent URL being treated as window title
- Remove auto-open from --no-wait path (agent/script context)
- Add `go cmd.Wait()` to reap child process

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/L Large or sensitive change across domains or core paths

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants