mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-10-04 16:02:02 +00:00
feat(github): read a repository with whichever gh account can see it (#987)
The GitHub panel borrowed only gh's active account, so a private repository owned by an organisation another signed-in account belongs to read as a 404. When the active account gets a 404, 401 or 403, retry with gh's other github.com accounts and remember, per owner, the one that got through. The other accounts are listed lazily (gh auth status checks each online), and a token from GH_TOKEN/GITHUB_TOKEN keeps its no-fallback meaning.
This commit is contained in:
+31
-10
@@ -10,7 +10,9 @@
|
||||
//! through the `Host` — the tree can be on another machine.
|
||||
//! - **Which token.** Resolved once, on a worker, from the environment or the
|
||||
//! GitHub CLI (`tty7_core::core::github::token`). Refresh resolves it again,
|
||||
//! so a `gh auth login` in a pane takes effect without a restart.
|
||||
//! so a `gh auth login` in a pane takes effect without a restart. A
|
||||
//! repository the active `gh` account cannot see is retried with the
|
||||
//! CLI's other accounts (`tty7_core::core::github::accounts`).
|
||||
//! - **The requests.** Made from *this* machine, never the remote host, on a
|
||||
//! dedicated thread each — a slow link must never hold a UI frame.
|
||||
//!
|
||||
@@ -141,18 +143,37 @@ where
|
||||
}
|
||||
|
||||
/// The real connector: resolve a token (env, then `gh`), build the client.
|
||||
/// A token from `gh` comes with the CLI's other accounts behind it, listed
|
||||
/// only if the active one comes up short.
|
||||
fn system_connector(proxy: Option<String>) -> Connector {
|
||||
use tty7_core::core::github::accounts::{Account, FallbackTransport};
|
||||
use tty7_core::core::github::http::HttpTransport;
|
||||
use tty7_core::core::github::token::{self, TokenSource};
|
||||
Arc::new(move || {
|
||||
let token =
|
||||
tty7_core::core::github::token::resolve_token_from_system().map(|(t, source)| {
|
||||
log::info!("github: signed in via {source:?}");
|
||||
t
|
||||
});
|
||||
let resolved = token::resolve_token_from_system();
|
||||
if let Some((_, source)) = &resolved {
|
||||
log::info!("github: signed in via {source:?}");
|
||||
}
|
||||
let from_gh = matches!(resolved, Some((_, TokenSource::GhCli)));
|
||||
let first: Arc<dyn Transport> = Arc::new(HttpTransport::new(
|
||||
resolved.map(|(t, _)| t),
|
||||
proxy.as_deref(),
|
||||
));
|
||||
if !from_gh {
|
||||
return Connection { transport: first };
|
||||
}
|
||||
let proxy = proxy.clone();
|
||||
let load = Box::new(move || {
|
||||
token::other_gh_accounts_from_system()
|
||||
.into_iter()
|
||||
.map(|(login, t)| Account {
|
||||
login,
|
||||
transport: Arc::new(HttpTransport::new(Some(t), proxy.as_deref())),
|
||||
})
|
||||
.collect()
|
||||
});
|
||||
Connection {
|
||||
transport: Arc::new(tty7_core::core::github::http::HttpTransport::new(
|
||||
token,
|
||||
proxy.as_deref(),
|
||||
)),
|
||||
transport: Arc::new(FallbackTransport::new(first, load)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user