Replace token-paste with native device-code/PKCE provider sign-in
Implement the official OAuth login flows natively (ported from pi-ai's reference): GitHub Copilot device-code, GPT account (ChatGPT Codex) and Google Antigravity authorization-code + PKCE via a loopback callback server. Obtained credentials are stored as JSON through the existing secret vault. Onboarding and Settings now run the real sign-in instead of pasting an access token.
This commit is contained in:
1 parent
d5bf6c6b5f
commit
49a9f16221
24 files changed
+1057
-64
No files matched your search
@@ -184,6 +184,27 @@ export interface LaunchProviderSignInInput {
|
||||
employeeId: string;
|
||||
}
|
||||
|
||||
export interface StartProviderOAuthInput {
|
||||
providerKey: string;
|
||||
enterpriseDomain?: string | null;
|
||||
/** Present when connecting an existing org's provider (Settings); absent
|
||||
* during onboarding, where the obtained credential is returned to the caller. */
|
||||
orgId?: string;
|
||||
providerId?: string;
|
||||
employeeId?: string;
|
||||
model?: string | null;
|
||||
}
|
||||
|
||||
export interface StartProviderOAuthResult {
|
||||
/** The obtained credential JSON when no org context was supplied, else null
|
||||
* (the credential was already stored). */
|
||||
secret: string | null;
|
||||
}
|
||||
|
||||
export interface CancelProviderOAuthInput {
|
||||
providerKey: string;
|
||||
}
|
||||
|
||||
export interface CheckProviderHealthInput {
|
||||
orgId: string;
|
||||
providerId: string;
|
||||
|
||||
@@ -14,6 +14,9 @@ import type {
|
||||
CreateLegalHoldInput,
|
||||
CreateMigrationReportInput,
|
||||
CheckProviderHealthInput,
|
||||
StartProviderOAuthInput,
|
||||
StartProviderOAuthResult,
|
||||
CancelProviderOAuthInput,
|
||||
MarkChatSpaceReadInput,
|
||||
CreateOrganizationInput,
|
||||
CreateProviderResponseInput,
|
||||
@@ -58,9 +61,21 @@ import type {
|
||||
} from "./commands";
|
||||
import type { ProviderStreamRendererEvent } from "./provider-request-domain";
|
||||
|
||||
export type ProviderOAuthPhase = "authorize" | "progress" | "active" | "error" | "cancelled";
|
||||
|
||||
export interface ProviderOAuthEvent {
|
||||
type: "provider-oauth";
|
||||
providerKey: string;
|
||||
phase: ProviderOAuthPhase;
|
||||
url?: string;
|
||||
instructions?: string;
|
||||
message?: string;
|
||||
}
|
||||
|
||||
export type RendererEvent =
|
||||
| { type: "snapshot-changed" }
|
||||
| { type: "provider-response-stream"; event: ProviderStreamRendererEvent };
|
||||
| { type: "provider-response-stream"; event: ProviderStreamRendererEvent }
|
||||
| ProviderOAuthEvent;
|
||||
|
||||
export interface DesktopApi {
|
||||
loadSnapshot(): Promise<DesktopResult<AppSnapshot>>;
|
||||
@@ -85,6 +100,8 @@ export interface DesktopApi {
|
||||
saveProviderCredential(input: SaveProviderCredentialInput): Promise<DesktopResult<AppSnapshot>>;
|
||||
revokeProviderCredential(input: RevokeProviderCredentialInput): Promise<DesktopResult<AppSnapshot>>;
|
||||
launchProviderSignIn(input: LaunchProviderSignInInput): Promise<DesktopResult<null>>;
|
||||
startProviderOAuth(input: StartProviderOAuthInput): Promise<DesktopResult<StartProviderOAuthResult>>;
|
||||
cancelProviderOAuth(input: CancelProviderOAuthInput): Promise<DesktopResult<null>>;
|
||||
checkProviderHealth(input: CheckProviderHealthInput): Promise<DesktopResult<AppSnapshot>>;
|
||||
updateProviderPolicy(input: UpdateProviderPolicyInput): Promise<DesktopResult<AppSnapshot>>;
|
||||
openExternalUrl(url: string): Promise<DesktopResult<null>>;
|
||||
|
||||
@@ -21,6 +21,8 @@ export const IPC_CHANNELS = {
|
||||
saveProviderCredential: "agentcompany:save-provider-credential",
|
||||
revokeProviderCredential: "agentcompany:revoke-provider-credential",
|
||||
launchProviderSignIn: "agentcompany:launch-provider-sign-in",
|
||||
startProviderOAuth: "agentcompany:start-provider-oauth",
|
||||
cancelProviderOAuth: "agentcompany:cancel-provider-oauth",
|
||||
checkProviderHealth: "agentcompany:check-provider-health",
|
||||
updateProviderPolicy: "agentcompany:update-provider-policy",
|
||||
openExternalUrl: "agentcompany:open-external-url",
|
||||
|
||||
@@ -44,8 +44,8 @@ const RAW_CATALOG: Omit<ProviderCatalogEntry, "models">[] = [
|
||||
authType: PROVIDER_AUTH_TYPE.OAUTH_PKCE,
|
||||
defaultModel: "claude-opus-4-5",
|
||||
capabilityTags: ["account", "coding"],
|
||||
signInUrl: "https://github.com/login",
|
||||
credentialHelp: "Sign in, then copy the personal access token (scope copilot) from github.com → Settings → Developer settings.",
|
||||
signInUrl: "https://github.com/login/device",
|
||||
credentialHelp: "Sign in with the GitHub device code shown here — no token to copy.",
|
||||
},
|
||||
{
|
||||
key: "google-antigravity",
|
||||
@@ -54,7 +54,7 @@ const RAW_CATALOG: Omit<ProviderCatalogEntry, "models">[] = [
|
||||
defaultModel: "claude-sonnet-4-5",
|
||||
capabilityTags: ["account", "coding"],
|
||||
signInUrl: "https://antigravity.google/",
|
||||
credentialHelp: "Sign in to Antigravity, then paste the session token shown in the dashboard.",
|
||||
credentialHelp: "Sign in with your Google account in the browser; AgentCompany finishes the handshake.",
|
||||
},
|
||||
{
|
||||
key: "gpt-account",
|
||||
@@ -63,7 +63,7 @@ const RAW_CATALOG: Omit<ProviderCatalogEntry, "models">[] = [
|
||||
defaultModel: "gpt-5.3-codex",
|
||||
capabilityTags: ["codex", "subscription"],
|
||||
signInUrl: "https://chatgpt.com/codex",
|
||||
credentialHelp: "Sign in to ChatGPT Plus/Pro, then paste the session access token from chatgpt.com/codex/settings.",
|
||||
credentialHelp: "Sign in to ChatGPT Plus/Pro in the browser; AgentCompany finishes the handshake.",
|
||||
},
|
||||
{
|
||||
key: "azure-openai",
|
||||
|
||||
Reference in new issue
Block a user