fix(listen): populate team_id in dashboard deep-links for user-scoped CLI keys - #320
Conversation
… 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
There was a problem hiding this comment.
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
resolveEffectiveProjectIDto derive the id used for deep-links (profile project id first, otherwise connectionTeamID). - Extracted TUI deep-link construction into
dashboardHomeURL/eventDashboardURLto omitteam_idwhen 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.
…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
There was a problem hiding this comment.
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 appendingteam_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,
Fixes #315
Problem
When
hookdeck listenis authenticated with a user-scoped CLI key (--cli-keyor a storedhookdeck logincredential),cfg.ProjectIDis 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
Listen(): use the profile's activeproject_idwhen set, otherwise fall back to theteam_idof the connections being listened to (already present on the fetchedConnectionobjects — no extra API call). NewresolveEffectiveProjectIDhelper.dashboardHomeURL/eventDashboardURL(pkg/listen/tui/links.go), which omit theteam_idparameter entirely when the project id is unknown instead of emittingteam_id=. The printer already had this guard; it now uses the resolved id.Testing
TestResolveEffectiveProjectIDcovers profile-first precedence, fallback to the connections' team, skipping nil/empty entries, and the all-unknown case.TestDashboardHomeURL/TestEventDashboardURLcover dashboard and console modes with and without a project id.go build ./...andgo test ./pkg/listen/...pass locally (pre-existing, unrelated failure inpkg/listen/healthcheckthat requires binding port 443, which this sandbox disallows).🤖 Generated with Claude Code
https://claude.ai/code/session_01Tt8HTLV1iCoQyxH9vozKra
Generated by Claude Code