Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 15 additions & 14 deletions docs/reference/cli-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,21 @@ github-code-search completions [--shell <shell>]

## Search options

| Option | Type | Required | Default | Description |
| ----------------------------------- | --------------------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--org <org>` | string | ✅ | — | GitHub organization to search in. Automatically injected as `org:<org>` in the query. |
| `--exclude-repositories <repos>` | string | ❌ | `""` | Comma-separated list of repositories to exclude. Short form (`repoA,repoB`) or full form (`org/repoA,org/repoB`) both accepted. |
| `--exclude-extracts <refs>` | string | ❌ | `""` | Comma-separated extract refs to exclude. Format: `repoName:path/to/file:index`. Short form (without org prefix) accepted. |
| `--no-interactive` | boolean (flag) | ❌ | `true` (on) | Disable interactive mode. Interactive mode is **on** by default; pass this flag to disable it. Also triggered by `CI=true`. |
| `--format <format>` | `markdown` \| `json` | ❌ | `markdown` | Output format. See [Output formats](/usage/output-formats). |
| `--output-type <type>` | `repo-and-matches` \| `repo-only` | ❌ | `repo-and-matches` | Controls output detail level. `repo-only` lists repository names only, without individual extracts. |
| `--include-archived` | boolean (flag) | ❌ | `false` | Include archived repositories in results (excluded by default). |
| `--exclude-template-repositories` | boolean (flag) | ❌ | `false` | Exclude template repositories from results (included by default). See [Filtering](/usage/filtering#--exclude-template-repositories). |
| `--group-by-team-prefix <prefixes>` | string | ❌ | `""` | Team-name prefixes for grouping result repos by GitHub team, as a hierarchy. `/` nests levels within one chain (`gamme-/squad-`), `,` separates independent chains (`gamme-/squad-,chapter-`). Requires `read:org` scope. See [Team grouping](/usage/team-grouping). |
| `--pick-team <assignment>` | string (repeatable) | ❌ | — | Assign a combined team section to a single owner. Format: `"<combined label>"=<chosenTeam>`, where the combined side is a bare label (auto-resolved when unambiguous) or a fully-qualified `"parent > combined"` path. Repeatable — one flag per combined section. Only applies with `--group-by-team-prefix`. See [Team pick mode](/usage/team-grouping#team-pick-mode). |
| `--no-cache` | boolean (flag) | ❌ | `true` (on) | Bypass the 24 h team-list cache and re-fetch teams from GitHub. Cache is **on** by default; pass this flag to disable it. Only applies with `--group-by-team-prefix`. |
| `--regex-hint <term>` | string | ❌ | — | Override the API search term used when the query is a regex (`/pattern/`). Useful when auto-extraction produces a term that is too broad or too narrow. See [Regex queries](/usage/search-syntax#regex-queries). |
| Option | Type | Required | Default | Description |
| ----------------------------------- | --------------------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--org <org>` | string | ✅ | — | GitHub organization to search in. Automatically injected as `org:<org>` in the query. |
| `--exclude-repositories <repos>` | string | ❌ | `""` | Comma-separated list of repositories to exclude. Short form (`repoA,repoB`) or full form (`org/repoA,org/repoB`) both accepted. |
| `--exclude-extracts <refs>` | string | ❌ | `""` | Comma-separated extract refs to exclude. Format: `repoName:path/to/file:index`. Short form (without org prefix) accepted. |
| `--no-interactive` | boolean (flag) | ❌ | `true` (on) | Disable interactive mode. Interactive mode is **on** by default; pass this flag to disable it. Also triggered by `CI=true`. |
| `--format <format>` | `markdown` \| `json` | ❌ | `markdown` | Output format. See [Output formats](/usage/output-formats). |
| `--output-type <type>` | `repo-and-matches` \| `repo-only` | ❌ | `repo-and-matches` | Controls output detail level. `repo-only` lists repository names only, without individual extracts. |
| `--include-archived` | boolean (flag) | ❌ | `false` | Include archived repositories in results (excluded by default). |
| `--exclude-template-repositories` | boolean (flag) | ❌ | `false` | Exclude template repositories from results (included by default). See [Filtering](/usage/filtering#--exclude-template-repositories). |
| `--group-by-team-prefix <prefixes>` | string | ❌ | `""` | Team-name prefixes for grouping result repos by GitHub team, as a hierarchy. `/` nests levels within one chain (`gamme-/squad-`), `,` separates independent chains (`gamme-/squad-,chapter-`). Requires `read:org` scope. See [Team grouping](/usage/team-grouping). |
| `--pick-team <assignment>` | string (repeatable) | ❌ | — | Assign a combined team section to a single owner. Format: `"<combined label>"=<chosenTeam>`, where the combined side is a bare label (auto-resolved when unambiguous) or a fully-qualified `"parent > combined"` path. Repeatable — one flag per combined section. Only applies with `--group-by-team-prefix`. See [Team pick mode](/usage/team-grouping#team-pick-mode). |
| `--pick-team-auto` | boolean (flag) | ❌ | `false` | Auto-resolve combined team sections whose team names share a common prefix (e.g. `gamme-lead-client + gamme-lead-client-p1` → `gamme-lead-client`), at every hierarchy depth. Combos with no common-prefix team are left unresolved. An explicit `--pick-team` for the same section always wins. Only applies with `--group-by-team-prefix`. See [Auto-pick by common prefix](/usage/team-grouping#auto-pick-by-common-prefix). |
| `--no-cache` | boolean (flag) | ❌ | `true` (on) | Bypass the 24 h team-list cache and re-fetch teams from GitHub. Cache is **on** by default; pass this flag to disable it. Only applies with `--group-by-team-prefix`. |
| `--regex-hint <term>` | string | ❌ | — | Override the API search term used when the query is a regex (`/pattern/`). Useful when auto-extraction produces a term that is too broad or too narrow. See [Regex queries](/usage/search-syntax#regex-queries). |

## Global options

Expand Down
19 changes: 19 additions & 0 deletions docs/usage/team-grouping.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,25 @@ The flag is repeatable — add one `--pick-team` per combined section to resolve

If the combined label or path is not found (typo, ambiguous, or the section was not formed), a warning is emitted on stderr listing the available combined sections — the run continues without error.

## Auto-pick by common prefix

Many combined sections aren't actually ambiguous: when one of the team names is a literal prefix of every other team name in the combo (e.g. `gamme-lead-client` and `gamme-lead-client-p1`), the "parent" team is the obvious owner. `--pick-team-auto` resolves these automatically, without needing a manual `--pick-team`:

```bash
github-code-search query "useFeatureFlag" --org fulll \
--group-by-team-prefix gamme- \
--pick-team-auto
```

```text
## gamme-lead-client + gamme-lead-client-p1 → ## gamme-lead-client
```

- Combos with **no common-prefix team** (e.g. `squad-frontend + squad-mobile` — neither is a prefix of the other) are left combined and unresolved, exactly like today.
- Applies independently **at every hierarchy depth**, not just the top level.
- An explicit `--pick-team` for the same section always wins: run explicit picks first, then `--pick-team-auto` resolves whatever combined sections remain.
- The replay command emits `--pick-team-auto` when it was used, so a session is reproduced exactly.

## Re-pick & undo pick

After using `--pick-team` (or the interactive `p` shortcut) to assign a combined section to a team, individual repos marked `◈` can be re-assigned or restored to their original combined section at any time — regardless of how deeply nested the original section was.
Expand Down
26 changes: 25 additions & 1 deletion github-code-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { formatRetryWait } from "./src/api-utils.ts";
import { buildOutput } from "./src/output.ts";
import {
applyTeamPickInTree,
autoPickTeamsByCommonPrefix,
findCombinedSectionPaths,
flattenTeamHierarchy,
groupByTeamHierarchy,
Expand Down Expand Up @@ -204,6 +205,19 @@ function addSearchOptions(cmd: Command): Command {
(val: string, list: string[]) => [...list, val],
[] as string[],
)
.option(
"--pick-team-auto",
[
"Auto-resolve combined team sections whose team names share a common",
'prefix (e.g. "gamme-lead-client + gamme-lead-client-p1" \u2192 auto-picks',
'"gamme-lead-client"), without needing an explicit --pick-team.',
"Combos with no common-prefix team (e.g. squad-a + squad-b) are left",
"unresolved. An explicit --pick-team for the same section always wins.",
"Applies at every hierarchy depth. Only applies with --group-by-team-prefix.",
"Docs: https://fulll.github.io/github-code-search/usage/team-grouping#auto-pick-by-common-prefix",
].join("\n"),
false,
)
.option(
"--no-cache",
"Bypass the 24 h team-list cache and re-fetch teams from GitHub (only applies with --group-by-team-prefix).",
Expand Down Expand Up @@ -233,6 +247,7 @@ async function searchAction(
excludeTemplateRepositories: boolean;
groupByTeamPrefix: string;
pickTeam: string[];
pickTeamAuto?: boolean;
cache: boolean;
regexHint?: string;
},
Expand Down Expand Up @@ -392,10 +407,17 @@ async function searchAction(
pickTeams[resolution.path.join(" > ")] = resolution.chosen;
}

// --pick-team-auto runs AFTER explicit assignments so an explicit --pick-team
// for the same section always wins (it no longer exists as a combined section
// by the time auto-pick runs, so auto-pick naturally skips it).
if (opts.pickTeamAuto) {
sections = autoPickTeamsByCommonPrefix(sections);
}

// Warn about combined sections that still have no pick assigned, so the user
// knows which labels to add to the next replay command or interactive session.
const unresolved = findCombinedSectionPaths(sections);
if (unresolved.length > 0 && opts.pickTeam.length > 0) {
if (unresolved.length > 0 && (opts.pickTeam.length > 0 || opts.pickTeamAuto)) {
process.stderr.write(
`note: ${unresolved.length} combined section${unresolved.length !== 1 ? "s" : ""} still unresolved ` +
`(press "p" in TUI or use --pick-team to assign):\n` +
Expand All @@ -414,6 +436,7 @@ async function searchAction(
includeArchived,
excludeTemplates,
groupByTeamPrefix: opts.groupByTeamPrefix,
pickTeamAuto: opts.pickTeamAuto,
regexHint: opts.regexHint,
pickTeams: Object.keys(pickTeams).length > 0 ? pickTeams : undefined,
}),
Expand Down Expand Up @@ -474,6 +497,7 @@ async function searchAction(
includeArchived,
excludeTemplates,
opts.groupByTeamPrefix,
Boolean(opts.pickTeamAuto),
opts.regexHint ?? "",
Object.keys(pickTeams).length > 0 ? pickTeams : {},
);
Expand Down
Loading
Loading