Skip to content

Add team pick mode — resolve multi-team sections interactively or via --pick-team#121

Merged
shouze merged 7 commits intomainfrom
feat/team-pick-mode
Mar 29, 2026
Merged

Add team pick mode — resolve multi-team sections interactively or via --pick-team#121
shouze merged 7 commits intomainfrom
feat/team-pick-mode

Conversation

@shouze
Copy link
Copy Markdown
Contributor

@shouze shouze commented Mar 29, 2026

Motivation

When --group-by-team-prefix matches a repository to multiple teams, it currently creates a combined section like squad-frontend + squad-mobile. There is no way to assign that repo to a single team — the user is stuck with the merged label in both the TUI and the replay command.

Fixes #85.

What changed

New --pick-team CLI option (repeatable)

github-code-search "axios" --org myorg \
  --group-by-team-prefix squad- \
  --pick-team "squad-frontend + squad-mobile"=squad-frontend

Each --pick-team "<combined label>"=<chosenTeam> assignment moves the repos from the combined section into the chosen team's section. Unrecognised labels emit a warning: on stderr listing available combined sections.

Interactive pick mode (p key in TUI)

When the cursor is on a multi-team section header, pressing p enters pick mode:

  • / cycle through candidate team names (shown in a hint bar at the top).
  • Enter confirms the choice; Esc cancels with no change.
  • Confirmed picks are accumulated in confirmedPicks and forwarded to buildOutput so the generated replay command includes the matching --pick-team flags.

Pure functions

File Purpose
src/group.ts applyTeamPick() — moves repos; rebuildTeamSections() — rebuilds from flat list
src/render/team-pick.ts renderTeamPickHeader() — pure ANSI hint bar

Updated modules

  • src/tui.tsp key, //Enter/Esc bindings, initialPickTeams param
  • src/output.tspickTeams field in ReplayOptions; forwarded to replay command
  • github-code-search.ts--pick-team repeatable option; stderr warning on unmatched label
  • Docsdocs/usage/team-grouping.md, docs/reference/keyboard-shortcuts.md, docs/reference/cli-options.md, docs/architecture/components.md, AGENTS.md

How to test manually

# Build
bun run build.ts

# Run a query against an org that has repos matching multiple team prefixes
./dist/github-code-search "some query" --org <org> \
  --group-by-team-prefix squad- \
  --pick-team "squad-a + squad-b"=squad-a

# Or enter the TUI and press p on a combined section header
./dist/github-code-search "some query" --org <org> \
  --group-by-team-prefix squad-

Validation

bun test          # 694 pass, 0 fail
bun run lint      # 0 errors
bun run format:check  # clean
bun run knip      # no unused exports

… --pick-team

- Add applyTeamPick + rebuildTeamSections to src/group.ts; moved repos
  tagged with pickedFrom for future split-mode support
- Add src/render/team-pick.ts: pure renderTeamPickHeader function
- Update src/render.ts: section cursor (bgMagenta + ── prefix), ◈ badge
  for picked repos, teamPickMode rendering branch, pick mode hints bar
- Update src/tui.ts: p key enters pick mode on multi-team sections,
  ← / → / Enter / Esc key bindings, nav fix (section rows no longer
  skipped), initialPickTeams param + confirmedPicks pre-seeding
- Update src/output.ts: pickTeams in ReplayOptions, --pick-team in replay
- Update github-code-search.ts: --pick-team repeatable option, stderr
  warning on unmatched label, pass picks to runInteractive
- Update docs: team-grouping.md, keyboard-shortcuts.md, cli-options.md,
  architecture/components.md, AGENTS.md, CONTRIBUTING.md

Fixes: applyTeamPick identity check, CLI picks not propagated to TUI,
silent failure on unmatched --pick-team label.

See issue #85
Copilot AI review requested due to automatic review settings March 29, 2026 21:56
@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

96.32%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.40%100%100%99.34%264
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts93.47%100%89.47%93.65%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 545–546
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 29, 2026

🔦 Lighthouse Report

Page ⚡ Perf ♿ A11y 🛡️ BP 🔍 SEO Report
/github-code-search/getting-started/ 🟢 99 (≥97) 🟢 100 (≥99) 🟢 100 (≥99) 🟢 100 (≥99) 🔗 view
/github-code-search/ 🟢 98 (≥97) 🟢 100 (≥99) 🟢 100 (≥99) 🟢 100 (≥99) 🔗 view

Thresholds: Perf ≥ 97 · A11y ≥ 99 · BP ≥ 99 · SEO ≥ 99
commit a457184 · full workflow run

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a “team pick mode” to resolve multi-team sections produced by --group-by-team-prefix, either interactively in the TUI (p) or non-interactively via repeatable --pick-team flags, and ensures replay commands capture these picks.

Changes:

  • Introduces pure grouping helpers applyTeamPick() / rebuildTeamSections() and RepoGroup.pickedFrom tagging for moved repos.
  • Adds TUI pick mode state + keybindings and renders a pick bar + badge in the TUI.
  • Extends CLI and replay output to accept/emit --pick-team, plus updates docs and contributor/agent guidance.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/types.ts Adds pickedFrom metadata on RepoGroup for picked repos.
src/group.ts Adds pure helpers to apply picks and rebuild sections.
src/group.test.ts Adds unit tests for team-pick grouping helpers.
src/tui.ts Implements interactive pick mode (p, arrows, Enter/Esc) and forwards picks into replay options.
src/render/team-pick.ts Adds pure pick-bar renderer for the active section header.
src/render/team-pick.test.ts Adds unit tests for pick-bar rendering.
src/render.ts Renders pick bar in section headers and shows badge on moved repos; adds help/hints text.
src/output.ts Adds pickTeams to replay options and emits --pick-team in replay command.
src/output.test.ts Tests replay command includes --pick-team.
github-code-search.ts Adds --pick-team option, applies picks pre-flattening, warns on unmatched labels, passes initial picks to TUI.
docs/usage/team-grouping.md Documents team pick mode UX + --pick-team.
docs/reference/keyboard-shortcuts.md Documents p binding and pick-mode keys.
docs/reference/cli-options.md Documents --pick-team option.
docs/architecture/components.md Updates C4 diagram to include team-pick component and styling.
CONTRIBUTING.md Updates file map and test coverage description.
AGENTS.md Updates agent-facing notes for --pick-team and pickedFrom.
bun.lock Bumps VitePress version.

@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

96.35%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.40%100%100%99.34%264
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts93.47%100%89.47%93.65%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 16 out of 17 changed files in this pull request and generated 4 comments.

@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

96.01%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts91.63%100%89.47%91.72%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547, 552–560
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 17 out of 18 changed files in this pull request and generated 2 comments.

shouze and others added 2 commits March 30, 2026 00:32
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

96.01%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts91.63%100%89.47%91.72%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547, 552–560
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

@shouze shouze requested a review from Copilot March 29, 2026 22:32
@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

96.01%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts91.63%100%89.47%91.72%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547, 552–560
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 17 out of 18 changed files in this pull request and generated 3 comments.

@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

95.62%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts89.66%100%89.47%89.66%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547, 552–559, 561–569, 571–572
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 17 out of 18 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

src/tui.ts:525

  • Now that section header rows are navigable, a/n (select all/none) won’t do anything when the cursor is on a section row because the handlers require row.type !== "section" (and applySelectAll/None require repo/extract context). Consider mapping section cursor to an adjacent repo row (e.g. the next non-section row) before invoking selection actions so global selection shortcuts still work from section headers.
    if (key === ANSI_ARROW_UP || key === "k") {
      // Arrow up — section-header rows are navigable (needed for `p`)
      const next = Math.max(0, cursor - 1);
      cursor = next;
      if (cursor < scrollOffset) scrollOffset = cursor;
    }

    if (key === ANSI_ARROW_DOWN || key === "j") {
      // Arrow down — section-header rows are navigable (needed for `p`)
      const next = Math.min(rows.length - 1, cursor + 1);
      cursor = next;
      while (
        scrollOffset < cursor &&
        !isCursorVisible(rows, groups, cursor, scrollOffset, getViewportHeight(rows))
      ) {
        scrollOffset++;
      }
    }

@github-actions
Copy link
Copy Markdown

Coverage after merging feat/team-pick-mode into main will be

95.62%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
src
   aggregate.ts100%100%100%100%
   api-utils.ts93.20%100%93.75%93.13%101–103, 65, 73, 86–87, 91–92
   api.ts94.57%100%100%93.89%319–323, 384, 401, 63–69
   cache.ts94.67%100%100%94.29%139–141, 39
   completions.ts99.42%100%100%99.37%270
   group.ts100%100%100%100%
   output.ts99.20%100%95%99.56%79
   regex.ts99.26%100%100%99.21%251
   render.ts89.66%100%89.47%89.66%167, 191–196, 198–200, 202–203, 254–255, 276, 456–457, 462–464, 530–534, 546–547, 552–559, 561–569, 571–572
   upgrade.ts88.38%100%94.44%87.89%128, 131, 133, 153, 167–168, 188–195, 198–204, 209, 214, 250–253
src/render
   filter-match.ts97.44%100%92.31%100%
   filter.ts100%100%100%100%
   highlight.ts96.63%100%90.40%99.31%284–285
   rows.ts97.58%100%100%97.44%168, 54–55
   selection.ts100%100%100%100%
   summary.ts100%100%100%100%
   team-pick.ts100%100%100%100%

@shouze shouze merged commit 2d507a6 into main Mar 29, 2026
9 checks passed
@shouze shouze deleted the feat/team-pick-mode branch March 29, 2026 22:52
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.

Team pick mode — p on a multi-team section header to assign it to a single team

2 participants