Skip to content

Improve auth flow and append code in auth request URL#102

Merged
gtsiolis merged 2 commits intomainfrom
george/pro-241
Mar 12, 2026
Merged

Improve auth flow and append code in auth request URL#102
gtsiolis merged 2 commits intomainfrom
george/pro-241

Conversation

@gtsiolis
Copy link
Copy Markdown
Member

@gtsiolis gtsiolis commented Mar 11, 2026

Fix DES-160 and DES-157.

BEFORE AFTER
Screenshot 2026-03-11 at 19 02 39 Screenshot 2026-03-11 at 20 52 29

@gtsiolis gtsiolis changed the title George/pro 241 Simplify login prompt and show browser fallback URL Mar 11, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 11, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: f6e2696e-f91b-481c-acb8-716ab2c32b3e

📥 Commits

Reviewing files that changed from the base of the PR and between d3bdae1 and 3afdfe1.

📒 Files selected for processing (2)
  • internal/auth/login.go
  • internal/auth/login_test.go

📝 Walkthrough

Walkthrough

Adds a helper to build auth URLs with an optional one-time code query parameter, updates browser-fallback messaging and one-time code placement in formatter/UI, and adds tests for URL construction and updated formatting behavior.

Changes

Cohort / File(s) Summary
Authentication URL & tests
internal/auth/login.go, internal/auth/login_test.go
Introduce unexported buildAuthURL(webAppURL, authRequestID, code) using net/url and strings; replace string concat with helper; add table-driven tests covering code present/escaped/empty and trailing-slash trimming.
Formatter & formatter tests
internal/output/plain_format.go, internal/output/plain_format_test.go, internal/output/events_test.go
Reorder and reword AuthEvent output: print "Opening browser to login..." then "Browser didn't open? Visit " and emit "One-time code: " only when present (after URL). Update/add tests for code and no-code paths and expected formatted lines.
UI rendering
internal/ui/app.go
Adjust AuthEvent rendering to use the new fallback message and to render the "One-time code: " block only when code exists; minor layout tweaks.
Integration & sink tests
test/integration/login_test.go, internal/output/plain_sink_test.go
Update integration and sink test expectations: stop asserting the previous inline "Your one-time code" line and expect the auth URL to include ?code=... when code is present and the new fallback messaging.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • carole-lavillonniere
  • silv-io
  • anisaoshafi
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main changes: improving the auth flow and appending the code as a query parameter in the auth request URL.
Description check ✅ Passed The description is directly related to the changeset, referencing the fixed issues (DES-160 and DES-157) and providing before/after screenshots showing the auth flow improvements.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch george/pro-241

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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: 4

🧹 Nitpick comments (4)
internal/output/events.go (1)

59-79: Add first-class emit helpers for the new status events.

InstanceInfoEvent and ServiceResourcesEvent are in the Event union now, but callers still have to fall back to the generic Emit, and the usual helper/test pattern for new events is incomplete. Matching EmitInstanceInfo / EmitServiceResources helpers would keep producers consistent and make parity coverage easier to extend.

♻️ Suggested helpers
+func EmitInstanceInfo(sink Sink, event InstanceInfoEvent) {
+	Emit(sink, event)
+}
+
+func EmitServiceResources(sink Sink, event ServiceResourcesEvent) {
+	Emit(sink, event)
+}

Based on learnings: When adding a new event type, update internal/output/events.go (event type + Event union constraint + emit helper), internal/output/plain_format.go (line formatting fallback), and tests in internal/output/*_test.go for formatter/sink behavior parity.

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

In `@internal/output/events.go` around lines 59 - 79, Add first-class emitter
helpers for the two new event types so callers don't need to call the generic
Emit directly: implement EmitInstanceInfo(ctx, e InstanceInfoEvent) and
EmitServiceResources(ctx, e ServiceResourcesEvent) (matching the existing helper
signatures/pattern used by other events) and have them call the generic Emit
with the concrete struct; update any tests to use these helpers. Ensure you
reference the types InstanceInfoEvent and ServiceResourcesEvent and follow the
existing helper naming/parameter conventions used by other emit helpers in this
package so formatter/sink parity remains consistent.
internal/ui/app.go (1)

151-159: Avoid duplicating AuthEvent wording in the TUI.

The new fallback text now lives here and in internal/output/plain_format.go, so plain and TUI rendering can drift on the next copy change. Prefer deriving the text from the shared formatter and only applying TUI-specific styling in this branch.

Based on learnings: UI should consume shared output events directly; reuse FormatEventLine(event any) for line-oriented rendering so plain and TUI stay consistent.

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

In `@internal/ui/app.go` around lines 151 - 159, The TUI branch handling the
AuthEvent duplicates plain-text wording instead of reusing the shared formatter;
change the AuthEvent case in the switch (the block that appends to a.lines using
appendLine and styledLine) to call the shared FormatEventLine(event any) (or the
existing formatter function) to obtain the canonical line(s) for the event and
then apply only TUI-specific styling (e.g., wrap/mark as secondary) before
appending to a.lines, so the TUI text stays consistent with
internal/output/plain_format.go; keep the existing styledLine/appendLine usage
but derive the content from FormatEventLine rather than hardcoding strings.
internal/output/plain_format.go (1)

151-153: Prefer emulator wording in the status details.

CONTAINER: is now part of the user-facing status output. That exposes the runtime implementation instead of the emulator concept the CLI uses elsewhere.

Based on learnings: In user-facing CLI/help/docs, prefer emulator over container/runtime; use container/runtime only for internal implementation details.

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

In `@internal/output/plain_format.go` around lines 151 - 153, Replace the
user-facing "CONTAINER: "+e.ContainerName entry with emulator wording so the
status shows the emulator label; modify the code that appends to meta (the block
that checks e.ContainerName in plain_format.go) to use "EMULATOR: " (or the
agreed-upon emulator label) instead of "CONTAINER: ", leaving the rest of the
logic (e.ContainerName and meta append) unchanged.
test/integration/status_test.go (1)

15-23: Force non-interactive mode in these tests.

These assertions are for plain-text output, but the command path is chosen at runtime. Right now the tests rely on whatever runLstk does with stdio; if that ever becomes terminal-backed, status will switch to Bubble Tea and these tests will become flaky or hang. Please pass the non-interactive flag/env explicitly here so the plain-sink path is pinned.

As per coding guidelines: **/integration/**/*_test.go: "Integration tests that run the CLI binary with Bubble Tea must use a PTY (github.com/creack/pty) since Bubble Tea requires a terminal; use pty.Start(cmd) instead of cmd.CombinedOutput()..."

Also applies to: 25-59, 61-87

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

In `@test/integration/status_test.go` around lines 15 - 23, The test
TestStatusCommandFailsWhenNotRunning (and the other tests in ranges 25-59 and
61-87) currently invoke runLstk which may pick a terminal-backed path and
trigger Bubble Tea; update these tests to force non-interactive/plain-sink mode
by passing the explicit non-interactive flag or environment to runLstk (e.g.,
add "--no-interactive" or set a NO_INTERACTIVE env var via the runLstk call) so
the CLI takes the plain-text path; modify the calls to runLstk(testContext(t),
...) in TestStatusCommandFailsWhenNotRunning and the other affected tests to
include that non-interactive indicator so assertions against stderr/stdout
remain stable.
🤖 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/auth/login.go`:
- Around line 39-45: The call to browser.OpenURL(authURL) in the login flow
currently discards its error; update the login handler to check the returned
error from browser.OpenURL(authURL) and handle it (e.g., log a warning via
processLogger or l.sink, or return the error up the call stack) instead of
ignoring it. Locate the code around buildAuthURL(...), output.EmitAuth(...), and
the browser.OpenURL(authURL) call and ensure the OpenURL error is captured,
logged with context (including authURL or authReq.ID), and then either
propagated from the enclosing function or used to trigger a fallback path (such
as instructing the user to open authURL manually).

In `@internal/container/status.go`:
- Around line 122-125: The loop that parses NDJSON lines currently does
json.Unmarshal into the local variable chunk (map[string][]instanceResource) and
simply continues on error, which silently drops malformed resource chunks;
change this to surface the problem by returning or propagating an error (or at
minimum logging a warning) instead of continuing: when
json.Unmarshal([]byte(line), &chunk) fails, call the enclosing function's error
return (or processLogger.Warn/Error with the line content and err) so callers
see incomplete parsing; update the code path that uses chunk (the loop handling
map[string][]instanceResource) to handle the propagated error accordingly.
- Around line 35-58: The code currently leaks internal container identifiers via
c.Name() into error messages and the user-facing output
(InstanceInfoEvent.ContainerName); update the runtime checks and event
population to use the user-facing label c.DisplayName() instead of the raw
container name: replace uses of name in fmt.Errorf("checking %s running: %w",
...) and fmt.Errorf("%s is not running", ...) with c.DisplayName(), and set
InstanceInfoEvent.ContainerName = c.DisplayName() (keep using c.Name() only for
internal calls to rt.IsRunning and rt.ContainerStartedAt where the real
identifier is required).

In `@internal/output/plain_format.go`:
- Around line 101-105: The renderer currently prints the manual fallback copy
whenever AuthEvent.URL is set because AuthEvent only has Preamble/URL; fix by
making AuthEvent carry a domain fact for which flow is active (e.g., add a
Mode/Flow enum or a bool like BrowserFlow/ManualFallback on the AuthEvent
struct) and update the plain_format.go rendering logic that reads e.URL to
branch on that new field: when Mode==auto (browser) print the "Opening browser
to login..." path, and when Mode==manual print the "Browser didn't open? Visit
<URL>" fallback. Ensure Preamble is still rendered as before and update any
constructors sending AuthEvent to populate the new field.

---

Nitpick comments:
In `@internal/output/events.go`:
- Around line 59-79: Add first-class emitter helpers for the two new event types
so callers don't need to call the generic Emit directly: implement
EmitInstanceInfo(ctx, e InstanceInfoEvent) and EmitServiceResources(ctx, e
ServiceResourcesEvent) (matching the existing helper signatures/pattern used by
other events) and have them call the generic Emit with the concrete struct;
update any tests to use these helpers. Ensure you reference the types
InstanceInfoEvent and ServiceResourcesEvent and follow the existing helper
naming/parameter conventions used by other emit helpers in this package so
formatter/sink parity remains consistent.

In `@internal/output/plain_format.go`:
- Around line 151-153: Replace the user-facing "CONTAINER: "+e.ContainerName
entry with emulator wording so the status shows the emulator label; modify the
code that appends to meta (the block that checks e.ContainerName in
plain_format.go) to use "EMULATOR: " (or the agreed-upon emulator label) instead
of "CONTAINER: ", leaving the rest of the logic (e.ContainerName and meta
append) unchanged.

In `@internal/ui/app.go`:
- Around line 151-159: The TUI branch handling the AuthEvent duplicates
plain-text wording instead of reusing the shared formatter; change the AuthEvent
case in the switch (the block that appends to a.lines using appendLine and
styledLine) to call the shared FormatEventLine(event any) (or the existing
formatter function) to obtain the canonical line(s) for the event and then apply
only TUI-specific styling (e.g., wrap/mark as secondary) before appending to
a.lines, so the TUI text stays consistent with internal/output/plain_format.go;
keep the existing styledLine/appendLine usage but derive the content from
FormatEventLine rather than hardcoding strings.

In `@test/integration/status_test.go`:
- Around line 15-23: The test TestStatusCommandFailsWhenNotRunning (and the
other tests in ranges 25-59 and 61-87) currently invoke runLstk which may pick a
terminal-backed path and trigger Bubble Tea; update these tests to force
non-interactive/plain-sink mode by passing the explicit non-interactive flag or
environment to runLstk (e.g., add "--no-interactive" or set a NO_INTERACTIVE env
var via the runLstk call) so the CLI takes the plain-text path; modify the calls
to runLstk(testContext(t), ...) in TestStatusCommandFailsWhenNotRunning and the
other affected tests to include that non-interactive indicator so assertions
against stderr/stdout remain stable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 4dbdcd7e-5a02-48ed-a390-82718cb3975a

📥 Commits

Reviewing files that changed from the base of the PR and between aa93b36 and 773ef44.

📒 Files selected for processing (20)
  • cmd/root.go
  • cmd/status.go
  • internal/auth/login.go
  • internal/auth/login_test.go
  • internal/auth/mock_token_storage.go
  • internal/container/status.go
  • internal/output/events.go
  • internal/output/events_test.go
  • internal/output/plain_format.go
  • internal/output/plain_format_test.go
  • internal/output/plain_sink_test.go
  • internal/runtime/docker.go
  • internal/runtime/mock_runtime.go
  • internal/runtime/runtime.go
  • internal/ui/app.go
  • internal/ui/components/input_prompt.go
  • internal/ui/run_status.go
  • test/integration/env/env.go
  • test/integration/login_test.go
  • test/integration/status_test.go

Copy link
Copy Markdown
Member

@silv-io silv-io left a comment

Choose a reason for hiding this comment

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

TBH I like it more with the code displayed. It makes it look more actionable?

What if the link fails somehow and the code isn't copied? What if there is a MITM somehow? I think it should still be easily recognizable what the code is.

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.

🧹 Nitpick comments (1)
internal/output/events.go (1)

61-77: Consider adding emit helper functions for new event types.

The new InstanceInfoEvent and ServiceResourcesEvent types are added to the Event union but lack corresponding emit helpers like EmitInstanceInfo and EmitServiceResources. While callers can use Emit() directly, the pattern established by other events (e.g., EmitAuth, EmitStatus) suggests helpers improve discoverability and consistency.

♻️ Suggested helpers
func EmitInstanceInfo(sink Sink, event InstanceInfoEvent) {
	Emit(sink, event)
}

func EmitServiceResources(sink Sink, event ServiceResourcesEvent) {
	Emit(sink, event)
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/output/events.go` around lines 61 - 77, Add two thin emitter helpers
to mirror existing patterns: implement EmitInstanceInfo(sink Sink, event
InstanceInfoEvent) and EmitServiceResources(sink Sink, event
ServiceResourcesEvent) that simply call Emit(sink, event). Place them alongside
other emit helpers so callers can use EmitInstanceInfo and EmitServiceResources
instead of calling Emit directly; reference the existing Emit function and the
types InstanceInfoEvent, ServiceResourcesEvent and the Sink type when adding
these helpers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/output/events.go`:
- Around line 61-77: Add two thin emitter helpers to mirror existing patterns:
implement EmitInstanceInfo(sink Sink, event InstanceInfoEvent) and
EmitServiceResources(sink Sink, event ServiceResourcesEvent) that simply call
Emit(sink, event). Place them alongside other emit helpers so callers can use
EmitInstanceInfo and EmitServiceResources instead of calling Emit directly;
reference the existing Emit function and the types InstanceInfoEvent,
ServiceResourcesEvent and the Sink type when adding these helpers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 51c3bffe-ee4c-4bba-a970-f458e3760618

📥 Commits

Reviewing files that changed from the base of the PR and between 773ef44 and f335355.

📒 Files selected for processing (19)
  • cmd/root.go
  • cmd/status.go
  • internal/auth/login.go
  • internal/auth/login_test.go
  • internal/auth/mock_token_storage.go
  • internal/container/status.go
  • internal/output/events.go
  • internal/output/events_test.go
  • internal/output/plain_format.go
  • internal/output/plain_format_test.go
  • internal/output/plain_sink_test.go
  • internal/runtime/docker.go
  • internal/runtime/mock_runtime.go
  • internal/runtime/runtime.go
  • internal/ui/app.go
  • internal/ui/run_status.go
  • test/integration/env/env.go
  • test/integration/login_test.go
  • test/integration/status_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • internal/auth/mock_token_storage.go
  • internal/runtime/runtime.go
  • cmd/status.go
  • test/integration/login_test.go
  • cmd/root.go
  • internal/runtime/docker.go
  • internal/container/status.go

@gtsiolis gtsiolis changed the title Simplify login prompt and show browser fallback URL Improve auth flow and append code in auth request URL Mar 11, 2026
@gtsiolis
Copy link
Copy Markdown
Member Author

Good point on the code print, @silv-io! Added the code separately on its own line, but moved it further below using secondary text since with the auto-fill this is no longer an important instruction for users to follow. ✔️

Updated also screenshots in the PR description. ✔️


Adding an updated plan ahead for more context on the direction for future reference:

  1. Browser auto-open. We now auto-open the browser. Today the code is not auto-filled yet, so users still land on a form they need to complete manually without clear instructions. The auto-fill from the query param should make this smoother.
  2. Device flow as the current baseline. For now we default to the device flow. This keeps the behavior consistent and avoids relying on the previous redirect-based approach, which had awkward UX and weaker security semantics, see previous planning.
  3. Authorization step (planned). A next improvement would be introducing a proper authorization page where the user explicitly approves access before the token exchange, DES-115.
  4. Authentication flow choice. Once the authorization step described in [3] exists, we can decide whether to default to the browser authorization flow, with device flow as fallback when no browser is detected, or explicitly let users choose the auth method.
  5. Polling is needed. Regardless of which path we choose for [4], the CLI should poll the backend while waiting for authentication instead of asking the user to press for user input when ready, PRO-215.

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.

🧹 Nitpick comments (1)
internal/output/events_test.go (1)

17-43: Test coverage is limited to URL-only scenario.

This test only validates the AuthEvent without a Code field. While plain_format_test.go covers the full scenario with Code, consider adding a second test case here to verify EmitAuth behavior when Code is populated, ensuring the emit helper and formatter work together correctly for both paths.

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

In `@internal/output/events_test.go` around lines 17 - 43, Add a second test case
that calls EmitAuth(sink, AuthEvent{Preamble: "Welcome", URL:
"https://example.com", Code: "1234"}) and then asserts sink.events length,
type-asserts the stored event to AuthEvent, checks event.Code, event.URL and
event.Preamble, and finally calls FormatEventLine(event) and compares the
returned line to the expected formatted string for the Code-present path; update
the test to exercise EmitAuth, AuthEvent and FormatEventLine together for the
Code-populated scenario.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/output/events_test.go`:
- Around line 17-43: Add a second test case that calls EmitAuth(sink,
AuthEvent{Preamble: "Welcome", URL: "https://example.com", Code: "1234"}) and
then asserts sink.events length, type-asserts the stored event to AuthEvent,
checks event.Code, event.URL and event.Preamble, and finally calls
FormatEventLine(event) and compares the returned line to the expected formatted
string for the Code-present path; update the test to exercise EmitAuth,
AuthEvent and FormatEventLine together for the Code-populated scenario.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: e5067e66-307e-4470-b054-b6b523b9e5d7

📥 Commits

Reviewing files that changed from the base of the PR and between f335355 and 5ed2e10.

📒 Files selected for processing (8)
  • internal/auth/login.go
  • internal/auth/login_test.go
  • internal/output/events_test.go
  • internal/output/plain_format.go
  • internal/output/plain_format_test.go
  • internal/output/plain_sink_test.go
  • internal/ui/app.go
  • test/integration/login_test.go
✅ Files skipped from review due to trivial changes (1)
  • internal/output/plain_sink_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/auth/login.go
  • internal/auth/login_test.go
  • internal/ui/app.go

@gtsiolis gtsiolis requested a review from silv-io March 11, 2026 19:10
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: 1

♻️ Duplicate comments (1)
internal/auth/login.go (1)

41-46: ⚠️ Potential issue | 🟡 Minor

Still handle the browser.OpenURL failure path.

Line 46 still ignores the error from browser.OpenURL(authURL), so this flow cannot distinguish “browser opened” from “browser launch failed” and always shows the optimistic path. Please check it and downgrade to a warning/manual-open flow when the launch fails. As per coding guidelines "Errors returned by functions should always be checked unless in test files".

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

In `@internal/auth/login.go` around lines 41 - 46, The call to
browser.OpenURL(authURL) in internal/auth/login.go is ignoring its returned
error; update the logic after output.EmitAuth(...) to capture the error from
browser.OpenURL(authURL), check it, and on failure downgrade to a
warning/manual-open flow: call the logger (or output) to emit a warning that the
browser launch failed and instruct the user to open authURL manually (instead of
assuming success). Reference the browser.OpenURL call and the
EmitAuth/output.AuthEvent usage so you modify the branch where the URL is opened
and emit an alternate message when err != nil rather than discarding the error.
🤖 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/auth/login.go`:
- Around line 70-78: The buildAuthURL function can produce a double-slash when
webAppURL ends with '/', so normalize webAppURL by trimming any trailing '/'
before concatenating the auth path (e.g. use strings.TrimSuffix or TrimRight on
the webAppURL in buildAuthURL), then rebuild the URL as normalizedWebAppURL +
"/auth/request/" + authRequestID and preserve the existing query behavior for
code; also add a regression unit test in internal/auth/login_test.go that passes
a webAppURL with a trailing slash and asserts the returned URL does not contain
a double '//' before "auth/request".

---

Duplicate comments:
In `@internal/auth/login.go`:
- Around line 41-46: The call to browser.OpenURL(authURL) in
internal/auth/login.go is ignoring its returned error; update the logic after
output.EmitAuth(...) to capture the error from browser.OpenURL(authURL), check
it, and on failure downgrade to a warning/manual-open flow: call the logger (or
output) to emit a warning that the browser launch failed and instruct the user
to open authURL manually (instead of assuming success). Reference the
browser.OpenURL call and the EmitAuth/output.AuthEvent usage so you modify the
branch where the URL is opened and emit an alternate message when err != nil
rather than discarding the error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 84d754e3-63a7-4db5-a001-8652c470508c

📥 Commits

Reviewing files that changed from the base of the PR and between 5ed2e10 and d3bdae1.

📒 Files selected for processing (8)
  • internal/auth/login.go
  • internal/auth/login_test.go
  • internal/output/events_test.go
  • internal/output/plain_format.go
  • internal/output/plain_format_test.go
  • internal/output/plain_sink_test.go
  • internal/ui/app.go
  • test/integration/login_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/output/plain_sink_test.go
  • test/integration/login_test.go
  • internal/output/plain_format.go
  • internal/output/events_test.go

@gtsiolis gtsiolis self-assigned this Mar 11, 2026
Copy link
Copy Markdown
Collaborator

@carole-lavillonniere carole-lavillonniere left a comment

Choose a reason for hiding this comment

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

👏

@gtsiolis
Copy link
Copy Markdown
Member Author

Thanks for taking a look, @carole-lavillonniere @silv-io! 🏀

@gtsiolis gtsiolis merged commit 298adb6 into main Mar 12, 2026
8 checks passed
@gtsiolis gtsiolis deleted the george/pro-241 branch March 12, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants