fix(dashboard): gate the legacy dashboard-report command on a config - #772
Merged
jeff-r2026 merged 2 commits intoSep 24, 2026
Merged
Conversation
A current install writes only `teamai hook-dispatch`, whose dashboard-report handler declares `requiresConfig` and is dropped when no config resolves for the hook's cwd. The legacy subcommand stayed ungated, so a hook left behind by an earlier install kept recording dashboard events for every directory it fired in — including projects that never set up teamai, whose sessions were then reported by whichever scope pulled next. Apply the same gate `teamai contribute-check` was given in Tencent#748, asked about the session's cwd (or, for a host that sends none, the directory the hook runs in), so the two legacy commands behave alike.
Both suites drive `dashboardReport()` directly, so they bypass the dispatcher and now hit the new config gate. Their payload cwd is a fixture path that need not exist, and resolveConfigForDir then falls back to the user scope — which nothing had seeded, so every hook call returned early and no event was ever recorded. Seed a user-scope config, which is what these pipelines already assume: an installed team reporting its own sessions.
|
Findings
No additional code defects or rule violations found in the current diff. No earlier findings were provided to mark resolved. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What's the problem
The legacy
teamai dashboard-report --stdinsubcommand records dashboard events with no config check.A current install writes only
teamai hook-dispatch, and itsdashboard-reporthandler is registered withrequiresConfig— so when no config resolves for the hook'scwd, the dispatcher drops it. The old subcommand never got that gate. Hooks written by an earlier install still call it in every directory, so it kept appending to~/.teamai/dashboard/events.jsonlfor projects that never set up teamai — and since the event log is one machine-wide file whose events carry acwd, those sessions were then attributed and reported by whichever scope pulled next.This is the first half of #768; #771 covers the second half (the double-count and cross-project totals in
teamai stats).What's the fix
Apply the same gate
teamai contribute-checkwas given in #748 — the other legacy command older installs still call. IndashboardReport(), after reading STDIN, resolve the config for the session's directory and return early when there is none:Two details worth calling out:
resolveHookCwd(the same helperparseHookEventuses), so a host that sendscwd— or Cursor'sworkspace_roots— resolves the right project. A host that sends neither falls back to the directory the hook runs in, which is the semantics [bug] TeamAI hooks reach projects that never set it up: Stop nudge, and skill usage pushed to another team's stats #748 already established forcontribute-check, so the two legacy commands behave alike.parseHookEvent, which reports it as before.Test plan
New
src/__tests__/dashboard-report-gate.test.ts(3 tests), driving the realdashboardReport()with aReadablestand-in for STDIN — the same harnessconversation-token-e2e.test.tsuses:events.jsonlgets 1session_startsession_startsession_start(unchanged)session_startVerified as follows:
session_start), the installed-team case passed both before and after, so the gate does not disturb the working path.npx tsc --noEmit→ exit 0.gstack:tddis seeded, and:is not legal in a Win32 filename). CleanHEAD: 105 failed / 4240 passed; with fix(stats): count each session once and keep other projects out #771 applied: 104/4241; with this change: 103 failed / 4242 passed — no new failures.hook-handlers.test.ts("contribute-check handler withholds the reminder when the payload cwd exists but cannot be checked") reproduces on a cleanHEADwith this change stashed, so it is not caused by this PR.Notes for reviewers
resolveConfigForDirandresolveHookCwdare both already onmain.TEAMAI_LEGACY_HOOK_SUBCOMMANDSstill lists it for cleanup, so older installs do call it, and removing the entry point would leave those hooks erroring on every event. Gating is the smaller, safer change.