Add GitHub connection type — repo viewer with org grouping and auto-refresh

New protocol type 'github' for browsing repositories via the GitHub REST API.
Creates a non-terminal panel showing repos grouped by owner/org, sorted by
last commit date (newest first), with search filtering and auto-refresh.

Backend:
- ProtocolGitHub constant and GitHubConfig/GitHubRepo model structs
- New internal/githubclient package (REST API, pagination, token validation)
- Session manager connectGitHub() with periodic refresh goroutine
- API surface: RefreshGitHubRepos() for on-demand refresh
- Token stored via existing credential infrastructure (keychain/vault)

Frontend:
- GitHub tab in profile editor with API URL and token storage fields
- New github.js viewer component (grouped repos, badges, language dots)
- github.css with charcoal-themed repo cards and org headers
- Protocol colour tokens, tab badge, sidebar indicator for GitHub
- Event wiring for session:github:repos and session:github:error
- Cleanup on tab close

Supports GitHub Enterprise via configurable API base URL.
This commit is contained in:
2026-04-16 00:00:00 +01:00
parent 58eb1626f6
commit c98ace2396
20 changed files with 1179 additions and 21 deletions
+5 -2
View File
@@ -141,6 +141,7 @@ class TabManager {
this.app.terminals.destroyTerminal(sessionId);
this.app.rawViewer.destroyViewer(sessionId);
window.NexusTerminal.GitHubViewer.destroyViewer(sessionId);
this.app.state.removeSession(sessionId);
this.removeTab(sessionId);
}
@@ -394,8 +395,9 @@ class TabManager {
});
// Protocol badge
const badge = createElement('span', `tab-badge ${protocolColour(sessionInfo.protocol)}`, {
textContent: sessionInfo.protocol.toUpperCase(),
const protoLabel = sessionInfo.protocol === 'github' ? 'GitHub' : sessionInfo.protocol.toUpperCase();
const badge = createElement('span', `tab-badge badge-${sessionInfo.protocol}`, {
textContent: protoLabel,
});
tab.appendChild(badge);
@@ -515,6 +517,7 @@ class TabManager {
// Close the current tab, then open a fresh connection
this.app.terminals.destroyTerminal(sessionId);
this.app.rawViewer.destroyViewer(sessionId);
window.NexusTerminal.GitHubViewer.destroyViewer(sessionId);
this.app.state.removeSession(sessionId);
this.removeTab(sessionId);