Skip to content

fix(listen): populate team_id in dashboard deep-links for user-scoped CLI keys - #320

Merged
leggetter merged 2 commits into
mainfrom
claude/315-listen-dashboard-team-id
Aug 4, 2026
Merged

fix(listen): populate team_id in dashboard deep-links for user-scoped CLI keys#320
leggetter merged 2 commits into
mainfrom
claude/315-listen-dashboard-team-id

Conversation

@leggetter

Copy link
Copy Markdown
Collaborator

Fixes #315

Problem

When hookdeck listen is authenticated with a user-scoped CLI key (--cli-key or a stored hookdeck login credential), cfg.ProjectID is empty because the key isn't tied to a single project. The TUI's "View dashboard" header link and the per-event open-in-dashboard action (o) both rendered …?team_id= with an empty value.

Fix

  • Resolve the effective project id in Listen(): use the profile's active project_id when set, otherwise fall back to the team_id of the connections being listened to (already present on the fetched Connection objects — no extra API call). New resolveEffectiveProjectID helper.
  • The resolved id feeds the renderer (TUI links) and the compact/quiet-mode printer. The websocket/proxy config intentionally keeps the profile value, so connection behavior is unchanged.
  • Guard against empty ids: the TUI link construction is extracted into dashboardHomeURL / eventDashboardURL (pkg/listen/tui/links.go), which omit the team_id parameter entirely when the project id is unknown instead of emitting team_id=. The printer already had this guard; it now uses the resolved id.

Testing

  • TestResolveEffectiveProjectID covers profile-first precedence, fallback to the connections' team, skipping nil/empty entries, and the all-unknown case.
  • TestDashboardHomeURL / TestEventDashboardURL cover dashboard and console modes with and without a project id.
  • go build ./... and go test ./pkg/listen/... pass locally (pre-existing, unrelated failure in pkg/listen/healthcheck that requires binding port 443, which this sandbox disallows).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Tt8HTLV1iCoQyxH9vozKra


Generated by Claude Code

… CLI keys

User-scoped CLI keys are not tied to a single project, so cfg.ProjectID
was empty and the TUI rendered links like /events/cli?team_id= (and the
per-event open-in-dashboard action did the same).

Resolve the effective project id from the team that owns the fetched
connections when the profile has no active project, and use it for the
renderer and the compact/quiet-mode printer. The websocket config is
intentionally left on the profile value. As a final guard, the TUI link
builders now omit the team_id parameter entirely when the project id is
unknown instead of emitting an empty value.

Fixes #315

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tt8HTLV1iCoQyxH9vozKra

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes hookdeck listen dashboard deep-links when authenticated with user-scoped CLI keys by resolving an “effective” project/team identifier for link rendering and ensuring links don’t emit an empty team_id query parameter.

Changes:

  • Added resolveEffectiveProjectID to derive the id used for deep-links (profile project id first, otherwise connection TeamID).
  • Extracted TUI deep-link construction into dashboardHomeURL / eventDashboardURL to omit team_id when unknown, with focused unit tests.
  • Plumbed the resolved id into the TUI config and the compact/quiet printer output.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pkg/listen/listen.go Resolves effective project/team id and passes it into renderer/TUI configs; keeps proxy config unchanged.
pkg/listen/listen_test.go Adds unit tests for resolveEffectiveProjectID.
pkg/listen/printer.go Threads resolved id into compact/quiet output (dashboard link rendering).
pkg/listen/tui/view.go Uses centralized dashboard home URL helper for the header hint link.
pkg/listen/tui/update.go Uses centralized event deep-link helper for “open in dashboard” action.
pkg/listen/tui/links.go Adds URL helpers that omit team_id when the id is unknown.
pkg/listen/tui/links_test.go Adds unit tests for link helpers across dashboard/console modes with/without id.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/listen/printer.go Outdated
…n console mode

Review feedback on the compact/quiet printer: it linked the dashboard
root when the project id was unknown, and console mode dropped team_id
even when the id was known — leaving compact-mode console links
unscoped, the very bug this PR fixes for the TUI.

Move link construction into pkg/listen/links, used by both the TUI and
the printer, so all output modes produce identical URLs: /events/cli
(or the console base) with team_id appended only when known.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tt8HTLV1iCoQyxH9vozKra

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (1)

pkg/listen/listen.go:200

  • RendererConfig now receives the resolved projectID (line 199), but the compact/quiet and interactive proxy renderers still build per-event dashboard/console URLs without ever appending team_id, so user-scoped CLI keys will continue to show unscoped links in the event log output.

Evidence: pkg/listen/proxy/renderer_simple.go:112-118 and pkg/listen/proxy/renderer_interactive.go:104-109 construct .../?event_id= / /events/ with no team_id handling and do not reference r.cfg.ProjectID.

Consider reusing pkg/listen/links.Event(...) (and a corresponding display helper if you want to omit the query in the display text) so URLs are consistently scoped across header, TUI open-in-browser, and per-event output lines.

	// Create renderer based on output mode
	rendererCfg := &proxy.RendererConfig{
		DeviceName:       config.DeviceName,
		APIKey:           config.Profile.APIKey,
		APIBaseURL:       config.APIBaseURL,
		DashboardBaseURL: config.DashboardBaseURL,
		ConsoleBaseURL:   config.ConsoleBaseURL,
		ProjectMode:      config.Profile.ProjectMode,
		ProjectID:        projectID,
		GuestURL:         guestURL,

@leggetter
leggetter merged commit 4eb7228 into main Aug 4, 2026
17 of 21 checks passed
@leggetter
leggetter deleted the claude/315-listen-dashboard-team-id branch August 4, 2026 19:34
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.

Dashboard deep-links omit team_id when authenticated with a CLI key

3 participants