{"version":3,"sources":["../../src/core/transaction.ts"],"names":["pendingTransactions","createSnapshot","filePaths","cwd","snapshot","filePath","readFileContent","applyOperations","operations","originalFiles","result","applyOperationsCore","newFileStates","renameOps","op","renameFile","fsPromises","allPaths","renamedFromPaths","path","oldContent","newContent","deleteFile","writeFileContent","restoreSnapshot","projectRoot","entries","directoriesToClean","restoreErrors","content","fullPath","error","sortedDirs","a","b","dir","removeEmptyParentDirectories","errorSummary","e","getErrorMessage","logCompletionSummary","_uuid","startTime","errorCount","duration","opCount","opPlural","logger","chalk","rollbackTransaction","uuid","reason","enableNotifications","isError","rollbackSuccessful","notifyRollbackFailure","deletePendingState","notifyFailure","cleanupError","handleApproval","config","getConfirmation","finalErrorCount","getErrorCount","getManualApproval","notificationResult","requestApprovalWithNotification","_processPatch","parsedResponse","options","createConfirmationHandler","control","reasoning","projectId","hasBeenProcessed","minFileChanges","maxFileChanges","operationCount","notifyPatchDetected","exitCode","stderr","executeShellCommand","affectedFilePaths","acc","stateFile","writePendingState","p","stats","calculateLineChangesCore","postResult","updatePendingState","commitState","notifySuccess","handleAutoGitBranch","processPatch","getPendingTransactionCount","_cwd","approveAllPendingTransactions","_config","yes","pending","sortedPending","tx","normalizeGitCommitMsg","processPatchesBulk","parsedResponses","branchNameSegment","sanitizedSegment","branchName","command"],"mappings":"0bAqBA,MAAMA,CAAAA,CAAsB,IAAI,GAAA,CAEnBC,CAAAA,CAAiB,MAAOC,CAAAA,CAAqBC,CAAAA,CAAc,QAAQ,GAAA,EAAI,GAA6B,CAC/G,MAAMC,CAAAA,CAAyB,EAAC,CAChC,OAAA,MAAM,QAAQ,GAAA,CACZF,CAAAA,CAAU,IAAI,MAAOG,CAAAA,EAAa,CAChCD,CAAAA,CAASC,CAAQ,CAAA,CAAI,MAAMC,mBAAgBD,CAAAA,CAAUF,CAAG,EAC1D,CAAC,CACH,EACOC,CACT,CAAA,CAWaG,EAAkB,MAC7BC,CAAAA,CACAC,EACAN,CAAAA,CAAc,OAAA,CAAQ,KAAI,GACc,CAExC,MAAMO,CAAAA,CAAS,MAAMC,6BAAAA,CAAoBH,CAAAA,CAAYC,CAAa,CAAA,CAElE,GAAI,CAACC,CAAAA,CAAO,OAAA,CACV,MAAM,IAAI,KAAA,CAAM,sCAAsCA,CAAAA,CAAO,KAAA,EAAS,eAAe,CAAA,CAAE,CAAA,CAGzF,KAAM,CAAE,aAAA,CAAAE,CAAc,CAAA,CAAIF,EAIpBG,CAAAA,CAAYL,CAAAA,CAAW,OAAQM,CAAAA,EAAuDA,CAAAA,CAAG,OAAS,QAAQ,CAAA,CAChH,UAAWA,CAAAA,IAAMD,CAAAA,CACf,MAAME,aAAAA,CAAWD,CAAAA,CAAG,KAAMA,CAAAA,CAAG,EAAA,CAAIX,CAAG,CAAA,CAItC,MAAMa,EAA8B,EAAC,CAC/BC,EAAW,IAAI,GAAA,CAAI,CAAC,GAAGR,CAAAA,CAAc,MAAK,CAAG,GAAGG,EAAc,IAAA,EAAM,CAAC,CAAA,CACrEM,CAAAA,CAAmB,IAAI,GAAA,CAAIL,CAAAA,CAAU,IAAIC,CAAAA,EAAMA,CAAAA,CAAG,IAAI,CAAC,EAE7D,IAAA,MAAWK,CAAAA,IAAQF,EAAU,CAC3B,GAAIC,EAAiB,GAAA,CAAIC,CAAI,EAAG,SAEhC,MAAMC,EAAaX,CAAAA,CAAc,GAAA,CAAIU,CAAI,CAAA,CACnCE,CAAAA,CAAaT,EAAc,GAAA,CAAIO,CAAI,CAAA,CACrCC,CAAAA,GAAeC,IAGXA,CAAAA,EAAc,IAAA,CACdL,EAAW,IAAA,CAAKM,aAAAA,CAAWH,EAAMhB,CAAG,CAAC,EAErCa,CAAAA,CAAW,IAAA,CAAKO,oBAAiBJ,CAAAA,CAAME,CAAAA,CAAYlB,CAAG,CAAC,CAAA,EAGjE,CACA,OAAA,MAAM,OAAA,CAAQ,GAAA,CAAIa,CAAU,EAErBJ,CACT,CAAA,CAEaY,EAAkB,MAAOpB,CAAAA,CAAwBD,EAAc,OAAA,CAAQ,GAAA,KAAyB,CAC3G,MAAMsB,EAAcN,kBAAAA,CAAK,OAAA,CAAQhB,CAAG,CAAA,CAC9BuB,CAAAA,CAAU,OAAO,OAAA,CAAQtB,CAAQ,CAAA,CACjCuB,CAAAA,CAAqB,IAAI,GAAA,CACzBC,CAAAA,CAAoD,EAAC,CAG3D,MAAM,QAAQ,GAAA,CAAIF,CAAAA,CAAQ,IAAI,MAAO,CAACrB,EAAUwB,CAAO,CAAA,GAAM,CACzD,MAAMC,CAAAA,CAAWX,mBAAK,OAAA,CAAQhB,CAAAA,CAAKE,CAAQ,CAAA,CAC3C,GAAI,CACEwB,CAAAA,GAAY,MAEd,MAAMP,aAAAA,CAAWjB,EAAUF,CAAG,CAAA,CAC9BwB,EAAmB,GAAA,CAAIR,kBAAAA,CAAK,QAAQW,CAAQ,CAAC,GAG7C,MAAMP,mBAAAA,CAAiBlB,EAAUwB,CAAAA,CAAS1B,CAAG,EAEjD,CAAA,MAAS4B,EAAO,CACdH,CAAAA,CAAc,KAAK,CAAE,IAAA,CAAMvB,EAAU,KAAA,CAAA0B,CAAM,CAAC,EAC9C,CACJ,CAAC,CAAC,CAAA,CAIF,MAAMC,CAAAA,CAAa,KAAA,CAAM,KAAKL,CAAkB,CAAA,CAC7C,IAAA,CAAK,CAACM,EAAGC,CAAAA,GAAMA,CAAAA,CAAE,MAAMf,kBAAAA,CAAK,GAAG,EAAE,MAAA,CAASc,CAAAA,CAAE,MAAMd,kBAAAA,CAAK,GAAG,EAAE,MAAM,CAAA,CAGrE,UAAWgB,CAAAA,IAAOH,CAAAA,CAChB,MAAMI,+BAAAA,CAA6BD,CAAAA,CAAKV,CAAW,CAAA,CAGrD,GAAIG,EAAc,MAAA,CAAS,CAAA,CAAG,CAC5B,MAAMS,CAAAA,CAAeT,EAClB,GAAA,CAAIU,CAAAA,EAAK,OAAOA,CAAAA,CAAE,IAAI,KAAKC,sBAAAA,CAAgBD,CAAAA,CAAE,KAAK,CAAC,CAAA,CAAE,EACrD,IAAA,CAAK;AAAA,CAAI,EACZ,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuBV,EAAc,MAAM,CAAA;AAAA,EAAcS,CAAY,CAAA,CAAE,CACzF,CACF,CAAA,CAEMG,EAAuB,CACzBC,CAAAA,CACAC,CAAAA,CACAlC,CAAAA,CACAmC,CAAAA,GACC,CACD,MAAMC,CAAAA,CAAAA,CAAY,IAAA,CAAK,GAAA,EAAI,CAAIF,CAAAA,EAAa,GAAA,CACtCG,CAAAA,CAAUrC,CAAAA,CAAW,MAAA,CACrBsC,CAAAA,CAAWD,CAAAA,GAAY,CAAA,CAAI,EAAA,CAAK,GAAA,CACtCE,cAAO,IAAA,CAAK,EAAE,CAAA,CACdA,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,KAAK,CAAA,SAAA,EAAYH,CAAO,CAAA,eAAA,EAAkBC,CAAQ,CAAA,YAAA,EAAeF,CAAAA,CAAS,QAAQ,CAAC,CAAC,CAAA,kBAAA,EAAqBD,CAAU,CAAA,CAAA,CAAG,CAAC,EAC7I,CAAA,CAEMM,CAAAA,CAAsB,MAAO9C,CAAAA,CAAa+C,CAAAA,CAAc9C,CAAAA,CAAwB+C,CAAAA,CAAgBC,EAA+B,IAAA,CAAMC,CAAAA,CAAmB,IAAA,GAAwB,CAElL,GAAI,CAACH,GAAQ,OAAOA,CAAAA,EAAS,QAAA,EAAY,CAACA,CAAAA,CAAK,KAAA,CAAM,+EAA+E,CAAA,CAAG,CACnIH,aAAAA,CAAO,KAAA,CAAM,CAAA,2CAAA,EAA8CG,CAAI,CAAA,CAAE,CAAA,CACjE,MACJ,CAEIG,CAAAA,EACAN,aAAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyBI,CAAM,CAAA,CAAE,CAAA,CAGjD,IAAIG,CAAAA,CAAqB,KAAA,CACzB,GAAI,CACA,MAAM9B,CAAAA,CAAgBpB,CAAAA,CAAUD,CAAG,CAAA,CACnC4C,aAAAA,CAAO,OAAA,CAAQ,uCAAuC,CAAA,CACtDO,CAAAA,CAAqB,CAAA,EACzB,CAAA,MAASvB,CAAAA,CAAO,CACZgB,aAAAA,CAAO,KAAA,CAAM,CAAA,wBAAA,EAA2BR,sBAAAA,CAAgBR,CAAK,CAAC,CAAA,CAAE,CAAA,CAChEwB,+BAAsBL,CAAAA,CAAME,CAAmB,EAEnD,CAAA,OAAE,CACE,GAAI,CACA,MAAMI,wBAAAA,CAAmBrD,CAAAA,CAAK+C,CAAI,CAAA,CAClClD,CAAAA,CAAoB,OAAOkD,CAAI,CAAA,CAC/BH,aAAAA,CAAO,IAAA,CAAK,CAAA,yBAAA,EAAkBC,kBAAAA,CAAM,IAAA,CAAKE,CAAI,CAAC,CAAA,aAAA,CAAe,CAAA,CACzDG,CAAAA,EAAWC,CAAAA,EACXG,sBAAAA,CAAcP,EAAME,CAAmB,EAE/C,CAAA,MAASM,CAAAA,CAAc,CACnBX,aAAAA,CAAO,KAAA,CAAM,CAAA,4CAAA,EAA+CC,kBAAAA,CAAM,IAAA,CAAKE,CAAI,CAAC,CAAA,EAAA,EAAKX,sBAAAA,CAAgBmB,CAAY,CAAC,CAAA,CAAE,EACpH,CACJ,CACJ,CAAA,CAQMC,CAAAA,CAAiB,MAAO,CAAE,MAAA,CAAAC,CAAAA,CAAQ,GAAA,CAAAzD,CAAAA,CAAK,eAAA,CAAA0D,CAAgB,CAAA,GAAyC,CAClG,MAAMC,CAAAA,CAAkB,MAAMC,mBAAAA,CAAcH,EAAO,KAAA,CAAM,MAAA,CAAQzD,CAAG,CAAA,CACpE4C,aAAAA,CAAO,GAAA,CAAI,iCAAiCe,CAAAA,CAAkB,CAAA,CAAId,kBAAAA,CAAM,GAAA,CAAIc,CAAe,CAAA,CAAId,kBAAAA,CAAM,KAAA,CAAMc,CAAe,CAAC,CAAA,CAAE,CAAA,CAE7H,MAAME,CAAAA,CAAoB,MAAOb,CAAAA,EAAqC,CAClEJ,aAAAA,CAAO,IAAA,CAAKI,CAAM,CAAA,CAElB,MAAMc,CAAAA,CAAqB,MAAMC,wCAAAA,CAAgCN,CAAAA,CAAO,SAAA,CAAWA,CAAAA,CAAO,IAAA,CAAK,mBAAmB,CAAA,CAElH,OAAIK,CAAAA,GAAuB,UAAA,EACvBlB,aAAAA,CAAO,IAAA,CAAK,4BAA4B,CAAA,CACjC,IAAA,EAEPkB,CAAAA,GAAuB,UAAA,EACvBlB,aAAAA,CAAO,IAAA,CAAK,4BAA4B,EACjC,KAAA,GAGPkB,CAAAA,GAAuB,SAAA,EACvBlB,aAAAA,CAAO,IAAA,CAAK,6DAA6D,EAGtE,MAAMc,CAAAA,CAAgB,gEAAgE,CAAA,CACjG,CAAA,CAEA,OAAID,EAAO,KAAA,CAAM,YAAA,GAAiB,QAAA,CACvB,MAAMI,CAAAA,CAAkB,EAAE,CAAA,CAGdF,CAAAA,EAAmBF,CAAAA,CAAO,KAAA,CAAM,oBAAA,EAEnDb,aAAAA,CAAO,OAAA,CAAQ,iEAAiE,EACzE,IAAA,EAEJ,MAAMiB,CAAAA,CAAkB,CAAA,uCAAA,EAA0CF,CAAe,CAAA,wBAAA,EAA2BF,EAAO,KAAA,CAAM,oBAAoB,CAAA,EAAA,CAAI,CAC5J,CAAA,CAEMO,EAAAA,CAAgB,MAAOP,CAAAA,CAAgBQ,CAAAA,CAAmCC,CAAAA,GAAiD,CAC7H,MAAMlE,CAAAA,CAAMkE,CAAAA,EAAS,GAAA,EAAO,OAAA,CAAQ,GAAA,EAAI,CAClCR,CAAAA,CAAkBS,gCAAAA,CAA0B,CAAE,IAAKD,CAAAA,EAAS,GAAI,CAAA,CAAGA,CAAAA,EAAS,QAAQ,CAAA,CACpF,CAAE,OAAA,CAAAE,CAAAA,CAAS,UAAA,CAAA/D,CAAAA,CAAY,SAAA,CAAAgE,CAAU,EAAIJ,CAAAA,CACrC,CAAE,IAAA,CAAAlB,CAAAA,CAAM,SAAA,CAAAuB,CAAU,CAAA,CAAIF,CAAAA,CACtB7B,CAAAA,CAAY,WAAA,CAAY,GAAA,EAAI,CAGlC,GAAI+B,CAAAA,GAAcb,EAAO,SAAA,CAAW,CAChCb,aAAAA,CAAO,IAAA,CAAK,CAAA,8CAAA,EAAiDC,kBAAAA,CAAM,IAAA,CAAKY,CAAAA,CAAO,SAAS,CAAC,CAAA,QAAA,EAAWZ,kBAAAA,CAAM,IAAA,CAAKyB,CAAS,CAAC,CAAA,GAAA,CAAK,CAAA,CAC9H,MACJ,CACA,GAAI,MAAMC,sBAAAA,CAAiBvE,CAAAA,CAAK+C,CAAI,CAAA,CAAG,CACnCH,aAAAA,CAAO,IAAA,CAAK,CAAA,sBAAA,EAAyBC,mBAAM,IAAA,CAAKE,CAAI,CAAC,CAAA,6BAAA,CAA+B,CAAA,CACpF,MACJ,CAEA,KAAM,CAAE,cAAA,CAAAyB,CAAAA,CAAgB,cAAA,CAAAC,CAAe,EAAIhB,CAAAA,CAAO,KAAA,CAC5CiB,CAAAA,CAAiBrE,CAAAA,CAAW,MAAA,CAClC,GAAImE,CAAAA,CAAiB,CAAA,EAAKE,CAAAA,CAAiBF,CAAAA,CAAgB,CACvD5B,aAAAA,CAAO,IAAA,CAAK,CAAA,2DAAA,EAA8D4B,CAAc,CAAA,MAAA,EAASE,CAAc,CAAA,EAAA,CAAI,CAAA,CACnH,MACJ,CACA,GAAID,CAAAA,EAAkBC,CAAAA,CAAiBD,CAAAA,CAAgB,CACnD7B,aAAAA,CAAO,IAAA,CAAK,CAAA,wDAAA,EAA2D6B,CAAc,CAAA,MAAA,EAASC,CAAc,CAAA,EAAA,CAAI,CAAA,CAChH,MACJ,CAQA,GALIR,CAAAA,EAAS,aAAA,EACTS,4BAAAA,CAAoBlB,CAAAA,CAAO,SAAA,CAAWA,CAAAA,CAAO,IAAA,CAAK,mBAAmB,CAAA,CAIrEA,CAAAA,CAAO,KAAA,CAAM,UAAA,CAAY,CACzBb,aAAAA,CAAO,IAAI,CAAA,yBAAA,EAA4BC,kBAAAA,CAAM,OAAA,CAAQY,CAAAA,CAAO,KAAA,CAAM,UAAU,CAAC,CAAA,CAAE,CAAA,CAC/E,KAAM,CAAE,QAAA,CAAAmB,CAAAA,CAAU,MAAA,CAAAC,CAAO,CAAA,CAAI,MAAMC,yBAAAA,CAAoBrB,CAAAA,CAAO,KAAA,CAAM,UAAA,CAAYzD,CAAG,CAAA,CACnF,GAAI4E,CAAAA,GAAa,CAAA,CAAG,CAChBhC,aAAAA,CAAO,KAAA,CAAM,CAAA,kCAAA,EAAqCC,kBAAAA,CAAM,GAAA,CAAI+B,CAAQ,CAAC,CAAA,uBAAA,CAAyB,CAAA,CAC1FC,GAAQjC,aAAAA,CAAO,KAAA,CAAM,CAAA,QAAA,EAAWiC,CAAM,CAAA,CAAE,CAAA,CAC5C,MACJ,CACJ,CAEAjC,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,IAAA,CAAK;AAAA,kDAAA,CAAsD,CAAC,EAC9ED,aAAAA,CAAO,IAAA,CAAKC,mBAAM,IAAA,CAAK,CAAA,yBAAA,EAAqBE,CAAAA,CAAK,SAAA,CAAU,CAAA,CAAE,CAAC,CAAC,CAAA,MAAA,EAASuB,CAAS,CAAA,IAAA,CAAM,CAAC,CAAA,CACxF1B,aAAAA,CAAO,IAAI,CAAA,EAAGC,kBAAAA,CAAM,IAAA,CAAK,YAAY,CAAC;AAAA,EAAA,EAAOwB,EAAU,IAAA,CAAK;AAAA,EAAA,CAAM,CAAC,CAAA,CAAE,CAAA,CAErE,MAAMU,EAAoB1E,CAAAA,CAAW,MAAA,CAAiB,CAAC2E,CAAAA,CAAKrE,CAAAA,IACpDA,CAAAA,CAAG,IAAA,GAAS,QAAA,CACZqE,EAAI,IAAA,CAAKrE,CAAAA,CAAG,IAAA,CAAMA,CAAAA,CAAG,EAAE,CAAA,CAEvBqE,CAAAA,CAAI,IAAA,CAAKrE,EAAG,IAAI,CAAA,CAEbqE,CAAAA,CAAAA,CACR,EAAE,CAAA,CACC/E,CAAAA,CAAW,MAAMH,EAAeiF,CAAAA,CAAmB/E,CAAG,CAAA,CAEtDiF,CAAAA,CAAuB,CACzB,IAAA,CAAAlC,CAAAA,CACA,SAAA,CAAAuB,EACA,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,CAClC,YAAA,CAAcF,CAAAA,CAAQ,aACtB,aAAA,CAAeA,CAAAA,CAAQ,aAAA,CACvB,SAAA,CAAAC,CAAAA,CACA,UAAA,CAAAhE,CAAAA,CACA,QAAA,CAAAJ,EACA,QAAA,CAAU,KACd,CAAA,CAEA,GAAI,CACA,MAAMiF,uBAAAA,CAAkBlF,CAAAA,CAAKiF,CAAS,EAEtC,MAAM3E,CAAAA,CAAgB,IAAI,GAAA,CAC1ByE,CAAAA,CAAkB,OAAA,CAAQI,CAAAA,EAAK7E,CAAAA,CAAc,IAAI6E,CAAAA,CAAGlF,CAAAA,CAASkF,CAAC,CAAA,EAAK,IAAI,CAAC,CAAA,CAGxE,MAAM1E,EAAgB,MAAML,CAAAA,CAAgBC,CAAAA,CAAYC,CAAAA,CAAeN,CAAG,CAAA,CAc1E,GAZAK,CAAAA,CAAW,QAAQM,CAAAA,EAAM,CACrB,MAAMyE,CAAAA,CAAQC,kCAAAA,CAAyB1E,CAAAA,CAAIL,CAAAA,CAAeG,CAAa,EACnEE,CAAAA,CAAG,IAAA,GAAS,OAAA,CACZiC,aAAAA,CAAO,OAAA,CAAQ,CAAA,gBAAA,EAAcC,kBAAAA,CAAM,IAAA,CAAKlC,EAAG,IAAI,CAAC,CAAA,EAAA,EAAKkC,kBAAAA,CAAM,KAAA,CAAM,CAAA,CAAA,EAAIuC,CAAAA,CAAM,KAAK,EAAE,CAAC,CAAA,EAAA,EAAKvC,kBAAAA,CAAM,GAAA,CAAI,CAAA,CAAA,EAAIuC,CAAAA,CAAM,OAAO,CAAA,CAAE,CAAC,CAAA,CAAA,CAAG,CAAA,CAClHzE,CAAAA,CAAG,IAAA,GAAS,SACnBiC,aAAAA,CAAO,OAAA,CAAQ,CAAA,gBAAA,EAAcC,kBAAAA,CAAM,KAAKlC,CAAAA,CAAG,IAAI,CAAC,CAAA,CAAE,CAAA,CAC3CA,CAAAA,CAAG,IAAA,GAAS,QAAA,EACnBiC,cAAO,OAAA,CAAQ,CAAA,gBAAA,EAAcC,kBAAAA,CAAM,IAAA,CAAKlC,CAAAA,CAAG,IAAI,CAAC,CAAA,IAAA,EAAOkC,mBAAM,IAAA,CAAKlC,CAAAA,CAAG,EAAE,CAAC,CAAA,CAAE,EAElF,CAAC,CAAA,CAGG8C,EAAO,KAAA,CAAM,WAAA,CAAa,CAC1Bb,aAAAA,CAAO,GAAA,CAAI,CAAA,0BAAA,EAA6BC,kBAAAA,CAAM,OAAA,CAAQY,EAAO,KAAA,CAAM,WAAW,CAAC,CAAA,CAAE,CAAA,CACjF,MAAM6B,CAAAA,CAAa,MAAMR,0BAAoBrB,CAAAA,CAAO,KAAA,CAAM,WAAA,CAAazD,CAAG,CAAA,CAC1E,GAAIsF,CAAAA,CAAW,QAAA,GAAa,EACxB,MAAA1C,aAAAA,CAAO,KAAA,CAAM,CAAA,mCAAA,EAAsCC,kBAAAA,CAAM,GAAA,CAAIyC,CAAAA,CAAW,QAAQ,CAAC,CAAA,CAAA,CAAG,CAAA,CAChFA,CAAAA,CAAW,MAAA,EAAQ1C,cAAO,KAAA,CAAM,CAAA,QAAA,EAAW0C,CAAAA,CAAW,MAAM,EAAE,CAAA,CAC5D,IAAI,KAAA,CAAM,wCAAwC,CAEhE,CAGA,MAAM9C,CAAAA,CAAa,MAAMoB,mBAAAA,CAAcH,CAAAA,CAAO,KAAA,CAAM,MAAA,CAAQzD,CAAG,CAAA,CAG/DqC,CAAAA,CAAqBU,CAAAA,CAAMR,EAAWlC,CAAAA,CAAYmC,CAAU,CAAA,CAEzC,MAAMgB,CAAAA,CAAe,CACpC,MAAA,CAAAC,CAAAA,CACA,IAAAzD,CAAAA,CACA,eAAA,CAAA0D,CACJ,CAAC,CAAA,EAGGuB,CAAAA,CAAU,QAAA,CAAW,CAAA,CAAA,CACrB,MAAMM,wBAAAA,CAAmBvF,CAAAA,CAAKiF,CAAS,CAAA,CACvC,MAAMO,iBAAAA,CAAYxF,CAAAA,CAAK+C,CAAI,EAC3B0C,sBAAAA,CAAc1C,CAAAA,CAAMU,CAAAA,CAAO,IAAA,CAAK,mBAAmB,CAAA,CACnD,MAAMiC,EAAAA,CAAoBjC,EAAQwB,CAAAA,CAAWjF,CAAG,CAAA,CAChD4C,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,KAAA,CAAM,CAAA,aAAA,EAAWE,EAAK,SAAA,CAAU,CAAA,CAAE,CAAC,CAAC,aAAa,CAAC,CAAA,CACpEH,aAAAA,CAAO,IAAA,CAAKC,mBAAM,IAAA,CAAK;AAAA,+BAAA,CAAmC,CAAC,CAAA,GAE3DD,aAAAA,CAAO,IAAA,CAAK,sDAAsD,EAClE,MAAME,CAAAA,CAAoB9C,CAAAA,CAAK+C,CAAAA,CAAM9C,EAAU,mBAAA,CAAqBwD,CAAAA,CAAO,KAAK,mBAAA,CAAqB,CAAA,CAAK,GAElH,CAAA,MAAS7B,CAAAA,CAAO,CACZ,MAAMoB,EAASZ,sBAAAA,CAAgBR,CAAK,EACpC,MAAMkB,CAAAA,CAAoB9C,EAAK+C,CAAAA,CAAM9C,CAAAA,CAAU+C,CAAAA,CAAQS,CAAAA,CAAO,KAAK,mBAAA,CAAqB,IAAI,EAC5Fb,aAAAA,CAAO,IAAA,CAAKC,mBAAM,IAAA,CAAK;AAAA,+BAAA,CAAmC,CAAC,EAC/D,CACJ,CAAA,CAWa8C,EAAAA,CAAe,MAAOlC,CAAAA,CAAgBQ,CAAAA,CAAmCC,CAAAA,GAAiD,CACnI,MAAMF,EAAAA,CAAcP,EAAQQ,CAAAA,CAAgBC,CAAO,EACvD,CAAA,CAEa0B,EAAAA,CAA6B,CAACC,EAAe,OAAA,CAAQ,GAAA,EAAI,GAC3DhG,CAAAA,CAAoB,IAAA,CAGlBiG,EAAAA,CAAgC,MAAOC,CAAAA,CAAiB/F,CAAAA,CAAc,OAAA,CAAQ,GAAA,EAAI,CAAGgG,CAAAA,CAAe,QAAyB,CACtI,MAAMC,CAAAA,CAAU,KAAA,CAAM,IAAA,CAAKpG,CAAAA,CAAoB,QAAQ,CAAA,CACvD,GAAIoG,CAAAA,CAAQ,MAAA,GAAW,CAAA,CAAG,CACtBrD,aAAAA,CAAO,IAAA,CAAK,qCAAqC,CAAA,CACjD,MACJ,CAEA,MAAMsD,CAAAA,CAAgBD,CAAAA,CAAQ,IAAA,CAAK,CAACnE,CAAAA,CAAEC,CAAAA,GAAM,IAAI,IAAA,CAAKD,CAAAA,CAAE,SAAS,CAAA,CAAE,OAAA,EAAQ,CAAI,IAAI,IAAA,CAAKC,CAAAA,CAAE,SAAS,CAAA,CAAE,OAAA,EAAS,EAS7G,GAPAa,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,IAAA,CAAK,CAAA,MAAA,EAASoD,EAAQ,MAAM,CAAA,mBAAA,CAAqB,CAAC,CAAA,CACpEC,CAAAA,CAAc,OAAA,CAAQC,GAAM,CACxB,MAAM9B,CAAAA,CAAAA,CAAa+B,mCAAAA,CAAsB,KAAA,CAAM,OAAA,CAAQD,EAAG,SAAS,CAAA,CAAIA,CAAAA,CAAG,SAAA,CAAU,IAAA,CAAK,GAAG,EAAIA,CAAAA,CAAG,SAAS,CAAA,EAAK,wBAAA,EAA0B,KAAA,CAAM;AAAA,CAAI,CAAA,CAAE,CAAC,CAAA,CACxJvD,aAAAA,CAAO,IAAA,CAAK,CAAA,IAAA,EAAOC,kBAAAA,CAAM,IAAA,CAAKsD,CAAAA,CAAG,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,CAAC,CAAC,CAAC,CAAA,EAAA,EAAK9B,CAAS,CAAA,CAAE,EACzE,CAAC,CAAA,CACDzB,aAAAA,CAAO,IAAA,CAAK,EAAE,CAAA,CAEVoD,CAAAA,CAAK,CACLpD,aAAAA,CAAO,KAAK,EAAE,CAAA,CACd,IAAA,MAAWuD,CAAAA,IAAMD,CAAAA,CAEb,MAAMV,iBAAAA,CAAYxF,CAAAA,CAAKmG,CAAAA,CAAG,IAAI,CAAA,CAC9BvD,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,KAAA,CAAM,CAAA,aAAA,EAAWsD,EAAG,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,CAAC,CAAC,CAAA,WAAA,CAAa,CAAC,CAAA,CACvEtG,CAAAA,CAAoB,MAAA,CAAOsG,CAAAA,CAAG,IAAI,CAAA,CAEtCvD,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,KAAK,KAAA,CAAM;AAAA,8BAAA,EAA8BoD,CAAAA,CAAQ,MAAM,CAAA,WAAA,CAAa,CAAC,CAAA,CACvF,MACJ,CAKA,GAAI,CAFc,MADD9B,gCAAAA,CAA0B,EAAE,CAAA,CACZ,gDAAgD,CAAA,CAEjE,CACZvB,aAAAA,CAAO,IAAA,CAAK,0BAA0B,CAAA,CACtC,MACJ,CAEAA,aAAAA,CAAO,IAAA,CAAK,EAAE,CAAA,CACd,IAAA,MAAWuD,CAAAA,IAAMD,CAAAA,CAEb,MAAMV,iBAAAA,CAAYxF,CAAAA,CAAKmG,CAAAA,CAAG,IAAI,CAAA,CAC9BvD,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,KAAA,CAAM,CAAA,aAAA,EAAWsD,CAAAA,CAAG,IAAA,CAAK,SAAA,CAAU,CAAA,CAAE,CAAC,CAAC,CAAA,WAAA,CAAa,CAAC,CAAA,CACvEtG,CAAAA,CAAoB,MAAA,CAAOsG,CAAAA,CAAG,IAAI,CAAA,CAGtCvD,aAAAA,CAAO,IAAA,CAAKC,kBAAAA,CAAM,IAAA,CAAK,KAAA,CAAM;AAAA,8BAAA,EAA8BoD,EAAQ,MAAM,CAAA,WAAA,CAAa,CAAC,EAC3F,EAEaI,EAAAA,CAAqB,MAAO5C,CAAAA,CAAgB6C,CAAAA,CAAsCpC,IAAiD,CAG5I,IAAA,MAAWD,CAAAA,IAAkBqC,CAAAA,CACzB,MAAMX,EAAAA,CAAalC,CAAAA,CAAQQ,CAAAA,CAAgBC,CAAO,EAE1D,CAAA,CAGMwB,EAAAA,CAAsB,MAAOjC,CAAAA,CAAgBwB,EAAsBjF,CAAAA,GAA+B,CACpG,GAAI,CAACyD,EAAO,GAAA,CAAI,aAAA,CAAe,OAE/B,IAAI8C,CAAAA,CAAoB,GACpB9C,CAAAA,CAAO,GAAA,CAAI,iBAAA,GAAsB,cAAA,EAAkBwB,EAAU,YAAA,CAC7DsB,CAAAA,CAAoBH,mCAAAA,CAAsBnB,CAAAA,CAAU,YAAY,CAAA,EAAK,EAAA,CAErEsB,CAAAA,CAAoBtB,CAAAA,CAAU,KAGlC,MAAMuB,CAAAA,CAAmBD,EACpB,IAAA,EAAK,CACL,aAAY,CACZ,OAAA,CAAQ,WAAA,CAAa,EAAE,EACvB,OAAA,CAAQ,SAAA,CAAW,GAAG,CAAA,CACtB,QAAQ,KAAA,CAAO,GAAG,CAAA,CAClB,OAAA,CAAQ,SAAU,EAAE,CAAA,CACpB,MAAM,CAAA,CAAG,EAAE,EAEhB,GAAIC,CAAAA,CAAkB,CAClB,MAAMC,EAAa,CAAA,EAAGhD,CAAAA,CAAO,GAAA,CAAI,eAAe,GAAG+C,CAAgB,CAAA,CAAA,CACnE5D,aAAAA,CAAO,IAAA,CAAK,6CAA6CC,kBAAAA,CAAM,OAAA,CAAQ4D,CAAU,CAAC,EAAE,CAAA,CACpF,MAAMC,CAAAA,CAAU,CAAA,iBAAA,EAAoBD,CAAU,CAAA,CAAA,CAAA,CACxClG,CAAAA,CAAS,MAAMuE,yBAAAA,CAAoB4B,EAAS1G,CAAG,CAAA,CACjDO,CAAAA,CAAO,QAAA,GAAa,EACpBqC,aAAAA,CAAO,OAAA,CAAQ,gDAAgDC,kBAAAA,CAAM,OAAA,CAAQ4D,CAAU,CAAC,CAAA,EAAA,CAAI,CAAA,EAGxFlG,CAAAA,CAAO,WAAa,GAAA,EAAOA,CAAAA,CAAO,MAAA,CAAO,QAAA,CAAS,gBAAgB,CAAA,CAClEqC,aAAAA,CAAO,IAAA,CAAK,CAAA,yBAAA,EAA4BC,mBAAM,OAAA,CAAQ4D,CAAU,CAAC,CAAA,4BAAA,CAA8B,CAAA,CAE/F7D,cAAO,IAAA,CAAK,CAAA,6BAAA,EAAgCC,kBAAAA,CAAM,OAAA,CAAQ4D,CAAU,CAAC,CAAA,EAAA,CAAI,CAAA,CAE7E7D,aAAAA,CAAO,MAAM,CAAA,CAAA,EAAI8D,CAAO,CAAA,eAAA,EAAkBnG,CAAAA,CAAO,MAAM,CAAA,CAAE,CAAA,EAEjE,MACIqC,aAAAA,CAAO,IAAA,CAAK,qGAAqG,EAEzH","file":"transaction.cjs","sourcesContent":["import { type Config, type ParsedLLMResponse, type StateFile, type FileSnapshot, type FileOperation, normalizeGitCommitMsg } from 'relaycode-core';\nimport { logger, getErrorMessage } from '../utils/logger';\nimport { getErrorCount, executeShellCommand } from '../utils/shell';\nimport { deleteFile, readFileContent, removeEmptyParentDirectories, renameFile, writeFileContent } from '../utils/fs';\nimport path from 'path';\nimport chalk from 'chalk';\nimport { applyOperations as applyOperationsCore, calculateLineChanges as calculateLineChangesCore } from 'relaycode-core';\n\nimport { commitState, deletePendingState, hasBeenProcessed, updatePendingState, writePendingState } from './state';\nimport { createConfirmationHandler } from '../utils/prompt';\nimport { requestApprovalWithNotification, notifyFailure, notifySuccess, notifyPatchDetected, notifyRollbackFailure } from '../utils/notifier';\n\ntype Prompter = (question: string) => Promise<boolean>;\n\ntype ProcessPatchOptions = {\n    prompter?: Prompter;\n    cwd?: string;\n    notifyOnStart?: boolean;\n    yes?: boolean;\n};\n\nconst pendingTransactions = new Map<string, StateFile>();\n\nexport const createSnapshot = async (filePaths: string[], cwd: string = process.cwd()): Promise<FileSnapshot> => {\n  const snapshot: FileSnapshot = {};\n  await Promise.all(\n    filePaths.map(async (filePath) => {\n      snapshot[filePath] = await readFileContent(filePath, cwd);\n    })\n  );\n  return snapshot;\n};\n\n/**\n * Applies a series of file operations to the filesystem and returns the new in-memory file states.\n * This function processes operations sequentially, applying patches (like diffs) against the evolving\n * state of files, and performing filesystem actions (write, delete, rename) along the way.\n * @param operations The file operations to apply.\n * @param originalFiles The initial state of the files.\n * @param cwd The working directory.\n * @returns A map representing the final state of all affected files.\n */\nexport const applyOperations = async (  \n  operations: FileOperation[],\n  originalFiles: Map<string, string | null>,\n  cwd: string = process.cwd()\n): Promise<Map<string, string | null>> => {\n  // Step 1: Calculate all new file states in-memory. This is now parallelized inside relaycode-core.\n  const result = await applyOperationsCore(operations, originalFiles);\n\n  if (!result.success) {\n    throw new Error(`Failed to calculate state changes: ${result.error || 'Unknown error'}`);\n  }\n\n  const { newFileStates } = result;\n\n  // Step 2: Apply physical changes to the filesystem.\n  // To correctly handle renames, we process rename operations first.\n  const renameOps = operations.filter((op): op is Extract<FileOperation, {type: 'rename'}> => op.type === 'rename');\n  for (const op of renameOps) {\n    await renameFile(op.from, op.to, cwd);\n  }\n\n  // Step 3: Apply writes and deletes, which can be done in parallel.\n  const fsPromises: Promise<void>[] = [];\n  const allPaths = new Set([...originalFiles.keys(), ...newFileStates.keys()]);\n  const renamedFromPaths = new Set(renameOps.map(op => op.from));\n\n  for (const path of allPaths) {\n    if (renamedFromPaths.has(path)) continue; // This path was a source of a rename, it's already handled.\n\n    const oldContent = originalFiles.get(path);\n    const newContent = newFileStates.get(path);\n    if (oldContent !== newContent) {\n        // Use `== null` to check for both null and undefined.\n        // If newContent is missing from the map, it's treated as a deletion.\n        if (newContent == null) {\n            fsPromises.push(deleteFile(path, cwd));\n        } else {\n            fsPromises.push(writeFileContent(path, newContent, cwd));\n        }\n    }\n  }\n  await Promise.all(fsPromises);\n\n  return newFileStates;\n};\n\nexport const restoreSnapshot = async (snapshot: FileSnapshot, cwd: string = process.cwd()): Promise<void> => {\n  const projectRoot = path.resolve(cwd);\n  const entries = Object.entries(snapshot);\n  const directoriesToClean = new Set<string>();\n  const restoreErrors: { path: string, error: unknown }[] = [];\n\n  // Attempt to restore all files in parallel, collecting errors.\n  await Promise.all(entries.map(async ([filePath, content]) => {\n      const fullPath = path.resolve(cwd, filePath);\n      try {\n        if (content === null) {\n          // If the file didn't exist in the snapshot, make sure it doesn't exist after restore.\n          await deleteFile(filePath, cwd);\n          directoriesToClean.add(path.dirname(fullPath));\n        } else {\n          // Create directory structure if needed and write the original content back.\n          await writeFileContent(filePath, content, cwd);\n        }\n      } catch (error) {\n        restoreErrors.push({ path: filePath, error });\n      }\n  }));\n  \n  // After all files are processed, clean up empty directories\n  // Sort directories by depth (deepest first) to clean up nested empty dirs properly\n  const sortedDirs = Array.from(directoriesToClean)\n    .sort((a, b) => b.split(path.sep).length - a.split(path.sep).length);\n  \n  // Process each directory that had files deleted\n  for (const dir of sortedDirs) {\n    await removeEmptyParentDirectories(dir, projectRoot);\n  }\n\n  if (restoreErrors.length > 0) {\n    const errorSummary = restoreErrors\n      .map(e => `  - ${e.path}: ${getErrorMessage(e.error)}`)\n      .join('\\n');\n    throw new Error(`Rollback failed for ${restoreErrors.length} file(s):\\n${errorSummary}`);\n  }\n};\n\nconst logCompletionSummary = (\n    _uuid: string,\n    startTime: number,\n    operations: FileOperation[],\n    errorCount: number\n) => {\n    const duration = (Date.now() - startTime) / 1000;\n    const opCount = operations.length;\n    const opPlural = opCount === 1 ? '' : 's';\n    logger.info(''); // Newline for spacing\n    logger.info(chalk.bold(`Summary: ${opCount} file operation${opPlural} applied in ${duration.toFixed(2)}s. Linter errors: ${errorCount}.`));\n};\n\nconst rollbackTransaction = async (cwd: string, uuid: string, snapshot: FileSnapshot, reason: string, enableNotifications: boolean = true, isError: boolean = true): Promise<void> => {\n    // Validate UUID to prevent undefined.yaml errors\n    if (!uuid || typeof uuid !== 'string' || !uuid.match(/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/)) {\n        logger.error(`Fatal: Invalid UUID provided for rollback: ${uuid}`);\n        return;\n    }\n    \n    if (isError) {\n        logger.warn(`Rolling back changes: ${reason}`);\n    }\n\n    let rollbackSuccessful = false;\n    try {\n        await restoreSnapshot(snapshot, cwd);\n        logger.success('  - Files restored to original state.');\n        rollbackSuccessful = true;\n    } catch (error) {\n        logger.error(`Fatal: Rollback failed: ${getErrorMessage(error)}`);\n        notifyRollbackFailure(uuid, enableNotifications);\n        // Do not rethrow; we're already in a final error handling state.\n    } finally {\n        try {\n            await deletePendingState(cwd, uuid);\n            pendingTransactions.delete(uuid);\n            logger.info(`↩️ Transaction ${chalk.gray(uuid)} rolled back.`);\n            if (isError && rollbackSuccessful) {\n                notifyFailure(uuid, enableNotifications);\n            }\n        } catch (cleanupError) {\n            logger.error(`Fatal: Could not clean up pending state for ${chalk.gray(uuid)}: ${getErrorMessage(cleanupError)}`);\n        }\n    }\n};\n\ntype ApprovalOptions = {\n    config: Config;\n    cwd: string;\n    getConfirmation: Prompter;\n}\n\nconst handleApproval = async ({ config, cwd, getConfirmation }: ApprovalOptions): Promise<boolean> => {\n    const finalErrorCount = await getErrorCount(config.patch.linter, cwd);\n    logger.log(`  - Final linter error count: ${finalErrorCount > 0 ? chalk.red(finalErrorCount) : chalk.green(finalErrorCount)}`);\n    \n    const getManualApproval = async (reason: string): Promise<boolean> => {\n        logger.warn(reason);\n        \n        const notificationResult = await requestApprovalWithNotification(config.projectId, config.core.enableNotifications);\n\n        if (notificationResult === 'approved') {\n            logger.info('Approved via notification.');\n            return true;\n        }\n        if (notificationResult === 'rejected') {\n            logger.info('Rejected via notification.');\n            return false;\n        }\n\n        if (notificationResult === 'timeout') {\n            logger.info('Notification timed out. Please use the terminal to respond.');\n        }\n\n        return await getConfirmation('Changes applied. Do you want to approve and commit them? (y/N)');\n    };\n\n    if (config.patch.approvalMode === 'manual') {\n        return await getManualApproval('');\n    }\n    // auto mode\n    const canAutoApprove = finalErrorCount <= config.patch.approvalOnErrorCount;\n    if (canAutoApprove) {\n        logger.success('  - Changes automatically approved based on your configuration.');\n        return true;\n    }\n    return await getManualApproval(`Manual approval required: Linter found ${finalErrorCount} error(s) (threshold is ${config.patch.approvalOnErrorCount}).`);\n};\n\nconst _processPatch = async (config: Config, parsedResponse: ParsedLLMResponse, options?: ProcessPatchOptions): Promise<void> => {\n    const cwd = options?.cwd || process.cwd();\n    const getConfirmation = createConfirmationHandler({ yes: options?.yes }, options?.prompter);\n    const { control, operations, reasoning } = parsedResponse;\n    const { uuid, projectId } = control;\n    const startTime = performance.now();\n\n    // 1. Validation\n    if (projectId !== config.projectId) {\n        logger.warn(`Skipping patch: projectId mismatch (expected '${chalk.cyan(config.projectId)}', got '${chalk.cyan(projectId)}').`);\n        return;\n    }\n    if (await hasBeenProcessed(cwd, uuid)) {\n        logger.info(`Skipping patch: uuid '${chalk.gray(uuid)}' has already been processed.`);\n        return;\n    }\n\n    const { minFileChanges, maxFileChanges } = config.patch;\n    const operationCount = operations.length;\n    if (minFileChanges > 0 && operationCount < minFileChanges) {\n        logger.warn(`Skipping patch: Not enough file changes (expected at least ${minFileChanges}, got ${operationCount}).`);\n        return;\n    }\n    if (maxFileChanges && operationCount > maxFileChanges) {\n        logger.warn(`Skipping patch: Too many file changes (expected at most ${maxFileChanges}, got ${operationCount}).`);\n        return;\n    }\n\n    // Notify if coming from watch mode, now that we know it's a new patch.\n    if (options?.notifyOnStart) {\n        notifyPatchDetected(config.projectId, config.core.enableNotifications);\n    }\n\n    // 2. Pre-flight checks\n    if (config.patch.preCommand) {\n        logger.log(`  - Running pre-command: ${chalk.magenta(config.patch.preCommand)}`);\n        const { exitCode, stderr } = await executeShellCommand(config.patch.preCommand, cwd);\n        if (exitCode !== 0) {\n            logger.error(`Pre-command failed with exit code ${chalk.red(exitCode)}, aborting transaction.`);\n            if (stderr) logger.error(`Stderr: ${stderr}`);\n            return;\n        }\n    }\n\n    logger.info(chalk.gray(`\\n--------------------------------------------------`));\n    logger.info(chalk.cyan(`🚀 Applying patch ${uuid.substring(0,8)} for '${projectId}'...`));\n    logger.log(`${chalk.bold('Reasoning:')}\\n  ${reasoning.join('\\n  ')}`);\n\n    const affectedFilePaths = operations.reduce<string[]>((acc, op) => {\n        if (op.type === 'rename') {\n            acc.push(op.from, op.to);\n        } else {\n            acc.push(op.path);\n        }\n        return acc;\n    }, []);\n    const snapshot = await createSnapshot(affectedFilePaths, cwd);\n    \n    const stateFile: StateFile = {\n        uuid,\n        projectId,\n        createdAt: new Date().toISOString(),\n        gitCommitMsg: control.gitCommitMsg,\n        promptSummary: control.promptSummary,\n        reasoning,\n        operations,\n        snapshot,\n        approved: false,\n    };\n\n    try {\n        await writePendingState(cwd, stateFile);\n\n        const originalFiles = new Map<string, string | null>();\n        affectedFilePaths.forEach(p => originalFiles.set(p, snapshot[p] ?? null));\n\n        // Apply changes\n        const newFileStates = await applyOperations(operations, originalFiles, cwd);\n\n        operations.forEach(op => {\n            const stats = calculateLineChangesCore(op, originalFiles, newFileStates);\n            if (op.type === 'write') {\n                logger.success(`✔ Written: ${chalk.cyan(op.path)} (${chalk.green(`+${stats.added}`)}, ${chalk.red(`-${stats.removed}`)})`);\n            } else if (op.type === 'delete') {\n                logger.success(`✔ Deleted: ${chalk.cyan(op.path)}`);\n            } else if (op.type === 'rename') {\n                logger.success(`✔ Renamed: ${chalk.cyan(op.from)} -> ${chalk.cyan(op.to)}`);\n            }\n        });\n\n        // Run post-command\n        if (config.patch.postCommand) {\n            logger.log(`  - Running post-command: ${chalk.magenta(config.patch.postCommand)}`);\n            const postResult = await executeShellCommand(config.patch.postCommand, cwd);\n            if (postResult.exitCode !== 0) {\n                logger.error(`Post-command failed with exit code ${chalk.red(postResult.exitCode)}.`);\n                if (postResult.stderr) logger.error(`Stderr: ${postResult.stderr}`);\n                throw new Error('Post-command failed, forcing rollback.');\n            }\n        }\n\n        // Run post-command\n        const errorCount = await getErrorCount(config.patch.linter, cwd);\n        \n        // Log summary before asking for approval\n        logCompletionSummary(uuid, startTime, operations, errorCount);\n\n        const isApproved = await handleApproval({ \n            config, \n            cwd, \n            getConfirmation\n        });\n\n        if (isApproved) {\n            stateFile.approved = true;\n            await updatePendingState(cwd, stateFile);\n            await commitState(cwd, uuid);\n            notifySuccess(uuid, config.core.enableNotifications);\n            await handleAutoGitBranch(config, stateFile, cwd);\n            logger.info(chalk.green(`✔ Patch ${uuid.substring(0,8)} committed.`));\n            logger.info(chalk.gray(`\\n[relay] Watching for patches...`));\n        } else {\n            logger.warn('Operation cancelled by user. Rolling back changes...');\n            await rollbackTransaction(cwd, uuid, snapshot, 'User cancellation', config.core.enableNotifications, false);\n        }\n    } catch (error) {\n        const reason = getErrorMessage(error);\n        await rollbackTransaction(cwd, uuid, snapshot, reason, config.core.enableNotifications, true);\n        logger.info(chalk.gray(`\\n[relay] Watching for patches...`));\n    }\n};\n\n/**\n * Processes a patch transaction. This function acts as a locking wrapper around the core\n * patch processing logic (`_processPatch`) to ensure that only one transaction is\n * processed at a time for a given working directory. This prevents race conditions\n * with the file-based database.\n * @param config The application configuration.\n * @param parsedResponse The parsed response from the LLM.\n * @param options Options for processing the patch.\n */\nexport const processPatch = async (config: Config, parsedResponse: ParsedLLMResponse, options?: ProcessPatchOptions): Promise<void> => {\n    await _processPatch(config, parsedResponse, options);\n};\n\nexport const getPendingTransactionCount = (_cwd: string = process.cwd()): number => {\n    return pendingTransactions.size;\n};\n\nexport const approveAllPendingTransactions = async (_config: Config, cwd: string = process.cwd(), yes: boolean = false): Promise<void> => {\n    const pending = Array.from(pendingTransactions.values());\n    if (pending.length === 0) {\n        logger.info('No pending transactions to approve.');\n        return;\n    }\n\n    const sortedPending = pending.sort((a,b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());\n\n    logger.info(chalk.bold(`Found ${pending.length} pending patch(es):`));\n    sortedPending.forEach(tx => {\n        const reasoning = (normalizeGitCommitMsg(Array.isArray(tx.reasoning) ? tx.reasoning.join(' ') : tx.reasoning) || 'No reasoning provided.').split('\\n')[0];\n        logger.info(`  - ${chalk.cyan(tx.uuid.substring(0,8))}: ${reasoning}`);\n    });\n    logger.info(''); // spacing\n\n    if (yes) {\n        logger.info(''); // spacing\n        for (const tx of sortedPending) {\n            // Note: autoCommit and autoBranch are not in the current config schema\n            await commitState(cwd, tx.uuid);\n            logger.info(chalk.green(`✔ Patch ${tx.uuid.substring(0,8)} committed.`));\n            pendingTransactions.delete(tx.uuid);\n        }\n        logger.info(chalk.bold.green(`\\n✅ Successfully committed ${pending.length} patch(es).`));\n        return;\n    }\n\n    const prompter = createConfirmationHandler({});\n    const confirmed = await prompter('Do you want to approve and commit all of them?');\n\n    if (!confirmed) {\n        logger.info('Bulk approval cancelled.');\n        return;\n    }\n\n    logger.info(''); // spacing\n    for (const tx of sortedPending) {\n        // Note: autoCommit and autoBranch are not in the current config schema\n        await commitState(cwd, tx.uuid);\n        logger.info(chalk.green(`✔ Patch ${tx.uuid.substring(0,8)} committed.`));\n        pendingTransactions.delete(tx.uuid);\n    }\n\n    logger.info(chalk.bold.green(`\\n✅ Successfully committed ${pending.length} patch(es).`));\n};\n\nexport const processPatchesBulk = async (config: Config, parsedResponses: ParsedLLMResponse[], options?: ProcessPatchOptions): Promise<void> => {\n    // In bulk mode, process each patch individually, which will trigger individual approvals.\n    // The \"bulk\" aspect is about clipboard gathering, not approval.\n    for (const parsedResponse of parsedResponses) {\n        await processPatch(config, parsedResponse, options);\n    }\n};\n\n\nconst handleAutoGitBranch = async (config: Config, stateFile: StateFile, cwd: string): Promise<void> => {\n    if (!config.git.autoGitBranch) return;\n\n    let branchNameSegment = '';\n    if (config.git.gitBranchTemplate === 'gitCommitMsg' && stateFile.gitCommitMsg) {\n        branchNameSegment = normalizeGitCommitMsg(stateFile.gitCommitMsg) ?? '';\n    } else {\n        branchNameSegment = stateFile.uuid;\n    }\n\n    const sanitizedSegment = branchNameSegment\n        .trim()\n        .toLowerCase()\n        .replace(/[^\\w\\s-]/g, '') // Remove all non-word, non-space, non-hyphen chars\n        .replace(/[\\s_]+/g, '-') // Replace spaces and underscores with a single hyphen\n        .replace(/-+/g, '-') // Collapse consecutive hyphens\n        .replace(/^-|-$/g, '') // Trim leading/trailing hyphens\n        .slice(0, 70); // Truncate\n\n    if (sanitizedSegment) {\n        const branchName = `${config.git.gitBranchPrefix}${sanitizedSegment}`;\n        logger.info(`Creating and switching to new git branch: ${chalk.magenta(branchName)}`);\n        const command = `git checkout -b \"${branchName}\"`;\n        const result = await executeShellCommand(command, cwd);\n        if (result.exitCode === 0) {\n            logger.success(`Successfully created and switched to branch '${chalk.magenta(branchName)}'.`);\n        } else {\n            // Exit code 128 from `git checkout -b` often means the branch already exists.\n            if (result.exitCode === 128 && result.stderr.includes('already exists')) {\n                logger.warn(`Could not create branch '${chalk.magenta(branchName)}' because it already exists.`);\n            } else {\n                logger.warn(`Could not create git branch '${chalk.magenta(branchName)}'.`);\n            }\n            logger.debug(`'${command}' failed with: ${result.stderr}`);\n        }\n    } else {\n        logger.warn('Could not generate a branch name segment from commit message or UUID. Skipping git branch creation.');\n    }\n};\n"]}