Skip to content

feat: UNCOMPACT_DASHBOARD_URL override and --debug logging for auth flow#568

Merged
greynewell merged 6 commits intomainfrom
claude/debug-auth-staging-20260309-0001
Mar 9, 2026
Merged

feat: UNCOMPACT_DASHBOARD_URL override and --debug logging for auth flow#568
greynewell merged 6 commits intomainfrom
claude/debug-auth-staging-20260309-0001

Conversation

@greynewell
Copy link
Contributor

@greynewell greynewell commented Mar 9, 2026

Problem

When the browser freezes after GitHub auth, there was no way to:

  1. Reproduce the issue against staging (dashboard URL was a hardcoded constant)
  2. See where in the callback flow things were breaking (no debug output)

Changes

1. `UNCOMPACT_DASHBOARD_URL` env var

Overrides the dashboard base domain used to build the CLI auth URL. No recompile needed for staging tests:

```sh
UNCOMPACT_DASHBOARD_URL=https://staging.dashboard.supermodeltools.com uncompact auth login
```

Implemented in `config.EffectiveCLIAuthURL()` — falls back to the production constant when the env var is not set.

2. `--debug` wired into `authLoginBrowser`

Running `uncompact auth login --debug` now emits:

```
[debug] auth: callback server listening on 127.0.0.1:PORT
[debug] auth: dashboard URL: https://staging.dashboard.../cli-auth/?port=PORT&state=STATE
[debug] auth: callback received: /callback?state=...&key=...
[debug] auth: key received (N chars)
```

If the browser freezes before redirecting back, the callback line never appears — pointing at the dashboard side. If it appears but with a wrong state or error param, it points at a specific mismatch.

How to debug the staging freeze

```sh
UNCOMPACT_DASHBOARD_URL=https://staging.dashboard.supermodeltools.com
uncompact auth login --debug
```

Watch the output:

  • Callback server starts → dashboard URL logged → browser opens
  • If no callback line appears after GitHub auth completes: the dashboard is not redirecting to localhost (staging-side bug)
  • If callback received but `state mismatch`: the state param is being dropped or mangled by the staging dashboard
  • If callback received but `error=...`: the dashboard is explicitly sending an error param; check what it says
  • If key received but auth still feels broken: the issue is in key validation, not the OAuth redirect

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Interactive prompt to detect and optionally install local editor hooks for the code assistant, showing a preview and confirming success.
  • Improvements

    • Allow overriding dashboard and API base URLs via UNCOMPACT_DASHBOARD_URL and UNCOMPACT_API_URL.
    • Enhanced authentication logging and debug messages for browser-based login.
    • Post-install now conditionally runs hook installation or initiates auth based on authentication state.
  • Documentation

    • Updated docs to reflect combined auth/install flow and new environment variables.

…flow

Two things needed to debug auth issues against staging:

1. UNCOMPACT_DASHBOARD_URL env var — overrides the dashboard base URL so
   the CLI auth flow can be pointed at a staging environment without
   recompiling:

   UNCOMPACT_DASHBOARD_URL=https://staging.dashboard.example.com uncompact auth login

2. --debug flag wired into authLoginBrowser — logs the full dashboard URL
   opened, every incoming callback request (with full query string), state
   comparison result, and key receipt so the exact failure point is visible:

   uncompact auth login --debug

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 286347bc-03af-41c9-a9e9-1f040563faee

📥 Commits

Reviewing files that changed from the base of the PR and between 6bd01a1 and 659b305.

📒 Files selected for processing (1)
  • cmd/auth.go

Walkthrough

Adds env overrides for dashboard/API URLs and a new EffectiveCLIAuthURL(); instruments browser-based auth login with debug logs; and adds an optional automatic Claude Code hooks installation flow after saving auth keys (diff preview, prompt, and install).

Changes

Cohort / File(s) Summary
Config Infrastructure
internal/config/config.go
Add EnvDashboardURL (UNCOMPACT_DASHBOARD_URL) and EnvAPIURL (UNCOMPACT_API_URL); new EffectiveCLIAuthURL() to prefer env override; Load() uses UNCOMPACT_API_URL to override API base URL when present.
Auth & Hooks Flow
cmd/auth.go
Add debug logging in browser auth flow; switch dashboard URL source to EffectiveCLIAuthURL(); extend saveAndCacheKey to call autoInstallHooks() which locates Claude Code settings, shows a diff, prompts user, and installs hooks if confirmed.
Docs / UX
README.md
Update auth/install docs to reflect combined auth+hooks install behavior; add UNCOMPACT_API_URL and UNCOMPACT_DASHBOARD_URL docs; streamline quick-start and install guidance.
Installer Script
npm/install.js
Post-install now checks whether binary is authenticated: if authenticated, runs hook installation to ensure hooks are current; otherwise invokes auth login. Conditionalizes messaging and error handling based on auth state.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as User
  participant CLI as CLI
  participant Browser as Browser/Dashboard
  participant CB as CallbackServer
  participant Hooks as HooksInstaller

  User->>CLI: run `auth login`
  CLI->>Browser: open EffectiveCLIAuthURL
  Browser-->>CB: user authenticates -> redirect callback
  CB->>CLI: deliver callback (state, query)
  CLI->>CLI: validate state & save key
  CLI->>Hooks: autoInstallHooks() -> find settings & compute diff
  Hooks->>User: show diff & prompt to install
  User-->>Hooks: confirm install
  Hooks->>Hooks: perform install
  Hooks-->>CLI: return install result
  CLI->>User: print final status / guidance
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

A tiny CLI opens a door,
Env flags point to one more shore,
Callbacks hum and logs explain,
Hooks show a diff — then you say "gain!"
Confirm the install, setup's humane. 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly matches the main changes: environment variable override (UNCOMPACT_DASHBOARD_URL) and debug logging for the auth flow are both core features implemented across multiple files.

✏️ 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 claude/debug-auth-staging-20260309-0001

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

Copy link

@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

🧹 Nitpick comments (1)
internal/config/config.go (1)

45-52: Consider making the dashboard override the single source of truth.

Right now only the browser-login URL respects UNCOMPACT_DASHBOARD_URL. The same auth flow still falls back to production URLs in cmd/auth.go Line 51 and Lines 224-228, so a staging run can quietly bounce back to prod after any browser-login failure. I’d derive the dashboard root, key page, and CLI auth URL from one helper.

♻️ Suggested shape
+func EffectiveDashboardURL() string {
+	if override := strings.TrimSpace(os.Getenv(EnvDashboardURL)); override != "" {
+		return strings.TrimRight(override, "/")
+	}
+	return DashboardURL
+}
+
+func EffectiveDashboardKeyURL() string {
+	return EffectiveDashboardURL() + "/api-keys/"
+}
+
 func EffectiveCLIAuthURL() string {
-	if override := os.Getenv(EnvDashboardURL); override != "" {
-		return strings.TrimRight(override, "/") + "/cli-auth/"
-	}
-	return DashboardCLIAuthURL
+	return EffectiveDashboardURL() + "/cli-auth/"
 }

Then switch the cmd/auth.go call sites that currently use DashboardKeyURL / DashboardURL to the effective helpers too.

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

In `@internal/config/config.go` around lines 45 - 52, The code only uses
EffectiveCLIAuthURL() for the CLI auth path but other places still reference
DashboardURL and DashboardKeyURL directly, allowing staging runs to fall back to
production; add a single-source helper (e.g., EffectiveDashboardRoot() that
reads EnvDashboardURL and defaults to DashboardURL) and derive
EffectiveCLIAuthURL() and EffectiveDashboardKeyURL() from that root, then
replace usages of DashboardURL and DashboardKeyURL in cmd/auth.go with the new
effective helpers so all auth-related URLs come from the same override logic.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmd/auth.go`:
- Around line 140-145: The debug logging currently prints sensitive data (full
URL and state token) via r.URL.String() and gotState; update the logging to
redact secrets before output: parse r.URL.Query(), replace values for sensitive
keys like "key", "state", "token" (or any long-looking API keys) with
"<redacted>" and log the sanitized URL or only the path plus sanitized query
instead of r.URL.String(), and for the state comparison log (where gotState and
state are used) avoid printing raw token values—either mask them (e.g., show
first/last chars) or log only whether they matched; make these changes in the
logFn calls referenced (logFn, r.URL, gotState, state) and apply the same
redaction approach to the other occurrence around lines 182-183.

---

Nitpick comments:
In `@internal/config/config.go`:
- Around line 45-52: The code only uses EffectiveCLIAuthURL() for the CLI auth
path but other places still reference DashboardURL and DashboardKeyURL directly,
allowing staging runs to fall back to production; add a single-source helper
(e.g., EffectiveDashboardRoot() that reads EnvDashboardURL and defaults to
DashboardURL) and derive EffectiveCLIAuthURL() and EffectiveDashboardKeyURL()
from that root, then replace usages of DashboardURL and DashboardKeyURL in
cmd/auth.go with the new effective helpers so all auth-related URLs come from
the same override logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7d7483e6-c5f0-4caf-9423-e2786dcbcf99

📥 Commits

Reviewing files that changed from the base of the PR and between 57756c9 and a9b5584.

📒 Files selected for processing (2)
  • cmd/auth.go
  • internal/config/config.go

greynewell and others added 5 commits March 9, 2026 16:30
The staging dashboard issues keys that are only valid against the staging
API. Without an API URL override, the CLI validates them against production
and gets "invalid API key". UNCOMPACT_API_URL lets both overrides be set
together for a full staging test:

  UNCOMPACT_DASHBOARD_URL=https://staging-dashboard.supermodeltools.com \
  UNCOMPACT_API_URL=https://staging-api.supermodeltools.com \
  uncompact auth login --debug

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After successful authentication, automatically offer to install the Claude
Code hooks so the entire setup is a single command. Previously users had
to run 'uncompact auth login' then 'uncompact install' separately; now
auth login handles both steps.

If hooks are already installed, confirms silently. If not, shows the diff
and prompts for confirmation before writing — matching the behaviour of
'uncompact install' but without requiring a separate command.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…or upgrades

Previously postinstall ran 'install --yes' then printed a message telling
the user to run 'uncompact auth login' separately — two steps.

Now:
- Fresh install (not authenticated): postinstall runs 'auth login', which
  handles browser OAuth + hook installation in one flow. npm install -g
  uncompact is the only command a new user needs to run.
- Upgrade (already authenticated): postinstall runs 'install --yes' to
  ensure hooks are current without re-prompting for auth.

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Quick Start is now a single command: npm install -g uncompact --foreground-scripts
- auth login flow documented as handling both auth and hook installation
- Added UNCOMPACT_API_URL and UNCOMPACT_DASHBOARD_URL to env vars table
- Updated caching strategy to reflect fast-fail on connection errors
- Removed now-redundant separate auth and install steps

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The callback URL contains key=smsk_... and state=<token> — both secrets.
Logging r.URL.String() or raw state values would expose them in CI logs,
bug reports, and support tickets.

- Callback log now prints only the path and param names (never values)
- State mismatch log drops the raw token values entirely
- Dashboard URL log shows port only; state is marked <redacted>

Co-Authored-By: Grey Newell <greyshipscode@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greynewell greynewell merged commit c4ae1dd into main Mar 9, 2026
2 checks passed
@greynewell greynewell deleted the claude/debug-auth-staging-20260309-0001 branch March 9, 2026 20:46
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.

1 participant