11import { readFileSync , writeFileSync , existsSync , mkdirSync } from "fs" ;
2- import { join , dirname } from "path" ;
2+ import { join } from "path" ;
33import { homedir } from "os" ;
44import {
55 setChannelCwd as setChannelCwdInConfig ,
@@ -9,10 +9,6 @@ import { loadSession } from "./sessions";
99const ODE_CONFIG_DIR = join ( homedir ( ) , ".config" , "ode" ) ;
1010const SETTINGS_FILE = join ( ODE_CONFIG_DIR , "settings.json" ) ;
1111const AGENTS_DIR = join ( ODE_CONFIG_DIR , "agents" ) ;
12- const GH_CONFIG_DIR = join ( homedir ( ) , ".config" , "gh" ) ;
13- const GH_HOSTS_FILENAME = "hosts.yml" ;
14- const GH_HOSTS_FILE = join ( GH_CONFIG_DIR , GH_HOSTS_FILENAME ) ;
15- const GH_USERS_DIR = join ( ODE_CONFIG_DIR , "gh-users" ) ;
1612
1713export interface ChannelSettings {
1814 threadSessions : Record < string , string > ; // threadId -> sessionId
@@ -320,219 +316,3 @@ export function clearOAuthState(): void {
320316 delete settings . oauthState ;
321317 saveSettings ( settings ) ;
322318}
323-
324- export interface GitHubAuthInfo {
325- host : string ;
326- user ?: string ;
327- gitProtocol ?: string ;
328- hasToken : boolean ;
329- }
330-
331- export interface GitHubAuthRecord {
332- host : string ;
333- user ?: string ;
334- token : string ;
335- gitProtocol ?: string ;
336- }
337-
338- export interface GitIdentity {
339- name : string ;
340- email : string ;
341- }
342-
343- export function normalizeGitHubHost ( input : string ) : string | null {
344- const trimmed = input . trim ( ) ;
345- if ( ! trimmed ) return null ;
346- const noProtocol = trimmed . replace ( / ^ h t t p s ? : \/ \/ / , "" ) ;
347- const host = noProtocol . split ( / [ / ? # ] / ) [ 0 ] ;
348- return host || null ;
349- }
350-
351- function ensureGitHubConfigDir ( ) : void {
352- if ( ! existsSync ( GH_CONFIG_DIR ) ) {
353- mkdirSync ( GH_CONFIG_DIR , { recursive : true } ) ;
354- }
355- }
356-
357- function ensureGitHubUserDir ( userId : string ) : void {
358- const userDir = join ( GH_USERS_DIR , userId ) ;
359- if ( ! existsSync ( userDir ) ) {
360- mkdirSync ( userDir , { recursive : true } ) ;
361- }
362- }
363-
364- export function getGitHubUserConfigDir ( userId : string ) : string {
365- return join ( GH_USERS_DIR , userId ) ;
366- }
367-
368- function getGitHubUserHostsFile ( userId : string ) : string {
369- return join ( GH_USERS_DIR , userId , GH_HOSTS_FILENAME ) ;
370- }
371-
372- function parseGitHubHosts ( contents : string ) : Record < string , Record < string , string > > {
373- const hosts : Record < string , Record < string , string > > = { } ;
374- let currentHost : string | null = null ;
375-
376- for ( const line of contents . split ( / \r ? \n / ) ) {
377- const trimmed = line . trim ( ) ;
378- if ( ! trimmed || trimmed . startsWith ( "#" ) ) continue ;
379-
380- if ( ! line . startsWith ( " " ) && trimmed . endsWith ( ":" ) ) {
381- currentHost = trimmed . slice ( 0 , - 1 ) . trim ( ) ;
382- if ( currentHost ) {
383- hosts [ currentHost ] = hosts [ currentHost ] || { } ;
384- }
385- continue ;
386- }
387-
388- if ( ! currentHost ) continue ;
389- const hostKey = currentHost ;
390- const match = trimmed . match ( / ^ ( [ A - Z a - z 0 - 9 _ - ] + ) : \s * ( .* ) $ / ) ;
391- if ( ! match ) continue ;
392- const field = match [ 1 ] ;
393- if ( ! field ) continue ;
394- hosts [ hostKey ] = hosts [ hostKey ] || { } ;
395- hosts [ hostKey ] [ field ] = match [ 2 ] ?? "" ;
396- }
397-
398- return hosts ;
399- }
400-
401- function serializeGitHubHosts ( hosts : Record < string , Record < string , string > > ) : string {
402- const lines : string [ ] = [ ] ;
403- for ( const [ host , entries ] of Object . entries ( hosts ) ) {
404- lines . push ( `${ host } :` ) ;
405- for ( const [ key , value ] of Object . entries ( entries ) ) {
406- lines . push ( ` ${ key } : ${ value } ` ) ;
407- }
408- }
409- return lines . length > 0 ? `${ lines . join ( "\n" ) } \n` : "" ;
410- }
411-
412- function readGitHubHosts ( filePath : string ) : Record < string , Record < string , string > > {
413- if ( ! existsSync ( filePath ) ) return { } ;
414- const contents = readFileSync ( filePath , "utf-8" ) ;
415- return parseGitHubHosts ( contents ) ;
416- }
417-
418- function writeGitHubHosts ( filePath : string , hosts : Record < string , Record < string , string > > ) : void {
419- const dirPath = dirname ( filePath ) ;
420- if ( ! existsSync ( dirPath ) ) {
421- mkdirSync ( dirPath , { recursive : true } ) ;
422- }
423- writeFileSync ( filePath , serializeGitHubHosts ( hosts ) ) ;
424- }
425-
426- function getGitHubAuthFromFile ( filePath : string , host : string ) : GitHubAuthInfo | null {
427- if ( ! existsSync ( filePath ) ) return null ;
428- const hosts = readGitHubHosts ( filePath ) ;
429- const entry = hosts [ host ] ;
430- if ( ! entry ) return null ;
431- return {
432- host,
433- user : entry . user ,
434- gitProtocol : entry . git_protocol ,
435- hasToken : Boolean ( entry . oauth_token ) ,
436- } ;
437- }
438-
439- function getGitHubAuthRecordFromFile ( filePath : string , host : string ) : GitHubAuthRecord | null {
440- if ( ! existsSync ( filePath ) ) return null ;
441- const hosts = readGitHubHosts ( filePath ) ;
442- const entry = hosts [ host ] ;
443- if ( ! entry ?. oauth_token ) return null ;
444- return {
445- host,
446- user : entry . user ,
447- token : entry . oauth_token ,
448- gitProtocol : entry . git_protocol ,
449- } ;
450- }
451-
452- function saveGitHubAuthToFile (
453- filePath : string ,
454- params : {
455- host : string ;
456- user ?: string ;
457- token : string ;
458- gitProtocol ?: string ;
459- }
460- ) : void {
461- const existing = readGitHubHosts ( filePath ) ;
462- const entry = { ...( existing [ params . host ] || { } ) } ;
463- if ( params . user ) entry . user = params . user ;
464- entry . oauth_token = params . token ;
465- entry . git_protocol = params . gitProtocol || entry . git_protocol || "https" ;
466- existing [ params . host ] = entry ;
467- writeGitHubHosts ( filePath , existing ) ;
468- }
469-
470- export function getGitHubAuth ( host = "github.com" ) : GitHubAuthInfo | null {
471- return getGitHubAuthFromFile ( GH_HOSTS_FILE , host ) ;
472- }
473-
474- export function getGitHubAuthForUser (
475- userId : string ,
476- host = "github.com"
477- ) : GitHubAuthInfo | null {
478- return getGitHubAuthFromFile ( getGitHubUserHostsFile ( userId ) , host ) ;
479- }
480-
481- export function getGitHubAuthRecord ( host = "github.com" ) : GitHubAuthRecord | null {
482- return getGitHubAuthRecordFromFile ( GH_HOSTS_FILE , host ) ;
483- }
484-
485- export function getGitHubAuthRecordForUser (
486- userId : string ,
487- host = "github.com"
488- ) : GitHubAuthRecord | null {
489- return getGitHubAuthRecordFromFile ( getGitHubUserHostsFile ( userId ) , host ) ;
490- }
491-
492- export function activateGitHubAuthForUser (
493- userId : string ,
494- host = "github.com"
495- ) : GitHubAuthInfo | null {
496- const record = getGitHubAuthRecordForUser ( userId , host ) ?? getGitHubAuthRecord ( host ) ;
497- if ( ! record ) return null ;
498- saveGitHubAuth ( record ) ;
499- return {
500- host : record . host ,
501- user : record . user ,
502- gitProtocol : record . gitProtocol ,
503- hasToken : true ,
504- } ;
505- }
506-
507- export function getGitIdentityForUser (
508- userId : string ,
509- host = "github.com"
510- ) : GitIdentity | null {
511- const record = getGitHubAuthRecordForUser ( userId , host ) ?? getGitHubAuthRecord ( host ) ;
512- if ( ! record ?. user ) return null ;
513- return {
514- name : record . user ,
515- email : `${ record . user } @users.noreply.github.com` ,
516- } ;
517- }
518-
519- export function saveGitHubAuth ( params : {
520- host : string ;
521- user ?: string ;
522- token : string ;
523- gitProtocol ?: string ;
524- } ) : void {
525- ensureGitHubConfigDir ( ) ;
526- saveGitHubAuthToFile ( GH_HOSTS_FILE , params ) ;
527- }
528-
529- export function saveGitHubAuthForUser ( params : {
530- userId : string ;
531- host : string ;
532- user ?: string ;
533- token : string ;
534- gitProtocol ?: string ;
535- } ) : void {
536- ensureGitHubUserDir ( params . userId ) ;
537- saveGitHubAuthToFile ( getGitHubUserHostsFile ( params . userId ) , params ) ;
538- }
0 commit comments