Issue trackers

Santree supports Linear and GitHub Issues behind a single interface. Each repo picks one.

  1. Choosing a tracker
  2. Linear
    1. Auth
    2. What gets fetched
    3. Branch naming
  3. GitHub Issues
    1. Auth
    2. What gets fetched
    3. Empty dashboard?
    4. Branch naming
  4. Cross-tracker resolution (Reviews tab)

Choosing a tracker

The active tracker is resolved in this order:

  1. SANTREE_TRACKER env var (one-off override)
  2. Per-repo _tracker.kind in .santree/metadata.json
  3. Legacy _linear.org (treated as Linear, for back-compat)
  4. Auto-detect — any Linear creds present → Linear, else GitHub

To set the per-repo tracker explicitly:

santree issue switch linear
santree issue switch github

The auth commands also flip the tracker as a side effect, so usually you just run the auth command for whichever backend you want and you’re done.

For one-off overrides (testing, scripting):

SANTREE_TRACKER=github santree dashboard

Linear

Santree fetches Linear ticket data via the GraphQL API (OAuth PKCE).

Auth

# Authenticate with Linear (opens browser for OAuth)
santree linear auth

# Check auth status
santree linear auth --status

# Verify a ticket fetches correctly
santree linear auth --test TEAM-123

# Log out
santree linear auth --logout

# Switch between authenticated workspaces
santree linear switch

On first run, santree linear auth opens your browser to authorize the app with your Linear workspace. Tokens are stored in $XDG_CONFIG_HOME/santree/auth.json (defaults to ~/.config/santree/auth.json) and auto-refresh transparently.

If you have multiple workspaces authenticated, running santree linear auth in a new repo lets you pick which one to link.

What gets fetched

  • Title, description, comments
  • State (name + type), priority, labels
  • Project name + ID
  • Attached images — downloaded to /tmp/santree-images-<ticketId>/ and the URLs in the description are rewritten to local paths so Claude can read them. (Cleanup is handled by macOS clearing /tmp on reboot — no explicit cleanup runs.)

Branch naming

Linear’s parser is permissive: any uppercased letter prefix + dash + digits anywhere in the branch matches. See Branch naming.


GitHub Issues

Santree uses the existing gh CLI — no separate OAuth.

Auth

# Verify gh is authenticated; flip this repo's tracker to GitHub
santree github auth

gh owns its own token; santree never writes a GitHub token of its own.

What gets fetched

Issues are listed via gh search issues --assignee=@me --state=open --repo <owner>/<name> — current repo only. Cross-repo issues aren’t surfaced today.

  • Title, body, comments
  • State (open / closed)
  • Labels — priority is derived from labels matching P0 / P1 / P2 / P3 / urgent / critical / high / medium / low, falling back to “No priority”
  • Project name = repository.nameWithOwner
  • Attached images on user-images.githubusercontent.com and github.com/.../assets/ are downloaded so Claude can read them when filling PR templates

Empty dashboard?

gh search issues --assignee=@me returns nothing if the issues you care about aren’t assigned to you. GitHub Projects affiliation doesn’t count — assignees do. If your team uses Projects without assignees, self-assign the issues you’re working on.

Branch naming

GitHub’s branch parser is strict to avoid false positives — a commit-style branch like fix-typo-1 would otherwise match issue 1. See Branch naming for the accepted patterns.


Cross-tracker resolution (Reviews tab)

When the Reviews tab encounters a PR whose branch was created using another tracker’s convention (e.g. a Linear-style TEAM-1234-… branch in a repo configured for GitHub Issues), santree’s getCandidateTrackers() falls back to other trackers with active credentials. If Linear is authed, the Linear ticket context shows up in the PR detail panel even though the repo’s active tracker is GitHub.

This is by design — your repo is configured one way, but contributors may use whatever convention they like.