Skip to content

feat: aggregate all authenticated GitHub hosts - #8

Draft
tensorcopy wants to merge 6 commits into
alysnnix:mainfrom
tensorcopy:multi-host
Draft

tensorcopy wants to merge 6 commits into
alysnnix:mainfrom
tensorcopy:multi-host

Conversation

@tensorcopy

@tensorcopy tensorcopy commented Sep 28, 2026 •

Copy link
Copy Markdown

Read the diff as the last two commits. This pull request is stacked on #6 and #7. Until both merge, the diff above includes their commits — GitHub requires a pull request's base branch to live on this repository, so a cross-fork stack cannot be based on one another's branches. Once #6 and #7 merge, this diff shrinks to exactly its own two commits: feat(github): send gh calls to a configured host and feat: aggregate all authenticated GitHub hosts. Merge order for the series: #6 → #7 → this one → #9. Draft until then so it cannot merge out of order; the code is final and ready to review now.

Why. The board served one GitHub host with one account. A GitHub Enterprise login meant a second board or a hand-set GH_HOST, and a read or action had no way to reach the host an item actually came from.

What.

  • gh auth status --json hosts names every authenticated host and its active account; the sweep queries them all at once and unions their columns, keeping each host's failure in the column error rather than failing the board.
  • Item ids carry their host, and every per-item handler — details, comments, labels, review, images, projects — runs its gh call against the host that owns the item. Calls outside any item's context use GH_HOST from the daemon environment.
  • An expired login on one host no longer blanks the board for the hosts that are fine: gh auth status exits non-zero when any one host has a problem, so its stdout is parsed first and the failure honoured only when the stdout says nothing usable.

How. server/github/host.ts discovers and caches the accounts (single-flight, five minutes); server/github/item-id.ts encodes host\u0000nodeId and withItemId runs a handler inside that host's context through AsyncLocalStorage; server/board/handler.ts sweeps each account and merges the columns. No host is named in code — the set comes from gh itself.

Test. host.test.ts and item-id.test.ts cover the account parsing and the id encoding, with generic fixtures (ghe.example.com, octocat). Typecheck and the suite pass at this point in the stack: 61 tests.

- the lock still said 0.5.0 while package.json says 1.0.1
- a shared budget went to whichever relation held the newest items, so a full review queue pushed the viewer's own work off the board
- nodes(ids:) caps at 100 ids; ask in batches of that size so a longer board keeps its checks
- match the pull request each active or retained workspace tracks to the first agent created there, the originating conversation
- an action on the row and in the panel jumps straight to that chat
- resolve the hostname from GH_HOST or the plugin's settings file and set it on every gh subprocess
- gh auth status names every authenticated host and its active account
- item ids carry their host, so reads and actions reach the host that owns the item
- the sweep unions every host's columns and keeps each host's failure in the column error
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.

1 participant