A compiled Go reimplementation of the core daily-use commands from the original our-lovely-cli TypeScript tool.
Ships as a single static binary with no Node.js or npm required.
- Installation
- Authentication
- Commands
- Reviewer nicknames
- Configuration
- Missing functionality
- Architecture
- Code consolidation analysis
go install github.com/StevenACoffman/olc@latestOr build from source:
git clone https://github.com/StevenACoffman/olc
cd olc
go build -o olc .
mv olc /usr/local/bin/Go 1.25 or later is required.
olc reads the token written by the gh CLI. Run gh auth login once and
you're done. No environment variable is required.
gh auth loginCredentials are read from ~/.config/jira (key=value format) or from
environment variables. Environment variables take precedence.
File format (~/.config/jira):
host=https://yourco.atlassian.net
user=your.email@company.com
token=your-atlassian-api-tokenEnvironment variables:
| Variable | Purpose |
|---|---|
ATLASSIAN_HOST |
JIRA instance base URL |
ATLASSIAN_API_USER |
Atlassian account email address |
ATLASSIAN_API_TOKEN |
Atlassian API token |
Generate an API token at https://id.atlassian.com/manage-profile/security/api-tokens.
Create a branch for a JIRA issue, assign it to yourself, and transition it to In Progress.
olc workon [issue-key-or-branch]
Flags:
| Flag | Description |
|---|---|
--no-jira |
Skip JIRA assignment and status transition |
--prefix |
Override branch prefix (default from ka.olc.workonPrefix or feature/) |
Argument forms:
| Input | Behaviour |
|---|---|
PROJ-1234 |
Fetches issue title to build a descriptive branch name |
1234 |
Bare number; requires ka.olc.preferredJiraProjectKey |
https://... |
Full Atlassian browse URL |
my-custom-branch |
Non-JIRA input; used as-is for the branch name |
What it does:
- Checks for uncommitted changes (controlled by
ka.olc.abortOnDirtyGit). - Resolves the JIRA issue key and fetches the issue summary.
- Builds a branch name:
{prefix}{KEY}-{slug-of-title}. - Confirms the branch name interactively, then creates the local branch.
- Assigns the JIRA issue to the authenticated user (skips if already assigned).
- Transitions the issue to In Progress (tries "In Progress", "Resume Development", "Start Development" in order).
Look up one or more JIRA issues and print a formatted summary.
olc wti [issue-key ...]
If no key is given, the current branch name is scanned for a JIRA key.
Issue key forms accepted: PROJ-1234, bare 1234 (requires
ka.olc.preferredJiraProjectKey), or a full Atlassian browse URL.
Output includes: key, summary, status, type, assignee, priority,
description (Jira markup β Markdown; [~accountid:β¦] mentions resolved to
display name + email), browse URL.
Interactively build a formatted git commit message, then run git commit.
olc commitment [-- git-commit-flags]
Any arguments after -- are passed directly to git commit.
Interactive steps (bubbletea TUI):
- Emoji β filterable list of gitmoji entries (ββ to navigate,
/to filter, Enter to choose). - JIRA issue β pre-filled from branch name if a key is detected; leave blank for none.
- Summary β one-line commit subject (required, β€72 chars).
- Body β extended description (optional; Ctrl+D or Esc to skip).
- Test plan β test plan section (optional; Ctrl+D or Esc to skip).
Output format:
{emoji} {summary}
{body}
Issue: {PROJ-1234 or "none"}
Test plan:
{test plan}
Branch prefix used when detecting the default JIRA key is controlled by
the GIT_WORKON_PREFIX environment variable (fallback: feature/).
Create (or update) a GitHub pull request for the current branch.
olc pr [FLAGS]
Flags:
| Flag | Short | Description |
|---|---|---|
--draft |
Open PR as a draft | |
--base |
-b |
Base branch (default: repo's default branch) |
--rr |
Comma-separated reviewer nicknames or GitHub logins | |
--audit |
Add the audit label to the PR |
|
--no-jira |
Skip JIRA status transition | |
--no-push |
Skip pushing the branch before creating the PR |
What it does:
- Pushes the current branch to
origin(unless--no-push). - Checks for an existing open PR on this branch; offers to update it instead of creating a new one.
- Determines the PR base branch:
--baseflag if supplied.branch.<name>.stackParentgit config key (set automatically byolc review-branch).- Repo default branch.
- When a stacked parent is detected, the parent's PR number is shown alongside the base.
- Opens a two-step bubbletea form:
- Title β pre-filled with the single commit subject when there is exactly one commit.
- Body β pre-filled with a bullet list of commit subjects when there are multiple commits.
- Appends a
JIRA issue: β¦link to the body if a JIRA key is detected in the branch name. - Creates or updates the PR.
- Requests reviewers (
--rr). - Adds the
auditlabel (--audit). - Transitions the JIRA issue to In Review.
Squash-merge the current branch's PR and transition the JIRA issue.
olc land [FLAGS]
Flags:
| Flag | Short | Description |
|---|---|---|
--pr |
PR number to land (default: open PR for current branch) | |
--no-jira |
Skip JIRA status transition | |
--force |
-f |
Skip the review-approval check |
What it does:
- Finds the open PR for the current branch (or uses
--pr N). - Checks merge-state via GraphQL: blocks on DIRTY / DRAFT; exits cleanly if already queued or auto-merging.
- Checks that at least one approval exists (unless
--force). - Warns if the current date falls in the winter holiday freeze (19 Dec β 5 Jan).
- Confirms before merging.
- Squash-merges the PR.
- Reparents stacked child PRs β finds any open PRs whose base is the
just-merged branch and retargets them to its base (the grandparent branch).
Optionally merges the new base into each child's branch
(controlled by
ka.land.mergeBaseIntoChildren). If the merge creates a conflict, posts a comment on the child PR prompting the author to resolve it manually. - Switches to the base branch locally, fast-forwards it, and deletes the local head branch.
- Transitions the JIRA issue to Landed.
Rebase the current stacked branch (and its descendants) onto their parents after an upstream change or squash-merge.
olc restack [FLAGS]
Flags:
| Flag | Short | Description |
|---|---|---|
--branch |
-b |
Start restacking from this branch instead of the current one |
--only |
Restack only the starting branch; skip descendants | |
--print |
Print the PR stack (base β head #N) without rebasing | |
--pull |
Fetch each branch from origin before rebasing (recommended) | |
--interactive |
-i |
Use git rebase -i so you can edit the rebase plan (opens editor per branch) |
--no-verify |
Pass --no-verify to force-push (skips pre-push hooks) |
|
--continue |
Resume a restack that was interrupted by a merge conflict | |
--abort |
Abort an in-progress restack and restore original state |
Normal mode β what it does:
- Connects to GitHub (best-effort; continues offline using git config fallback).
- Determines the start branch:
--branchflag or current branch. If--branchdiffers from the current branch, prompts to confirm. - Warns if
--pullis not set (fetching first is strongly recommended). - Discovers the stack breadth-first via GitHub PR API: queries for open PRs
whose
baseRefNameequals each branch in the queue, then their children, and so on. Parent relationships discovered via GitHub are written tobranch.<name>.stackParentgit config for offline use. If GitHub is unavailable, the existing git config values are used instead. - Integration-branch PRs (label
integration-branch) are skipped. - If
--print: displays each branch with its parent, commits-behind count, and PR number, then exits without making any changes. - Auto-stashes uncommitted working-tree changes. The stash ref is stored in state and
restored on completion,
--continue, or--abort. - For each (parent β branch) pair in BFS order:
- If
--pull: fetches parent and branch from origin (deduplicating fetches). - Counts commits behind; skips the branch if it is already up to date.
- Prompts: "Restack
<branch>onto<parent>?" (default yes). - If not pulling: warns about remote commits that would be overwritten; prompts to confirm.
- Checks out the branch locally.
- Runs the rebase (see Fork-point strategy below).
- On merge conflict: saves full pending state to
.git/olc-restack-state.json, prints recovery instructions, and exits. - On success: stores the parent's SHA as
branch.<name>.stackForkPoint. - Prompts: "Force push
<branch>?" (default yes) β uses--force-with-lease. - Prompts: "Keep going?" (default yes).
- If
- Prints an operation summary, returns to the original branch, and pops the stash.
Fork-point strategy (squash-merge awareness):
After each successful rebase the parent's SHA is stored as branch.<name>.stackForkPoint.
On the next run, if the stored fork point differs from the current merge-base (indicating
the parent was squash-merged), the rebase uses:
git rebase --onto <parent> <forkPoint>
This replays only the commits made after the fork, avoiding re-apply conflicts that occur
when the parent's history disappears after a squash-merge. Standard git rebase <parent>
is used when no fork point exists or when the merge-base matches.
Conflict recovery:
# After resolving conflicts:
git rebase --continue
olc restack --continue
# To abandon everything:
olc restack --abort--continue loads state from .git/olc-restack-state.json, completes the in-progress rebase
(git rebase --continue), offers to force-push the resolved branch, then resumes with any
remaining branches. --abort runs git rebase --abort, returns to the original branch, and
pops the stash.
Differences from the TypeScript git restack:
| Feature | Go port | TypeScript original |
|---|---|---|
--continue / --abort |
β stateful recovery | β must re-run command |
| Fork-point awareness | β
--onto for squash-merges |
β plain rebase; manual conflict fix |
| Auto-stash | β | β requires clean tree |
| Offline fallback | β git config | β fatal if GitHub unavailable |
--simple-update-downstream |
β local upstream traversal | β |
--set-upstream |
β update upstream ref only | β |
--empty keep|drop|ask |
β
passed to git rebase |
β |
| Upstream reset prompts | β
maybeResetUpstream() |
β |
| Default fetch behaviour | opt-in --pull |
opt-out --no-pull-on-restack |
Manage JIRA issues: view, create, comment, transition, and update fields.
olc jira <subcommand> [FLAGS] [issue-key ...]
Issue keys can be PROJ-1234, a bare number (requires ka.olc.preferredJiraProjectKey),
or a full Atlassian browse URL. If no key is given the current branch name is scanned.
Subcommands:
| Subcommand | Action |
|---|---|
show |
Display issue details (same output as wti) |
new <type> <summary...> |
Create one or more issues (bug/b, task/t, software/sw) |
comment <text> |
Add a plain-text comment |
start |
Assign to self + transition to In Progress |
take |
Assign to self + add to the active sprint (no transition) |
review |
Transition to In Review |
qe |
Transition to Ready for QE |
accept |
Transition to QE Accepted |
reject |
Transition to QE Rejected |
todo |
Transition to To Do |
done |
Transition to Done |
finish |
Transition to Done (alias for done) |
land |
Transition to Landed |
update |
Update fields without transitioning (see flags below) |
open |
Open the issue in the default browser |
update flags:
| Flag | Description |
|---|---|
-p / --priority |
Set priority: P0βP4, 0β4, or none to clear |
--story-points N |
Set story points (integer > 0; field: ka.olc.storyPointsField) |
-a / --assign |
Assign to yourself |
-s / --sprint NAME |
Add to sprint by fuzzy name match (Levenshtein) |
-m / --comment TEXT |
Add a comment |
All update flags can be combined and applied to multiple issues in one call:
olc jira update --priority P1 --story-points 3 PROJ-1234
olc jira update -p p2 --assign --sprint "FEI 11" PROJ-1234 PROJ-5678
olc jira new bug "Login crash" "Signup 500 error"
olc jira comment "Blocked on infra" PROJ-1234Sprint lookup uses fuzzy matching (Levenshtein distance): "fei 11" will match
"FEI 2025 Sprint 11". Sprint resolution requires a Jira Agile board for the
project (scrum board type).
The custom field ID for story points varies between Jira instances. Configure it
with git config --global ka.olc.storyPointsField customfield_NNNNN
(default: customfield_10105).
Open GitHub to the list of PRs awaiting your audit review.
olc audit [FLAGS]
Flags:
| Flag | Description |
|---|---|
--no-browse |
Print the URL instead of opening browser |
Constructs a GitHub search URL filtering for open, non-archived PRs with the
audit label that have requested your review, then opens it in the browser.
Interactive reviewer-side workflow for merged PRs that have not yet received a code audit review.
olc auditor [FLAGS]
Flags:
| Flag | Description |
|---|---|
--all |
Search all repos and all users |
--all-repos |
Search all repos for the current user (review-requested) |
--all-users |
Search the current repo for all users |
--auto-action |
approve or ping β run this action for every PR without prompting |
--limit N |
Maximum number of PRs to load (default: 100) |
--skip-requested |
Skip PRs already labelled to-be-reviewed |
--date-range |
Override merged date range (YYYY-MM-DD..YYYY-MM-DD) |
--summary |
Print matching PR list only; do not enter the interactive review loop |
Base search criteria (applied to all scope modes):
is:mergedβ squash-merged PRs onlyreview:noneβ no review yet submittedarchived:falseβ skip archived repos-label:reviewedβ not already marked reviewed-label:integration-branchβ skip integration branches-author:khan-actions-botβ skip bot PRsmerged:β within the past year (overridden by--date-range)
Scope flags (default: current repo + review-requested for the current user):
| Flag | Adds to query |
|---|---|
| (default) | repo:owner/repo review-requested:@me |
--all-repos |
review-requested:@me (all repos) |
--all-users |
repo:owner/repo (all authors) |
--all |
No repo or user scope restriction |
What it does:
- Displays the GitHub search URL so you can open it manually if needed.
- Runs the GitHub GraphQL search with a bubbletea spinner while fetching.
- If no PRs are found, exits with a success message.
- For each PR:
- Shows PR number, title, URL, author, branch direction, labels, and body (first 20 lines; truncated if longer).
- If the PR already has any reviews, automatically marks it
reviewed, removesto-be-reviewed, and moves on. - Opens a bubbletea action picker with these choices:
| Action | Key | Effect |
|---|---|---|
| Open in browser | o |
Opens the PR URL in your default browser; returns to the picker |
| Approve | a |
Prompts for a comment (default :thumbsup:), posts it, adds reviewed, removes to-be-reviewed |
| Reject | r |
Prompts for rejection context (default :thumbsdown:), posts it, adds reviewed, removes to-be-reviewed |
| Ping reviewers | p |
Fetches requested reviewers, posts a ping comment, adds to-be-reviewed |
| Skip | s |
Moves to the next PR without taking any action |
With --auto-action approve or --auto-action ping, each PR is processed
automatically without the picker (a 2-second pause separates PRs to avoid API
rate limits; the pause is context-cancellation aware so Ctrl+C exits cleanly).
Create a remote deploy branch for use with GitHub-style deploys.
olc deploy-branch <branch-name> [FLAGS]
Flags:
| Flag | Description |
|---|---|
--parent |
Start point for a new branch (default: origin/HEAD) |
--no-fetch |
Skip git fetch origin before checking for the remote branch |
What it does:
- Runs
git fetch origin(unless--no-fetch) to ensure remote refs are current. - Resolves the parent ref (defaults to
origin/HEADβ e.g.origin/main). - Checks whether
<branch-name>already exists onorigin:- Exists: checks out the branch locally (creating a local copy if needed)
and sets it to track
origin/<branch-name>. Prints a warning. - Does not exist: creates a new local branch from the parent ref
(without tracking), pushes it to origin with
--set-upstream.
- Exists: checks out the branch locally (creating a local copy if needed)
and sets it to track
All feature work intended for a deploy should branch off a deploy branch via
olc review-branch.
Create a new local tracking branch off a deploy branch for use with GitHub-style deploys.
olc review-branch <branch-name> [parent] [FLAGS]
Flags:
| Flag | Description |
|---|---|
--parent |
Deploy branch to base off (see resolution order below) |
What it does:
- Validates the branch name; errors immediately if it already exists locally.
- Warns if the working tree has uncommitted changes.
- Resolves the parent branch in this order:
--parentflag- Second positional argument (
olc review-branch my-feature deploy/my-branch) branch.review-parent-defaultgit config key- Current branch (no switch)
- If the resolved parent differs from the current branch, runs
git checkout <parent>β which will auto-create a local tracking branch fromorigin/<parent>if it doesn't exist locally yet. - Blocks creation off
masterwhen either of the following is true:kaclone.protect-master = truein git config- Any remote URL contains
Khan/webapp
- Creates the new local branch:
git checkout --track -b <name> - Records the stack parent β writes the base branch to
branch.<name>.stackParentgit config so thatolc prautomatically targets the correct base branch without needing--base.
Setting a persistent default parent:
git config branch.review-parent-default <deploy-branch-name>After setting this, running olc review-branch my-feature will automatically
base off that deploy branch without needing --parent.
Enable auto-merge (squash) on a pull request, adding it to the GitHub merge queue once all required checks pass.
olc queue [FLAGS]
Flags:
| Flag | Description |
|---|---|
--pr |
PR number (default: open PR for current branch) |
Blocks on: merged PR, non-open PR, draft PR, merge conflicts (DIRTY state). Warns and confirms when the base branch is itself in the merge queue. If auto-merge or merge queue is already active, exits cleanly.
Use olc dequeue to cancel a queued PR.
Remove a pull request from the GitHub merge queue, or disable auto-merge if it is enabled but the PR is not yet queued.
olc dequeue [FLAGS]
Flags:
| Flag | Description |
|---|---|
--pr |
PR number (default: open PR for current branch) |
The operation performed depends on the PR's current state:
| State | Action |
|---|---|
| In merge queue | dequeuePullRequest GraphQL mutation |
| Auto-merge enabled | disablePullRequestAutoMerge GraphQL mutation |
| Neither | Error: nothing to do |
Requires the base branch to have a merge queue enabled.
Interactively switch to a local branch using an embedded fuzzy finder.
olc switch-branch [branch-name]
With no argument, opens an embedded fuzzy picker (powered by
github.com/junegunn/fzf/src β no external fzf binary required):
- Start typing to fuzzy-filter the branch list in real time.
- Arrow keys or Ctrl-N/P to move through results.
- Enter to check out the highlighted branch.
- Esc or Ctrl-C to cancel without switching.
- The current branch is shown in the header and excluded from the list.
- A preview panel on the right shows the last 10 commits on the
highlighted branch (
git log --oneline --color=always -10 {}).
If branch-name is given as an argument, the command resolves by exact match
or unambiguous prefix and checks out directly without opening the picker. Git
will automatically create a local tracking branch from origin/<name> if the
branch exists on the remote but not locally.
$FZF_DEFAULT_OPTS_FILE and $FZF_DEFAULT_OPTS are honoured, so any personal
fzf keybindings or colour settings carry over automatically.
Show open GitHub PRs relevant to you in an interactive bubbletea list.
olc tasks [FLAGS]
Flags:
| Flag | Short | Description |
|---|---|---|
--org |
GitHub org to search (default: owner from git remote) | |
--repo |
Narrow to a specific repo | |
--created |
-C |
Show only PRs you authored |
--assigned |
-A |
Show only PRs to which you are assigned |
--mentioned |
-M |
Show only PRs where you are mentioned |
--reviewer |
-R |
Show only PRs where you are a requested reviewer |
--extra |
-x |
Fetch CI status + review state per PR (makes extra API calls) |
Without -C/-A/-M/-R all four categories are shown. Results load in the
background behind a spinner, then open in a full-screen bubbletea list:
- ββ or Ctrl+N/P β navigate
- / β filter by PR title/repo/author
- Enter β open the highlighted PR in your default browser
- q or Esc β quit
Differences from the original TypeScript git tasks:
The original TypeScript git tasks is equivalent to git pull-requests with
interactive browsing. The Go port's tasks command searches all four
involvement categories (created, assigned, mentioned, review-requested).
The --extra flag (CI + review state) is a Go-port addition.
Show a categorized, interactive view of open GitHub pull requests involving you.
olc prs [FLAGS]
Flags:
| Flag | Description |
|---|---|
--org |
GitHub org to search (default: owner from git remote) |
--user |
Show PRs for this login or reviewer nickname instead of yourself |
Fetches all open PRs that involve you and groups them into five categories:
| Category | Contents |
|---|---|
| NEEDS MY REVIEW | You are an explicitly requested reviewer |
| AUTHORED BY ME | You created the PR |
| WAITING ON AUTHOR | You have already submitted a review; ball is in author's court |
| TAGS GROUPS I'M IN | You were tagged via a team membership (not a direct request) |
| DRAFTS | Draft PRs not authored by you |
Each PR is shown with a review-state indicator:
| Emoji | Meaning |
|---|---|
| β³ | Waiting for reviewers |
| β | Approved |
| π¬ | Commented |
| β | Changes requested |
| π | No reviewers requested |
Internally runs two parallel GitHub searches (involves:me and
review-requested:me with -involves:me) and deduplicates results.
PR details and reviews are fetched concurrently (up to 8 at a time).
Results load in the background behind a spinner, then open in a full-screen bubbletea list:
- ββ β navigate
- / β filter by PR title
- Enter β open the highlighted PR in your default browser
- q or Esc β quit
Relationship to olc tasks:
olc tasks is a quick four-category search (assigned / reviewing / mentioned
/ created). olc prs is a closer port of the original git pull-requests
command: it fetches the full PR object for each result (including
requested_reviewers and all submitted reviews) and applies the five-bucket
categorization from business-logic.ts.
Suggest code reviewers by analysing git blame on the lines you changed.
olc find-reviewers [FLAGS] [FILE...]
Flags:
| Flag | Short | Description |
|---|---|---|
--num-reviewers N |
-n |
How many top reviewers to print (default: 3) |
--output-per-file |
-f |
Print a separate ranked list for each changed file |
--whole-file |
-w |
Rank based on every line in the file, not just changed lines |
--revision REV |
-r |
Base revision to diff against (default: HEAD) |
If no FILE arguments are given, all modified/deleted files in the working
tree (relative to --revision) are analysed.
Algorithm:
- Runs
git diff -U0 --diff-filter=DMagainst the base revision to find which lines of which files were modified or deleted. Pure additions (no original lines) are skipped. - Runs
git blame -M -C --line-porcelainconcurrently for each changed file to find who last authored each of those lines. - Ranks authors by the number of changed lines they own and prints the top
--num-reviewerscandidates with a percentage share, displayed in a lipgloss-styled table.
With --whole-file, step 1 is replaced by git show revision:file to count
every line in the file rather than just the diff.
Example output:
ββββββββββββββββββββββββββββββββββββββ
β Reviewer Lines Share β
ββββββββββββββββββββββββββββββββββββββ€
β alice 47 58.0% β
β bob 22 27.2% β
β carol 12 14.8% β
ββββββββββββββββββββββββββββββββββββββ
Example usage:
olc find-reviewers # analyse all changed files
olc find-reviewers pkg/foo.go # analyse one file
olc find-reviewers -n 5 -f # top-5 per file
olc find-reviewers -w -r main # whole-file, diff against mainThis is a Go port of the Python script bin/git-find-reviewers from the
original our-lovely-cli-private repository. Email addresses are trimmed to
their local part (before @), making the output org-agnostic.
Show a GitHub memory from the same day in a previous year or month.
olc marley [FLAGS]
Flags:
| Flag | Description |
|---|---|
--org |
GitHub org to search (default: owner from git remote) |
--years-ago |
How many years back to search (default: 5) |
Searches for GitHub issues and PRs that involved you on the same calendar day
in previous years (going back --years-ago years). If nothing is found there,
searches the same day in previous months (up to 11 months ago). Displays the
first match and offers to open it in your browser.
Originally a 2020 Hackathon project.
Show commits between a base branch and HEAD, copying output to the clipboard.
olc clog [base-branch] [FLAGS]
Flags:
| Flag | Description |
|---|---|
--no-copy |
Print only; do not copy to clipboard |
Prints the one-line commit log for git log <base>..HEAD --no-merges. If
base-branch is omitted, the base is detected automatically from origin/HEAD
(or falls back to main/master). The output is copied to the clipboard via
pbcopy (macOS) or xclip/xsel (Linux) unless --no-copy is specified.
Useful for summarising branch work before raising a PR or writing release notes.
Differences from the original TypeScript git clog:
The original always required an explicit base branch argument. The Go port
auto-detects the base from origin/HEAD when no argument is given.
Print version information.
olc version
The version string is embedded at build time via:
go build -ldflags "-X github.com/StevenACoffman/olc/cmd/version.Version=1.2.3" .olc pr --rr accepts a comma-or-space-separated list of reviewer tokens.
Each token is resolved using the same three-step priority as the original
TypeScript canonicalize-members-and-teams.ts:
- Pre-formatted β
@loginpasses through as a user;#team-slugpasses through as a team. No lookup needed. - Alias table β the token (lowercased) is looked up in the hard-coded
mapping ported from
config/reviewer-mapping.ts. User aliases map to@login; team aliases map to#team-slug. - Bare pass-through β unrecognised tokens are sent as literal GitHub logins.
Examples:
--rr mcp β @seanmcp (alias β login)
--rr tx β #teacher-experience (alias β team)
--rr @coady β @coady (pre-formatted login)
--rr "#districts" β #districts (pre-formatted team slug)
--rr "mcp zaq" β @seanmcp @zaquestion (space-separated)
--rr mcp,zaq β @seanmcp @zaquestion (comma-separated)
--rr unknownperson β @unknownperson (literal pass-through)
Teams are sent as TeamReviewers in the GitHub API call; users as Reviewers.
Current alias table:
| Alias | Resolves to |
|---|---|
aric |
@coady |
dave |
@dbraley |
drewbie |
@drewkiimon |
dw |
@daniellewhyte |
emilyjanzer |
@ejanzer |
jason |
@jvoll |
jeff |
@somewhatabstract |
jeffl |
@jlauzy |
jeffw |
@jeffkhan |
jon |
@jonmarkprice |
kimberlymerrill |
@kmerrill27 |
kphilip |
@kphilipkhan |
mattmorgan |
@matthewmorgan |
mcp |
@seanmcp |
michael |
@mpolyak |
nicole |
@nixterrimus |
nrowe |
@nixterrimus |
rj |
@rjcorwin |
seandb |
@seandriedger |
zaq |
@zaquestion |
class |
#teacher-experience |
classroom |
#teacher-experience |
dist |
#districts |
districts |
#districts |
platform |
#infra-platform |
qe-team |
#quality-engineering |
tx |
#teacher-experience |
The table lives in pkg/reviewers/reviewers.go.
All settings are stored as git config values under the ka.olc.* namespace
and are read at startup via git config --get. Set them globally:
git config --global ka.olc.workonPrefix "feature/"
git config --global ka.olc.preferredJiraProjectKey "PROJ"Available keys:
| Git config key | Type | Default | Description |
|---|---|---|---|
ka.olc.abortOnDirtyGit |
awna | warn |
Behaviour when working tree has uncommitted changes |
ka.olc.abortOnUntrackedFiles |
awna | warn |
Behaviour when untracked files exist |
ka.olc.abortOnBehindUpstream |
awna | warn |
Behaviour when local branch is behind upstream |
ka.olc.preferredJiraProjectKey |
string | β | Default project key for bare numbers (e.g. PROJ) |
ka.olc.targetBranches |
csv | main,master |
Branches treated as merge targets |
ka.olc.showToolTips |
bool | true |
Show contextual tips |
ka.olc.quiet |
bool | false |
Suppress informational output |
ka.olc.noJira |
bool | false |
Globally disable all JIRA operations |
ka.olc.smartJiraSkipping |
bool | false |
Skip JIRA when issue cannot be determined |
ka.olc.workonPrefix |
string | feature/ |
Branch name prefix used by workon and commitment |
ka.olc.warnBeforeUpdatingGitHubMessage |
bool | false |
Prompt before overwriting existing PR title/body |
ka.pr.draftAsDefault |
bool | false |
Create PRs as drafts by default |
ka.pr.browse |
ana | ask |
Open PR in browser after creation |
ka.pr.pushFirst |
ana | ask |
Push branch before creating PR |
ka.pr.allowRemotesAsBase |
bool | false |
Allow remote branches as PR base |
ka.prMessage.summaryFromCommits |
bool | false |
Auto-fill PR body from commit list |
ka.land.ignoreBotComments |
csv | β | Bot logins whose comments don't count as reviews |
ka.land.mergeBaseIntoChildren |
ana | ask |
Merge base branch into child PRs after landing |
ka.jiraTool.alwaysVerify |
bool | false |
Always confirm JIRA transitions before applying |
ka.olc.storyPointsField |
string | customfield_10105 |
Jira custom field ID used for story points |
Type legend:
awnaβalways|warn|never|askanaβalways|never|askboolβtrue|falsecsvβ comma-separated string list
The following features exist in the original TypeScript CLI (our-lovely-cli)
but have not yet been ported to the Go binary.
Full mobile release automation:
- Scans JIRA for issues attached to a fix version.
- Validates issue states.
- Creates and manages a release branch.
- Transitions many issues through release states in bulk.
- Parses git history to link commits back to JIRA tickets.
Not implemented.
Automated dependency update management: scans repos for outdated packages, creates update branches, opens PRs, and tracks progress. Not implemented.
Run local CI actions and test the Gerald code-review bot respectively. Not implemented.
The TypeScript CLI had an interactive olc setup command that ran three
setup steps in sequence:
- GitHub auth β stored a personal access token in
~/.config/github. - JIRA auth β stored credentials (host, email, API token) in
~/.config/jira. - gcloud auth β ran
gcloud auth application-default loginto create~/.config/gcloud/application_default_credentials.json, used for uploading screenshot images to Google Cloud Storage and attaching them to pull requests.
The SKIP_GCLOUD=true environment variable suppressed step 3 (useful in CI
where gcloud is already configured via a service account).
olc has no equivalent of any of these steps:
- GitHub auth is handled by the
ghCLI (gh auth login).GITHUB_TOKENandGH_TOKENwork in CI viago-gh. The TypeScript-eraGITHUB_PERSONAL_TOKENis not recognised; useGITHUB_TOKENinstead. - JIRA auth is read from
~/.config/jira(same file path as the TypeScript tool) or fromATLASSIAN_HOST/ATLASSIAN_API_USER/ATLASSIAN_API_TOKENenv vars β the same names as the TypeScript tool. - GCS image upload and PR screenshot attachment are not implemented. There
is no
setupcommand, no gcloud integration, and no equivalent ofSKIP_GCLOUD.
olc/
βββ main.go # Entry point; wires peterbourgon/ff root command
βββ cmd/
β βββ cmd.go # Registers all subcommands; sets up slog on --verbose
β βββ root/root.go # Shared root Config (Stdout, Stderr, Stdin, Flags, Confirm)
β βββ version/ # version subcommand
β βββ commitment/ # commitment subcommand (bubbletea multi-step form)
β βββ workon/ # workon subcommand
β βββ wti/ # wti subcommand
β βββ pr/ # pr subcommand (bubbletea form)
β βββ land/ # land subcommand
β βββ restack/ # restack subcommand (stacked-PR rebasing with JSON state)
β βββ jira/ # jira subcommand group (15 subcommands)
β βββ audit/ # audit subcommand (open browser)
β βββ auditor/ # auditor subcommand (bubbletea action picker + spinner)
β βββ queue/ # queue subcommand
β βββ dequeue/ # dequeue subcommand
β βββ deploybranch/ # deploy-branch subcommand
β βββ reviewbranch/ # review-branch subcommand
β βββ switchbranch/ # switch-branch subcommand (embedded fzf)
β βββ tasks/ # tasks subcommand (bubbletea list with spinner)
β βββ prs/ # prs subcommand (bubbletea list with spinner)
β βββ findreviewers/ # find-reviewers subcommand (blame-based, lipgloss table)
β βββ marley/ # marley subcommand (GitHub time-machine)
β βββ clog/ # clog subcommand (commit log + clipboard)
βββ pkg/
βββ config/config.go # Git-config-backed settings (ka.olc.*)
βββ git/
β βββ git.go # go-git helpers + branch/JIRA name parsing; all cmds accept ctx
β βββ git_test.go # BranchNameFromIssue, ValidateBranchName tests
β βββ stack.go # branch stack config accessors (GetStackParent, SetStackParent, β¦)
βββ github/
β βββ github.go # go-github REST client wrapper + ResolvePR helper
β βββ graphql.go # shurcooL/githubv4 GraphQL queries/mutations
βββ gitmoji/gitmoji.go # gitmoji list
βββ reviewers/
β βββ reviewers.go # nicknameβlogin/team mapping (reviewer-mapping.ts port)
β βββ reviewers_test.go # Resolve, ResolveCSV tests
βββ jira/
β βββ client.go # JIRA client, JiraToMD, transitions, parsing; ctx throughout
β βββ client_test.go # ParseFromBranchName, NormalizeKey, ParsePriority, JiraToMD tests
β βββ wrapped.go # WrappedClient type
βββ tui/styles.go # lipgloss styles + NewSpinner/NewList factories + ConfirmSimple
I/O discipline: Every command writes exclusively to cfg.Stdout / cfg.Stderr
(never os.Stdout / os.Stderr) and reads confirmations through cfg.Confirm()
which uses the injected cfg.Stdin. This makes all commands testable with
&bytes.Buffer{} / strings.NewReader() without touching the terminal.
Context propagation: All git subprocess calls use exec.CommandContext(ctx, β¦)
and all GitHub/JIRA API calls accept and propagate context.Context, so
Ctrl+C cancels in-flight network requests cleanly.
Dependencies:
| Package | Role |
|---|---|
peterbourgon/ff/v4 |
CLI framework (commands + flags) |
charm.land/bubbletea/v2 |
Interactive TUI programs (forms, lists, spinners) |
charm.land/bubbles/v2 |
textinput, textarea, list, spinner components |
charm.land/lipgloss/v2 |
Terminal styling and table rendering |
google/go-github/v84 |
GitHub REST API client |
shurcooL/githubv4 |
GitHub GraphQL API client |
cli/go-gh/v2 |
Reads gh auth token from keychain |
go-git/go-git/v5 |
In-process git operations (branch, HEAD, log) |
andygrunwald/go-jira |
JIRA Cloud REST API client |
golang.org/x/oauth2 |
OAuth2 HTTP transport for GitHub |
junegunn/fzf/src |
Embedded fuzzy finder (switch-branch; no binary needed) |
cockroachdb/errors |
Error wrapping with stack traces |
This section catalogues patterns in the Go implementation that are candidates for sharing, consolidation, consistency fixes, or replacement with calls to existing dependency libraries.
tui.BrowseLoop (the old fmt.Scanln-based numeric-index navigation loop)
was removed when tasks and prs were refactored to bubbletea lists. Any
future commands that need "open a URL from a list" should use tui.NewList()
with an OnEnter callback rather than re-introducing a hand-rolled
fmt.Scanln loop.