@@ -725,6 +725,9 @@ const HELP_BY_COMMAND: Record<string, string> = {
725725 $ ade prs comments <pr> --text Show unresolved review work
726726 $ ade prs inventory <pr> Refresh ADE issue inventory
727727 $ ade prs path-to-merge <pr> --model <model> --max-rounds 3 --no-auto-merge
728+ $ ade prs path-to-merge <pr> --model <model> --conflict-strategy auto --force-finalize conditional
729+ $ ade prs path-to-merge <pr> --model <model> --no-early-merge-on-green
730+ $ ade prs pipeline <pr> save --conflict-strategy rebase --early-merge-on-green
728731 $ ade prs resolve-thread <pr> --thread <id> Resolve a review thread
729732 $ ade prs labels set <pr> ready-to-merge Replace labels
730733 $ ade prs reviewers request <pr> alice bob Request reviewers
@@ -1334,6 +1337,72 @@ function maybePut(target: JsonObject, key: string, value: unknown): void {
13341337 }
13351338}
13361339
1340+ /**
1341+ * Parse the PR pipeline-settings flags shared by ` prs path - to - merge ` and
1342+ * ` prs pipeline ` subcommands. Returns a partial ` PipelineSettings ` patch
1343+ * suitable for ` issue_inventory . savePipelineSettings `. Only fields the user
1344+ * explicitly passed are included so the patch never clobbers other settings.
1345+ *
1346+ * The orchestrator reads these from saved settings (not StartPathToMergeArgs),
1347+ * so the path-to-merge command must save them before launching the loop.
1348+ */
1349+ function readPipelineSettingsPatch(args: string[]): JsonObject {
1350+ const patch: JsonObject = {};
1351+
1352+ const maxRounds = readIntOption(args, ["--max-rounds", "--rounds"]);
1353+ if (maxRounds != null) patch.maxRounds = maxRounds;
1354+
1355+ const autoMerge = readFlag(args, ["--auto-merge"]);
1356+ const noAutoMerge = readFlag(args, ["--no-auto-merge"]);
1357+ if (autoMerge || noAutoMerge) patch.autoMerge = autoMerge && !noAutoMerge;
1358+
1359+ const mergeMethod = readValue(args, ["--merge-method"]);
1360+ if (mergeMethod) patch.mergeMethod = mergeMethod;
1361+
1362+ const conflictStrategy = readValue(args, ["--conflict-strategy"]);
1363+ if (conflictStrategy) {
1364+ if (
1365+ conflictStrategy !== "pause"
1366+ && conflictStrategy !== "rebase"
1367+ && conflictStrategy !== "merge"
1368+ && conflictStrategy !== "auto"
1369+ ) {
1370+ throw new CliUsageError(
1371+ "--conflict-strategy must be one of pause, rebase, merge, or auto.",
1372+ );
1373+ }
1374+ patch.conflictStrategy = conflictStrategy;
1375+ }
1376+
1377+ const forceFinalize = readValue(args, ["--force-finalize"]);
1378+ if (forceFinalize) {
1379+ if (
1380+ forceFinalize !== "off"
1381+ && forceFinalize !== "conditional"
1382+ && forceFinalize !== "unconditional"
1383+ ) {
1384+ throw new CliUsageError(
1385+ "--force-finalize must be one of off, conditional, or unconditional.",
1386+ );
1387+ }
1388+ patch.forceFinalizeMode = forceFinalize;
1389+ }
1390+
1391+ const requireNoCi = readFlag(args, ["--force-finalize-require-no-ci"]);
1392+ const allowCi = readFlag(args, ["--force-finalize-allow-ci"]);
1393+ if (requireNoCi || allowCi) {
1394+ patch.forceFinalizeRequireNoCiFailures = requireNoCi && !allowCi;
1395+ }
1396+
1397+ const earlyMergeOn = readFlag(args, ["--early-merge-on-green"]);
1398+ const earlyMergeOff = readFlag(args, ["--no-early-merge-on-green"]);
1399+ if (earlyMergeOn || earlyMergeOff) {
1400+ patch.earlyMergeOnGreen = earlyMergeOn && !earlyMergeOff;
1401+ }
1402+
1403+ return patch;
1404+ }
1405+
13371406function parseCliArgs(argv: string[]): ParsedCli {
13381407 const command: string[] = [];
13391408 const options: GlobalOptions = {
@@ -1907,19 +1976,16 @@ function buildPrPlan(args: string[]): CliPlan {
19071976 maybePut ( input , "reasoning" , readValue ( args , [ "--reasoning" ] ) ) ;
19081977 maybePut ( input , "permissionMode" , readValue ( args , [ "--permission-mode" , "--permissions" ] ) ) ;
19091978 maybePut ( input , "additionalInstructions" , readValue ( args , [ "--instructions" , "--additional-instructions" ] ) ) ;
1910- const maxRounds = readIntOption ( args , [ "--max-rounds" , "--rounds" ] ) ;
1911- const autoMerge = readFlag ( args , [ "--auto-merge" ] ) ;
1912- const noAutoMerge = readFlag ( args , [ "--no-auto-merge" ] ) ;
1913- const mergeMethod = readValue ( args , [ "--merge-method" ] ) ;
1979+ // Path to Merge orchestrator reads conflictStrategy / forceFinalizeMode /
1980+ // earlyMergeOnGreen / autoMerge / maxRounds / mergeMethod from saved
1981+ // PipelineSettings, not from the launch args. Persist any user-supplied
1982+ // overrides before the resolver step so the loop picks them up.
1983+ const pipelinePatch = readPipelineSettingsPatch ( args ) ;
19141984 const steps : InvocationStep [ ] = [ ] ;
1915- if ( maxRounds != null || autoMerge || noAutoMerge || mergeMethod ) {
1985+ if ( Object . keys ( pipelinePatch ) . length > 0 ) {
19161986 steps . push ( actionArgsListStep ( "pipelineSettings" , "issue_inventory" , "savePipelineSettings" , [
19171987 id ,
1918- {
1919- ...( maxRounds != null ? { maxRounds } : { } ) ,
1920- ...( autoMerge || noAutoMerge ? { autoMerge : autoMerge && ! noAutoMerge } : { } ) ,
1921- ...( mergeMethod ? { mergeMethod } : { } ) ,
1922- } ,
1988+ pipelinePatch ,
19231989 ] ) ) ;
19241990 }
19251991 steps . push ( actionCallStep ( "result" , mode === "preview" ? "pr_preview_issue_resolution_prompt" : "pr_start_issue_resolution" , collectGenericObjectArgs ( args , input ) ) ) ;
@@ -1931,12 +1997,7 @@ function buildPrPlan(args: string[]): CliPlan {
19311997 const id = requireValue ( prId ?? firstPositional ( args ) , "prId" ) ;
19321998 if ( mode === "get" ) return { kind : "execute" , label : "PR pipeline" , steps : [ actionArgsListStep ( "result" , "issue_inventory" , "getPipelineSettings" , [ id ] ) ] } ;
19331999 if ( mode === "delete" ) return { kind : "execute" , label : "PR pipeline delete" , steps : [ actionArgsListStep ( "result" , "issue_inventory" , "deletePipelineSettings" , [ id ] ) ] } ;
1934- const maxRounds = readIntOption ( args , [ "--max-rounds" , "--rounds" ] ) ;
1935- const mergeMethod = readValue ( args , [ "--merge-method" ] ) ;
1936- const settings = collectGenericObjectArgs ( args , {
1937- ...( maxRounds != null ? { maxRounds } : { } ) ,
1938- ...( mergeMethod ? { mergeMethod } : { } ) ,
1939- } ) ;
2000+ const settings = collectGenericObjectArgs ( args , readPipelineSettingsPatch ( args ) ) ;
19402001 return { kind : "execute" , label : "PR pipeline save" , steps : [ actionArgsListStep ( "result" , "issue_inventory" , "savePipelineSettings" , [ id , settings ] ) ] } ;
19412002 }
19422003
0 commit comments