Skip to content

EPIC: Hierarchical team-prefix grouping (multi-level headings) #125

Description

@vibou

Context

The original request in this issue proposes organizing --group-by-team-prefix results with a hierarchy logic instead of the current flat, single-level grouping:

  1. Hierarchical prefixes: a prefix chain like gamme-/squad- should produce nested headings (## gamme-client / ### squad-dashboard).
  2. Grouping overlapping levels: when team names themselves overlap (e.g. gamme-lead-client and gamme-lead-client-p1), nest them automatically instead of listing them as unrelated siblings.
  3. Advanced/consolidated rendering: collapse deep single-branch chains into one heading with a summary suffix (e.g. gamme-lead-client (including p1, unset, etc.)).

This is a substantial change touching the grouping algorithm, both output formats (markdown/JSON), the interactive TUI, and the --pick-team feature. It is tracked as an EPIC and split into the 7 sub-issues below.

Update: after using it in practice, mechanism 3 (--group-by-team-prefix-consolidate) turned out not to match the actual functional need. It is being removed (#196) and replaced by an automatic pick-team resolution strategy, --pick-team-auto (#197), which resolves combined/ambiguous sections by common prefix instead of collapsing unambiguous single-branch chains.

Further update: real-world usage of --pick-team-auto surfaced 3 edge cases (see investigation tests added in #197):

  • Auto-nesting of overlapping single-team labels (mechanism 2) combines with a /-chain's own depth to produce more heading levels than the chain alone would suggest — confirmed as the intended interaction of two separate, already-documented mechanisms, not a bug.
  • A repo matching only a non-first prefix in a chain (e.g. squad- in gamme-/squad-) with no match on the first prefix (gamme-) is invisible to that chain and falls through to a later independent chain instead — existing, documented "first chain to match wins" behavior.
  • --pick-team-auto's common-prefix strategy correctly leaves combos unresolved when no single candidate is a literal prefix of every other candidate, even when several combos share some (but not all) team members — a more aggressive merge heuristic was considered and rejected as risking silent loss of team-membership information. Instead, a new --exclude-team-prefixes option ([10/10] --exclude-team-prefixes: exclude noisy team-name prefixes from grouping #200) lets noisy team-name prefixes be excluded from grouping at the source, reducing ambiguous combos before --pick-team / --pick-team-auto even need to resolve them.

Solution

Implement all 3 mechanisms as a coherent hierarchical model:

  • A tree-shaped grouping result (replacing the current flat TeamSection[]) built from a CLI-declared prefix chain (/ for depth, , for independent sibling hierarchies) plus automatic nesting of overlapping team names.
  • Depth-aware rendering in both markdown (##/###/####) and JSON output.
  • Depth-aware TUI rendering and navigation.
  • --pick-team extended to resolve a section at any depth, not just the leaf level.

This is a breaking change to the --group-by-team-prefix / --pick-team CLI surface and to the JSON output shape, and will ship as a major release per AGENTS.md.

Implementation overview

flowchart TD
    CLI["github-code-search.ts<br/>--group-by-team-prefix chain grammar"] --> Parse["Parse chains #6<br/>e.g. gamme-/squad-,chapter-"]
    Parse --> Fetch["fetchRepoTeams (api.ts)<br/>flattened prefix list, unchanged"]
    Fetch --> Algo["groupByTeamHierarchy #1<br/>src/group.ts"]
    Algo --> Tree["TeamSection tree<br/>{label, groups, level, children}"]
    Tree --> Consolidate["Consolidation #2<br/>collapse single-branch chains"]
    Consolidate --> Flatten["flatten/rebuild helpers<br/>RepoGroup.sectionLabel + level"]
    Flatten --> MD["buildMarkdownOutput #3<br/>##/###/#### headings"]
    Flatten --> JSON["buildJsonOutput #3<br/>nested sections"]
    Flatten --> TUI["buildRows / render.ts #4<br/>nested header rows"]
    Tree --> Pick["--pick-team path addressing #5<br/>applyTeamPick / moveRepoToSection"]
    Pick --> Flatten
    MD --> Docs["docs/usage/team-grouping.md #7"]
    JSON --> Docs
    TUI --> Docs
Loading

Sub-issues (in dependency order):

Acceptance Criteria

Definition of Done

  • All sub-issue PRs merged into a shared long-lived feature branch feat/hierarchical-team-grouping, then merged into main.
  • Full validation suite green on main: bun test, bun run lint, bun run format:check, bun run knip, bun run build.ts.
  • Major release cut per AGENTS.md release process, including the required blog post (highlights gathered interactively from the user before writing).
  • CHANGELOG.md updated, no _pending_ rows left.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions