@@ -41,6 +41,7 @@ import { inject, injectable } from "inversify";
4141import { MAIN_TOKENS } from "../../di/tokens" ;
4242import { logger } from "../../utils/logger" ;
4343import { TypedEventEmitter } from "../../utils/typed-event-emitter" ;
44+ import type { AgentService } from "../agent/service" ;
4445import type { LlmGatewayService } from "../llm-gateway/service" ;
4546import type { SidebarPrState } from "../workspace/schemas" ;
4647import type { WorkspaceService } from "../workspace/service" ;
@@ -136,10 +137,31 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
136137 private readonly llmGateway : LlmGatewayService ,
137138 @inject ( MAIN_TOKENS . WorkspaceService )
138139 private readonly workspaceService : WorkspaceService ,
140+ @inject ( MAIN_TOKENS . AgentService )
141+ private readonly agentService : AgentService ,
139142 ) {
140143 super ( ) ;
141144 }
142145
146+ /**
147+ * Resolve env-var overrides set by the agent's SessionStart hooks for the
148+ * given task. Used so UI-triggered git/gh operations (Commit, Create PR)
149+ * see the same env (notably `SSH_AUTH_SOCK` re-pointed at Secretive) as
150+ * the agent's bash tool. Returns `undefined` if there's nothing to apply.
151+ */
152+ private async getSessionEnv (
153+ taskId : string | undefined ,
154+ ) : Promise < Record < string , string > | undefined > {
155+ if ( ! taskId ) return undefined ;
156+ try {
157+ const env = await this . agentService . getSessionEnvForTask ( taskId ) ;
158+ return Object . keys ( env ) . length > 0 ? env : undefined ;
159+ } catch ( err ) {
160+ log . warn ( "Failed to load session env for task" , { taskId, err } ) ;
161+ return undefined ;
162+ }
163+ }
164+
143165 private async getStateSnapshot (
144166 directoryPath : string ,
145167 options ?: {
@@ -481,6 +503,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
481503 branch ?: string ,
482504 setUpstream = false ,
483505 signal ?: AbortSignal ,
506+ env ?: Record < string , string > ,
484507 ) : Promise < PushOutput > {
485508 const saga = new PushSaga ( ) ;
486509 const result = await saga . run ( {
@@ -489,6 +512,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
489512 branch : branch || undefined ,
490513 setUpstream,
491514 signal,
515+ env,
492516 } ) ;
493517 if ( ! result . success ) {
494518 return { success : false , message : result . error } ;
@@ -538,6 +562,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
538562 directoryPath : string ,
539563 remote = "origin" ,
540564 signal ?: AbortSignal ,
565+ env ?: Record < string , string > ,
541566 ) : Promise < PublishOutput > {
542567 const currentBranch = await getCurrentBranch ( directoryPath ) ;
543568 if ( ! currentBranch ) {
@@ -550,6 +575,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
550575 currentBranch ,
551576 true ,
552577 signal ,
578+ env ,
553579 ) ;
554580 return {
555581 success : pushResult . success ,
@@ -623,6 +649,8 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
623649 } ) ;
624650 } ;
625651
652+ const sessionEnv = await this . getSessionEnv ( input . taskId ) ;
653+
626654 const saga = new CreatePrSaga (
627655 {
628656 getCurrentBranch : ( dir ) => getCurrentBranch ( dir ) ,
@@ -631,14 +659,16 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
631659 getChangedFilesHead : ( dir ) => this . getChangedFilesHead ( dir ) ,
632660 generateCommitMessage : ( dir ) =>
633661 this . generateCommitMessage ( dir , input . conversationContext ) ,
634- commit : ( dir , msg , opts ) => this . commit ( dir , msg , opts ) ,
662+ commit : ( dir , msg , opts ) =>
663+ this . commit ( dir , msg , { ...opts , envOverride : sessionEnv } ) ,
635664 getSyncStatus : ( dir ) => this . getGitSyncStatus ( dir ) ,
636- push : ( dir ) => this . push ( dir ) ,
637- publish : ( dir ) => this . publish ( dir ) ,
665+ push : ( dir ) =>
666+ this . push ( dir , "origin" , undefined , false , undefined , sessionEnv ) ,
667+ publish : ( dir ) => this . publish ( dir , "origin" , undefined , sessionEnv ) ,
638668 generatePrTitleAndBody : ( dir ) =>
639669 this . generatePrTitleAndBody ( dir , input . conversationContext ) ,
640670 createPr : ( dir , title , body , draft ) =>
641- this . createPrViaGh ( dir , title , body , draft ) ,
671+ this . createPrViaGh ( dir , title , body , draft , sessionEnv ) ,
642672 onProgress : emitProgress ,
643673 } ,
644674 log ,
@@ -729,6 +759,8 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
729759 allowEmpty ?: boolean ;
730760 stagedOnly ?: boolean ;
731761 taskId ?: string ;
762+ /** Pre-resolved session env. Internal — used by createPr to avoid re-loading. */
763+ envOverride ?: Record < string , string > ;
732764 } ,
733765 ) : Promise < CommitOutput > {
734766 const fail = ( msg : string ) : CommitOutput => ( {
@@ -740,11 +772,15 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
740772
741773 if ( ! message . trim ( ) ) return fail ( "Commit message is required" ) ;
742774
775+ const { envOverride, ...sagaOptions } = options ?? { } ;
776+ const env = envOverride ?? ( await this . getSessionEnv ( options ?. taskId ) ) ;
777+
743778 const saga = new CommitSaga ( ) ;
744779 const result = await saga . run ( {
745780 baseDir : directoryPath ,
746781 message : message . trim ( ) ,
747- ...options ,
782+ env,
783+ ...sagaOptions ,
748784 } ) ;
749785
750786 if ( ! result . success ) return fail ( result . error ) ;
@@ -955,6 +991,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
955991 title ?: string ,
956992 body ?: string ,
957993 draft ?: boolean ,
994+ env ?: Record < string , string > ,
958995 ) : Promise < { success : boolean ; message : string ; prUrl : string | null } > {
959996 const prFooter =
960997 "\n\n---\n*Created with [PostHog Code](https://posthog.com/code?ref=pr)*" ;
@@ -968,7 +1005,7 @@ export class GitService extends TypedEventEmitter<GitServiceEvents> {
9681005 }
9691006 if ( draft ) args . push ( "--draft" ) ;
9701007
971- const result = await execGh ( args , { cwd : directoryPath } ) ;
1008+ const result = await execGh ( args , { cwd : directoryPath , env } ) ;
9721009 if ( result . exitCode !== 0 ) {
9731010 return {
9741011 success : false ,
0 commit comments