@@ -116,6 +116,16 @@ interface SourceControlTextGenerationSettings {
116116 readonly style : SourceControlWritingStyleSettings ;
117117}
118118
119+ export interface GitCreatePullRequestResult {
120+ readonly status : "created" | "opened_existing" ;
121+ /** Absent when the host accepted the PR but did not list it back yet. */
122+ readonly url ?: string ;
123+ readonly number ?: number ;
124+ readonly baseBranch : string ;
125+ readonly headBranch : string ;
126+ readonly title : string ;
127+ }
128+
119129export class GitManager extends Context . Service <
120130 GitManager ,
121131 {
@@ -151,6 +161,13 @@ export class GitManager extends Context.Service<
151161 input : GitRunStackedActionInput ,
152162 options ?: GitRunStackedActionOptions ,
153163 ) => Effect . Effect < GitRunStackedActionResult , GitManagerServiceError > ;
164+ /** Opens a PR for the checkout's pushed branch, or returns the one already open. */
165+ readonly createPullRequest : ( input : {
166+ readonly cwd : string ;
167+ readonly title : string ;
168+ readonly body : string ;
169+ readonly baseBranch ?: string | undefined ;
170+ } ) => Effect . Effect < GitCreatePullRequestResult , GitManagerServiceError > ;
154171 readonly subscribePullRequestStateChanges : Effect . Effect <
155172 Stream . Stream < ThreadPullRequestKey > ,
156173 never ,
@@ -2218,12 +2235,17 @@ export const make = Effect.gen(function* () {
22182235 } ;
22192236 } ) ;
22202237
2221- const runPrStep = Effect . fn ( "runPrStep" ) ( function * (
2222- settings : SourceControlTextGenerationSettings ,
2238+ const openPrFromBranch = Effect . fn ( "openPrFromBranch" ) ( function * < E > (
22232239 cwd : string ,
22242240 fallbackBranch : string | null ,
2225- threadId : ThreadId | undefined ,
22262241 emit : GitActionProgressEmitter ,
2242+ requestedBase : string | undefined ,
2243+ content : ( input : {
2244+ readonly provider : SourceControlProvider . SourceControlProvider [ "Service" ] ;
2245+ readonly baseBranch : string ;
2246+ readonly baseRef : string ;
2247+ readonly headBranch : string ;
2248+ } ) => Effect . Effect < { readonly title : string ; readonly body : string } , E > ,
22272249 ) {
22282250 const provider = yield * sourceControlProvider ( cwd ) ;
22292251 const terms = sourceControlDefinitions . get ( provider . kind ) . changeRequest ;
@@ -2261,41 +2283,14 @@ export const make = Effect.gen(function* () {
22612283 } ;
22622284 }
22632285
2264- const { baseBranch, baseRef } = yield * resolvePrBase (
2265- cwd ,
2266- branch ,
2267- details . upstreamRef ,
2268- headContext ,
2269- ) ;
2270- yield * emit ( {
2271- kind : "phase_started" ,
2272- phase : "pr" ,
2273- label : `Generating ${ terms . shortLabel } content...` ,
2274- } ) ;
2275- const baseRangeRef = yield * resolveBaseRangeRef ( cwd , baseRef ) ;
2276- const rangeContext = yield * gitCore . readRangeContext ( cwd , baseRangeRef ) ;
2277- const policy = yield * resolveStylePolicy ( cwd , settings ) ;
2278- const changeRequestTemplate =
2279- settings . style . followChangeRequestTemplates && provider . readChangeRequestTemplate
2280- ? Option . getOrUndefined (
2281- yield * provider . readChangeRequestTemplate ( { cwd, treeish : baseRangeRef } ) ,
2282- )
2283- : undefined ;
2284- const threadContext = yield * readThreadContext ( threadId ) ;
2285-
2286- const generated = yield * textGeneration . generatePrContent ( {
2287- cwd,
2286+ const resolved = yield * resolvePrBase ( cwd , branch , details . upstreamRef , headContext ) ;
2287+ const baseBranch = requestedBase ?? resolved . baseBranch ;
2288+ const generated = yield * content ( {
2289+ provider,
22882290 baseBranch,
2291+ baseRef : requestedBase ?? resolved . baseRef ,
22892292 headBranch : headContext . headBranch ,
2290- commitSummary : limitContext ( rangeContext . commitSummary , 20_000 ) ,
2291- diffSummary : limitContext ( rangeContext . diffSummary , 20_000 ) ,
2292- diffPatch : limitContext ( rangeContext . diffPatch , 60_000 ) ,
2293- ...( changeRequestTemplate ? { changeRequestTemplate } : { } ) ,
2294- ...( threadContext ? { threadContext } : { } ) ,
2295- ...( policy ? { policy } : { } ) ,
2296- modelSelection : settings . modelSelection ,
22972293 } ) ;
2298-
22992294 const bodyFile = path . join (
23002295 tempDir ,
23012296 `t3code-pr-body-${ process . pid } -${ yield * randomUUIDv4 ( cwd ) } .md` ,
@@ -2346,6 +2341,64 @@ export const make = Effect.gen(function* () {
23462341 } ;
23472342 } ) ;
23482343
2344+ const runPrStep = (
2345+ settings : SourceControlTextGenerationSettings ,
2346+ cwd : string ,
2347+ fallbackBranch : string | null ,
2348+ threadId : ThreadId | undefined ,
2349+ emit : GitActionProgressEmitter ,
2350+ ) =>
2351+ openPrFromBranch (
2352+ cwd ,
2353+ fallbackBranch ,
2354+ emit ,
2355+ undefined ,
2356+ ( { provider, baseBranch, baseRef, headBranch } ) =>
2357+ Effect . gen ( function * ( ) {
2358+ const terms = sourceControlDefinitions . get ( provider . kind ) . changeRequest ;
2359+ yield * emit ( {
2360+ kind : "phase_started" ,
2361+ phase : "pr" ,
2362+ label : `Generating ${ terms . shortLabel } content...` ,
2363+ } ) ;
2364+ const baseRangeRef = yield * resolveBaseRangeRef ( cwd , baseRef ) ;
2365+ const rangeContext = yield * gitCore . readRangeContext ( cwd , baseRangeRef ) ;
2366+ const policy = yield * resolveStylePolicy ( cwd , settings ) ;
2367+ const changeRequestTemplate =
2368+ settings . style . followChangeRequestTemplates && provider . readChangeRequestTemplate
2369+ ? Option . getOrUndefined (
2370+ yield * provider . readChangeRequestTemplate ( { cwd, treeish : baseRangeRef } ) ,
2371+ )
2372+ : undefined ;
2373+ const threadContext = yield * readThreadContext ( threadId ) ;
2374+
2375+ return yield * textGeneration . generatePrContent ( {
2376+ cwd,
2377+ baseBranch,
2378+ headBranch,
2379+ commitSummary : limitContext ( rangeContext . commitSummary , 20_000 ) ,
2380+ diffSummary : limitContext ( rangeContext . diffSummary , 20_000 ) ,
2381+ diffPatch : limitContext ( rangeContext . diffPatch , 60_000 ) ,
2382+ ...( changeRequestTemplate ? { changeRequestTemplate } : { } ) ,
2383+ ...( threadContext ? { threadContext } : { } ) ,
2384+ ...( policy ? { policy } : { } ) ,
2385+ modelSelection : settings . modelSelection ,
2386+ } ) ;
2387+ } ) ,
2388+ ) ;
2389+
2390+ const createPullRequest : GitManager [ "Service" ] [ "createPullRequest" ] = Effect . fn (
2391+ "GitManager.createPullRequest" ,
2392+ ) ( function * ( input ) {
2393+ return yield * openPrFromBranch (
2394+ input . cwd ,
2395+ null ,
2396+ ( ) => Effect . void ,
2397+ input . baseBranch ,
2398+ ( ) => Effect . succeed ( { title : input . title , body : input . body } ) ,
2399+ ) ;
2400+ } ) ;
2401+
23492402 const localStatus : GitManager [ "Service" ] [ "localStatus" ] = Effect . fn ( "localStatus" ) (
23502403 function * ( input ) {
23512404 const cacheKey = yield * normalizeStatusCacheKey ( input . cwd ) ;
@@ -3229,6 +3282,7 @@ export const make = Effect.gen(function* () {
32293282 resolvePullRequest,
32303283 preparePullRequestThread,
32313284 runStackedAction,
3285+ createPullRequest,
32323286 subscribePullRequestStateChanges : PubSub . subscribe ( pullRequestStateChanges ) . pipe (
32333287 Effect . map ( ( subscription ) => Stream . fromSubscription ( subscription ) ) ,
32343288 ) ,
0 commit comments