@@ -12,6 +12,8 @@ import { createWorktree, removeWorktree } from './worktree';
1212import { resolvePostCreateHook } from './worktree-setup' ;
1313import { writePromptFile , cleanupPromptFile , writeLauncherScript , cleanupLauncherScript } from './prompt-file' ;
1414import { getCurrentModel } from './model-tracker' ;
15+ import { detectOMO } from './omo' ;
16+ import { copyPlansToWorktree } from './plan-copier' ;
1517import {
1618 createSession ,
1719 createWindow ,
@@ -21,6 +23,7 @@ import {
2123 isTmuxHealthy ,
2224 killSession ,
2325 killWindow ,
26+ sendKeys ,
2427 setPaneDiedHook ,
2528} from './tmux' ;
2629
@@ -675,6 +678,7 @@ export class Orchestrator {
675678 const placement = this . planPlacement ?? this . config . defaultPlacement ?? 'session' ;
676679 const shortPlanId = planId ? planId . slice ( 0 , 8 ) : '' ;
677680 const branch = job . branch ?? `mc/plan/${ shortPlanId } /${ job . name } ` ;
681+ const mode = job . mode ?? this . config . omo ?. defaultMode ?? 'vanilla' ;
678682 const sanitizedName = job . name . replace ( / [ ^ a - z A - Z 0 - 9 _ - ] / g, '-' ) ;
679683 const tmuxSessionName = `mc-${ sanitizedName } ` ;
680684 const tmuxTarget =
@@ -711,6 +715,25 @@ export class Orchestrator {
711715
712716 worktreePath = await createWorktree ( { branch, startPoint, postCreate } ) ;
713717
718+ if ( mode !== 'vanilla' ) {
719+ const omoStatus = await detectOMO ( ) ;
720+ if ( ! omoStatus . detected ) {
721+ throw new Error (
722+ `OMO mode "${ mode } " requires Oh-My-OpenCode to be installed and detected` ,
723+ ) ;
724+ }
725+
726+ if ( mode === 'plan' || mode === 'ralph' || mode === 'ulw' ) {
727+ try {
728+ const sourcePlansPath = './.sisyphus/plans' ;
729+ const targetPlansPath = `${ worktreePath } /.sisyphus/plans` ;
730+ await copyPlansToWorktree ( sourcePlansPath , targetPlansPath ) ;
731+ } catch {
732+ // Non-fatal: plans might not exist
733+ }
734+ }
735+ }
736+
714737 const mcReportSuffix = `\n\nCRITICAL — STATUS REPORTING REQUIRED:
715738You MUST call the mc_report tool at these points — this is NOT optional:
716739
@@ -725,7 +748,12 @@ If your work needs human review before it can proceed: mc_report(status: "needs_
725748 const autoCommitSuffix = ( this . config . autoCommit !== false )
726749 ? `\n\nIMPORTANT: When you have completed ALL of your work, you MUST commit your changes before finishing. Stage all modified and new files, then create a commit with a conventional commit message (e.g. "feat: ...", "fix: ...", "docs: ...", "refactor: ...", "chore: ..."). Do NOT skip this step.`
727750 : '' ;
728- const jobPrompt = job . prompt + mcReportSuffix + autoCommitSuffix ;
751+ let jobPrompt = job . prompt + mcReportSuffix + autoCommitSuffix ;
752+ if ( mode === 'ralph' ) {
753+ jobPrompt = `/ralph-loop ${ jobPrompt } ` ;
754+ } else if ( mode === 'ulw' ) {
755+ jobPrompt = `/ulw-loop ${ jobPrompt } ` ;
756+ }
729757 promptFilePath = await writePromptFile ( worktreePath , jobPrompt ) ;
730758 const model = this . planModelSnapshot ?? getCurrentModel ( ) ;
731759 const launcherPath = await writeLauncherScript ( worktreePath , promptFilePath , model ) ;
@@ -750,6 +778,28 @@ If your work needs human review before it can proceed: mc_report(status: "needs_
750778 cleanupPromptFile ( promptFilePath ) ;
751779 cleanupLauncherScript ( worktreePath ) ;
752780
781+ if ( mode !== 'vanilla' ) {
782+ try {
783+ await new Promise ( ( resolve ) => setTimeout ( resolve , 2000 ) ) ;
784+ switch ( mode ) {
785+ case 'plan' :
786+ await sendKeys ( tmuxTarget , '/start-work' ) ;
787+ await sendKeys ( tmuxTarget , 'Enter' ) ;
788+ break ;
789+ case 'ralph' :
790+ await sendKeys ( tmuxTarget , '/ralph-loop' ) ;
791+ await sendKeys ( tmuxTarget , 'Enter' ) ;
792+ break ;
793+ case 'ulw' :
794+ await sendKeys ( tmuxTarget , '/ulw-loop' ) ;
795+ await sendKeys ( tmuxTarget , 'Enter' ) ;
796+ break ;
797+ }
798+ } catch {
799+ // Non-fatal: OMO command delivery is best-effort
800+ }
801+ }
802+
753803 const existingState = await loadJobState ( ) ;
754804 const staleJobs = existingState . jobs . filter (
755805 ( j ) => j . name === job . name && j . status !== 'running' ,
@@ -769,7 +819,7 @@ If your work needs human review before it can proceed: mc_report(status: "needs_
769819 placement,
770820 status : 'running' ,
771821 prompt : job . prompt ,
772- mode : 'vanilla' ,
822+ mode,
773823 createdAt : new Date ( ) . toISOString ( ) ,
774824 planId,
775825 } ) ;
0 commit comments